h(t,e))))(t),N=("li",t=>g(t)&&"li"===t.dom.nodeName.toLowerCase());const A=(t,e,n)=>{u(e,(e=>{const c=d(e),m=N(c),f=((t,e)=>{return(e?(o=t,r="ol,ul",((t,e,o)=>{let n=t.dom;const s=i(o)?o:l;for(;n.parentNode;){n=n.parentNode;const t=d(n);if(h(t,r))return a.some(t);if(s(t))break}return a.none()})(o,0,n)):a.some(t)).getOr(t);var o,r,n})(c,m);var v;(v=f,(t=>a.from(t.dom.parentNode).map(d))(v).filter(g)).each((e=>{if(t.setStyle(f.dom,"direction",null),b(e)===n?y(f,"dir"):((t,e,n)=>{((t,e,n)=>{if(!(o(n)||r(n)||s(n)))throw console.error("Invalid call to Attribute.set. Key ",e,":: Value ",n,":: Element ",t),new Error("Attribute value was not simple");t.setAttribute(e,n+"")})(t.dom,e,n)})(f,"dir",n),b(f)!==n&&t.setStyle(f.dom,"direction",n),m){const e=S(f,"li[dir],li[style]");u(e,(e=>{y(e,"dir"),t.setStyle(e.dom,"direction",null)}))}}))}))},T=(t,e)=>{t.selection.isEditable()&&(A(t.dom,t.selection.getSelectedBlocks(),e),t.nodeChanged())},C=(t,e)=>o=>{const r=r=>{const n=d(r.element);o.setActive(b(n)===e),o.setEnabled(t.selection.isEditable())};return t.on("NodeChange",r),o.setEnabled(t.selection.isEditable()),()=>t.off("NodeChange",r)};t.add("directionality",(t=>{(t=>{t.addCommand("mceDirectionLTR",(()=>{T(t,"ltr")})),t.addCommand("mceDirectionRTL",(()=>{T(t,"rtl")}))})(t),(t=>{t.ui.registry.addToggleButton("ltr",{tooltip:"Left to right",icon:"ltr",onAction:()=>t.execCommand("mceDirectionLTR"),onSetup:C(t,"ltr")}),t.ui.registry.addToggleButton("rtl",{tooltip:"Right to left",icon:"rtl",onAction:()=>t.execCommand("mceDirectionRTL"),onSetup:C(t,"rtl")})})(t)}))}();
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/da.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.da',
2 | 'Start tastaturnavigation \n' +
3 | '\n' +
4 | '\n' +
5 | ' Fokuser på menulinjen \n' +
6 | ' Windows eller Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' Fokuser på værktøjslinjen \n' +
9 | ' Windows eller Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' Fokuser på sidefoden \n' +
12 | ' Windows eller Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' Fokuser på meddelelsen \n' +
15 | ' Windows eller Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' Fokuser på kontekstuel værktøjslinje \n' +
18 | ' Windows, Linux eller macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'Navigationen starter ved det første UI-element, som fremhæves eller understreges hvad angår det første element i\n' +
22 | ' sidefodens sti til elementet.
\n' +
23 | '\n' +
24 | 'Naviger mellem UI-sektioner \n' +
25 | '\n' +
26 | 'Gå fra én UI-sektion til den næste ved at trykke på Tab .
\n' +
27 | '\n' +
28 | 'Gå fra én UI-sektion til den forrige ved at trykke på Shift+Tab .
\n' +
29 | '\n' +
30 | 'Tab -rækkefølgen af disse UI-sektioner er:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' Menulinje \n' +
34 | ' Hver værktøjsgruppe \n' +
35 | ' Sidepanel \n' +
36 | ' Sti til elementet i sidefoden \n' +
37 | ' Til/fra-knap for ordoptælling i sidefoden \n' +
38 | ' Brandinglink i sidefoden \n' +
39 | ' Tilpasningshåndtag for editor i sidefoden \n' +
40 | ' \n' +
41 | '\n' +
42 | 'Hvis en UI-sektion ikke er til stede, springes den over.
\n' +
43 | '\n' +
44 | 'Hvis sidefoden har fokus til tastaturnavigation, og der ikke er noget synligt sidepanel, kan der trykkes på Shift+Tab \n' +
45 | ' for at flytte fokus til den første værktøjsgruppe, ikke den sidste.
\n' +
46 | '\n' +
47 | 'Naviger inden for UI-sektioner \n' +
48 | '\n' +
49 | 'Gå fra ét UI-element til det næste ved at trykke på den relevante piletast .
\n' +
50 | '\n' +
51 | 'Venstre og højre piletast
\n' +
52 | '\n' +
53 | '\n' +
54 | ' flytter mellem menuerne i menulinjen. \n' +
55 | ' åbner en undermenu i en menu. \n' +
56 | ' flytter mellem knapperne i en værktøjsgruppe. \n' +
57 | ' flytter mellem elementer i sidefodens sti til elementet. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'Pil ned og op
\n' +
61 | '\n' +
62 | '\n' +
63 | ' flytter mellem menupunkterne i en menu. \n' +
64 | ' flytter mellem punkterne i en genvejsmenu i værktøjslinjen. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'Piletasterne kører rundt inden for UI-sektionen, der fokuseres på.
\n' +
68 | '\n' +
69 | 'For at lukke en åben menu, en åben undermenu eller en åben genvejsmenu trykkes der på Esc -tasten.
\n' +
70 | '\n' +
71 | "Hvis det aktuelle fokus er i 'toppen' af en bestemt UI-sektion, vil tryk på Esc -tasten også afslutte\n" +
72 | ' tastaturnavigationen helt.
\n' +
73 | '\n' +
74 | 'Udfør et menupunkt eller en værktøjslinjeknap \n' +
75 | '\n' +
76 | 'Når det ønskede menupunkt eller den ønskede værktøjslinjeknap er fremhævet, trykkes der på Retur , Enter \n' +
77 | ' eller mellemrumstasten for at udføre elementet.
\n' +
78 | '\n' +
79 | 'Naviger i ikke-faneopdelte dialogbokse \n' +
80 | '\n' +
81 | 'I ikke-faneopdelte dialogbokse får den første interaktive komponent fokus, når dialogboksen åbnes.
\n' +
82 | '\n' +
83 | 'Naviger mellem interaktive dialogbokskomponenter ved at trykke på Tab eller Shift+Tab .
\n' +
84 | '\n' +
85 | 'Naviger i faneopdelte dialogbokse \n' +
86 | '\n' +
87 | 'I faneopdelte dialogbokse får den første knap i fanemenuen fokus, når dialogboksen åbnes.
\n' +
88 | '\n' +
89 | 'Naviger mellem interaktive komponenter i denne dialogboksfane ved at trykke på Tab eller\n' +
90 | ' Shift+Tab .
\n' +
91 | '\n' +
92 | 'Skift til en anden dialogboksfane ved at fokusere på fanemenuen og derefter trykke på den relevante piletast \n' +
93 | ' for at køre igennem de tilgængelige faner.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/en.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.en',
2 | 'Begin keyboard navigation \n' +
3 | '\n' +
4 | '\n' +
5 | ' Focus the Menu bar \n' +
6 | ' Windows or Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' Focus the Toolbar \n' +
9 | ' Windows or Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' Focus the footer \n' +
12 | ' Windows or Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' Focus the notification \n' +
15 | ' Windows or Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' Focus a contextual toolbar \n' +
18 | ' Windows, Linux or macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'Navigation will start at the first UI item, which will be highlighted, or underlined in the case of the first item in\n' +
22 | ' the Footer element path.
\n' +
23 | '\n' +
24 | 'Navigate between UI sections \n' +
25 | '\n' +
26 | 'To move from one UI section to the next, press Tab .
\n' +
27 | '\n' +
28 | 'To move from one UI section to the previous, press Shift+Tab .
\n' +
29 | '\n' +
30 | 'The Tab order of these UI sections is:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' Menu bar \n' +
34 | ' Each toolbar group \n' +
35 | ' Sidebar \n' +
36 | ' Element path in the footer \n' +
37 | ' Word count toggle button in the footer \n' +
38 | ' Branding link in the footer \n' +
39 | ' Editor resize handle in the footer \n' +
40 | ' \n' +
41 | '\n' +
42 | 'If a UI section is not present, it is skipped.
\n' +
43 | '\n' +
44 | 'If the footer has keyboard navigation focus, and there is no visible sidebar, pressing Shift+Tab \n' +
45 | ' moves focus to the first toolbar group, not the last.
\n' +
46 | '\n' +
47 | 'Navigate within UI sections \n' +
48 | '\n' +
49 | 'To move from one UI element to the next, press the appropriate Arrow key.
\n' +
50 | '\n' +
51 | 'The Left and Right arrow keys
\n' +
52 | '\n' +
53 | '\n' +
54 | ' move between menus in the menu bar. \n' +
55 | ' open a sub-menu in a menu. \n' +
56 | ' move between buttons in a toolbar group. \n' +
57 | ' move between items in the footer’s element path. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'The Down and Up arrow keys
\n' +
61 | '\n' +
62 | '\n' +
63 | ' move between menu items in a menu. \n' +
64 | ' move between items in a toolbar pop-up menu. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'Arrow keys cycle within the focused UI section.
\n' +
68 | '\n' +
69 | 'To close an open menu, an open sub-menu, or an open pop-up menu, press the Esc key.
\n' +
70 | '\n' +
71 | 'If the current focus is at the ‘top’ of a particular UI section, pressing the Esc key also exits\n' +
72 | ' keyboard navigation entirely.
\n' +
73 | '\n' +
74 | 'Execute a menu item or toolbar button \n' +
75 | '\n' +
76 | 'When the desired menu item or toolbar button is highlighted, press Return , Enter ,\n' +
77 | ' or the Space bar to execute the item.
\n' +
78 | '\n' +
79 | 'Navigate non-tabbed dialogs \n' +
80 | '\n' +
81 | 'In non-tabbed dialogs, the first interactive component takes focus when the dialog opens.
\n' +
82 | '\n' +
83 | 'Navigate between interactive dialog components by pressing Tab or Shift+Tab .
\n' +
84 | '\n' +
85 | 'Navigate tabbed dialogs \n' +
86 | '\n' +
87 | 'In tabbed dialogs, the first button in the tab menu takes focus when the dialog opens.
\n' +
88 | '\n' +
89 | 'Navigate between interactive components of this dialog tab by pressing Tab or\n' +
90 | ' Shift+Tab .
\n' +
91 | '\n' +
92 | 'Switch to another dialog tab by giving the tab menu focus and then pressing the appropriate Arrow \n' +
93 | ' key to cycle through the available tabs.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/fa.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.fa',
2 | 'شروع پیمایش صفحهکلید \n' +
3 | '\n' +
4 | '\n' +
5 | ' تمرکز بر نوار منو \n' +
6 | ' Windows یا Linux:: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' تمرکز بر نوار ابزار \n' +
9 | ' Windows یا Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' تمرکز بر پانویس \n' +
12 | ' Windows یا Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' تمرکز اعلان \n' +
15 | ' ویندوز یا لینوکس: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' تمرکز بر نوار ابزار بافتاری \n' +
18 | ' Windows ،Linux یا macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'پیمایش در اولین مورد رابط کاربری شروع میشود و درخصوص اولین مورد در\n' +
22 | ' مسیر عنصر پانویس، برجسته یا زیرخطدار میشود.
\n' +
23 | '\n' +
24 | 'پیمایش بین بخشهای رابط کاربری \n' +
25 | '\n' +
26 | 'برای جابجایی از یک بخش رابط کاربری به بخش بعدی، Tab را فشار دهید.
\n' +
27 | '\n' +
28 | 'برای جابجایی از یک بخش رابط کاربری به بخش قبلی، Shift+Tab را فشار دهید.
\n' +
29 | '\n' +
30 | 'ترتیب Tab این بخشهای رابط کاربری عبارتند از:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' نوار منو \n' +
34 | ' هر گروه نوار ابزار \n' +
35 | ' نوار کناری \n' +
36 | ' مسیر عنصر در پانویس \n' +
37 | ' دکمه تغییر وضعیت تعداد کلمات در پانویس \n' +
38 | ' پیوند نمانامسازی در پانویس \n' +
39 | ' دسته تغییر اندازه ویرایشگر در پانویس \n' +
40 | ' \n' +
41 | '\n' +
42 | 'اگر بخشی از رابط کاربری موجود نباشد، رد میشود.
\n' +
43 | '\n' +
44 | 'اگر پانویس دارای تمرکز بر پیمایش صفحهکلید باشد، و نوار کناری قابلمشاهده وجود ندارد، فشردن Shift+Tab \n' +
45 | ' تمرکز را به گروه نوار ابزار اول میبرد، نه آخر.
\n' +
46 | '\n' +
47 | 'پیمایش در بخشهای رابط کاربری \n' +
48 | '\n' +
49 | 'برای جابجایی از یک عنصر رابط کاربری به بعدی، کلید جهتنمای مناسب را فشار دهید.
\n' +
50 | '\n' +
51 | 'کلیدهای جهتنمای چپ و راست
\n' +
52 | '\n' +
53 | '\n' +
54 | ' جابجایی بین منوها در نوار منو. \n' +
55 | ' باز کردن منوی فرعی در یک منو. \n' +
56 | ' جابجایی بین دکمهها در یک گروه نوار ابزار. \n' +
57 | ' جابجایی بین موارد در مسیر عنصر پانویس. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'کلیدهای جهتنمای پایین و بالا
\n' +
61 | '\n' +
62 | '\n' +
63 | ' جابجایی بین موارد منو در یک منو. \n' +
64 | ' جابجایی بین موارد در یک منوی بازشوی نوار ابزار. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'کلیدهایجهتنما در بخش رابط کاربری متمرکز میچرخند.
\n' +
68 | '\n' +
69 | 'برای بستن یک منوی باز، یک منوی فرعی باز، یا یک منوی بازشوی باز، کلید Esc را فشار دهید.
\n' +
70 | '\n' +
71 | 'اگر تمرکز فعلی در «بالای» یک بخش رابط کاربری خاص است، فشردن کلید Esc نیز موجب\n' +
72 | ' خروج کامل از پیمایش صفحهکلید میشود.
\n' +
73 | '\n' +
74 | 'اجرای یک مورد منو یا دکمه نوار ابزار \n' +
75 | '\n' +
76 | 'وقتی مورد منو یا دکمه نوار ابزار مورد نظر هایلایت شد، دکمه بازگشت ، Enter ،\n' +
77 | ' یا نوار Space را فشار دهید تا مورد را اجرا کنید.
\n' +
78 | '\n' +
79 | 'پیمایش در کادرهای گفتگوی بدون زبانه \n' +
80 | '\n' +
81 | 'در کادرهای گفتگوی بدون زبانه، وقتی کادر گفتگو باز میشود، اولین جزء تعاملی متمرکز میشود.
\n' +
82 | '\n' +
83 | 'با فشردن Tab یا Shift+Tab ، بین اجزای کادر گفتگوی تعاملی پیمایش کنید.
\n' +
84 | '\n' +
85 | 'پیمایش کادرهای گفتگوی زبانهدار \n' +
86 | '\n' +
87 | 'در کادرهای گفتگوی زبانهدار، وقتی کادر گفتگو باز میشود، اولین دکمه در منوی زبانه متمرکز میشود.
\n' +
88 | '\n' +
89 | 'با فشردن Tab یا\n' +
90 | ' Shift+Tab ، بین اجزای تعاملی این زبانه کادر گفتگو پیمایش کنید.
\n' +
91 | '\n' +
92 | 'با دادن تمرکز به منوی زبانه و سپس فشار دادن کلید جهتنمای \n' +
93 | ' مناسب برای چرخش میان زبانههای موجود، به زبانه کادر گفتگوی دیگری بروید.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/he_IL.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.he_IL',
2 | 'התחל ניווט במקלדת \n' +
3 | '\n' +
4 | '\n' +
5 | ' התמקד בשורת התפריטים \n' +
6 | ' Windows או Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' העבר מיקוד לסרגל הכלים \n' +
9 | ' Windows או Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' העבר מיקוד לכותרת התחתונה \n' +
12 | ' Windows או Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' העבר מיקוד להודעה \n' +
15 | ' Windows או Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' העבר מיקוד לסרגל כלים הקשרי \n' +
18 | ' Windows, Linux או macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'הניווט יתחיל ברכיב הראשון במשך, שיודגש או שיהיה מתחתיו קו תחתון במקרה של הפריט הראשון\n' +
22 | ' הנתיב של רכיב הכותרת התחתונה.
\n' +
23 | '\n' +
24 | 'עבור בין מקטעים במסך \n' +
25 | '\n' +
26 | 'כדי לעבור בין המקטעים במסך, הקש Tab .
\n' +
27 | '\n' +
28 | 'כדי לעבור למקטע הקודם במסך, הקש Shift+Tab .
\n' +
29 | '\n' +
30 | 'הסדר מבחינת מקש Tab של הרכיבים במסך:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' שורת התפריטים \n' +
34 | ' כל קבוצה בסרגל הכלים \n' +
35 | ' הסרגל הצידי \n' +
36 | ' נתיב של רכיב בכותרת התחתונה \n' +
37 | ' לחצן לספירת מילים בכותרת התחתונה \n' +
38 | ' קישור של המותג בכותרת התחתונה \n' +
39 | ' ידית לשינוי גודל עבור העורך בכותרת התחתונה \n' +
40 | ' \n' +
41 | '\n' +
42 | 'אם רכיב כלשהו במסך לא מופיע, המערכת תדלג עליו.
\n' +
43 | '\n' +
44 | 'אם בכותרת התחתונה יש מיקוד של ניווט במקלדת, ולא מופיע סרגל בצד, יש להקיש Shift+Tab \n' +
45 | ' מעביר את המיקוד לקבוצה הראשונה בסרגל הכלים, לא האחרונה.
\n' +
46 | '\n' +
47 | 'עבור בתוך מקטעים במסך \n' +
48 | '\n' +
49 | 'כדי לעבור מרכיב אחד לרכיב אחר במסך, הקש על מקש החץ המתאים.
\n' +
50 | '\n' +
51 | 'מקשי החיצים שמאלה וימינה
\n' +
52 | '\n' +
53 | '\n' +
54 | ' עבור בין תפריטים בשורת התפריטים. \n' +
55 | ' פתח תפריט משני בתפריט. \n' +
56 | ' עבור בין לחצנים בקבוצה בסרגל הכלים. \n' +
57 | ' עבור בין פריטים ברכיב בכותרת התחתונה. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'מקשי החיצים למטה ולמעלה
\n' +
61 | '\n' +
62 | '\n' +
63 | ' עבור בין פריטים בתפריט. \n' +
64 | ' עבור בין פריטים בחלון הקובץ של סרגל הכלים. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'מקשי החצים משתנים בתוך המקטע במסך שעליו נמצא המיקוד.
\n' +
68 | '\n' +
69 | 'כדי לסגור תפריט פתוח, תפריט משני פתוח או חלון קופץ, הקש על Esc .
\n' +
70 | '\n' +
71 | "אם המיקוד הוא על החלק 'העליון' של מקטע מסוים במסך, הקשה על Esc מביאה גם ליציאה\n" +
72 | ' מהניווט במקלדת לחלוטין.
\n' +
73 | '\n' +
74 | 'הפעל פריט בתפריט או לחצן בסרגל הכלים \n' +
75 | '\n' +
76 | 'כאשר הפריט הרצוי בתפריט או הלחצן בסרגל הכלים מודגשים, הקש על Return , Enter ,\n' +
77 | ' או על מקש הרווח כדי להפעיל את הפריט.
\n' +
78 | '\n' +
79 | 'ניווט בחלונות דו-שיח בלי כרטיסיות \n' +
80 | '\n' +
81 | 'בחלונות דו-שיח בלי כרטיסיות, הרכיב האינטראקטיבי הראשון מקבל את המיקוד כאשר החלון נפתח.
\n' +
82 | '\n' +
83 | 'עבור בין רכיבים אינטראקטיביים בחלון על ידי הקשה על Tab או Shift+Tab .
\n' +
84 | '\n' +
85 | 'ניווט בחלונות דו-שיח עם כרטיסיות \n' +
86 | '\n' +
87 | 'בחלונות דו-שיח עם כרטיסיות, הלחצן הראשון בתפריט מקבל את המיקוד כאשר החלון נפתח.
\n' +
88 | '\n' +
89 | 'עבור בין רכיבים אינטראקטיביים בחלון על ידי הקשה על Tab או\n' +
90 | ' Shift+Tab .
\n' +
91 | '\n' +
92 | 'עבור לכרטיסיה אחרת בחלון על ידי העברת המיקוד לתפריט הכרטיסיות והקשה על החץ המתאים\n' +
93 | ' כדי לעבור בין הכרטיסיות הזמינות.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/hi.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.hi',
2 | 'कीबोर्ड नेविगेशन शुरू करें \n' +
3 | '\n' +
4 | '\n' +
5 | ' मेन्यू बार पर फ़ोकस करें \n' +
6 | ' Windows या Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' टूलबार पर फ़ोकस करें \n' +
9 | ' Windows या Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' फ़ुटर पर फ़ोकस करें \n' +
12 | ' Windows या Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' नोटिफ़िकेशन फ़ोकस \n' +
15 | ' Windows या Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' प्रासंगिक टूलबार पर फ़ोकस करें \n' +
18 | ' Windows, Linux या macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'नेविगेशन पहले UI आइटम पर शुरू होगा, जिसे हाइलाइट किया जाएगा या पहले आइटम के मामले में फ़ुटर तत्व पथ में\n' +
22 | ' रेखांकित किया जाएगा।
\n' +
23 | '\n' +
24 | 'UI सेक्शन के बीच नेविगेट करें \n' +
25 | '\n' +
26 | 'एक UI सेक्शन से दूसरे सेक्शन में जाने के लिए, Tab दबाएं।
\n' +
27 | '\n' +
28 | 'एक UI सेक्शन से पिछले सेक्शन में जाने के लिए, Shift+Tab दबाएं।
\n' +
29 | '\n' +
30 | 'इन UI सेक्शन का Tab क्रम नीचे दिया गया है:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' मेन्यू बार \n' +
34 | ' प्रत्येक टूलबार समूह \n' +
35 | ' साइडबार \n' +
36 | ' फ़ुटर में तत्व पथ \n' +
37 | ' फ़ुटर में शब्द गणना टॉगल बटन \n' +
38 | ' फ़ुटर में ब्रांडिंग लिंक \n' +
39 | ' फ़ुटर में संपादक का आकार बदलने का हैंडल \n' +
40 | ' \n' +
41 | '\n' +
42 | 'अगर कोई UI सेक्शन मौजूद नहीं है, तो उसे छोड़ दिया जाता है।
\n' +
43 | '\n' +
44 | 'अगर फ़ुटर में कीबोर्ड नेविगेशन फ़ोकस है, और कोई दिखा देने वाला साइडबार नहीं है, तो Shift+Tab दबाने से\n' +
45 | ' फ़ोकस पहले टूलबार समूह पर चला जाता है, पिछले पर नहीं।
\n' +
46 | '\n' +
47 | 'UI सेक्शन के भीतर नेविगेट करें \n' +
48 | '\n' +
49 | 'एक UI तत्व से दूसरे में जाने के लिए उपयुक्त ऐरो कुंजी दबाएं।
\n' +
50 | '\n' +
51 | 'बाएं और दाएं ऐरो कुंजियां
\n' +
52 | '\n' +
53 | '\n' +
54 | ' मेन्यू बार में मेन्यू के बीच ले जाती हैं। \n' +
55 | ' मेन्यू में एक सब-मेन्यू खोलें। \n' +
56 | ' टूलबार समूह में बटनों के बीच ले जाएं। \n' +
57 | ' फ़ुटर के तत्व पथ में आइटम के बीच ले जाएं। \n' +
58 | ' \n' +
59 | '\n' +
60 | 'नीचे और ऊपर ऐरो कुंजियां
\n' +
61 | '\n' +
62 | '\n' +
63 | ' मेन्यू में मेन्यू आइटम के बीच ले जाती हैं। \n' +
64 | ' टूलबार पॉप-अप मेन्यू में आइटम के बीच ले जाएं। \n' +
65 | ' \n' +
66 | '\n' +
67 | 'फ़ोकस वाले UI सेक्शन के भीतर ऐरो कुंजियां चलाती रहती हैं।
\n' +
68 | '\n' +
69 | 'कोई खुला मेन्यू, कोई खुला सब-मेन्यू या कोई खुला पॉप-अप मेन्यू बंद करने के लिए Esc कुंजी दबाएं।
\n' +
70 | '\n' +
71 | "अगर मौजूदा फ़ोकस किसी विशेष UI सेक्शन के 'शीर्ष' पर है, तो Esc कुंजी दबाने से भी\n" +
72 | ' कीबोर्ड नेविगेशन पूरी तरह से बाहर हो जाता है।
\n' +
73 | '\n' +
74 | 'मेन्यू आइटम या टूलबार बटन निष्पादित करें \n' +
75 | '\n' +
76 | 'जब वांछित मेन्यू आइटम या टूलबार बटन हाइलाइट किया जाता है, तो आइटम को निष्पादित करने के लिए Return , Enter ,\n' +
77 | ' या Space bar दबाएं।
\n' +
78 | '\n' +
79 | 'गैर-टैब वाले डायलॉग पर नेविगेट करें \n' +
80 | '\n' +
81 | 'गैर-टैब वाले डायलॉग में, डायलॉग खुलने पर पहला इंटरैक्टिव घटक फ़ोकस लेता है।
\n' +
82 | '\n' +
83 | 'Tab or Shift+Tab दबाकर इंटरैक्टिव डायलॉग घटकों के बीच नेविगेट करें।
\n' +
84 | '\n' +
85 | 'टैब किए गए डायलॉग पर नेविगेट करें \n' +
86 | '\n' +
87 | 'टैब किए गए डायलॉग में, डायलॉग खुलने पर टैब मेन्यू में पहला बटन फ़ोकस लेता है।
\n' +
88 | '\n' +
89 | 'इस डायलॉग टैब के इंटरैक्टिव घटकों के बीच नेविगेट करने के लिए Tab या\n' +
90 | ' Shift+Tab दबाएं।
\n' +
91 | '\n' +
92 | 'टैब मेन्यू को फ़ोकस देकर और फिर उपलब्ध टैब में के बीच जाने के लिए उपयुक्त ऐरो \n' +
93 | ' कुंजी दबाकर दूसरे डायलॉग टैब पर स्विच करें।
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/ja.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.ja',
2 | 'キーボード ナビゲーションの開始 \n' +
3 | '\n' +
4 | '\n' +
5 | ' メニュー バーをフォーカス \n' +
6 | ' Windows または Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' ツール バーをフォーカス \n' +
9 | ' Windows または Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' フッターをフォーカス \n' +
12 | ' Windows または Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' 通知にフォーカス \n' +
15 | ' Windows または Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' コンテキスト ツール バーをフォーカス \n' +
18 | ' Windows、Linux または macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'ナビゲーションは最初の UI 項目から開始され、強調表示されるか、フッターの要素パスにある最初の項目の場合は\n' +
22 | ' 下線が引かれます。
\n' +
23 | '\n' +
24 | 'UI セクション間の移動 \n' +
25 | '\n' +
26 | '次の UI セクションに移動するには、Tab を押します。
\n' +
27 | '\n' +
28 | '前の UI セクションに移動するには、Shift+Tab を押します。
\n' +
29 | '\n' +
30 | 'これらの UI セクションの Tab の順序:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' メニュー バー \n' +
34 | ' 各ツール バー グループ \n' +
35 | ' サイド バー \n' +
36 | ' フッターの要素パス \n' +
37 | ' フッターの単語数切り替えボタン \n' +
38 | ' フッターのブランド リンク \n' +
39 | ' フッターのエディター サイズ変更ハンドル \n' +
40 | ' \n' +
41 | '\n' +
42 | 'UI セクションが存在しない場合は、スキップされます。
\n' +
43 | '\n' +
44 | 'フッターにキーボード ナビゲーション フォーカスがあり、表示可能なサイド バーがない場合、Shift+Tab を押すと、\n' +
45 | ' フォーカスが最後ではなく最初のツール バー グループに移動します。
\n' +
46 | '\n' +
47 | 'UI セクション内の移動 \n' +
48 | '\n' +
49 | '次の UI 要素に移動するには、適切な矢印 キーを押します。
\n' +
50 | '\n' +
51 | '左矢印 と右矢印 のキー
\n' +
52 | '\n' +
53 | '\n' +
54 | ' メニュー バーのメニュー間で移動します。 \n' +
55 | ' メニュー内のサブメニューを開きます。 \n' +
56 | ' ツール バー グループのボタン間で移動します。 \n' +
57 | ' フッターの要素パスの項目間で移動します。 \n' +
58 | ' \n' +
59 | '\n' +
60 | '下矢印 と上矢印 のキー
\n' +
61 | '\n' +
62 | '\n' +
63 | ' メニュー内のメニュー項目間で移動します。 \n' +
64 | ' ツール バー ポップアップ メニュー内のメニュー項目間で移動します。 \n' +
65 | ' \n' +
66 | '\n' +
67 | '矢印 キーで、フォーカスされた UI セクション内で循環します。
\n' +
68 | '\n' +
69 | '開いたメニュー、開いたサブメニュー、開いたポップアップ メニューを閉じるには、Esc キーを押します。
\n' +
70 | '\n' +
71 | '現在のフォーカスが特定の UI セクションの「一番上」にある場合、Esc キーを押すと\n' +
72 | ' キーボード ナビゲーションも完全に閉じられます。
\n' +
73 | '\n' +
74 | 'メニュー項目またはツール バー ボタンの実行 \n' +
75 | '\n' +
76 | '目的のメニュー項目やツール バー ボタンが強調表示されている場合、リターン 、Enter 、\n' +
77 | ' またはスペース キー を押して項目を実行します。
\n' +
78 | '\n' +
79 | 'タブのないダイアログの移動 \n' +
80 | '\n' +
81 | 'タブのないダイアログでは、ダイアログが開くと最初の対話型コンポーネントがフォーカスされます。
\n' +
82 | '\n' +
83 | 'Tab または Shift+Tab を押して、対話型ダイアログ コンポーネント間で移動します。
\n' +
84 | '\n' +
85 | 'タブ付きダイアログの移動 \n' +
86 | '\n' +
87 | 'タブ付きダイアログでは、ダイアログが開くとタブ メニューの最初のボタンがフォーカスされます。
\n' +
88 | '\n' +
89 | 'Tab または\n' +
90 | ' Shift+Tab を押して、このダイアログ タブの対話型コンポーネント間で移動します。
\n' +
91 | '\n' +
92 | 'タブ メニューをフォーカスしてから適切な矢印 キーを押して表示可能なタブを循環して、\n' +
93 | ' 別のダイアログに切り替えます。
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/ko_KR.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.ko_KR',
2 | '키보드 탐색 시작 \n' +
3 | '\n' +
4 | '\n' +
5 | ' 메뉴 모음 포커스 표시 \n' +
6 | ' Windows 또는 Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' 도구 모음 포커스 표시 \n' +
9 | ' Windows 또는 Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' 푸터 포커스 표시 \n' +
12 | ' Windows 또는 Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' 알림 포커스 \n' +
15 | ' Windows 또는 Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' 컨텍스트 도구 모음에 포커스 표시 \n' +
18 | ' Windows, Linux 또는 macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | '첫 번째 UI 항목에서 탐색이 시작되며, 이때 첫 번째 항목이 강조 표시되거나 푸터 요소 경로에 있는\n' +
22 | ' 경우 밑줄 표시됩니다.
\n' +
23 | '\n' +
24 | 'UI 섹션 간 탐색 \n' +
25 | '\n' +
26 | '한 UI 섹션에서 다음 UI 섹션으로 이동하려면 Tab(탭) 을 누릅니다.
\n' +
27 | '\n' +
28 | '한 UI 섹션에서 이전 UI 섹션으로 돌아가려면 Shift+Tab(시프트+탭) 을 누릅니다.
\n' +
29 | '\n' +
30 | '이 UI 섹션의 Tab(탭) 순서는 다음과 같습니다.
\n' +
31 | '\n' +
32 | '\n' +
33 | ' 메뉴 바 \n' +
34 | ' 각 도구 모음 그룹 \n' +
35 | ' 사이드바 \n' +
36 | ' 푸터의 요소 경로 \n' +
37 | ' 푸터의 단어 수 토글 버튼 \n' +
38 | ' 푸터의 브랜딩 링크 \n' +
39 | ' 푸터의 에디터 크기 변경 핸들 \n' +
40 | ' \n' +
41 | '\n' +
42 | 'UI 섹션이 없는 경우 건너뛰기합니다.
\n' +
43 | '\n' +
44 | '푸터에 키보드 탐색 포커스가 있고 사이드바는 보이지 않는 경우 Shift+Tab(시프트+탭) 을 누르면\n' +
45 | ' 포커스 표시가 마지막이 아닌 첫 번째 도구 모음 그룹으로 이동합니다.
\n' +
46 | '\n' +
47 | 'UI 섹션 내 탐색 \n' +
48 | '\n' +
49 | '한 UI 요소에서 다음 UI 요소로 이동하려면 적절한 화살표 키를 누릅니다.
\n' +
50 | '\n' +
51 | '왼쪽 과 오른쪽 화살표 키의 용도:
\n' +
52 | '\n' +
53 | '\n' +
54 | ' 메뉴 모음에서 메뉴 항목 사이를 이동합니다. \n' +
55 | ' 메뉴에서 하위 메뉴를 엽니다. \n' +
56 | ' 도구 모음 그룹에서 버튼 사이를 이동합니다. \n' +
57 | ' 푸터의 요소 경로에서 항목 간에 이동합니다. \n' +
58 | ' \n' +
59 | '\n' +
60 | '아래 와 위 화살표 키의 용도:
\n' +
61 | '\n' +
62 | '\n' +
63 | ' 메뉴에서 메뉴 항목 사이를 이동합니다. \n' +
64 | ' 도구 모음 팝업 메뉴에서 메뉴 항목 사이를 이동합니다. \n' +
65 | ' \n' +
66 | '\n' +
67 | '화살표 키는 포커스 표시 UI 섹션 내에서 순환됩니다.
\n' +
68 | '\n' +
69 | '열려 있는 메뉴, 열려 있는 하위 메뉴 또는 열려 있는 팝업 메뉴를 닫으려면 Esc 키를 누릅니다.
\n' +
70 | '\n' +
71 | "현재 포커스 표시가 특정 UI 섹션 '상단'에 있는 경우 이때도 Esc 키를 누르면\n" +
72 | ' 키보드 탐색이 완전히 종료됩니다.
\n' +
73 | '\n' +
74 | '메뉴 항목 또는 도구 모음 버튼 실행 \n' +
75 | '\n' +
76 | '원하는 메뉴 항목 또는 도구 모음 버튼이 강조 표시되어 있을 때 Return(리턴) , Enter(엔터) ,\n' +
77 | ' 또는 Space bar(스페이스바) 를 눌러 해당 항목을 실행합니다.
\n' +
78 | '\n' +
79 | '탭이 없는 대화 탐색 \n' +
80 | '\n' +
81 | '탭이 없는 대화의 경우, 첫 번째 대화형 요소가 포커스 표시된 상태로 대화가 열립니다.
\n' +
82 | '\n' +
83 | '대화형 요소들 사이를 이동할 때는 Tab(탭) 또는 Shift+Tab(시프트+탭) 을 누릅니다.
\n' +
84 | '\n' +
85 | '탭이 있는 대화 탐색 \n' +
86 | '\n' +
87 | '탭이 있는 대화의 경우, 탭 메뉴에서 첫 번째 버튼이 포커스 표시된 상태로 대화가 열립니다.
\n' +
88 | '\n' +
89 | '이 대화 탭의 대화형 요소들 사이를 이동할 때는 Tab(탭) 또는\n' +
90 | ' Shift+Tab(시프트+탭) 을 누릅니다.
\n' +
91 | '\n' +
92 | '다른 대화 탭으로 이동하려면 탭 메뉴를 포커스 표시한 다음 적절한 화살표 \n' +
93 | ' 키를 눌러 사용 가능한 탭들을 지나 원하는 탭으로 이동합니다.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/ms.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.ms',
2 | 'Mulakan navigasi papan kekunci \n' +
3 | '\n' +
4 | '\n' +
5 | ' Fokus bar Menu \n' +
6 | ' Windows atau Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' Fokus Bar Alat \n' +
9 | ' Windows atau Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' Fokus pengaki \n' +
12 | ' Windows atau Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' Tumpu kepada pemberitahuan \n' +
15 | ' Windows atau Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' Fokus bar alat kontekstual \n' +
18 | ' Windows, Linux atau macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'Navigasi akan bermula pada item UI pertama, yang akan diserlahkan atau digaris bawah dalam saiz item pertama dalam\n' +
22 | ' laluan elemen Pengaki.
\n' +
23 | '\n' +
24 | 'Navigasi antara bahagian UI \n' +
25 | '\n' +
26 | 'Untuk bergerak dari satu bahagian UI ke yang seterusnya, tekan Tab .
\n' +
27 | '\n' +
28 | 'Untuk bergerak dari satu bahagian UI ke yang sebelumnya, tekan Shift+Tab .
\n' +
29 | '\n' +
30 | 'Tertib Tab bahagian UI ini ialah:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' Bar menu \n' +
34 | ' Setiap kumpulan bar alat \n' +
35 | ' Bar sisi \n' +
36 | ' Laluan elemen dalam pengaki \n' +
37 | ' Butang togol kiraan perkataan dalam pengaki \n' +
38 | ' Pautan penjenamaan dalam pengaki \n' +
39 | ' Pemegang saiz semula editor dalam pengaki \n' +
40 | ' \n' +
41 | '\n' +
42 | 'Jika bahagian UI tidak wujud, ia dilangkau.
\n' +
43 | '\n' +
44 | 'Jika pengaki mempunyai fokus navigasi papan kekunci dan tiada bar sisi kelihatan, menekan Shift+Tab \n' +
45 | ' akan mengalihkan fokus ke kumpulan bar alat pertama, bukannya yang terakhir.
\n' +
46 | '\n' +
47 | 'Navigasi dalam bahagian UI \n' +
48 | '\n' +
49 | 'Untuk bergerak dari satu elemen UI ke yang seterusnya, tekan kekunci Anak Panah yang bersesuaian.
\n' +
50 | '\n' +
51 | 'Kekunci anak panah Kiri dan Kanan
\n' +
52 | '\n' +
53 | '\n' +
54 | ' bergerak antara menu dalam bar menu. \n' +
55 | ' membukan submenu dalam menu. \n' +
56 | ' bergerak antara butang dalam kumpulan bar alat. \n' +
57 | ' Laluan elemen dalam pengaki. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'Kekunci anak panah Bawah dan Atas
\n' +
61 | '\n' +
62 | '\n' +
63 | ' bergerak antara item menu dalam menu. \n' +
64 | ' bergerak antara item dalam menu timbul bar alat. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'Kekunci Anak Panah berkitar dalam bahagian UI difokuskan.
\n' +
68 | '\n' +
69 | 'Untuk menutup menu buka, submenu terbuka atau menu timbul terbuka, tekan kekunci Esc .
\n' +
70 | '\n' +
71 | "Jika fokus semasa berada di bahagian 'atas' bahagian UI tertentu, menekan kekunci Esc juga akan keluar daripada\n" +
72 | ' navigasi papan kekunci sepenuhnya.
\n' +
73 | '\n' +
74 | 'Laksanakan item menu atau butang bar alat \n' +
75 | '\n' +
76 | 'Apabila item menu atau butang bar alat yang diinginkan diserlahkan, tekan Return , Enter ,\n' +
77 | ' atau bar Space untuk melaksanakan item.
\n' +
78 | '\n' +
79 | 'Navigasi ke dialog tidak bertab \n' +
80 | '\n' +
81 | 'Dalam dialog tidak bertab, komponen interaksi pertama difokuskan apabila dialog dibuka.
\n' +
82 | '\n' +
83 | 'Navigasi antara komponen dialog interaktif dengan menekan Tab atau Shift+Tab .
\n' +
84 | '\n' +
85 | 'Navigasi ke dialog bertab \n' +
86 | '\n' +
87 | 'Dalam dialog bertab, butang pertama dalam menu tab difokuskan apabila dialog dibuka.
\n' +
88 | '\n' +
89 | 'Navigasi antara komponen interaktif tab dialog ini dengan menekan Tab atau\n' +
90 | ' Shift+Tab .
\n' +
91 | '\n' +
92 | 'Tukar kepada tab dialog lain dengan memfokuskan menu tab, kemudian menekan kekunci Anak Panah yang bersesuaian\n' +
93 | ' untuk berkitar menerusi tab yang tersedia.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/sv_SE.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.sv_SE',
2 | 'Påbörja tangentbordsnavigering \n' +
3 | '\n' +
4 | '\n' +
5 | ' Fokusera på menyraden \n' +
6 | ' Windows eller Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' Fokusera på verktygsraden \n' +
9 | ' Windows eller Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' Fokusera på verktygsraden \n' +
12 | ' Windows eller Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' Fokusera aviseringen \n' +
15 | ' Windows eller Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' Fokusera på en snabbverktygsrad \n' +
18 | ' Windows, Linux eller macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'Navigeringen börjar vid det första gränssnittsobjektet, vilket är markerat eller understruket om det gäller det första objektet i\n' +
22 | ' sidfotens elementsökväg.
\n' +
23 | '\n' +
24 | 'Navigera mellan UI-avsnitt \n' +
25 | '\n' +
26 | 'Flytta från ett UI-avsnitt till nästa genom att trycka på Tabb .
\n' +
27 | '\n' +
28 | 'Flytta från ett UI-avsnitt till det föregående genom att trycka på Skift+Tabb .
\n' +
29 | '\n' +
30 | 'Tabb -ordningen för dessa UI-avsnitt är:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' Menyrad \n' +
34 | ' Varje verktygsradsgrupp \n' +
35 | ' Sidoruta \n' +
36 | ' Elementsökväg i sidfoten \n' +
37 | ' Växlingsknapp för ordantal i sidfoten \n' +
38 | ' Varumärkeslänk i sidfoten \n' +
39 | ' Storlekshandtag för redigeraren i sidfoten \n' +
40 | ' \n' +
41 | '\n' +
42 | 'Om ett UI-avsnitt inte finns hoppas det över.
\n' +
43 | '\n' +
44 | 'Om sidfoten har fokus på tangentbordsnavigering, och det inte finns någon synlig sidoruta, flyttas fokus till den första verktygsradsgruppen\n' +
45 | ' när du trycker på Skift+Tabb , inte till den sista.
\n' +
46 | '\n' +
47 | 'Navigera i UI-avsnitt \n' +
48 | '\n' +
49 | 'Flytta från ett UI-element till nästa genom att trycka på motsvarande piltangent .
\n' +
50 | '\n' +
51 | 'Vänsterpil och högerpil
\n' +
52 | '\n' +
53 | '\n' +
54 | ' flytta mellan menyer på menyraden. \n' +
55 | ' öppna en undermeny på en meny. \n' +
56 | ' flytta mellan knappar i en verktygsradgrupp. \n' +
57 | ' flytta mellan objekt i sidfotens elementsökväg. \n' +
58 | ' \n' +
59 | '\n' +
60 | 'Nedpil och uppil
\n' +
61 | '\n' +
62 | '\n' +
63 | ' flytta mellan menyalternativ på en meny. \n' +
64 | ' flytta mellan alternativ på en popup-meny på verktygsraden. \n' +
65 | ' \n' +
66 | '\n' +
67 | 'Piltangenterna cirkulerar inom det fokuserade UI-avsnittet.
\n' +
68 | '\n' +
69 | 'Tryck på Esc -tangenten om du vill stänga en öppen meny, undermeny eller popup-meny.
\n' +
70 | '\n' +
71 | 'Om det aktuella fokuset är högst upp i ett UI-avsnitt avlutas även tangentbordsnavigeringen helt när\n' +
72 | ' du trycker på Esc -tangenten.
\n' +
73 | '\n' +
74 | 'Köra ett menyalternativ eller en verktygfältsknapp \n' +
75 | '\n' +
76 | 'När menyalternativet eller verktygsradsknappen är markerad trycker du på Retur , Enter \n' +
77 | ' eller blanksteg för att köra alternativet.
\n' +
78 | '\n' +
79 | 'Navigera i dialogrutor utan flikar \n' +
80 | '\n' +
81 | 'I dialogrutor utan flikar är den första interaktiva komponenten i fokus när dialogrutan öppnas.
\n' +
82 | '\n' +
83 | 'Navigera mellan interaktiva dialogkomponenter genom att trycka på Tabb eller Skift+Tabb .
\n' +
84 | '\n' +
85 | 'Navigera i dialogrutor med flikar \n' +
86 | '\n' +
87 | 'I dialogrutor utan flikar är den första knappen på flikmenyn i fokus när dialogrutan öppnas.
\n' +
88 | '\n' +
89 | 'Navigera mellan interaktiva komponenter på dialogrutefliken genom att trycka på Tabb eller\n' +
90 | ' Skift+Tabb .
\n' +
91 | '\n' +
92 | 'Växla till en annan dialogruta genom att fokusera på flikmenyn och sedan trycka på motsvarande piltangent \n' +
93 | ' för att cirkulera mellan de tillgängliga flikarna.
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/th_TH.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.th_TH',
2 | 'เริ่มต้นการนำทางด้วยแป้นพิมพ์ \n' +
3 | '\n' +
4 | '\n' +
5 | ' โฟกัสที่แถบเมนู \n' +
6 | ' Windows หรือ Linux: Alt+F9 \n' +
7 | ' macOS: ⌥F9 \n' +
8 | ' โฟกัสที่แถบเครื่องมือ \n' +
9 | ' Windows หรือ Linux: Alt+F10 \n' +
10 | ' macOS: ⌥F10 \n' +
11 | ' โฟกัสที่ส่วนท้าย \n' +
12 | ' Windows หรือ Linux: Alt+F11 \n' +
13 | ' macOS: ⌥F11 \n' +
14 | ' โฟกัสไปที่การแจ้งเตือน \n' +
15 | ' Windows หรือ Linux: Alt+F12 \n' +
16 | ' macOS: ⌥F12 \n' +
17 | ' โฟกัสที่แถบเครื่องมือตามบริบท \n' +
18 | ' Windows, Linux หรือ macOS: Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | 'การนำทางจะเริ่มที่รายการ UI แรก ซึ่งจะมีการไฮไลต์หรือขีดเส้นใต้ไว้ในกรณีที่รายการแรกอยู่ใน\n' +
22 | ' พาธองค์ประกอบส่วนท้าย
\n' +
23 | '\n' +
24 | 'การนำทางระหว่างส่วนต่างๆ ของ UI \n' +
25 | '\n' +
26 | 'ในการย้ายจากส่วน UI หนึ่งไปยังส่วนถัดไป ให้กด Tab
\n' +
27 | '\n' +
28 | 'ในการย้ายจากส่วน UI หนึ่งไปยังส่วนก่อนหน้า ให้กด Shift+Tab
\n' +
29 | '\n' +
30 | 'ลำดับแท็บ ของส่วนต่างๆ ของ UI คือ:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' แถบเมนู \n' +
34 | ' แต่ละกลุ่มแถบเครื่องมือ \n' +
35 | ' แถบข้าง \n' +
36 | ' พาธองค์ประกอบในส่วนท้าย \n' +
37 | ' ปุ่มสลับเปิด/ปิดจำนวนคำในส่วนท้าย \n' +
38 | ' ลิงก์ชื่อแบรนด์ในส่วนท้าย \n' +
39 | ' จุดจับปรับขนาดของตัวแก้ไขในส่วนท้าย \n' +
40 | ' \n' +
41 | '\n' +
42 | 'หากส่วน UI ไม่ปรากฏ แสดงว่าถูกข้ามไป
\n' +
43 | '\n' +
44 | 'หากส่วนท้ายมีการโฟกัสการนำทางแป้นพิมพ์และไม่มีแถบข้างปรากฏ การกด Shift+Tab \n' +
45 | ' จะย้ายการโฟกัสไปที่กลุ่มแถบเครื่องมือแรก ไม่ใช่สุดท้าย
\n' +
46 | '\n' +
47 | 'การนำทางภายในส่วนต่างๆ ของ UI \n' +
48 | '\n' +
49 | 'ในการย้ายจากองค์ประกอบ UI หนึ่งไปยังองค์ประกอบส่วนถัดไป ให้กดปุ่มลูกศร ที่เหมาะสม
\n' +
50 | '\n' +
51 | 'ปุ่มลูกศรซ้าย และขวา
\n' +
52 | '\n' +
53 | '\n' +
54 | ' ย้ายไปมาระหว่างเมนูต่างๆ ในแถบเมนู \n' +
55 | ' เปิดเมนูย่อยในเมนู \n' +
56 | ' ย้ายไปมาระหว่างปุ่มต่างๆ ในกลุ่มแถบเครื่องมือ \n' +
57 | ' ย้ายไปมาระหว่างรายการต่างๆ ในพาธองค์ประกอบของส่วนท้าย \n' +
58 | ' \n' +
59 | '\n' +
60 | 'ปุ่มลูกศรลง และขึ้น
\n' +
61 | '\n' +
62 | '\n' +
63 | ' ย้ายไปมาระหว่างรายการเมนูต่างๆ ในเมนู \n' +
64 | ' ย้ายไปมาระหว่างรายการต่างๆ ในเมนูป๊อบอัพแถบเครื่องมือ \n' +
65 | ' \n' +
66 | '\n' +
67 | 'ปุ่มลูกศร จะเลื่อนไปมาภายในส่วน UI ที่โฟกัส
\n' +
68 | '\n' +
69 | 'ในการปิดเมนูที่เปิดอยู่ เมนูย่อยที่เปิดอยู่ หรือเมนูป๊อบอัพที่เปิดอยู่ ให้กดปุ่ม Esc
\n' +
70 | '\n' +
71 | 'หากโฟกัสปัจจุบันอยู่ที่ ‘ด้านบนสุด’ ของส่วน UI เฉพาะ การกดปุ่ม Esc จะทำให้ออกจาก\n' +
72 | ' การนำทางด้วยแป้นพิมพ์ทั้งหมดเช่นกัน
\n' +
73 | '\n' +
74 | 'การดำเนินการรายการเมนูหรือปุ่มในแถบเครื่องมือ \n' +
75 | '\n' +
76 | 'เมื่อไฮไลต์รายการเมนูหรือปุ่มในแถบเครื่องมือที่ต้องการ ให้กด Return , Enter \n' +
77 | ' หรือ Space bar เพื่อดำเนินการรายการดังกล่าว
\n' +
78 | '\n' +
79 | 'การนำทางสำหรับกล่องโต้ตอบที่ไม่อยู่ในแท็บ \n' +
80 | '\n' +
81 | 'ในกล่องโต้ตอบที่ไม่อยู่ในแท็บ จะโฟกัสที่ส่วนประกอบเชิงโต้ตอบแรกเมื่อกล่องโต้ตอบเปิด
\n' +
82 | '\n' +
83 | 'นำทางระหว่างส่วนประกอบเชิงโต้ตอบต่างๆ ของกล่องโต้ตอบ โดยการกด Tab หรือ Shift+Tab
\n' +
84 | '\n' +
85 | 'การนำทางสำหรับกล่องโต้ตอบที่อยู่ในแท็บ \n' +
86 | '\n' +
87 | 'ในกล่องโต้ตอบที่อยู่ในแท็บ จะโฟกัสที่ปุ่มแรกในเมนูแท็บเมื่อกล่องโต้ตอบเปิด
\n' +
88 | '\n' +
89 | 'นำทางระหว่างส่วนประกอบเชิงโต้ตอบต่างๆ ของแท็บกล่องโต้ตอบนี้โดยการกด Tab หรือ\n' +
90 | ' Shift+Tab
\n' +
91 | '\n' +
92 | 'สลับไปยังแท็บกล่องโต้ตอบอื่นโดยการเลือกโฟกัสที่เมนูแท็บ แล้วกดปุ่มลูกศร ที่เหมาะสม\n' +
93 | ' เพื่อเลือกแท็บที่ใช้ได้
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/zh_CN.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.zh_CN',
2 | '开始键盘导航 \n' +
3 | '\n' +
4 | '\n' +
5 | ' 使菜单栏处于焦点 \n' +
6 | ' Windows 或 Linux:Alt+F9 \n' +
7 | ' macOS:⌥F9 \n' +
8 | ' 使工具栏处于焦点 \n' +
9 | ' Windows 或 Linux:Alt+F10 \n' +
10 | ' macOS:⌥F10 \n' +
11 | ' 使页脚处于焦点 \n' +
12 | ' Windows 或 Linux:Alt+F11 \n' +
13 | ' macOS:⌥F11 \n' +
14 | ' 使通知处于焦点 \n' +
15 | ' Windows 或 Linux:Alt+F12 \n' +
16 | ' macOS:⌥F12 \n' +
17 | ' 使上下文工具栏处于焦点 \n' +
18 | ' Windows、Linux 或 macOS:Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | '导航将在第一个 UI 项上开始,其中突出显示该项,或者对于页脚元素路径中的第一项,将为其添加下划线。
\n' +
22 | '\n' +
23 | '在 UI 部分之间导航 \n' +
24 | '\n' +
25 | '要从一个 UI 部分移至下一个,请按 Tab 。
\n' +
26 | '\n' +
27 | '要从一个 UI 部分移至上一个,请按 Shift+Tab 。
\n' +
28 | '\n' +
29 | '这些 UI 部分的 Tab 顺序为:
\n' +
30 | '\n' +
31 | '\n' +
32 | ' 菜单栏 \n' +
33 | ' 每个工具栏组 \n' +
34 | ' 边栏 \n' +
35 | ' 页脚中的元素路径 \n' +
36 | ' 页脚中的字数切换按钮 \n' +
37 | ' 页脚中的品牌链接 \n' +
38 | ' 页脚中的编辑器调整大小图柄 \n' +
39 | ' \n' +
40 | '\n' +
41 | '如果不存在某个 UI 部分,则跳过它。
\n' +
42 | '\n' +
43 | '如果键盘导航焦点在页脚,并且没有可见的边栏,则按 Shift+Tab 将焦点移至第一个工具栏组而非最后一个。
\n' +
44 | '\n' +
45 | '在 UI 部分内导航 \n' +
46 | '\n' +
47 | '要从一个 UI 元素移至下一个,请按相应的箭头 键。
\n' +
48 | '\n' +
49 | '左 和右 箭头键
\n' +
50 | '\n' +
51 | '\n' +
52 | ' 在菜单栏中的菜单之间移动。 \n' +
53 | ' 打开菜单中的子菜单。 \n' +
54 | ' 在工具栏组中的按钮之间移动。 \n' +
55 | ' 在页脚的元素路径中的各项之间移动。 \n' +
56 | ' \n' +
57 | '\n' +
58 | '下 和上 箭头键
\n' +
59 | '\n' +
60 | '\n' +
61 | ' 在菜单中的菜单项之间移动。 \n' +
62 | ' 在工具栏弹出菜单中的各项之间移动。 \n' +
63 | ' \n' +
64 | '\n' +
65 | '箭头 键在具有焦点的 UI 部分内循环。
\n' +
66 | '\n' +
67 | '要关闭打开的菜单、打开的子菜单或打开的弹出菜单,请按 Esc 键。
\n' +
68 | '\n' +
69 | '如果当前的焦点在特定 UI 部分的“顶部”,则按 Esc 键还将完全退出键盘导航。
\n' +
70 | '\n' +
71 | '执行菜单项或工具栏按钮 \n' +
72 | '\n' +
73 | '当突出显示所需的菜单项或工具栏按钮时,按 Return 、Enter 或空格 以执行该项。
\n' +
74 | '\n' +
75 | '在非标签页式对话框中导航 \n' +
76 | '\n' +
77 | '在非标签页式对话框中,当对话框打开时,第一个交互组件获得焦点。
\n' +
78 | '\n' +
79 | '通过按 Tab 或 Shift+Tab ,在交互对话框组件之间导航。
\n' +
80 | '\n' +
81 | '在标签页式对话框中导航 \n' +
82 | '\n' +
83 | '在标签页式对话框中,当对话框打开时,标签页菜单中的第一个按钮获得焦点。
\n' +
84 | '\n' +
85 | '通过按 Tab 或 Shift+Tab ,在此对话框的交互组件之间导航。
\n' +
86 | '\n' +
87 | '通过将焦点移至另一对话框标签页的菜单,然后按相应的箭头 键以在可用的标签页间循环,从而切换到该对话框标签页。
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/help/js/i18n/keynav/zh_TW.js:
--------------------------------------------------------------------------------
1 | tinymce.Resource.add('tinymce.html-i18n.help-keynav.zh_TW',
2 | '開始鍵盤瀏覽 \n' +
3 | '\n' +
4 | '\n' +
5 | ' 跳至功能表列 \n' +
6 | ' Windows 或 Linux:Alt+F9 \n' +
7 | ' macOS:⌥F9 \n' +
8 | ' 跳至工具列 \n' +
9 | ' Windows 或 Linux:Alt+F10 \n' +
10 | ' macOS:⌥F10 \n' +
11 | ' 跳至頁尾 \n' +
12 | ' Windows 或 Linux:Alt+F11 \n' +
13 | ' macOS:⌥F11 \n' +
14 | ' 跳至通知 \n' +
15 | ' Windows 或 Linux:Alt+F12 \n' +
16 | ' macOS:⌥F12 \n' +
17 | ' 跳至關聯式工具列 \n' +
18 | ' Windows、Linux 或 macOS:Ctrl+F9 \n' +
19 | ' \n' +
20 | '\n' +
21 | '瀏覽會從第一個 UI 項目開始,該項目會反白顯示,但如果是「頁尾」元素路徑的第一項,\n' +
22 | ' 則加底線。
\n' +
23 | '\n' +
24 | '在 UI 區段之間瀏覽 \n' +
25 | '\n' +
26 | '從 UI 區段移至下一個,請按 Tab 。
\n' +
27 | '\n' +
28 | '從 UI 區段移回上一個,請按 Shift+Tab 。
\n' +
29 | '\n' +
30 | '這些 UI 區段的 Tab 順序如下:
\n' +
31 | '\n' +
32 | '\n' +
33 | ' 功能表列 \n' +
34 | ' 各個工具列群組 \n' +
35 | ' 側邊欄 \n' +
36 | ' 頁尾中的元素路徑 \n' +
37 | ' 頁尾中字數切換按鈕 \n' +
38 | ' 頁尾中的品牌連結 \n' +
39 | ' 頁尾中編輯器調整大小控點 \n' +
40 | ' \n' +
41 | '\n' +
42 | '如果 UI 區段未顯示,表示已略過該區段。
\n' +
43 | '\n' +
44 | '如果鍵盤瀏覽跳至頁尾,但沒有顯示側邊欄,則按下 Shift+Tab \n' +
45 | ' 會跳至第一個工具列群組,而不是最後一個。
\n' +
46 | '\n' +
47 | '在 UI 區段之內瀏覽 \n' +
48 | '\n' +
49 | '在兩個 UI 元素之間移動,請按適當的方向 鍵。
\n' +
50 | '\n' +
51 | '向左 和向右 方向鍵
\n' +
52 | '\n' +
53 | '\n' +
54 | ' 在功能表列中的功能表之間移動。 \n' +
55 | ' 開啟功能表中的子功能表。 \n' +
56 | ' 在工具列群組中的按鈕之間移動。 \n' +
57 | ' 在頁尾的元素路徑中項目之間移動。 \n' +
58 | ' \n' +
59 | '\n' +
60 | '向下 和向上 方向鍵
\n' +
61 | '\n' +
62 | '\n' +
63 | ' 在功能表中的功能表項目之間移動。 \n' +
64 | ' 在工具列快顯功能表中的項目之間移動。 \n' +
65 | ' \n' +
66 | '\n' +
67 | '方向 鍵會在所跳至 UI 區段之內循環。
\n' +
68 | '\n' +
69 | '若要關閉已開啟的功能表、已開啟的子功能表,或已開啟的快顯功能表,請按 Esc 鍵。
\n' +
70 | '\n' +
71 | '如果目前已跳至特定 UI 區段的「頂端」,則按 Esc 鍵也會結束\n' +
72 | ' 整個鍵盤瀏覽。
\n' +
73 | '\n' +
74 | '執行功能表列項目或工具列按鈕 \n' +
75 | '\n' +
76 | '當想要的功能表項目或工具列按鈕已反白顯示時,按 Return 、Enter 、\n' +
77 | ' 或空白鍵 即可執行該項目。
\n' +
78 | '\n' +
79 | '瀏覽非索引標籤式對話方塊 \n' +
80 | '\n' +
81 | '在非索引標籤式對話方塊中,開啟對話方塊時會跳至第一個互動元件。
\n' +
82 | '\n' +
83 | '按 Tab 或 Shift+Tab 即可在互動式對話方塊元件之間瀏覽。
\n' +
84 | '\n' +
85 | '瀏覽索引標籤式對話方塊 \n' +
86 | '\n' +
87 | '在索引標籤式對話方塊中,開啟對話方塊時會跳至索引標籤式功能表中的第一個按鈕。
\n' +
88 | '\n' +
89 | '若要在此對話方塊的互動式元件之間瀏覽,請按 Tab 或\n' +
90 | ' Shift+Tab 。
\n' +
91 | '\n' +
92 | '先跳至索引標籤式功能表,然後按適當的方向 鍵,即可切換至另一個對話方塊索引標籤,\n' +
93 | ' 以循環瀏覽可用的索引標籤。
\n');
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/importcss/plugin.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TinyMCE version 7.3.0 (2024-08-07)
3 | */
4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>(e=>{const t=typeof e;return null===e?"null":"object"===t&&Array.isArray(e)?"array":"object"===t&&(s=r=e,(o=String).prototype.isPrototypeOf(s)||(null===(n=r.constructor)||void 0===n?void 0:n.name)===o.name)?"string":t;var s,r,o,n})(t)===e,s=t("string"),r=t("object"),o=t("array"),n=("function",e=>"function"==typeof e);var c=tinymce.util.Tools.resolve("tinymce.dom.DOMUtils"),i=tinymce.util.Tools.resolve("tinymce.EditorManager"),l=tinymce.util.Tools.resolve("tinymce.Env"),a=tinymce.util.Tools.resolve("tinymce.util.Tools");const p=e=>t=>t.options.get(e),u=p("importcss_merge_classes"),m=p("importcss_exclusive"),f=p("importcss_selector_converter"),y=p("importcss_selector_filter"),d=p("importcss_groups"),h=p("importcss_append"),g=p("importcss_file_filter"),_=p("skin"),v=p("skin_url"),b=Array.prototype.push,x=/^\.(?:ephox|tiny-pageembed|mce)(?:[.-]+\w+)+$/,T=e=>s(e)?t=>-1!==t.indexOf(e):e instanceof RegExp?t=>e.test(t):e,S=(e,t)=>{let s={};const r=/^(?:([a-z0-9\-_]+))?(\.[a-z0-9_\-\.]+)$/i.exec(t);if(!r)return;const o=r[1],n=r[2].substr(1).split(".").join(" "),c=a.makeMap("a,img");return r[1]?(s={title:t},e.schema.getTextBlockElements()[o]?s.block=o:e.schema.getBlockElements()[o]||c[o.toLowerCase()]?s.selector=o:s.inline=o):r[2]&&(s={inline:"span",title:t.substr(1),classes:n}),u(e)?s.classes=n:s.attributes={class:n},s},k=(e,t)=>null===t||m(e),M=e=>{e.on("init",(()=>{const t=(()=>{const e=[],t=[],s={};return{addItemToGroup:(e,r)=>{s[e]?s[e].push(r):(t.push(e),s[e]=[r])},addItem:t=>{e.push(t)},toFormats:()=>{return(r=t,n=e=>{const t=s[e];return 0===t.length?[]:[{title:e,items:t}]},(e=>{const t=[];for(let s=0,r=e.length;s{const s=e.length,r=new Array(s);for(let o=0;oa.map(e,(e=>a.extend({},e,{original:e,selectors:{},filter:T(e.filter)}))))(d(e)),u=(t,s)=>{if(((e,t,s,r)=>!(k(e,s)?t in r:t in s.selectors))(e,t,s,r)){((e,t,s,r)=>{k(e,s)?r[t]=!0:s.selectors[t]=!0})(e,t,s,r);const o=((e,t,s,r)=>{let o;const n=f(e);return o=r&&r.selector_converter?r.selector_converter:n||(()=>S(e,s)),o.call(t,s,r)})(e,e.plugins.importcss,t,s);if(o){const t=o.name||c.DOM.uniqueId();return e.formatter.register(t,o),{title:o.title,format:t}}}return null};a.each(((e,t,r)=>{const o=[],n={},c=(t,n)=>{let p,u=t.href;if(u=(e=>{const t=l.cacheSuffix;return s(e)&&(e=e.replace("?"+t,"").replace("&"+t,"")),e})(u),u&&(!r||r(u,n))&&!((e,t)=>{const s=_(e);if(s){const r=v(e),o=r?e.documentBaseURI.toAbsolute(r):i.baseURL+"/skins/ui/"+s,n=i.baseURL+"/skins/content/",c=e.editorManager.suffix;return t===o+"/content"+(e.inline?".inline":"")+`${c}.css`||-1!==t.indexOf(n)}return!1})(e,u)){a.each(t.imports,(e=>{c(e,!0)}));try{p=t.cssRules||t.rules}catch(e){}a.each(p,(e=>{e.styleSheet&&e.styleSheet?c(e.styleSheet,!0):e.selectorText&&a.each(e.selectorText.split(","),(e=>{o.push(a.trim(e))}))}))}};a.each(e.contentCSS,(e=>{n[e]=!0})),r||(r=(e,t)=>t||n[e]);try{a.each(t.styleSheets,(e=>{c(e)}))}catch(e){}return o})(e,e.getDoc(),T(g(e))),(e=>{if(!x.test(e)&&(!n||n(e))){const s=((e,t)=>a.grep(e,(e=>!e.filter||e.filter(t))))(p,e);if(s.length>0)a.each(s,(s=>{const r=u(e,s);r&&t.addItemToGroup(s.title,r)}));else{const s=u(e,null);s&&t.addItem(s)}}}));const m=t.toFormats();e.dispatch("addStyleModifications",{items:m,replace:!h(e)})}))};e.add("importcss",(e=>((e=>{const t=e.options.register,o=e=>s(e)||n(e)||r(e);t("importcss_merge_classes",{processor:"boolean",default:!0}),t("importcss_exclusive",{processor:"boolean",default:!0}),t("importcss_selector_converter",{processor:"function"}),t("importcss_selector_filter",{processor:o}),t("importcss_file_filter",{processor:o}),t("importcss_groups",{processor:"object[]"}),t("importcss_append",{processor:"boolean",default:!1})})(e),M(e),(e=>({convertSelectorToFormat:t=>S(e,t)}))(e))))}();
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/insertdatetime/plugin.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TinyMCE version 7.3.0 (2024-08-07)
3 | */
4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager");const t=e=>t=>t.options.get(e),a=t("insertdatetime_dateformat"),n=t("insertdatetime_timeformat"),r=t("insertdatetime_formats"),s=t("insertdatetime_element"),i="Sun Mon Tue Wed Thu Fri Sat Sun".split(" "),o="Sunday Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split(" "),l="Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "),m="January February March April May June July August September October November December".split(" "),c=(e,t)=>{if((e=""+e).length(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=(t=t.replace("%D","%m/%d/%Y")).replace("%r","%I:%M:%S %p")).replace("%Y",""+a.getFullYear())).replace("%y",""+a.getYear())).replace("%m",c(a.getMonth()+1,2))).replace("%d",c(a.getDate(),2))).replace("%H",""+c(a.getHours(),2))).replace("%M",""+c(a.getMinutes(),2))).replace("%S",""+c(a.getSeconds(),2))).replace("%I",""+((a.getHours()+11)%12+1))).replace("%p",a.getHours()<12?"AM":"PM")).replace("%B",""+e.translate(m[a.getMonth()]))).replace("%b",""+e.translate(l[a.getMonth()]))).replace("%A",""+e.translate(o[a.getDay()]))).replace("%a",""+e.translate(i[a.getDay()]))).replace("%%","%"),u=(e,t)=>{if(s(e)){const a=d(e,t);let n;n=/%[HMSIp]/.test(t)?d(e,"%Y-%m-%dT%H:%M"):d(e,"%Y-%m-%d");const r=e.dom.getParent(e.selection.getStart(),"time");r?((e,t,a,n)=>{const r=e.dom.create("time",{datetime:a},n);e.dom.replace(r,t),e.selection.select(r,!0),e.selection.collapse(!1)})(e,r,n,a):e.insertContent(''+a+" ")}else e.insertContent(d(e,t))};var p=tinymce.util.Tools.resolve("tinymce.util.Tools");const g=e=>t=>{const a=()=>{t.setEnabled(e.selection.isEditable())};return e.on("NodeChange",a),a(),()=>{e.off("NodeChange",a)}};e.add("insertdatetime",(e=>{(e=>{const t=e.options.register;t("insertdatetime_dateformat",{processor:"string",default:e.translate("%Y-%m-%d")}),t("insertdatetime_timeformat",{processor:"string",default:e.translate("%H:%M:%S")}),t("insertdatetime_formats",{processor:"string[]",default:["%H:%M:%S","%Y-%m-%d","%I:%M:%S %p","%D"]}),t("insertdatetime_element",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mceInsertDate",((t,n)=>{u(e,null!=n?n:a(e))})),e.addCommand("mceInsertTime",((t,a)=>{u(e,null!=a?a:n(e))}))})(e),(e=>{const t=r(e),a=(e=>{let t=e;return{get:()=>t,set:e=>{t=e}}})((e=>{const t=r(e);return t.length>0?t[0]:n(e)})(e)),s=t=>e.execCommand("mceInsertDate",!1,t);e.ui.registry.addSplitButton("insertdatetime",{icon:"insert-time",tooltip:"Insert date/time",select:e=>e===a.get(),fetch:a=>{a(p.map(t,(t=>({type:"choiceitem",text:d(e,t),value:t}))))},onAction:e=>{s(a.get())},onItemAction:(e,t)=>{a.set(t),s(t)},onSetup:g(e)});const i=e=>()=>{a.set(e),s(e)};e.ui.registry.addNestedMenuItem("insertdatetime",{icon:"insert-time",text:"Date/time",getSubmenuItems:()=>p.map(t,(t=>({type:"menuitem",text:d(e,t),onAction:i(t)}))),onSetup:g(e)})})(e)}))}();
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/nonbreaking/plugin.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TinyMCE version 7.3.0 (2024-08-07)
3 | */
4 | !function(){"use strict";var n=tinymce.util.Tools.resolve("tinymce.PluginManager");const e=n=>e=>typeof e===n,o=e("boolean"),a=e("number"),t=n=>e=>e.options.get(n),i=t("nonbreaking_force_tab"),s=t("nonbreaking_wrap"),r=(n,e)=>{let o="";for(let a=0;a{const o=s(n)||n.plugins.visualchars?`${r(" ",e)} `:r(" ",e);n.undoManager.transact((()=>n.insertContent(o)))};var l=tinymce.util.Tools.resolve("tinymce.util.VK");const u=n=>e=>{const o=()=>{e.setEnabled(n.selection.isEditable())};return n.on("NodeChange",o),o(),()=>{n.off("NodeChange",o)}};n.add("nonbreaking",(n=>{(n=>{const e=n.options.register;e("nonbreaking_force_tab",{processor:n=>o(n)?{value:n?3:0,valid:!0}:a(n)?{value:n,valid:!0}:{valid:!1,message:"Must be a boolean or number."},default:!1}),e("nonbreaking_wrap",{processor:"boolean",default:!0})})(n),(n=>{n.addCommand("mceNonBreaking",(()=>{c(n,1)}))})(n),(n=>{const e=()=>n.execCommand("mceNonBreaking");n.ui.registry.addButton("nonbreaking",{icon:"non-breaking",tooltip:"Nonbreaking space",onAction:e,onSetup:u(n)}),n.ui.registry.addMenuItem("nonbreaking",{icon:"non-breaking",text:"Nonbreaking space",onAction:e,onSetup:u(n)})})(n),(n=>{const e=i(n);e>0&&n.on("keydown",(o=>{if(o.keyCode===l.TAB&&!o.isDefaultPrevented()){if(o.shiftKey)return;o.preventDefault(),o.stopImmediatePropagation(),c(n,e)}}))})(n)}))}();
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/pagebreak/plugin.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TinyMCE version 7.3.0 (2024-08-07)
3 | */
4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.Env");const t=e=>a=>a.options.get(e),n=t("pagebreak_separator"),o=t("pagebreak_split_block"),r="mce-pagebreak",s=e=>{const t=` `;return e?`${t}
`:t},c=e=>a=>{const t=()=>{a.setEnabled(e.selection.isEditable())};return e.on("NodeChange",t),t(),()=>{e.off("NodeChange",t)}};e.add("pagebreak",(e=>{(e=>{const a=e.options.register;a("pagebreak_separator",{processor:"string",default:"\x3c!-- pagebreak --\x3e"}),a("pagebreak_split_block",{processor:"boolean",default:!1})})(e),(e=>{e.addCommand("mcePageBreak",(()=>{e.insertContent(s(o(e)))}))})(e),(e=>{const a=()=>e.execCommand("mcePageBreak");e.ui.registry.addButton("pagebreak",{icon:"page-break",tooltip:"Page break",onAction:a,onSetup:c(e)}),e.ui.registry.addMenuItem("pagebreak",{text:"Page break",icon:"page-break",onAction:a,onSetup:c(e)})})(e),(e=>{const a=n(e),t=()=>o(e),c=new RegExp(a.replace(/[\?\.\*\[\]\(\)\{\}\+\^\$\:]/g,(e=>"\\"+e)),"gi");e.on("BeforeSetContent",(e=>{e.content=e.content.replace(c,s(t()))})),e.on("PreInit",(()=>{e.serializer.addNodeFilter("img",(n=>{let o,s,c=n.length;for(;c--;)if(o=n[c],s=o.attr("class"),s&&-1!==s.indexOf(r)){const n=o.parent;if(n&&e.schema.getBlockElements()[n.name]&&t()){n.type=3,n.value=a,n.raw=!0,o.remove();continue}o.type=3,o.value=a,o.raw=!0}}))}))})(e),(e=>{e.on("ResolveName",(a=>{"IMG"===a.target.nodeName&&e.dom.hasClass(a.target,r)&&(a.name="pagebreak")}))})(e)}))}();
--------------------------------------------------------------------------------
/public/static/tinymce/plugins/preview/plugin.min.js:
--------------------------------------------------------------------------------
1 | /**
2 | * TinyMCE version 7.3.0 (2024-08-07)
3 | */
4 | !function(){"use strict";var e=tinymce.util.Tools.resolve("tinymce.PluginManager"),t=tinymce.util.Tools.resolve("tinymce.Env"),o=tinymce.util.Tools.resolve("tinymce.util.Tools");const n=e=>t=>t.options.get(e),i=n("content_style"),s=n("content_css_cors"),c=n("body_class"),r=n("body_id");e.add("preview",(e=>{(e=>{e.addCommand("mcePreview",(()=>{(e=>{const n=(e=>{var n;let l="";const a=e.dom.encode,d=null!==(n=i(e))&&void 0!==n?n:"";l+=' ';const m=s(e)?' crossorigin="anonymous"':"";o.each(e.contentCSS,(t=>{l+=' "})),d&&(l+='");const y=r(e),u=c(e),v='
20 |
21 |
32 |
--------------------------------------------------------------------------------
/src/api/article.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | addArticle: (data: object) => {
5 | return request({
6 | url: '/article/article/add',
7 | method: 'post',
8 | data
9 | })
10 | },
11 | editArticle: (data: object) => {
12 | return request({
13 | url: '/article/article/edit',
14 | method: 'post',
15 | data
16 | })
17 | },
18 | deleteArticle: (data: object) => {
19 | return request({
20 | url: '/article/article/delete',
21 | method: 'post',
22 | data
23 | })
24 | },
25 | getArticleList: (data: object) => {
26 | return request({
27 | url: '/article/article/list',
28 | method: 'post',
29 | data
30 | })
31 | },
32 |
33 | addCategory: (data: object) => {
34 | return request({
35 | url: '/article/category/add',
36 | method: 'post',
37 | data
38 | })
39 | },
40 | editCategory: (data: object) => {
41 | return request({
42 | url: '/article/category/edit',
43 | method: 'post',
44 | data
45 | })
46 | },
47 | deleteCategory: (data: object) => {
48 | return request({
49 | url: '/article/category/delete',
50 | method: 'post',
51 | data
52 | })
53 | },
54 |
55 | getCategoryList: (data: object) => {
56 | return request({
57 | url: '/article/category/list',
58 | method: 'post',
59 | data
60 | })
61 | },
62 | uploadImg: (data: object) => {
63 | return request({
64 | url: '/article/article/upload',
65 | method: 'post',
66 | data
67 | })
68 | },
69 | })
--------------------------------------------------------------------------------
/src/api/express.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | addCompany: (data: object) => {
5 | return request({
6 | url: '/express/company/add',
7 | method: 'post',
8 | data
9 | })
10 | },
11 | editCompany: (data: object) => {
12 | return request({
13 | url: '/express/company/edit',
14 | method: 'post',
15 | data
16 | })
17 | },
18 | deleteCompany: (data: object) => {
19 | return request({
20 | url: '/express/company/delete',
21 | method: 'post',
22 | data
23 | })
24 | },
25 | getCompanyList: (data: object) => {
26 | return request({
27 | url: '/express/company/list',
28 | method: 'post',
29 | data
30 | })
31 | },
32 | editFreeRule: (data: object) => {
33 | return request({
34 | url: '/express/freeRule/edit',
35 | method: 'post',
36 | data
37 | })
38 | },
39 | getFreeRule: () => {
40 | return request({
41 | url: '/express/freeRule/get',
42 | method: 'post'
43 | })
44 | },
45 | editFeeRule: (data: object) => {
46 | return request({
47 | url: '/express/feeRule/edit',
48 | method: 'post',
49 | data
50 | })
51 | },
52 | getFeeRule: () => {
53 | return request({
54 | url: '/express/feeRule/get',
55 | method: 'post'
56 | })
57 | },
58 | })
--------------------------------------------------------------------------------
/src/api/goods.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | addBrand: (data: object) => {
5 | return request({
6 | url: '/goods/brand/add',
7 | method: 'post',
8 | data
9 | })
10 | },
11 | editBrand: (data: object) => {
12 | return request({
13 | url: '/goods/brand/edit',
14 | method: 'post',
15 | data
16 | })
17 | },
18 | deleteBrand: (data: object) => {
19 | return request({
20 | url: '/goods/brand/delete',
21 | method: 'post',
22 | data
23 | })
24 | },
25 | getBrandList: (data: object) => {
26 | return request({
27 | url: '/goods/brand/list',
28 | method: 'post',
29 | data
30 | })
31 | },
32 |
33 | addCategory: (data: object) => {
34 | return request({
35 | url: '/goods/category/add',
36 | method: 'post',
37 | data
38 | })
39 | },
40 | editCategory: (data: object) => {
41 | return request({
42 | url: '/goods/category/edit',
43 | method: 'post',
44 | data
45 | })
46 | },
47 | deleteCategory: (data: object) => {
48 | return request({
49 | url: '/goods/category/delete',
50 | method: 'post',
51 | data
52 | })
53 | },
54 |
55 | getCategoryList: (data: object) => {
56 | return request({
57 | url: '/goods/category/list',
58 | method: 'post',
59 | data
60 | })
61 | },
62 |
63 |
64 | addGoods: (data: object) => {
65 | return request({
66 | url: '/goods/goods/add',
67 | method: 'post',
68 | data
69 | })
70 | },
71 | editGoods: (data: object) => {
72 | return request({
73 | url: '/goods/goods/edit',
74 | method: 'post',
75 | data
76 | })
77 | },
78 | deleteGoods: (data: object) => {
79 | return request({
80 | url: '/goods/goods/delete',
81 | method: 'post',
82 | data
83 | })
84 | },
85 | getGoods: (data: object) => {
86 | return request({
87 | url: '/goods/goods/get',
88 | method: 'post',
89 | data
90 | })
91 | },
92 | getGoodsList: (data: object) => {
93 | return request({
94 | url: '/goods/goods/list',
95 | method: 'post',
96 | data
97 | })
98 | },
99 |
100 | uploadGoodsImg: (data: object) => {
101 | return request({
102 | url: '/goods/goods/upload',
103 | method: 'post',
104 | data
105 | })
106 | },
107 |
108 | addSpec: (data: object) => {
109 | return request({
110 | url: '/goods/spec/add',
111 | method: 'post',
112 | data
113 | })
114 | },
115 | editSpec: (data: object) => {
116 | return request({
117 | url: '/goods/spec/edit',
118 | method: 'post',
119 | data
120 | })
121 | },
122 | deleteSpec: (data: object) => {
123 | return request({
124 | url: '/goods/spec/delete',
125 | method: 'post',
126 | data
127 | })
128 | },
129 | getSpecList: (data: object) => {
130 | return request({
131 | url: '/goods/spec/list',
132 | method: 'post',
133 | data
134 | })
135 | },
136 | editTemplate: (data: object) => {
137 | return request({
138 | url: '/goods/template/edit',
139 | method: 'post',
140 | data
141 | })
142 | },
143 | getTemplate: () => {
144 | return request({
145 | url: '/goods/template/get',
146 | method: 'post'
147 | })
148 | },
149 | uploadTemplateImg: (data: object) => {
150 | return request({
151 | url: '/goods/template/upload',
152 | method: 'post',
153 | data
154 | })
155 | },
156 |
157 | })
--------------------------------------------------------------------------------
/src/api/main.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | const mainApi = {
4 | /** get RSA public key */
5 | getRsaPubKey: () => {
6 | return request({
7 | url: '/main/rsaPubKey',
8 | method: 'post'
9 | })
10 | },
11 |
12 | /** 登录api */
13 | login(data: object) {
14 | return request({
15 | url: '/main/login',
16 | method: 'post',
17 | data
18 | })
19 | },
20 |
21 | /** 退出登录Api */
22 | logout: () => {
23 | return request({
24 | url: '/main/logout',
25 | method: 'post'
26 | })
27 | },
28 |
29 | /** get user info */
30 | getInfo: () => {
31 | return request({
32 | url: '/main/info',
33 | method: 'post'
34 | })
35 | },
36 |
37 | }
38 | export default mainApi
--------------------------------------------------------------------------------
/src/api/order.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | addOrder: (data: object) => {
5 | return request({
6 | url: '/order/order/add',
7 | method: 'post',
8 | data
9 | })
10 | },
11 | editOrder: (data: object) => {
12 | return request({
13 | url: '/order/order/edit',
14 | method: 'post',
15 | data
16 | })
17 | },
18 | deleteOrder: (data: object) => {
19 | return request({
20 | url: '/order/order/delete',
21 | method: 'post',
22 | data
23 | })
24 | },
25 | getOrder: (data: object) => {
26 | return request({
27 | url: '/order/order/get',
28 | method: 'post',
29 | data
30 | })
31 | },
32 | getOrderList: (data: object) => {
33 | return request({
34 | url: '/order/order/list',
35 | method: 'post',
36 | data
37 | })
38 | },
39 | orderCancelOrder: (data: object) => {
40 | return request({
41 | url: '/order/order/cancelOrder',
42 | method: 'post',
43 | data
44 | })
45 | },
46 | orderCancelShip: (data: object) => {
47 | return request({
48 | url: '/order/order/cancelShip',
49 | method: 'post',
50 | data
51 | })
52 | },
53 | orderConfirm: (data: object) => {
54 | return request({
55 | url: '/order/order/confirm',
56 | method: 'post',
57 | data
58 | })
59 | },
60 |
61 | orderPay: (data: object) => {
62 | return request({
63 | url: '/order/order/pay',
64 | method: 'post',
65 | data
66 | })
67 | },
68 | orderRefund: (data: object) => {
69 | return request({
70 | url: '/order/order/refund',
71 | method: 'post',
72 | data
73 | })
74 | },
75 | orderShip: (data: object) => {
76 | return request({
77 | url: '/order/order/ship',
78 | method: 'post',
79 | data
80 | })
81 | },
82 |
83 |
84 | })
--------------------------------------------------------------------------------
/src/api/other.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | editCarousel: (data: object) => {
5 | return request({
6 | url: '/other/carousel/edit',
7 | method: 'post',
8 | data
9 | })
10 | },
11 | getCarousel: () => {
12 | return request({
13 | url: '/other/carousel/get',
14 | method: 'post'
15 | })
16 | },
17 | editStaticRes: (data: object) => {
18 | return request({
19 | url: '/other/staticRes/edit',
20 | method: 'post',
21 | data
22 | })
23 | },
24 | getStaticRes: () => {
25 | return request({
26 | url: '/other/staticRes/get',
27 | method: 'post'
28 | })
29 | },
30 | })
--------------------------------------------------------------------------------
/src/api/system.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 |
5 | getConfig: () => {
6 | return request({
7 | url: '/system/config',
8 | method: 'post'
9 | })
10 | },
11 |
12 | editConfig: (data: object) => {
13 | return request({
14 | url: '/system/config/edit',
15 | method: 'post',
16 | data
17 | })
18 | },
19 |
20 | getSystemInfo: () => {
21 | return request({
22 | url: '/system/info/get',
23 | method: 'post'
24 | })
25 | },
26 |
27 | getLogList: (data: object) => {
28 | return request({
29 | url: '/system/log/list',
30 | method: 'post',
31 | data
32 | })
33 | },
34 | addManager: (data: object) => {
35 | return request({
36 | url: '/system/manager/add',
37 | method: 'post',
38 | data
39 | })
40 | },
41 |
42 | deleteManager: (data: object) => {
43 | return request({
44 | url: '/system/manager/delete',
45 | method: 'post',
46 | data
47 | })
48 | },
49 |
50 | editManager: (data: object) => {
51 | return request({
52 | url: '/system/manager/edit',
53 | method: 'post',
54 | data
55 | })
56 | },
57 |
58 | getManagerList: (data: object) => {
59 | return request({
60 | url: '/system/manager/list',
61 | method: 'post',
62 | data
63 | })
64 | },
65 |
66 |
67 | addMenu: (data: object) => {
68 | return request({
69 | url: '/system/menu/add',
70 | method: 'post',
71 | data
72 | })
73 | },
74 |
75 | deleteMenu: (data: object) => {
76 | return request({
77 | url: '/system/menu/delete',
78 | method: 'post',
79 | data
80 | })
81 | },
82 |
83 | editMenu: (data: object) => {
84 | return request({
85 | url: '/system/menu/edit',
86 | method: 'post',
87 | data
88 | })
89 | },
90 |
91 | getMenuList: (data: object) => {
92 | return request({
93 | url: '/system/menu/list',
94 | method: 'post',
95 | data
96 | })
97 | },
98 |
99 | getPaymentList: (data: object) => {
100 | return request({
101 | url: '/system/payment/list',
102 | method: 'post',
103 | data
104 | })
105 | },
106 | getPayment: (data: object) => {
107 | return request({
108 | url: '/system/payment/get',
109 | method: 'post',
110 | data
111 | })
112 | },
113 | editPayment: (data: object) => {
114 | return request({
115 | url: '/system/payment/edit',
116 | method: 'post',
117 | data
118 | })
119 | },
120 |
121 | addRole: (data: object) => {
122 | return request({
123 | url: '/system/role/add',
124 | method: 'post',
125 | data
126 | })
127 | },
128 |
129 | deleteRole: (data: object) => {
130 | return request({
131 | url: '/system/role/delete',
132 | method: 'post',
133 | data
134 | })
135 | },
136 |
137 | getRoleList: (data: object) => {
138 | return request({
139 | url: '/system/role/list',
140 | method: 'post',
141 | data
142 | })
143 | },
144 | editRole: (data: object) => {
145 | return request({
146 | url: '/system/role/edit',
147 | method: 'post',
148 | data
149 | })
150 | },
151 |
152 |
153 | })
154 |
--------------------------------------------------------------------------------
/src/api/user.ts:
--------------------------------------------------------------------------------
1 | import request from '@/utils/system/request'
2 |
3 | export default ({
4 | getBalanceLogList: (data: object) => {
5 | return request({
6 | url: '/user/balanceLog/list',
7 | method: 'post',
8 | data
9 | })
10 | },
11 |
12 | changeBalance: (data: object) => {
13 | return request({
14 | url: '/user/user/changeBalance',
15 | method: 'post',
16 | data
17 | })
18 | },
19 | changePassword: (data: object) => {
20 | return request({
21 | url: '/user/user/changePassword',
22 | method: 'post',
23 | data
24 | })
25 | },
26 |
27 | getUser: (data: object) => {
28 | return request({
29 | url: '/user/user/get',
30 | method: 'post',
31 | data
32 | })
33 | },
34 |
35 | getUserList: (data: object) => {
36 | return request({
37 | url: '/user/user/list',
38 | method: 'post',
39 | data
40 | })
41 | }
42 | })
--------------------------------------------------------------------------------
/src/assets/images/401.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/images/401.gif
--------------------------------------------------------------------------------
/src/assets/images/404.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/images/404.png
--------------------------------------------------------------------------------
/src/assets/images/404_cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/images/404_cloud.png
--------------------------------------------------------------------------------
/src/assets/login/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/login/bg.png
--------------------------------------------------------------------------------
/src/assets/login/left.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/login/left.jpg
--------------------------------------------------------------------------------
/src/assets/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/assets/logo.png
--------------------------------------------------------------------------------
/src/assets/style/common.scss:
--------------------------------------------------------------------------------
1 | @import './transition.scss';
2 | @import '@/theme/index.scss';
3 |
4 | .layout-container {
5 | background-color: var(--system-container-main-background);
6 | width: calc(100% - 30px);
7 | height: calc(100% - 30px);
8 | margin: 15px;
9 | display: flex;
10 | flex-direction: column;
11 | overflow-y: auto;
12 |
13 | &-form {
14 | display: flex;
15 | justify-content: space-between;
16 | padding: 15px 15px 0;
17 |
18 | &-handle {
19 | display: flex;
20 | justify-content: flex-start;
21 |
22 | .export-excel-btn {
23 | margin-left: 15px;
24 | }
25 | }
26 |
27 | &-search {
28 | display: flex;
29 | justify-content: flex-end;
30 |
31 | .search-btn {
32 | margin-left: 15px;
33 | }
34 | }
35 |
36 | .el-form-item {
37 | margin-bottom: 0;
38 | }
39 | }
40 |
41 | &-table {
42 | flex: 1;
43 | height: 100%;
44 | padding: 15px;
45 | overflow: auto;
46 | }
47 | }
48 |
49 | .flex-box {
50 | display: flex;
51 | flex-direction: column;
52 | width: 100%;
53 | height: 100%;
54 | padding: 15px;
55 | box-sizing: border-box;
56 | }
57 |
58 | .flex {
59 | display: flex;
60 | }
61 |
62 | .center {
63 | justify-content: center;
64 | align-items: center;
65 | text-align: center;
66 | }
67 |
68 | a {
69 | text-decoration: none;
70 | }
71 |
72 | /** element-plus **/
73 | .el-icon {
74 | text-align: center;
75 | }
76 |
77 | /** 用于提示信息 **/
78 | .my-tip {
79 | background-color: #f1f1f1;
80 | padding: 5px 10px;
81 | text-align: left;
82 | border-radius: 4px;
83 | }
84 |
85 | .system-scrollbar {
86 | &::-webkit-scrollbar {
87 | display: none;
88 | width: 6px;
89 | }
90 |
91 | &::-webkit-scrollbar-thumb {
92 | border-radius: 10px;
93 | background: rgba(144, 147, 153, 0.3);
94 | }
95 |
96 | &:hover {
97 | &::-webkit-scrollbar {
98 | display: block;
99 | }
100 |
101 | &::-webkit-scrollbar-thumb {
102 | border-radius: 10px;
103 | background: rgba(144, 147, 153, 0.3);
104 |
105 | &:hover {
106 | background: rgba(144, 147, 153, 0.5);
107 | }
108 | }
109 | }
110 | }
111 |
112 | .el-form--inline {
113 | .el-form-item {
114 |
115 | &>.el-input,
116 | .el-cascader,
117 | .el-select,
118 | .el-date-editor,
119 | .el-autocomplete {
120 | width: 196px;
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/src/assets/style/transition.scss:
--------------------------------------------------------------------------------
1 | /* fade-transform */
2 | .fade-transform-leave-active,
3 | .fade-transform-enter-active {
4 | transition: all .2s;
5 | }
6 |
7 | .fade-transform-enter-from {
8 | opacity: 0;
9 | transform: translateX(-30px);
10 | transition: all .2s;
11 | }
12 |
13 | .fade-transform-leave-to {
14 | opacity: 0;
15 | transform: translateX(30px);
16 | transition: all .2s;
17 | }
18 |
19 | /* breadcrumb transition */
20 | .breadcrumb-enter-active,
21 | .breadcrumb-leave-active {
22 | transition: all .2s;
23 | }
24 |
25 | .breadcrumb-enter,
26 | .breadcrumb-leave-active {
27 | opacity: 0;
28 | transform: translateX(80px);
29 | }
30 |
31 | .breadcrumb-move {
32 | transition: all .5s;
33 | }
34 |
35 | .breadcrumb-leave-active {
36 | position: absolute;
37 | }
--------------------------------------------------------------------------------
/src/assets/svg/read.md:
--------------------------------------------------------------------------------
1 |
6 | 请在当前文件夹内放入svg文件,并删除当前文件
--------------------------------------------------------------------------------
/src/config/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Date: 2023-05-22 20:44:25
3 | * @Description:
4 | */
5 | const systemTitle = '后台管理系统' // 系统名称,用于显示在左上角模块,登录模块、以及浏览器标题上使用,使用配置项
6 | const systemSubTitle = '时间不在于你拥有多少,而在于你怎样使用。' // 系统提示信息,用于登录模块使用
7 |
8 | export {
9 | systemTitle,
10 | systemSubTitle
11 | }
--------------------------------------------------------------------------------
/src/layout/Header/Breadcrumb.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{
6 | item.meta.title }}
7 |
8 | {{ item.meta.title }}
9 |
10 |
11 |
12 |
13 |
14 |
15 |
39 |
40 |
--------------------------------------------------------------------------------
/src/layout/Header/functionList/fullscreen.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
25 |
26 |
36 |
--------------------------------------------------------------------------------
/src/layout/Header/functionList/sizeChange.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 | {{ d.name }}
12 |
13 |
14 |
15 |
16 |
17 |
18 |
47 |
48 |
--------------------------------------------------------------------------------
/src/layout/Header/functionList/theme/theme-color.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
11 |
48 |
49 |
--------------------------------------------------------------------------------
/src/layout/Header/functionList/theme/theme-icon.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
18 |
19 |
20 |
21 |
22 |
70 |
71 |
--------------------------------------------------------------------------------
/src/layout/Header/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
42 |
43 |
44 |
91 |
92 |
--------------------------------------------------------------------------------
/src/layout/Header/passwordLayer.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 管理员
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
91 |
92 |
--------------------------------------------------------------------------------
/src/layout/Logo/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
{{ systemTitle }}
5 |
6 |
7 |
8 |
23 |
24 |
--------------------------------------------------------------------------------
/src/layout/Menu/Link.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
38 |
--------------------------------------------------------------------------------
/src/layout/Menu/MenuItem.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 |
7 |
8 |
9 | {{ menu.meta.title }}
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | {{ menu.children[0].meta.title }}
19 |
20 |
21 |
22 |
24 | {{ menu.children[0].meta.title }}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | {{ menu.meta.title }}
35 |
36 |
37 |
38 |
39 |
40 |
97 |
98 |
--------------------------------------------------------------------------------
/src/layout/Menu/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
9 |
10 |
11 |
12 |
45 |
46 |
--------------------------------------------------------------------------------
/src/layout/Tabs/item.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{ menu.meta.title }}
5 |
6 |
7 |
8 |
9 |
10 |
11 |
54 |
55 |
--------------------------------------------------------------------------------
/src/layout/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
77 |
78 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Date: 2022-05-22 20:44:25
3 | * @Description:
4 | */
5 | import { createApp } from 'vue'
6 | import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
7 | import ElementPlus from 'element-plus'
8 | import * as ElementPlusIconsVue from '@element-plus/icons-vue'
9 | import 'element-plus/theme-chalk/display.css' // 引入基于断点的隐藏类
10 | import 'element-plus/dist/index.css'
11 | import 'normalize.css' // css初始化
12 | import './assets/style/common.scss' // 公共css
13 | import './theme/modules/chinese/index.scss'
14 | import App from './App.vue'
15 | import stores from './stores'
16 | import router from './router'
17 | if (import.meta.env.MODE === 'development') { // 开发环境调用
18 |
19 | }
20 |
21 | const app = createApp(App)
22 | app.use(ElementPlus, { locale: zhCn })
23 | app.use(router)
24 | app.use(stores)
25 | for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
26 | app.component(key, component)
27 | }
28 | // app.config.performance = true
29 | app.mount('#app')
30 |
--------------------------------------------------------------------------------
/src/router/createNode.ts:
--------------------------------------------------------------------------------
1 | // 1. 用于解决keep-alive需要name的问题,动态生成随机name供keep-alive使用
2 | // 2. 用于解决transition动画内部结点只能为根元素的问题,单文件可写多结点
3 | import type { DefineComponent, Component } from 'vue'
4 | import { defineComponent, h, createVNode, ref, nextTick } from 'vue'
5 | import reload from './reload.vue'
6 | import NProgress from '@/utils/system/nprogress'
7 |
8 | export function createNameComponent(component: () => Promise): () => Promise> {
9 | return () => {
10 | return new Promise((resolve) => {
11 | component().then((comm: DefineComponent<{}, {}, any>) => {
12 | const name = (comm.default.name || 'vueAdminBox') + '$' + Date.now();
13 | const tempComm = defineComponent({
14 | name,
15 | setup() {
16 | const isReload = ref(false);
17 | let timeOut: any = null;
18 | const handleReload = () => {
19 | isReload.value = true;
20 | timeOut && clearTimeout(timeOut);
21 | NProgress.start();
22 | timeOut = setTimeout(() => {
23 | nextTick(() => {
24 | NProgress.done();
25 | isReload.value = false;
26 | });
27 | }, 260);
28 | };
29 | return {
30 | isReload,
31 | handleReload
32 | };
33 | },
34 | render: function () {
35 | if (this.isReload) {
36 | return h('div', { class: 'el-main-box' }, [h(reload)]);
37 | } else {
38 | return h('div', { class: 'el-main-box' }, [createVNode(comm.default)]);
39 | }
40 | }
41 | });
42 | resolve(tempComm);
43 | });
44 | });
45 | }
46 | }
47 |
48 |
--------------------------------------------------------------------------------
/src/router/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Date: 2023-01-25 09:51:12
3 | * @LastEditTime: 2023-01-25 12:25:51
4 | * @Description:
5 | */
6 | /**
7 | * @description 所有人可使用的参数配置列表
8 | * @params hideMenu: 是否隐藏当前路由结点不在导航中展示
9 | * @params alwayShow: 只有一个子路由时是否总是展示菜单,默认false
10 | */
11 | import { reactive } from 'vue'
12 | import { createRouter, createWebHashHistory, Router } from 'vue-router'
13 | import NProgress from '@/utils/system/nprogress'
14 | import { changeTitle } from '@/utils/system/title'
15 | import { useUserStore } from '@/stores/user'
16 | import { useAppStore } from '@/stores/app'
17 | import { RouteLocationNormalized } from 'vue-router'
18 | import mainApi from '@/api/main'
19 |
20 |
21 | NProgress.configure({ showSpinner: true })
22 |
23 | // 引入不需要权限的modules
24 | import System from './modules/system'
25 |
26 | /**
27 | * @name 初始化必须要的路由
28 | * @description 使用reactive属性使得modules可以在路由菜单里面实时响应,搞定菜单回显的问题
29 | * @detail 针对modules的任何修改,均会同步至菜单级别,记住,是针对变量名为:moduels的修改
30 | **/
31 | let modules = reactive([
32 | ...System
33 | ])
34 |
35 | const router: Router = createRouter({
36 | history: createWebHashHistory(),
37 | routes: modules
38 | })
39 |
40 | // installed route
41 | const installed: any[] = []
42 |
43 | // clear router on logout
44 | export const clearRouter = () => {
45 | for (const removeRoute of installed) {
46 | removeRoute()
47 | }
48 | installed.length = 0
49 | modules = reactive([
50 | ...System
51 | ])
52 | needLoad = true
53 | }
54 |
55 | // 未授权时可访问的白名单
56 | const whiteList = ['/login']
57 |
58 | // loaded status
59 | let needLoad: boolean = true
60 |
61 | // 路由跳转前的监听操作
62 | router.beforeEach(async (to, _from, next) => {
63 | const userStore = useUserStore()
64 | // load route
65 | if (needLoad) {
66 | const appStore = useAppStore()
67 | let result: any = await mainApi.getInfo()
68 | if (result.data.name && result.data.name.length > 1) {
69 | userStore.authorize = result.data.authorize
70 | userStore.menu = result.data.menu
71 | userStore.name = result.data.name
72 | userStore.superAdmin = result.data.superAdmin
73 | for (const item of userStore.getRoute()) {
74 | modules.push(item)
75 | installed.push(router.addRoute(item))
76 | }
77 | needLoad = false
78 | // go to homepage after loaded
79 | if (['', '/', '/login'].includes(appStore.currentPath)) router.replace('/home')
80 | else router.replace(appStore.currentPath)
81 | }
82 |
83 | }
84 |
85 | NProgress.start()
86 | to.meta.title ? (changeTitle(to.meta.title)) : "" // 动态title
87 | if (userStore.name.length > 0) {
88 | next()
89 | } else if (whiteList.includes(to.path)) {
90 | next()
91 | } else {
92 | next("/login"); // 全部重定向到登录页
93 | }
94 | });
95 |
96 | // 路由跳转后的监听操作
97 | router.afterEach((to: RouteLocationNormalized | any, _from) => {
98 | const userStore = useUserStore()
99 | const name = to.matched[to.matched.length - 1].components.default.name
100 | if (to.meta && to.meta.cache && name && !userStore.cachedComponents.includes(name)) {
101 | useUserStore().cachedComponents.push(name)
102 | }
103 | useAppStore().currentPath = to.fullPath
104 | NProgress.done()
105 | });
106 |
107 |
108 | export {
109 | modules
110 | }
111 |
112 | export default router
113 |
--------------------------------------------------------------------------------
/src/router/index.type.ts:
--------------------------------------------------------------------------------
1 | import type { DefineComponent } from 'vue'
2 | import type { RouteRecordRaw } from 'vue-router'
3 |
4 | /** @name 基础路由类型 */
5 | export type Route = {
6 | /** @name 访问路径 */
7 | path: string
8 | /** @name 需要使用的组件 @description 两种类型,第一种是默认的Vue文件类型,第二种是通过createNameComponent搞出来的,凡是一个组件需要keep-alive,必须使用createNameComponent来搞定 */
9 | component: DefineComponent<{}, {}, any> | (() => Promise>)
10 | /** @name 基础元数据 */
11 | meta: Meta
12 |
13 | /** @name 路由名称,全局唯一,可以不填 */
14 | name?: string
15 | /** @name 需要重定向的地址,可选 */
16 | redirect?: string
17 | /** @name 总是显示菜单,可选 @description 大部分时候针对二级三级四级菜单的根结点,不设置的话,子元素只有一个的时候默认显示子元素,隐藏父元素 @default false */
18 | alwayShow?: boolean
19 | /** @name 是否隐藏菜单,可选 @description 这个属性通常用于详情页面、404、401页面等不需要显示在总菜单里面的 @default false */
20 | hideMenu?: boolean
21 | /** @name 路由子集,和Route类型一致的数组,可选 */
22 | children?: Route[]
23 | } & RouteRecordRaw
24 |
25 | /** @name 基础元数据的类型说明 */
26 | export interface Meta {
27 | /** @name 标题 @description 可供很多地方使用,在国际化版本中使用i18n对应的值,非国际化版本中使用真实的路由值 */
28 | title: string
29 | /** @name 使用的icon的值,可选 @description 对应自己Iconfont链接库进来,通常只在一级菜单使用,但二级三级使用也没问题 */
30 | icon?: string
31 | /** @name 是否需要缓存页面,目前仅支持二级菜单缓存,多级菜单缓存会在未来支持,可选 @default false */
32 | cache?: boolean
33 | /** @name 是否隐藏标签页,可选 @default false */
34 | hideTabs?: boolean
35 | /** @name 左侧菜单强制聚焦时的路由,比如新增、编辑一类页面,可能需要使用 */
36 | activeMenu?: string
37 | /** @name 任意值 @description 供自行扩展使用,但推荐在上面自己定义好 */
38 | [key: string]: any
39 | }
--------------------------------------------------------------------------------
/src/router/modules/dashboard.ts:
--------------------------------------------------------------------------------
1 | import type { Route } from '../index.type'
2 | import Layout from '@/layout/index.vue'
3 | import { createNameComponent } from '../createNode'
4 | const route: Route[] = [
5 | {
6 | path: '/',
7 | component: Layout,
8 | redirect: '/dashboard',
9 | meta: { title: 'dashboard', icon: 'sfont system-home' },
10 | children: [
11 | {
12 | path: 'dashboard',
13 | component: createNameComponent(() => import('@/views/main/dashboard/index.vue')),
14 | meta: { cache: true, title: '首页', icon: 'sfont system-home', hideClose: true }
15 | }
16 | ]
17 | },
18 | {
19 | path: "/system",
20 | component: Layout,
21 | meta: { title: "系统管理", icon: "sfont system-document" },
22 | children: [
23 | {
24 | path: "menu",
25 | meta: { cache: true, title: "菜单管理" },
26 | component: createNameComponent(() => import('@/views/system/menu.vue'))
27 | },
28 | {
29 | path: "log",
30 | meta: { cache: true, title: "管理日志" },
31 | component: createNameComponent(() => import('@/views/system/log.vue'))
32 | },
33 | {
34 | path: "info",
35 | meta: { cache: true, title: "系统信息" },
36 | component: createNameComponent(() => import('@/views/system/info.vue'))
37 | },
38 | ]
39 | }
40 | ]
41 |
42 | export default route
--------------------------------------------------------------------------------
/src/router/modules/system.ts:
--------------------------------------------------------------------------------
1 | import type { Route } from '../index.type'
2 | import Layout from '@/layout/index.vue'
3 | import { createNameComponent } from '../createNode'
4 | const route: Route[] = [
5 | {
6 | path: '/system',
7 | component: Layout,
8 | redirect: '/404',
9 | hideMenu: true,
10 | meta: { title: '系统目录' },
11 | children: [
12 | {
13 | path: '/404',
14 | component: createNameComponent(() => import('@/views/main/404.vue')),
15 | meta: { title: '404', hideTabs: true }
16 | },
17 | {
18 | path: '/401',
19 | component: createNameComponent(() => import('@/views/main/401.vue')),
20 | meta: { title: '401', hideTabs: true }
21 | },
22 | {
23 | path: '/redirect/:path(.*)',
24 | component: createNameComponent(() => import('@/views/main/redirect.vue')),
25 | meta: { title: '重定向页面', hideTabs: true }
26 | }
27 | ]
28 | },
29 | {
30 | path: '/login',
31 | component: createNameComponent(() => import('@/views/main/login.vue')),
32 | hideMenu: true,
33 | meta: { title: '登录', hideTabs: true }
34 | },
35 | {
36 | // 找不到路由重定向到404页面
37 | path: "/:pathMatch(.*)",
38 | component: Layout,
39 | redirect: "/404",
40 | hideMenu: true,
41 | meta: { title: '' },
42 | children: []
43 | }
44 | ]
45 |
46 | export default route
--------------------------------------------------------------------------------
/src/router/permission/front.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * 前端路由管理
3 | **/
4 |
5 | /** 路由类型 */
6 | import type { Route } from '../index.type'
7 |
8 | /** 引入需要权限的Modules */
9 | import Dashboard from '../modules/dashboard'
10 |
11 | /** 登录后需要动态加入的本地路由 */
12 | const FrontRoutes: Route[] = [
13 | ...Dashboard,
14 | ]
15 |
16 | export default FrontRoutes
--------------------------------------------------------------------------------
/src/router/reload.vue:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
14 |
15 |
--------------------------------------------------------------------------------
/src/stores/app.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 |
3 |
4 | export const useAppStore = defineStore('app', {
5 | persist: true,
6 | state: () => {
7 | return {
8 | currentPath: '' as string, // 当前页面路径
9 | isCollapse: false as boolean, // 侧边栏是否收缩展示
10 | contentFullScreen: false as boolean, // 内容是否可全屏展示
11 | showLogo: true as boolean, // 是否显示Logo
12 | fixedTop: false as boolean, // 是否固定顶部, todo,暂未使用
13 | showTabs: true as boolean, // 是否显示导航历史
14 | expandOneMenu: true as boolean, // 一次是否只能展开一个菜单
15 | elementSize: "default" as "" | "default" | "small" | "large", // element默认尺寸,支持官网'large / default /small'小参数
16 | lang: '', // 默认采用的国际化方案,初次进入,采用浏览器当前设置的语言,默认采用中文
17 | theme: {
18 | style: 'default',
19 | primaryColor: '#409eff',
20 | menuType: 'side'
21 | },
22 | tabs: [] as any[] // 标签列表
23 |
24 | }
25 | },
26 | getters: {
27 | },
28 | actions: {
29 | },
30 | })
--------------------------------------------------------------------------------
/src/stores/index.ts:
--------------------------------------------------------------------------------
1 | import { createPinia } from "pinia"
2 | import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
3 |
4 | const stores = createPinia()
5 | stores.use(piniaPluginPersistedstate)
6 |
7 | export default stores
--------------------------------------------------------------------------------
/src/stores/user.ts:
--------------------------------------------------------------------------------
1 | import { defineStore } from 'pinia'
2 | import mainApi from '@/api/main'
3 |
4 | import router, { clearRouter } from '@/router'
5 | import Layout from '@/layout/index.vue'
6 | import { createNameComponent } from '../router/createNode'
7 | import { useAppStore } from './app'
8 |
9 | export const useUserStore = defineStore('user', {
10 | state: () => {
11 | return {
12 | authorize: [] as string[],
13 | cachedComponents: [] as string[],
14 | menu: [] as any[],
15 | name: '' as string,
16 | superAdmin: false as boolean
17 | }
18 | },
19 | getters: {
20 |
21 | },
22 | actions: {
23 | /**
24 | * get route
25 | * @returns route
26 | */
27 | getRoute() {
28 | const recurse = (items: any[], level: number = 1) => {
29 | const result: any[] = []
30 | for (const item of items) {
31 | const obj = { ...item }
32 | obj.meta = Object.assign({}, item.meta)
33 | if (level === 1) {
34 | if (item.path == undefined) continue;
35 | obj.component = Layout
36 | obj.children = recurse(item.children, level + 1)
37 | } else if (level === 2) {
38 | /*
39 | * 不支持完全的动态文件名,webpack 的工作原理是对文件进行静态扫描,然后根据一定规则处理的。
40 | * webpack 在扫描到“import()”语法时,会将变量转换成正则表达式的“.*”,然后根据这个规则匹配文件名,对匹配上的文件独立 chunk 输出
41 | */
42 | if (item.component == undefined || item.path == undefined) continue;
43 | const path: string[] = item.component.split("/")
44 | obj.component = null
45 | switch (path.length) {
46 | case 1: obj.component = createNameComponent(() => import(`@/views/${path[0]}.vue`))
47 | break;
48 | case 2: obj.component = createNameComponent(() => import(`@/views/${path[0]}/${path[1]}.vue`))
49 | break;
50 | case 3: obj.component = createNameComponent(() => import(`@/views/${path[0]}/${path[1]}/${path[2]}.vue`))
51 | break;
52 | }
53 | if (obj.component === null) {
54 | throw new Error('component error: ' + item.component)
55 | }
56 | }
57 | result.push(obj)
58 | }
59 | return result
60 | }
61 |
62 | const route = recurse(this.menu)
63 | return route
64 | },
65 | hasAuthorize(name: string): boolean {
66 | if (this.superAdmin) return true
67 | return this.authorize.includes(name)
68 | },
69 | login(loginParam: any) {
70 | return new Promise((resolve, reject) => {
71 | mainApi.login(loginParam)
72 | .then(res => {
73 | this.name = res.data.name
74 | useAppStore().tabs = []
75 | resolve(res.data)
76 | }).catch(err => {
77 | reject(err)
78 | })
79 | })
80 | },
81 | logout() {
82 | mainApi.logout().then(() => {
83 | this.$reset()
84 | useAppStore().tabs = []
85 | clearRouter()
86 | router.replace('/login')
87 | })
88 |
89 | },
90 | },
91 | })
--------------------------------------------------------------------------------
/src/theme/index.scss:
--------------------------------------------------------------------------------
1 | :root {
2 | // 主题色
3 | --system-primary-color: #409eff; // 可做背景色和文本色,用做背景色时,需要和--system-primary-text-color配合使用,避免文件颜色和主题色冲突
4 | --system-primary-text-color: #fff; // 主题色作为背景色时使用
5 |
6 | // logo颜色相关
7 | --system-logo-color: #f1f1f1;
8 | --system-logo-background: #263445;
9 |
10 | // 菜单颜色相关
11 | --system-menu-text-color: #bfcbd9;
12 | --system-menu-background: #181f31;
13 | --system-menu-children-background: #1f2d3d;
14 | --system-menu-submenu-active-color: #fff;
15 | --system-menu-hover-background: #203448;
16 |
17 | // header区域
18 | --system-header-background: #fff;
19 | --system-header-text-color: #303133;
20 | --system-header-breadcrumb-text-color: #606266;
21 | --system-header-item-hover-color: rgba(0,0,0,.06);
22 | --system-header-border-color: #d8dce5;
23 | --system-header-tab-background: #fff;
24 |
25 | // contaier区域,父框架
26 | --system-container-background: #f0f2f5;
27 | --system-container-main-background: #fff;
28 |
29 | // 页面区域, 这一块是你在自己写的文件中使用主题,核心需要关注的地方
30 | --system-page-background: #fff; // 主背景
31 | --system-page-color: #303133; // 主要的文本颜色
32 | --system-page-tip-color: rgba(0, 0, 0, 0.45); // 协助展示的文本颜色
33 | --system-page-border-color: #ebeef5; // 通用的边框配置色,便于主题扩展
34 |
35 | // element主题色修改
36 | --el-color-primary: var(--system-primary-color);
37 | }
38 |
39 | // 进度条颜色修改为主题色
40 | body #nprogress .bar {
41 | background-color: var(--system-primary-color);
42 | }
43 | body #nprogress .peg {
44 | box-shadow: 0 0 10px var(--system-primary-color), 0 0 5px var(--system-primary-color);
45 | }
46 | body #nprogress .spinner-icon {
47 | border-top-color: var(--system-primary-color);
48 | border-left-color: var(--system-primary-color);
49 | }
50 |
51 | @import './modules/dark.scss';
--------------------------------------------------------------------------------
/src/theme/index.ts:
--------------------------------------------------------------------------------
1 |
2 | export interface Colors {
3 | name: '' // 非国际化版本直接写字符串,如:默认菜单风格
4 | menu: {
5 | textColor: string
6 | background: string
7 | childrenBackground: string
8 | hoverBackground: string
9 | submenuActiveColor: string
10 | }
11 | logo: {
12 | color: string
13 | background: string
14 | }
15 | header: {
16 | background: string
17 | textColor: string
18 | itemHoverColor: string
19 | breadcrumbTextColor: string
20 | borderColor: string
21 | tabBackground: string
22 | }
23 | container: {
24 | background: string
25 | mainBackground: string
26 | }
27 | page: {
28 | background: string
29 | color: string
30 | tipColor: string
31 | borderColor: string
32 | }
33 | }
34 |
35 | export interface Style {
36 | default: Colors
37 | light: Colors
38 | dark: Colors,
39 | [propName: string]: Colors
40 | }
41 | export const style: Style = {
42 | 'default': {
43 | name: '默认菜单风格',
44 | menu: {
45 | textColor: '#bfcbd9',
46 | background: '#181f31',
47 | childrenBackground: '#1f2d3d',
48 | hoverBackground: '#203448',
49 | submenuActiveColor: '#fff'
50 | },
51 | logo: {
52 | color: '#f1f1f1',
53 | background: '#263445'
54 | },
55 | header: {
56 | background: '#fff',
57 | textColor: '#303133',
58 | itemHoverColor: 'rgba(0,0,0,.06)',
59 | breadcrumbTextColor: '#606266',
60 | borderColor: '#d8dce5',
61 | tabBackground: '#fff'
62 | },
63 | container: {
64 | background: '#f0f2f5',
65 | mainBackground: '#fff'
66 | },
67 | page: {
68 | background: '#fff',
69 | color: '#303133',
70 | tipColor: 'rgba(0, 0, 0, 0.45)',
71 | borderColor: '#ebeef5'
72 | }
73 | },
74 | 'light': {
75 | name: '亮色菜单风格',
76 | menu: {
77 | textColor: '#272727',
78 | background: '#fff',
79 | childrenBackground: '#fff',
80 | hoverBackground: '#f1f1f1',
81 | submenuActiveColor: 'var(--system-primary-color)'
82 | },
83 | logo: {
84 | color: '#000',
85 | background: '#fff'
86 | },
87 | header: {
88 | background: '#fff',
89 | textColor: '#303133',
90 | itemHoverColor: 'rgba(0,0,0,.025)',
91 | breadcrumbTextColor: '#606266',
92 | borderColor: '#d8dce5',
93 | tabBackground: '#fff'
94 | },
95 | container: {
96 | background: '#f0f2f5',
97 | mainBackground: '#fff'
98 | },
99 | page: {
100 | background: '#fff',
101 | color: '#303133',
102 | tipColor: 'rgba(0, 0, 0, 0.45)',
103 | borderColor: '#ebeef5'
104 | }
105 | },
106 | 'chinese': {
107 | name: '中国水墨风',
108 | menu: {
109 | textColor: '#c7c7c7',
110 | background: '#232323',
111 | childrenBackground: '#292929',
112 | hoverBackground: '#1d1d1d',
113 | submenuActiveColor: 'var(--system-primary-color)'
114 | },
115 | logo: {
116 | color: '#fff',
117 | background: '#232323'
118 | },
119 | header: {
120 | background: '#f1f0ed',
121 | textColor: '#303133',
122 | itemHoverColor: 'rgba(0,0,0,.025)',
123 | breadcrumbTextColor: '#606266',
124 | borderColor: '#d8dce5',
125 | tabBackground: 'rgba(216, 216, 216, 0.51)'
126 | },
127 | container: {
128 | background: 'rgba(255, 255, 255, 0.92)',
129 | mainBackground: 'rgba(255, 255, 255, 0.92)'
130 | },
131 | page: {
132 | background: 'rgba(255, 255, 255, 0.92)',
133 | color: '#303133',
134 | tipColor: 'rgba(0, 0, 0, 0.45)',
135 | borderColor: '#ebeef5'
136 | }
137 | },
138 | 'dark': {
139 | name: '暗色菜单风格',
140 | menu: {
141 | textColor: '#bbb',
142 | background: '#18181c',
143 | childrenBackground: '#18181c',
144 | hoverBackground: '#000',
145 | submenuActiveColor: '#fff'
146 | },
147 | logo: {
148 | color: '#fff',
149 | background: '#18181c'
150 | },
151 | header: {
152 | background: '#18181c',
153 | textColor: '#e3e3e4',
154 | itemHoverColor: '#000',
155 | breadcrumbTextColor: '#fff',
156 | borderColor: '#3e3e3e',
157 | tabBackground: '#1b1b1b'
158 | },
159 | container: {
160 | background: '#000',
161 | mainBackground: '#18181c'
162 | },
163 | page: {
164 | background: '#18181c',
165 | color: '#c7c7c7',
166 | tipColor: 'rgba(255, 255, 255, 0.45)',
167 | borderColor: '#3e3e3e'
168 | }
169 | }
170 | }
--------------------------------------------------------------------------------
/src/theme/modules/chinese/index.scss:
--------------------------------------------------------------------------------
1 | // 带有本地背景图片的主题需要在main.ts里面主动引入,否则无法正常解析
2 | [data-theme='chinese'] {
3 | .el-main {
4 | background-image: url("./screen.png");
5 | background-size: 100% 100%;
6 | }
7 | }
--------------------------------------------------------------------------------
/src/theme/modules/chinese/screen.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swq8/vue-manage/f6182714ef62c96184e62d74808681544347320b/src/theme/modules/chinese/screen.png
--------------------------------------------------------------------------------
/src/theme/modules/dark.scss:
--------------------------------------------------------------------------------
1 | [data-theme="dark"] {
2 | // 通用
3 | p, h1, h2, h3, h4, h5, h6, article {
4 | color: var(--system-page-color);
5 | }
6 | .el-tree {
7 | background-color: var(--system-page-background);
8 | --el-color-primary-light-9: #272727;
9 | .el-tree-node__content:hover {
10 | background-color: #272727;
11 | }
12 | }
13 | .el-card {
14 | background-color: var(--system-page-background);
15 | color: var(--system-page-color);
16 | border-color: var(--system-page-border-color);
17 | .el-card__header {
18 | border-color: var(--system-page-border-color);
19 | }
20 | }
21 | // 页面内部样式修改
22 |
23 | }
--------------------------------------------------------------------------------
/src/types/images.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.bmp'
2 | declare module '*.gif'
3 | declare module '*.jpg'
4 | declare module '*.jpeg'
5 | declare module '*.png'
6 | declare module '*.svg'
7 | declare module '*.tiff'
8 | declare module '*.webp'
--------------------------------------------------------------------------------
/src/types/main.d.ts:
--------------------------------------------------------------------------------
1 | interface GeneralDto {
2 | id?: number,
3 | ip?: string,
4 | keyword?: string,
5 | name?: string,
6 | pass?: string,
7 | page?: number,
8 | pageSize?: number,
9 | q?: string,
10 | sort?: string
11 | }
--------------------------------------------------------------------------------
/src/types/shims-vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import { DefineComponent } from 'vue'
3 | const component: DefineComponent<{}, {}, any>
4 | export default component
5 | }
6 | // 国际化声明
7 | declare module 'element-plus/dist/locale/*.mjs';
8 |
--------------------------------------------------------------------------------
/src/utils/index.ts:
--------------------------------------------------------------------------------
1 | import * as math from 'mathjs'
2 | /**
3 | * 从目标对象中拷贝已有的属性
4 | *
5 | * @param objA
6 | * @param objB
7 | */
8 | export const objAssign = (objA: any, objB: any): void => {
9 | let keysA = Object.keys(objA)
10 | let keysB = Object.keys(objB)
11 | //交集
12 | let arr = keysA.filter(item => keysB.indexOf(item) > -1)
13 | for (const key of arr) {
14 | objA[key] = objB[key]
15 | }
16 |
17 | }
18 |
19 | export const priceToNumber = (price: number | string): number => {
20 | return parseInt(math.multiply(math.bignumber(price), math.bignumber(100)).toString())
21 | }
22 |
23 | /**
24 | * price format, like this: 1020 -> 10.20
25 | *
26 | * @param
27 | */
28 | export const priceFormat = (price: number | string): string => {
29 | const num = Number(price)
30 | if (num < 10) {
31 | return "0.0" + price;
32 | } else if (num < 100) {
33 | return "0." + num;
34 | }
35 | let rem = num % 100;
36 | let i = Math.floor(num / 100);
37 | if (rem < 10) {
38 | return i + ".0" + rem;
39 | } else {
40 | return i + "." + rem;
41 | }
42 | }
--------------------------------------------------------------------------------
/src/utils/system/nprogress.ts:
--------------------------------------------------------------------------------
1 | import NProgress from "nprogress"
2 | import "nprogress/nprogress.css"
3 |
4 | NProgress.configure({
5 | easing: 'ease', // 动画方式
6 | speed: 500, // 递增进度条的速度
7 | showSpinner: true, // 是否显示加载ico
8 | trickleSpeed: 200, // 自动递增间隔
9 | minimum: 0.3 // 初始化时的最小百分比
10 | })
11 |
12 | export default NProgress
--------------------------------------------------------------------------------
/src/utils/system/request.ts:
--------------------------------------------------------------------------------
1 | import axios, { AxiosError, AxiosResponse, AxiosInstance, InternalAxiosRequestConfig } from 'axios'
2 | import { useUserStore } from '@/stores/user'
3 | import { ElMessage } from 'element-plus'
4 | const baseURL: any = import.meta.env.VITE_BASE_URL
5 |
6 | const service: AxiosInstance = axios.create({
7 | baseURL: baseURL,
8 | timeout: 10000
9 | })
10 |
11 | // 请求前的统一处理
12 | service.interceptors.request.use(
13 | (config: InternalAxiosRequestConfig) => {
14 | // JWT鉴权处理
15 | const userStore = useUserStore()
16 | if (userStore.name) {
17 | config.headers['name'] = userStore.name
18 | }
19 | return config
20 | },
21 | (error: AxiosError) => {
22 | console.log(error) // for debug
23 | return Promise.reject(error)
24 | }
25 | )
26 |
27 | /**
28 | * response.code mean
29 | * SUCCESS = 1
30 | * FORBIDDEN = 2
31 | * NO_PERMISSIONS = 3
32 | * BAD_REQUEST = 4
33 | * ERROR = 5
34 | */
35 |
36 | service.interceptors.response.use(
37 | (response: AxiosResponse) => {
38 | const res = response.data
39 | if (res.code === 1) {
40 | return res
41 | } else {
42 | showError(res)
43 | return Promise.reject(res)
44 | }
45 | },
46 | (error: AxiosError) => {
47 | console.log(error) // for debug
48 | const badMessage: any = error.message || error
49 | const code = parseInt(badMessage.toString().replace('Error: Request failed with status code ', ''))
50 | showError({ code, message: badMessage })
51 | return Promise.reject(error)
52 | }
53 | )
54 |
55 | // 错误处理
56 | function showError(error: any) {
57 | // token过期,清除本地数据,并跳转至登录页面
58 | if (error.code === 2) {
59 | // to login
60 | useUserStore().logout()
61 |
62 | } else {
63 | ElMessage({
64 | message: error.msg || error.message || '服务异常',
65 | type: 'error',
66 | duration: 3000
67 | })
68 | }
69 |
70 | }
71 |
72 | export default service
--------------------------------------------------------------------------------
/src/utils/system/statistics.ts:
--------------------------------------------------------------------------------
1 | // 百度统计代码,需自行更换
2 | export function baidu() {
3 | const script = document.createElement('script')
4 | script.type = 'text/javascript'
5 | script.text = `
6 | var _hmt = _hmt || [];
7 | (function() {
8 | var hm = document.createElement("script");
9 | hm.src = "https://hm.baidu.com/hm.js?bd78bc908e66174e7dde385bf37cb4c1";
10 | var s = document.getElementsByTagName("script")[0];
11 | s.parentNode.insertBefore(hm, s);
12 | })();
13 | `
14 | document.getElementsByTagName('head')[0].appendChild(script)
15 | }
--------------------------------------------------------------------------------
/src/utils/system/title.ts:
--------------------------------------------------------------------------------
1 | import { systemTitle } from '@/config'
2 |
3 | export function changeTitle(name: any) {
4 | document.title = `${name}-${systemTitle}`
5 | }
6 |
--------------------------------------------------------------------------------
/src/utils/tab/index.ts:
--------------------------------------------------------------------------------
1 | /*
2 | * @Date: 2022-09-25 20:05:01
3 | * @Description: tab面板的操作方法
4 | */
5 |
6 | /** 关闭当前标签 */
7 | export const closeCurrentTab = (nextPath?: string) => {
8 | /** 拿到tab组件 */
9 | const tab = document.getElementById('vueAdminBoxTabCloseSelf')
10 | if (nextPath) {
11 | /** 设置下一个tab的路径 */
12 | tab?.setAttribute('nextpath', nextPath)
13 | }
14 | /** 触发tab事件点击 */
15 | tab?.click()
16 | if (nextPath) {
17 | setTimeout(() => {
18 | /** 清除下一个tab的路径 */
19 | tab?.removeAttribute('nextpath')
20 | }, 100)
21 | }
22 | }
23 |
24 | /** 关闭其他标签 */
25 | export const closeOtherTab = () => {
26 | /** 拿到tab组件 */
27 | const tab = document.getElementById('vueAdminBoxTabCloseOther')
28 | /** 触发tab事件点击 */
29 | tab?.click()
30 | }
31 |
32 | /** 关闭所有标签 */
33 | export const closeAllTab = () => {
34 | /** 拿到tab组件 */
35 | const tab = document.getElementById('vueAdminBoxTabCloseAll')
36 | /** 触发tab事件点击 */
37 | tab?.click()
38 | }
39 |
40 | /** 刷新当前标签 */
41 | export const refreshCurrentTab = () => {
42 | /** 拿到tab组件 */
43 | const tab = document.getElementById('vueAdminBoxTabRefresh')
44 | /** 触发tab事件点击 */
45 | tab?.click()
46 | }
--------------------------------------------------------------------------------
/src/views/express/freeRule.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 包邮规则
4 |
5 |
6 |
7 |
8 |
9 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | 保存
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
74 |
75 |
--------------------------------------------------------------------------------
/src/views/goods/template.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 商品模板
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | 保存
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
108 |
109 |
--------------------------------------------------------------------------------
/src/views/main/redirect.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/views/other/staticRes.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | 静态文件
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | 保存
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
67 |
68 |
--------------------------------------------------------------------------------
/src/views/system/components/ElIconPicker.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{ modelValue || '请选择图标'
6 | }}
7 |
8 |
9 |
11 |
12 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
76 |
77 |
--------------------------------------------------------------------------------
/src/views/user/balanceLog.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | 查询
10 |
11 |
12 |
13 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
26 |
27 |
28 |
115 |
116 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "allowJs": true,
4 | "target": "esnext",
5 | "module": "esnext",
6 | "moduleResolution": "node",
7 | "strict": true,
8 | "jsx": "preserve",
9 | "sourceMap": true,
10 | "resolveJsonModule": true,
11 | "esModuleInterop": true,
12 | "lib": [
13 | "esnext",
14 | "dom"
15 | ],
16 | "types": [
17 | "element-plus/global",
18 | "vite/client",
19 | "node"
20 | ],
21 | "typeRoots": [
22 | "node_modules",
23 | "node_modules/@types"
24 | ],
25 | "baseUrl": "./",
26 | "paths": {
27 | "@/*": [
28 | "src/*"
29 | ]
30 | }
31 | },
32 | "include": [
33 | "src/**/*.ts",
34 | "src/**/*.d.ts",
35 | "src/**/*.tsx",
36 | "src/**/*.vue"
37 | ]
38 | }
--------------------------------------------------------------------------------
/vite.config.mts:
--------------------------------------------------------------------------------
1 | import { ConfigEnv, UserConfigExport } from 'vite'
2 | import vue from '@vitejs/plugin-vue'
3 | import { vitePluginSvg } from "@webxrd/vite-plugin-svg"
4 | import { resolve } from 'path'
5 |
6 | const pathResolve = (dir: string): any => {
7 | return resolve(__dirname, ".", dir)
8 | }
9 |
10 | const alias: Record = {
11 | '@': pathResolve("src")
12 | }
13 |
14 | /**
15 | * @description-en vite document address
16 | * @description-cn vite官网
17 | * https://vitejs.cn/config/ */
18 | export default ({ command }: ConfigEnv): UserConfigExport => {
19 | return {
20 | base: './',
21 | build: {
22 | chunkSizeWarningLimit: 20_000
23 | },
24 | // optimized dependencies changed
25 | optimizeDeps: {
26 | include: ['@tinymce/tinymce-vue', 'mathjs']
27 | },
28 | server: {
29 | host: '0.0.0.0',
30 | proxy: {
31 | // 接口地址代理
32 | '/adminApi': {
33 | target: 'http://127.0.0.1:8080',
34 | changeOrigin: true, // 跨域
35 | // rewrite: path => path.replace(/^\/demo/, '/demo')
36 | },
37 | // 图片资源代理
38 | '/img': {
39 | target: 'http://127.0.0.1:8080',
40 | changeOrigin: true, // 跨域
41 | },
42 | }
43 | },
44 | resolve: {
45 | alias
46 | },
47 | plugins: [
48 | vue(),
49 | vitePluginSvg({
50 | // 必要的。必须是绝对路径组成的数组。
51 | iconDirs: [
52 | resolve(__dirname, 'src/assets/svg'),
53 | ],
54 | // 必要的。入口script
55 | main: resolve(__dirname, 'src/main.js'),
56 | symbolIdFormat: 'icon-[name]'
57 | }),
58 | ],
59 | css: {
60 | postcss: {
61 | plugins: [
62 | {
63 | postcssPlugin: 'internal:charset-removal',
64 | AtRule: {
65 | charset: (atRule) => {
66 | if (atRule.name === 'charset') {
67 | atRule.remove();
68 | }
69 | }
70 | }
71 | }
72 | ],
73 | },
74 | }
75 | };
76 | }
77 |
--------------------------------------------------------------------------------