Files
pascar/index.html
T

1 line
30 KiB
HTML

<!doctype html><html lang=en><meta charset=UTF-8><meta name=viewport content="width=device-width,initial-scale=1"><title>Untitled - Pascar</title><link rel=manifest href=/manifest.json><style>*,:before,:after{box-sizing:border-box;margin:0;padding:0}:root{--bg:#1c1c1c;--fg:#fff;--menu-bg:#295991;--menu-fg:#fff;--menu-sel-bg:navy;--menu-sel-fg:#fff;--border:#aaa;--shadow:#555;--dialog-bg:#aaa;--dialog-title-bg:#295991;--dialog-title-fg:#fff;--input-bg:#fff;--input-fg:#000;--scrollbar-track:#aaa;--scrollbar-thumb:#555;--status-bg:#aaa;--status-fg:#000;--notif-bg:navy;--notif-fg:#fff;--help-bg:#000040;--help-key:#0ff;--help-heading:#ff0;--ln-fg:#aaa}html,body{height:100%;overflow:hidden}body{background:var(--bg);color:var(--fg);user-select:none;flex-direction:column;height:100vh;font-family:Courier New,Courier,monospace;font-size:15px;display:flex}#title-bar{background:var(--bg);color:var(--fg);text-align:center;letter-spacing:.5px;flex-shrink:0;padding:2px 0;font-size:15px}#menu-bar{background:var(--menu-bg);color:var(--menu-fg);z-index:50;flex-shrink:0;align-items:stretch;display:flex;position:relative}.menu-item{cursor:default;white-space:nowrap;align-items:center;padding:2px 12px;display:flex;position:relative}.menu-item:hover,.menu-item.active{background:var(--menu-sel-bg);color:var(--menu-sel-fg)}.menu-item .ul{text-decoration:underline}.dropdown{background:var(--menu-bg);color:var(--menu-fg);z-index:200;min-width:220px;box-shadow:3px 3px 0 var(--shadow);border:1px solid #000;display:none;position:absolute;top:100%}.dropdown.open{display:block}.dd-item{cursor:default;white-space:nowrap;justify-content:space-between;align-items:center;gap:24px;padding:3px 18px 3px 20px;font-size:14px;display:flex}.dd-item:hover,.dd-item.dd-focused{background:var(--menu-sel-bg);color:var(--menu-sel-fg)}.dd-item:hover .dd-key,.dd-item.dd-focused .dd-key{color:#aaa}.dd-item.disabled{color:#777;cursor:default}.dd-item.disabled:hover{background:var(--menu-bg);color:#777}.dd-sep{border-top:1px solid #666;margin:3px 0}.dd-key{color:var(--menu-fg);font-size:12px}#editor-area{background:var(--bg);flex:1;display:flex;position:relative;overflow:hidden}#line-numbers{background:var(--bg);color:var(--ln-fg);text-align:right;border-right:1px solid var(--border);pointer-events:none;white-space:pre;flex-shrink:0;min-width:44px;padding:2px 6px 2px 4px;font-family:Courier New,Courier,monospace;font-size:15px;line-height:1.25;overflow:hidden}#editor{background:var(--bg);color:var(--fg);resize:none;white-space:pre;caret-color:#fff;-moz-tab-size:4;tab-size:4;-webkit-user-select:text;user-select:text;border:none;outline:none;flex:1;padding:2px 8px;font-family:Courier New,Courier,monospace;font-size:15px;line-height:1.25;overflow:auto scroll}#editor::selection{color:navy;background:#fff}#editor::-webkit-scrollbar{width:14px;height:14px}#editor::-webkit-scrollbar-track{background:var(--scrollbar-track)}#editor::-webkit-scrollbar-thumb{background:var(--scrollbar-thumb);border:1px solid #333}#editor::-webkit-scrollbar-corner{background:var(--scrollbar-track)}#goto-bar{background:var(--status-bg);color:var(--status-fg);border-top:1px solid #555;flex-shrink:0;align-items:center;gap:8px;padding:3px 10px;font-size:13px;display:none}#goto-bar.open{display:flex}#goto-bar input{color:#000;background:#fff;border:1px solid #000;outline:none;width:70px;padding:1px 5px;font-family:Courier New,monospace;font-size:13px}#goto-bar input:focus{outline:2px solid navy}#find-bar{background:var(--status-bg);color:var(--status-fg);border-top:1px solid #555;flex-wrap:wrap;flex-shrink:0;align-items:center;gap:8px;padding:3px 10px;font-size:13px;display:none}#find-bar.open{display:flex}#find-bar input[type=text]{color:#000;background:#fff;border:1px solid #000;outline:none;width:160px;padding:1px 5px;font-family:Courier New,monospace;font-size:13px}#find-bar input[type=text]:focus{outline:2px solid navy}#find-bar label{cursor:pointer;align-items:center;gap:4px;display:flex}#status-bar{background:var(--status-bg);color:var(--status-fg);border-top:1px solid #555;flex-shrink:0;justify-content:space-between;align-items:center;padding:2px 8px;font-size:13px;display:flex}.status-left,.status-right{align-items:center;gap:16px;display:flex}#status-modified{color:#c00;font-weight:700}#dialog-overlay{z-index:300;background:#0000008c;justify-content:center;align-items:center;display:none;position:absolute;inset:0}#dialog-overlay.open{display:flex}.dialog{background:var(--bg);color:var(--menu-fg);border:2px solid #fff;min-width:340px;max-width:480px;box-shadow:5px 5px #000}.dialog-title{background:var(--dialog-title-bg);color:var(--dialog-title-fg);padding:4px 10px;font-size:14px;font-weight:700}.dialog-body{padding:14px 18px 10px}.dialog-body label{margin-bottom:4px;font-size:13px;display:block}.dialog-body input[type=text]{background:var(--input-bg);width:100%;color:var(--input-fg);border:1px solid #000;outline:none;margin-bottom:10px;padding:3px 5px;font-family:Courier New,monospace;font-size:13px}.dialog-body input[type=text]:focus{outline:2px solid navy}.dialog-check{cursor:pointer;align-items:center;gap:6px;margin-bottom:6px;font-size:13px;display:flex}.dialog-buttons{justify-content:flex-end;gap:8px;margin-top:12px;display:flex}.btn{background:var(--menu-bg);color:#000;cursor:pointer;border:1px solid #000;outline:none;padding:3px 16px;font-family:Courier New,monospace;font-size:13px;box-shadow:2px 2px #555}.btn:hover{background:#ccc}.btn:active{box-shadow:none;transform:translate(1px,1px)}.btn.primary{background:(--menu-bg);color:#fff;border-color:#fff}.btn.primary:hover{background:#00a}.btn:focus{outline:2px solid navy}#notif{background:var(--notif-bg);color:var(--notif-fg);z-index:400;white-space:nowrap;pointer-events:none;border:1px solid #fff;padding:5px 18px;font-size:13px;display:none;position:absolute;bottom:32px;left:50%;transform:translate(-50%)}#notif.show{display:block}#help-overlay{z-index:300;color:#fff;background:#000040f5;padding:24px 32px;display:none;position:absolute;inset:0;overflow-y:auto}#help-overlay.open{display:block}.help-title{text-align:center;color:var(--help-heading);letter-spacing:1px;margin-bottom:16px;font-size:17px}.help-cols{flex-wrap:wrap;justify-content:center;gap:40px;display:flex}.help-section-title{color:var(--help-heading);margin:12px 0 4px;font-size:13px;font-weight:700}.help-table{border-collapse:collapse;font-size:13px}.help-table td{vertical-align:top;padding:2px 12px 2px 0}.help-table td:first-child{color:var(--help-key);min-width:150px}.help-close{text-align:center;color:#aaa;margin-top:18px;font-size:13px}</style><div id=title-bar>Pascar</div><div id=menu-bar><div class=menu-item data-menu=file><span class=ul>F</span>ile</div><div class=menu-item data-menu=edit><span class=ul>E</span>dit</div><div class=menu-item data-menu=search><span class=ul>S</span>earch</div><div class=menu-item data-menu=view><span class=ul>V</span>iew</div><div class=menu-item data-menu=help><span class=ul>H</span>elp</div><div id=menu-file class=dropdown><div class=dd-item data-action=new><span><span class=ul>N</span>ew</span><span class=dd-key>Ctrl+N</span></div><div class=dd-item data-action=open><span><span class=ul>O</span>pen...</span><span class=dd-key>Ctrl+O</span></div><div class=dd-item data-action=save><span><span class=ul>S</span>ave</span><span class=dd-key>Ctrl+S</span></div><div class=dd-item data-action=saveas><span>Save <span class=ul>A</span>s...</span><span class=dd-key>Ctrl+Shift+S</span></div><div class=dd-sep></div><div class=dd-item data-action=print><span><span class=ul>P</span>rint...</span><span class=dd-key>Ctrl+P</span></div><div class=dd-sep></div><div class=dd-item data-action=exit><span>E<span class=ul>x</span>it</span><span class=dd-key>Alt+F4</span></div></div><div id=menu-edit class=dropdown><div class=dd-item data-action=undo><span><span class=ul>U</span>ndo</span><span class=dd-key>Ctrl+Z</span></div><div class=dd-item data-action=redo><span><span class=ul>R</span>edo</span><span class=dd-key>Ctrl+Y</span></div><div class=dd-sep></div><div class=dd-item data-action=cut><span>Cu<span class=ul>t</span></span><span class=dd-key>Ctrl+X</span></div><div class=dd-item data-action=copy><span><span class=ul>C</span>opy</span><span class=dd-key>Ctrl+C</span></div><div class=dd-item data-action=paste><span><span class=ul>P</span>aste</span><span class=dd-key>Ctrl+V</span></div><div class=dd-item data-action=delete><span><span class=ul>D</span>elete</span><span class=dd-key>Del</span></div><div class=dd-sep></div><div class=dd-item data-action=selectall><span>Select <span class=ul>A</span>ll</span><span class=dd-key>Ctrl+A</span></div><div class=dd-sep></div><div class=dd-item data-action=timestamp><span>Time/<span class=ul>D</span>ate</span><span class=dd-key>F5</span></div></div><div id=menu-search class=dropdown><div class=dd-item data-action=find><span><span class=ul>F</span>ind...</span><span class=dd-key>Ctrl+F</span></div><div class=dd-item data-action=replace><span><span class=ul>R</span>eplace...</span><span class=dd-key>Ctrl+H</span></div><div class=dd-item data-action=findnext><span>Find <span class=ul>N</span>ext</span><span class=dd-key>F3</span></div><div class=dd-item data-action=findprev><span>Find <span class=ul>P</span>revious</span><span class=dd-key>Shift+F3</span></div><div class=dd-sep></div><div class=dd-item data-action=goto><span><span class=ul>G</span>o to Line...</span><span class=dd-key>Ctrl+G</span></div></div><div id=menu-view class=dropdown><div class=dd-item data-action=wordwrap><span><span class=ul>W</span>ord Wrap</span><span class=dd-key>Alt+W</span></div><div class=dd-item data-action=linenumbers><span><span class=ul>L</span>ine Numbers</span><span class=dd-key>Alt+L</span></div><div class=dd-sep></div><div class=dd-item data-action=zoomin><span>Zoom <span class=ul>I</span>n</span><span class=dd-key>Ctrl++</span></div><div class=dd-item data-action=zoomout><span>Zoom <span class=ul>O</span>ut</span><span class=dd-key>Ctrl+-</span></div><div class=dd-item data-action=zoomreset><span>Reset Zoo<span class=ul>m</span></span><span class=dd-key>Ctrl+0</span></div></div><div id=menu-help class=dropdown><div class=dd-item data-action=shortcuts><span><span class=ul>K</span>eyboard Shortcuts</span><span class=dd-key>F1</span></div><div class=dd-sep></div><div class=dd-item data-action=about><span><span class=ul>A</span>bout Pascar</span></div></div></div><div id=editor-area><div id=line-numbers></div><textarea id=editor spellcheck=false autocomplete=off autocorrect=off autocapitalize=off></textarea><div id=dialog-overlay><div class=dialog id=dialog-box><div class=dialog-title id=dialog-title>Dialog</div><div class=dialog-body id=dialog-body></div></div></div><div id=help-overlay><div class=help-title>Pascar - Keyboard Shortcuts</div><div class=help-cols><div><div class=help-section-title>Menu Navigation</div><table class=help-table><tr><td>Alt+F<td>Open File menu<tr><td>Alt+E<td>Open Edit menu<tr><td>Alt+S<td>Open Search menu<tr><td>Alt+V<td>Open View menu<tr><td>Alt+H<td>Open Help menu<tr><td>↑ / ↓<td>Move through menu items<tr><td>← / →<td>Switch between menus<tr><td>Enter<td>Activate highlighted item<tr><td>Letter key<td>Activate underlined shortcut<tr><td>Escape<td>Close menu</table><div class=help-section-title>File Operations</div><table class=help-table><tr><td>Ctrl+N<td>New file<tr><td>Ctrl+O<td>Open file from disk<tr><td>Ctrl+S<td>Save / download file<tr><td>Ctrl+Shift+S<td>Save As...<tr><td>Ctrl+P<td>Print</table><div class=help-section-title>Editing</div><table class=help-table><tr><td>Ctrl+Z<td>Undo<tr><td>Ctrl+Y<td>Redo<tr><td>Ctrl+X<td>Cut<tr><td>Ctrl+C<td>Copy<tr><td>Ctrl+V<td>Paste<tr><td>Ctrl+A<td>Select All<tr><td>Del<td>Delete selection<tr><td>F5<td>Insert date/time<tr><td>Insert<td>Toggle Insert/Overwrite<tr><td>Tab<td>Indent (4 spaces)<tr><td>Shift+Tab<td>Unindent</table></div><div><div class=help-section-title>Search</div><table class=help-table><tr><td>Ctrl+F<td>Find...<tr><td>Ctrl+H<td>Find & Replace...<tr><td>F3<td>Find Next<tr><td>Shift+F3<td>Find Previous<tr><td>Ctrl+G<td>Go to Line...</table><div class=help-section-title>View</div><table class=help-table><tr><td>Alt+W<td>Toggle Word Wrap<tr><td>Alt+L<td>Toggle Line Numbers<tr><td>Ctrl++<td>Zoom In<tr><td>Ctrl+-<td>Zoom Out<tr><td>Ctrl+0<td>Reset Zoom</table><div class=help-section-title>Navigation</div><table class=help-table><tr><td>Ctrl+Home<td>Beginning of file<tr><td>Ctrl+End<td>End of file<tr><td>Ctrl+Left/Right<td>Move word by word<tr><td>Home / End<td>Start / end of line<tr><td>Page Up / Down<td>Scroll one page</table><div class=help-section-title>General</div><table class=help-table><tr><td>F1<td>Show this help screen<tr><td>Escape<td>Close menus / dialogs<tr><td>Alt+F4<td>Exit (close tab)</table></div></div><div class=help-close>Press <strong>Escape</strong> or <strong>F1</strong> to close this screen</div></div><div id=notif></div></div><div id=find-bar><span id=find-label>Find:</span> <input id=find-input placeholder="Search text..." autocomplete=off> <span id=replace-label style=display:none>Replace:</span> <input id=replace-input placeholder="Replace with..." autocomplete=off style=display:none> <label><input type=checkbox id=find-case> Case</label> <label><input type=checkbox id=find-whole> Word</label> <button class="btn primary" id=btn-find-next>▼ Next</button> <button class=btn id=btn-find-prev>▲ Prev</button> <button class=btn id=btn-replace-one style=display:none>Replace</button> <button class=btn id=btn-replace-all style=display:none>Replace All</button> <span id=find-status style=color:#555;margin-left:4px;font-size:12px></span> <button class=btn id=btn-find-close style=margin-left:auto>✕ Close</button></div><div id=goto-bar><span>Go to line:</span> <input id=goto-input maxlength=7 placeholder="Line #"> <button class="btn primary" id=goto-ok>OK</button> <button class=btn id=goto-cancel>Cancel</button></div><div id=status-bar><div class=status-left><span id=status-file>Untitled</span> <span id=status-modified></span> <span id=status-enc>UTF-8</span></div><div class=status-right><span id=status-words>Words: 0</span> <span id=status-chars>Chars: 0</span> <span id=status-pos>Ln 1, Col 1</span> <span id=status-mode>INS</span></div></div><script>!function(){"use strict";const e=document.getElementById("editor"),t=document.getElementById("line-numbers"),n=document.getElementById("title-bar"),o=document.getElementById("status-file"),l=document.getElementById("status-modified"),s=document.getElementById("status-pos"),a=document.getElementById("status-mode"),i=document.getElementById("status-words"),c=document.getElementById("status-chars"),r=document.getElementById("notif"),d=document.getElementById("help-overlay"),u=document.getElementById("dialog-overlay"),m=document.getElementById("dialog-title"),f=document.getElementById("dialog-body"),p=document.getElementById("find-bar"),v=document.getElementById("find-input"),g=document.getElementById("replace-input"),y=document.getElementById("find-case"),h=document.getElementById("find-whole"),E=document.getElementById("find-status"),b=document.getElementById("goto-bar"),w=document.getElementById("goto-input"),x=document.getElementById("menu-bar");let L="Untitled",k=!1,S=!0,I=!1,B=!0,D=15,C="",A="",F=null,O=!1;function R(){$(),q()}function $(){if(!B)return void(t.style.display="none");t.style.display="";const n=e.value.split("\n").length,o=String(n).length;t.style.minWidth=9*o+16+"px";let l="";for(let e=1;e<=n;e++)l+=e+"\n";t.textContent=l,t.scrollTop=e.scrollTop}function q(){const t=e.value,r=e.selectionStart,d=t.substring(0,r).split("\n"),u=d.length,m=d[d.length-1].length+1;s.textContent=`Ln ${u}, Col ${m}`,a.textContent=S?"INS":"OVR",o.textContent=L,l.textContent=k?"●":"";const f=t.trim(),p=f?f.split(/\s+/).length:0;i.textContent=`Words: ${p}`,c.textContent=`Chars: ${t.length}`,n.textContent=(k?"* ":"")+L+" - Pascar"}function T(e,t=2500){r.textContent=e,r.classList.add("show"),clearTimeout(F),F=setTimeout(()=>r.classList.remove("show"),t)}e.value=["Pascar","======","","A faithful offline recreation of the classic MS-DOS Editor","Runs entirely in your browser - no server, no internet.","","QUICK START","-----------"," Ctrl+O Open a text file from your computer"," Ctrl+S Save / download the current file"," Ctrl+F Find text"," Ctrl+H Find and Replace"," Ctrl+G Go to a specific line number"," F3 / Shift+F3 Find next / previous match"," F5 Insert current date and time"," Alt+F/E/S/V/H Open menu (then ↑↓ to navigate, Enter to select)"," Alt+L Toggle line numbers"," Ctrl++ / Ctrl-- Zoom in / out"," Insert Toggle Insert / Overwrite mode"," F1 Show full keyboard shortcuts","","Start typing to edit this file."].join("\n"),R(),e.focus(),e.addEventListener("input",()=>{k=!0,R()}),e.addEventListener("keyup",q),e.addEventListener("click",q),e.addEventListener("scroll",()=>{t.scrollTop=e.scrollTop}),e.addEventListener("keydown",t=>{if("Insert"===t.key&&!t.ctrlKey&&!t.altKey)return S=!S,void q();if("Tab"===t.key&&!t.ctrlKey&&!t.altKey){t.preventDefault();const n=e.selectionStart,o=e.selectionEnd;if(t.shiftKey){const t=e.value.lastIndexOf("\n",n-1)+1,o=e.value.substring(t,n).match(/^ {1,4}/);o&&(e.value=e.value.substring(0,t)+e.value.substring(t+o[0].length),e.selectionStart=e.selectionEnd=n-o[0].length,k=!0,R())}else e.value=e.value.substring(0,n)+" "+e.value.substring(o),e.selectionStart=e.selectionEnd=n+4,k=!0,R()}});const P={f:"file",e:"edit",s:"search",v:"view",h:"help"};function K(){return document.querySelector(".dropdown.open")||null}function j(e){const t=document.querySelector(`.menu-item[data-menu="${e}"]`),n=document.getElementById("menu-"+e);if(!t||!n)return;const o=t.getBoundingClientRect(),l=x.getBoundingClientRect();n.style.left=o.left-l.left+"px"}function z(e){const t=document.querySelector(`.menu-item[data-menu="${e}"]`),n=document.getElementById("menu-"+e);t&&n&&(document.querySelectorAll(".dropdown").forEach(e=>e.classList.remove("open")),document.querySelectorAll(".menu-item").forEach(e=>e.classList.remove("active")),j(e),n.classList.add("open"),t.classList.add("active"),U(n,0))}function N(e){return Array.from(e.querySelectorAll(".dd-item:not(.disabled)"))}function U(e,t){const n=N(e);if(n.forEach(e=>e.classList.remove("dd-focused")),0===n.length)return;n[(t%n.length+n.length)%n.length].classList.add("dd-focused")}function M(e){return N(e).findIndex(e=>e.classList.contains("dd-focused"))}function W(){document.querySelectorAll(".dropdown").forEach(e=>e.classList.remove("open")),document.querySelectorAll(".menu-item").forEach(e=>e.classList.remove("active")),u.classList.remove("open"),d.classList.remove("open"),p.classList.remove("open"),b.classList.remove("open"),e.focus()}function H(){d.classList.contains("open")?W():(W(),d.classList.add("open"))}function V(t){const n={new:J,open:Q,save:_,saveas:X,print:ee,exit:()=>T("Close this browser tab to exit."),undo:()=>{e.focus(),document.execCommand("undo"),R()},redo:()=>{e.focus(),document.execCommand("redo"),R()},cut:()=>{e.focus(),document.execCommand("cut")},copy:()=>{e.focus(),document.execCommand("copy")},paste:()=>{e.focus(),document.execCommand("paste")},delete:te,selectall:()=>{e.select()},timestamp:ne,find:()=>ce(!1),replace:()=>ce(!0),findnext:()=>ue(1),findprev:()=>ue(-1),goto:me,wordwrap:oe,linenumbers:le,zoomin:()=>se(1),zoomout:()=>se(-1),zoomreset:ae,shortcuts:H,about:ve};n[t]&&n[t]()}document.querySelectorAll(".menu-item").forEach(e=>{e.addEventListener("click",t=>{t.stopPropagation();const n=e.dataset.menu,o=document.getElementById("menu-"+n),l=o.classList.contains("open");document.querySelectorAll(".dropdown").forEach(e=>e.classList.remove("open")),document.querySelectorAll(".menu-item").forEach(e=>e.classList.remove("active")),l||(j(n),o.classList.add("open"),e.classList.add("active"))}),e.addEventListener("mouseenter",()=>{if(document.querySelector(".dropdown.open")){const t=e.dataset.menu;document.querySelectorAll(".dropdown").forEach(e=>e.classList.remove("open")),document.querySelectorAll(".menu-item").forEach(e=>e.classList.remove("active")),j(t),document.getElementById("menu-"+t).classList.add("open"),e.classList.add("active")}})}),document.querySelectorAll(".dd-item:not(.disabled)").forEach(e=>{e.addEventListener("click",t=>{t.preventDefault(),t.stopPropagation(),W(),V(e.dataset.action)})}),document.addEventListener("click",e=>{e.target.closest("#menu-bar")&&W()}),document.addEventListener("keydown",e=>{const t=e.ctrlKey||e.metaKey,n=e.shiftKey,o=e.altKey,l=e.key.toLowerCase();if(o&&!t&&P[l]){e.preventDefault();const t=K();return void(t&&t.id==="menu-"+P[l]?W():z(P[l]))}const s=K();if(s){if("ArrowDown"===e.key)return e.preventDefault(),void U(s,M(s)+1);if("ArrowUp"===e.key){e.preventDefault();const t=M(s);return void U(s,t<=0?N(s).length-1:t-1)}if("ArrowLeft"===e.key){e.preventDefault();const t=["file","edit","search","view","help"],n=s.id.replace("menu-","");return void z(t[(t.indexOf(n)-1+t.length)%t.length])}if("ArrowRight"===e.key){e.preventDefault();const t=["file","edit","search","view","help"],n=s.id.replace("menu-","");return void z(t[(t.indexOf(n)+1)%t.length])}if("Enter"===e.key){e.preventDefault();const t=s.querySelector(".dd-item.dd-focused");if(p.classList.contains("open")&&b.classList.contains("open")&&d.classList.contains("open")&&u.classList.contains("open"))return e.preventDefault(),void e.stopPropagation();if(t&&t.dataset.action){const e=t.dataset.action;W(),V(e)}return}if(!t&&!o&&1===e.key.length){const t=e.key.toLowerCase(),n=N(s).find(e=>{const n=e.querySelector(".ul");return n&&n.textContent.toLowerCase()===t});if(n&&n.dataset.action){e.preventDefault();const t=n.dataset.action;return W(),void V(t)}}}return"Escape"===e.key?(e.preventDefault(),void W()):"F1"===e.key?(e.preventDefault(),void H()):"F3"===e.key?(e.preventDefault(),void ue(n?-1:1)):"F5"!==e.key||t||o?(t&&"n"===l&&(e.preventDefault(),J()),t&&"o"===l&&(e.preventDefault(),Q()),t&&"s"===l&&n?(e.preventDefault(),X()):t&&"s"===l&&(e.preventDefault(),_()),t&&"p"===l&&(e.preventDefault(),ee()),t&&"f"===l&&(e.preventDefault(),ce(!1)),t&&"h"===l&&(e.preventDefault(),ce(!0)),t&&"g"===l&&(e.preventDefault(),me()),!t||"="!==l&&"+"!==l||(e.preventDefault(),se(1)),t&&"-"===l&&(e.preventDefault(),se(-1)),t&&"0"===l&&(e.preventDefault(),ae()),o&&"w"===l&&(e.preventDefault(),oe()),void(o&&"l"===l&&(e.preventDefault(),le()))):(e.preventDefault(),void ne())});let G=null;const Z="function"==typeof window.showOpenFilePicker;function J(){k&&!confirm("Discard unsaved changes?")||(e.value="",L="Untitled",G=null,k=!1,R(),e.focus())}async function Q(){if(!k||confirm("Discard unsaved changes?"))if(Z)try{const[t]=await window.showOpenFilePicker({types:[{description:"Text files",accept:{"text/*":[".txt",".md",".js",".ts",".py",".html",".css",".json",".xml",".csv",".log",".c",".cpp",".h",".java",".rs",".go",".rb",".sh",".bat",".ini",".cfg",".yaml",".yml"]}}],multiple:!1});G=t;const n=await t.getFile();L=n.name,e.value=await n.text(),k=!1,R(),e.focus(),T(`Opened: ${L}`)}catch(e){"AbortError"!==e.name&&T("Could not open file.")}else{const t=document.createElement("input");t.type="file",t.accept=".txt,.md,.js,.ts,.py,.html,.css,.json,.xml,.csv,.log,.c,.cpp,.h,.java,.rs,.go,.rb,.sh,.bat,.ini,.cfg,.yaml,.yml,text/*",t.onchange=t=>{const n=t.target.files[0];if(!n)return;G=null,L=n.name;const o=new FileReader;o.onload=t=>{e.value=t.target.result,k=!1,R(),e.focus(),T(`Opened: ${L}`)},o.readAsText(n)},t.click()}}async function _(){if(Z&&G)try{const t=await G.createWritable();await t.write(e.value),await t.close(),k=!1,q(),T(`Saved: ${L}`)}catch(e){"AbortError"!==e.name&&T("Save failed: "+e.message)}else Z&&!G?await X():Y("Untitled"===L?"untitled.txt":L)}async function X(){if(Z)try{const t=await window.showSaveFilePicker({suggestedName:"Untitled"===L?"untitled.txt":L,types:[{description:"Text files",accept:{"text/plain":[".txt",".md",".js",".ts",".py",".html",".css",".json",".xml",".csv",".log"]}}]});G=t,L=t.name;const n=await t.createWritable();await n.write(e.value),await n.close(),k=!1,q(),T(`Saved: ${L}`)}catch(e){"AbortError"!==e.name&&T("Save failed: "+e.message)}else pe("Save As",`\n <label>File name:</label>\n <input type="text" id="d-savename" value="${t="Untitled"===L?"untitled.txt":L,t.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}">\n <div style="font-size:12px;color:#aaa;margin-bottom:8px;">File System Access API not supported in this browser.<br>File will be downloaded instead.</div>\n <div class="dialog-buttons">\n <button class="btn primary" id="d-saveas-ok">Download</button>\n <button class="btn" id="d-saveas-cancel">Cancel</button>\n </div>\n `,()=>{const e=document.getElementById("d-savename");e.focus(),e.select(),document.getElementById("d-saveas-ok").addEventListener("click",()=>{const t=e.value.trim();t&&(L=t,W(),Y(t))}),e.addEventListener("keydown",e=>{"Enter"===e.key&&document.getElementById("d-saveas-ok").click()}),document.getElementById("d-saveas-cancel").addEventListener("click",W)});var t}function Y(t){const n=new Blob([e.value],{type:"text/plain;charset=utf-8"}),o=URL.createObjectURL(n),l=document.createElement("a");l.href=o,l.download=t,l.click(),URL.revokeObjectURL(o),k=!1,q(),T(`Downloaded: ${t}`)}function ee(){window.print()}function te(){const t=e.selectionStart,n=e.selectionEnd;t!==n&&(e.value=e.value.substring(0,t)+e.value.substring(n),e.selectionStart=e.selectionEnd=t,k=!0,R())}function ne(){const t=(new Date).toLocaleString(),n=e.selectionStart,o=e.selectionEnd;e.value=e.value.substring(0,n)+t+e.value.substring(o),e.selectionStart=e.selectionEnd=n+t.length,k=!0,R(),e.focus()}function oe(){I=!I,e.style.whiteSpace=I?"pre-wrap":"pre",T("Word Wrap: "+(I?"ON":"OFF"))}function le(){B=!B,$(),T("Line Numbers: "+(B?"ON":"OFF"))}function se(e){D=Math.min(32,Math.max(9,D+2*e)),ie()}function ae(){D=15,ie()}function ie(){e.style.fontSize=D+"px",t.style.fontSize=D+"px",e.style.lineHeight=t.style.lineHeight="1.25",$(),T(`Zoom: ${D}px`)}function ce(e){O=e,W(),p.classList.add("open"),document.getElementById("replace-label").style.display=e?"":"none",g.style.display=e?"":"none",document.getElementById("btn-replace-one").style.display=e?"":"none",document.getElementById("btn-replace-all").style.display=e?"":"none",v.value=C,g.value=A,E.textContent="",v.focus(),v.select()}function re(){C=v.value,A=g.value}function de(e){if(!C)return null;let t=e?"g":"";y.checked||(t+="i");let n=C.replace(/[.*+?^${}()|[\]\\]/g,"\\$&");h.checked&&(n="\\b"+n+"\\b");try{return new RegExp(n,t)}catch{return null}}function ue(t){if(!C)return void ce(!1);const n=de(!0);if(!n)return void T("Invalid search pattern.");const o=e.value,l=[];let s;for(;null!==(s=n.exec(o));)l.push({i:s.index,len:s[0].length});if(!l.length)return E.textContent="Not found",void T(`"${C}" not found.`);const a=1===t?e.selectionEnd:e.selectionStart-1;let i;i=1===t?l.find(e=>e.i>=a)||l[0]:[...l].reverse().find(e=>e.i<=a)||l[l.length-1],e.setSelectionRange(i.i,i.i+i.len),e.focus(),E.textContent=`${l.indexOf(i)+1} / ${l.length}`,function(){const t=e.value.substring(0,e.selectionStart).split("\n"),n=e.scrollHeight/Math.max(1,e.value.split("\n").length);e.scrollTop=Math.max(0,(t.length-5)*n)}(),q()}function me(){W(),b.classList.add("open"),w.value="",w.focus()}function fe(){const t=parseInt(w.value,10);if(isNaN(t)||t<1)return void T("Enter a valid line number.");const n=e.value.split("\n"),o=Math.min(t,n.length);let l=0;for(let e=0;e<o-1;e++)l+=n[e].length+1;e.setSelectionRange(l,l),e.focus(),b.classList.remove("open"),q();const s=e.scrollHeight/Math.max(1,n.length);e.scrollTop=Math.max(0,(o-5)*s),T(`Jumped to line ${o}`)}function pe(e,t,n){m.textContent=e,f.innerHTML=t,u.classList.add("open"),u.addEventListener("keydown",e=>{e.preventDefault()}),u.addEventListener("click",e=>{e.preventDefault()}),n&&n()}function ve(e){pe("About Pascar",'\n <div style="text-align:center;padding:8px 0 4px;">\n <div style="font-size:22px;font-weight:bold;margin-bottom:6px;letter-spacing:1px;">Pascar</div>\n <div style="margin-bottom:4px;font-size:14px;">Browser based offline text editor</div>\n <div style="color:#7f7f7f;font-size:12px;margin-bottom:14px;">Inspired by the classic MS-DOS editor</div>\n <div style="font-size:12px;color:#fff;line-height:1.6;">\n Runs 100% offline in your browser.<br>\n No server. No data sent anywhere.<br>\n Open &amp; save files via your local filesystem.\n </div>\n\t<div style="font-size:14px;line-height:1.6;text-align:center;">\n\t <a style="color:#295991;" href="https://github.com/potentzero/pascar" target="_blank">Source code</a>\n\t by Nirmal Kumar R.\n </div>\n <div class="dialog-buttons"><button class="btn primary" id="d-about-ok">OK</button></div>\n ',()=>{document.getElementById("d-about-ok").addEventListener("click",W)})}v.addEventListener("keydown",e=>{"Enter"===e.key&&(e.preventDefault(),e.stopPropagation(),re(),ue(e.shiftKey?-1:1)),"Escape"===e.key&&W()}),g.addEventListener("keydown",e=>{"Escape"===e.key&&W()}),document.getElementById("btn-find-next").onclick=e=>{e.preventDefault(),e.stopPropagation(),re(),ue(1)},document.getElementById("btn-find-prev").onclick=e=>{e.preventDefault(),e.stopPropagation(),re(),ue(-1)},document.getElementById("btn-replace-one").onclick=t=>{t.preventDefault(),t.stopPropagation(),re(),function(){const t=e.selectionStart,n=e.selectionEnd,o=de(!1);if(!o)return;const l=e.value.substring(t,n);o.test(l)&&(e.value=e.value.substring(0,t)+A+e.value.substring(n),e.setSelectionRange(t,t+A.length),k=!0,R());ue(1)}()},document.getElementById("btn-replace-all").onclick=t=>{t.preventDefault(),t.stopPropagation(),re(),function(){const t=de(!0);if(!t)return;const n=e.value,o=(n.match(t)||[]).length;if(!o)return E.textContent="Not found",void T(`"${C}" not found.`);e.value=n.replace(t,A),k=!0,R(),E.textContent=`Replaced ${o}`,T(`Replaced ${o} occurrence(s).`)}()},document.getElementById("btn-find-close").onclick=W,document.getElementById("goto-ok").onclick=fe,document.getElementById("goto-cancel").onclick=()=>{b.classList.remove("open"),e.focus()},w.addEventListener("keydown",t=>{"Enter"===t.key&&fe(),"Escape"===t.key&&(b.classList.remove("open"),e.focus())}),window.addEventListener("keydown",e=>{!e.ctrlKey&&!e.metaKey||"0"!==e.key&&"+"!==e.key&&"="!==e.key&&"-"!==e.key||e.preventDefault()},{capture:!0}),window.addEventListener("beforeunload",e=>{k&&(e.preventDefault(),e.returnValue="")}),"serviceWorker"in navigator&&window.addEventListener("load",()=>{navigator.serviceWorker.register("sw.js").then(e=>console.log("Service Worker Registered")).catch(e=>console.log("Registration Failed",e))})}()</script>