dev
Wayne 2 years ago
parent 06c203ccea
commit b28b9f520b

@ -8,6 +8,8 @@
│ ├── helpers.php
│ └── bootstrap.php
├── web 前台前端
├── nginx nginx docker 建構資料
├── mysql mysql docker 建構資料
└── data 系統資枓
### 前端

@ -49,7 +49,7 @@ Follow the guides available on https://ckeditor.com/docs/ckeditor5/latest/framew
## FAQ
| Where is the place to report bugs and feature requests?
You can create an issue on https://github.com/ckeditor/ckeditor5/issues including the build id - `159xygvqs85-m65lqtchlynm`. Make sure that the question / problem is unique, please look for a possibly asked questions in the search box. Duplicates will be closed.
You can create an issue on https://github.com/ckeditor/ckeditor5/issues including the build id - `rv3q54x35x49-lgc6tk0e6ik`. Make sure that the question / problem is unique, please look for a possibly asked questions in the search box. Duplicates will be closed.
| Where can I learn more about the CKEditor 5 framework?

@ -9,6 +9,7 @@ import { BlockQuote } from '@ckeditor/ckeditor5-block-quote';
import { CloudServices } from '@ckeditor/ckeditor5-cloud-services';
import type { EditorConfig } from '@ckeditor/ckeditor5-core';
import { Essentials } from '@ckeditor/ckeditor5-essentials';
import { FontBackgroundColor, FontColor, FontSize } from '@ckeditor/ckeditor5-font';
import { Heading } from '@ckeditor/ckeditor5-heading';
import { Image, ImageCaption, ImageResize, ImageStyle, ImageToolbar, ImageUpload } from '@ckeditor/ckeditor5-image';
import { Indent } from '@ckeditor/ckeditor5-indent';
@ -23,7 +24,7 @@ import { TextTransformation } from '@ckeditor/ckeditor5-typing';
import { Undo } from '@ckeditor/ckeditor5-undo';
import { SimpleUploadAdapter } from '@ckeditor/ckeditor5-upload';
declare class Editor extends ClassicEditor {
static builtinPlugins: (typeof Autoformat | typeof BlockQuote | typeof Bold | typeof CloudServices | typeof Essentials | typeof Heading | typeof Image | typeof ImageCaption | typeof ImageResize | typeof ImageStyle | typeof ImageToolbar | typeof ImageUpload | typeof Indent | typeof Italic | typeof Link | typeof List | typeof MediaEmbed | typeof Paragraph | typeof PasteFromOffice | typeof SimpleUploadAdapter | typeof SourceEditing | typeof Table | typeof TableToolbar | typeof TextTransformation | typeof Undo)[];
static builtinPlugins: (typeof Autoformat | typeof BlockQuote | typeof Bold | typeof CloudServices | typeof Essentials | typeof FontBackgroundColor | typeof FontColor | typeof FontSize | typeof Heading | typeof Image | typeof ImageCaption | typeof ImageResize | typeof ImageStyle | typeof ImageToolbar | typeof ImageUpload | typeof Indent | typeof Italic | typeof Link | typeof List | typeof MediaEmbed | typeof Paragraph | typeof PasteFromOffice | typeof SimpleUploadAdapter | typeof SourceEditing | typeof Table | typeof TableToolbar | typeof TextTransformation | typeof Undo)[];
static defaultConfig: EditorConfig;
}
export default Editor;

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(function(e){const i=e["bs"]=e["bs"]||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"%0 od %1","Block quote":"Citat",Bold:"Podebljano","Break text":"",Cancel:"Poništi","Caption for image: %0":"","Caption for the image":"","Centered image":"Centrirana slika","Change image text alternative":"Promijeni ALT atribut za sliku","Choose heading":"Odaberi naslov",Clear:"",Code:"Kod","Enter image caption":"Unesi naziv slike","Full size image":"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6","Image resize list":"Lista veličina slike","Image toolbar":"","image widget":"","In line":"",Insert:"Umetni","Insert image":"Umetni sliku","Insert image via URL":"Umetni sliku preko URLa",Italic:"Zakrivljeno","Left aligned image":"Lijevo poravnata slika",Original:"Original",Paragraph:"Paragraf","Remove color":"Ukloni boju","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"Promijeni veličinu slike","Resize image to %0":"","Resize image to the original size":"Postavi originalnu veličinu slike","Restore default":"Vrati na zadano","Right aligned image":"Desno poravnata slika",Save:"Sačuvaj","Show more items":"Prikaži više stavki","Side image":"",Strikethrough:"Precrtano",Subscript:"",Superscript:"","Text alternative":"ALT atribut","Type or paste your content here.":"Unesite ili zalijepite vaš sadržaj ovdje","Type your title":"Unesite naslov",Underline:"Podcrtano",Update:"Ažuriraj","Update image URL":"Ažuriraj URL slike","Upload failed":"Učitavanje slike nije uspjelo","Upload from computer":"","Upload image from computer":"","Wrap text":"Prelomi tekst"});i.getPluralForm=function(e){return e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
(function(e){const i=e["bs"]=e["bs"]||{};i.dictionary=Object.assign(i.dictionary||{},{"%0 of %1":"%0 od %1",Big:"","Block quote":"Citat",Bold:"Podebljano","Break text":"",Cancel:"Poništi","Caption for image: %0":"","Caption for the image":"","Centered image":"Centrirana slika","Change image text alternative":"Promijeni ALT atribut za sliku","Choose heading":"Odaberi naslov",Clear:"",Code:"Kod",Default:"Zadani","Document colors":"","Enter image caption":"Unesi naziv slike","Font Background Color":"Boja pozadine","Font Color":"Boja","Font Family":"Font","Font Size":"Veličina fonta","Full size image":"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6",Huge:"","Image resize list":"Lista veličina slike","Image toolbar":"","image widget":"","In line":"",Insert:"Umetni","Insert image":"Umetni sliku","Insert image via URL":"Umetni sliku preko URLa",Italic:"Zakrivljeno","Left aligned image":"Lijevo poravnata slika",Original:"Original",Paragraph:"Paragraf","Remove color":"Ukloni boju","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"Promijeni veličinu slike","Resize image to %0":"","Resize image to the original size":"Postavi originalnu veličinu slike","Restore default":"Vrati na zadano","Right aligned image":"Desno poravnata slika",Save:"Sačuvaj","Show more items":"Prikaži više stavki","Side image":"",Small:"",Strikethrough:"Precrtano",Subscript:"",Superscript:"","Text alternative":"ALT atribut",Tiny:"","Type or paste your content here.":"Unesite ili zalijepite vaš sadržaj ovdje","Type your title":"Unesite naslov",Underline:"Podcrtano",Update:"Ažuriraj","Update image URL":"Ažuriraj URL slike","Upload failed":"Učitavanje slike nije uspjelo","Upload from computer":"","Upload image from computer":"","Wrap text":"Prelomi tekst"});i.getPluralForm=function(e){return e%10==1&&e%100!=11?0:e%10>=2&&e%10<=4&&(e%100<10||e%100>=20)?1:2}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(function(e){const a=e["jv"]=e["jv"]||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"%0 saking %1",Bold:"Kandhel","Break text":"","Bulleted List":"","Bulleted list styles toolbar":"",Cancel:"Batal","Caption for image: %0":"","Caption for the image":"","Centered image":"Gambar ing tengah","Change image text alternative":"","Choose heading":"",Circle:"Bunder",Clear:"",Code:"Kode",Decimal:"","Decimal with leading zero":"",Disc:"Kaset","Enter image caption":"","Full size image":"Gambar ukuran kebak",Heading:"","Heading 1":"","Heading 2":"","Heading 3":"","Heading 4":"","Heading 5":"","Heading 6":"","Image resize list":"","Image toolbar":"","image widget":"","In line":"",Insert:"Tambah","Insert image":"Tambahaken gambar","Insert image via URL":"Tambah gambar saking URL",Italic:"Miring","Left aligned image":"Gambar ing kiwa","List properties":"","Lower-latin":"","Lowerroman":"","Numbered List":"","Numbered list styles toolbar":"",Original:"Asli",Paragraph:"","Remove color":"Busek warni","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"Mangsulaken default","Reversed order":"Dipunwangsul","Right aligned image":"Gambar ing tengen",Save:"Rimat","Show more items":"Tampilaken langkung kathah","Side image":"",Square:"Kotak","Start at":"Wiwit saking","Start index must be greater than 0.":"",Strikethrough:"Seratan dicoret",Subscript:"",Superscript:"","Text alternative":"","To-do List":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lowerlatin list style":"","Toggle the lowerroman list style":"","Toggle the square list style":"","Toggle the upperlatin list style":"","Toggle the upperroman list style":"","Type or paste your content here.":"Serataken utawi nyukani babagan ing ngriki","Type your title":"Serataken irah-irahan",Underline:"Garis ngandhap",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Wrap text":""});a.getPluralForm=function(e){return 0}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
(function(e){const a=e["jv"]=e["jv"]||{};a.dictionary=Object.assign(a.dictionary||{},{"%0 of %1":"%0 saking %1",Big:"Ageng",Bold:"Kandhel","Break text":"","Bulleted List":"","Bulleted list styles toolbar":"",Cancel:"Batal","Caption for image: %0":"","Caption for the image":"","Centered image":"Gambar ing tengah","Change image text alternative":"","Choose heading":"",Circle:"Bunder",Clear:"",Code:"Kode",Decimal:"","Decimal with leading zero":"",Default:"Default",Disc:"Kaset","Document colors":"Warni dokumen","Enter image caption":"","Font Background Color":"Warni Latar Aksara","Font Color":"Warni aksara","Font Family":"Jinising Aksara","Font Size":"Ukuran aksara","Full size image":"Gambar ukuran kebak",Heading:"","Heading 1":"","Heading 2":"","Heading 3":"","Heading 4":"","Heading 5":"","Heading 6":"",Huge:"Langkung ageng","Image resize list":"","Image toolbar":"","image widget":"","In line":"",Insert:"Tambah","Insert image":"Tambahaken gambar","Insert image via URL":"Tambah gambar saking URL",Italic:"Miring","Left aligned image":"Gambar ing kiwa","List properties":"","Lower-latin":"","Lowerroman":"","Numbered List":"","Numbered list styles toolbar":"",Original:"Asli",Paragraph:"","Remove color":"Busek warni","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"Mangsulaken default","Reversed order":"Dipunwangsul","Right aligned image":"Gambar ing tengen",Save:"Rimat","Show more items":"Tampilaken langkung kathah","Side image":"",Small:"Alit",Square:"Kotak","Start at":"Wiwit saking","Start index must be greater than 0.":"",Strikethrough:"Seratan dicoret",Subscript:"",Superscript:"","Text alternative":"",Tiny:"Langkung alit","To-do List":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lowerlatin list style":"","Toggle the lowerroman list style":"","Toggle the square list style":"","Toggle the upperlatin list style":"","Toggle the upperroman list style":"","Type or paste your content here.":"Serataken utawi nyukani babagan ing ngriki","Type your title":"Serataken irah-irahan",Underline:"Garis ngandhap",Update:"","Update image URL":"","Upload failed":"","Upload from computer":"","Upload image from computer":"","Upper-latin":"","Upper-roman":"","Wrap text":""});a.getPluralForm=function(e){return 0}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(function(e){const t=e["nb"]=e["nb"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align table to the left":"","Align table to the right":"",Alignment:"",Aquamarine:"",Background:"",Black:"","Block quote":"Blokksitat",Blue:"",Bold:"Fet",Border:"","Break text":"","Bulleted List":"Punktmerket liste","Bulleted list styles toolbar":"",Cancel:"Avbryt","Caption for image: %0":"","Caption for the image":"","Cell properties":"","Center table":"","Centered image":"Midtstilt bilde","Change image text alternative":"Endre tekstalternativ for bilde","Choose heading":"Velg overskrift",Circle:"",Clear:"","Click to edit block":"",Close:"",Code:"Kode",Color:"","Color picker":"",Column:"Kolonne",Dashed:"",Decimal:"","Decimal with leading zero":"","Delete column":"Slett kolonne","Delete row":"Slett rad","Dim grey":"",Dimensions:"",Disc:"",Dotted:"",Double:"",Downloadable:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Edit link":"Rediger lenke","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor toolbar":"","Enter image caption":"Skriv inn bildetekst","Enter table caption":"","Full size image":"Bilde i full størrelse",Green:"",Grey:"",Groove:"","Header column":"Overskriftkolonne","Header row":"Overskriftrad",Heading:"Overskrift","Heading 1":"Overskrift 1","Heading 2":"Overskrift 2","Heading 3":"Overskrift 3","Heading 4":"","Heading 5":"","Heading 6":"",Height:"",HEX:"","Horizontal text alignment toolbar":"","Image resize list":"","Image toolbar":"","image widget":"Bilde-widget","In line":"",Insert:"","Insert column left":"","Insert column right":"","Insert image":"Sett inn bilde","Insert image via URL":"","Insert row above":"Sett inn rad over","Insert row below":"Sett inn rad under","Insert table":"Sett inn tabell",Inset:"",Italic:"Kursiv","Justify cell text":"","Left aligned image":"Venstrejustert bilde","Light blue":"","Light green":"","Light grey":"",Link:"Lenke","Link image":"","Link URL":"URL for lenke","List properties":"","Lower-latin":"","Lowerroman":"","Merge cell down":"Slå sammen celle ned","Merge cell left":"Slå sammen celle til venstre","Merge cell right":"Slå sammen celle til høyre","Merge cell up":"Slå sammen celle opp","Merge cells":"Slå sammen celler",Next:"","No results found":"","No searchable items":"",None:"","Numbered List":"Nummerert liste","Numbered list styles toolbar":"","Open in a new tab":"","Open link in new tab":"Åpne lenke i ny fane",Orange:"",Original:"",Outset:"",Padding:"",Paragraph:"Avsnitt",Previous:"",Purple:"",Red:"",Redo:"Gjør om","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Rich Text Editor":"Rikteksteditor",Ridge:"","Right aligned image":"Høyrejustert bilde",Row:"Rad",Save:"Lagre","Select column":"","Select row":"","Show more items":"","Side image":"Sidebilde",Solid:"","Split cell horizontally":"Del celle horisontalt","Split cell vertically":"Del celle vertikalt",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"Gjennomstreking",Style:"",Subscript:"",Superscript:"","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"","Text alternative":"Tekstalternativ for bilde",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"","This link has no URL":"Denne lenken har ingen URL","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lowerlatin list style":"","Toggle the lowerroman list style":"","Toggle the square list style":"","Toggle the upperlatin list style":"","Toggle the upperroman list style":"",Turquoise:"","Type or paste your content here.":"","Type your title":"",Underline:"Understreking",Undo:"Angre",Unlink:"Fjern lenke",Update:"","Update image URL":"","Upload failed":"Opplasting feilet","Upload from computer":"","Upload image from computer":"","Upload in progress":"Opplasting pågår","Upper-latin":"","Upper-roman":"","Vertical text alignment toolbar":"",White:"",Width:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
(function(e){const t=e["nb"]=e["nb"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align table to the left":"","Align table to the right":"",Alignment:"",Aquamarine:"",Background:"",Big:"Stor",Black:"","Block quote":"Blokksitat",Blue:"",Bold:"Fet",Border:"","Break text":"","Bulleted List":"Punktmerket liste","Bulleted list styles toolbar":"",Cancel:"Avbryt","Caption for image: %0":"","Caption for the image":"","Cell properties":"","Center table":"","Centered image":"Midtstilt bilde","Change image text alternative":"Endre tekstalternativ for bilde","Choose heading":"Velg overskrift",Circle:"",Clear:"","Click to edit block":"",Close:"",Code:"Kode",Color:"","Color picker":"",Column:"Kolonne",Dashed:"",Decimal:"","Decimal with leading zero":"",Default:"Standard","Delete column":"Slett kolonne","Delete row":"Slett rad","Dim grey":"",Dimensions:"",Disc:"","Document colors":"",Dotted:"",Double:"",Downloadable:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Edit link":"Rediger lenke","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor toolbar":"","Enter image caption":"Skriv inn bildetekst","Enter table caption":"","Font Background Color":"","Font Color":"","Font Family":"Skrifttype","Font Size":"Skriftstørrelse","Full size image":"Bilde i full størrelse",Green:"",Grey:"",Groove:"","Header column":"Overskriftkolonne","Header row":"Overskriftrad",Heading:"Overskrift","Heading 1":"Overskrift 1","Heading 2":"Overskrift 2","Heading 3":"Overskrift 3","Heading 4":"","Heading 5":"","Heading 6":"",Height:"",HEX:"","Horizontal text alignment toolbar":"",Huge:"Veldig stor","Image resize list":"","Image toolbar":"","image widget":"Bilde-widget","In line":"",Insert:"","Insert column left":"","Insert column right":"","Insert image":"Sett inn bilde","Insert image via URL":"","Insert row above":"Sett inn rad over","Insert row below":"Sett inn rad under","Insert table":"Sett inn tabell",Inset:"",Italic:"Kursiv","Justify cell text":"","Left aligned image":"Venstrejustert bilde","Light blue":"","Light green":"","Light grey":"",Link:"Lenke","Link image":"","Link URL":"URL for lenke","List properties":"","Lower-latin":"","Lowerroman":"","Merge cell down":"Slå sammen celle ned","Merge cell left":"Slå sammen celle til venstre","Merge cell right":"Slå sammen celle til høyre","Merge cell up":"Slå sammen celle opp","Merge cells":"Slå sammen celler",Next:"","No results found":"","No searchable items":"",None:"","Numbered List":"Nummerert liste","Numbered list styles toolbar":"","Open in a new tab":"","Open link in new tab":"Åpne lenke i ny fane",Orange:"",Original:"",Outset:"",Padding:"",Paragraph:"Avsnitt",Previous:"",Purple:"",Red:"",Redo:"Gjør om","Remove color":"","Replace from computer":"","Replace image":"","Replace image from computer":"","Resize image":"","Resize image to %0":"","Resize image to the original size":"","Restore default":"","Reversed order":"","Rich Text Editor":"Rikteksteditor",Ridge:"","Right aligned image":"Høyrejustert bilde",Row:"Rad",Save:"Lagre","Select column":"","Select row":"","Show more items":"","Side image":"Sidebilde",Small:"Liten",Solid:"","Split cell horizontally":"Del celle horisontalt","Split cell vertically":"Del celle vertikalt",Square:"","Start at":"","Start index must be greater than 0.":"",Strikethrough:"Gjennomstreking",Style:"",Subscript:"",Superscript:"","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"","Text alternative":"Tekstalternativ for bilde",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"","This link has no URL":"Denne lenken har ingen URL",Tiny:"Veldig liten","To-do List":"","Toggle caption off":"","Toggle caption on":"","Toggle the circle list style":"","Toggle the decimal list style":"","Toggle the decimal with leading zero list style":"","Toggle the disc list style":"","Toggle the lowerlatin list style":"","Toggle the lowerroman list style":"","Toggle the square list style":"","Toggle the upperlatin list style":"","Toggle the upperroman list style":"",Turquoise:"","Type or paste your content here.":"","Type your title":"",Underline:"Understreking",Undo:"Angre",Unlink:"Fjern lenke",Update:"","Update image URL":"","Upload failed":"Opplasting feilet","Upload from computer":"","Upload image from computer":"","Upload in progress":"Opplasting pågår","Upper-latin":"","Upper-roman":"","Vertical text alignment toolbar":"",White:"",Width:"","Wrap text":"",Yellow:""});t.getPluralForm=function(e){return e!=1}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
(function(e){const t=e["sl"]=e["sl"]||{};t.dictionary=Object.assign(t.dictionary||{},{"%0 of %1":"",Accept:"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align table to the left":"","Align table to the right":"",Alignment:"",Aquamarine:"Akvamarin",Background:"",Black:"Črna","Block quote":"Blokiraj citat",Blue:"Modra",Bold:"Krepko",Border:"",Cancel:"Prekliči","Cell properties":"","Center table":"","Choose heading":"Izberi naslov",Clear:"","Click to edit block":"",Close:"",Code:"Koda",Color:"","Color picker":"",Column:"",Dashed:"","Delete column":"","Delete row":"","Dim grey":"Temno siva",Dimensions:"",Dotted:"",Double:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor toolbar":"","Enter table caption":"",Green:"Zelena",Grey:"Siva",Groove:"","Header column":"","Header row":"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6",Height:"",HEX:"","Horizontal text alignment toolbar":"","Insert column left":"","Insert column right":"","Insert row above":"","Insert row below":"","Insert table":"Vstavi tabelo",Inset:"",Italic:"Poševno","Justify cell text":"","Light blue":"Svetlo modra","Light green":"Svetlo zelena","Light grey":"Svetlo siva","Merge cell down":"","Merge cell left":"","Merge cell right":"","Merge cell up":"","Merge cells":"",Next:"","No results found":"","No searchable items":"",None:"",Orange:"Oranžna",Outset:"",Padding:"",Paragraph:"Odstavek",Previous:"",Purple:"Vijolična",Red:"Rdeča","Remove color":"Odstrani barvo","Restore default":"","Rich Text Editor":"",Ridge:"",Row:"",Save:"Shrani","Select column":"","Select row":"","Show more items":"",Solid:"","Split cell horizontally":"","Split cell vertically":"",Strikethrough:"Prečrtano",Style:"",Subscript:"Naročnik",Superscript:"Nadpis","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"","Toggle caption off":"","Toggle caption on":"",Turquoise:"Turkizna","Type or paste your content here.":"Vnesi ali prilepi vsebino","Type your title":"Vnesi naslov",Underline:"Podčrtaj","Vertical text alignment toolbar":"",White:"Bela",Width:"",Yellow:"Rumena"});t.getPluralForm=function(e){return e%100==1?0:e%100==2?1:e%100==3||e%100==4?2:3}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));
(function(e){const o=e["sl"]=e["sl"]||{};o.dictionary=Object.assign(o.dictionary||{},{"%0 of %1":"",Accept:"","Align cell text to the bottom":"","Align cell text to the center":"","Align cell text to the left":"","Align cell text to the middle":"","Align cell text to the right":"","Align cell text to the top":"","Align table to the left":"","Align table to the right":"",Alignment:"",Aquamarine:"Akvamarin",Background:"",Big:"Veliko",Black:"Črna","Block quote":"Blokiraj citat",Blue:"Modra",Bold:"Krepko",Border:"",Cancel:"Prekliči","Cell properties":"","Center table":"","Choose heading":"Izberi naslov",Clear:"","Click to edit block":"",Close:"",Code:"Koda",Color:"","Color picker":"",Column:"",Dashed:"",Default:"Privzeto","Delete column":"","Delete row":"","Dim grey":"Temno siva",Dimensions:"","Document colors":"Barve dokumenta",Dotted:"",Double:"","Drag to move":"","Dropdown toolbar":"","Edit block":"","Editor block content toolbar":"","Editor contextual toolbar":"","Editor dialog":"","Editor editing area: %0":"","Editor toolbar":"","Enter table caption":"","Font Background Color":"Barva ozadja pisave","Font Color":"Barva pisave","Font Family":"Vrsta oz. tip pisave","Font Size":"Velikost pisave",Green:"Zelena",Grey:"Siva",Groove:"","Header column":"","Header row":"",Heading:"Naslov","Heading 1":"Naslov 1","Heading 2":"Naslov 2","Heading 3":"Naslov 3","Heading 4":"Naslov 4","Heading 5":"Naslov 5","Heading 6":"Naslov 6",Height:"",HEX:"","Horizontal text alignment toolbar":"",Huge:"Ogromno","Insert column left":"","Insert column right":"","Insert row above":"","Insert row below":"","Insert table":"Vstavi tabelo",Inset:"",Italic:"Poševno","Justify cell text":"","Light blue":"Svetlo modra","Light green":"Svetlo zelena","Light grey":"Svetlo siva","Merge cell down":"","Merge cell left":"","Merge cell right":"","Merge cell up":"","Merge cells":"",Next:"","No results found":"","No searchable items":"",None:"",Orange:"Oranžna",Outset:"",Padding:"",Paragraph:"Odstavek",Previous:"",Purple:"Vijolična",Red:"Rdeča","Remove color":"Odstrani barvo","Restore default":"","Rich Text Editor":"",Ridge:"",Row:"",Save:"Shrani","Select column":"","Select row":"","Show more items":"",Small:"Majhna",Solid:"","Split cell horizontally":"","Split cell vertically":"",Strikethrough:"Prečrtano",Style:"",Subscript:"Naročnik",Superscript:"Nadpis","Table alignment toolbar":"","Table cell text alignment":"","Table properties":"","Table toolbar":"",'The color is invalid. Try "#FF0000" or "rgb(255,0,0)" or "red".':"",'The value is invalid. Try "10px" or "2em" or simply "2".':"",Tiny:"Drobna","Toggle caption off":"","Toggle caption on":"",Turquoise:"Turkizna","Type or paste your content here.":"Vnesi ali prilepi vsebino","Type your title":"Vnesi naslov",Underline:"Podčrtaj","Vertical text alignment toolbar":"",White:"Bela",Width:"",Yellow:"Rumena"});o.getPluralForm=function(e){return e%100==1?0:e%100==2?1:e%100==3||e%100==4?2:3}})(window.CKEDITOR_TRANSLATIONS||(window.CKEDITOR_TRANSLATIONS={}));

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -14,6 +14,7 @@
"@ckeditor/ckeditor5-cloud-services": "41.0.0",
"@ckeditor/ckeditor5-editor-classic": "41.0.0",
"@ckeditor/ckeditor5-essentials": "41.0.0",
"@ckeditor/ckeditor5-font": "41.0.0",
"@ckeditor/ckeditor5-heading": "41.0.0",
"@ckeditor/ckeditor5-image": "41.0.0",
"@ckeditor/ckeditor5-indent": "41.0.0",

@ -12,7 +12,7 @@ function handleSampleError( error ) {
const message = [
'Oops, something went wrong!',
`Please, report the following error on ${ issueUrl } with the build id "159xygvqs85-m65lqtchlynm" and the error stack trace:`
`Please, report the following error on ${ issueUrl } with the build id "rv3q54x35x49-lgc6tk0e6ik" and the error stack trace:`
].join( '\n' );
console.error( message );

@ -11,6 +11,7 @@ import { BlockQuote } from '@ckeditor/ckeditor5-block-quote';
import { CloudServices } from '@ckeditor/ckeditor5-cloud-services';
import type { EditorConfig } from '@ckeditor/ckeditor5-core';
import { Essentials } from '@ckeditor/ckeditor5-essentials';
import { FontBackgroundColor, FontColor, FontSize } from '@ckeditor/ckeditor5-font';
import { Heading } from '@ckeditor/ckeditor5-heading';
import {
Image,
@ -42,6 +43,9 @@ class Editor extends ClassicEditor {
Bold,
CloudServices,
Essentials,
FontBackgroundColor,
FontColor,
FontSize,
Heading,
Image,
ImageCaption,
@ -75,6 +79,10 @@ class Editor extends ClassicEditor {
'italic',
'link',
'|',
'fontSize',
'fontColor',
'fontBackgroundColor',
'|',
'outdent',
'indent',
'|',

@ -10,13 +10,20 @@ const editorContent = ref("");
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',
'Authorization' : `${sessionStorage.getItem('token')}`
}
},
fontSize: {
options: [
'tiny',
'default',
'big'
]
},
image: {
resize: true,
toolbar: [
@ -28,6 +35,10 @@ const editorConfig = ref({
"imageStyle:alignBlockLeft",
"imageStyle:block",
"imageStyle:alignBlockRight",
"|",
"fontSize",
"fontColor",
"fontBackgroundColor",
],
styles: [
'full',

@ -10,7 +10,7 @@ const editorContent = ref("");
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',

@ -131,7 +131,7 @@ const handleCloseFormDraw = (val) => {
<template v-for="(item,index) in props.row.imageList" :key="index">
<el-image
style="width: 100px; height: 60px"
:src="'https://prodio.zltest.com.tw'+item.url"
:src="item.url"
:fit="cover"
/>
</template>

@ -35,7 +35,7 @@ onMounted(async () => {
fileList.value = res.data.imageList.map(item => {
return {
uid: item.uid,
url: 'https://prodio.zltest.com.tw' + item.url,
url: item.url,
}
})
}

@ -6,7 +6,7 @@ const editor = ClassicEditor;
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',

@ -9,7 +9,7 @@ const editor = ClassicEditor;
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',

@ -11,7 +11,7 @@ const editor = ClassicEditor;
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',

@ -20,7 +20,7 @@ const editor = ClassicEditor;
const editorConfig = ref({
simpleUpload: {
// The URL that the images are uploaded to.
uploadUrl: 'https://prodio.zltest.com.tw/adminapi/article/uploadImage',
uploadUrl: '/adminapi/article/uploadImage',
// // Headers sent along with the XMLHttpRequest to the upload server.
headers: {
'X-CSRF-TOKEN': 'CSFR-Token',

@ -93,6 +93,13 @@
dependencies:
ckeditor5 "41.0.0"
"@ckeditor/ckeditor5-font@41.0.0":
version "41.0.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-font/-/ckeditor5-font-41.0.0.tgz#a04352cbf88d931a4366dc72f8226ba5eb5e4c27"
integrity sha512-1AbJvWOs0c56O2ARyMGWybsy5fW/9EB7pOcTKeiXaDYZsligb+iOYsUL0XqOdi0v8tibl4l1y49QIJ25TO2N7w==
dependencies:
ckeditor5 "41.0.0"
"@ckeditor/ckeditor5-heading@41.0.0":
version "41.0.0"
resolved "https://registry.yarnpkg.com/@ckeditor/ckeditor5-heading/-/ckeditor5-heading-41.0.0.tgz#7b6451a032eb137ac5d9dfceae3abaa9ac30f7e0"
@ -653,6 +660,7 @@ chokidar@^3.5.3:
"@ckeditor/ckeditor5-cloud-services" "41.0.0"
"@ckeditor/ckeditor5-editor-classic" "41.0.0"
"@ckeditor/ckeditor5-essentials" "41.0.0"
"@ckeditor/ckeditor5-font" "41.0.0"
"@ckeditor/ckeditor5-heading" "41.0.0"
"@ckeditor/ckeditor5-image" "41.0.0"
"@ckeditor/ckeditor5-indent" "41.0.0"

@ -20,7 +20,7 @@ class ActivityController extends BaseController
$list = Db::name('activity')
->where($where)
->order('id', 'asc')
->order('id', 'desc')
->page($page, $pageSize)
->select()
->toArray();

@ -152,7 +152,7 @@ class CateController extends BaseController
$filename = uniqid() . '.' . $file->getUploadExtension();
$file->move(public_path().'/storage/category/'. $filename);
$savePath = getUrl().'/storage/category/'. $filename;
$savePath = '/storage/category/'. $filename;
return $this->Success($savePath);
}
return $this->Error('操作失敗');

@ -120,7 +120,7 @@ class IndexController extends BaseController
$filename = uniqid() . '.' . $file->getUploadExtension();
$file->move(public_path().'/storage/banner/'. $filename);
$savePath = getUrl().'/storage/banner/'. $filename;
$savePath = '/storage/banner/'. $filename;
return $this->Success($savePath);
}
return $this->Error('操作失敗');

@ -149,7 +149,7 @@ class ProductController extends BaseController
$filename = uniqid() . '.' . $file->getUploadExtension();
$file->move(public_path().'/storage/product/'. $filename);
$savePath = getUrl().'/storage/product/'. $filename;
$savePath = '/storage/product/'. $filename;
return $this->Success($savePath);
}
return $this->Error('操作失敗');

@ -130,7 +130,7 @@ class SupplierController extends BaseController
$filename = uniqid() . '.' . $file->getUploadExtension();
$file->move(public_path() . '/storage/supplier/' . $filename);
$savePath = getUrl() . '/storage/supplier/' . $filename;
$savePath = '/storage/supplier/' . $filename;
return $this->Success($savePath);
}
return $this->Error('操作失敗');

@ -32,12 +32,12 @@ class GetData{
$list = Db::name($db)
->where($where)
->order('id', 'asc')
->order('id', 'desc')
->page($page, $pageSize)
->select()
->toArray();
$total = Db::name('activity')
$total = Db::name($db)
->where($where)
->count();

@ -0,0 +1,66 @@
version: '3.8'
services:
nginx:
image: nginx:latest
container_name: "prodio-nginx"
ports:
- "6060:80"
volumes:
- ./nginx/html:/usr/share/nginx/html
- ./nginx/nginx.conf:/etc/nginx/nginx.conf
- ./nginx/default.conf:/etc/nginx/conf.d/default.conf
- ./data/nginx/logs:/var/log/nginx
networks:
- internal
# web:
# build:
# context: .
# dockerfile: ./nuxt/Dockerfile
# container_name: "prodio-web"
# ports:
# - "6061:3000"
# volumes:
# - ./nuxt/app:/app
# networks:
# - internal
api:
image: krisss/docker-webman:8.2-cli-alpine
container_name: "prodio-api"
ports:
- "6065:8787"
volumes:
- ./app:/app
networks:
- internal
mysql:
build:
context: .
dockerfile: ./mysql/Dockerfile
container_name: "prodio-mysql"
networks:
- internal
volumes:
- ./data/mysql/data:/var/lib/mysql
- ./data/mysql/init:/docker-entrypoint-initdb.d
environment:
MYSQL_ROOT_PASSWORD: 1qazvfr4
# redis:
# image: redis
# container_name: "prodio-redis"
# networks:
# - internal
phpmyadmin:
image: phpmyadmin/phpmyadmin
container_name: "prodio-myadmin"
ports:
- "6069:80"
networks:
- internal
environment:
PMA_HOST: mysql
PMA_PORT: 3306
UPLOAD_LIMIT: 100M
networks:
internal:
driver: bridge

@ -0,0 +1,10 @@
FROM nginx:latest
EXPOSE 80
ENV TZ=Asia/Taipei
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY nginx/nginx.conf /etc/nginx/nginx.conf

@ -0,0 +1,96 @@
server {
listen 80;
listen [::]:80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
location /adminapi
{
proxy_pass http://api:8787;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
add_header X-Cache $upstream_cache_status;
#Set Nginx Cache
add_header Cache-Control no-cache;
}
location /appapi
{
proxy_pass http://api:8787;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header REMOTE-HOST $remote_addr;
add_header X-Cache $upstream_cache_status;
#Set Nginx Cache
add_header Cache-Control no-cache;
}
# location /adminapi {
# proxy_pass http://api:6065;
# proxy_set_header Host $host;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# }
location /storage {
proxy_pass http://api:8787;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
location /home {
proxy_pass http://web:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.card-footer[data-v-edcc74e1]{background-color:#f5f7fa;border-top:1px solid #ebeef5;padding:10px;text-align:right}[data-v-edcc74e1] .ck-editor__editable_inline{height:calc(100vh - 315px)}

@ -0,0 +1 @@
import{G as h}from"./el-button-6b66070a.js";import{a as x,b as C,E}from"./el-breadcrumb-item-0eb7853a.js";import{C as S}from"./ckeditor-c707ce29.js";import{g as k,u as I}from"./article-2a36286c.js";import{E as c}from"./el-message-76e8eab1.js";import{_ as B}from"./_plugin-vue_export-helper-c27b6911.js";import{q as d,z as w,L as V,o as N,f as R,M as t,Q as e,w as o,N as m,a as L,a7 as T,a8 as z}from"./index-3ef4d3eb.js";import"./request-63584e50.js";import"./aria-60e0cdc6.js";const _=a=>(T("data-v-cc062065"),a=a(),z(),a),A={class:"main"},F={class:"breadcrumb-section"},M=_(()=>t("a",{href:"/"},"經營理念",-1)),U=_(()=>t("div",null,null,-1)),q={style:{padding:"10px"}},G={class:"card-footer"},K={__name:"Index",setup(a){const p=S,s=d(""),u=d({simpleUpload:{uploadUrl:"https://prodio.zltest.com.tw/adminapi/article/uploadImage",headers:{"X-CSRF-TOKEN":"CSFR-Token"}},image:{resize:!0,toolbar:["imageTextAlternative","|","imageStyle:alignLeft","imageStyle:alignRight","|","imageStyle:alignBlockLeft","imageStyle:block","imageStyle:alignBlockRight"],styles:["full","alignLeft","alignRight"]}});w(async()=>{let l=await k(2);l.code===200&&(s.value=l.data.content)});const f=async()=>(await I({id:2,content:s.value})).code===200?c({message:"更新成功",type:"success"}):c({message:"更新失敗",type:"error"});return(l,n)=>{const r=x,g=C,v=V("ckeditor"),y=h,b=E;return N(),R("div",A,[t("div",F,[t("div",null,[e(g,{separator:"/"},{default:o(()=>[e(r,null,{default:o(()=>[m(" 經銷系統 ")]),_:1}),e(r,null,{default:o(()=>[M]),_:1})]),_:1})]),U]),e(b,{"body-style":{padding:"0px"}},{default:o(()=>[t("div",q,[e(v,{editor:L(p),modelValue:s.value,"onUpdate:modelValue":n[0]||(n[0]=i=>s.value=i),config:u.value},null,8,["editor","modelValue","config"])]),t("div",G,[e(y,{type:"primary",onClick:n[1]||(n[1]=i=>f())},{default:o(()=>[m("確認")]),_:1})])]),_:1})])}}},W=B(K,[["__scopeId","data-v-cc062065"]]);export{W as default};

@ -0,0 +1 @@
.card-footer[data-v-a87ce681]{background-color:#f5f7fa;border-top:1px solid #ebeef5;padding:10px;text-align:right}[data-v-a87ce681] .ck-editor__editable_inline{height:calc(100vh - 315px)}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -0,0 +1 @@
.card-footer[data-v-61a86e6f]{background-color:#f5f7fa;border-top:1px solid #ebeef5;padding:10px;text-align:right}[data-v-61a86e6f] .ck-editor__editable_inline{height:calc(100vh - 315px)}

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save