pinokiod 3.85.0 → 3.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/kernel/api/index.js +7 -0
  2. package/kernel/bin/caddy.js +10 -4
  3. package/kernel/peer.js +0 -3
  4. package/kernel/prototype.js +1 -0
  5. package/kernel/shell.js +43 -2
  6. package/kernel/util.js +2 -0
  7. package/package.json +1 -1
  8. package/pipe/views/login.ejs +1 -1
  9. package/server/index.js +133 -83
  10. package/server/public/common.js +534 -0
  11. package/server/public/opener.js +12 -11
  12. package/server/public/serve/style.css +1 -1
  13. package/server/public/style.css +25 -24
  14. package/server/public/urldropdown.css +473 -4
  15. package/server/public/urldropdown.js +202 -8
  16. package/server/views/404.ejs +1 -1
  17. package/server/views/500.ejs +1 -1
  18. package/server/views/app.ejs +29 -33
  19. package/server/views/bookmarklet.ejs +197 -0
  20. package/server/views/connect/x.ejs +4 -4
  21. package/server/views/connect.ejs +10 -10
  22. package/server/views/container.ejs +2 -2
  23. package/server/views/d.ejs +3 -3
  24. package/server/views/download.ejs +1 -1
  25. package/server/views/editor.ejs +1 -1
  26. package/server/views/env_editor.ejs +3 -3
  27. package/server/views/explore.ejs +2 -2
  28. package/server/views/file_explorer.ejs +2 -2
  29. package/server/views/git.ejs +7 -7
  30. package/server/views/github.ejs +3 -3
  31. package/server/views/help.ejs +2 -2
  32. package/server/views/index.ejs +5 -5
  33. package/server/views/index2.ejs +3 -3
  34. package/server/views/init/index.ejs +11 -74
  35. package/server/views/install.ejs +3 -3
  36. package/server/views/keys.ejs +2 -2
  37. package/server/views/mini.ejs +2 -2
  38. package/server/views/net.ejs +6 -6
  39. package/server/views/network.ejs +21 -21
  40. package/server/views/network2.ejs +10 -10
  41. package/server/views/old_network.ejs +8 -8
  42. package/server/views/pro.ejs +369 -0
  43. package/server/views/prototype/index.ejs +2 -2
  44. package/server/views/required_env_editor.ejs +2 -2
  45. package/server/views/review.ejs +6 -6
  46. package/server/views/screenshots.ejs +5 -4
  47. package/server/views/settings.ejs +3 -3
  48. package/server/views/setup.ejs +2 -2
  49. package/server/views/setup_home.ejs +2 -2
  50. package/server/views/share_editor.ejs +4 -4
  51. package/server/views/shell.ejs +3 -3
  52. package/server/views/start.ejs +2 -2
  53. package/server/views/task.ejs +2 -2
  54. package/server/views/terminal.ejs +5 -4
  55. package/server/views/tools.ejs +13 -13
@@ -603,4 +603,538 @@ document.addEventListener("DOMContentLoaded", () => {
603
603
  }
604
604
  })
605
605
  }
606
+
607
+ let pendingCreateLauncherDefaults = null;
608
+ let shouldCleanupCreateLauncherQuery = false;
609
+
610
+ initCreateLauncherFlow();
611
+ handleCreateLauncherQueryParams();
612
+
613
+ function openPendingCreateLauncherModal() {
614
+ if (!pendingCreateLauncherDefaults) return;
615
+ showCreateLauncherModal(pendingCreateLauncherDefaults);
616
+ pendingCreateLauncherDefaults = null;
617
+
618
+ if (!shouldCleanupCreateLauncherQuery) return;
619
+ shouldCleanupCreateLauncherQuery = false;
620
+
621
+ try {
622
+ const url = new URL(window.location.href);
623
+ Array.from(url.searchParams.keys()).forEach((key) => {
624
+ if (
625
+ key === 'create' ||
626
+ key === 'prompt' ||
627
+ key === 'folder' ||
628
+ key === 'tool' ||
629
+ key.startsWith('template.') ||
630
+ key.startsWith('template_')
631
+ ) {
632
+ url.searchParams.delete(key);
633
+ }
634
+ });
635
+ window.history.replaceState(null, '', `${url.pathname}${url.search}${url.hash}`);
636
+ } catch (error) {
637
+ console.warn('Failed to update history for create launcher params', error);
638
+ }
639
+ }
640
+
641
+ let createLauncherModalInstance = null;
642
+ let createLauncherKeydownHandler = null;
643
+
644
+ function initCreateLauncherFlow() {
645
+ const trigger = document.getElementById('create-launcher-button');
646
+ if (!trigger) return;
647
+ if (trigger.dataset.createLauncherInit === 'true') return;
648
+ trigger.dataset.createLauncherInit = 'true';
649
+
650
+ trigger.addEventListener('click', () => {
651
+ showCreateLauncherModal();
652
+ });
653
+
654
+ // If we already captured query params that request the modal, open it now that the
655
+ // trigger has been initialised and the modal can be constructed.
656
+ requestAnimationFrame(openPendingCreateLauncherModal);
657
+ }
658
+
659
+ function ensureCreateLauncherModal() {
660
+ if (createLauncherModalInstance) {
661
+ return createLauncherModalInstance;
662
+ }
663
+
664
+ const overlay = document.createElement('div');
665
+ overlay.className = 'create-launcher-modal-overlay';
666
+ overlay.style.display = 'none';
667
+
668
+ const modal = document.createElement('div');
669
+ modal.className = 'create-launcher-modal';
670
+
671
+ const header = document.createElement('div');
672
+ header.className = 'create-launcher-modal-header';
673
+
674
+ const iconWrapper = document.createElement('div');
675
+ iconWrapper.className = 'create-launcher-modal-icon';
676
+
677
+ const headerIcon = document.createElement('i');
678
+ //headerIcon.className = 'fa-solid fa-magnifying-glass';
679
+ headerIcon.className = 'fa-solid fa-wand-magic-sparkles'
680
+ iconWrapper.appendChild(headerIcon);
681
+
682
+ const headingStack = document.createElement('div');
683
+ headingStack.className = 'create-launcher-modal-headings';
684
+
685
+ const title = document.createElement('h3');
686
+ title.textContent = 'Create';
687
+
688
+ const description = document.createElement('p');
689
+ description.className = 'create-launcher-modal-description';
690
+ description.textContent = 'Create a reusable and shareable launcher for any task or any app'
691
+
692
+ headingStack.appendChild(title);
693
+ headingStack.appendChild(description);
694
+ header.appendChild(iconWrapper);
695
+ header.appendChild(headingStack);
696
+
697
+ const promptLabel = document.createElement('label');
698
+ promptLabel.className = 'create-launcher-modal-label';
699
+ promptLabel.textContent = 'What do you want to do?';
700
+
701
+ const promptTextarea = document.createElement('textarea');
702
+ promptTextarea.className = 'create-launcher-modal-textarea';
703
+ promptTextarea.placeholder = 'Examples: "a 1-click launcher for ComfyUI", "I want to change file format", "I want to clone a website to run locally", etc.';
704
+ promptLabel.appendChild(promptTextarea);
705
+
706
+ const templateWrapper = document.createElement('div');
707
+ templateWrapper.className = 'create-launcher-modal-template';
708
+ templateWrapper.style.display = 'none';
709
+
710
+ const templateTitle = document.createElement('div');
711
+ templateTitle.className = 'create-launcher-modal-template-title';
712
+ templateTitle.textContent = 'Template variables';
713
+
714
+ const templateDescription = document.createElement('p');
715
+ templateDescription.className = 'create-launcher-modal-template-description';
716
+ templateDescription.textContent = 'Fill in each variable below before creating your launcher.';
717
+
718
+ const templateFields = document.createElement('div');
719
+ templateFields.className = 'create-launcher-modal-template-fields';
720
+
721
+ templateWrapper.appendChild(templateTitle);
722
+ templateWrapper.appendChild(templateDescription);
723
+ templateWrapper.appendChild(templateFields);
724
+
725
+ const folderLabel = document.createElement('label');
726
+ folderLabel.className = 'create-launcher-modal-label';
727
+ folderLabel.textContent = 'name';
728
+
729
+ const folderInput = document.createElement('input');
730
+ folderInput.type = 'text';
731
+ folderInput.placeholder = 'example: my-launcher';
732
+ folderInput.className = 'create-launcher-modal-input';
733
+ folderLabel.appendChild(folderInput);
734
+
735
+
736
+ const toolWrapper = document.createElement('div');
737
+ toolWrapper.className = 'create-launcher-modal-tools';
738
+
739
+ const toolTitle = document.createElement('div');
740
+ toolTitle.className = 'create-launcher-modal-tools-title';
741
+ toolTitle.textContent = 'Choose AI tool';
742
+
743
+ const toolOptions = document.createElement('div');
744
+ toolOptions.className = 'create-launcher-modal-tools-options';
745
+
746
+ const tools = [
747
+ { value: 'claude', label: 'Claude Code', iconSrc: '/asset/plugin/code/claude/claude.png', defaultChecked: true },
748
+ { value: 'codex', label: 'OpenAI Codex', iconSrc: '/asset/plugin/code/codex/openai.webp', defaultChecked: false },
749
+ { value: 'gemini', label: 'Google Gemini CLI', iconSrc: '/asset/plugin/code/gemini/gemini.jpeg', defaultChecked: false }
750
+ ];
751
+
752
+ const toolEntries = [];
753
+
754
+ tools.forEach(({ value, label, iconSrc, defaultChecked }) => {
755
+ const option = document.createElement('label');
756
+ option.className = 'create-launcher-modal-tool';
757
+
758
+ const radio = document.createElement('input');
759
+ radio.type = 'radio';
760
+ radio.name = 'create-launcher-tool';
761
+ radio.value = value;
762
+ if (defaultChecked) {
763
+ radio.checked = true;
764
+ }
765
+
766
+ const badge = document.createElement('span');
767
+ badge.className = 'create-launcher-modal-tool-label';
768
+ badge.textContent = label;
769
+
770
+ option.appendChild(radio);
771
+ if (iconSrc) {
772
+ const icon = document.createElement('img');
773
+ icon.className = 'create-launcher-modal-tool-icon';
774
+ icon.src = iconSrc;
775
+ icon.alt = `${label} icon`;
776
+ icon.onerror = () => { icon.style.display='none'; }
777
+ option.appendChild(icon);
778
+ }
779
+ option.appendChild(badge);
780
+ toolOptions.appendChild(option);
781
+ toolEntries.push({ input: radio, container: option });
782
+ radio.addEventListener('change', () => {
783
+ updateToolSelections(toolEntries);
784
+ });
785
+ });
786
+
787
+ toolWrapper.appendChild(toolTitle);
788
+ toolWrapper.appendChild(toolOptions);
789
+
790
+ const error = document.createElement('div');
791
+ error.className = 'create-launcher-modal-error';
792
+
793
+ const actions = document.createElement('div');
794
+ actions.className = 'create-launcher-modal-actions';
795
+
796
+ const cancelButton = document.createElement('button');
797
+ cancelButton.type = 'button';
798
+ cancelButton.className = 'create-launcher-modal-button cancel';
799
+ cancelButton.textContent = 'Cancel';
800
+
801
+ const confirmButton = document.createElement('button');
802
+ confirmButton.type = 'button';
803
+ confirmButton.className = 'create-launcher-modal-button confirm';
804
+ confirmButton.textContent = 'Create';
805
+
806
+ actions.appendChild(cancelButton);
807
+ actions.appendChild(confirmButton);
808
+
809
+ const advancedLink = document.createElement('a');
810
+ advancedLink.className = 'create-launcher-modal-advanced';
811
+ advancedLink.href = '/init';
812
+ advancedLink.textContent = 'Or, try advanced options';
813
+
814
+ const bookmarkletLink = document.createElement('a');
815
+ bookmarkletLink.className = 'create-launcher-modal-advanced secondary';
816
+ bookmarkletLink.href = '/bookmarklet';
817
+ bookmarkletLink.target = '_blank';
818
+ bookmarkletLink.setAttribute("features", "browser")
819
+ bookmarkletLink.rel = 'noopener';
820
+ bookmarkletLink.textContent = 'Add 1-click bookmarklet';
821
+
822
+ const linkRow = document.createElement('div');
823
+ linkRow.className = 'create-launcher-modal-links';
824
+ linkRow.appendChild(advancedLink);
825
+ linkRow.appendChild(bookmarkletLink);
826
+
827
+ modal.appendChild(header);
828
+ modal.appendChild(promptLabel);
829
+ modal.appendChild(templateWrapper);
830
+ modal.appendChild(folderLabel);
831
+ modal.appendChild(toolWrapper);
832
+ modal.appendChild(error);
833
+ modal.appendChild(actions);
834
+ modal.appendChild(linkRow);
835
+ overlay.appendChild(modal);
836
+ document.body.appendChild(overlay);
837
+
838
+ let folderEditedByUser = false;
839
+ let templateValues = new Map();
840
+
841
+ function syncTemplateFields(promptText, defaults = {}) {
842
+ const variableNames = extractTemplateVariableNames(promptText);
843
+ const previousValues = templateValues;
844
+ const newValues = new Map();
845
+
846
+ variableNames.forEach((name) => {
847
+ if (Object.prototype.hasOwnProperty.call(defaults, name) && defaults[name] !== undefined) {
848
+ newValues.set(name, defaults[name]);
849
+ } else if (previousValues.has(name)) {
850
+ newValues.set(name, previousValues.get(name));
851
+ } else {
852
+ newValues.set(name, '');
853
+ }
854
+ });
855
+
856
+ templateValues = newValues;
857
+ templateFields.innerHTML = '';
858
+
859
+ if (variableNames.length === 0) {
860
+ templateWrapper.style.display = 'none';
861
+ return;
862
+ }
863
+
864
+ templateWrapper.style.display = 'flex';
865
+
866
+ variableNames.forEach((name) => {
867
+ const field = document.createElement('label');
868
+ field.className = 'create-launcher-modal-template-field';
869
+
870
+ const labelText = document.createElement('span');
871
+ labelText.className = 'create-launcher-modal-template-field-label';
872
+ labelText.textContent = name;
873
+
874
+ const input = document.createElement('input');
875
+ input.type = 'text';
876
+ input.className = 'create-launcher-modal-template-input';
877
+ input.placeholder = `Enter ${name}`;
878
+ input.value = templateValues.get(name) || '';
879
+ input.dataset.templateInput = name;
880
+ input.addEventListener('input', () => {
881
+ templateValues.set(name, input.value);
882
+ });
883
+
884
+ field.appendChild(labelText);
885
+ field.appendChild(input);
886
+ templateFields.appendChild(field);
887
+ });
888
+ }
889
+
890
+ folderInput.addEventListener('input', () => {
891
+ folderEditedByUser = true;
892
+ });
893
+
894
+ promptTextarea.addEventListener('input', () => {
895
+ syncTemplateFields(promptTextarea.value);
896
+ if (folderEditedByUser) return;
897
+ folderInput.value = generateFolderSuggestion(promptTextarea.value);
898
+ });
899
+
900
+ cancelButton.addEventListener('click', hideCreateLauncherModal);
901
+ confirmButton.addEventListener('click', submitCreateLauncherModal);
902
+ overlay.addEventListener('click', (event) => {
903
+ if (event.target === overlay) {
904
+ hideCreateLauncherModal();
905
+ }
906
+ });
907
+
908
+ advancedLink.addEventListener('click', () => {
909
+ hideCreateLauncherModal();
910
+ });
911
+
912
+ bookmarkletLink.addEventListener('click', () => {
913
+ hideCreateLauncherModal();
914
+ });
915
+
916
+ createLauncherModalInstance = {
917
+ overlay,
918
+ modal,
919
+ folderInput,
920
+ promptTextarea,
921
+ cancelButton,
922
+ confirmButton,
923
+ error,
924
+ toolEntries,
925
+ // description,
926
+ resetFolderTracking() {
927
+ folderEditedByUser = false;
928
+ },
929
+ syncTemplateFields,
930
+ getTemplateValues() {
931
+ return new Map(templateValues);
932
+ },
933
+ templateFields,
934
+ markFolderEdited() {
935
+ folderEditedByUser = true;
936
+ }
937
+ };
938
+
939
+ updateToolSelections(toolEntries);
940
+
941
+ return createLauncherModalInstance;
942
+ }
943
+
944
+ function showCreateLauncherModal(defaults = {}) {
945
+ const modal = ensureCreateLauncherModal();
946
+
947
+ modal.error.textContent = '';
948
+ modal.resetFolderTracking();
949
+ const { prompt = '', folder = '', tool = '' } = defaults;
950
+
951
+ modal.promptTextarea.value = prompt;
952
+ if (folder) {
953
+ modal.folderInput.value = folder;
954
+ if (typeof modal.markFolderEdited === 'function') {
955
+ modal.markFolderEdited();
956
+ }
957
+ } else if (prompt) {
958
+ modal.folderInput.value = generateFolderSuggestion(prompt);
959
+ } else {
960
+ modal.folderInput.value = '';
961
+ }
962
+
963
+ const matchingToolEntry = modal.toolEntries.find((entry) => entry.input.value === tool);
964
+ modal.toolEntries.forEach((entry, index) => {
965
+ entry.input.checked = matchingToolEntry ? entry === matchingToolEntry : index === 0;
966
+ });
967
+ updateToolSelections(modal.toolEntries);
968
+
969
+ modal.syncTemplateFields(modal.promptTextarea.value, defaults.templateValues || {});
970
+
971
+ modal.overlay.style.display = 'flex';
972
+
973
+ requestAnimationFrame(() => {
974
+ //modal.folderInput.focus();
975
+ modal.folderInput.select();
976
+ modal.promptTextarea.focus();
977
+ });
978
+
979
+ createLauncherKeydownHandler = (event) => {
980
+ if (event.key === 'Escape') {
981
+ event.preventDefault();
982
+ hideCreateLauncherModal();
983
+ } else if (event.key === 'Enter' && event.target === modal.folderInput) {
984
+ event.preventDefault();
985
+ submitCreateLauncherModal();
986
+ }
987
+ };
988
+
989
+ document.addEventListener('keydown', createLauncherKeydownHandler, true);
990
+ }
991
+
992
+ function hideCreateLauncherModal() {
993
+ if (!createLauncherModalInstance) return;
994
+ createLauncherModalInstance.overlay.style.display = 'none';
995
+ if (createLauncherKeydownHandler) {
996
+ document.removeEventListener('keydown', createLauncherKeydownHandler, true);
997
+ createLauncherKeydownHandler = null;
998
+ }
999
+ }
1000
+
1001
+ function submitCreateLauncherModal() {
1002
+ const modal = ensureCreateLauncherModal();
1003
+ modal.error.textContent = '';
1004
+
1005
+ const folderName = modal.folderInput.value.trim();
1006
+ const rawPrompt = modal.promptTextarea.value;
1007
+ const templateValues = modal.getTemplateValues ? modal.getTemplateValues() : new Map();
1008
+ const selectedTool = modal.toolEntries.find((entry) => entry.input.checked)?.input.value || 'claude';
1009
+
1010
+ if (!folderName) {
1011
+ debugger
1012
+ modal.error.textContent = 'Please enter a folder name.';
1013
+ modal.folderInput.focus();
1014
+ return;
1015
+ }
1016
+
1017
+ if (folderName.includes(' ')) {
1018
+ debugger
1019
+ modal.error.textContent = 'Folder names cannot contain spaces.';
1020
+ modal.folderInput.focus();
1021
+ return;
1022
+ }
1023
+
1024
+ let finalPrompt = rawPrompt;
1025
+ if (templateValues.size > 0) {
1026
+ const missingVariables = [];
1027
+ templateValues.forEach((value, name) => {
1028
+ if (!value || value.trim() === '') {
1029
+ missingVariables.push(name);
1030
+ }
1031
+ });
1032
+
1033
+ if (missingVariables.length > 0) {
1034
+ modal.error.textContent = `Please fill in values for: ${missingVariables.join(', ')}`;
1035
+ const targetInput = modal.templateFields?.querySelector(`[data-template-input="${missingVariables[0]}"]`);
1036
+ if (targetInput) {
1037
+ targetInput.focus();
1038
+ } else {
1039
+ modal.promptTextarea.focus();
1040
+ }
1041
+ return;
1042
+ }
1043
+
1044
+ finalPrompt = applyTemplateValues(rawPrompt, templateValues);
1045
+ }
1046
+
1047
+ const prompt = finalPrompt.trim();
1048
+
1049
+ if (!prompt) {
1050
+ debugger
1051
+ modal.error.textContent = 'Please enter a prompt.';
1052
+ modal.promptTextarea.focus();
1053
+ return;
1054
+ }
1055
+
1056
+ const url = `/pro?name=${encodeURIComponent(folderName)}&message=${encodeURIComponent(prompt)}&tool=${encodeURIComponent(selectedTool)}`;
1057
+ hideCreateLauncherModal();
1058
+ window.location.href = url;
1059
+ }
1060
+
1061
+ function handleCreateLauncherQueryParams() {
1062
+ const params = new URLSearchParams(window.location.search);
1063
+ if (!params.has('create')) return;
1064
+
1065
+ const defaults = {};
1066
+ const templateDefaults = {};
1067
+
1068
+ const promptParam = params.get('prompt');
1069
+ if (promptParam) defaults.prompt = promptParam.trim();
1070
+
1071
+ const folderParam = params.get('folder');
1072
+ if (folderParam) defaults.folder = folderParam.trim();
1073
+
1074
+ const toolParam = params.get('tool');
1075
+ if (toolParam) defaults.tool = toolParam.trim();
1076
+
1077
+ params.forEach((value, key) => {
1078
+ if (key.startsWith('template.') || key.startsWith('template_')) {
1079
+ const name = key.replace(/^template[._]/, '');
1080
+ if (name) {
1081
+ templateDefaults[name] = value ? value.trim() : '';
1082
+ }
1083
+ }
1084
+ });
1085
+
1086
+ if (Object.keys(templateDefaults).length > 0) {
1087
+ defaults.templateValues = templateDefaults;
1088
+ }
1089
+
1090
+ pendingCreateLauncherDefaults = defaults;
1091
+ shouldCleanupCreateLauncherQuery = true;
1092
+
1093
+ requestAnimationFrame(openPendingCreateLauncherModal);
1094
+ }
1095
+
1096
+ function generateFolderSuggestion(prompt) {
1097
+ if (!prompt) return '';
1098
+ return prompt
1099
+ .toLowerCase()
1100
+ .replace(/[^a-z0-9\-\s_]/g, '')
1101
+ .replace(/[\s_]+/g, '-')
1102
+ .replace(/^-+|-+$/g, '')
1103
+ .slice(0, 50);
1104
+ }
1105
+
1106
+ function updateToolSelections(entries) {
1107
+ entries.forEach(({ input, container }) => {
1108
+ if (input.checked) {
1109
+ container.classList.add('selected');
1110
+ } else {
1111
+ container.classList.remove('selected');
1112
+ }
1113
+ });
1114
+ }
1115
+
1116
+ function extractTemplateVariableNames(template) {
1117
+ const regex = /{{\s*([a-zA-Z0-9_][a-zA-Z0-9_\-.]*)\s*}}/g;
1118
+ const names = new Set();
1119
+ if (!template) return [];
1120
+ let match;
1121
+ while ((match = regex.exec(template)) !== null) {
1122
+ names.add(match[1]);
1123
+ }
1124
+ return Array.from(names);
1125
+ }
1126
+
1127
+ function escapeRegExp(str) {
1128
+ return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
1129
+ }
1130
+
1131
+ function applyTemplateValues(template, values) {
1132
+ if (!template) return '';
1133
+ let result = template;
1134
+ values.forEach((value, name) => {
1135
+ const pattern = new RegExp(`{{\\s*${escapeRegExp(name)}\\s*}}`, 'g');
1136
+ result = result.replace(pattern, value);
1137
+ });
1138
+ return result;
1139
+ }
606
1140
  })
@@ -6,19 +6,20 @@ const open_url = (href, target, features) => {
6
6
  // - otherwise => open in a regular browser
7
7
  if (features && features.includes("pinokio")) {
8
8
  window.open(href, "_blank", features)
9
+ } else if (features && features.includes("browser")) {
10
+ fetch("/go", {
11
+ method: "POST",
12
+ headers: {
13
+ "Content-Type": "application/json"
14
+ },
15
+ body: JSON.stringify({ url: href })
16
+ }).then((res) => {
17
+ return res.json()
18
+ }).then((res) => {
19
+ console.log(res)
20
+ })
9
21
  } else {
10
22
  window.open(href, "_blank", features)
11
- //fetch("/go", {
12
- // method: "POST",
13
- // headers: {
14
- // "Content-Type": "application/json"
15
- // },
16
- // body: JSON.stringify({ url: href })
17
- //}).then((res) => {
18
- // return res.json()
19
- //}).then((res) => {
20
- // console.log(res)
21
- //})
22
23
  }
23
24
  } else {
24
25
  // no target => just move from the same window
@@ -123,7 +123,7 @@ ul#files li a.highlight {
123
123
  border-color: #E9DC51;
124
124
  */
125
125
  background: aliceblue;
126
- color: royalblue;
126
+ color: rgba(127, 91, 243, 0.9);
127
127
  font-weight: bold;
128
128
  }
129
129
  #open {