Repository: star7th/showdoc Branch: master Commit: 19e5a99d3128 Files: 4901 Total size: 27.8 MB Directory structure: gitextract_xhentcdn/ ├── .dockerignore ├── .github/ │ └── workflows/ │ ├── docker-arm.yml │ ├── docker-release.yml │ └── docker.yml ├── .gitignore ├── .htaccess ├── Dockerfile ├── Dockerfile.ARM ├── LICENSE.txt ├── Public/ │ ├── README.md │ ├── Uploads/ │ │ └── index.html │ ├── css/ │ │ ├── index.css │ │ ├── item/ │ │ │ ├── index.css │ │ │ ├── show.css │ │ │ └── show_single_page.css │ │ ├── jquery.fullPage.css │ │ ├── login.css │ │ ├── page/ │ │ │ ├── edit.css │ │ │ └── index.css │ │ ├── showdoc.css │ │ └── tab-tpl.css │ ├── diff/ │ │ ├── difflib.js │ │ ├── diffview.css │ │ └── diffview.js │ ├── editor.md/ │ │ ├── Gulpfile.js │ │ ├── LICENSE │ │ ├── README.md │ │ ├── css/ │ │ │ ├── editormd.css │ │ │ ├── editormd.logo.css │ │ │ └── editormd.preview.css │ │ ├── editormd.amd.js │ │ ├── editormd.js │ │ ├── fonts/ │ │ │ └── FontAwesome.otf │ │ ├── languages/ │ │ │ ├── en.js │ │ │ └── zh-tw.js │ │ ├── lib/ │ │ │ └── codemirror/ │ │ │ ├── AUTHORS │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── addon/ │ │ │ │ ├── comment/ │ │ │ │ │ ├── comment.js │ │ │ │ │ └── continuecomment.js │ │ │ │ ├── dialog/ │ │ │ │ │ ├── dialog.css │ │ │ │ │ └── dialog.js │ │ │ │ ├── display/ │ │ │ │ │ ├── fullscreen.css │ │ │ │ │ ├── fullscreen.js │ │ │ │ │ ├── panel.js │ │ │ │ │ ├── placeholder.js │ │ │ │ │ └── rulers.js │ │ │ │ ├── edit/ │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ ├── closetag.js │ │ │ │ │ ├── continuelist.js │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ ├── matchtags.js │ │ │ │ │ └── trailingspace.js │ │ │ │ ├── fold/ │ │ │ │ │ ├── brace-fold.js │ │ │ │ │ ├── comment-fold.js │ │ │ │ │ ├── foldcode.js │ │ │ │ │ ├── foldgutter.css │ │ │ │ │ ├── foldgutter.js │ │ │ │ │ ├── indent-fold.js │ │ │ │ │ ├── markdown-fold.js │ │ │ │ │ └── xml-fold.js │ │ │ │ ├── hint/ │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ ├── css-hint.js │ │ │ │ │ ├── html-hint.js │ │ │ │ │ ├── javascript-hint.js │ │ │ │ │ ├── show-hint.css │ │ │ │ │ ├── show-hint.js │ │ │ │ │ ├── sql-hint.js │ │ │ │ │ └── xml-hint.js │ │ │ │ ├── lint/ │ │ │ │ │ ├── coffeescript-lint.js │ │ │ │ │ ├── css-lint.js │ │ │ │ │ ├── javascript-lint.js │ │ │ │ │ ├── json-lint.js │ │ │ │ │ ├── lint.css │ │ │ │ │ ├── lint.js │ │ │ │ │ └── yaml-lint.js │ │ │ │ ├── merge/ │ │ │ │ │ ├── merge.css │ │ │ │ │ └── merge.js │ │ │ │ ├── mode/ │ │ │ │ │ ├── loadmode.js │ │ │ │ │ ├── multiplex.js │ │ │ │ │ ├── multiplex_test.js │ │ │ │ │ ├── overlay.js │ │ │ │ │ └── simple.js │ │ │ │ ├── runmode/ │ │ │ │ │ ├── colorize.js │ │ │ │ │ ├── runmode-standalone.js │ │ │ │ │ ├── runmode.js │ │ │ │ │ └── runmode.node.js │ │ │ │ ├── scroll/ │ │ │ │ │ ├── annotatescrollbar.js │ │ │ │ │ ├── scrollpastend.js │ │ │ │ │ ├── simplescrollbars.css │ │ │ │ │ └── simplescrollbars.js │ │ │ │ ├── search/ │ │ │ │ │ ├── match-highlighter.js │ │ │ │ │ ├── matchesonscrollbar.css │ │ │ │ │ ├── matchesonscrollbar.js │ │ │ │ │ ├── search.js │ │ │ │ │ └── searchcursor.js │ │ │ │ ├── selection/ │ │ │ │ │ ├── active-line.js │ │ │ │ │ ├── mark-selection.js │ │ │ │ │ └── selection-pointer.js │ │ │ │ ├── tern/ │ │ │ │ │ ├── tern.css │ │ │ │ │ ├── tern.js │ │ │ │ │ └── worker.js │ │ │ │ └── wrap/ │ │ │ │ └── hardwrap.js │ │ │ ├── bower.json │ │ │ ├── lib/ │ │ │ │ ├── codemirror.css │ │ │ │ └── codemirror.js │ │ │ ├── mode/ │ │ │ │ ├── apl/ │ │ │ │ │ ├── apl.js │ │ │ │ │ └── index.html │ │ │ │ ├── asterisk/ │ │ │ │ │ ├── asterisk.js │ │ │ │ │ └── index.html │ │ │ │ ├── clike/ │ │ │ │ │ ├── clike.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── scala.html │ │ │ │ ├── clojure/ │ │ │ │ │ ├── clojure.js │ │ │ │ │ └── index.html │ │ │ │ ├── cobol/ │ │ │ │ │ ├── cobol.js │ │ │ │ │ └── index.html │ │ │ │ ├── coffeescript/ │ │ │ │ │ ├── coffeescript.js │ │ │ │ │ └── index.html │ │ │ │ ├── commonlisp/ │ │ │ │ │ ├── commonlisp.js │ │ │ │ │ └── index.html │ │ │ │ ├── css/ │ │ │ │ │ ├── css.js │ │ │ │ │ ├── index.html │ │ │ │ │ ├── less.html │ │ │ │ │ ├── less_test.js │ │ │ │ │ ├── scss.html │ │ │ │ │ ├── scss_test.js │ │ │ │ │ └── test.js │ │ │ │ ├── cypher/ │ │ │ │ │ ├── cypher.js │ │ │ │ │ └── index.html │ │ │ │ ├── d/ │ │ │ │ │ ├── d.js │ │ │ │ │ └── index.html │ │ │ │ ├── dart/ │ │ │ │ │ ├── dart.js │ │ │ │ │ └── index.html │ │ │ │ ├── diff/ │ │ │ │ │ ├── diff.js │ │ │ │ │ └── index.html │ │ │ │ ├── django/ │ │ │ │ │ ├── django.js │ │ │ │ │ └── index.html │ │ │ │ ├── dockerfile/ │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ └── index.html │ │ │ │ ├── dtd/ │ │ │ │ │ ├── dtd.js │ │ │ │ │ └── index.html │ │ │ │ ├── dylan/ │ │ │ │ │ ├── dylan.js │ │ │ │ │ └── index.html │ │ │ │ ├── ebnf/ │ │ │ │ │ ├── ebnf.js │ │ │ │ │ └── index.html │ │ │ │ ├── ecl/ │ │ │ │ │ ├── ecl.js │ │ │ │ │ └── index.html │ │ │ │ ├── eiffel/ │ │ │ │ │ ├── eiffel.js │ │ │ │ │ └── index.html │ │ │ │ ├── erlang/ │ │ │ │ │ ├── erlang.js │ │ │ │ │ └── index.html │ │ │ │ ├── forth/ │ │ │ │ │ ├── forth.js │ │ │ │ │ └── index.html │ │ │ │ ├── fortran/ │ │ │ │ │ ├── fortran.js │ │ │ │ │ └── index.html │ │ │ │ ├── gas/ │ │ │ │ │ ├── gas.js │ │ │ │ │ └── index.html │ │ │ │ ├── gfm/ │ │ │ │ │ ├── gfm.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── test.js │ │ │ │ ├── gherkin/ │ │ │ │ │ ├── gherkin.js │ │ │ │ │ └── index.html │ │ │ │ ├── go/ │ │ │ │ │ ├── go.js │ │ │ │ │ └── index.html │ │ │ │ ├── groovy/ │ │ │ │ │ ├── groovy.js │ │ │ │ │ └── index.html │ │ │ │ ├── haml/ │ │ │ │ │ ├── haml.js │ │ │ │ │ ├── index.html │ │ │ │ │ └── test.js │ │ │ │ ├── haskell/ │ │ │ │ │ ├── haskell.js │ │ │ │ │ └── index.html │ │ │ │ ├── haxe/ │ │ │ │ │ ├── haxe.js │ │ │ │ │ └── index.html │ │ │ │ ├── htmlembedded/ │ │ │ │ │ ├── htmlembedded.js │ │ │ │ │ └── index.html │ │ │ │ ├── htmlmixed/ │ │ │ │ │ ├── htmlmixed.js │ │ │ │ │ └── index.html │ │ │ │ ├── http/ │ │ │ │ │ ├── http.js │ │ │ │ │ └── index.html │ │ │ │ ├── idl/ │ │ │ │ │ ├── idl.js │ │ │ │ │ └── index.html │ │ │ │ ├── index.html │ │ │ │ ├── jade/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── jade.js │ │ │ │ ├── javascript/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── javascript.js │ │ │ │ │ ├── json-ld.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── typescript.html │ │ │ │ ├── jinja2/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── jinja2.js │ │ │ │ ├── julia/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── julia.js │ │ │ │ ├── kotlin/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── kotlin.js │ │ │ │ ├── livescript/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── livescript.js │ │ │ │ ├── lua/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── lua.js │ │ │ │ ├── markdown/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── markdown.js │ │ │ │ │ └── test.js │ │ │ │ ├── meta.js │ │ │ │ ├── mirc/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── mirc.js │ │ │ │ ├── mllike/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── mllike.js │ │ │ │ ├── modelica/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── modelica.js │ │ │ │ ├── nginx/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── nginx.js │ │ │ │ ├── ntriples/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── ntriples.js │ │ │ │ ├── octave/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── octave.js │ │ │ │ ├── pascal/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── pascal.js │ │ │ │ ├── pegjs/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── pegjs.js │ │ │ │ ├── perl/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── perl.js │ │ │ │ ├── php/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── php.js │ │ │ │ │ └── test.js │ │ │ │ ├── pig/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── pig.js │ │ │ │ ├── properties/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── properties.js │ │ │ │ ├── puppet/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── puppet.js │ │ │ │ ├── python/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── python.js │ │ │ │ ├── q/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── q.js │ │ │ │ ├── r/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── r.js │ │ │ │ ├── rpm/ │ │ │ │ │ ├── changes/ │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── index.html │ │ │ │ │ └── rpm.js │ │ │ │ ├── rst/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── rst.js │ │ │ │ ├── ruby/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── ruby.js │ │ │ │ │ └── test.js │ │ │ │ ├── rust/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── rust.js │ │ │ │ ├── sass/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── sass.js │ │ │ │ ├── scheme/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── scheme.js │ │ │ │ ├── shell/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── shell.js │ │ │ │ │ └── test.js │ │ │ │ ├── sieve/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── sieve.js │ │ │ │ ├── slim/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── slim.js │ │ │ │ │ └── test.js │ │ │ │ ├── smalltalk/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── smalltalk.js │ │ │ │ ├── smarty/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── smarty.js │ │ │ │ ├── smartymixed/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── smartymixed.js │ │ │ │ ├── solr/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── solr.js │ │ │ │ ├── soy/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── soy.js │ │ │ │ ├── sparql/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── sparql.js │ │ │ │ ├── spreadsheet/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── spreadsheet.js │ │ │ │ ├── sql/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── sql.js │ │ │ │ ├── stex/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── stex.js │ │ │ │ │ └── test.js │ │ │ │ ├── stylus/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── stylus.js │ │ │ │ ├── tcl/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── tcl.js │ │ │ │ ├── textile/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── textile.js │ │ │ │ ├── tiddlywiki/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── tiddlywiki.css │ │ │ │ │ └── tiddlywiki.js │ │ │ │ ├── tiki/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── tiki.css │ │ │ │ │ └── tiki.js │ │ │ │ ├── toml/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── toml.js │ │ │ │ ├── tornado/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── tornado.js │ │ │ │ ├── turtle/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── turtle.js │ │ │ │ ├── vb/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── vb.js │ │ │ │ ├── vbscript/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── vbscript.js │ │ │ │ ├── velocity/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── velocity.js │ │ │ │ ├── verilog/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── verilog.js │ │ │ │ ├── xml/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── xml.js │ │ │ │ ├── xquery/ │ │ │ │ │ ├── index.html │ │ │ │ │ ├── test.js │ │ │ │ │ └── xquery.js │ │ │ │ ├── yaml/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── yaml.js │ │ │ │ └── z80/ │ │ │ │ ├── index.html │ │ │ │ └── z80.js │ │ │ ├── package.json │ │ │ └── theme/ │ │ │ ├── 3024-day.css │ │ │ ├── 3024-night.css │ │ │ ├── ambiance-mobile.css │ │ │ ├── ambiance.css │ │ │ ├── base16-dark.css │ │ │ ├── base16-light.css │ │ │ ├── blackboard.css │ │ │ ├── cobalt.css │ │ │ ├── colorforth.css │ │ │ ├── eclipse.css │ │ │ ├── elegant.css │ │ │ ├── erlang-dark.css │ │ │ ├── lesser-dark.css │ │ │ ├── mbo.css │ │ │ ├── mdn-like.css │ │ │ ├── midnight.css │ │ │ ├── monokai.css │ │ │ ├── neat.css │ │ │ ├── neo.css │ │ │ ├── night.css │ │ │ ├── paraiso-dark.css │ │ │ ├── paraiso-light.css │ │ │ ├── pastel-on-dark.css │ │ │ ├── rubyblue.css │ │ │ ├── solarized.css │ │ │ ├── the-matrix.css │ │ │ ├── tomorrow-night-bright.css │ │ │ ├── tomorrow-night-eighties.css │ │ │ ├── twilight.css │ │ │ ├── vibrant-ink.css │ │ │ ├── xq-dark.css │ │ │ ├── xq-light.css │ │ │ └── zenburn.css │ │ ├── package.json │ │ └── plugins/ │ │ ├── code-block-dialog/ │ │ │ └── code-block-dialog.js │ │ ├── emoji-dialog/ │ │ │ ├── emoji-dialog.js │ │ │ └── emoji.json │ │ ├── goto-line-dialog/ │ │ │ └── goto-line-dialog.js │ │ ├── help-dialog/ │ │ │ ├── help-dialog.js │ │ │ └── help.md │ │ ├── html-entities-dialog/ │ │ │ ├── html-entities-dialog.js │ │ │ └── html-entities.json │ │ ├── image-dialog/ │ │ │ └── image-dialog.js │ │ ├── link-dialog/ │ │ │ └── link-dialog.js │ │ ├── plugin-template.js │ │ ├── preformatted-text-dialog/ │ │ │ └── preformatted-text-dialog.js │ │ ├── reference-link-dialog/ │ │ │ └── reference-link-dialog.js │ │ ├── table-dialog/ │ │ │ └── table-dialog.js │ │ └── test-plugin/ │ │ └── test-plugin.js │ ├── exception.tpl │ ├── js/ │ │ ├── attorn/ │ │ │ └── index.js │ │ ├── catalog/ │ │ │ └── edit.js │ │ ├── common/ │ │ │ └── showdoc.js │ │ ├── dialog.js │ │ ├── item/ │ │ │ ├── delete.js │ │ │ ├── export.js │ │ │ ├── index.js │ │ │ ├── setting.js │ │ │ ├── show.js │ │ │ └── show_single_page.js │ │ ├── jquery.hotkeys.js │ │ ├── lang.en-us.js │ │ ├── lang.zh-cn.js │ │ ├── member/ │ │ │ └── edit.js │ │ └── page/ │ │ ├── edit.js │ │ └── index.js │ ├── layer/ │ │ ├── layer.js │ │ ├── mobile/ │ │ │ ├── layer.js │ │ │ └── need/ │ │ │ └── layer.css │ │ └── skin/ │ │ └── default/ │ │ └── layer.css │ └── verifyCode.php ├── README.md ├── SECURITY.md ├── Sqlite/ │ └── showdoc.db.php ├── composer.json ├── docker-compose.yml ├── docker.run.sh ├── documentation/ │ ├── en/ │ │ ├── AutoInstall.md │ │ ├── ByComposer.md │ │ ├── ByDocker.md │ │ ├── DeployManual.md │ │ ├── Development&Contribution.md │ │ └── README.md │ └── zh-CN/ │ └── README.md ├── index.php ├── install/ │ ├── ajax.php │ ├── common.php │ ├── index.php │ ├── lang.en.php │ ├── lang.zh.php │ └── non_interactive.php ├── mcp.php ├── mock/ │ ├── .gitignore │ ├── index.js │ └── package.json ├── robots.txt ├── server/ │ ├── Application/ │ │ ├── Api/ │ │ │ ├── Common/ │ │ │ │ └── index.html │ │ │ ├── Conf/ │ │ │ │ ├── config.php │ │ │ │ ├── index.html │ │ │ │ └── tags.php │ │ │ ├── Controller/ │ │ │ │ ├── AdminItemController.class.php │ │ │ │ ├── AdminMessageController.class.php │ │ │ │ ├── AdminSettingController.class.php │ │ │ │ ├── AdminUpdateController.class.php │ │ │ │ ├── AdminUserController.class.php │ │ │ │ ├── AiController.class.php │ │ │ │ ├── AttachmentController.class.php │ │ │ │ ├── BaseController.class.php │ │ │ │ ├── CatalogController.class.php │ │ │ │ ├── CommonController.class.php │ │ │ │ ├── ExportController.class.php │ │ │ │ ├── ExportHtmlController.class.php │ │ │ │ ├── ExtLoginController.class.php │ │ │ │ ├── FlowController.class.php │ │ │ │ ├── FromCommentsController.class.php │ │ │ │ ├── ImportController.class.php │ │ │ │ ├── ImportPostmanController.class.php │ │ │ │ ├── ImportSwaggerController.class.php │ │ │ │ ├── ItemController.class.php │ │ │ │ ├── ItemGroupController.class.php │ │ │ │ ├── ItemVariableController.class.php │ │ │ │ ├── MemberController.class.php │ │ │ │ ├── MessageController.class.php │ │ │ │ ├── MockController.class.php │ │ │ │ ├── OpenController.class.php │ │ │ │ ├── PageCommentController.class.php │ │ │ │ ├── PageController.class.php │ │ │ │ ├── PageFeedbackController.class.php │ │ │ │ ├── ParamDescLibController.class.php │ │ │ │ ├── PublicSquareController.class.php │ │ │ │ ├── RecycleController.class.php │ │ │ │ ├── RunapiController.class.php │ │ │ │ ├── ScriptCronController.class.php │ │ │ │ ├── SubscriptionController.class.php │ │ │ │ ├── TeamController.class.php │ │ │ │ ├── TeamItemController.class.php │ │ │ │ ├── TeamItemMemberController.class.php │ │ │ │ ├── TeamMemberController.class.php │ │ │ │ ├── TemplateController.class.php │ │ │ │ ├── UpdateController.class.php │ │ │ │ ├── UserController.class.php │ │ │ │ └── index.html │ │ │ ├── Helper/ │ │ │ │ ├── AiHelper.class.php │ │ │ │ └── Convert.class.php │ │ │ ├── Lang/ │ │ │ │ ├── en-us.php │ │ │ │ └── zh-cn.php │ │ │ ├── Model/ │ │ │ │ ├── AttachmentModel.class.php │ │ │ │ ├── BaseModel.class.php │ │ │ │ ├── CaptchaModel.class.php │ │ │ │ ├── CatalogModel.class.php │ │ │ │ ├── ExportModel.class.php │ │ │ │ ├── ItemAiConfigModel.class.php │ │ │ │ ├── ItemChangeLogModel.class.php │ │ │ │ ├── ItemModel.class.php │ │ │ │ ├── ItemTokenModel.class.php │ │ │ │ ├── MemberModel.class.php │ │ │ │ ├── MessageContentModel.class.php │ │ │ │ ├── MessageModel.class.php │ │ │ │ ├── OptionsModel.class.php │ │ │ │ ├── PageModel.class.php │ │ │ │ ├── RunapiDbConfigModel.class.php │ │ │ │ ├── RunapiModel.class.php │ │ │ │ ├── SubscriptionModel.class.php │ │ │ │ ├── UpdateModel.class.php │ │ │ │ ├── UserModel.class.php │ │ │ │ ├── UserSettingModel.class.php │ │ │ │ ├── UserTokenModel.class.php │ │ │ │ ├── VerifyCodeModel.class.php │ │ │ │ └── index.html │ │ │ ├── View/ │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── Common/ │ │ │ ├── Common/ │ │ │ │ ├── function.php │ │ │ │ └── index.html │ │ │ ├── Conf/ │ │ │ │ ├── config.php │ │ │ │ ├── debug.php │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── Home/ │ │ │ ├── Common/ │ │ │ │ └── index.html │ │ │ ├── Conf/ │ │ │ │ ├── config.php │ │ │ │ ├── index.html │ │ │ │ └── tags.php │ │ │ ├── Controller/ │ │ │ │ ├── BaseController.class.php │ │ │ │ ├── CommonController.class.php │ │ │ │ ├── IndexController.class.php │ │ │ │ ├── ItemController.class.php │ │ │ │ ├── PageController.class.php │ │ │ │ ├── UpdateController.class.php │ │ │ │ ├── UserController.class.php │ │ │ │ └── index.html │ │ │ ├── Lang/ │ │ │ │ ├── en-us.php │ │ │ │ └── zh-cn.php │ │ │ ├── Model/ │ │ │ │ ├── BaseModel.class.php │ │ │ │ ├── ItemModel.class.php │ │ │ │ ├── UserModel.class.php │ │ │ │ ├── UserTokenModel.class.php │ │ │ │ └── index.html │ │ │ ├── View/ │ │ │ │ └── index.html │ │ │ └── index.html │ │ ├── README.md │ │ ├── Static/ │ │ │ └── export-html/ │ │ │ ├── app.js │ │ │ └── common.css │ │ └── index.html │ ├── README.md │ ├── ThinkPHP/ │ │ ├── Common/ │ │ │ └── functions.php │ │ ├── Conf/ │ │ │ ├── convention.php │ │ │ └── debug.php │ │ ├── LICENSE.txt │ │ ├── Lang/ │ │ │ ├── en-us.php │ │ │ ├── pt-br.php │ │ │ ├── zh-cn.php │ │ │ └── zh-tw.php │ │ ├── Library/ │ │ │ ├── Behavior/ │ │ │ │ ├── BuildLiteBehavior.class.php │ │ │ │ ├── CheckLangBehavior.class.php │ │ │ │ ├── ContentReplaceBehavior.class.php │ │ │ │ ├── ParseTemplateBehavior.class.php │ │ │ │ ├── ReadHtmlCacheBehavior.class.php │ │ │ │ ├── ShowPageTraceBehavior.class.php │ │ │ │ ├── ShowRuntimeBehavior.class.php │ │ │ │ ├── TokenBuildBehavior.class.php │ │ │ │ └── WriteHtmlCacheBehavior.class.php │ │ │ ├── Think/ │ │ │ │ ├── App.class.php │ │ │ │ ├── Build.class.php │ │ │ │ ├── Cache/ │ │ │ │ │ └── Driver/ │ │ │ │ │ ├── Apachenote.class.php │ │ │ │ │ ├── Apc.class.php │ │ │ │ │ ├── Db.class.php │ │ │ │ │ ├── Eaccelerator.class.php │ │ │ │ │ ├── File.class.php │ │ │ │ │ ├── Memcache.class.php │ │ │ │ │ ├── Memcached.class.php │ │ │ │ │ ├── Memcachesae.class.php │ │ │ │ │ ├── Redis.class.php │ │ │ │ │ ├── Shmop.class.php │ │ │ │ │ ├── Sqlite.class.php │ │ │ │ │ ├── Wincache.class.php │ │ │ │ │ └── Xcache.class.php │ │ │ │ ├── Cache.class.php │ │ │ │ ├── Controller.class.php │ │ │ │ ├── Db/ │ │ │ │ │ ├── Driver/ │ │ │ │ │ │ ├── Firebird.class.php │ │ │ │ │ │ ├── Mongo.class.php │ │ │ │ │ │ ├── Mysql.class.php │ │ │ │ │ │ ├── Oracle.class.php │ │ │ │ │ │ ├── Pgsql.class.php │ │ │ │ │ │ ├── Sqlite.class.php │ │ │ │ │ │ └── Sqlsrv.class.php │ │ │ │ │ ├── Driver.class.php │ │ │ │ │ └── Lite.class.php │ │ │ │ ├── Db.class.php │ │ │ │ ├── Dispatcher.class.php │ │ │ │ ├── Exception.class.php │ │ │ │ ├── Hook.class.php │ │ │ │ ├── Log/ │ │ │ │ │ └── Driver/ │ │ │ │ │ ├── File.class.php │ │ │ │ │ └── Sae.class.php │ │ │ │ ├── Log.class.php │ │ │ │ ├── Model.class.php │ │ │ │ ├── Route.class.php │ │ │ │ ├── Storage/ │ │ │ │ │ └── Driver/ │ │ │ │ │ ├── File.class.php │ │ │ │ │ └── Sae.class.php │ │ │ │ ├── Storage.class.php │ │ │ │ ├── Template/ │ │ │ │ │ ├── Driver/ │ │ │ │ │ │ ├── Ease.class.php │ │ │ │ │ │ ├── Lite.class.php │ │ │ │ │ │ ├── Mobile.class.php │ │ │ │ │ │ ├── Smart.class.php │ │ │ │ │ │ └── Smarty.class.php │ │ │ │ │ ├── TagLib/ │ │ │ │ │ │ ├── Cx.class.php │ │ │ │ │ │ └── Html.class.php │ │ │ │ │ └── TagLib.class.php │ │ │ │ ├── Template.class.php │ │ │ │ ├── Think.class.php │ │ │ │ ├── Upload/ │ │ │ │ │ └── Driver/ │ │ │ │ │ ├── Bcs/ │ │ │ │ │ │ ├── bcs.class.php │ │ │ │ │ │ ├── mimetypes.class.php │ │ │ │ │ │ └── requestcore.class.php │ │ │ │ │ ├── Bcs.class.php │ │ │ │ │ ├── Ftp.class.php │ │ │ │ │ ├── Local.class.php │ │ │ │ │ ├── Qiniu/ │ │ │ │ │ │ └── QiniuStorage.class.php │ │ │ │ │ ├── Qiniu.class.php │ │ │ │ │ ├── Sae.class.php │ │ │ │ │ └── Upyun.class.php │ │ │ │ ├── Upload.class.php │ │ │ │ └── View.class.php │ │ │ └── Vendor/ │ │ │ ├── Alioss/ │ │ │ │ ├── autoload.php │ │ │ │ ├── build-phar.sh │ │ │ │ ├── composer.json │ │ │ │ ├── index.php │ │ │ │ └── src/ │ │ │ │ └── OSS/ │ │ │ │ ├── Core/ │ │ │ │ │ ├── MimeTypes.php │ │ │ │ │ ├── OssException.php │ │ │ │ │ └── OssUtil.php │ │ │ │ ├── Http/ │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── RequestCore.php │ │ │ │ │ ├── RequestCore_Exception.php │ │ │ │ │ └── ResponseCore.php │ │ │ │ ├── Model/ │ │ │ │ │ ├── BucketInfo.php │ │ │ │ │ ├── BucketListInfo.php │ │ │ │ │ ├── CnameConfig.php │ │ │ │ │ ├── CorsConfig.php │ │ │ │ │ ├── CorsRule.php │ │ │ │ │ ├── GetLiveChannelHistory.php │ │ │ │ │ ├── GetLiveChannelInfo.php │ │ │ │ │ ├── GetLiveChannelStatus.php │ │ │ │ │ ├── LifecycleAction.php │ │ │ │ │ ├── LifecycleConfig.php │ │ │ │ │ ├── LifecycleRule.php │ │ │ │ │ ├── ListMultipartUploadInfo.php │ │ │ │ │ ├── ListPartsInfo.php │ │ │ │ │ ├── LiveChannelConfig.php │ │ │ │ │ ├── LiveChannelHistory.php │ │ │ │ │ ├── LiveChannelInfo.php │ │ │ │ │ ├── LiveChannelListInfo.php │ │ │ │ │ ├── LoggingConfig.php │ │ │ │ │ ├── ObjectInfo.php │ │ │ │ │ ├── ObjectListInfo.php │ │ │ │ │ ├── PartInfo.php │ │ │ │ │ ├── PrefixInfo.php │ │ │ │ │ ├── RefererConfig.php │ │ │ │ │ ├── StorageCapacityConfig.php │ │ │ │ │ ├── UploadInfo.php │ │ │ │ │ ├── WebsiteConfig.php │ │ │ │ │ └── XmlConfig.php │ │ │ │ ├── OssClient.php │ │ │ │ └── Result/ │ │ │ │ ├── AclResult.php │ │ │ │ ├── AppendResult.php │ │ │ │ ├── BodyResult.php │ │ │ │ ├── CallbackResult.php │ │ │ │ ├── CopyObjectResult.php │ │ │ │ ├── DeleteObjectsResult.php │ │ │ │ ├── ExistResult.php │ │ │ │ ├── GetCnameResult.php │ │ │ │ ├── GetCorsResult.php │ │ │ │ ├── GetLifecycleResult.php │ │ │ │ ├── GetLiveChannelHistoryResult.php │ │ │ │ ├── GetLiveChannelInfoResult.php │ │ │ │ ├── GetLiveChannelStatusResult.php │ │ │ │ ├── GetLocationResult.php │ │ │ │ ├── GetLoggingResult.php │ │ │ │ ├── GetRefererResult.php │ │ │ │ ├── GetStorageCapacityResult.php │ │ │ │ ├── GetWebsiteResult.php │ │ │ │ ├── HeaderResult.php │ │ │ │ ├── InitiateMultipartUploadResult.php │ │ │ │ ├── ListBucketsResult.php │ │ │ │ ├── ListLiveChannelResult.php │ │ │ │ ├── ListMultipartUploadResult.php │ │ │ │ ├── ListObjectsResult.php │ │ │ │ ├── ListPartsResult.php │ │ │ │ ├── PutLiveChannelResult.php │ │ │ │ ├── PutSetDeleteResult.php │ │ │ │ ├── Result.php │ │ │ │ ├── SymlinkResult.php │ │ │ │ └── UploadPartResult.php │ │ │ ├── Parsedown/ │ │ │ │ └── Parsedown.class.php │ │ │ ├── Phpqrcode/ │ │ │ │ └── phpqrcode.php │ │ │ └── README.txt │ │ ├── Mode/ │ │ │ └── common.php │ │ ├── ThinkPHP.php │ │ └── Tpl/ │ │ ├── dispatch_jump.tpl │ │ ├── page_trace.tpl │ │ └── think_exception.tpl │ ├── app/ │ │ ├── Api/ │ │ │ └── Controller/ │ │ │ ├── AdminItemController.php │ │ │ ├── AdminMessageController.php │ │ │ ├── AdminSettingController.php │ │ │ ├── AdminUpdateController.php │ │ │ ├── AdminUserController.php │ │ │ ├── AiController.php │ │ │ ├── AiTokenController.php │ │ │ ├── AttachmentController.php │ │ │ ├── CatalogController.php │ │ │ ├── CommonController.php │ │ │ ├── ExportController.php │ │ │ ├── ExportHtmlController.php │ │ │ ├── ExtLoginController.php │ │ │ ├── FlowController.php │ │ │ ├── FromCommentsController.php │ │ │ ├── ImportController.php │ │ │ ├── ImportPostmanController.php │ │ │ ├── ImportSwaggerController.php │ │ │ ├── ItemController.php │ │ │ ├── ItemGroupController.php │ │ │ ├── ItemVariableController.php │ │ │ ├── McpController.php │ │ │ ├── MemberController.php │ │ │ ├── MessageController.php │ │ │ ├── MockController.php │ │ │ ├── OpenController.php │ │ │ ├── PageCommentController.php │ │ │ ├── PageController.php │ │ │ ├── PageFeedbackController.php │ │ │ ├── ParamDescLibController.php │ │ │ ├── PublicSquareController.php │ │ │ ├── RecycleController.php │ │ │ ├── RunapiController.php │ │ │ ├── ScriptCronController.php │ │ │ ├── SubscriptionController.php │ │ │ ├── TeamController.php │ │ │ ├── TeamItemController.php │ │ │ ├── TeamItemMemberController.php │ │ │ ├── TeamMemberController.php │ │ │ ├── TemplateController.php │ │ │ ├── UpdateController.php │ │ │ └── UserController.php │ │ ├── Common/ │ │ │ ├── BaseController.php │ │ │ ├── BotDetector.php │ │ │ ├── Cache/ │ │ │ │ └── CacheManager.php │ │ │ ├── Config/ │ │ │ │ └── ErrorCodes.php │ │ │ ├── Database/ │ │ │ │ ├── Database.php │ │ │ │ └── Upgrade.php │ │ │ ├── Helper/ │ │ │ │ ├── AiHelper.php │ │ │ │ ├── ContentCodec.php │ │ │ │ ├── Convert.php │ │ │ │ ├── Env.php │ │ │ │ ├── FileHelper.php │ │ │ │ ├── HttpHelper.php │ │ │ │ ├── IpHelper.php │ │ │ │ ├── LogHelper.php │ │ │ │ ├── OssHelper.php │ │ │ │ ├── Security.php │ │ │ │ └── UrlHelper.php │ │ │ ├── Vendor/ │ │ │ │ └── Parsedown.php │ │ │ ├── bootstrap.php │ │ │ └── container.php │ │ ├── Home/ │ │ │ └── Controller/ │ │ │ ├── CommonController.php │ │ │ ├── DomainController.php │ │ │ ├── IndexController.php │ │ │ ├── ItemController.php │ │ │ ├── PageController.php │ │ │ └── UserController.php │ │ ├── Mcp/ │ │ │ ├── Handler/ │ │ │ │ ├── AttachmentHandler.php │ │ │ │ ├── CatalogHandler.php │ │ │ │ ├── ItemHandler.php │ │ │ │ ├── OpenApiHandler.php │ │ │ │ └── PageHandler.php │ │ │ ├── McpError.php │ │ │ ├── McpException.php │ │ │ ├── McpHandler.php │ │ │ └── McpServer.php │ │ ├── Model/ │ │ │ ├── Attachment.php │ │ │ ├── Captcha.php │ │ │ ├── Catalog.php │ │ │ ├── ExportLog.php │ │ │ ├── FileFlow.php │ │ │ ├── FilePage.php │ │ │ ├── Item.php │ │ │ ├── ItemAiConfig.php │ │ │ ├── ItemBlacklist.php │ │ │ ├── ItemChangeLog.php │ │ │ ├── ItemGroup.php │ │ │ ├── ItemMember.php │ │ │ ├── ItemSort.php │ │ │ ├── ItemToken.php │ │ │ ├── ItemVariable.php │ │ │ ├── ItemViews.php │ │ │ ├── Member.php │ │ │ ├── Message.php │ │ │ ├── MessageContent.php │ │ │ ├── Mock.php │ │ │ ├── Options.php │ │ │ ├── Page.php │ │ │ ├── PageComment.php │ │ │ ├── PageFeedback.php │ │ │ ├── PageHistory.php │ │ │ ├── ParameterDescriptionEntry.php │ │ │ ├── Questionnaire.php │ │ │ ├── Recycle.php │ │ │ ├── Runapi.php │ │ │ ├── RunapiDbConfig.php │ │ │ ├── RunapiEnv.php │ │ │ ├── RunapiEnvSelectd.php │ │ │ ├── RunapiFlow.php │ │ │ ├── RunapiFlowPage.php │ │ │ ├── RunapiGlobalParam.php │ │ │ ├── SinglePage.php │ │ │ ├── Subscription.php │ │ │ ├── Team.php │ │ │ ├── TeamItem.php │ │ │ ├── TeamItemMember.php │ │ │ ├── TeamMember.php │ │ │ ├── Template.php │ │ │ ├── TemplateItem.php │ │ │ ├── UploadFile.php │ │ │ ├── User.php │ │ │ ├── UserAiToken.php │ │ │ ├── UserSetting.php │ │ │ ├── UserToken.php │ │ │ ├── VerifyCode.php │ │ │ └── VersionUpdate.php │ │ ├── Runtime/ │ │ │ ├── Cache/ │ │ │ │ └── index.html │ │ │ ├── Logs/ │ │ │ │ └── index.html │ │ │ └── index.html │ │ └── Static/ │ │ └── export-html/ │ │ ├── app.js │ │ └── common.css │ ├── index.php │ ├── index_old.php │ ├── tests/ │ │ └── mcp/ │ │ ├── README.md │ │ ├── bootstrap.php │ │ ├── mcp_test.php │ │ └── openapi3.json │ └── vendor/ │ ├── async-aws/ │ │ ├── core/ │ │ │ ├── .gitattributes │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── roave-bc-check.yaml │ │ │ └── src/ │ │ │ ├── AbstractApi.php │ │ │ ├── AwsClientFactory.php │ │ │ ├── AwsError/ │ │ │ │ ├── AwsError.php │ │ │ │ ├── AwsErrorFactoryFromResponseTrait.php │ │ │ │ ├── AwsErrorFactoryInterface.php │ │ │ │ ├── ChainAwsErrorFactory.php │ │ │ │ ├── JsonRestAwsErrorFactory.php │ │ │ │ ├── JsonRpcAwsErrorFactory.php │ │ │ │ └── XmlAwsErrorFactory.php │ │ │ ├── Configuration.php │ │ │ ├── Credentials/ │ │ │ │ ├── CacheProvider.php │ │ │ │ ├── ChainProvider.php │ │ │ │ ├── ConfigurationProvider.php │ │ │ │ ├── ContainerProvider.php │ │ │ │ ├── CredentialProvider.php │ │ │ │ ├── Credentials.php │ │ │ │ ├── DateFromResult.php │ │ │ │ ├── IniFileLoader.php │ │ │ │ ├── IniFileProvider.php │ │ │ │ ├── InstanceProvider.php │ │ │ │ ├── NullProvider.php │ │ │ │ ├── PsrCacheProvider.php │ │ │ │ ├── SsoCacheFileLoader.php │ │ │ │ ├── SsoTokenProvider.php │ │ │ │ ├── SymfonyCacheProvider.php │ │ │ │ ├── TokenFileLoader.php │ │ │ │ └── WebIdentityProvider.php │ │ │ ├── EndpointDiscovery/ │ │ │ │ ├── EndpointCache.php │ │ │ │ └── EndpointInterface.php │ │ │ ├── EnvVar.php │ │ │ ├── Exception/ │ │ │ │ ├── Exception.php │ │ │ │ ├── Http/ │ │ │ │ │ ├── ClientException.php │ │ │ │ │ ├── HttpException.php │ │ │ │ │ ├── HttpExceptionTrait.php │ │ │ │ │ ├── NetworkException.php │ │ │ │ │ ├── RedirectionException.php │ │ │ │ │ └── ServerException.php │ │ │ │ ├── InvalidArgument.php │ │ │ │ ├── LogicException.php │ │ │ │ ├── MissingDependency.php │ │ │ │ ├── RuntimeException.php │ │ │ │ ├── UnexpectedValue.php │ │ │ │ ├── UnparsableResponse.php │ │ │ │ └── UnsupportedRegion.php │ │ │ ├── HttpClient/ │ │ │ │ ├── AwsHttpClientFactory.php │ │ │ │ └── AwsRetryStrategy.php │ │ │ ├── Input.php │ │ │ ├── Request.php │ │ │ ├── RequestContext.php │ │ │ ├── Response.php │ │ │ ├── Result.php │ │ │ ├── Signer/ │ │ │ │ ├── Signer.php │ │ │ │ ├── SignerV4.php │ │ │ │ └── SigningContext.php │ │ │ ├── Stream/ │ │ │ │ ├── CallableStream.php │ │ │ │ ├── FixedSizeStream.php │ │ │ │ ├── IterableStream.php │ │ │ │ ├── ReadOnceResultStream.php │ │ │ │ ├── RequestStream.php │ │ │ │ ├── ResourceStream.php │ │ │ │ ├── ResponseBodyResourceStream.php │ │ │ │ ├── ResponseBodyStream.php │ │ │ │ ├── ResultStream.php │ │ │ │ ├── RewindableStream.php │ │ │ │ ├── StreamFactory.php │ │ │ │ └── StringStream.php │ │ │ ├── Sts/ │ │ │ │ ├── Exception/ │ │ │ │ │ ├── ExpiredTokenException.php │ │ │ │ │ ├── IDPCommunicationErrorException.php │ │ │ │ │ ├── IDPRejectedClaimException.php │ │ │ │ │ ├── InvalidIdentityTokenException.php │ │ │ │ │ ├── MalformedPolicyDocumentException.php │ │ │ │ │ ├── PackedPolicyTooLargeException.php │ │ │ │ │ └── RegionDisabledException.php │ │ │ │ ├── Input/ │ │ │ │ │ ├── AssumeRoleRequest.php │ │ │ │ │ ├── AssumeRoleWithWebIdentityRequest.php │ │ │ │ │ └── GetCallerIdentityRequest.php │ │ │ │ ├── Result/ │ │ │ │ │ ├── AssumeRoleResponse.php │ │ │ │ │ ├── AssumeRoleWithWebIdentityResponse.php │ │ │ │ │ └── GetCallerIdentityResponse.php │ │ │ │ ├── StsClient.php │ │ │ │ └── ValueObject/ │ │ │ │ ├── AssumedRoleUser.php │ │ │ │ ├── Credentials.php │ │ │ │ ├── PolicyDescriptorType.php │ │ │ │ ├── ProvidedContext.php │ │ │ │ └── Tag.php │ │ │ ├── Test/ │ │ │ │ ├── Http/ │ │ │ │ │ └── SimpleMockedResponse.php │ │ │ │ ├── ResultMockFactory.php │ │ │ │ ├── SimpleResultStream.php │ │ │ │ └── TestCase.php │ │ │ └── Waiter.php │ │ └── s3/ │ │ ├── .gitattributes │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ ├── Enum/ │ │ │ ├── ArchiveStatus.php │ │ │ ├── BucketCannedACL.php │ │ │ ├── BucketLocationConstraint.php │ │ │ ├── ChecksumAlgorithm.php │ │ │ ├── ChecksumMode.php │ │ │ ├── EncodingType.php │ │ │ ├── Event.php │ │ │ ├── FilterRuleName.php │ │ │ ├── IntelligentTieringAccessTier.php │ │ │ ├── MetadataDirective.php │ │ │ ├── ObjectCannedACL.php │ │ │ ├── ObjectLockLegalHoldStatus.php │ │ │ ├── ObjectLockMode.php │ │ │ ├── ObjectOwnership.php │ │ │ ├── ObjectStorageClass.php │ │ │ ├── Permission.php │ │ │ ├── ReplicationStatus.php │ │ │ ├── RequestCharged.php │ │ │ ├── RequestPayer.php │ │ │ ├── ServerSideEncryption.php │ │ │ ├── StorageClass.php │ │ │ ├── TaggingDirective.php │ │ │ └── Type.php │ │ ├── Exception/ │ │ │ ├── BucketAlreadyExistsException.php │ │ │ ├── BucketAlreadyOwnedByYouException.php │ │ │ ├── InvalidObjectStateException.php │ │ │ ├── NoSuchBucketException.php │ │ │ ├── NoSuchKeyException.php │ │ │ ├── NoSuchUploadException.php │ │ │ └── ObjectNotInActiveTierErrorException.php │ │ ├── Input/ │ │ │ ├── AbortMultipartUploadRequest.php │ │ │ ├── CompleteMultipartUploadRequest.php │ │ │ ├── CopyObjectRequest.php │ │ │ ├── CreateBucketRequest.php │ │ │ ├── CreateMultipartUploadRequest.php │ │ │ ├── DeleteBucketCorsRequest.php │ │ │ ├── DeleteBucketRequest.php │ │ │ ├── DeleteObjectRequest.php │ │ │ ├── DeleteObjectsRequest.php │ │ │ ├── GetBucketCorsRequest.php │ │ │ ├── GetBucketEncryptionRequest.php │ │ │ ├── GetObjectAclRequest.php │ │ │ ├── GetObjectRequest.php │ │ │ ├── HeadBucketRequest.php │ │ │ ├── HeadObjectRequest.php │ │ │ ├── ListBucketsRequest.php │ │ │ ├── ListMultipartUploadsRequest.php │ │ │ ├── ListObjectsV2Request.php │ │ │ ├── ListPartsRequest.php │ │ │ ├── PutBucketCorsRequest.php │ │ │ ├── PutBucketNotificationConfigurationRequest.php │ │ │ ├── PutObjectAclRequest.php │ │ │ ├── PutObjectRequest.php │ │ │ └── UploadPartRequest.php │ │ ├── Result/ │ │ │ ├── AbortMultipartUploadOutput.php │ │ │ ├── BucketExistsWaiter.php │ │ │ ├── BucketNotExistsWaiter.php │ │ │ ├── CompleteMultipartUploadOutput.php │ │ │ ├── CopyObjectOutput.php │ │ │ ├── CreateBucketOutput.php │ │ │ ├── CreateMultipartUploadOutput.php │ │ │ ├── DeleteObjectOutput.php │ │ │ ├── DeleteObjectsOutput.php │ │ │ ├── GetBucketCorsOutput.php │ │ │ ├── GetBucketEncryptionOutput.php │ │ │ ├── GetObjectAclOutput.php │ │ │ ├── GetObjectOutput.php │ │ │ ├── HeadObjectOutput.php │ │ │ ├── ListBucketsOutput.php │ │ │ ├── ListMultipartUploadsOutput.php │ │ │ ├── ListObjectsV2Output.php │ │ │ ├── ListPartsOutput.php │ │ │ ├── ObjectExistsWaiter.php │ │ │ ├── ObjectNotExistsWaiter.php │ │ │ ├── PutObjectAclOutput.php │ │ │ ├── PutObjectOutput.php │ │ │ └── UploadPartOutput.php │ │ ├── S3Client.php │ │ ├── Signer/ │ │ │ └── SignerV4ForS3.php │ │ └── ValueObject/ │ │ ├── AccessControlPolicy.php │ │ ├── AwsObject.php │ │ ├── Bucket.php │ │ ├── CORSConfiguration.php │ │ ├── CORSRule.php │ │ ├── CommonPrefix.php │ │ ├── CompletedMultipartUpload.php │ │ ├── CompletedPart.php │ │ ├── CopyObjectResult.php │ │ ├── CreateBucketConfiguration.php │ │ ├── Delete.php │ │ ├── DeletedObject.php │ │ ├── Error.php │ │ ├── EventBridgeConfiguration.php │ │ ├── FilterRule.php │ │ ├── Grant.php │ │ ├── Grantee.php │ │ ├── Initiator.php │ │ ├── LambdaFunctionConfiguration.php │ │ ├── MultipartUpload.php │ │ ├── NotificationConfiguration.php │ │ ├── NotificationConfigurationFilter.php │ │ ├── ObjectIdentifier.php │ │ ├── Owner.php │ │ ├── Part.php │ │ ├── QueueConfiguration.php │ │ ├── S3KeyFilter.php │ │ ├── ServerSideEncryptionByDefault.php │ │ ├── ServerSideEncryptionConfiguration.php │ │ ├── ServerSideEncryptionRule.php │ │ └── TopicConfiguration.php │ ├── autoload.php │ ├── bin/ │ │ └── carbon │ ├── carbonphp/ │ │ └── carbon-doctrine-types/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ └── Carbon/ │ │ └── Doctrine/ │ │ ├── CarbonDoctrineType.php │ │ ├── CarbonImmutableType.php │ │ ├── CarbonType.php │ │ ├── CarbonTypeConverter.php │ │ ├── DateTimeDefaultPrecision.php │ │ ├── DateTimeImmutableType.php │ │ └── DateTimeType.php │ ├── composer/ │ │ ├── ClassLoader.php │ │ ├── InstalledVersions.php │ │ ├── LICENSE │ │ ├── autoload_classmap.php │ │ ├── autoload_files.php │ │ ├── autoload_namespaces.php │ │ ├── autoload_psr4.php │ │ ├── autoload_real.php │ │ ├── autoload_static.php │ │ ├── installed.json │ │ ├── installed.php │ │ └── platform_check.php │ ├── doctrine/ │ │ └── inflector/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ ├── docs/ │ │ │ └── en/ │ │ │ └── index.rst │ │ └── lib/ │ │ └── Doctrine/ │ │ └── Inflector/ │ │ ├── CachedWordInflector.php │ │ ├── GenericLanguageInflectorFactory.php │ │ ├── Inflector.php │ │ ├── InflectorFactory.php │ │ ├── Language.php │ │ ├── LanguageInflectorFactory.php │ │ ├── NoopWordInflector.php │ │ ├── Rules/ │ │ │ ├── English/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ ├── French/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ ├── NorwegianBokmal/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ ├── Pattern.php │ │ │ ├── Patterns.php │ │ │ ├── Portuguese/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ ├── Ruleset.php │ │ │ ├── Spanish/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ ├── Substitution.php │ │ │ ├── Substitutions.php │ │ │ ├── Transformation.php │ │ │ ├── Transformations.php │ │ │ ├── Turkish/ │ │ │ │ ├── Inflectible.php │ │ │ │ ├── InflectorFactory.php │ │ │ │ ├── Rules.php │ │ │ │ └── Uninflected.php │ │ │ └── Word.php │ │ ├── RulesetInflector.php │ │ └── WordInflector.php │ ├── graham-campbell/ │ │ └── result-type/ │ │ ├── LICENSE │ │ ├── composer.json │ │ └── src/ │ │ ├── Error.php │ │ ├── Result.php │ │ └── Success.php │ ├── guzzlehttp/ │ │ ├── command/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── Command.php │ │ │ ├── CommandInterface.php │ │ │ ├── Exception/ │ │ │ │ ├── CommandClientException.php │ │ │ │ ├── CommandException.php │ │ │ │ └── CommandServerException.php │ │ │ ├── HasDataTrait.php │ │ │ ├── Result.php │ │ │ ├── ResultInterface.php │ │ │ ├── ServiceClient.php │ │ │ ├── ServiceClientInterface.php │ │ │ └── ToArrayInterface.php │ │ ├── guzzle/ │ │ │ ├── .php_cs │ │ │ ├── CHANGELOG.md │ │ │ ├── Dockerfile │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── UPGRADING.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── Client.php │ │ │ ├── ClientInterface.php │ │ │ ├── Cookie/ │ │ │ │ ├── CookieJar.php │ │ │ │ ├── CookieJarInterface.php │ │ │ │ ├── FileCookieJar.php │ │ │ │ ├── SessionCookieJar.php │ │ │ │ └── SetCookie.php │ │ │ ├── Exception/ │ │ │ │ ├── BadResponseException.php │ │ │ │ ├── ClientException.php │ │ │ │ ├── ConnectException.php │ │ │ │ ├── GuzzleException.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ ├── RequestException.php │ │ │ │ ├── SeekException.php │ │ │ │ ├── ServerException.php │ │ │ │ ├── TooManyRedirectsException.php │ │ │ │ └── TransferException.php │ │ │ ├── Handler/ │ │ │ │ ├── CurlFactory.php │ │ │ │ ├── CurlFactoryInterface.php │ │ │ │ ├── CurlHandler.php │ │ │ │ ├── CurlMultiHandler.php │ │ │ │ ├── EasyHandle.php │ │ │ │ ├── MockHandler.php │ │ │ │ ├── Proxy.php │ │ │ │ └── StreamHandler.php │ │ │ ├── HandlerStack.php │ │ │ ├── MessageFormatter.php │ │ │ ├── Middleware.php │ │ │ ├── Pool.php │ │ │ ├── PrepareBodyMiddleware.php │ │ │ ├── RedirectMiddleware.php │ │ │ ├── RequestOptions.php │ │ │ ├── RetryMiddleware.php │ │ │ ├── TransferStats.php │ │ │ ├── UriTemplate.php │ │ │ ├── Utils.php │ │ │ ├── functions.php │ │ │ └── functions_include.php │ │ ├── promises/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── AggregateException.php │ │ │ ├── CancellationException.php │ │ │ ├── Coroutine.php │ │ │ ├── Create.php │ │ │ ├── Each.php │ │ │ ├── EachPromise.php │ │ │ ├── FulfilledPromise.php │ │ │ ├── Is.php │ │ │ ├── Promise.php │ │ │ ├── PromiseInterface.php │ │ │ ├── PromisorInterface.php │ │ │ ├── RejectedPromise.php │ │ │ ├── RejectionException.php │ │ │ ├── TaskQueue.php │ │ │ ├── TaskQueueInterface.php │ │ │ ├── Utils.php │ │ │ ├── functions.php │ │ │ └── functions_include.php │ │ └── psr7/ │ │ ├── .github/ │ │ │ ├── FUNDING.yml │ │ │ ├── stale.yml │ │ │ └── workflows/ │ │ │ ├── ci.yml │ │ │ ├── integration.yml │ │ │ └── static.yml │ │ ├── .php_cs.dist │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ ├── AppendStream.php │ │ ├── BufferStream.php │ │ ├── CachingStream.php │ │ ├── DroppingStream.php │ │ ├── FnStream.php │ │ ├── Header.php │ │ ├── InflateStream.php │ │ ├── LazyOpenStream.php │ │ ├── LimitStream.php │ │ ├── Message.php │ │ ├── MessageTrait.php │ │ ├── MimeType.php │ │ ├── MultipartStream.php │ │ ├── NoSeekStream.php │ │ ├── PumpStream.php │ │ ├── Query.php │ │ ├── Request.php │ │ ├── Response.php │ │ ├── Rfc7230.php │ │ ├── ServerRequest.php │ │ ├── Stream.php │ │ ├── StreamDecoratorTrait.php │ │ ├── StreamWrapper.php │ │ ├── UploadedFile.php │ │ ├── Uri.php │ │ ├── UriComparator.php │ │ ├── UriNormalizer.php │ │ ├── UriResolver.php │ │ ├── Utils.php │ │ ├── functions.php │ │ └── functions_include.php │ ├── illuminate/ │ │ ├── bus/ │ │ │ ├── Batch.php │ │ │ ├── BatchFactory.php │ │ │ ├── BatchRepository.php │ │ │ ├── Batchable.php │ │ │ ├── BusServiceProvider.php │ │ │ ├── DatabaseBatchRepository.php │ │ │ ├── Dispatcher.php │ │ │ ├── Events/ │ │ │ │ └── BatchDispatched.php │ │ │ ├── LICENSE.md │ │ │ ├── PendingBatch.php │ │ │ ├── PrunableBatchRepository.php │ │ │ ├── Queueable.php │ │ │ ├── UniqueLock.php │ │ │ ├── UpdatedBatchJobCounts.php │ │ │ └── composer.json │ │ ├── collections/ │ │ │ ├── Arr.php │ │ │ ├── Collection.php │ │ │ ├── Enumerable.php │ │ │ ├── HigherOrderCollectionProxy.php │ │ │ ├── HigherOrderWhenProxy.php │ │ │ ├── ItemNotFoundException.php │ │ │ ├── LICENSE.md │ │ │ ├── LazyCollection.php │ │ │ ├── MultipleItemsFoundException.php │ │ │ ├── Traits/ │ │ │ │ └── EnumeratesValues.php │ │ │ ├── composer.json │ │ │ └── helpers.php │ │ ├── container/ │ │ │ ├── BoundMethod.php │ │ │ ├── Container.php │ │ │ ├── ContextualBindingBuilder.php │ │ │ ├── EntryNotFoundException.php │ │ │ ├── LICENSE.md │ │ │ ├── RewindableGenerator.php │ │ │ ├── Util.php │ │ │ └── composer.json │ │ ├── contracts/ │ │ │ ├── Auth/ │ │ │ │ ├── Access/ │ │ │ │ │ ├── Authorizable.php │ │ │ │ │ └── Gate.php │ │ │ │ ├── Authenticatable.php │ │ │ │ ├── CanResetPassword.php │ │ │ │ ├── Factory.php │ │ │ │ ├── Guard.php │ │ │ │ ├── Middleware/ │ │ │ │ │ └── AuthenticatesRequests.php │ │ │ │ ├── MustVerifyEmail.php │ │ │ │ ├── PasswordBroker.php │ │ │ │ ├── PasswordBrokerFactory.php │ │ │ │ ├── StatefulGuard.php │ │ │ │ ├── SupportsBasicAuth.php │ │ │ │ └── UserProvider.php │ │ │ ├── Broadcasting/ │ │ │ │ ├── Broadcaster.php │ │ │ │ ├── Factory.php │ │ │ │ ├── HasBroadcastChannel.php │ │ │ │ ├── ShouldBroadcast.php │ │ │ │ └── ShouldBroadcastNow.php │ │ │ ├── Bus/ │ │ │ │ ├── Dispatcher.php │ │ │ │ └── QueueingDispatcher.php │ │ │ ├── Cache/ │ │ │ │ ├── Factory.php │ │ │ │ ├── Lock.php │ │ │ │ ├── LockProvider.php │ │ │ │ ├── LockTimeoutException.php │ │ │ │ ├── Repository.php │ │ │ │ └── Store.php │ │ │ ├── Config/ │ │ │ │ └── Repository.php │ │ │ ├── Console/ │ │ │ │ ├── Application.php │ │ │ │ └── Kernel.php │ │ │ ├── Container/ │ │ │ │ ├── BindingResolutionException.php │ │ │ │ ├── CircularDependencyException.php │ │ │ │ ├── Container.php │ │ │ │ └── ContextualBindingBuilder.php │ │ │ ├── Cookie/ │ │ │ │ ├── Factory.php │ │ │ │ └── QueueingFactory.php │ │ │ ├── Database/ │ │ │ │ ├── Eloquent/ │ │ │ │ │ ├── Castable.php │ │ │ │ │ ├── CastsAttributes.php │ │ │ │ │ ├── CastsInboundAttributes.php │ │ │ │ │ ├── DeviatesCastableAttributes.php │ │ │ │ │ ├── SerializesCastableAttributes.php │ │ │ │ │ └── SupportsPartialRelations.php │ │ │ │ ├── Events/ │ │ │ │ │ └── MigrationEvent.php │ │ │ │ └── ModelIdentifier.php │ │ │ ├── Debug/ │ │ │ │ └── ExceptionHandler.php │ │ │ ├── Encryption/ │ │ │ │ ├── DecryptException.php │ │ │ │ ├── EncryptException.php │ │ │ │ ├── Encrypter.php │ │ │ │ └── StringEncrypter.php │ │ │ ├── Events/ │ │ │ │ └── Dispatcher.php │ │ │ ├── Filesystem/ │ │ │ │ ├── Cloud.php │ │ │ │ ├── Factory.php │ │ │ │ ├── FileExistsException.php │ │ │ │ ├── FileNotFoundException.php │ │ │ │ ├── Filesystem.php │ │ │ │ └── LockTimeoutException.php │ │ │ ├── Foundation/ │ │ │ │ ├── Application.php │ │ │ │ ├── CachesConfiguration.php │ │ │ │ └── CachesRoutes.php │ │ │ ├── Hashing/ │ │ │ │ └── Hasher.php │ │ │ ├── Http/ │ │ │ │ └── Kernel.php │ │ │ ├── LICENSE.md │ │ │ ├── Mail/ │ │ │ │ ├── Factory.php │ │ │ │ ├── MailQueue.php │ │ │ │ ├── Mailable.php │ │ │ │ └── Mailer.php │ │ │ ├── Notifications/ │ │ │ │ ├── Dispatcher.php │ │ │ │ └── Factory.php │ │ │ ├── Pagination/ │ │ │ │ ├── CursorPaginator.php │ │ │ │ ├── LengthAwarePaginator.php │ │ │ │ └── Paginator.php │ │ │ ├── Pipeline/ │ │ │ │ ├── Hub.php │ │ │ │ └── Pipeline.php │ │ │ ├── Queue/ │ │ │ │ ├── ClearableQueue.php │ │ │ │ ├── EntityNotFoundException.php │ │ │ │ ├── EntityResolver.php │ │ │ │ ├── Factory.php │ │ │ │ ├── Job.php │ │ │ │ ├── Monitor.php │ │ │ │ ├── Queue.php │ │ │ │ ├── QueueableCollection.php │ │ │ │ ├── QueueableEntity.php │ │ │ │ ├── ShouldBeEncrypted.php │ │ │ │ ├── ShouldBeUnique.php │ │ │ │ ├── ShouldBeUniqueUntilProcessing.php │ │ │ │ └── ShouldQueue.php │ │ │ ├── Redis/ │ │ │ │ ├── Connection.php │ │ │ │ ├── Connector.php │ │ │ │ ├── Factory.php │ │ │ │ └── LimiterTimeoutException.php │ │ │ ├── Routing/ │ │ │ │ ├── BindingRegistrar.php │ │ │ │ ├── Registrar.php │ │ │ │ ├── ResponseFactory.php │ │ │ │ ├── UrlGenerator.php │ │ │ │ └── UrlRoutable.php │ │ │ ├── Session/ │ │ │ │ └── Session.php │ │ │ ├── Support/ │ │ │ │ ├── Arrayable.php │ │ │ │ ├── CanBeEscapedWhenCastToString.php │ │ │ │ ├── DeferrableProvider.php │ │ │ │ ├── DeferringDisplayableValue.php │ │ │ │ ├── Htmlable.php │ │ │ │ ├── Jsonable.php │ │ │ │ ├── MessageBag.php │ │ │ │ ├── MessageProvider.php │ │ │ │ ├── Renderable.php │ │ │ │ ├── Responsable.php │ │ │ │ └── ValidatedData.php │ │ │ ├── Translation/ │ │ │ │ ├── HasLocalePreference.php │ │ │ │ ├── Loader.php │ │ │ │ └── Translator.php │ │ │ ├── Validation/ │ │ │ │ ├── DataAwareRule.php │ │ │ │ ├── Factory.php │ │ │ │ ├── ImplicitRule.php │ │ │ │ ├── Rule.php │ │ │ │ ├── UncompromisedVerifier.php │ │ │ │ ├── ValidatesWhenResolved.php │ │ │ │ ├── Validator.php │ │ │ │ └── ValidatorAwareRule.php │ │ │ ├── View/ │ │ │ │ ├── Engine.php │ │ │ │ ├── Factory.php │ │ │ │ └── View.php │ │ │ └── composer.json │ │ ├── database/ │ │ │ ├── Capsule/ │ │ │ │ └── Manager.php │ │ │ ├── ClassMorphViolationException.php │ │ │ ├── Concerns/ │ │ │ │ ├── BuildsQueries.php │ │ │ │ ├── ExplainsQueries.php │ │ │ │ └── ManagesTransactions.php │ │ │ ├── ConfigurationUrlParser.php │ │ │ ├── Connection.php │ │ │ ├── ConnectionInterface.php │ │ │ ├── ConnectionResolver.php │ │ │ ├── ConnectionResolverInterface.php │ │ │ ├── Connectors/ │ │ │ │ ├── ConnectionFactory.php │ │ │ │ ├── Connector.php │ │ │ │ ├── ConnectorInterface.php │ │ │ │ ├── MySqlConnector.php │ │ │ │ ├── PostgresConnector.php │ │ │ │ ├── SQLiteConnector.php │ │ │ │ └── SqlServerConnector.php │ │ │ ├── Console/ │ │ │ │ ├── DbCommand.php │ │ │ │ ├── DumpCommand.php │ │ │ │ ├── Factories/ │ │ │ │ │ ├── FactoryMakeCommand.php │ │ │ │ │ └── stubs/ │ │ │ │ │ └── factory.stub │ │ │ │ ├── Migrations/ │ │ │ │ │ ├── BaseCommand.php │ │ │ │ │ ├── FreshCommand.php │ │ │ │ │ ├── InstallCommand.php │ │ │ │ │ ├── MigrateCommand.php │ │ │ │ │ ├── MigrateMakeCommand.php │ │ │ │ │ ├── RefreshCommand.php │ │ │ │ │ ├── ResetCommand.php │ │ │ │ │ ├── RollbackCommand.php │ │ │ │ │ ├── StatusCommand.php │ │ │ │ │ └── TableGuesser.php │ │ │ │ ├── PruneCommand.php │ │ │ │ ├── Seeds/ │ │ │ │ │ ├── SeedCommand.php │ │ │ │ │ ├── SeederMakeCommand.php │ │ │ │ │ └── stubs/ │ │ │ │ │ └── seeder.stub │ │ │ │ └── WipeCommand.php │ │ │ ├── DBAL/ │ │ │ │ └── TimestampType.php │ │ │ ├── DatabaseManager.php │ │ │ ├── DatabaseServiceProvider.php │ │ │ ├── DatabaseTransactionRecord.php │ │ │ ├── DatabaseTransactionsManager.php │ │ │ ├── DetectsConcurrencyErrors.php │ │ │ ├── DetectsLostConnections.php │ │ │ ├── Eloquent/ │ │ │ │ ├── BroadcastableModelEventOccurred.php │ │ │ │ ├── BroadcastsEvents.php │ │ │ │ ├── Builder.php │ │ │ │ ├── Casts/ │ │ │ │ │ ├── ArrayObject.php │ │ │ │ │ ├── AsArrayObject.php │ │ │ │ │ ├── AsCollection.php │ │ │ │ │ ├── AsEncryptedArrayObject.php │ │ │ │ │ ├── AsEncryptedCollection.php │ │ │ │ │ ├── AsStringable.php │ │ │ │ │ └── Attribute.php │ │ │ │ ├── Collection.php │ │ │ │ ├── Concerns/ │ │ │ │ │ ├── GuardsAttributes.php │ │ │ │ │ ├── HasAttributes.php │ │ │ │ │ ├── HasEvents.php │ │ │ │ │ ├── HasGlobalScopes.php │ │ │ │ │ ├── HasRelationships.php │ │ │ │ │ ├── HasTimestamps.php │ │ │ │ │ ├── HidesAttributes.php │ │ │ │ │ └── QueriesRelationships.php │ │ │ │ ├── Factories/ │ │ │ │ │ ├── BelongsToManyRelationship.php │ │ │ │ │ ├── BelongsToRelationship.php │ │ │ │ │ ├── CrossJoinSequence.php │ │ │ │ │ ├── Factory.php │ │ │ │ │ ├── HasFactory.php │ │ │ │ │ ├── Relationship.php │ │ │ │ │ └── Sequence.php │ │ │ │ ├── HigherOrderBuilderProxy.php │ │ │ │ ├── InvalidCastException.php │ │ │ │ ├── JsonEncodingException.php │ │ │ │ ├── MassAssignmentException.php │ │ │ │ ├── MassPrunable.php │ │ │ │ ├── Model.php │ │ │ │ ├── ModelNotFoundException.php │ │ │ │ ├── Prunable.php │ │ │ │ ├── QueueEntityResolver.php │ │ │ │ ├── RelationNotFoundException.php │ │ │ │ ├── Relations/ │ │ │ │ │ ├── BelongsTo.php │ │ │ │ │ ├── BelongsToMany.php │ │ │ │ │ ├── Concerns/ │ │ │ │ │ │ ├── AsPivot.php │ │ │ │ │ │ ├── CanBeOneOfMany.php │ │ │ │ │ │ ├── ComparesRelatedModels.php │ │ │ │ │ │ ├── InteractsWithDictionary.php │ │ │ │ │ │ ├── InteractsWithPivotTable.php │ │ │ │ │ │ └── SupportsDefaultModels.php │ │ │ │ │ ├── HasMany.php │ │ │ │ │ ├── HasManyThrough.php │ │ │ │ │ ├── HasOne.php │ │ │ │ │ ├── HasOneOrMany.php │ │ │ │ │ ├── HasOneThrough.php │ │ │ │ │ ├── MorphMany.php │ │ │ │ │ ├── MorphOne.php │ │ │ │ │ ├── MorphOneOrMany.php │ │ │ │ │ ├── MorphPivot.php │ │ │ │ │ ├── MorphTo.php │ │ │ │ │ ├── MorphToMany.php │ │ │ │ │ ├── Pivot.php │ │ │ │ │ └── Relation.php │ │ │ │ ├── Scope.php │ │ │ │ ├── SoftDeletes.php │ │ │ │ └── SoftDeletingScope.php │ │ │ ├── Events/ │ │ │ │ ├── ConnectionEvent.php │ │ │ │ ├── DatabaseRefreshed.php │ │ │ │ ├── MigrationEnded.php │ │ │ │ ├── MigrationEvent.php │ │ │ │ ├── MigrationStarted.php │ │ │ │ ├── MigrationsEnded.php │ │ │ │ ├── MigrationsEvent.php │ │ │ │ ├── MigrationsStarted.php │ │ │ │ ├── ModelsPruned.php │ │ │ │ ├── NoPendingMigrations.php │ │ │ │ ├── QueryExecuted.php │ │ │ │ ├── SchemaDumped.php │ │ │ │ ├── SchemaLoaded.php │ │ │ │ ├── StatementPrepared.php │ │ │ │ ├── TransactionBeginning.php │ │ │ │ ├── TransactionCommitted.php │ │ │ │ └── TransactionRolledBack.php │ │ │ ├── Grammar.php │ │ │ ├── LICENSE.md │ │ │ ├── LazyLoadingViolationException.php │ │ │ ├── MigrationServiceProvider.php │ │ │ ├── Migrations/ │ │ │ │ ├── DatabaseMigrationRepository.php │ │ │ │ ├── Migration.php │ │ │ │ ├── MigrationCreator.php │ │ │ │ ├── MigrationRepositoryInterface.php │ │ │ │ ├── Migrator.php │ │ │ │ └── stubs/ │ │ │ │ ├── migration.create.stub │ │ │ │ ├── migration.stub │ │ │ │ └── migration.update.stub │ │ │ ├── MultipleRecordsFoundException.php │ │ │ ├── MySqlConnection.php │ │ │ ├── PDO/ │ │ │ │ ├── Concerns/ │ │ │ │ │ └── ConnectsToDatabase.php │ │ │ │ ├── Connection.php │ │ │ │ ├── MySqlDriver.php │ │ │ │ ├── PostgresDriver.php │ │ │ │ ├── SQLiteDriver.php │ │ │ │ ├── SqlServerConnection.php │ │ │ │ └── SqlServerDriver.php │ │ │ ├── PostgresConnection.php │ │ │ ├── Query/ │ │ │ │ ├── Builder.php │ │ │ │ ├── Expression.php │ │ │ │ ├── Grammars/ │ │ │ │ │ ├── Grammar.php │ │ │ │ │ ├── MySqlGrammar.php │ │ │ │ │ ├── PostgresGrammar.php │ │ │ │ │ ├── SQLiteGrammar.php │ │ │ │ │ └── SqlServerGrammar.php │ │ │ │ ├── JoinClause.php │ │ │ │ └── Processors/ │ │ │ │ ├── MySqlProcessor.php │ │ │ │ ├── PostgresProcessor.php │ │ │ │ ├── Processor.php │ │ │ │ ├── SQLiteProcessor.php │ │ │ │ └── SqlServerProcessor.php │ │ │ ├── QueryException.php │ │ │ ├── README.md │ │ │ ├── RecordsNotFoundException.php │ │ │ ├── SQLiteConnection.php │ │ │ ├── Schema/ │ │ │ │ ├── Blueprint.php │ │ │ │ ├── Builder.php │ │ │ │ ├── ColumnDefinition.php │ │ │ │ ├── ForeignIdColumnDefinition.php │ │ │ │ ├── ForeignKeyDefinition.php │ │ │ │ ├── Grammars/ │ │ │ │ │ ├── ChangeColumn.php │ │ │ │ │ ├── Grammar.php │ │ │ │ │ ├── MySqlGrammar.php │ │ │ │ │ ├── PostgresGrammar.php │ │ │ │ │ ├── RenameColumn.php │ │ │ │ │ ├── SQLiteGrammar.php │ │ │ │ │ └── SqlServerGrammar.php │ │ │ │ ├── MySqlBuilder.php │ │ │ │ ├── MySqlSchemaState.php │ │ │ │ ├── PostgresBuilder.php │ │ │ │ ├── PostgresSchemaState.php │ │ │ │ ├── SQLiteBuilder.php │ │ │ │ ├── SchemaState.php │ │ │ │ ├── SqlServerBuilder.php │ │ │ │ └── SqliteSchemaState.php │ │ │ ├── Seeder.php │ │ │ ├── SqlServerConnection.php │ │ │ └── composer.json │ │ ├── events/ │ │ │ ├── CallQueuedListener.php │ │ │ ├── Dispatcher.php │ │ │ ├── EventServiceProvider.php │ │ │ ├── InvokeQueuedClosure.php │ │ │ ├── LICENSE.md │ │ │ ├── NullDispatcher.php │ │ │ ├── QueuedClosure.php │ │ │ ├── composer.json │ │ │ └── functions.php │ │ ├── macroable/ │ │ │ ├── LICENSE.md │ │ │ ├── Traits/ │ │ │ │ └── Macroable.php │ │ │ └── composer.json │ │ ├── pipeline/ │ │ │ ├── Hub.php │ │ │ ├── LICENSE.md │ │ │ ├── Pipeline.php │ │ │ ├── PipelineServiceProvider.php │ │ │ └── composer.json │ │ └── support/ │ │ ├── AggregateServiceProvider.php │ │ ├── Carbon.php │ │ ├── Composer.php │ │ ├── ConfigurationUrlParser.php │ │ ├── DateFactory.php │ │ ├── Env.php │ │ ├── Facades/ │ │ │ ├── App.php │ │ │ ├── Artisan.php │ │ │ ├── Auth.php │ │ │ ├── Blade.php │ │ │ ├── Broadcast.php │ │ │ ├── Bus.php │ │ │ ├── Cache.php │ │ │ ├── Config.php │ │ │ ├── Cookie.php │ │ │ ├── Crypt.php │ │ │ ├── DB.php │ │ │ ├── Date.php │ │ │ ├── Event.php │ │ │ ├── Facade.php │ │ │ ├── File.php │ │ │ ├── Gate.php │ │ │ ├── Hash.php │ │ │ ├── Http.php │ │ │ ├── Lang.php │ │ │ ├── Log.php │ │ │ ├── Mail.php │ │ │ ├── Notification.php │ │ │ ├── ParallelTesting.php │ │ │ ├── Password.php │ │ │ ├── Queue.php │ │ │ ├── RateLimiter.php │ │ │ ├── Redirect.php │ │ │ ├── Redis.php │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ ├── Route.php │ │ │ ├── Schema.php │ │ │ ├── Session.php │ │ │ ├── Storage.php │ │ │ ├── URL.php │ │ │ ├── Validator.php │ │ │ └── View.php │ │ ├── Fluent.php │ │ ├── HigherOrderTapProxy.php │ │ ├── HtmlString.php │ │ ├── InteractsWithTime.php │ │ ├── Js.php │ │ ├── LICENSE.md │ │ ├── Manager.php │ │ ├── MessageBag.php │ │ ├── MultipleInstanceManager.php │ │ ├── NamespacedItemResolver.php │ │ ├── Optional.php │ │ ├── Pluralizer.php │ │ ├── ProcessUtils.php │ │ ├── Reflector.php │ │ ├── ServiceProvider.php │ │ ├── Str.php │ │ ├── Stringable.php │ │ ├── Testing/ │ │ │ └── Fakes/ │ │ │ ├── BatchRepositoryFake.php │ │ │ ├── BusFake.php │ │ │ ├── EventFake.php │ │ │ ├── MailFake.php │ │ │ ├── NotificationFake.php │ │ │ ├── PendingBatchFake.php │ │ │ ├── PendingChainFake.php │ │ │ ├── PendingMailFake.php │ │ │ └── QueueFake.php │ │ ├── Timebox.php │ │ ├── Traits/ │ │ │ ├── CapsuleManagerTrait.php │ │ │ ├── Conditionable.php │ │ │ ├── ForwardsCalls.php │ │ │ ├── Localizable.php │ │ │ ├── ReflectsClosures.php │ │ │ └── Tappable.php │ │ ├── ValidatedInput.php │ │ ├── ViewErrorBag.php │ │ ├── composer.json │ │ └── helpers.php │ ├── jasig/ │ │ └── phpcas/ │ │ ├── CAS.php │ │ ├── LICENSE │ │ ├── NOTICE │ │ ├── README.md │ │ ├── composer.json │ │ └── source/ │ │ ├── CAS/ │ │ │ ├── AuthenticationException.php │ │ │ ├── Autoload.php │ │ │ ├── Client.php │ │ │ ├── CookieJar.php │ │ │ ├── Exception.php │ │ │ ├── GracefullTerminationException.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── Languages/ │ │ │ │ ├── Catalan.php │ │ │ │ ├── ChineseSimplified.php │ │ │ │ ├── English.php │ │ │ │ ├── French.php │ │ │ │ ├── Galego.php │ │ │ │ ├── German.php │ │ │ │ ├── Greek.php │ │ │ │ ├── Japanese.php │ │ │ │ ├── LanguageInterface.php │ │ │ │ ├── Portuguese.php │ │ │ │ └── Spanish.php │ │ │ ├── OutOfSequenceBeforeAuthenticationCallException.php │ │ │ ├── OutOfSequenceBeforeClientException.php │ │ │ ├── OutOfSequenceBeforeProxyException.php │ │ │ ├── OutOfSequenceException.php │ │ │ ├── PGTStorage/ │ │ │ │ ├── AbstractStorage.php │ │ │ │ ├── Db.php │ │ │ │ └── File.php │ │ │ ├── ProxiedService/ │ │ │ │ ├── Abstract.php │ │ │ │ ├── Exception.php │ │ │ │ ├── Http/ │ │ │ │ │ ├── Abstract.php │ │ │ │ │ ├── Get.php │ │ │ │ │ └── Post.php │ │ │ │ ├── Http.php │ │ │ │ ├── Imap.php │ │ │ │ └── Testable.php │ │ │ ├── ProxiedService.php │ │ │ ├── ProxyChain/ │ │ │ │ ├── AllowedList.php │ │ │ │ ├── Any.php │ │ │ │ ├── Interface.php │ │ │ │ └── Trusted.php │ │ │ ├── ProxyChain.php │ │ │ ├── ProxyTicketException.php │ │ │ ├── Request/ │ │ │ │ ├── AbstractRequest.php │ │ │ │ ├── CurlMultiRequest.php │ │ │ │ ├── CurlRequest.php │ │ │ │ ├── Exception.php │ │ │ │ ├── MultiRequestInterface.php │ │ │ │ └── RequestInterface.php │ │ │ ├── ServiceBaseUrl/ │ │ │ │ ├── AllowedListDiscovery.php │ │ │ │ ├── Base.php │ │ │ │ ├── Interface.php │ │ │ │ └── Static.php │ │ │ ├── Session/ │ │ │ │ └── PhpSession.php │ │ │ └── TypeMismatchException.php │ │ └── CAS.php │ ├── laravel/ │ │ └── serializable-closure/ │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ ├── Contracts/ │ │ │ ├── Serializable.php │ │ │ └── Signer.php │ │ ├── Exceptions/ │ │ │ ├── InvalidSignatureException.php │ │ │ ├── MissingSecretKeyException.php │ │ │ └── PhpVersionNotSupportedException.php │ │ ├── SerializableClosure.php │ │ ├── Serializers/ │ │ │ ├── Native.php │ │ │ └── Signed.php │ │ ├── Signers/ │ │ │ └── Hmac.php │ │ ├── Support/ │ │ │ ├── ClosureScope.php │ │ │ ├── ClosureStream.php │ │ │ ├── ReflectionClosure.php │ │ │ └── SelfReference.php │ │ └── UnsignedSerializableClosure.php │ ├── league/ │ │ └── oauth2-client/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ ├── phpunit.xml.dist │ │ └── src/ │ │ ├── Grant/ │ │ │ ├── AbstractGrant.php │ │ │ ├── AuthorizationCode.php │ │ │ ├── ClientCredentials.php │ │ │ ├── Exception/ │ │ │ │ └── InvalidGrantException.php │ │ │ ├── GrantFactory.php │ │ │ ├── Password.php │ │ │ └── RefreshToken.php │ │ ├── OptionProvider/ │ │ │ ├── HttpBasicAuthOptionProvider.php │ │ │ ├── OptionProviderInterface.php │ │ │ └── PostAuthOptionProvider.php │ │ ├── Provider/ │ │ │ ├── AbstractProvider.php │ │ │ ├── Exception/ │ │ │ │ └── IdentityProviderException.php │ │ │ ├── GenericProvider.php │ │ │ ├── GenericResourceOwner.php │ │ │ └── ResourceOwnerInterface.php │ │ ├── Token/ │ │ │ ├── AccessToken.php │ │ │ ├── AccessTokenInterface.php │ │ │ ├── ResourceOwnerAccessTokenInterface.php │ │ │ └── SettableRefreshTokenInterface.php │ │ └── Tool/ │ │ ├── ArrayAccessorTrait.php │ │ ├── BearerAuthorizationTrait.php │ │ ├── GuardedPropertyTrait.php │ │ ├── MacAuthorizationTrait.php │ │ ├── ProviderRedirectTrait.php │ │ ├── QueryBuilderTrait.php │ │ ├── RequestFactory.php │ │ └── RequiredParameterTrait.php │ ├── nesbot/ │ │ └── carbon/ │ │ ├── .phpstorm.meta.php │ │ ├── LICENSE │ │ ├── bin/ │ │ │ ├── carbon │ │ │ └── carbon.bat │ │ ├── composer.json │ │ ├── extension.neon │ │ ├── lazy/ │ │ │ └── Carbon/ │ │ │ ├── MessageFormatter/ │ │ │ │ ├── MessageFormatterMapperStrongType.php │ │ │ │ └── MessageFormatterMapperWeakType.php │ │ │ ├── PHPStan/ │ │ │ │ ├── AbstractMacroBuiltin.php │ │ │ │ ├── AbstractMacroStatic.php │ │ │ │ ├── MacroStrongType.php │ │ │ │ └── MacroWeakType.php │ │ │ ├── TranslatorStrongType.php │ │ │ └── TranslatorWeakType.php │ │ ├── readme.md │ │ ├── sponsors.php │ │ └── src/ │ │ └── Carbon/ │ │ ├── AbstractTranslator.php │ │ ├── Carbon.php │ │ ├── CarbonConverterInterface.php │ │ ├── CarbonImmutable.php │ │ ├── CarbonInterface.php │ │ ├── CarbonInterval.php │ │ ├── CarbonPeriod.php │ │ ├── CarbonPeriodImmutable.php │ │ ├── CarbonTimeZone.php │ │ ├── Cli/ │ │ │ └── Invoker.php │ │ ├── Exceptions/ │ │ │ ├── BadComparisonUnitException.php │ │ │ ├── BadFluentConstructorException.php │ │ │ ├── BadFluentSetterException.php │ │ │ ├── BadMethodCallException.php │ │ │ ├── EndLessPeriodException.php │ │ │ ├── Exception.php │ │ │ ├── ImmutableException.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── InvalidCastException.php │ │ │ ├── InvalidDateException.php │ │ │ ├── InvalidFormatException.php │ │ │ ├── InvalidIntervalException.php │ │ │ ├── InvalidPeriodDateException.php │ │ │ ├── InvalidPeriodParameterException.php │ │ │ ├── InvalidTimeZoneException.php │ │ │ ├── InvalidTypeException.php │ │ │ ├── NotACarbonClassException.php │ │ │ ├── NotAPeriodException.php │ │ │ ├── NotLocaleAwareException.php │ │ │ ├── OutOfRangeException.php │ │ │ ├── ParseErrorException.php │ │ │ ├── RuntimeException.php │ │ │ ├── UnitException.php │ │ │ ├── UnitNotConfiguredException.php │ │ │ ├── UnknownGetterException.php │ │ │ ├── UnknownMethodException.php │ │ │ ├── UnknownSetterException.php │ │ │ ├── UnknownUnitException.php │ │ │ └── UnreachableException.php │ │ ├── Factory.php │ │ ├── FactoryImmutable.php │ │ ├── Lang/ │ │ │ ├── aa.php │ │ │ ├── aa_DJ.php │ │ │ ├── aa_ER.php │ │ │ ├── aa_ER@saaho.php │ │ │ ├── aa_ET.php │ │ │ ├── af.php │ │ │ ├── af_NA.php │ │ │ ├── af_ZA.php │ │ │ ├── agq.php │ │ │ ├── agr.php │ │ │ ├── agr_PE.php │ │ │ ├── ak.php │ │ │ ├── ak_GH.php │ │ │ ├── am.php │ │ │ ├── am_ET.php │ │ │ ├── an.php │ │ │ ├── an_ES.php │ │ │ ├── anp.php │ │ │ ├── anp_IN.php │ │ │ ├── ar.php │ │ │ ├── ar_AE.php │ │ │ ├── ar_BH.php │ │ │ ├── ar_DJ.php │ │ │ ├── ar_DZ.php │ │ │ ├── ar_EG.php │ │ │ ├── ar_EH.php │ │ │ ├── ar_ER.php │ │ │ ├── ar_IL.php │ │ │ ├── ar_IN.php │ │ │ ├── ar_IQ.php │ │ │ ├── ar_JO.php │ │ │ ├── ar_KM.php │ │ │ ├── ar_KW.php │ │ │ ├── ar_LB.php │ │ │ ├── ar_LY.php │ │ │ ├── ar_MA.php │ │ │ ├── ar_MR.php │ │ │ ├── ar_OM.php │ │ │ ├── ar_PS.php │ │ │ ├── ar_QA.php │ │ │ ├── ar_SA.php │ │ │ ├── ar_SD.php │ │ │ ├── ar_SO.php │ │ │ ├── ar_SS.php │ │ │ ├── ar_SY.php │ │ │ ├── ar_Shakl.php │ │ │ ├── ar_TD.php │ │ │ ├── ar_TN.php │ │ │ ├── ar_YE.php │ │ │ ├── as.php │ │ │ ├── as_IN.php │ │ │ ├── asa.php │ │ │ ├── ast.php │ │ │ ├── ast_ES.php │ │ │ ├── ayc.php │ │ │ ├── ayc_PE.php │ │ │ ├── az.php │ │ │ ├── az_AZ.php │ │ │ ├── az_Cyrl.php │ │ │ ├── az_IR.php │ │ │ ├── az_Latn.php │ │ │ ├── bas.php │ │ │ ├── be.php │ │ │ ├── be_BY.php │ │ │ ├── be_BY@latin.php │ │ │ ├── bem.php │ │ │ ├── bem_ZM.php │ │ │ ├── ber.php │ │ │ ├── ber_DZ.php │ │ │ ├── ber_MA.php │ │ │ ├── bez.php │ │ │ ├── bg.php │ │ │ ├── bg_BG.php │ │ │ ├── bhb.php │ │ │ ├── bhb_IN.php │ │ │ ├── bho.php │ │ │ ├── bho_IN.php │ │ │ ├── bi.php │ │ │ ├── bi_VU.php │ │ │ ├── bm.php │ │ │ ├── bn.php │ │ │ ├── bn_BD.php │ │ │ ├── bn_IN.php │ │ │ ├── bo.php │ │ │ ├── bo_CN.php │ │ │ ├── bo_IN.php │ │ │ ├── br.php │ │ │ ├── br_FR.php │ │ │ ├── brx.php │ │ │ ├── brx_IN.php │ │ │ ├── bs.php │ │ │ ├── bs_BA.php │ │ │ ├── bs_Cyrl.php │ │ │ ├── bs_Latn.php │ │ │ ├── byn.php │ │ │ ├── byn_ER.php │ │ │ ├── ca.php │ │ │ ├── ca_AD.php │ │ │ ├── ca_ES.php │ │ │ ├── ca_ES_Valencia.php │ │ │ ├── ca_FR.php │ │ │ ├── ca_IT.php │ │ │ ├── ccp.php │ │ │ ├── ccp_IN.php │ │ │ ├── ce.php │ │ │ ├── ce_RU.php │ │ │ ├── cgg.php │ │ │ ├── chr.php │ │ │ ├── chr_US.php │ │ │ ├── ckb.php │ │ │ ├── cmn.php │ │ │ ├── cmn_TW.php │ │ │ ├── crh.php │ │ │ ├── crh_UA.php │ │ │ ├── cs.php │ │ │ ├── cs_CZ.php │ │ │ ├── csb.php │ │ │ ├── csb_PL.php │ │ │ ├── cu.php │ │ │ ├── cv.php │ │ │ ├── cv_RU.php │ │ │ ├── cy.php │ │ │ ├── cy_GB.php │ │ │ ├── da.php │ │ │ ├── da_DK.php │ │ │ ├── da_GL.php │ │ │ ├── dav.php │ │ │ ├── de.php │ │ │ ├── de_AT.php │ │ │ ├── de_BE.php │ │ │ ├── de_CH.php │ │ │ ├── de_DE.php │ │ │ ├── de_IT.php │ │ │ ├── de_LI.php │ │ │ ├── de_LU.php │ │ │ ├── dje.php │ │ │ ├── doi.php │ │ │ ├── doi_IN.php │ │ │ ├── dsb.php │ │ │ ├── dsb_DE.php │ │ │ ├── dua.php │ │ │ ├── dv.php │ │ │ ├── dv_MV.php │ │ │ ├── dyo.php │ │ │ ├── dz.php │ │ │ ├── dz_BT.php │ │ │ ├── ebu.php │ │ │ ├── ee.php │ │ │ ├── ee_TG.php │ │ │ ├── el.php │ │ │ ├── el_CY.php │ │ │ ├── el_GR.php │ │ │ ├── en.php │ │ │ ├── en_001.php │ │ │ ├── en_150.php │ │ │ ├── en_AG.php │ │ │ ├── en_AI.php │ │ │ ├── en_AS.php │ │ │ ├── en_AT.php │ │ │ ├── en_AU.php │ │ │ ├── en_BB.php │ │ │ ├── en_BE.php │ │ │ ├── en_BI.php │ │ │ ├── en_BM.php │ │ │ ├── en_BS.php │ │ │ ├── en_BW.php │ │ │ ├── en_BZ.php │ │ │ ├── en_CA.php │ │ │ ├── en_CC.php │ │ │ ├── en_CH.php │ │ │ ├── en_CK.php │ │ │ ├── en_CM.php │ │ │ ├── en_CX.php │ │ │ ├── en_CY.php │ │ │ ├── en_DE.php │ │ │ ├── en_DG.php │ │ │ ├── en_DK.php │ │ │ ├── en_DM.php │ │ │ ├── en_ER.php │ │ │ ├── en_FI.php │ │ │ ├── en_FJ.php │ │ │ ├── en_FK.php │ │ │ ├── en_FM.php │ │ │ ├── en_GB.php │ │ │ ├── en_GD.php │ │ │ ├── en_GG.php │ │ │ ├── en_GH.php │ │ │ ├── en_GI.php │ │ │ ├── en_GM.php │ │ │ ├── en_GU.php │ │ │ ├── en_GY.php │ │ │ ├── en_HK.php │ │ │ ├── en_IE.php │ │ │ ├── en_IL.php │ │ │ ├── en_IM.php │ │ │ ├── en_IN.php │ │ │ ├── en_IO.php │ │ │ ├── en_ISO.php │ │ │ ├── en_JE.php │ │ │ ├── en_JM.php │ │ │ ├── en_KE.php │ │ │ ├── en_KI.php │ │ │ ├── en_KN.php │ │ │ ├── en_KY.php │ │ │ ├── en_LC.php │ │ │ ├── en_LR.php │ │ │ ├── en_LS.php │ │ │ ├── en_MG.php │ │ │ ├── en_MH.php │ │ │ ├── en_MO.php │ │ │ ├── en_MP.php │ │ │ ├── en_MS.php │ │ │ ├── en_MT.php │ │ │ ├── en_MU.php │ │ │ ├── en_MW.php │ │ │ ├── en_MY.php │ │ │ ├── en_NA.php │ │ │ ├── en_NF.php │ │ │ ├── en_NG.php │ │ │ ├── en_NL.php │ │ │ ├── en_NR.php │ │ │ ├── en_NU.php │ │ │ ├── en_NZ.php │ │ │ ├── en_PG.php │ │ │ ├── en_PH.php │ │ │ ├── en_PK.php │ │ │ ├── en_PN.php │ │ │ ├── en_PR.php │ │ │ ├── en_PW.php │ │ │ ├── en_RW.php │ │ │ ├── en_SB.php │ │ │ ├── en_SC.php │ │ │ ├── en_SD.php │ │ │ ├── en_SE.php │ │ │ ├── en_SG.php │ │ │ ├── en_SH.php │ │ │ ├── en_SI.php │ │ │ ├── en_SL.php │ │ │ ├── en_SS.php │ │ │ ├── en_SX.php │ │ │ ├── en_SZ.php │ │ │ ├── en_TC.php │ │ │ ├── en_TK.php │ │ │ ├── en_TO.php │ │ │ ├── en_TT.php │ │ │ ├── en_TV.php │ │ │ ├── en_TZ.php │ │ │ ├── en_UG.php │ │ │ ├── en_UM.php │ │ │ ├── en_US.php │ │ │ ├── en_US_Posix.php │ │ │ ├── en_VC.php │ │ │ ├── en_VG.php │ │ │ ├── en_VI.php │ │ │ ├── en_VU.php │ │ │ ├── en_WS.php │ │ │ ├── en_ZA.php │ │ │ ├── en_ZM.php │ │ │ ├── en_ZW.php │ │ │ ├── eo.php │ │ │ ├── es.php │ │ │ ├── es_419.php │ │ │ ├── es_AR.php │ │ │ ├── es_BO.php │ │ │ ├── es_BR.php │ │ │ ├── es_BZ.php │ │ │ ├── es_CL.php │ │ │ ├── es_CO.php │ │ │ ├── es_CR.php │ │ │ ├── es_CU.php │ │ │ ├── es_DO.php │ │ │ ├── es_EA.php │ │ │ ├── es_EC.php │ │ │ ├── es_ES.php │ │ │ ├── es_GQ.php │ │ │ ├── es_GT.php │ │ │ ├── es_HN.php │ │ │ ├── es_IC.php │ │ │ ├── es_MX.php │ │ │ ├── es_NI.php │ │ │ ├── es_PA.php │ │ │ ├── es_PE.php │ │ │ ├── es_PH.php │ │ │ ├── es_PR.php │ │ │ ├── es_PY.php │ │ │ ├── es_SV.php │ │ │ ├── es_US.php │ │ │ ├── es_UY.php │ │ │ ├── es_VE.php │ │ │ ├── et.php │ │ │ ├── et_EE.php │ │ │ ├── eu.php │ │ │ ├── eu_ES.php │ │ │ ├── ewo.php │ │ │ ├── fa.php │ │ │ ├── fa_AF.php │ │ │ ├── fa_IR.php │ │ │ ├── ff.php │ │ │ ├── ff_CM.php │ │ │ ├── ff_GN.php │ │ │ ├── ff_MR.php │ │ │ ├── ff_SN.php │ │ │ ├── fi.php │ │ │ ├── fi_FI.php │ │ │ ├── fil.php │ │ │ ├── fil_PH.php │ │ │ ├── fo.php │ │ │ ├── fo_DK.php │ │ │ ├── fo_FO.php │ │ │ ├── fr.php │ │ │ ├── fr_BE.php │ │ │ ├── fr_BF.php │ │ │ ├── fr_BI.php │ │ │ ├── fr_BJ.php │ │ │ ├── fr_BL.php │ │ │ ├── fr_CA.php │ │ │ ├── fr_CD.php │ │ │ ├── fr_CF.php │ │ │ ├── fr_CG.php │ │ │ ├── fr_CH.php │ │ │ ├── fr_CI.php │ │ │ ├── fr_CM.php │ │ │ ├── fr_DJ.php │ │ │ ├── fr_DZ.php │ │ │ ├── fr_FR.php │ │ │ ├── fr_GA.php │ │ │ ├── fr_GF.php │ │ │ ├── fr_GN.php │ │ │ ├── fr_GP.php │ │ │ ├── fr_GQ.php │ │ │ ├── fr_HT.php │ │ │ ├── fr_KM.php │ │ │ ├── fr_LU.php │ │ │ ├── fr_MA.php │ │ │ ├── fr_MC.php │ │ │ ├── fr_MF.php │ │ │ ├── fr_MG.php │ │ │ ├── fr_ML.php │ │ │ ├── fr_MQ.php │ │ │ ├── fr_MR.php │ │ │ ├── fr_MU.php │ │ │ ├── fr_NC.php │ │ │ ├── fr_NE.php │ │ │ ├── fr_PF.php │ │ │ ├── fr_PM.php │ │ │ ├── fr_RE.php │ │ │ ├── fr_RW.php │ │ │ ├── fr_SC.php │ │ │ ├── fr_SN.php │ │ │ ├── fr_SY.php │ │ │ ├── fr_TD.php │ │ │ ├── fr_TG.php │ │ │ ├── fr_TN.php │ │ │ ├── fr_VU.php │ │ │ ├── fr_WF.php │ │ │ ├── fr_YT.php │ │ │ ├── fur.php │ │ │ ├── fur_IT.php │ │ │ ├── fy.php │ │ │ ├── fy_DE.php │ │ │ ├── fy_NL.php │ │ │ ├── ga.php │ │ │ ├── ga_IE.php │ │ │ ├── gd.php │ │ │ ├── gd_GB.php │ │ │ ├── gez.php │ │ │ ├── gez_ER.php │ │ │ ├── gez_ET.php │ │ │ ├── gl.php │ │ │ ├── gl_ES.php │ │ │ ├── gom.php │ │ │ ├── gom_Latn.php │ │ │ ├── gsw.php │ │ │ ├── gsw_CH.php │ │ │ ├── gsw_FR.php │ │ │ ├── gsw_LI.php │ │ │ ├── gu.php │ │ │ ├── gu_IN.php │ │ │ ├── guz.php │ │ │ ├── gv.php │ │ │ ├── gv_GB.php │ │ │ ├── ha.php │ │ │ ├── ha_GH.php │ │ │ ├── ha_NE.php │ │ │ ├── ha_NG.php │ │ │ ├── hak.php │ │ │ ├── hak_TW.php │ │ │ ├── haw.php │ │ │ ├── he.php │ │ │ ├── he_IL.php │ │ │ ├── hi.php │ │ │ ├── hi_IN.php │ │ │ ├── hif.php │ │ │ ├── hif_FJ.php │ │ │ ├── hne.php │ │ │ ├── hne_IN.php │ │ │ ├── hr.php │ │ │ ├── hr_BA.php │ │ │ ├── hr_HR.php │ │ │ ├── hsb.php │ │ │ ├── hsb_DE.php │ │ │ ├── ht.php │ │ │ ├── ht_HT.php │ │ │ ├── hu.php │ │ │ ├── hu_HU.php │ │ │ ├── hy.php │ │ │ ├── hy_AM.php │ │ │ ├── i18n.php │ │ │ ├── ia.php │ │ │ ├── ia_FR.php │ │ │ ├── id.php │ │ │ ├── id_ID.php │ │ │ ├── ig.php │ │ │ ├── ig_NG.php │ │ │ ├── ii.php │ │ │ ├── ik.php │ │ │ ├── ik_CA.php │ │ │ ├── in.php │ │ │ ├── is.php │ │ │ ├── is_IS.php │ │ │ ├── it.php │ │ │ ├── it_CH.php │ │ │ ├── it_IT.php │ │ │ ├── it_SM.php │ │ │ ├── it_VA.php │ │ │ ├── iu.php │ │ │ ├── iu_CA.php │ │ │ ├── iw.php │ │ │ ├── ja.php │ │ │ ├── ja_JP.php │ │ │ ├── jgo.php │ │ │ ├── jmc.php │ │ │ ├── jv.php │ │ │ ├── ka.php │ │ │ ├── ka_GE.php │ │ │ ├── kab.php │ │ │ ├── kab_DZ.php │ │ │ ├── kam.php │ │ │ ├── kde.php │ │ │ ├── kea.php │ │ │ ├── khq.php │ │ │ ├── ki.php │ │ │ ├── kk.php │ │ │ ├── kk_KZ.php │ │ │ ├── kkj.php │ │ │ ├── kl.php │ │ │ ├── kl_GL.php │ │ │ ├── kln.php │ │ │ ├── km.php │ │ │ ├── km_KH.php │ │ │ ├── kn.php │ │ │ ├── kn_IN.php │ │ │ ├── ko.php │ │ │ ├── ko_KP.php │ │ │ ├── ko_KR.php │ │ │ ├── kok.php │ │ │ ├── kok_IN.php │ │ │ ├── ks.php │ │ │ ├── ks_IN.php │ │ │ ├── ks_IN@devanagari.php │ │ │ ├── ksb.php │ │ │ ├── ksf.php │ │ │ ├── ksh.php │ │ │ ├── ku.php │ │ │ ├── ku_TR.php │ │ │ ├── kw.php │ │ │ ├── kw_GB.php │ │ │ ├── ky.php │ │ │ ├── ky_KG.php │ │ │ ├── lag.php │ │ │ ├── lb.php │ │ │ ├── lb_LU.php │ │ │ ├── lg.php │ │ │ ├── lg_UG.php │ │ │ ├── li.php │ │ │ ├── li_NL.php │ │ │ ├── lij.php │ │ │ ├── lij_IT.php │ │ │ ├── lkt.php │ │ │ ├── ln.php │ │ │ ├── ln_AO.php │ │ │ ├── ln_CD.php │ │ │ ├── ln_CF.php │ │ │ ├── ln_CG.php │ │ │ ├── lo.php │ │ │ ├── lo_LA.php │ │ │ ├── lrc.php │ │ │ ├── lrc_IQ.php │ │ │ ├── lt.php │ │ │ ├── lt_LT.php │ │ │ ├── lu.php │ │ │ ├── luo.php │ │ │ ├── luy.php │ │ │ ├── lv.php │ │ │ ├── lv_LV.php │ │ │ ├── lzh.php │ │ │ ├── lzh_TW.php │ │ │ ├── mag.php │ │ │ ├── mag_IN.php │ │ │ ├── mai.php │ │ │ ├── mai_IN.php │ │ │ ├── mas.php │ │ │ ├── mas_TZ.php │ │ │ ├── mer.php │ │ │ ├── mfe.php │ │ │ ├── mfe_MU.php │ │ │ ├── mg.php │ │ │ ├── mg_MG.php │ │ │ ├── mgh.php │ │ │ ├── mgo.php │ │ │ ├── mhr.php │ │ │ ├── mhr_RU.php │ │ │ ├── mi.php │ │ │ ├── mi_NZ.php │ │ │ ├── miq.php │ │ │ ├── miq_NI.php │ │ │ ├── mjw.php │ │ │ ├── mjw_IN.php │ │ │ ├── mk.php │ │ │ ├── mk_MK.php │ │ │ ├── ml.php │ │ │ ├── ml_IN.php │ │ │ ├── mn.php │ │ │ ├── mn_MN.php │ │ │ ├── mni.php │ │ │ ├── mni_IN.php │ │ │ ├── mo.php │ │ │ ├── mr.php │ │ │ ├── mr_IN.php │ │ │ ├── ms.php │ │ │ ├── ms_BN.php │ │ │ ├── ms_MY.php │ │ │ ├── ms_SG.php │ │ │ ├── mt.php │ │ │ ├── mt_MT.php │ │ │ ├── mua.php │ │ │ ├── my.php │ │ │ ├── my_MM.php │ │ │ ├── mzn.php │ │ │ ├── nan.php │ │ │ ├── nan_TW.php │ │ │ ├── nan_TW@latin.php │ │ │ ├── naq.php │ │ │ ├── nb.php │ │ │ ├── nb_NO.php │ │ │ ├── nb_SJ.php │ │ │ ├── nd.php │ │ │ ├── nds.php │ │ │ ├── nds_DE.php │ │ │ ├── nds_NL.php │ │ │ ├── ne.php │ │ │ ├── ne_IN.php │ │ │ ├── ne_NP.php │ │ │ ├── nhn.php │ │ │ ├── nhn_MX.php │ │ │ ├── niu.php │ │ │ ├── niu_NU.php │ │ │ ├── nl.php │ │ │ ├── nl_AW.php │ │ │ ├── nl_BE.php │ │ │ ├── nl_BQ.php │ │ │ ├── nl_CW.php │ │ │ ├── nl_NL.php │ │ │ ├── nl_SR.php │ │ │ ├── nl_SX.php │ │ │ ├── nmg.php │ │ │ ├── nn.php │ │ │ ├── nn_NO.php │ │ │ ├── nnh.php │ │ │ ├── no.php │ │ │ ├── nr.php │ │ │ ├── nr_ZA.php │ │ │ ├── nso.php │ │ │ ├── nso_ZA.php │ │ │ ├── nus.php │ │ │ ├── nyn.php │ │ │ ├── oc.php │ │ │ ├── oc_FR.php │ │ │ ├── om.php │ │ │ ├── om_ET.php │ │ │ ├── om_KE.php │ │ │ ├── or.php │ │ │ ├── or_IN.php │ │ │ ├── os.php │ │ │ ├── os_RU.php │ │ │ ├── pa.php │ │ │ ├── pa_Arab.php │ │ │ ├── pa_Guru.php │ │ │ ├── pa_IN.php │ │ │ ├── pa_PK.php │ │ │ ├── pap.php │ │ │ ├── pap_AW.php │ │ │ ├── pap_CW.php │ │ │ ├── pl.php │ │ │ ├── pl_PL.php │ │ │ ├── prg.php │ │ │ ├── ps.php │ │ │ ├── ps_AF.php │ │ │ ├── pt.php │ │ │ ├── pt_AO.php │ │ │ ├── pt_BR.php │ │ │ ├── pt_CH.php │ │ │ ├── pt_CV.php │ │ │ ├── pt_GQ.php │ │ │ ├── pt_GW.php │ │ │ ├── pt_LU.php │ │ │ ├── pt_MO.php │ │ │ ├── pt_MZ.php │ │ │ ├── pt_PT.php │ │ │ ├── pt_ST.php │ │ │ ├── pt_TL.php │ │ │ ├── qu.php │ │ │ ├── qu_BO.php │ │ │ ├── qu_EC.php │ │ │ ├── quz.php │ │ │ ├── quz_PE.php │ │ │ ├── raj.php │ │ │ ├── raj_IN.php │ │ │ ├── rm.php │ │ │ ├── rn.php │ │ │ ├── ro.php │ │ │ ├── ro_MD.php │ │ │ ├── ro_RO.php │ │ │ ├── rof.php │ │ │ ├── ru.php │ │ │ ├── ru_BY.php │ │ │ ├── ru_KG.php │ │ │ ├── ru_KZ.php │ │ │ ├── ru_MD.php │ │ │ ├── ru_RU.php │ │ │ ├── ru_UA.php │ │ │ ├── rw.php │ │ │ ├── rw_RW.php │ │ │ ├── rwk.php │ │ │ ├── sa.php │ │ │ ├── sa_IN.php │ │ │ ├── sah.php │ │ │ ├── sah_RU.php │ │ │ ├── saq.php │ │ │ ├── sat.php │ │ │ ├── sat_IN.php │ │ │ ├── sbp.php │ │ │ ├── sc.php │ │ │ ├── sc_IT.php │ │ │ ├── sd.php │ │ │ ├── sd_IN.php │ │ │ ├── sd_IN@devanagari.php │ │ │ ├── se.php │ │ │ ├── se_FI.php │ │ │ ├── se_NO.php │ │ │ ├── se_SE.php │ │ │ ├── seh.php │ │ │ ├── ses.php │ │ │ ├── sg.php │ │ │ ├── sgs.php │ │ │ ├── sgs_LT.php │ │ │ ├── sh.php │ │ │ ├── shi.php │ │ │ ├── shi_Latn.php │ │ │ ├── shi_Tfng.php │ │ │ ├── shn.php │ │ │ ├── shn_MM.php │ │ │ ├── shs.php │ │ │ ├── shs_CA.php │ │ │ ├── si.php │ │ │ ├── si_LK.php │ │ │ ├── sid.php │ │ │ ├── sid_ET.php │ │ │ ├── sk.php │ │ │ ├── sk_SK.php │ │ │ ├── sl.php │ │ │ ├── sl_SI.php │ │ │ ├── sm.php │ │ │ ├── sm_WS.php │ │ │ ├── smn.php │ │ │ ├── sn.php │ │ │ ├── so.php │ │ │ ├── so_DJ.php │ │ │ ├── so_ET.php │ │ │ ├── so_KE.php │ │ │ ├── so_SO.php │ │ │ ├── sq.php │ │ │ ├── sq_AL.php │ │ │ ├── sq_MK.php │ │ │ ├── sq_XK.php │ │ │ ├── sr.php │ │ │ ├── sr_Cyrl.php │ │ │ ├── sr_Cyrl_BA.php │ │ │ ├── sr_Cyrl_ME.php │ │ │ ├── sr_Cyrl_XK.php │ │ │ ├── sr_Latn.php │ │ │ ├── sr_Latn_BA.php │ │ │ ├── sr_Latn_ME.php │ │ │ ├── sr_Latn_XK.php │ │ │ ├── sr_ME.php │ │ │ ├── sr_RS.php │ │ │ ├── sr_RS@latin.php │ │ │ ├── ss.php │ │ │ ├── ss_ZA.php │ │ │ ├── st.php │ │ │ ├── st_ZA.php │ │ │ ├── sv.php │ │ │ ├── sv_AX.php │ │ │ ├── sv_FI.php │ │ │ ├── sv_SE.php │ │ │ ├── sw.php │ │ │ ├── sw_CD.php │ │ │ ├── sw_KE.php │ │ │ ├── sw_TZ.php │ │ │ ├── sw_UG.php │ │ │ ├── szl.php │ │ │ ├── szl_PL.php │ │ │ ├── ta.php │ │ │ ├── ta_IN.php │ │ │ ├── ta_LK.php │ │ │ ├── ta_MY.php │ │ │ ├── ta_SG.php │ │ │ ├── tcy.php │ │ │ ├── tcy_IN.php │ │ │ ├── te.php │ │ │ ├── te_IN.php │ │ │ ├── teo.php │ │ │ ├── teo_KE.php │ │ │ ├── tet.php │ │ │ ├── tg.php │ │ │ ├── tg_TJ.php │ │ │ ├── th.php │ │ │ ├── th_TH.php │ │ │ ├── the.php │ │ │ ├── the_NP.php │ │ │ ├── ti.php │ │ │ ├── ti_ER.php │ │ │ ├── ti_ET.php │ │ │ ├── tig.php │ │ │ ├── tig_ER.php │ │ │ ├── tk.php │ │ │ ├── tk_TM.php │ │ │ ├── tl.php │ │ │ ├── tl_PH.php │ │ │ ├── tlh.php │ │ │ ├── tn.php │ │ │ ├── tn_ZA.php │ │ │ ├── to.php │ │ │ ├── to_TO.php │ │ │ ├── tpi.php │ │ │ ├── tpi_PG.php │ │ │ ├── tr.php │ │ │ ├── tr_CY.php │ │ │ ├── tr_TR.php │ │ │ ├── ts.php │ │ │ ├── ts_ZA.php │ │ │ ├── tt.php │ │ │ ├── tt_RU.php │ │ │ ├── tt_RU@iqtelif.php │ │ │ ├── twq.php │ │ │ ├── tzl.php │ │ │ ├── tzm.php │ │ │ ├── tzm_Latn.php │ │ │ ├── ug.php │ │ │ ├── ug_CN.php │ │ │ ├── uk.php │ │ │ ├── uk_UA.php │ │ │ ├── unm.php │ │ │ ├── unm_US.php │ │ │ ├── ur.php │ │ │ ├── ur_IN.php │ │ │ ├── ur_PK.php │ │ │ ├── uz.php │ │ │ ├── uz_Arab.php │ │ │ ├── uz_Cyrl.php │ │ │ ├── uz_Latn.php │ │ │ ├── uz_UZ.php │ │ │ ├── uz_UZ@cyrillic.php │ │ │ ├── vai.php │ │ │ ├── vai_Latn.php │ │ │ ├── vai_Vaii.php │ │ │ ├── ve.php │ │ │ ├── ve_ZA.php │ │ │ ├── vi.php │ │ │ ├── vi_VN.php │ │ │ ├── vo.php │ │ │ ├── vun.php │ │ │ ├── wa.php │ │ │ ├── wa_BE.php │ │ │ ├── wae.php │ │ │ ├── wae_CH.php │ │ │ ├── wal.php │ │ │ ├── wal_ET.php │ │ │ ├── wo.php │ │ │ ├── wo_SN.php │ │ │ ├── xh.php │ │ │ ├── xh_ZA.php │ │ │ ├── xog.php │ │ │ ├── yav.php │ │ │ ├── yi.php │ │ │ ├── yi_US.php │ │ │ ├── yo.php │ │ │ ├── yo_BJ.php │ │ │ ├── yo_NG.php │ │ │ ├── yue.php │ │ │ ├── yue_HK.php │ │ │ ├── yue_Hans.php │ │ │ ├── yue_Hant.php │ │ │ ├── yuw.php │ │ │ ├── yuw_PG.php │ │ │ ├── zgh.php │ │ │ ├── zh.php │ │ │ ├── zh_CN.php │ │ │ ├── zh_HK.php │ │ │ ├── zh_Hans.php │ │ │ ├── zh_Hans_HK.php │ │ │ ├── zh_Hans_MO.php │ │ │ ├── zh_Hans_SG.php │ │ │ ├── zh_Hant.php │ │ │ ├── zh_Hant_HK.php │ │ │ ├── zh_Hant_MO.php │ │ │ ├── zh_Hant_TW.php │ │ │ ├── zh_MO.php │ │ │ ├── zh_SG.php │ │ │ ├── zh_TW.php │ │ │ ├── zh_YUE.php │ │ │ ├── zu.php │ │ │ └── zu_ZA.php │ │ ├── Language.php │ │ ├── Laravel/ │ │ │ └── ServiceProvider.php │ │ ├── List/ │ │ │ ├── languages.php │ │ │ └── regions.php │ │ ├── MessageFormatter/ │ │ │ └── MessageFormatterMapper.php │ │ ├── PHPStan/ │ │ │ ├── AbstractMacro.php │ │ │ ├── Macro.php │ │ │ ├── MacroExtension.php │ │ │ └── MacroScanner.php │ │ ├── Traits/ │ │ │ ├── Boundaries.php │ │ │ ├── Cast.php │ │ │ ├── Comparison.php │ │ │ ├── Converter.php │ │ │ ├── Creator.php │ │ │ ├── Date.php │ │ │ ├── DeprecatedProperties.php │ │ │ ├── Difference.php │ │ │ ├── IntervalRounding.php │ │ │ ├── IntervalStep.php │ │ │ ├── Localization.php │ │ │ ├── Macro.php │ │ │ ├── MagicParameter.php │ │ │ ├── Mixin.php │ │ │ ├── Modifiers.php │ │ │ ├── Mutability.php │ │ │ ├── ObjectInitialisation.php │ │ │ ├── Options.php │ │ │ ├── Rounding.php │ │ │ ├── Serialization.php │ │ │ ├── Test.php │ │ │ ├── Timestamp.php │ │ │ ├── ToStringFormat.php │ │ │ ├── Units.php │ │ │ └── Week.php │ │ ├── Translator.php │ │ ├── TranslatorImmutable.php │ │ └── TranslatorStrongTypeInterface.php │ ├── nikic/ │ │ └── fast-route/ │ │ ├── .gitignore │ │ ├── .hhconfig │ │ ├── .travis.yml │ │ ├── FastRoute.hhi │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ ├── phpunit.xml │ │ ├── psalm.xml │ │ ├── src/ │ │ │ ├── BadRouteException.php │ │ │ ├── DataGenerator/ │ │ │ │ ├── CharCountBased.php │ │ │ │ ├── GroupCountBased.php │ │ │ │ ├── GroupPosBased.php │ │ │ │ ├── MarkBased.php │ │ │ │ └── RegexBasedAbstract.php │ │ │ ├── DataGenerator.php │ │ │ ├── Dispatcher/ │ │ │ │ ├── CharCountBased.php │ │ │ │ ├── GroupCountBased.php │ │ │ │ ├── GroupPosBased.php │ │ │ │ ├── MarkBased.php │ │ │ │ └── RegexBasedAbstract.php │ │ │ ├── Dispatcher.php │ │ │ ├── Route.php │ │ │ ├── RouteCollector.php │ │ │ ├── RouteParser/ │ │ │ │ └── Std.php │ │ │ ├── RouteParser.php │ │ │ ├── bootstrap.php │ │ │ └── functions.php │ │ └── test/ │ │ ├── Dispatcher/ │ │ │ ├── CharCountBasedTest.php │ │ │ ├── DispatcherTest.php │ │ │ ├── GroupCountBasedTest.php │ │ │ ├── GroupPosBasedTest.php │ │ │ └── MarkBasedTest.php │ │ ├── HackTypechecker/ │ │ │ ├── HackTypecheckerTest.php │ │ │ └── fixtures/ │ │ │ ├── all_options.php │ │ │ ├── empty_options.php │ │ │ └── no_options.php │ │ ├── RouteCollectorTest.php │ │ ├── RouteParser/ │ │ │ └── StdTest.php │ │ └── bootstrap.php │ ├── php-di/ │ │ ├── invoker/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── CallableResolver.php │ │ │ ├── Exception/ │ │ │ │ ├── InvocationException.php │ │ │ │ ├── NotCallableException.php │ │ │ │ └── NotEnoughParametersException.php │ │ │ ├── Invoker.php │ │ │ ├── InvokerInterface.php │ │ │ ├── ParameterResolver/ │ │ │ │ ├── AssociativeArrayResolver.php │ │ │ │ ├── Container/ │ │ │ │ │ ├── ParameterNameContainerResolver.php │ │ │ │ │ └── TypeHintContainerResolver.php │ │ │ │ ├── DefaultValueResolver.php │ │ │ │ ├── NumericArrayResolver.php │ │ │ │ ├── ParameterResolver.php │ │ │ │ ├── ResolverChain.php │ │ │ │ └── TypeHintResolver.php │ │ │ └── Reflection/ │ │ │ └── CallableReflection.php │ │ ├── php-di/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── change-log.md │ │ │ ├── composer.json │ │ │ ├── src/ │ │ │ │ ├── Annotation/ │ │ │ │ │ ├── Inject.php │ │ │ │ │ └── Injectable.php │ │ │ │ ├── CompiledContainer.php │ │ │ │ ├── Compiler/ │ │ │ │ │ ├── Compiler.php │ │ │ │ │ ├── ObjectCreationCompiler.php │ │ │ │ │ ├── RequestedEntryHolder.php │ │ │ │ │ └── Template.php │ │ │ │ ├── Container.php │ │ │ │ ├── ContainerBuilder.php │ │ │ │ ├── Definition/ │ │ │ │ │ ├── ArrayDefinition.php │ │ │ │ │ ├── ArrayDefinitionExtension.php │ │ │ │ │ ├── AutowireDefinition.php │ │ │ │ │ ├── DecoratorDefinition.php │ │ │ │ │ ├── Definition.php │ │ │ │ │ ├── Dumper/ │ │ │ │ │ │ └── ObjectDefinitionDumper.php │ │ │ │ │ ├── EnvironmentVariableDefinition.php │ │ │ │ │ ├── Exception/ │ │ │ │ │ │ ├── InvalidAnnotation.php │ │ │ │ │ │ └── InvalidDefinition.php │ │ │ │ │ ├── ExtendsPreviousDefinition.php │ │ │ │ │ ├── FactoryDefinition.php │ │ │ │ │ ├── Helper/ │ │ │ │ │ │ ├── AutowireDefinitionHelper.php │ │ │ │ │ │ ├── CreateDefinitionHelper.php │ │ │ │ │ │ ├── DefinitionHelper.php │ │ │ │ │ │ └── FactoryDefinitionHelper.php │ │ │ │ │ ├── InstanceDefinition.php │ │ │ │ │ ├── ObjectDefinition/ │ │ │ │ │ │ ├── MethodInjection.php │ │ │ │ │ │ └── PropertyInjection.php │ │ │ │ │ ├── ObjectDefinition.php │ │ │ │ │ ├── Reference.php │ │ │ │ │ ├── Resolver/ │ │ │ │ │ │ ├── ArrayResolver.php │ │ │ │ │ │ ├── DecoratorResolver.php │ │ │ │ │ │ ├── DefinitionResolver.php │ │ │ │ │ │ ├── EnvironmentVariableResolver.php │ │ │ │ │ │ ├── FactoryResolver.php │ │ │ │ │ │ ├── InstanceInjector.php │ │ │ │ │ │ ├── ObjectCreator.php │ │ │ │ │ │ ├── ParameterResolver.php │ │ │ │ │ │ └── ResolverDispatcher.php │ │ │ │ │ ├── SelfResolvingDefinition.php │ │ │ │ │ ├── Source/ │ │ │ │ │ │ ├── AnnotationBasedAutowiring.php │ │ │ │ │ │ ├── Autowiring.php │ │ │ │ │ │ ├── DefinitionArray.php │ │ │ │ │ │ ├── DefinitionFile.php │ │ │ │ │ │ ├── DefinitionNormalizer.php │ │ │ │ │ │ ├── DefinitionSource.php │ │ │ │ │ │ ├── MutableDefinitionSource.php │ │ │ │ │ │ ├── NoAutowiring.php │ │ │ │ │ │ ├── ReflectionBasedAutowiring.php │ │ │ │ │ │ ├── SourceCache.php │ │ │ │ │ │ └── SourceChain.php │ │ │ │ │ ├── StringDefinition.php │ │ │ │ │ └── ValueDefinition.php │ │ │ │ ├── DependencyException.php │ │ │ │ ├── Factory/ │ │ │ │ │ └── RequestedEntry.php │ │ │ │ ├── FactoryInterface.php │ │ │ │ ├── Invoker/ │ │ │ │ │ ├── DefinitionParameterResolver.php │ │ │ │ │ └── FactoryParameterResolver.php │ │ │ │ ├── NotFoundException.php │ │ │ │ ├── Proxy/ │ │ │ │ │ └── ProxyFactory.php │ │ │ │ └── functions.php │ │ │ └── support.md │ │ └── phpdoc-reader/ │ │ ├── .gitattributes │ │ ├── .github/ │ │ │ └── workflows/ │ │ │ └── ci.yml │ │ ├── .gitignore │ │ ├── .phpcs.xml.dist │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ └── PhpDocReader/ │ │ ├── AnnotationException.php │ │ ├── PhpDocReader.php │ │ └── PhpParser/ │ │ ├── TokenParser.php │ │ └── UseStatementParser.php │ ├── phpoption/ │ │ └── phpoption/ │ │ ├── LICENSE │ │ ├── composer.json │ │ └── src/ │ │ └── PhpOption/ │ │ ├── LazyOption.php │ │ ├── None.php │ │ ├── Option.php │ │ └── Some.php │ ├── psr/ │ │ ├── cache/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE.txt │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── CacheException.php │ │ │ ├── CacheItemInterface.php │ │ │ ├── CacheItemPoolInterface.php │ │ │ └── InvalidArgumentException.php │ │ ├── clock/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ └── ClockInterface.php │ │ ├── container/ │ │ │ ├── .gitignore │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── ContainerExceptionInterface.php │ │ │ ├── ContainerInterface.php │ │ │ └── NotFoundExceptionInterface.php │ │ ├── http-factory/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── RequestFactoryInterface.php │ │ │ ├── ResponseFactoryInterface.php │ │ │ ├── ServerRequestFactoryInterface.php │ │ │ ├── StreamFactoryInterface.php │ │ │ ├── UploadedFileFactoryInterface.php │ │ │ └── UriFactoryInterface.php │ │ ├── http-message/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ ├── docs/ │ │ │ │ ├── PSR7-Interfaces.md │ │ │ │ └── PSR7-Usage.md │ │ │ └── src/ │ │ │ ├── MessageInterface.php │ │ │ ├── RequestInterface.php │ │ │ ├── ResponseInterface.php │ │ │ ├── ServerRequestInterface.php │ │ │ ├── StreamInterface.php │ │ │ ├── UploadedFileInterface.php │ │ │ └── UriInterface.php │ │ ├── http-server-handler/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ └── RequestHandlerInterface.php │ │ ├── http-server-middleware/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ └── MiddlewareInterface.php │ │ ├── log/ │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── AbstractLogger.php │ │ │ ├── InvalidArgumentException.php │ │ │ ├── LogLevel.php │ │ │ ├── LoggerAwareInterface.php │ │ │ ├── LoggerAwareTrait.php │ │ │ ├── LoggerInterface.php │ │ │ ├── LoggerTrait.php │ │ │ └── NullLogger.php │ │ └── simple-cache/ │ │ ├── .editorconfig │ │ ├── LICENSE.md │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ ├── CacheException.php │ │ ├── CacheInterface.php │ │ └── InvalidArgumentException.php │ ├── qcloud/ │ │ └── cos-sdk-v5/ │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ ├── phpunit.xml │ │ ├── sample/ │ │ │ ├── abortMultipartUpload.php │ │ │ ├── blindWatermark.php │ │ │ ├── catchException.php │ │ │ ├── ciTransformation.php │ │ │ ├── completeMultipartUpload.php │ │ │ ├── copy.php │ │ │ ├── copyObject.php │ │ │ ├── cosClient.php │ │ │ ├── createBucket.php │ │ │ ├── createFolder.php │ │ │ ├── createMultipartUpload.php │ │ │ ├── deleteBucket.php │ │ │ ├── deleteBucketCors.php │ │ │ ├── deleteBucketDomain.php │ │ │ ├── deleteBucketGuetzli.php │ │ │ ├── deleteBucketImageStyle.php │ │ │ ├── deleteBucketLifecycle.php │ │ │ ├── deleteBucketTagging.php │ │ │ ├── deleteBucketWebsite.php │ │ │ ├── deleteFolder.php │ │ │ ├── deleteObject.php │ │ │ ├── detectLable.php │ │ │ ├── download.php │ │ │ ├── downloadFolder.php │ │ │ ├── getBlindWatermark.php │ │ │ ├── getBucketAcl.php │ │ │ ├── getBucketCors.php │ │ │ ├── getBucketDomain.php │ │ │ ├── getBucketGuetzli.php │ │ │ ├── getBucketImageStyle.php │ │ │ ├── getBucketInventory.php │ │ │ ├── getBucketLifecycle.php │ │ │ ├── getBucketLogging.php │ │ │ ├── getBucketTagging.php │ │ │ ├── getBucketWebsite.php │ │ │ ├── getObject.php │ │ │ ├── getObjectUrl.php │ │ │ ├── getPresignedUrl.php │ │ │ ├── headBucket.php │ │ │ ├── headObject.php │ │ │ ├── imageAve.php │ │ │ ├── imageExif.php │ │ │ ├── imageInfo.php │ │ │ ├── imageMogr.php │ │ │ ├── imageProcess.php │ │ │ ├── imageView.php │ │ │ ├── imageWatermark.php │ │ │ ├── listBucket.php │ │ │ ├── listMultipartUploads.php │ │ │ ├── listObjects.php │ │ │ ├── listParts.php │ │ │ ├── picOperations.php │ │ │ ├── putBlindWatermark.php │ │ │ ├── putBucketAcl.php │ │ │ ├── putBucketCors.php │ │ │ ├── putBucketDomain.php │ │ │ ├── putBucketGuetzli.php │ │ │ ├── putBucketImageStyle.php │ │ │ ├── putBucketInventory.php │ │ │ ├── putBucketLifecycle.php │ │ │ ├── putBucketLogging.php │ │ │ ├── putBucketTagging.php │ │ │ ├── putBucketWebsite.php │ │ │ ├── putImageStyle.php │ │ │ ├── putObject.php │ │ │ ├── putQrcode.php │ │ │ ├── qrcode.php │ │ │ ├── qrcodeGenerate.php │ │ │ ├── restoreObject.php │ │ │ ├── selectObjectContent.php │ │ │ ├── textWatermark.php │ │ │ ├── upload.php │ │ │ ├── uploadFolder.php │ │ │ └── uploadPart.php │ │ └── src/ │ │ └── Qcloud/ │ │ └── Cos/ │ │ ├── Client.php │ │ ├── CommandToRequestTransformer.php │ │ ├── Common.php │ │ ├── Copy.php │ │ ├── Exception/ │ │ │ ├── CosException.php │ │ │ └── ServiceResponseException.php │ │ ├── ExceptionMiddleware.php │ │ ├── ExceptionParser.php │ │ ├── ImageParamTemplate/ │ │ │ ├── BlindWatermarkTemplate.php │ │ │ ├── CIParamTransformation.php │ │ │ ├── ImageMogrTemplate.php │ │ │ ├── ImageQrcodeTemplate.php │ │ │ ├── ImageStyleTemplate.php │ │ │ ├── ImageTemplate.php │ │ │ ├── ImageViewTemplate.php │ │ │ ├── ImageWatermarkTemplate.php │ │ │ ├── PicOperationsTransformation.php │ │ │ └── TextWatermarkTemplate.php │ │ ├── MultipartUpload.php │ │ ├── RangeDownload.php │ │ ├── Request/ │ │ │ └── BodyLocation.php │ │ ├── ResultTransformer.php │ │ ├── Serializer.php │ │ ├── Service.php │ │ ├── Signature.php │ │ ├── SignatureMiddleware.php │ │ └── Tests/ │ │ ├── COSTest.php │ │ └── TestHelper.php │ ├── ralouphie/ │ │ └── getallheaders/ │ │ ├── LICENSE │ │ ├── README.md │ │ ├── composer.json │ │ └── src/ │ │ └── getallheaders.php │ ├── slim/ │ │ ├── psr7/ │ │ │ ├── LICENSE.md │ │ │ ├── MAINTAINERS.md │ │ │ ├── composer.json │ │ │ └── src/ │ │ │ ├── Cookies.php │ │ │ ├── Environment.php │ │ │ ├── Factory/ │ │ │ │ ├── RequestFactory.php │ │ │ │ ├── ResponseFactory.php │ │ │ │ ├── ServerRequestFactory.php │ │ │ │ ├── StreamFactory.php │ │ │ │ ├── UploadedFileFactory.php │ │ │ │ └── UriFactory.php │ │ │ ├── Header.php │ │ │ ├── Headers.php │ │ │ ├── Interfaces/ │ │ │ │ └── HeadersInterface.php │ │ │ ├── Message.php │ │ │ ├── NonBufferedBody.php │ │ │ ├── Request.php │ │ │ ├── Response.php │ │ │ ├── Stream.php │ │ │ ├── UploadedFile.php │ │ │ └── Uri.php │ │ └── slim/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE.md │ │ ├── MAINTAINERS.md │ │ ├── SECURITY.md │ │ ├── Slim/ │ │ │ ├── App.php │ │ │ ├── CallableResolver.php │ │ │ ├── Error/ │ │ │ │ ├── AbstractErrorRenderer.php │ │ │ │ └── Renderers/ │ │ │ │ ├── HtmlErrorRenderer.php │ │ │ │ ├── JsonErrorRenderer.php │ │ │ │ ├── PlainTextErrorRenderer.php │ │ │ │ └── XmlErrorRenderer.php │ │ │ ├── Exception/ │ │ │ │ ├── HttpBadRequestException.php │ │ │ │ ├── HttpException.php │ │ │ │ ├── HttpForbiddenException.php │ │ │ │ ├── HttpGoneException.php │ │ │ │ ├── HttpInternalServerErrorException.php │ │ │ │ ├── HttpMethodNotAllowedException.php │ │ │ │ ├── HttpNotFoundException.php │ │ │ │ ├── HttpNotImplementedException.php │ │ │ │ ├── HttpSpecializedException.php │ │ │ │ ├── HttpTooManyRequestsException.php │ │ │ │ └── HttpUnauthorizedException.php │ │ │ ├── Factory/ │ │ │ │ ├── AppFactory.php │ │ │ │ ├── Psr17/ │ │ │ │ │ ├── GuzzlePsr17Factory.php │ │ │ │ │ ├── HttpSoftPsr17Factory.php │ │ │ │ │ ├── LaminasDiactorosPsr17Factory.php │ │ │ │ │ ├── NyholmPsr17Factory.php │ │ │ │ │ ├── Psr17Factory.php │ │ │ │ │ ├── Psr17FactoryProvider.php │ │ │ │ │ ├── ServerRequestCreator.php │ │ │ │ │ ├── SlimHttpPsr17Factory.php │ │ │ │ │ ├── SlimHttpServerRequestCreator.php │ │ │ │ │ └── SlimPsr17Factory.php │ │ │ │ └── ServerRequestCreatorFactory.php │ │ │ ├── Handlers/ │ │ │ │ ├── ErrorHandler.php │ │ │ │ └── Strategies/ │ │ │ │ ├── RequestHandler.php │ │ │ │ ├── RequestResponse.php │ │ │ │ ├── RequestResponseArgs.php │ │ │ │ └── RequestResponseNamedArgs.php │ │ │ ├── Interfaces/ │ │ │ │ ├── AdvancedCallableResolverInterface.php │ │ │ │ ├── CallableResolverInterface.php │ │ │ │ ├── DispatcherInterface.php │ │ │ │ ├── ErrorHandlerInterface.php │ │ │ │ ├── ErrorRendererInterface.php │ │ │ │ ├── InvocationStrategyInterface.php │ │ │ │ ├── MiddlewareDispatcherInterface.php │ │ │ │ ├── Psr17FactoryInterface.php │ │ │ │ ├── Psr17FactoryProviderInterface.php │ │ │ │ ├── RequestHandlerInvocationStrategyInterface.php │ │ │ │ ├── RouteCollectorInterface.php │ │ │ │ ├── RouteCollectorProxyInterface.php │ │ │ │ ├── RouteGroupInterface.php │ │ │ │ ├── RouteInterface.php │ │ │ │ ├── RouteParserInterface.php │ │ │ │ ├── RouteResolverInterface.php │ │ │ │ └── ServerRequestCreatorInterface.php │ │ │ ├── Logger.php │ │ │ ├── Middleware/ │ │ │ │ ├── BodyParsingMiddleware.php │ │ │ │ ├── ContentLengthMiddleware.php │ │ │ │ ├── ErrorMiddleware.php │ │ │ │ ├── MethodOverrideMiddleware.php │ │ │ │ ├── OutputBufferingMiddleware.php │ │ │ │ └── RoutingMiddleware.php │ │ │ ├── MiddlewareDispatcher.php │ │ │ ├── ResponseEmitter.php │ │ │ └── Routing/ │ │ │ ├── Dispatcher.php │ │ │ ├── FastRouteDispatcher.php │ │ │ ├── Route.php │ │ │ ├── RouteCollector.php │ │ │ ├── RouteCollectorProxy.php │ │ │ ├── RouteContext.php │ │ │ ├── RouteGroup.php │ │ │ ├── RouteParser.php │ │ │ ├── RouteResolver.php │ │ │ ├── RouteRunner.php │ │ │ └── RoutingResults.php │ │ └── composer.json │ ├── symfony/ │ │ ├── console/ │ │ │ ├── Application.php │ │ │ ├── Attribute/ │ │ │ │ └── AsCommand.php │ │ │ ├── CHANGELOG.md │ │ │ ├── CI/ │ │ │ │ └── GithubActionReporter.php │ │ │ ├── Color.php │ │ │ ├── Command/ │ │ │ │ ├── Command.php │ │ │ │ ├── CompleteCommand.php │ │ │ │ ├── DumpCompletionCommand.php │ │ │ │ ├── HelpCommand.php │ │ │ │ ├── LazyCommand.php │ │ │ │ ├── ListCommand.php │ │ │ │ ├── LockableTrait.php │ │ │ │ └── SignalableCommandInterface.php │ │ │ ├── CommandLoader/ │ │ │ │ ├── CommandLoaderInterface.php │ │ │ │ ├── ContainerCommandLoader.php │ │ │ │ └── FactoryCommandLoader.php │ │ │ ├── Completion/ │ │ │ │ ├── CompletionInput.php │ │ │ │ ├── CompletionSuggestions.php │ │ │ │ ├── Output/ │ │ │ │ │ ├── BashCompletionOutput.php │ │ │ │ │ └── CompletionOutputInterface.php │ │ │ │ └── Suggestion.php │ │ │ ├── ConsoleEvents.php │ │ │ ├── Cursor.php │ │ │ ├── DependencyInjection/ │ │ │ │ └── AddConsoleCommandPass.php │ │ │ ├── Descriptor/ │ │ │ │ ├── ApplicationDescription.php │ │ │ │ ├── Descriptor.php │ │ │ │ ├── DescriptorInterface.php │ │ │ │ ├── JsonDescriptor.php │ │ │ │ ├── MarkdownDescriptor.php │ │ │ │ ├── TextDescriptor.php │ │ │ │ └── XmlDescriptor.php │ │ │ ├── Event/ │ │ │ │ ├── ConsoleCommandEvent.php │ │ │ │ ├── ConsoleErrorEvent.php │ │ │ │ ├── ConsoleEvent.php │ │ │ │ ├── ConsoleSignalEvent.php │ │ │ │ └── ConsoleTerminateEvent.php │ │ │ ├── EventListener/ │ │ │ │ └── ErrorListener.php │ │ │ ├── Exception/ │ │ │ │ ├── CommandNotFoundException.php │ │ │ │ ├── ExceptionInterface.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ ├── InvalidOptionException.php │ │ │ │ ├── LogicException.php │ │ │ │ ├── MissingInputException.php │ │ │ │ ├── NamespaceNotFoundException.php │ │ │ │ └── RuntimeException.php │ │ │ ├── Formatter/ │ │ │ │ ├── NullOutputFormatter.php │ │ │ │ ├── NullOutputFormatterStyle.php │ │ │ │ ├── OutputFormatter.php │ │ │ │ ├── OutputFormatterInterface.php │ │ │ │ ├── OutputFormatterStyle.php │ │ │ │ ├── OutputFormatterStyleInterface.php │ │ │ │ ├── OutputFormatterStyleStack.php │ │ │ │ └── WrappableOutputFormatterInterface.php │ │ │ ├── Helper/ │ │ │ │ ├── DebugFormatterHelper.php │ │ │ │ ├── DescriptorHelper.php │ │ │ │ ├── Dumper.php │ │ │ │ ├── FormatterHelper.php │ │ │ │ ├── Helper.php │ │ │ │ ├── HelperInterface.php │ │ │ │ ├── HelperSet.php │ │ │ │ ├── InputAwareHelper.php │ │ │ │ ├── ProcessHelper.php │ │ │ │ ├── ProgressBar.php │ │ │ │ ├── ProgressIndicator.php │ │ │ │ ├── QuestionHelper.php │ │ │ │ ├── SymfonyQuestionHelper.php │ │ │ │ ├── Table.php │ │ │ │ ├── TableCell.php │ │ │ │ ├── TableCellStyle.php │ │ │ │ ├── TableRows.php │ │ │ │ ├── TableSeparator.php │ │ │ │ └── TableStyle.php │ │ │ ├── Input/ │ │ │ │ ├── ArgvInput.php │ │ │ │ ├── ArrayInput.php │ │ │ │ ├── Input.php │ │ │ │ ├── InputArgument.php │ │ │ │ ├── InputAwareInterface.php │ │ │ │ ├── InputDefinition.php │ │ │ │ ├── InputInterface.php │ │ │ │ ├── InputOption.php │ │ │ │ ├── StreamableInputInterface.php │ │ │ │ └── StringInput.php │ │ │ ├── LICENSE │ │ │ ├── Logger/ │ │ │ │ └── ConsoleLogger.php │ │ │ ├── Output/ │ │ │ │ ├── BufferedOutput.php │ │ │ │ ├── ConsoleOutput.php │ │ │ │ ├── ConsoleOutputInterface.php │ │ │ │ ├── ConsoleSectionOutput.php │ │ │ │ ├── NullOutput.php │ │ │ │ ├── Output.php │ │ │ │ ├── OutputInterface.php │ │ │ │ ├── StreamOutput.php │ │ │ │ └── TrimmedBufferOutput.php │ │ │ ├── Question/ │ │ │ │ ├── ChoiceQuestion.php │ │ │ │ ├── ConfirmationQuestion.php │ │ │ │ └── Question.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── completion.bash │ │ │ ├── SignalRegistry/ │ │ │ │ └── SignalRegistry.php │ │ │ ├── SingleCommandApplication.php │ │ │ ├── Style/ │ │ │ │ ├── OutputStyle.php │ │ │ │ ├── StyleInterface.php │ │ │ │ └── SymfonyStyle.php │ │ │ ├── Terminal.php │ │ │ ├── Tester/ │ │ │ │ ├── ApplicationTester.php │ │ │ │ ├── CommandCompletionTester.php │ │ │ │ ├── CommandTester.php │ │ │ │ ├── Constraint/ │ │ │ │ │ └── CommandIsSuccessful.php │ │ │ │ └── TesterTrait.php │ │ │ └── composer.json │ │ ├── deprecation-contracts/ │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── composer.json │ │ │ └── function.php │ │ ├── finder/ │ │ │ ├── CHANGELOG.md │ │ │ ├── Comparator/ │ │ │ │ ├── Comparator.php │ │ │ │ ├── DateComparator.php │ │ │ │ └── NumberComparator.php │ │ │ ├── Exception/ │ │ │ │ ├── AccessDeniedException.php │ │ │ │ └── DirectoryNotFoundException.php │ │ │ ├── Finder.php │ │ │ ├── Gitignore.php │ │ │ ├── Glob.php │ │ │ ├── Iterator/ │ │ │ │ ├── CustomFilterIterator.php │ │ │ │ ├── DateRangeFilterIterator.php │ │ │ │ ├── DepthRangeFilterIterator.php │ │ │ │ ├── ExcludeDirectoryFilterIterator.php │ │ │ │ ├── FileTypeFilterIterator.php │ │ │ │ ├── FilecontentFilterIterator.php │ │ │ │ ├── FilenameFilterIterator.php │ │ │ │ ├── LazyIterator.php │ │ │ │ ├── MultiplePcreFilterIterator.php │ │ │ │ ├── PathFilterIterator.php │ │ │ │ ├── RecursiveDirectoryIterator.php │ │ │ │ ├── SizeRangeFilterIterator.php │ │ │ │ ├── SortableIterator.php │ │ │ │ └── VcsIgnoredFilterIterator.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── SplFileInfo.php │ │ │ └── composer.json │ │ ├── http-client/ │ │ │ ├── AmpHttpClient.php │ │ │ ├── AsyncDecoratorTrait.php │ │ │ ├── CHANGELOG.md │ │ │ ├── CachingHttpClient.php │ │ │ ├── Chunk/ │ │ │ │ ├── DataChunk.php │ │ │ │ ├── ErrorChunk.php │ │ │ │ ├── FirstChunk.php │ │ │ │ ├── InformationalChunk.php │ │ │ │ ├── LastChunk.php │ │ │ │ └── ServerSentEvent.php │ │ │ ├── CurlHttpClient.php │ │ │ ├── DataCollector/ │ │ │ │ └── HttpClientDataCollector.php │ │ │ ├── DecoratorTrait.php │ │ │ ├── DependencyInjection/ │ │ │ │ └── HttpClientPass.php │ │ │ ├── EventSourceHttpClient.php │ │ │ ├── Exception/ │ │ │ │ ├── ClientException.php │ │ │ │ ├── EventSourceException.php │ │ │ │ ├── HttpExceptionTrait.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ ├── JsonException.php │ │ │ │ ├── RedirectionException.php │ │ │ │ ├── ServerException.php │ │ │ │ ├── TimeoutException.php │ │ │ │ └── TransportException.php │ │ │ ├── HttpClient.php │ │ │ ├── HttpClientTrait.php │ │ │ ├── HttpOptions.php │ │ │ ├── HttplugClient.php │ │ │ ├── Internal/ │ │ │ │ ├── AmpBody.php │ │ │ │ ├── AmpClientState.php │ │ │ │ ├── AmpListener.php │ │ │ │ ├── AmpResolver.php │ │ │ │ ├── Canary.php │ │ │ │ ├── ClientState.php │ │ │ │ ├── CurlClientState.php │ │ │ │ ├── DnsCache.php │ │ │ │ ├── HttplugWaitLoop.php │ │ │ │ ├── LegacyHttplugInterface.php │ │ │ │ ├── NativeClientState.php │ │ │ │ └── PushedResponse.php │ │ │ ├── LICENSE │ │ │ ├── Messenger/ │ │ │ │ ├── PingWebhookMessage.php │ │ │ │ └── PingWebhookMessageHandler.php │ │ │ ├── MockHttpClient.php │ │ │ ├── NativeHttpClient.php │ │ │ ├── NoPrivateNetworkHttpClient.php │ │ │ ├── Psr18Client.php │ │ │ ├── README.md │ │ │ ├── Response/ │ │ │ │ ├── AmpResponse.php │ │ │ │ ├── AsyncContext.php │ │ │ │ ├── AsyncResponse.php │ │ │ │ ├── CommonResponseTrait.php │ │ │ │ ├── CurlResponse.php │ │ │ │ ├── HttplugPromise.php │ │ │ │ ├── JsonMockResponse.php │ │ │ │ ├── MockResponse.php │ │ │ │ ├── NativeResponse.php │ │ │ │ ├── ResponseStream.php │ │ │ │ ├── StreamWrapper.php │ │ │ │ ├── StreamableInterface.php │ │ │ │ ├── TraceableResponse.php │ │ │ │ └── TransportResponseTrait.php │ │ │ ├── Retry/ │ │ │ │ ├── GenericRetryStrategy.php │ │ │ │ └── RetryStrategyInterface.php │ │ │ ├── RetryableHttpClient.php │ │ │ ├── ScopingHttpClient.php │ │ │ ├── Test/ │ │ │ │ └── HarFileResponseFactory.php │ │ │ ├── TraceableHttpClient.php │ │ │ ├── UriTemplateHttpClient.php │ │ │ └── composer.json │ │ ├── http-client-contracts/ │ │ │ ├── CHANGELOG.md │ │ │ ├── ChunkInterface.php │ │ │ ├── Exception/ │ │ │ │ ├── ClientExceptionInterface.php │ │ │ │ ├── DecodingExceptionInterface.php │ │ │ │ ├── ExceptionInterface.php │ │ │ │ ├── HttpExceptionInterface.php │ │ │ │ ├── RedirectionExceptionInterface.php │ │ │ │ ├── ServerExceptionInterface.php │ │ │ │ ├── TimeoutExceptionInterface.php │ │ │ │ └── TransportExceptionInterface.php │ │ │ ├── HttpClientInterface.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── ResponseInterface.php │ │ │ ├── ResponseStreamInterface.php │ │ │ ├── Test/ │ │ │ │ ├── Fixtures/ │ │ │ │ │ └── web/ │ │ │ │ │ └── index.php │ │ │ │ ├── HttpClientTestCase.php │ │ │ │ └── TestHttpServer.php │ │ │ └── composer.json │ │ ├── polyfill-ctype/ │ │ │ ├── Ctype.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap80.php │ │ │ └── composer.json │ │ ├── polyfill-intl-grapheme/ │ │ │ ├── Grapheme.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap80.php │ │ │ └── composer.json │ │ ├── polyfill-intl-idn/ │ │ │ ├── Idn.php │ │ │ ├── Info.php │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── unidata/ │ │ │ │ ├── DisallowedRanges.php │ │ │ │ ├── Regex.php │ │ │ │ ├── deviation.php │ │ │ │ ├── disallowed.php │ │ │ │ ├── disallowed_STD3_mapped.php │ │ │ │ ├── disallowed_STD3_valid.php │ │ │ │ ├── ignored.php │ │ │ │ ├── mapped.php │ │ │ │ └── virama.php │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap80.php │ │ │ └── composer.json │ │ ├── polyfill-intl-normalizer/ │ │ │ ├── LICENSE │ │ │ ├── Normalizer.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ ├── stubs/ │ │ │ │ │ └── Normalizer.php │ │ │ │ └── unidata/ │ │ │ │ ├── canonicalComposition.php │ │ │ │ ├── canonicalDecomposition.php │ │ │ │ ├── combiningClass.php │ │ │ │ └── compatibilityDecomposition.php │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap80.php │ │ │ └── composer.json │ │ ├── polyfill-mbstring/ │ │ │ ├── LICENSE │ │ │ ├── Mbstring.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── unidata/ │ │ │ │ ├── caseFolding.php │ │ │ │ ├── lowerCase.php │ │ │ │ ├── titleCaseRegexp.php │ │ │ │ └── upperCase.php │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap80.php │ │ │ └── composer.json │ │ ├── polyfill-php73/ │ │ │ ├── LICENSE │ │ │ ├── Php73.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── stubs/ │ │ │ │ └── JsonException.php │ │ │ ├── bootstrap.php │ │ │ └── composer.json │ │ ├── polyfill-php80/ │ │ │ ├── LICENSE │ │ │ ├── Php80.php │ │ │ ├── PhpToken.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── stubs/ │ │ │ │ ├── Attribute.php │ │ │ │ ├── PhpToken.php │ │ │ │ ├── Stringable.php │ │ │ │ ├── UnhandledMatchError.php │ │ │ │ └── ValueError.php │ │ │ ├── bootstrap.php │ │ │ └── composer.json │ │ ├── polyfill-php83/ │ │ │ ├── LICENSE │ │ │ ├── Php83.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ └── stubs/ │ │ │ │ ├── DateError.php │ │ │ │ ├── DateException.php │ │ │ │ ├── DateInvalidOperationException.php │ │ │ │ ├── DateInvalidTimeZoneException.php │ │ │ │ ├── DateMalformedIntervalStringException.php │ │ │ │ ├── DateMalformedPeriodStringException.php │ │ │ │ ├── DateMalformedStringException.php │ │ │ │ ├── DateObjectError.php │ │ │ │ ├── DateRangeError.php │ │ │ │ ├── Override.php │ │ │ │ └── SQLite3Exception.php │ │ │ ├── bootstrap.php │ │ │ ├── bootstrap81.php │ │ │ └── composer.json │ │ ├── service-contracts/ │ │ │ ├── Attribute/ │ │ │ │ ├── Required.php │ │ │ │ └── SubscribedService.php │ │ │ ├── CHANGELOG.md │ │ │ ├── LICENSE │ │ │ ├── README.md │ │ │ ├── ResetInterface.php │ │ │ ├── ServiceCollectionInterface.php │ │ │ ├── ServiceLocatorTrait.php │ │ │ ├── ServiceMethodsSubscriberTrait.php │ │ │ ├── ServiceProviderInterface.php │ │ │ ├── ServiceSubscriberInterface.php │ │ │ ├── ServiceSubscriberTrait.php │ │ │ ├── Test/ │ │ │ │ ├── ServiceLocatorTest.php │ │ │ │ └── ServiceLocatorTestCase.php │ │ │ └── composer.json │ │ ├── string/ │ │ │ ├── AbstractString.php │ │ │ ├── AbstractUnicodeString.php │ │ │ ├── ByteString.php │ │ │ ├── CHANGELOG.md │ │ │ ├── CodePointString.php │ │ │ ├── Exception/ │ │ │ │ ├── ExceptionInterface.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ └── RuntimeException.php │ │ │ ├── Inflector/ │ │ │ │ ├── EnglishInflector.php │ │ │ │ ├── FrenchInflector.php │ │ │ │ └── InflectorInterface.php │ │ │ ├── LICENSE │ │ │ ├── LazyString.php │ │ │ ├── README.md │ │ │ ├── Resources/ │ │ │ │ ├── data/ │ │ │ │ │ ├── wcswidth_table_wide.php │ │ │ │ │ └── wcswidth_table_zero.php │ │ │ │ └── functions.php │ │ │ ├── Slugger/ │ │ │ │ ├── AsciiSlugger.php │ │ │ │ └── SluggerInterface.php │ │ │ ├── UnicodeString.php │ │ │ └── composer.json │ │ ├── translation/ │ │ │ ├── CHANGELOG.md │ │ │ ├── Catalogue/ │ │ │ │ ├── AbstractOperation.php │ │ │ │ ├── MergeOperation.php │ │ │ │ ├── OperationInterface.php │ │ │ │ └── TargetOperation.php │ │ │ ├── CatalogueMetadataAwareInterface.php │ │ │ ├── Command/ │ │ │ │ ├── TranslationPullCommand.php │ │ │ │ ├── TranslationPushCommand.php │ │ │ │ ├── TranslationTrait.php │ │ │ │ └── XliffLintCommand.php │ │ │ ├── DataCollector/ │ │ │ │ └── TranslationDataCollector.php │ │ │ ├── DataCollectorTranslator.php │ │ │ ├── DependencyInjection/ │ │ │ │ ├── DataCollectorTranslatorPass.php │ │ │ │ ├── LoggingTranslatorPass.php │ │ │ │ ├── TranslationDumperPass.php │ │ │ │ ├── TranslationExtractorPass.php │ │ │ │ ├── TranslatorPass.php │ │ │ │ └── TranslatorPathsPass.php │ │ │ ├── Dumper/ │ │ │ │ ├── CsvFileDumper.php │ │ │ │ ├── DumperInterface.php │ │ │ │ ├── FileDumper.php │ │ │ │ ├── IcuResFileDumper.php │ │ │ │ ├── IniFileDumper.php │ │ │ │ ├── JsonFileDumper.php │ │ │ │ ├── MoFileDumper.php │ │ │ │ ├── PhpFileDumper.php │ │ │ │ ├── PoFileDumper.php │ │ │ │ ├── QtFileDumper.php │ │ │ │ ├── XliffFileDumper.php │ │ │ │ └── YamlFileDumper.php │ │ │ ├── Exception/ │ │ │ │ ├── ExceptionInterface.php │ │ │ │ ├── IncompleteDsnException.php │ │ │ │ ├── InvalidArgumentException.php │ │ │ │ ├── InvalidResourceException.php │ │ │ │ ├── LogicException.php │ │ │ │ ├── MissingRequiredOptionException.php │ │ │ │ ├── NotFoundResourceException.php │ │ │ │ ├── ProviderException.php │ │ │ │ ├── ProviderExceptionInterface.php │ │ │ │ ├── RuntimeException.php │ │ │ │ └── UnsupportedSchemeException.php │ │ │ ├── Extractor/ │ │ │ │ ├── AbstractFileExtractor.php │ │ │ │ ├── ChainExtractor.php │ │ │ │ ├── ExtractorInterface.php │ │ │ │ ├── PhpAstExtractor.php │ │ │ │ ├── PhpExtractor.php │ │ │ │ ├── PhpStringTokenParser.php │ │ │ │ └── Visitor/ │ │ │ │ ├── AbstractVisitor.php │ │ │ │ ├── ConstraintVisitor.php │ │ │ │ ├── TransMethodVisitor.php │ │ │ │ └── TranslatableMessageVisitor.php │ │ │ ├── Formatter/ │ │ │ │ ├── IntlFormatter.php │ │ │ │ ├── IntlFormatterInterface.php │ │ │ │ ├── MessageFormatter.php │ │ │ │ └── MessageFormatterInterface.php │ │ │ ├── IdentityTranslator.php │ │ │ ├── LICENSE │ │ │ ├── Loader/ │ │ │ │ ├── ArrayLoader.php │ │ │ │ ├── CsvFileLoader.php │ │ │ │ ├── FileLoader.php │ │ │ │ ├── IcuDatFileLoader.php │ │ │ │ ├── IcuResFileLoader.php │ │ │ │ ├── IniFileLoader.php │ │ │ │ ├── JsonFileLoader.php │ │ │ │ ├── LoaderInterface.php │ │ │ │ ├── MoFileLoader.php │ │ │ │ ├── PhpFileLoader.php │ │ │ │ ├── PoFileLoader.php │ │ │ │ ├── QtFileLoader.php │ │ │ │ ├── XliffFileLoader.php │ │ │ │ └── YamlFileLoader.php │ │ │ ├── LocaleSwitcher.php │ │ │ ├── LoggingTranslator.php │ │ │ ├── MessageCatalogue.php │ │ │ ├── MessageCatalogueInterface.php │ │ │ ├── MetadataAwareInterface.php │ │ │ ├── Provider/ │ │ │ │ ├── AbstractProviderFactory.php │ │ │ │ ├── Dsn.php │ │ │ │ ├── FilteringProvider.php │ │ │ │ ├── NullProvider.php │ │ │ │ ├── NullProviderFactory.php │ │ │ │ ├── ProviderFactoryInterface.php │ │ │ │ ├── ProviderInterface.php │ │ │ │ ├── TranslationProviderCollection.php │ │ │ │ └── TranslationProviderCollectionFactory.php │ │ │ ├── PseudoLocalizationTranslator.php │ │ │ ├── README.md │ │ │ ├── Reader/ │ │ │ │ ├── TranslationReader.php │ │ │ │ └── TranslationReaderInterface.php │ │ │ ├── Resources/ │ │ │ │ ├── bin/ │ │ │ │ │ └── translation-status.php │ │ │ │ ├── data/ │ │ │ │ │ └── parents.json │ │ │ │ ├── functions.php │ │ │ │ └── schemas/ │ │ │ │ ├── xliff-core-1.2-transitional.xsd │ │ │ │ ├── xliff-core-2.0.xsd │ │ │ │ └── xml.xsd │ │ │ ├── Test/ │ │ │ │ ├── ProviderFactoryTestCase.php │ │ │ │ └── ProviderTestCase.php │ │ │ ├── TranslatableMessage.php │ │ │ ├── Translator.php │ │ │ ├── TranslatorBag.php │ │ │ ├── TranslatorBagInterface.php │ │ │ ├── Util/ │ │ │ │ ├── ArrayConverter.php │ │ │ │ └── XliffUtils.php │ │ │ ├── Writer/ │ │ │ │ ├── TranslationWriter.php │ │ │ │ └── TranslationWriterInterface.php │ │ │ └── composer.json │ │ └── translation-contracts/ │ │ ├── CHANGELOG.md │ │ ├── LICENSE │ │ ├── LocaleAwareInterface.php │ │ ├── README.md │ │ ├── Test/ │ │ │ └── TranslatorTest.php │ │ ├── TranslatableInterface.php │ │ ├── TranslatorInterface.php │ │ ├── TranslatorTrait.php │ │ └── composer.json │ ├── vlucas/ │ │ └── phpdotenv/ │ │ ├── LICENSE │ │ ├── composer.json │ │ └── src/ │ │ ├── Dotenv.php │ │ ├── Exception/ │ │ │ ├── ExceptionInterface.php │ │ │ ├── InvalidEncodingException.php │ │ │ ├── InvalidFileException.php │ │ │ ├── InvalidPathException.php │ │ │ └── ValidationException.php │ │ ├── Loader/ │ │ │ ├── Loader.php │ │ │ ├── LoaderInterface.php │ │ │ └── Resolver.php │ │ ├── Parser/ │ │ │ ├── Entry.php │ │ │ ├── EntryParser.php │ │ │ ├── Lexer.php │ │ │ ├── Lines.php │ │ │ ├── Parser.php │ │ │ ├── ParserInterface.php │ │ │ └── Value.php │ │ ├── Repository/ │ │ │ ├── Adapter/ │ │ │ │ ├── AdapterInterface.php │ │ │ │ ├── ApacheAdapter.php │ │ │ │ ├── ArrayAdapter.php │ │ │ │ ├── EnvConstAdapter.php │ │ │ │ ├── GuardedWriter.php │ │ │ │ ├── ImmutableWriter.php │ │ │ │ ├── MultiReader.php │ │ │ │ ├── MultiWriter.php │ │ │ │ ├── PutenvAdapter.php │ │ │ │ ├── ReaderInterface.php │ │ │ │ ├── ReplacingWriter.php │ │ │ │ ├── ServerConstAdapter.php │ │ │ │ └── WriterInterface.php │ │ │ ├── AdapterRepository.php │ │ │ ├── RepositoryBuilder.php │ │ │ └── RepositoryInterface.php │ │ ├── Store/ │ │ │ ├── File/ │ │ │ │ ├── Paths.php │ │ │ │ └── Reader.php │ │ │ ├── FileStore.php │ │ │ ├── StoreBuilder.php │ │ │ ├── StoreInterface.php │ │ │ └── StringStore.php │ │ ├── Util/ │ │ │ ├── Regex.php │ │ │ └── Str.php │ │ └── Validator.php │ └── voku/ │ └── portable-ascii/ │ ├── .whitesource │ ├── CHANGELOG.md │ ├── LICENSE.txt │ ├── README.md │ ├── build/ │ │ ├── composer.json │ │ ├── docs/ │ │ │ └── base.md │ │ ├── generate_docs.php │ │ └── generate_max_key_length.php │ ├── composer.json │ └── src/ │ └── voku/ │ └── helper/ │ ├── ASCII.php │ └── data/ │ ├── ascii_by_languages.php │ ├── ascii_extras_by_languages.php │ ├── ascii_language_max_key.php │ ├── ascii_ord.php │ ├── x000.php │ ├── x001.php │ ├── x002.php │ ├── x003.php │ ├── x004.php │ ├── x005.php │ ├── x006.php │ ├── x007.php │ ├── x009.php │ ├── x00a.php │ ├── x00b.php │ ├── x00c.php │ ├── x00d.php │ ├── x00e.php │ ├── x00f.php │ ├── x010.php │ ├── x011.php │ ├── x012.php │ ├── x013.php │ ├── x014.php │ ├── x015.php │ ├── x016.php │ ├── x017.php │ ├── x018.php │ ├── x01d.php │ ├── x01e.php │ ├── x01f.php │ ├── x020.php │ ├── x021.php │ ├── x022.php │ ├── x023.php │ ├── x024.php │ ├── x025.php │ ├── x026.php │ ├── x027.php │ ├── x028.php │ ├── x029.php │ ├── x02a.php │ ├── x02c.php │ ├── x02e.php │ ├── x02f.php │ ├── x030.php │ ├── x031.php │ ├── x032.php │ ├── x033.php │ ├── x04d.php │ ├── x04e.php │ ├── x04f.php │ ├── x050.php │ ├── x051.php │ ├── x052.php │ ├── x053.php │ ├── x054.php │ ├── x055.php │ ├── x056.php │ ├── x057.php │ ├── x058.php │ ├── x059.php │ ├── x05a.php │ ├── x05b.php │ ├── x05c.php │ ├── x05d.php │ ├── x05e.php │ ├── x05f.php │ ├── x060.php │ ├── x061.php │ ├── x062.php │ ├── x063.php │ ├── x064.php │ ├── x065.php │ ├── x066.php │ ├── x067.php │ ├── x068.php │ ├── x069.php │ ├── x06a.php │ ├── x06b.php │ ├── x06c.php │ ├── x06d.php │ ├── x06e.php │ ├── x06f.php │ ├── x070.php │ ├── x071.php │ ├── x072.php │ ├── x073.php │ ├── x074.php │ ├── x075.php │ ├── x076.php │ ├── x077.php │ ├── x078.php │ ├── x079.php │ ├── x07a.php │ ├── x07b.php │ ├── x07c.php │ ├── x07d.php │ ├── x07e.php │ ├── x07f.php │ ├── x080.php │ ├── x081.php │ ├── x082.php │ ├── x083.php │ ├── x084.php │ ├── x085.php │ ├── x086.php │ ├── x087.php │ ├── x088.php │ ├── x089.php │ ├── x08a.php │ ├── x08b.php │ ├── x08c.php │ ├── x08d.php │ ├── x08e.php │ ├── x08f.php │ ├── x090.php │ ├── x091.php │ ├── x092.php │ ├── x093.php │ ├── x094.php │ ├── x095.php │ ├── x096.php │ ├── x097.php │ ├── x098.php │ ├── x099.php │ ├── x09a.php │ ├── x09b.php │ ├── x09c.php │ ├── x09d.php │ ├── x09e.php │ ├── x09f.php │ ├── x0a0.php │ ├── x0a1.php │ ├── x0a2.php │ ├── x0a3.php │ ├── x0a4.php │ ├── x0ac.php │ ├── x0ad.php │ ├── x0ae.php │ ├── x0af.php │ ├── x0b0.php │ ├── x0b1.php │ ├── x0b2.php │ ├── x0b3.php │ ├── x0b4.php │ ├── x0b5.php │ ├── x0b6.php │ ├── x0b7.php │ ├── x0b8.php │ ├── x0b9.php │ ├── x0ba.php │ ├── x0bb.php │ ├── x0bc.php │ ├── x0bd.php │ ├── x0be.php │ ├── x0bf.php │ ├── x0c0.php │ ├── x0c1.php │ ├── x0c2.php │ ├── x0c3.php │ ├── x0c4.php │ ├── x0c5.php │ ├── x0c6.php │ ├── x0c7.php │ ├── x0c8.php │ ├── x0c9.php │ ├── x0ca.php │ ├── x0cb.php │ ├── x0cc.php │ ├── x0cd.php │ ├── x0ce.php │ ├── x0cf.php │ ├── x0d0.php │ ├── x0d1.php │ ├── x0d2.php │ ├── x0d3.php │ ├── x0d4.php │ ├── x0d5.php │ ├── x0d6.php │ ├── x0d7.php │ ├── x0f9.php │ ├── x0fa.php │ ├── x0fb.php │ ├── x0fc.php │ ├── x0fd.php │ ├── x0fe.php │ ├── x0ff.php │ ├── x1d4.php │ ├── x1d5.php │ ├── x1d6.php │ ├── x1d7.php │ └── x1f1.php ├── web/ │ ├── assets/ │ │ ├── assets-952385a1.css │ │ ├── assets-d4226b27.js │ │ ├── components-0a6cba7b.js │ │ ├── components-a7ea9a2a.css │ │ ├── core-f857f2ca.js │ │ ├── index-222f752e.js │ │ ├── index-726c1082.css │ │ ├── vendor-49dc2278.css │ │ ├── vendor-8fa27e24.js │ │ ├── vendor-vue-e0182f4b.css │ │ ├── vendor-vue-f1f9849c.js │ │ ├── views-a894d0a6.css │ │ └── views-ab2bd0f9.js │ ├── diff/ │ │ ├── difflib.js │ │ ├── diffview.css │ │ └── diffview.js │ ├── editor.md/ │ │ ├── Gulpfile.js │ │ ├── LICENSE │ │ ├── README.md │ │ ├── css/ │ │ │ ├── editormd.css │ │ │ ├── editormd.logo.css │ │ │ └── editormd.preview.css │ │ ├── editormd.amd.js │ │ ├── editormd.js │ │ ├── fonts/ │ │ │ └── FontAwesome.otf │ │ ├── languages/ │ │ │ ├── en.js │ │ │ └── zh-tw.js │ │ ├── lib/ │ │ │ ├── codemirror/ │ │ │ │ ├── AUTHORS │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── addon/ │ │ │ │ │ ├── comment/ │ │ │ │ │ │ ├── comment.js │ │ │ │ │ │ └── continuecomment.js │ │ │ │ │ ├── dialog/ │ │ │ │ │ │ ├── dialog.css │ │ │ │ │ │ └── dialog.js │ │ │ │ │ ├── display/ │ │ │ │ │ │ ├── fullscreen.css │ │ │ │ │ │ ├── fullscreen.js │ │ │ │ │ │ ├── panel.js │ │ │ │ │ │ ├── placeholder.js │ │ │ │ │ │ └── rulers.js │ │ │ │ │ ├── edit/ │ │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ │ ├── closetag.js │ │ │ │ │ │ ├── continuelist.js │ │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ │ ├── matchtags.js │ │ │ │ │ │ └── trailingspace.js │ │ │ │ │ ├── fold/ │ │ │ │ │ │ ├── brace-fold.js │ │ │ │ │ │ ├── comment-fold.js │ │ │ │ │ │ ├── foldcode.js │ │ │ │ │ │ ├── foldgutter.css │ │ │ │ │ │ ├── foldgutter.js │ │ │ │ │ │ ├── indent-fold.js │ │ │ │ │ │ ├── markdown-fold.js │ │ │ │ │ │ └── xml-fold.js │ │ │ │ │ ├── hint/ │ │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ │ ├── css-hint.js │ │ │ │ │ │ ├── html-hint.js │ │ │ │ │ │ ├── javascript-hint.js │ │ │ │ │ │ ├── show-hint.css │ │ │ │ │ │ ├── show-hint.js │ │ │ │ │ │ ├── sql-hint.js │ │ │ │ │ │ └── xml-hint.js │ │ │ │ │ ├── lint/ │ │ │ │ │ │ ├── coffeescript-lint.js │ │ │ │ │ │ ├── css-lint.js │ │ │ │ │ │ ├── javascript-lint.js │ │ │ │ │ │ ├── json-lint.js │ │ │ │ │ │ ├── lint.css │ │ │ │ │ │ ├── lint.js │ │ │ │ │ │ └── yaml-lint.js │ │ │ │ │ ├── merge/ │ │ │ │ │ │ ├── merge.css │ │ │ │ │ │ └── merge.js │ │ │ │ │ ├── mode/ │ │ │ │ │ │ ├── loadmode.js │ │ │ │ │ │ ├── multiplex.js │ │ │ │ │ │ ├── multiplex_test.js │ │ │ │ │ │ ├── overlay.js │ │ │ │ │ │ └── simple.js │ │ │ │ │ ├── runmode/ │ │ │ │ │ │ ├── colorize.js │ │ │ │ │ │ ├── runmode-standalone.js │ │ │ │ │ │ ├── runmode.js │ │ │ │ │ │ └── runmode.node.js │ │ │ │ │ ├── scroll/ │ │ │ │ │ │ ├── annotatescrollbar.js │ │ │ │ │ │ ├── scrollpastend.js │ │ │ │ │ │ ├── simplescrollbars.css │ │ │ │ │ │ └── simplescrollbars.js │ │ │ │ │ ├── search/ │ │ │ │ │ │ ├── match-highlighter.js │ │ │ │ │ │ ├── matchesonscrollbar.css │ │ │ │ │ │ ├── matchesonscrollbar.js │ │ │ │ │ │ ├── search.js │ │ │ │ │ │ └── searchcursor.js │ │ │ │ │ ├── selection/ │ │ │ │ │ │ ├── active-line.js │ │ │ │ │ │ ├── mark-selection.js │ │ │ │ │ │ └── selection-pointer.js │ │ │ │ │ ├── tern/ │ │ │ │ │ │ ├── tern.css │ │ │ │ │ │ ├── tern.js │ │ │ │ │ │ └── worker.js │ │ │ │ │ └── wrap/ │ │ │ │ │ └── hardwrap.js │ │ │ │ ├── bower.json │ │ │ │ ├── lib/ │ │ │ │ │ ├── codemirror.css │ │ │ │ │ └── codemirror.js │ │ │ │ ├── mode/ │ │ │ │ │ ├── apl/ │ │ │ │ │ │ ├── apl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── asterisk/ │ │ │ │ │ │ ├── asterisk.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── clike/ │ │ │ │ │ │ ├── clike.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── scala.html │ │ │ │ │ ├── clojure/ │ │ │ │ │ │ ├── clojure.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── cobol/ │ │ │ │ │ │ ├── cobol.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── coffeescript/ │ │ │ │ │ │ ├── coffeescript.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── commonlisp/ │ │ │ │ │ │ ├── commonlisp.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── css.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── less.html │ │ │ │ │ │ ├── less_test.js │ │ │ │ │ │ ├── scss.html │ │ │ │ │ │ ├── scss_test.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── cypher/ │ │ │ │ │ │ ├── cypher.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── d/ │ │ │ │ │ │ ├── d.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dart/ │ │ │ │ │ │ ├── dart.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── diff/ │ │ │ │ │ │ ├── diff.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── django/ │ │ │ │ │ │ ├── django.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dockerfile/ │ │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dtd/ │ │ │ │ │ │ ├── dtd.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dylan/ │ │ │ │ │ │ ├── dylan.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── ebnf/ │ │ │ │ │ │ ├── ebnf.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── ecl/ │ │ │ │ │ │ ├── ecl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── eiffel/ │ │ │ │ │ │ ├── eiffel.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── erlang/ │ │ │ │ │ │ ├── erlang.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── forth/ │ │ │ │ │ │ ├── forth.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── fortran/ │ │ │ │ │ │ ├── fortran.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── gas/ │ │ │ │ │ │ ├── gas.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── gfm/ │ │ │ │ │ │ ├── gfm.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── gherkin/ │ │ │ │ │ │ ├── gherkin.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── go/ │ │ │ │ │ │ ├── go.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── groovy/ │ │ │ │ │ │ ├── groovy.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── haml/ │ │ │ │ │ │ ├── haml.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── haskell/ │ │ │ │ │ │ ├── haskell.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── haxe/ │ │ │ │ │ │ ├── haxe.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── htmlembedded/ │ │ │ │ │ │ ├── htmlembedded.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── htmlmixed/ │ │ │ │ │ │ ├── htmlmixed.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── http/ │ │ │ │ │ │ ├── http.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── idl/ │ │ │ │ │ │ ├── idl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── index.html │ │ │ │ │ ├── jade/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── jade.js │ │ │ │ │ ├── javascript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── javascript.js │ │ │ │ │ │ ├── json-ld.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── typescript.html │ │ │ │ │ ├── jinja2/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── jinja2.js │ │ │ │ │ ├── julia/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── julia.js │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── kotlin.js │ │ │ │ │ ├── livescript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── livescript.js │ │ │ │ │ ├── lua/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── lua.js │ │ │ │ │ ├── markdown/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── markdown.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── meta.js │ │ │ │ │ ├── mirc/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── mirc.js │ │ │ │ │ ├── mllike/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── mllike.js │ │ │ │ │ ├── modelica/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── modelica.js │ │ │ │ │ ├── nginx/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── nginx.js │ │ │ │ │ ├── ntriples/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── ntriples.js │ │ │ │ │ ├── octave/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── octave.js │ │ │ │ │ ├── pascal/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pascal.js │ │ │ │ │ ├── pegjs/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pegjs.js │ │ │ │ │ ├── perl/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── perl.js │ │ │ │ │ ├── php/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── php.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── pig/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pig.js │ │ │ │ │ ├── properties/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── properties.js │ │ │ │ │ ├── puppet/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── puppet.js │ │ │ │ │ ├── python/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── python.js │ │ │ │ │ ├── q/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── q.js │ │ │ │ │ ├── r/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── r.js │ │ │ │ │ ├── rpm/ │ │ │ │ │ │ ├── changes/ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rpm.js │ │ │ │ │ ├── rst/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rst.js │ │ │ │ │ ├── ruby/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── ruby.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── rust/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rust.js │ │ │ │ │ ├── sass/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sass.js │ │ │ │ │ ├── scheme/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── scheme.js │ │ │ │ │ ├── shell/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── shell.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── sieve/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sieve.js │ │ │ │ │ ├── slim/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── slim.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── smalltalk/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smalltalk.js │ │ │ │ │ ├── smarty/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smarty.js │ │ │ │ │ ├── smartymixed/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smartymixed.js │ │ │ │ │ ├── solr/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── solr.js │ │ │ │ │ ├── soy/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── soy.js │ │ │ │ │ ├── sparql/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sparql.js │ │ │ │ │ ├── spreadsheet/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── spreadsheet.js │ │ │ │ │ ├── sql/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sql.js │ │ │ │ │ ├── stex/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── stex.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── stylus/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── stylus.js │ │ │ │ │ ├── tcl/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── tcl.js │ │ │ │ │ ├── textile/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── textile.js │ │ │ │ │ ├── tiddlywiki/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── tiddlywiki.css │ │ │ │ │ │ └── tiddlywiki.js │ │ │ │ │ ├── tiki/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── tiki.css │ │ │ │ │ │ └── tiki.js │ │ │ │ │ ├── toml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── toml.js │ │ │ │ │ ├── tornado/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── tornado.js │ │ │ │ │ ├── turtle/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── turtle.js │ │ │ │ │ ├── vb/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── vb.js │ │ │ │ │ ├── vbscript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── vbscript.js │ │ │ │ │ ├── velocity/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── velocity.js │ │ │ │ │ ├── verilog/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── verilog.js │ │ │ │ │ ├── xml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── xml.js │ │ │ │ │ ├── xquery/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── xquery.js │ │ │ │ │ ├── yaml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── yaml.js │ │ │ │ │ └── z80/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── z80.js │ │ │ │ ├── package.json │ │ │ │ └── theme/ │ │ │ │ ├── 3024-day.css │ │ │ │ ├── 3024-night.css │ │ │ │ ├── ambiance-mobile.css │ │ │ │ ├── ambiance.css │ │ │ │ ├── base16-dark.css │ │ │ │ ├── base16-light.css │ │ │ │ ├── blackboard.css │ │ │ │ ├── cobalt.css │ │ │ │ ├── colorforth.css │ │ │ │ ├── eclipse.css │ │ │ │ ├── elegant.css │ │ │ │ ├── erlang-dark.css │ │ │ │ ├── lesser-dark.css │ │ │ │ ├── mbo.css │ │ │ │ ├── mdn-like.css │ │ │ │ ├── midnight.css │ │ │ │ ├── monokai.css │ │ │ │ ├── neat.css │ │ │ │ ├── neo.css │ │ │ │ ├── night.css │ │ │ │ ├── paraiso-dark.css │ │ │ │ ├── paraiso-light.css │ │ │ │ ├── pastel-on-dark.css │ │ │ │ ├── rubyblue.css │ │ │ │ ├── solarized.css │ │ │ │ ├── the-matrix.css │ │ │ │ ├── tomorrow-night-bright.css │ │ │ │ ├── tomorrow-night-eighties.css │ │ │ │ ├── twilight.css │ │ │ │ ├── vibrant-ink.css │ │ │ │ ├── xq-dark.css │ │ │ │ ├── xq-light.css │ │ │ │ └── zenburn.css │ │ │ └── plantuml.js │ │ ├── package.json │ │ └── plugins/ │ │ ├── code-block-dialog/ │ │ │ └── code-block-dialog.js │ │ ├── emoji-dialog/ │ │ │ ├── emoji-dialog.js │ │ │ └── emoji.json │ │ ├── goto-line-dialog/ │ │ │ └── goto-line-dialog.js │ │ ├── help-dialog/ │ │ │ ├── help-dialog.js │ │ │ └── help.md │ │ ├── html-entities-dialog/ │ │ │ ├── html-entities-dialog.js │ │ │ └── html-entities.json │ │ ├── image-dialog/ │ │ │ └── image-dialog.js │ │ ├── link-dialog/ │ │ │ └── link-dialog.js │ │ ├── plugin-template.js │ │ ├── preformatted-text-dialog/ │ │ │ └── preformatted-text-dialog.js │ │ ├── reference-link-dialog/ │ │ │ └── reference-link-dialog.js │ │ ├── table-dialog/ │ │ │ └── table-dialog.js │ │ └── test-plugin/ │ │ └── test-plugin.js │ ├── index.html │ └── xspreadsheet/ │ ├── locale/ │ │ ├── de.js │ │ ├── en.js │ │ ├── nl.js │ │ └── zh-cn.js │ ├── xspreadsheet.css │ └── xspreadsheet.js └── web_src/ ├── index.html ├── package.json ├── public/ │ ├── diff/ │ │ ├── difflib.js │ │ ├── diffview.css │ │ └── diffview.js │ ├── editor.md/ │ │ ├── Gulpfile.js │ │ ├── LICENSE │ │ ├── README.md │ │ ├── css/ │ │ │ ├── editormd.css │ │ │ ├── editormd.logo.css │ │ │ └── editormd.preview.css │ │ ├── editormd.amd.js │ │ ├── editormd.js │ │ ├── fonts/ │ │ │ └── FontAwesome.otf │ │ ├── languages/ │ │ │ ├── en.js │ │ │ └── zh-tw.js │ │ ├── lib/ │ │ │ ├── codemirror/ │ │ │ │ ├── AUTHORS │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── addon/ │ │ │ │ │ ├── comment/ │ │ │ │ │ │ ├── comment.js │ │ │ │ │ │ └── continuecomment.js │ │ │ │ │ ├── dialog/ │ │ │ │ │ │ ├── dialog.css │ │ │ │ │ │ └── dialog.js │ │ │ │ │ ├── display/ │ │ │ │ │ │ ├── fullscreen.css │ │ │ │ │ │ ├── fullscreen.js │ │ │ │ │ │ ├── panel.js │ │ │ │ │ │ ├── placeholder.js │ │ │ │ │ │ └── rulers.js │ │ │ │ │ ├── edit/ │ │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ │ ├── closetag.js │ │ │ │ │ │ ├── continuelist.js │ │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ │ ├── matchtags.js │ │ │ │ │ │ └── trailingspace.js │ │ │ │ │ ├── fold/ │ │ │ │ │ │ ├── brace-fold.js │ │ │ │ │ │ ├── comment-fold.js │ │ │ │ │ │ ├── foldcode.js │ │ │ │ │ │ ├── foldgutter.css │ │ │ │ │ │ ├── foldgutter.js │ │ │ │ │ │ ├── indent-fold.js │ │ │ │ │ │ ├── markdown-fold.js │ │ │ │ │ │ └── xml-fold.js │ │ │ │ │ ├── hint/ │ │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ │ ├── css-hint.js │ │ │ │ │ │ ├── html-hint.js │ │ │ │ │ │ ├── javascript-hint.js │ │ │ │ │ │ ├── show-hint.css │ │ │ │ │ │ ├── show-hint.js │ │ │ │ │ │ ├── sql-hint.js │ │ │ │ │ │ └── xml-hint.js │ │ │ │ │ ├── lint/ │ │ │ │ │ │ ├── coffeescript-lint.js │ │ │ │ │ │ ├── css-lint.js │ │ │ │ │ │ ├── javascript-lint.js │ │ │ │ │ │ ├── json-lint.js │ │ │ │ │ │ ├── lint.css │ │ │ │ │ │ ├── lint.js │ │ │ │ │ │ └── yaml-lint.js │ │ │ │ │ ├── merge/ │ │ │ │ │ │ ├── merge.css │ │ │ │ │ │ └── merge.js │ │ │ │ │ ├── mode/ │ │ │ │ │ │ ├── loadmode.js │ │ │ │ │ │ ├── multiplex.js │ │ │ │ │ │ ├── multiplex_test.js │ │ │ │ │ │ ├── overlay.js │ │ │ │ │ │ └── simple.js │ │ │ │ │ ├── runmode/ │ │ │ │ │ │ ├── colorize.js │ │ │ │ │ │ ├── runmode-standalone.js │ │ │ │ │ │ ├── runmode.js │ │ │ │ │ │ └── runmode.node.js │ │ │ │ │ ├── scroll/ │ │ │ │ │ │ ├── annotatescrollbar.js │ │ │ │ │ │ ├── scrollpastend.js │ │ │ │ │ │ ├── simplescrollbars.css │ │ │ │ │ │ └── simplescrollbars.js │ │ │ │ │ ├── search/ │ │ │ │ │ │ ├── match-highlighter.js │ │ │ │ │ │ ├── matchesonscrollbar.css │ │ │ │ │ │ ├── matchesonscrollbar.js │ │ │ │ │ │ ├── search.js │ │ │ │ │ │ └── searchcursor.js │ │ │ │ │ ├── selection/ │ │ │ │ │ │ ├── active-line.js │ │ │ │ │ │ ├── mark-selection.js │ │ │ │ │ │ └── selection-pointer.js │ │ │ │ │ ├── tern/ │ │ │ │ │ │ ├── tern.css │ │ │ │ │ │ ├── tern.js │ │ │ │ │ │ └── worker.js │ │ │ │ │ └── wrap/ │ │ │ │ │ └── hardwrap.js │ │ │ │ ├── bower.json │ │ │ │ ├── lib/ │ │ │ │ │ ├── codemirror.css │ │ │ │ │ └── codemirror.js │ │ │ │ ├── mode/ │ │ │ │ │ ├── apl/ │ │ │ │ │ │ ├── apl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── asterisk/ │ │ │ │ │ │ ├── asterisk.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── clike/ │ │ │ │ │ │ ├── clike.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── scala.html │ │ │ │ │ ├── clojure/ │ │ │ │ │ │ ├── clojure.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── cobol/ │ │ │ │ │ │ ├── cobol.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── coffeescript/ │ │ │ │ │ │ ├── coffeescript.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── commonlisp/ │ │ │ │ │ │ ├── commonlisp.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── css/ │ │ │ │ │ │ ├── css.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── less.html │ │ │ │ │ │ ├── less_test.js │ │ │ │ │ │ ├── scss.html │ │ │ │ │ │ ├── scss_test.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── cypher/ │ │ │ │ │ │ ├── cypher.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── d/ │ │ │ │ │ │ ├── d.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dart/ │ │ │ │ │ │ ├── dart.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── diff/ │ │ │ │ │ │ ├── diff.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── django/ │ │ │ │ │ │ ├── django.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dockerfile/ │ │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dtd/ │ │ │ │ │ │ ├── dtd.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── dylan/ │ │ │ │ │ │ ├── dylan.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── ebnf/ │ │ │ │ │ │ ├── ebnf.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── ecl/ │ │ │ │ │ │ ├── ecl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── eiffel/ │ │ │ │ │ │ ├── eiffel.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── erlang/ │ │ │ │ │ │ ├── erlang.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── forth/ │ │ │ │ │ │ ├── forth.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── fortran/ │ │ │ │ │ │ ├── fortran.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── gas/ │ │ │ │ │ │ ├── gas.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── gfm/ │ │ │ │ │ │ ├── gfm.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── gherkin/ │ │ │ │ │ │ ├── gherkin.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── go/ │ │ │ │ │ │ ├── go.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── groovy/ │ │ │ │ │ │ ├── groovy.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── haml/ │ │ │ │ │ │ ├── haml.js │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── haskell/ │ │ │ │ │ │ ├── haskell.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── haxe/ │ │ │ │ │ │ ├── haxe.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── htmlembedded/ │ │ │ │ │ │ ├── htmlembedded.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── htmlmixed/ │ │ │ │ │ │ ├── htmlmixed.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── http/ │ │ │ │ │ │ ├── http.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── idl/ │ │ │ │ │ │ ├── idl.js │ │ │ │ │ │ └── index.html │ │ │ │ │ ├── index.html │ │ │ │ │ ├── jade/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── jade.js │ │ │ │ │ ├── javascript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── javascript.js │ │ │ │ │ │ ├── json-ld.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── typescript.html │ │ │ │ │ ├── jinja2/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── jinja2.js │ │ │ │ │ ├── julia/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── julia.js │ │ │ │ │ ├── kotlin/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── kotlin.js │ │ │ │ │ ├── livescript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── livescript.js │ │ │ │ │ ├── lua/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── lua.js │ │ │ │ │ ├── markdown/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── markdown.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── meta.js │ │ │ │ │ ├── mirc/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── mirc.js │ │ │ │ │ ├── mllike/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── mllike.js │ │ │ │ │ ├── modelica/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── modelica.js │ │ │ │ │ ├── nginx/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── nginx.js │ │ │ │ │ ├── ntriples/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── ntriples.js │ │ │ │ │ ├── octave/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── octave.js │ │ │ │ │ ├── pascal/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pascal.js │ │ │ │ │ ├── pegjs/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pegjs.js │ │ │ │ │ ├── perl/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── perl.js │ │ │ │ │ ├── php/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── php.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── pig/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── pig.js │ │ │ │ │ ├── properties/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── properties.js │ │ │ │ │ ├── puppet/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── puppet.js │ │ │ │ │ ├── python/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── python.js │ │ │ │ │ ├── q/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── q.js │ │ │ │ │ ├── r/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── r.js │ │ │ │ │ ├── rpm/ │ │ │ │ │ │ ├── changes/ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rpm.js │ │ │ │ │ ├── rst/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rst.js │ │ │ │ │ ├── ruby/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── ruby.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── rust/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── rust.js │ │ │ │ │ ├── sass/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sass.js │ │ │ │ │ ├── scheme/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── scheme.js │ │ │ │ │ ├── shell/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── shell.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── sieve/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sieve.js │ │ │ │ │ ├── slim/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── slim.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── smalltalk/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smalltalk.js │ │ │ │ │ ├── smarty/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smarty.js │ │ │ │ │ ├── smartymixed/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── smartymixed.js │ │ │ │ │ ├── solr/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── solr.js │ │ │ │ │ ├── soy/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── soy.js │ │ │ │ │ ├── sparql/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sparql.js │ │ │ │ │ ├── spreadsheet/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── spreadsheet.js │ │ │ │ │ ├── sql/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── sql.js │ │ │ │ │ ├── stex/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── stex.js │ │ │ │ │ │ └── test.js │ │ │ │ │ ├── stylus/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── stylus.js │ │ │ │ │ ├── tcl/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── tcl.js │ │ │ │ │ ├── textile/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── textile.js │ │ │ │ │ ├── tiddlywiki/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── tiddlywiki.css │ │ │ │ │ │ └── tiddlywiki.js │ │ │ │ │ ├── tiki/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── tiki.css │ │ │ │ │ │ └── tiki.js │ │ │ │ │ ├── toml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── toml.js │ │ │ │ │ ├── tornado/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── tornado.js │ │ │ │ │ ├── turtle/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── turtle.js │ │ │ │ │ ├── vb/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── vb.js │ │ │ │ │ ├── vbscript/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── vbscript.js │ │ │ │ │ ├── velocity/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── velocity.js │ │ │ │ │ ├── verilog/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── verilog.js │ │ │ │ │ ├── xml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── xml.js │ │ │ │ │ ├── xquery/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ └── xquery.js │ │ │ │ │ ├── yaml/ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ └── yaml.js │ │ │ │ │ └── z80/ │ │ │ │ │ ├── index.html │ │ │ │ │ └── z80.js │ │ │ │ ├── package.json │ │ │ │ └── theme/ │ │ │ │ ├── 3024-day.css │ │ │ │ ├── 3024-night.css │ │ │ │ ├── ambiance-mobile.css │ │ │ │ ├── ambiance.css │ │ │ │ ├── base16-dark.css │ │ │ │ ├── base16-light.css │ │ │ │ ├── blackboard.css │ │ │ │ ├── cobalt.css │ │ │ │ ├── colorforth.css │ │ │ │ ├── eclipse.css │ │ │ │ ├── elegant.css │ │ │ │ ├── erlang-dark.css │ │ │ │ ├── lesser-dark.css │ │ │ │ ├── mbo.css │ │ │ │ ├── mdn-like.css │ │ │ │ ├── midnight.css │ │ │ │ ├── monokai.css │ │ │ │ ├── neat.css │ │ │ │ ├── neo.css │ │ │ │ ├── night.css │ │ │ │ ├── paraiso-dark.css │ │ │ │ ├── paraiso-light.css │ │ │ │ ├── pastel-on-dark.css │ │ │ │ ├── rubyblue.css │ │ │ │ ├── solarized.css │ │ │ │ ├── the-matrix.css │ │ │ │ ├── tomorrow-night-bright.css │ │ │ │ ├── tomorrow-night-eighties.css │ │ │ │ ├── twilight.css │ │ │ │ ├── vibrant-ink.css │ │ │ │ ├── xq-dark.css │ │ │ │ ├── xq-light.css │ │ │ │ └── zenburn.css │ │ │ └── plantuml.js │ │ ├── package.json │ │ └── plugins/ │ │ ├── code-block-dialog/ │ │ │ └── code-block-dialog.js │ │ ├── emoji-dialog/ │ │ │ ├── emoji-dialog.js │ │ │ └── emoji.json │ │ ├── goto-line-dialog/ │ │ │ └── goto-line-dialog.js │ │ ├── help-dialog/ │ │ │ ├── help-dialog.js │ │ │ └── help.md │ │ ├── html-entities-dialog/ │ │ │ ├── html-entities-dialog.js │ │ │ └── html-entities.json │ │ ├── image-dialog/ │ │ │ └── image-dialog.js │ │ ├── link-dialog/ │ │ │ └── link-dialog.js │ │ ├── plugin-template.js │ │ ├── preformatted-text-dialog/ │ │ │ └── preformatted-text-dialog.js │ │ ├── reference-link-dialog/ │ │ │ └── reference-link-dialog.js │ │ ├── table-dialog/ │ │ │ └── table-dialog.js │ │ └── test-plugin/ │ │ └── test-plugin.js │ └── xspreadsheet/ │ ├── locale/ │ │ ├── de.js │ │ ├── en.js │ │ ├── nl.js │ │ └── zh-cn.js │ ├── xspreadsheet.css │ └── xspreadsheet.js ├── src/ │ ├── App.vue │ ├── assets/ │ │ ├── fontawesome/ │ │ │ └── scss/ │ │ │ ├── _animated.scss │ │ │ ├── _bordered-pulled.scss │ │ │ ├── _core.scss │ │ │ ├── _duotone-icons.scss │ │ │ ├── _fixed-width.scss │ │ │ ├── _functions.scss │ │ │ ├── _icons.scss │ │ │ ├── _list.scss │ │ │ ├── _mixins.scss │ │ │ ├── _rotated-flipped.scss │ │ │ ├── _screen-reader.scss │ │ │ ├── _shims.scss │ │ │ ├── _sizing.scss │ │ │ ├── _stacked.scss │ │ │ ├── _variables.scss │ │ │ ├── brands.scss │ │ │ ├── duotone.scss │ │ │ ├── fontawesome.scss │ │ │ ├── light.scss │ │ │ ├── regular.scss │ │ │ ├── sharp-light.scss │ │ │ ├── sharp-regular.scss │ │ │ ├── sharp-solid.scss │ │ │ ├── solid.scss │ │ │ ├── thin.scss │ │ │ └── v4-shims.scss │ │ └── fontawesome.scss │ ├── components/ │ │ ├── AiChatButton.vue │ │ ├── AiChatDialog.vue │ │ ├── AlertModal/ │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── CommonButton.vue │ │ ├── CommonDropdownMenu.vue │ │ ├── CommonInput.vue │ │ ├── CommonModal.vue │ │ ├── CommonSelector.vue │ │ ├── CommonSwitch.vue │ │ ├── CommonTab.vue │ │ ├── CommonTable.vue │ │ ├── CommonTextarea.vue │ │ ├── CommonTop.vue │ │ ├── ConfirmModal/ │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── ContextmenuModal/ │ │ │ ├── Children.vue │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── EditorModal.vue │ │ ├── EditormdEditor/ │ │ │ ├── ShowdocAdapter.vue │ │ │ ├── assets/ │ │ │ │ ├── css/ │ │ │ │ │ ├── editormd.css │ │ │ │ │ └── editormd.preview.css │ │ │ │ └── fonts/ │ │ │ │ └── FontAwesome.otf │ │ │ ├── constants.ts │ │ │ ├── index.ts │ │ │ ├── index.vue │ │ │ ├── themes/ │ │ │ │ ├── base.css │ │ │ │ ├── dark-vars.css │ │ │ │ ├── dialog-theme.css │ │ │ │ ├── font-path-fix.css │ │ │ │ ├── index.ts │ │ │ │ └── light-vars.css │ │ │ └── types.ts │ │ ├── LanguageToggle.vue │ │ ├── MenuButton.vue │ │ ├── ModalHeader.vue │ │ ├── Notify.vue │ │ ├── PromptModal/ │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── SDropdown.vue │ │ ├── SearchBreadcrumb.vue │ │ ├── SortableList.vue │ │ ├── TableDraggable.vue │ │ ├── TextHighlight.vue │ │ ├── ThemeToggle.vue │ │ ├── Toc.vue │ │ └── message/ │ │ ├── Index.vue │ │ └── index.ts │ ├── i18n/ │ │ ├── en-US/ │ │ │ ├── admin.ts │ │ │ ├── ai.ts │ │ │ ├── attachment.ts │ │ │ ├── catalog.ts │ │ │ ├── common.ts │ │ │ ├── feedback.ts │ │ │ ├── header.ts │ │ │ ├── index.ts │ │ │ ├── item.ts │ │ │ ├── itemSetting.ts │ │ │ ├── main.ts │ │ │ ├── message.ts │ │ │ ├── page.ts │ │ │ ├── pageComment.ts │ │ │ ├── pageFeedback.ts │ │ │ ├── team.ts │ │ │ ├── time.ts │ │ │ ├── user.ts │ │ │ └── wechat.ts │ │ ├── index.ts │ │ └── zh-CN/ │ │ ├── admin.ts │ │ ├── ai.ts │ │ ├── attachment.ts │ │ ├── catalog.ts │ │ ├── common.ts │ │ ├── feedback.ts │ │ ├── header.ts │ │ ├── index.ts │ │ ├── item.ts │ │ ├── itemSetting.ts │ │ ├── main.ts │ │ ├── message.ts │ │ ├── page.ts │ │ ├── pageComment.ts │ │ ├── pageFeedback.ts │ │ ├── team.ts │ │ ├── time.ts │ │ ├── user.ts │ │ └── wechat.ts │ ├── main.ts │ ├── models/ │ │ ├── admin.ts │ │ ├── attachment.ts │ │ ├── item.ts │ │ ├── itemGroup.ts │ │ ├── itemTree.ts │ │ ├── markdown.ts │ │ ├── member.ts │ │ ├── message.ts │ │ ├── page.ts │ │ ├── pageComment.ts │ │ ├── pageFeedback.ts │ │ ├── publicSquare.ts │ │ ├── recycle.ts │ │ ├── subscription.ts │ │ ├── team.ts │ │ └── user.ts │ ├── router/ │ │ └── index.ts │ ├── store/ │ │ ├── app.ts │ │ ├── index.ts │ │ ├── item.ts │ │ └── user.ts │ ├── styles/ │ │ ├── antdv.scss │ │ ├── index.scss │ │ ├── runapi-base.scss │ │ ├── utilities.scss │ │ ├── variables.scss │ │ └── vue-json-pretty.scss │ ├── utils/ │ │ ├── clientId.ts │ │ ├── icon.ts │ │ ├── language.ts │ │ ├── modalAppFactory.ts │ │ ├── request.ts │ │ ├── system.ts │ │ ├── template.ts │ │ └── tools.ts │ ├── views/ │ │ ├── admin/ │ │ │ ├── Index.vue │ │ │ ├── components/ │ │ │ │ ├── AboutSite.vue │ │ │ │ ├── AdminLayout.vue │ │ │ │ ├── AnnouncementManagement.vue │ │ │ │ ├── AttachmentManagement.vue │ │ │ │ ├── ExtLogin.vue │ │ │ │ ├── ItemManagement.vue │ │ │ │ ├── RecommendManagement.vue │ │ │ │ ├── SystemSettings.vue │ │ │ │ ├── UserManagement.vue │ │ │ │ └── VisitManagement.vue │ │ │ └── modals/ │ │ │ ├── AddKeywordModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── AddMemberToItemModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── AddWhitelistModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── AttornItemModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── BanItemModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── BanUserModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── EditUserModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── LoginLogModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── MemberManageModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── TransferAttachmentModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ └── ViewTeamMembersModal/ │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── attachment/ │ │ │ └── Index.vue │ │ ├── item/ │ │ │ ├── components/ │ │ │ │ ├── ItemHeader.vue │ │ │ │ └── MobileHeader.vue │ │ │ ├── export/ │ │ │ │ └── Index.vue │ │ │ ├── home/ │ │ │ │ ├── HeaderRight.vue │ │ │ │ ├── Index.vue │ │ │ │ ├── ItemAdd.vue │ │ │ │ ├── ItemCardList.vue │ │ │ │ ├── ItemGroup.vue │ │ │ │ ├── ItemList.vue │ │ │ │ └── Search.vue │ │ │ ├── password/ │ │ │ │ └── Index.vue │ │ │ ├── setting/ │ │ │ │ ├── Index.vue │ │ │ │ └── Member.vue │ │ │ └── show/ │ │ │ ├── Index.vue │ │ │ ├── ShowRegularItem/ │ │ │ │ ├── CatalogActions.vue │ │ │ │ ├── CatalogTree.vue │ │ │ │ ├── HeaderRight.vue │ │ │ │ ├── components/ │ │ │ │ │ ├── PageComment.vue │ │ │ │ │ └── PageFeedback.vue │ │ │ │ └── index.vue │ │ │ ├── ShowSinglePageItem/ │ │ │ │ ├── HeaderRight.vue │ │ │ │ └── index.vue │ │ │ ├── ShowTableItem/ │ │ │ │ ├── HeaderRight.vue │ │ │ │ └── index.vue │ │ │ └── ShowWhiteboardItem/ │ │ │ ├── HeaderRight.vue │ │ │ ├── Toolbar.vue │ │ │ ├── index.vue │ │ │ └── utils/ │ │ │ ├── canvasHistory.ts │ │ │ ├── canvasImportExport.ts │ │ │ ├── canvasInit.ts │ │ │ ├── canvasPanZoom.ts │ │ │ ├── canvasShapes.ts │ │ │ ├── canvasSize.ts │ │ │ ├── canvasTools.ts │ │ │ └── fabricLoader.ts │ │ ├── landing/ │ │ │ ├── Index.vue │ │ │ ├── LandingFooter.vue │ │ │ ├── LandingHeader.vue │ │ │ ├── illustrations/ │ │ │ │ ├── ApiDocumentIllustration.vue │ │ │ │ ├── AutoGenerateIllustration.vue │ │ │ │ ├── DataDictionaryIllustration.vue │ │ │ │ ├── HeroIllustration.vue │ │ │ │ ├── IntegrationIllustration.vue │ │ │ │ └── TeamCollaborationIllustration.vue │ │ │ └── landing-common.scss │ │ ├── message/ │ │ │ └── Index.vue │ │ ├── modals/ │ │ │ ├── attachment/ │ │ │ │ ├── AttachmentModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ └── UploadModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── catalog/ │ │ │ │ ├── CatalogSelectModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── CopyCatalogModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── CreateCatalogModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ └── SelectCatalogModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── common/ │ │ │ │ └── FeedbackModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── item/ │ │ │ │ ├── AddMemberModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AddTeamMemberModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AddTeamModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AiKnowledgeBaseModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ArchiveModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AttornModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AttornTeamModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── BindItemModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ChangeLogModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── CopyItemModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── CreateItemModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── DeleteModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ExportFileModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ImportFileModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ImportOpenApiModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── MemberModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── OpenApiModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── RecycleModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── ShareModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── TeamItemMemberModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── TeamItemModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── TeamMemberAuthorityModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ └── TeamMemberModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── message/ │ │ │ │ └── MessageModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── page/ │ │ │ │ ├── AIModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AttachmentListModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── AttachmentModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── EditPageModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── FilehubModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── FilehubUploadModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── HistoryModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── InterfaceListModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── JsonBeautifyModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── JsonToTableModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── MockModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── NotifyModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── PasteTableModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── SaveTemplateModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── SqlToMarkdownModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── TemplateSelectModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── UploadModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── team/ │ │ │ │ └── TeamModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ └── user/ │ │ │ ├── AiTokenModal/ │ │ │ │ ├── CreateTokenModal/ │ │ │ │ │ ├── index.ts │ │ │ │ │ └── index.vue │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── DeleteAccountModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── EmailModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── MobileModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── PasswordModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── PaymentVerifyModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── PushUrlModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── UnbindMobileModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ ├── UserCenterModal/ │ │ │ │ ├── index.ts │ │ │ │ └── index.vue │ │ │ └── WechatModal/ │ │ │ ├── index.ts │ │ │ └── index.vue │ │ ├── page/ │ │ │ ├── diff/ │ │ │ │ └── Index.vue │ │ │ ├── edit/ │ │ │ │ └── Index.vue │ │ │ └── show/ │ │ │ └── Index.vue │ │ ├── public-square/ │ │ │ └── Index.vue │ │ ├── team/ │ │ │ ├── Index.vue │ │ │ ├── Item.vue │ │ │ └── Member.vue │ │ └── user/ │ │ ├── Login.vue │ │ ├── LoginByUserToken.vue │ │ ├── Register.vue │ │ ├── ResetPassword.vue │ │ ├── ResetPasswordByUrl.vue │ │ ├── Setting.vue │ │ ├── VerifyEmailByUrl.vue │ │ └── WechatModal/ │ │ ├── index.ts │ │ └── index.vue │ └── vite-env.d.ts ├── tsconfig.json ├── tsconfig.node.json └── vite.config.ts ================================================ FILE CONTENTS ================================================ ================================================ FILE: .dockerignore ================================================ .dockerignore .github .gitignore Dockerfile* docker-compose.yml showdocdata/ .git/ Application/Runtime/ server/Application/Runtime/ web_src/.DS_Store web_src/node_modules/ web_src/dist/ web_src/npm-debug.log* web_src/yarn-debug.log* web_src/yarn-error.log* web_src//test/unit/coverage/ web_src//test/e2e/reports/ web_src/selenium-debug.log # Editor directories and files web_src/.idea web_src/.vscode web_src/*.suo web_src/*.ntvs* web_src/*.njsproj web_src/*.sln ================================================ FILE: .github/workflows/docker-arm.yml ================================================ name: ci on: push: branches: - "master" jobs: docker: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to DockerHub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v4 with: context: . push: true tags: star7th/showdoc:arm-latest file: Dockerfile.ARM platforms: | linux/arm/v7 linux/arm64 ================================================ FILE: .github/workflows/docker-release.yml ================================================ name: Build and push Docker image on: release: types: [published] jobs: build-and-push: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to DockerHub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v4 with: context: . push: true tags: star7th/showdoc:${{ github.event.release.tag_name }} ================================================ FILE: .github/workflows/docker.yml ================================================ name: ci on: push: branches: - "master" jobs: docker: runs-on: ubuntu-latest steps: - name: Checkout uses: actions/checkout@v3 - name: Set up QEMU uses: docker/setup-qemu-action@v2 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - name: Login to DockerHub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} - name: Build and push uses: docker/build-push-action@v4 with: context: . push: true tags: star7th/showdoc:latest ================================================ FILE: .gitignore ================================================ Application/Runtime/ server/Application/Runtime/ web_src/.DS_Store web_src/node_modules/ web_src/dist/ web_src/npm-debug.log* web_src/yarn-debug.log* web_src/yarn-error.log* web_src//test/unit/coverage/ web_src//test/e2e/reports/ web_src/selenium-debug.log # Editor directories and files web_src/.idea web_src/.vscode web_src/*.suo web_src/*.ntvs* web_src/*.njsproj web_src/*.sln showdocdata/ /server/app/Runtime/mcp_rate_limit ================================================ FILE: .htaccess ================================================ Options +FollowSymlinks RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteCond $1 !^(index\.php|robots\.txt|favicon\.ico) RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] ================================================ FILE: Dockerfile ================================================ FROM webdevops/php-nginx:8.3-alpine ## 构建时环境变量 docker build --build-arg=IN_CHINA=true . ARG IN_CHINA=false # 环境变量 ENV SHOWDOC_DOCKER_VERSION=3.4.1 ENV IN_CHINA=${IN_CHINA} WORKDIR /showdoc_data/html COPY . . RUN bash docker.run.sh --build CMD ["bash", "docker.run.sh"] ================================================ FILE: Dockerfile.ARM ================================================ FROM wordpress:php8.1 COPY ./ /var/www/html/ RUN mkdir -p /showdoc_data/html RUN cp -R /var/www/html/ /showdoc_data/ RUN rm -rf /usr/src/wordpress COPY ./ /usr/src/wordpress RUN echo "" > /var/www/html/web/index.php RUN chmod -R 777 /var/www/html/ # 写环境变量 ENV SHOWDOC_DOCKER_VERSION 2.8 ENV SHOWDOC_DOCKER_ARM 1 ================================================ FILE: LICENSE.txt ================================================  ShowDoc遵循Apache2开源协议发布。 ShowDoc在遵循Apache2开源协议之上有一条额外版权声明: showdoc官方(https://www.showdoc.com.cn/)以及作者star7th ( https://github.com/star7th )拥有程序的版权和相应权利, 在保留程序UI界面上的版权信息和链接的前提下,可免费使用或者二次开发 如需更改版权信息或版权链接,需取得官方同意授权。 Apache Licence是著名的非盈利开源组织Apache采用的协议。 该协议和BSD类似,鼓励代码共享和尊重原作者的著作权, 允许代码修改,再作为开源或商业软件发布。需要满足 的条件: 1. 需要给代码的用户一份Apache Licence ; 2. 如果你修改了代码,需要在被修改的文件中说明; 3. 在延伸的代码中(修改和有源代码衍生的代码中)需要 带有原来代码中的协议,商标,专利声明和其他原来作者规 定需要包含的说明; 4. 如果再发布的产品中包含一个Notice文件,则在Notice文 件中需要带有本协议内容。你可以在Notice中增加自己的 许可,但不可以表现为对Apache Licence构成更改。 具体的协议参考:http://www.apache.org/licenses/LICENSE-2.0 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. Showdoc has an additional copyright notice on compliance with the Apache2 Open Source License: Showdoc official( https://www.showdoc.com.cn/ )And author star7th( https://github.com/star7th )Have the copyright and corresponding rights of the program, On the premise of retaining the copyright information and links on the program UI interface, it can be used for free or secondary development If you need to change copyright information or copyright links, you need to obtain official consent and authorization. ================================================ FILE: Public/README.md ================================================ 资源文件目录 ================================================ FILE: Public/Uploads/index.html ================================================ ================================================ FILE: Public/css/index.css ================================================ body { padding-top: 20px; padding-bottom: 40px; } /* Custom container */ .container-narrow { margin: 0 auto; max-width: 700px; } .container-narrow > hr { margin: 30px 0; } /* Main marketing message and sign up button */ .jumbotron { margin: 60px 0; text-align: center; } .jumbotron h1 { font-size: 72px; line-height: 1; } .jumbotron .btn { font-size: 21px; padding: 14px 24px; } /* Supporting marketing content */ .marketing { margin: 60px 0; } .marketing p + h4 { margin-top: 28px; } .markdown-body pre { background-color: #f0f0f0; } ================================================ FILE: Public/css/item/index.css ================================================ body { padding-top: 20px; padding-bottom: 40px; } /* Custom container */ .container-narrow { margin: 0 auto; max-width: 700px; } .container-narrow > hr { margin: 30px 0; } .my-item{ margin: 40px 10px; } .container-thumbnails{ margin-top: 60px; } .thumbnails li a{ color: #777; font-weight: bold; height: 100px; } .thumbnails li a:hover, .thumbnails li a:focus{ border-color:#f2f5e9; -webkit-box-shadow:none; box-shadow:none; text-decoration: none; background-color: #f2f5e9; } .masthead h3{ color: #333; } .item-setting{ float:right; margin-right:15px; margin-top:5px; display: none; } .item-top{ float:right; margin-right:5px; margin-top:5px; display: none; } ================================================ FILE: Public/css/item/show.css ================================================ body,html,.doc-body{ height: 100%; } .doc-head{ padding-top: 5px; padding-bottom: 5px; padding-left: 10px; border-bottom: 1px solid #eee; position: fixed; width: 100%; background-color: #FFFFFF; z-index: 999; height: 40px; } .doc-head .left{ padding-left: 30px; float: left; } .doc-head .right{ padding-top: 10px; padding-right: 40px; } .doc-left{ width: 240px; margin-top: 51px; height: calc(100% - 60px); border-right-color: rgb(221, 221, 221); border-right-width: 1px; border-right-style: solid; overflow-y: auto; display: block; /*background: rgb(245, 245, 245);*/ position: fixed; } .doc-left .form-search{ padding-top: 15px; } .doc-left ul li{ font-size: 16px; line-height: 30px; } .doc-left ul li a{ color: #000; } .doc-left ul li a:hover ,.doc-left ul li a:focus{ color: #fff; text-shadow: 0 -1px 0 rgba(0,0,0,0.2); background-color: #08c; } .doc-right{ margin-top: 81px; margin-left: 260px; } .child-ul{ list-style: none; padding-left: 10px; } .child-ul li a { padding: 3px 15px; margin-right: -15px; margin-left: -15px; text-shadow: 0 1px 0 rgba(255,255,255,0.5); display: block; text-decoration: none; font-size: 14px; line-height: 25px; } .icon-blank{ padding-right: 4px; } .doc-left-newbar{ /*float: right;*/ margin-left: 180px; margin-top: 10px; } .page-edit-link{ padding-top: 10px; } .iframe_content{ padding-left: 20px; padding-right: 20px; width: 80%; max-width: 700px; margin: 0 auto; } .search-query-input{ width: 140px; } .third-child-catalog{ margin-left: -16px; } @media screen and (min-width:500px){ .doc-right{ width: 400px;} } @media screen and (min-width:600px){ .doc-right{ width: 500px;} } @media screen and (min-width:700px){ .doc-right{ width: 600px;} } @media screen and (min-width:800px){ .doc-right{ width: 700px;} } @media screen and (min-width:900px){ .doc-right{ width: 800px;} } @media screen and (min-width:1000px){ .doc-right{ width: 700px;} } @media screen and (min-width:1100px){ .doc-right{ width: 800px;} } @media screen and (min-width:1200px){ .doc-right{ width: 900px;} } @media screen and (min-width:1300px){ .doc-right{ width: 1000px;} } @media screen and (min-width:1400px){ .doc-right{ width: 1100px;} } @media screen and (min-width:1500px){ .doc-right{ width: 1200px;} } @media screen and (min-width:1600px){ .doc-right{ width: 1300px;} } @media screen and (min-width:1700px){ .doc-right{ width: 1400px;} } @media screen and (min-width:1800px){ .doc-right{ width: 1500px;} } @media screen and (min-width:1900px){ .doc-right{ width: 1600px;} } .page-edit-link .btn-link{ padding-right: 4px; padding-left: 4px; margin-right: 0px; margin-left: 0px; } .show_cut_title{ white-space:nowrap; text-overflow:ellipsis; -o-text-overflow:ellipsis; overflow:hidden } .left-dropdown-menu{ left: auto; right: 0; } ================================================ FILE: Public/css/item/show_single_page.css ================================================ body{ background: #F1F0F1; height: auto; overflow: auto; margin: 0 auto; } #page_content{ padding: 11px 0 90px 0; overflow: hidden; font-size: 11pt; line-height: 1.7; color: #333; } #doc-body{ background-color: #fff; } .doc-container { position: static; -webkit-box-shadow: 0px 1px 6px #ccc; -moz-box-shadow: 0px 1px 6px #ccc; -ms-box-shadow: 0px 1px 6px #ccc; -o-box-shadow: 0px 1px 6px #ccc; box-shadow: 0px 1px 6px #ccc; background-color: #fff; border-bottom: 1px solid #d9d9d9; margin-bottom: 20px; width: 800px; min-height: 500px; } #header{ height: 80px; } #doc-body{ width: 600px; margin: 0 auto; } .doc-title-box{ height: auto; margin: 30px 100px 10px 100px; width: auto; border-bottom: 1px solid #ebebeb; padding-bottom: 10px; } #footer{ margin: 0 auto; width: 180px; font-size: 8px; color: #959595; } #doc-title{ display: inline-block; } .tool-bar{ font-size: 14px; padding-top: 15px; } .tool-bar .btn-link{ padding: 0px; } .linenums li { list-style-type: none; line-height: 20px; } .markdown-body pre { background-color: #fcfcfc; border: 1px solid #e1e1e8; } .hljs{ padding:0.2em; background-color: #fcfcfc; } ================================================ FILE: Public/css/jquery.fullPage.css ================================================ /** * fullPage 2.4.6 * https://github.com/alvarotrigo/fullPage.js * MIT licensed * * Copyright (C) 2013 alvarotrigo.com - A project by Alvaro Trigo */ html, body { margin: 0; padding: 0; overflow:hidden; /*Avoid flicker on slides transitions for mobile phones #336 */ -webkit-tap-highlight-color: rgba(0,0,0,0); } #superContainer { height: 100%; position: relative; /* Touch detection for Windows 8 */ -ms-touch-action: none; /* IE 11 on Windows Phone 8.1*/ touch-action: none; } .fp-section { position: relative; -webkit-box-sizing: border-box; /* Safari<=5 Android<=3 */ -moz-box-sizing: border-box; /* <=28 */ box-sizing: border-box; } .fp-slide { float: left; } .fp-slide, .fp-slidesContainer { height: 100%; display: block; } .fp-slides { z-index:1; height: 100%; overflow: hidden; position: relative; -webkit-transition: all 0.3s ease-out; /* Safari<=6 Android<=4.3 */ transition: all 0.3s ease-out; } .fp-section.fp-table, .fp-slide.fp-table { display: table; table-layout:fixed; width: 100%; } .fp-tableCell { display: table-cell; vertical-align: middle; width: 100%; height: 100%; } .fp-slidesContainer { float: left; position: relative; } .fp-controlArrow { position: absolute; z-index: 4; top: 50%; cursor: pointer; width: 0; height: 0; border-style: solid; margin-top: -38px; } .fp-controlArrow.fp-prev { left: 15px; width: 0; border-width: 38.5px 34px 38.5px 0; border-color: transparent #fff transparent transparent; } .fp-controlArrow.fp-next { right: 15px; border-width: 38.5px 0 38.5px 34px; border-color: transparent transparent transparent #fff; } .fp-scrollable { overflow: scroll; } .fp-notransition { -webkit-transition: none !important; transition: none !important; } #fp-nav { position: fixed; z-index: 100; margin-top: -32px; top: 50%; opacity: 1; } #fp-nav.right { right: 17px; } #fp-nav.left { left: 17px; } .fp-slidesNav{ position: absolute; z-index: 4; left: 50%; opacity: 1; } .fp-slidesNav.bottom { bottom: 17px; } .fp-slidesNav.top { top: 17px; } #fp-nav ul, .fp-slidesNav ul { margin: 0; padding: 0; } #fp-nav ul li, .fp-slidesNav ul li { display: block; width: 14px; height: 13px; margin: 7px; position:relative; } .fp-slidesNav ul li { display: inline-block; } #fp-nav ul li a, .fp-slidesNav ul li a { display: block; position: relative; z-index: 1; width: 100%; height: 100%; cursor: pointer; text-decoration: none; } #fp-nav ul li a.active span, .fp-slidesNav ul li a.active span { background: #333; } #fp-nav ul li a span, .fp-slidesNav ul li a span { top: 2px; left: 2px; width: 8px; height: 8px; border: 1px solid #000; background: rgba(0, 0, 0, 0); border-radius: 50%; position: absolute; z-index: 1; } #fp-nav ul li .fp-tooltip { position: absolute; top: -2px; color: #fff; font-size: 14px; font-family: arial, helvetica, sans-serif; white-space: nowrap; max-width: 220px; overflow: hidden; display: block; opacity: 0; width: 0; } #fp-nav ul li:hover .fp-tooltip { -webkit-transition: opacity 0.2s ease-in; transition: opacity 0.2s ease-in; width: auto; opacity: 1; } #fp-nav ul li .fp-tooltip.right { right: 20px; } #fp-nav ul li .fp-tooltip.left { left: 20px; } ================================================ FILE: Public/css/login.css ================================================ body { padding-top: 40px; padding-bottom: 40px; background-color: #f5f5f5; } .form-signin { max-width: 300px; padding: 19px 29px 29px; margin: 0 auto 20px; background-color: #fff; border: 1px solid #e5e5e5; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; -webkit-box-shadow: 0 1px 2px rgba(0,0,0,.05); -moz-box-shadow: 0 1px 2px rgba(0,0,0,.05); box-shadow: 0 1px 2px rgba(0,0,0,.05); } .form-signin .form-signin-heading, .form-signin .checkbox { margin-bottom: 10px; } .form-signin input[type="text"], .form-signin input[type="password"] { font-size: 16px; height: auto; margin-bottom: 15px; padding: 7px 9px; } .container{ margin-top: 5%; } .card{ width: 330px; position : absolute; top : 50%; left : 50%; transform : translate(-50%,-50%); padding-top: 30px; padding-left: 45px; padding-right: 45px; padding-bottom: 30px; background-color: #fff; box-sizing: border-box; } .heading{ text-align: center; padding-bottom: 20px ================================================ FILE: Public/css/page/edit.css ================================================ * { padding: 0; margin: 0; } *, *:before, *:after { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; } body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td,hr,button,article,aside,details,figcaption,figure,footer,header,hgroup,menu,nav,section{ margin: 0; padding: 0; } article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section, summary { display: block; } audio, canvas, video { display: inline-block; } img { border: none; vertical-align: middle; } ul, ol { /*list-style: none;*/ } .clear { *zoom: 1; /* for IE 6/7 */ } .clear:before, .clear:after { height: 0; content: ""; font-size: 0; display: table; line-height: 0; /* for Opera */ visibility: hidden; } .clear:after { clear: both; } body { font-size: 14px; color: #666; font-family: "Microsoft YaHei", "微软雅黑", Helvetica, Tahoma, STXihei, "华文细黑", STHeiti, "Helvetica Neue", Helvetica, Tahoma, "Droid Sans", "wenquanyi micro hei", FreeSans, Arimo, Arial, SimSun, "宋体", Heiti, "黑体", sans-serif; background: #fff; text-align: center; } #layout { text-align: left; } #layout > header, .btns { padding: 15px 0; width: 90%; margin: 0 auto; } .btns { padding-top: 0; } .btns button { padding: 2px 8px; } #layout > header > h1 { font-size: 20px; margin-bottom: 10px; } .btns button, .btn { padding: 8px 10px; background: #fff; border: 1px solid #ddd; -webkit-border-radius: 3px; border-radius: 3px; cursor: pointer; -webkit-transition: background 300ms ease-out; transition: background 300ms ease-out; } .btns button:hover, .btn:hover { background: #f6f6f6; } #json-templ,#beautify-json-dialog{ position:fixed; float:left; top:100px; left:300px; border:2px solid #ccc; display:none; z-index:999999;} .markdown-body.editormd-preview-container table tr td{ max-width:300px;} .btn-primary { background-color: #006dcc; } .btn-primary:hover { background-color: #04c; } #page_title, #cat_id, #order { height: 30px; } #cat_id ,#parent_cat_id { width: 120px; } #s_number { width: 120px; margin-right: 20px; height: 28px; } ol.linenums li { list-style-type: none !important; } ================================================ FILE: Public/css/page/index.css ================================================ h3{ font-size: 1.5em; } body{ overflow-x:hidden;overflow-y:hidden; font-size: 1rem; line-height: 1.7em; } p{ margin: 0 0 20px; } li{ line-height: 30px; } .linenums li{ list-style-type:none; line-height: 20px; } #page_md_content{ padding-top:10px; word-break: break-all; } .hljs{ padding:0.2em; background-color: #fcfcfc; } #page_title{ text-align: left; border-bottom: 1px solid #d9d9d9; padding-top: 30px; padding-bottom: 20px } .markdown-body pre { background-color: #fcfcfc; border: 1px solid #e1e1e8; } ================================================ FILE: Public/css/showdoc.css ================================================ @charset "utf-8"; body { font:14px/1.5 "Microsoft Yahei","微软雅黑",Tahoma,Arial,Helvetica,STHeiti; } .btn-primary{ background-color: #08c !important; background-image: linear-gradient(to bottom,#08c,#08c); } .btn-primary:active{ background-color: #07c !important; } .btn-primary:hover{ background-color: #07c !important; background-image: linear-gradient(to bottom,#07c,#07c); } /*定义滚动条高宽及背景 高宽分别对应横竖滚动条的尺寸*/ ::-webkit-scrollbar { width: 7px; height: 10px; background-color: rgba(0, 0, 0, 0.1); } /*定义滑块 内阴影+圆角*/ ::-webkit-scrollbar-thumb { background-color: rgba(0, 0, 0, 0.3); -webkit-border-radius:6px; -moz-border-radius: 6px; -ms-border-radius: 6px; -o-border-radius: 6px; border-radius: 6px; } ================================================ FILE: Public/css/tab-tpl.css ================================================ body{ background: #F1F0F1; height: auto; overflow: auto; margin: 0 auto; } .tab-doc-content{ padding: 11px 0 90px 0; overflow: hidden; font-size: 11pt; line-height: 1.7; color: #333; } .tab-doc-body{ background-color: #fff; width: 600px; margin: 0 auto; } .tab-doc-container { position: static; -webkit-box-shadow: 0px 1px 6px #ccc; -moz-box-shadow: 0px 1px 6px #ccc; -ms-box-shadow: 0px 1px 6px #ccc; -o-box-shadow: 0px 1px 6px #ccc; box-shadow: 0px 1px 6px #ccc; background-color: #fff; border-bottom: 1px solid #d9d9d9; margin-bottom: 20px; width: 800px; min-height: 500px; } .tab-header{ height: 40px; } .tab-doc-title-box{ height: auto; margin: 30px 100px 10px 100px; width: auto; /*border-bottom: 1px solid #ebebeb;*/ padding-bottom: 10px; } ================================================ FILE: Public/diff/difflib.js ================================================ /*** This is part of jsdifflib v1.0. Copyright (c) 2007, Snowtide Informatics Systems, Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the Snowtide Informatics Systems nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ***/ /* Author: Chas Emerick */ __whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true}; difflib = { defaultJunkFunction: function (c) { return __whitespace.hasOwnProperty(c); }, stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); }, stringAsLines: function (str) { var lfpos = str.indexOf("\n"); var crpos = str.indexOf("\r"); var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r"; var lines = str.split(linebreak); for (var i = 0; i < lines.length; i++) { lines[i] = difflib.stripLinebreaks(lines[i]); } return lines; }, // iteration-based reduce implementation __reduce: function (func, list, initial) { if (initial != null) { var value = initial; var idx = 0; } else if (list) { var value = list[0]; var idx = 1; } else { return null; } for (; idx < list.length; idx++) { value = func(value, list[idx]); } return value; }, // comparison function for sorting lists of numeric tuples __ntuplecomp: function (a, b) { var mlen = Math.max(a.length, b.length); for (var i = 0; i < mlen; i++) { if (a[i] < b[i]) return -1; if (a[i] > b[i]) return 1; } return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1); }, __calculate_ratio: function (matches, length) { return length ? 2.0 * matches / length : 1.0; }, // returns a function that returns true if a key passed to the returned function // is in the dict (js object) provided to this function; replaces being able to // carry around dict.has_key in python... __isindict: function (dict) { return function (key) { return dict.hasOwnProperty(key); }; }, // replacement for python's dict.get function -- need easy default values __dictget: function (dict, key, defaultValue) { return dict.hasOwnProperty(key) ? dict[key] : defaultValue; }, SequenceMatcher: function (a, b, isjunk) { this.set_seqs = function (a, b) { this.set_seq1(a); this.set_seq2(b); } this.set_seq1 = function (a) { if (a == this.a) return; this.a = a; this.matching_blocks = this.opcodes = null; } this.set_seq2 = function (b) { if (b == this.b) return; this.b = b; this.matching_blocks = this.opcodes = this.fullbcount = null; this.__chain_b(); } this.__chain_b = function () { var b = this.b; var n = b.length; var b2j = this.b2j = {}; var populardict = {}; for (var i = 0; i < b.length; i++) { var elt = b[i]; if (b2j.hasOwnProperty(elt)) { var indices = b2j[elt]; if (n >= 200 && indices.length * 100 > n) { populardict[elt] = 1; delete b2j[elt]; } else { indices.push(i); } } else { b2j[elt] = [i]; } } for (var elt in populardict) { if (populardict.hasOwnProperty(elt)) { delete b2j[elt]; } } var isjunk = this.isjunk; var junkdict = {}; if (isjunk) { for (var elt in populardict) { if (populardict.hasOwnProperty(elt) && isjunk(elt)) { junkdict[elt] = 1; delete populardict[elt]; } } for (var elt in b2j) { if (b2j.hasOwnProperty(elt) && isjunk(elt)) { junkdict[elt] = 1; delete b2j[elt]; } } } this.isbjunk = difflib.__isindict(junkdict); this.isbpopular = difflib.__isindict(populardict); } this.find_longest_match = function (alo, ahi, blo, bhi) { var a = this.a; var b = this.b; var b2j = this.b2j; var isbjunk = this.isbjunk; var besti = alo; var bestj = blo; var bestsize = 0; var j = null; var j2len = {}; var nothing = []; for (var i = alo; i < ahi; i++) { var newj2len = {}; var jdict = difflib.__dictget(b2j, a[i], nothing); for (var jkey in jdict) { if (jdict.hasOwnProperty(jkey)) { j = jdict[jkey]; if (j < blo) continue; if (j >= bhi) break; newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1; if (k > bestsize) { besti = i - k + 1; bestj = j - k + 1; bestsize = k; } } } j2len = newj2len; } while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { besti--; bestj--; bestsize++; } while (besti + bestsize < ahi && bestj + bestsize < bhi && !isbjunk(b[bestj + bestsize]) && a[besti + bestsize] == b[bestj + bestsize]) { bestsize++; } while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) { besti--; bestj--; bestsize++; } while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) && a[besti + bestsize] == b[bestj + bestsize]) { bestsize++; } return [besti, bestj, bestsize]; } this.get_matching_blocks = function () { if (this.matching_blocks != null) return this.matching_blocks; var la = this.a.length; var lb = this.b.length; var queue = [[0, la, 0, lb]]; var matching_blocks = []; var alo, ahi, blo, bhi, qi, i, j, k, x; while (queue.length) { qi = queue.pop(); alo = qi[0]; ahi = qi[1]; blo = qi[2]; bhi = qi[3]; x = this.find_longest_match(alo, ahi, blo, bhi); i = x[0]; j = x[1]; k = x[2]; if (k) { matching_blocks.push(x); if (alo < i && blo < j) queue.push([alo, i, blo, j]); if (i+k < ahi && j+k < bhi) queue.push([i + k, ahi, j + k, bhi]); } } matching_blocks.sort(difflib.__ntuplecomp); var i1 = j1 = k1 = block = 0; var non_adjacent = []; for (var idx in matching_blocks) { if (matching_blocks.hasOwnProperty(idx)) { block = matching_blocks[idx]; i2 = block[0]; j2 = block[1]; k2 = block[2]; if (i1 + k1 == i2 && j1 + k1 == j2) { k1 += k2; } else { if (k1) non_adjacent.push([i1, j1, k1]); i1 = i2; j1 = j2; k1 = k2; } } } if (k1) non_adjacent.push([i1, j1, k1]); non_adjacent.push([la, lb, 0]); this.matching_blocks = non_adjacent; return this.matching_blocks; } this.get_opcodes = function () { if (this.opcodes != null) return this.opcodes; var i = 0; var j = 0; var answer = []; this.opcodes = answer; var block, ai, bj, size, tag; var blocks = this.get_matching_blocks(); for (var idx in blocks) { if (blocks.hasOwnProperty(idx)) { block = blocks[idx]; ai = block[0]; bj = block[1]; size = block[2]; tag = ''; if (i < ai && j < bj) { tag = 'replace'; } else if (i < ai) { tag = 'delete'; } else if (j < bj) { tag = 'insert'; } if (tag) answer.push([tag, i, ai, j, bj]); i = ai + size; j = bj + size; if (size) answer.push(['equal', ai, i, bj, j]); } } return answer; } // this is a generator function in the python lib, which of course is not supported in javascript // the reimplementation builds up the grouped opcodes into a list in their entirety and returns that. this.get_grouped_opcodes = function (n) { if (!n) n = 3; var codes = this.get_opcodes(); if (!codes) codes = [["equal", 0, 1, 0, 1]]; var code, tag, i1, i2, j1, j2; if (codes[0][0] == 'equal') { code = codes[0]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2]; } if (codes[codes.length - 1][0] == 'equal') { code = codes[codes.length - 1]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]; } var nn = n + n; var group = []; var groups = []; for (var idx in codes) { if (codes.hasOwnProperty(idx)) { code = codes[idx]; tag = code[0]; i1 = code[1]; i2 = code[2]; j1 = code[3]; j2 = code[4]; if (tag == 'equal' && i2 - i1 > nn) { group.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]); groups.push(group); group = []; i1 = Math.max(i1, i2-n); j1 = Math.max(j1, j2-n); } group.push([tag, i1, i2, j1, j2]); } } if (group && !(group.length == 1 && group[0][0] == 'equal')) groups.push(group) return groups; } this.ratio = function () { matches = difflib.__reduce( function (sum, triple) { return sum + triple[triple.length - 1]; }, this.get_matching_blocks(), 0); return difflib.__calculate_ratio(matches, this.a.length + this.b.length); } this.quick_ratio = function () { var fullbcount, elt; if (this.fullbcount == null) { this.fullbcount = fullbcount = {}; for (var i = 0; i < this.b.length; i++) { elt = this.b[i]; fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1; } } fullbcount = this.fullbcount; var avail = {}; var availhas = difflib.__isindict(avail); var matches = numb = 0; for (var i = 0; i < this.a.length; i++) { elt = this.a[i]; if (availhas(elt)) { numb = avail[elt]; } else { numb = difflib.__dictget(fullbcount, elt, 0); } avail[elt] = numb - 1; if (numb > 0) matches++; } return difflib.__calculate_ratio(matches, this.a.length + this.b.length); } this.real_quick_ratio = function () { var la = this.a.length; var lb = this.b.length; return _calculate_ratio(Math.min(la, lb), la + lb); } this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction; this.a = this.b = null; this.set_seqs(a, b); } }; ================================================ FILE: Public/diff/diffview.css ================================================ /* This is part of jsdifflib v1.0. Copyright 2007 - 2011 Chas Emerick . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Chas Emerick. */ table.diff { border-collapse:collapse; border:1px solid darkgray; white-space:pre-wrap } table.diff tbody { font-family:Courier, monospace } table.diff tbody th { font-family:verdana,arial,'Bitstream Vera Sans',helvetica,sans-serif; background:#EED; font-size:11px; font-weight:normal; border:1px solid #BBC; color:#886; padding:.3em .5em .1em 2em; text-align:right; vertical-align:top } table.diff thead { border-bottom:1px solid #BBC; background:#EFEFEF; font-family:Verdana } table.diff thead th.texttitle { text-align:left } table.diff tbody td { padding:0px .4em; padding-top:.4em; vertical-align:top; } table.diff .empty { background-color:#DDD; } table.diff .replace { background-color:#FD8 } table.diff .delete { background-color:#E99; } table.diff .skip { background-color:#EFEFEF; border:1px solid #AAA; border-right:1px solid #BBC; } table.diff .insert { background-color:#9E9 } table.diff th.author { text-align:right; border-top:1px solid #BBC; background:#EFEFEF } ================================================ FILE: Public/diff/diffview.js ================================================ /* This is part of jsdifflib v1.0. Copyright 2007 - 2011 Chas Emerick . All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY Chas Emerick ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Chas Emerick OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of Chas Emerick. */ diffview = { /** * Builds and returns a visual diff view. The single parameter, `params', should contain * the following values: * * - baseTextLines: the array of strings that was used as the base text input to SequenceMatcher * - newTextLines: the array of strings that was used as the new text input to SequenceMatcher * - opcodes: the array of arrays returned by SequenceMatcher.get_opcodes() * - baseTextName: the title to be displayed above the base text listing in the diff view; defaults * to "Base Text" * - newTextName: the title to be displayed above the new text listing in the diff view; defaults * to "New Text" * - contextSize: the number of lines of context to show around differences; by default, all lines * are shown * - viewType: if 0, a side-by-side diff view is generated (default); if 1, an inline diff view is * generated */ buildView: function (params) { var baseTextLines = params.baseTextLines; var newTextLines = params.newTextLines; var opcodes = params.opcodes; var baseTextName = params.baseTextName ? params.baseTextName : "Base Text"; var newTextName = params.newTextName ? params.newTextName : "New Text"; var contextSize = params.contextSize; var inline = (params.viewType == 0 || params.viewType == 1) ? params.viewType : 0; if (baseTextLines == null) throw "Cannot build diff view; baseTextLines is not defined."; if (newTextLines == null) throw "Cannot build diff view; newTextLines is not defined."; if (!opcodes) throw "Canno build diff view; opcodes is not defined."; function celt (name, clazz) { var e = document.createElement(name); e.className = clazz; return e; } function telt (name, text) { var e = document.createElement(name); e.appendChild(document.createTextNode(text)); return e; } function ctelt (name, clazz, text) { var e = document.createElement(name); e.className = clazz; e.appendChild(document.createTextNode(text)); return e; } var tdata = document.createElement("thead"); var node = document.createElement("tr"); tdata.appendChild(node); if (inline) { node.appendChild(document.createElement("th")); node.appendChild(document.createElement("th")); node.appendChild(ctelt("th", "texttitle", baseTextName + " vs. " + newTextName)); } else { node.appendChild(document.createElement("th")); node.appendChild(ctelt("th", "texttitle", baseTextName)); node.appendChild(document.createElement("th")); node.appendChild(ctelt("th", "texttitle", newTextName)); } tdata = [tdata]; var rows = []; var node2; /** * Adds two cells to the given row; if the given row corresponds to a real * line number (based on the line index tidx and the endpoint of the * range in question tend), then the cells will contain the line number * and the line of text from textLines at position tidx (with the class of * the second cell set to the name of the change represented), and tidx + 1 will * be returned. Otherwise, tidx is returned, and two empty cells are added * to the given row. */ function addCells (row, tidx, tend, textLines, change) { if (tidx < tend) { row.appendChild(telt("th", (tidx + 1).toString())); row.appendChild(ctelt("td", change, textLines[tidx].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0"))); return tidx + 1; } else { row.appendChild(document.createElement("th")); row.appendChild(celt("td", "empty")); return tidx; } } function addCellsInline (row, tidx, tidx2, textLines, change) { row.appendChild(telt("th", tidx == null ? "" : (tidx + 1).toString())); row.appendChild(telt("th", tidx2 == null ? "" : (tidx2 + 1).toString())); row.appendChild(ctelt("td", change, textLines[tidx != null ? tidx : tidx2].replace(/\t/g, "\u00a0\u00a0\u00a0\u00a0"))); } for (var idx = 0; idx < opcodes.length; idx++) { code = opcodes[idx]; change = code[0]; var b = code[1]; var be = code[2]; var n = code[3]; var ne = code[4]; var rowcnt = Math.max(be - b, ne - n); var toprows = []; var botrows = []; for (var i = 0; i < rowcnt; i++) { // jump ahead if we've alredy provided leading context or if this is the first range if (contextSize && opcodes.length > 1 && ((idx > 0 && i == contextSize) || (idx == 0 && i == 0)) && change=="equal") { var jump = rowcnt - ((idx == 0 ? 1 : 2) * contextSize); if (jump > 1) { toprows.push(node = document.createElement("tr")); b += jump; n += jump; i += jump - 1; node.appendChild(telt("th", "...")); if (!inline) node.appendChild(ctelt("td", "skip", "")); node.appendChild(telt("th", "...")); node.appendChild(ctelt("td", "skip", "")); // skip last lines if they're all equal if (idx + 1 == opcodes.length) { break; } else { continue; } } } toprows.push(node = document.createElement("tr")); if (inline) { if (change == "insert") { addCellsInline(node, null, n++, newTextLines, change); } else if (change == "replace") { botrows.push(node2 = document.createElement("tr")); if (b < be) addCellsInline(node, b++, null, baseTextLines, "delete"); if (n < ne) addCellsInline(node2, null, n++, newTextLines, "insert"); } else if (change == "delete") { addCellsInline(node, b++, null, baseTextLines, change); } else { // equal addCellsInline(node, b++, n++, baseTextLines, change); } } else { b = addCells(node, b, be, baseTextLines, change); n = addCells(node, n, ne, newTextLines, change); } } for (var i = 0; i < toprows.length; i++) rows.push(toprows[i]); for (var i = 0; i < botrows.length; i++) rows.push(botrows[i]); } rows.push(node = ctelt("th", "author", "diff view generated by ")); node.setAttribute("colspan", inline ? 3 : 4); node.appendChild(node2 = telt("a", "jsdifflib")); node2.setAttribute("href", "http://github.com/cemerick/jsdifflib"); tdata.push(node = document.createElement("tbody")); for (var idx in rows) rows.hasOwnProperty(idx) && node.appendChild(rows[idx]); node = celt("table", "diff" + (inline ? " inlinediff" : "")); for (var idx in tdata) tdata.hasOwnProperty(idx) && node.appendChild(tdata[idx]); return node; } }; ================================================ FILE: Public/editor.md/Gulpfile.js ================================================ "use strict"; var os = require("os"); var gulp = require("gulp"); var gutil = require("gulp-util"); var sass = require("gulp-ruby-sass"); var jshint = require("gulp-jshint"); var uglify = require("gulp-uglifyjs"); var rename = require("gulp-rename"); var concat = require("gulp-concat"); var notify = require("gulp-notify"); var header = require("gulp-header"); var minifycss = require("gulp-minify-css"); //var jsdoc = require("gulp-jsdoc"); //var jsdoc2md = require("gulp-jsdoc-to-markdown"); var pkg = require("./package.json"); var dateFormat = require("dateformatter").format; var replace = require("gulp-replace"); pkg.name = "Editor.md"; pkg.today = dateFormat; var headerComment = ["/*", " * <%= pkg.name %>", " *", " * @file <%= fileName(file) %> ", " * @version v<%= pkg.version %> ", " * @description <%= pkg.description %>", " * @license MIT License", " * @author <%= pkg.author %>", " * {@link <%= pkg.homepage %>}", " * @updateTime <%= pkg.today('Y-m-d') %>", " */", "\r\n"].join("\r\n"); var headerMiniComment = "/*! <%= pkg.name %> v<%= pkg.version %> | <%= fileName(file) %> | <%= pkg.description %> | MIT License | By: <%= pkg.author %> | <%= pkg.homepage %> | <%=pkg.today('Y-m-d') %> */\r\n"; var scssTask = function(fileName, path) { path = path || "scss/"; var distPath = "css"; return sass(path + fileName + ".scss", { style: "expanded", sourcemap: false, noCache : true }) .pipe(gulp.dest(distPath)) .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base); return name[1].replace("\\", ""); }})) .pipe(gulp.dest(distPath)) .pipe(rename({ suffix: ".min" })) .pipe(gulp.dest(distPath)) .pipe(minifycss()) .pipe(gulp.dest(distPath)) .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base); return name[1].replace("\\", ""); }})) .pipe(gulp.dest(distPath)) .pipe(notify({ message: fileName + ".scss task completed!" })); }; gulp.task("scss", function() { return scssTask("editormd"); }); gulp.task("scss2", function() { return scssTask("editormd.preview"); }); gulp.task("scss3", function() { return scssTask("editormd.logo"); }); gulp.task("js", function() { return gulp.src("./src/editormd.js") .pipe(jshint("./.jshintrc")) .pipe(jshint.reporter("default")) .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base); return name[1].replace(/[\\\/]?/, ""); }})) .pipe(gulp.dest("./")) .pipe(rename({ suffix: ".min" })) .pipe(uglify()) // {outSourceMap: true, sourceRoot: './'} .pipe(gulp.dest("./")) .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") ); return name[1].replace(/[\\\/]?/, ""); }})) .pipe(gulp.dest("./")) .pipe(notify({ message: "editormd.js task complete" })); }); gulp.task("amd", function() { var replaceText1 = [ 'var cmModePath = "codemirror/mode/";', ' var cmAddonPath = "codemirror/addon/";', '', ' var codeMirrorModules = [', ' "jquery", "marked", "prettify",', ' "katex", "raphael", "underscore", "flowchart", "jqueryflowchart", "sequenceDiagram",', '', ' "codemirror/lib/codemirror",', ' cmModePath + "css/css",', ' cmModePath + "sass/sass",', ' cmModePath + "shell/shell",', ' cmModePath + "sql/sql",', ' cmModePath + "clike/clike",', ' cmModePath + "php/php",', ' cmModePath + "xml/xml",', ' cmModePath + "markdown/markdown",', ' cmModePath + "javascript/javascript",', ' cmModePath + "htmlmixed/htmlmixed",', ' cmModePath + "gfm/gfm",', ' cmModePath + "http/http",', ' cmModePath + "go/go",', ' cmModePath + "dart/dart",', ' cmModePath + "coffeescript/coffeescript",', ' cmModePath + "nginx/nginx",', ' cmModePath + "python/python",', ' cmModePath + "perl/perl",', ' cmModePath + "lua/lua",', ' cmModePath + "r/r", ', ' cmModePath + "ruby/ruby", ', ' cmModePath + "rst/rst",', ' cmModePath + "smartymixed/smartymixed",', ' cmModePath + "vb/vb",', ' cmModePath + "vbscript/vbscript",', ' cmModePath + "velocity/velocity",', ' cmModePath + "xquery/xquery",', ' cmModePath + "yaml/yaml",', ' cmModePath + "erlang/erlang",', ' cmModePath + "jade/jade",', '', ' cmAddonPath + "edit/trailingspace", ', ' cmAddonPath + "dialog/dialog", ', ' cmAddonPath + "search/searchcursor", ', ' cmAddonPath + "search/search", ', ' cmAddonPath + "scroll/annotatescrollbar", ', ' cmAddonPath + "search/matchesonscrollbar", ', ' cmAddonPath + "display/placeholder", ', ' cmAddonPath + "edit/closetag", ', ' cmAddonPath + "fold/foldcode",', ' cmAddonPath + "fold/foldgutter",', ' cmAddonPath + "fold/indent-fold",', ' cmAddonPath + "fold/brace-fold",', ' cmAddonPath + "fold/xml-fold", ', ' cmAddonPath + "fold/markdown-fold",', ' cmAddonPath + "fold/comment-fold", ', ' cmAddonPath + "mode/overlay", ', ' cmAddonPath + "selection/active-line", ', ' cmAddonPath + "edit/closebrackets", ', ' cmAddonPath + "display/fullscreen",', ' cmAddonPath + "search/match-highlighter"', ' ];', '', ' define(codeMirrorModules, factory);' ].join("\r\n"); var replaceText2 = [ "if (typeof define == \"function\" && define.amd) {", " $ = arguments[0];", " marked = arguments[1];", " prettify = arguments[2];", " katex = arguments[3];", " Raphael = arguments[4];", " _ = arguments[5];", " flowchart = arguments[6];", " CodeMirror = arguments[9];", " }" ].join("\r\n"); gulp.src("src/editormd.js") .pipe(rename({ suffix: ".amd" })) .pipe(gulp.dest('./')) .pipe(header(headerComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base); return name[1].replace(/[\\\/]?/, ""); }})) .pipe(gulp.dest("./")) .pipe(replace("/* Require.js define replace */", replaceText1)) .pipe(gulp.dest('./')) .pipe(replace("/* Require.js assignment replace */", replaceText2)) .pipe(gulp.dest('./')) .pipe(rename({ suffix: ".min" })) .pipe(uglify()) //{outSourceMap: true, sourceRoot: './'} .pipe(gulp.dest("./")) .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base + ( (os.platform() === "win32") ? "\\" : "/") ); return name[1].replace(/[\\\/]?/, ""); }})) .pipe(gulp.dest("./")) .pipe(notify({ message: "amd version task complete"})); }); var codeMirror = { path : { src : { mode : "lib/codemirror/mode", addon : "lib/codemirror/addon" }, dist : "lib/codemirror" }, modes : [ "css", "sass", "shell", "sql", "clike", "php", "xml", "markdown", "javascript", "htmlmixed", "gfm", "http", "go", "dart", "coffeescript", "nginx", "python", "perl", "lua", "r", "ruby", "rst", "smartymixed", "vb", "vbscript", "velocity", "xquery", "yaml", "erlang", "jade", ], addons : [ "edit/trailingspace", "dialog/dialog", "search/searchcursor", "search/search", "scroll/annotatescrollbar", "search/matchesonscrollbar", "display/placeholder", "edit/closetag", "fold/foldcode", "fold/foldgutter", "fold/indent-fold", "fold/brace-fold", "fold/xml-fold", "fold/markdown-fold", "fold/comment-fold", "mode/overlay", "selection/active-line", "edit/closebrackets", "display/fullscreen", "search/match-highlighter" ] }; gulp.task("cm-mode", function() { var modes = [ codeMirror.path.src.mode + "/meta.js" ]; for(var i in codeMirror.modes) { var mode = codeMirror.modes[i]; modes.push(codeMirror.path.src.mode + "/" + mode + "/" + mode + ".js"); } return gulp.src(modes) .pipe(concat("modes.min.js")) .pipe(gulp.dest(codeMirror.path.dist)) .pipe(uglify()) // {outSourceMap: true, sourceRoot: codeMirror.path.dist} .pipe(gulp.dest(codeMirror.path.dist)) .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base + "\\"); return (name[1]?name[1]:name[0]).replace(/\\/g, ""); }})) .pipe(gulp.dest(codeMirror.path.dist)) .pipe(notify({ message: "codemirror-mode task complete!" })); }); gulp.task("cm-addon", function() { var addons = []; for(var i in codeMirror.addons) { var addon = codeMirror.addons[i]; addons.push(codeMirror.path.src.addon + "/" + addon + ".js"); } return gulp.src(addons) .pipe(concat("addons.min.js")) .pipe(gulp.dest(codeMirror.path.dist)) .pipe(uglify()) //{outSourceMap: true, sourceRoot: codeMirror.path.dist} .pipe(gulp.dest(codeMirror.path.dist)) .pipe(header(headerMiniComment, {pkg : pkg, fileName : function(file) { var name = file.path.split(file.base + "\\"); return (name[1]?name[1]:name[0]).replace(/\\/g, ""); }})) .pipe(gulp.dest(codeMirror.path.dist)) .pipe(notify({ message: "codemirror-addon.js task complete" })); }); /* gulp.task("jsdoc", function(){ return gulp.src(["./src/editormd.js", "README.md"]) .pipe(jsdoc.parser()) .pipe(jsdoc.generator("./docs/html")); }); gulp.task("jsdoc2md", function() { return gulp.src("src/js/editormd.js") .pipe(jsdoc2md()) .on("error", function(err){ gutil.log(gutil.colors.red("jsdoc2md failed"), err.message); }) .pipe(rename(function(path) { path.extname = ".md"; })) .pipe(gulp.dest("docs/markdown")); }); */ gulp.task("watch", function() { gulp.watch("scss/editormd.scss", ["scss"]); gulp.watch("scss/editormd.preview.scss", ["scss", "scss2"]); gulp.watch("scss/editormd.logo.scss", ["scss", "scss3"]); gulp.watch("src/editormd.js", ["js", "amd"]); }); gulp.task("default", function() { gulp.run("scss"); gulp.run("scss2"); gulp.run("scss3"); gulp.run("js"); gulp.run("amd"); gulp.run("cm-addon"); gulp.run("cm-mode"); }); ================================================ FILE: Public/editor.md/LICENSE ================================================ The MIT License (MIT) Copyright (c) 2015 pandao Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Public/editor.md/README.md ================================================ # Editor.md ![](https://pandao.github.io/editor.md/images/logos/editormd-logo-180x180.png) ![](https://img.shields.io/github/stars/pandao/editor.md.svg) ![](https://img.shields.io/github/forks/pandao/editor.md.svg) ![](https://img.shields.io/github/tag/pandao/editor.md.svg) ![](https://img.shields.io/github/release/pandao/editor.md.svg) ![](https://img.shields.io/github/issues/pandao/editor.md.svg) ![](https://img.shields.io/bower/v/editor.md.svg) **Editor.md** : The open source embeddable online markdown editor (component), based on CodeMirror & jQuery & Marked. ### Features - Support Standard Markdown / CommonMark and GFM (GitHub Flavored Markdown); - Full-featured: Real-time Preview, Image (cross-domain) upload, Preformatted text/Code blocks/Tables insert, Code fold, Search replace, Read only, Themes, Multi-languages, L18n, HTML entities, Code syntax highlighting...; - Markdown Extras : Support [ToC (Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html), [Emoji](https://pandao.github.io/editor.md/examples/emoji.html), [Task lists](https://pandao.github.io/editor.md/examples/task-lists.html), [@Links](https://pandao.github.io/editor.md/examples/@links.html)...; - Compatible with all major browsers (IE8+), compatible Zepto.js and iPad; - Support [decode & fliter of the HTML tags & attributes](https://pandao.github.io/editor.md/examples/html-tags-decode.html); - Support [TeX (LaTeX expressions, Based on KaTeX)](https://pandao.github.io/editor.md/examples/katex.html), [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) and [Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html) of Markdown extended syntax; - Support AMD/CMD (Require.js & Sea.js) Module Loader, and Custom/define editor plugins; [README & Examples (English)](https://pandao.github.io/editor.md/en.html) -------- **Editor.md** 是一款开源的、可嵌入的 Markdown 在线编辑器(组件),基于 CodeMirror、jQuery 和 Marked 构建。 ![editormd-screenshot](https://pandao.github.io/editor.md/examples/images/editormd-screenshot.png "editormd-screenshot") #### 主要特性 - 支持通用 Markdown / CommonMark 和 GFM (GitHub Flavored Markdown) 风格的语法,也可[变身为代码编辑器](https://pandao.github.io/editor.md/examples/change-mode.html); - 支持实时预览、图片(跨域)上传、预格式文本/代码/表格插入、代码折叠、跳转到行、搜索替换、只读模式、自定义样式主题和多语言语法高亮等功能; - 支持 [ToC(Table of Contents)](https://pandao.github.io/editor.md/examples/toc.html)、[Emoji表情](https://pandao.github.io/editor.md/examples/emoji.html)、[Task lists](https://pandao.github.io/editor.md/examples/task-lists.html)、[@链接](https://pandao.github.io/editor.md/examples/@links.html)等 Markdown 扩展语法; - 支持 TeX 科学公式(基于 [KaTeX](https://pandao.github.io/editor.md/examples/katex.html))、流程图 [Flowchart](https://pandao.github.io/editor.md/examples/flowchart.html) 和 [时序图 Sequence Diagram](https://pandao.github.io/editor.md/examples/sequence-diagram.html); - 支持[识别和解析 HTML 标签,并且支持自定义过滤标签及属性解析](https://pandao.github.io/editor.md/examples/html-tags-decode.html),具有可靠的安全性和几乎无限的扩展性; - 支持 AMD / CMD 模块化加载(支持 [Require.js](https://pandao.github.io/editor.md/examples/use-requirejs.html) & [Sea.js](https://pandao.github.io/editor.md/examples/use-seajs.html)),并且支持[自定义扩展插件](https://pandao.github.io/editor.md/examples/define-plugin.html); - 兼容主流的浏览器(IE8+)和 [Zepto.js](https://pandao.github.io/editor.md/examples/use-zepto.html),且支持 iPad 等平板设备; #### Examples [https://pandao.github.io/editor.md/examples/index.html](https://pandao.github.io/editor.md/examples/index.html) #### Download & install [Github download](https://github.com/pandao/editor.md/archive/master.zip) Bower install : ```shell bower install editor.md ``` #### Usages HTML: ```html
``` > Tip: Editor.md can auto append `"); markdownTextarea = this.markdownTextarea = editor.children("textarea"); } markdownTextarea.addClass(classNames.textarea.markdown).attr("placeholder", settings.placeholder); if (typeof markdownTextarea.attr("name") === "undefined" || markdownTextarea.attr("name") === "") { markdownTextarea.attr("name", (settings.name !== "") ? settings.name : id + "-markdown-doc"); } var appendElements = [ (!settings.readOnly) ? "" : "", ( (settings.saveHTMLToTextarea) ? "" : "" ), "
", "
", "
" ].join("\n"); editor.append(appendElements).addClass(classPrefix + "vertical"); if (settings.theme !== "") { editor.addClass(classPrefix + "theme-" + settings.theme); } this.mask = editor.children("." + classPrefix + "mask"); this.containerMask = editor.children("." + classPrefix + "container-mask"); if (settings.markdown !== "") { markdownTextarea.val(settings.markdown); } if (settings.appendMarkdown !== "") { markdownTextarea.val(markdownTextarea.val() + settings.appendMarkdown); } this.htmlTextarea = editor.children("." + classNames.textarea.html); this.preview = editor.children("." + classPrefix + "preview"); this.previewContainer = this.preview.children("." + classPrefix + "preview-container"); if (settings.previewTheme !== "") { this.preview.addClass(classPrefix + "preview-theme-" + settings.previewTheme); } if (typeof define === "function" && define.amd) { if (typeof katex !== "undefined") { editormd.$katex = katex; } if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(settings.path + "codemirror/addon/dialog/dialog"); editormd.loadCSS(settings.path + "codemirror/addon/search/matchesonscrollbar"); } } if ((typeof define === "function" && define.amd) || !settings.autoLoadModules) { if (typeof CodeMirror !== "undefined") { editormd.$CodeMirror = CodeMirror; } if (typeof marked !== "undefined") { editormd.$marked = marked; } this.setCodeMirror().setToolbar().loadedDisplay(); } else { this.loadQueues(); } return this; }, /** * 所需组件加载队列 * Required components loading queue * * @returns {editormd} 返回editormd的实例对象 */ loadQueues : function() { var _this = this; var settings = this.settings; var loadPath = settings.path; var loadFlowChartOrSequenceDiagram = function() { if (editormd.isIE8) { _this.loadedDisplay(); return ; } if (settings.flowChart || settings.sequenceDiagram) { editormd.loadScript(loadPath + "raphael.min", function() { editormd.loadScript(loadPath + "underscore.min", function() { if (!settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); } else if (settings.flowChart && !settings.sequenceDiagram) { editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { _this.loadedDisplay(); }); }); } else if (settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); }); }); } }); }); } else { _this.loadedDisplay(); } }; editormd.loadCSS(loadPath + "codemirror/codemirror.min"); if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(loadPath + "codemirror/addon/dialog/dialog"); editormd.loadCSS(loadPath + "codemirror/addon/search/matchesonscrollbar"); } if (settings.codeFold) { editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); } editormd.loadScript(loadPath + "codemirror/codemirror.min", function() { editormd.$CodeMirror = CodeMirror; editormd.loadScript(loadPath + "codemirror/modes.min", function() { editormd.loadScript(loadPath + "codemirror/addons.min", function() { _this.setCodeMirror(); if (settings.mode !== "gfm" && settings.mode !== "markdown") { _this.loadedDisplay(); return false; } _this.setToolbar(); editormd.loadScript(loadPath + "marked.min", function() { editormd.$marked = marked; if (settings.previewCodeHighlight) { editormd.loadScript(loadPath + "prettify.min", function() { loadFlowChartOrSequenceDiagram(); }); } else { loadFlowChartOrSequenceDiagram(); } }); }); }); }); return this; }, /** * 设置 Editor.md 的整体主题,主要是工具栏 * Setting Editor.md theme * * @returns {editormd} 返回editormd的实例对象 */ setTheme : function(theme) { var editor = this.editor; var oldTheme = this.settings.theme; var themePrefix = this.classPrefix + "theme-"; editor.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); this.settings.theme = theme; return this; }, /** * 设置 CodeMirror(编辑区)的主题 * Setting CodeMirror (Editor area) theme * * @returns {editormd} 返回editormd的实例对象 */ setEditorTheme : function(theme) { var settings = this.settings; settings.editorTheme = theme; if (theme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } this.cm.setOption("theme", theme); return this; }, /** * setEditorTheme() 的别名 * setEditorTheme() alias * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirrorTheme : function (theme) { this.setEditorTheme(theme); return this; }, /** * 设置 Editor.md 的主题 * Setting Editor.md theme * * @returns {editormd} 返回editormd的实例对象 */ setPreviewTheme : function(theme) { var preview = this.preview; var oldTheme = this.settings.previewTheme; var themePrefix = this.classPrefix + "preview-theme-"; preview.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); this.settings.previewTheme = theme; return this; }, /** * 配置和初始化CodeMirror组件 * CodeMirror initialization * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirror : function() { var settings = this.settings; var editor = this.editor; if (settings.editorTheme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } var codeMirrorConfig = { mode : settings.mode, theme : settings.editorTheme, tabSize : settings.tabSize, dragDrop : false, autofocus : settings.autoFocus, autoCloseTags : settings.autoCloseTags, readOnly : (settings.readOnly) ? "nocursor" : false, indentUnit : settings.indentUnit, lineNumbers : settings.lineNumbers, lineWrapping : settings.lineWrapping, extraKeys : { "Ctrl-Q": function(cm) { cm.foldCode(cm.getCursor()); } }, foldGutter : settings.codeFold, gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], matchBrackets : settings.matchBrackets, indentWithTabs : settings.indentWithTabs, styleActiveLine : settings.styleActiveLine, styleSelectedText : settings.styleSelectedText, autoCloseBrackets : settings.autoCloseBrackets, showTrailingSpace : settings.showTrailingSpace, highlightSelectionMatches : ( (!settings.matchWordHighlight) ? false : { showToken: (settings.matchWordHighlight === "onselected") ? false : /\w/ } ) }; this.codeEditor = this.cm = editormd.$CodeMirror.fromTextArea(this.markdownTextarea[0], codeMirrorConfig); this.codeMirror = this.cmElement = editor.children(".CodeMirror"); if (settings.value !== "") { this.cm.setValue(settings.value); } this.codeMirror.css({ fontSize : settings.fontSize, width : (!settings.watch) ? "100%" : "50%" }); if (settings.autoHeight) { this.codeMirror.css("height", "auto"); this.cm.setOption("viewportMargin", Infinity); } if (!settings.lineNumbers) { this.codeMirror.find(".CodeMirror-gutters").css("border-right", "none"); } return this; }, /** * 获取CodeMirror的配置选项 * Get CodeMirror setting options * * @returns {Mixed} return CodeMirror setting option value */ getCodeMirrorOption : function(key) { return this.cm.getOption(key); }, /** * 配置和重配置CodeMirror的选项 * CodeMirror setting options / resettings * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirrorOption : function(key, value) { this.cm.setOption(key, value); return this; }, /** * 添加 CodeMirror 键盘快捷键 * Add CodeMirror keyboard shortcuts key map * * @returns {editormd} 返回editormd的实例对象 */ addKeyMap : function(map, bottom) { this.cm.addKeyMap(map, bottom); return this; }, /** * 移除 CodeMirror 键盘快捷键 * Remove CodeMirror keyboard shortcuts key map * * @returns {editormd} 返回editormd的实例对象 */ removeKeyMap : function(map) { this.cm.removeKeyMap(map); return this; }, /** * 跳转到指定的行 * Goto CodeMirror line * * @param {String|Intiger} line line number or "first"|"last" * @returns {editormd} 返回editormd的实例对象 */ gotoLine : function (line) { var settings = this.settings; if (!settings.gotoLine) { return this; } var cm = this.cm; var editor = this.editor; var count = cm.lineCount(); var preview = this.preview; if (typeof line === "string") { if(line === "last") { line = count; } if (line === "first") { line = 1; } } if (typeof line !== "number") { alert("Error: The line number must be an integer."); return this; } line = parseInt(line) - 1; if (line > count) { alert("Error: The line number range 1-" + count); return this; } cm.setCursor( {line : line, ch : 0} ); var scrollInfo = cm.getScrollInfo(); var clientHeight = scrollInfo.clientHeight; var coords = cm.charCoords({line : line, ch : 0}, "local"); cm.scrollTo(null, (coords.top + coords.bottom - clientHeight) / 2); if (settings.watch) { var cmScroll = this.codeMirror.find(".CodeMirror-scroll")[0]; var height = $(cmScroll).height(); var scrollTop = cmScroll.scrollTop; var percent = (scrollTop / cmScroll.scrollHeight); if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= cmScroll.scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop(preview[0].scrollHeight * percent); } } cm.focus(); return this; }, /** * 扩展当前实例对象,可同时设置多个或者只设置一个 * Extend editormd instance object, can mutil setting. * * @returns {editormd} this(editormd instance object.) */ extend : function() { if (typeof arguments[1] !== "undefined") { if (typeof arguments[1] === "function") { arguments[1] = $.proxy(arguments[1], this); } this[arguments[0]] = arguments[1]; } if (typeof arguments[0] === "object" && typeof arguments[0].length === "undefined") { $.extend(true, this, arguments[0]); } return this; }, /** * 设置或扩展当前实例对象,单个设置 * Extend editormd instance object, one by one * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ set : function (key, value) { if (typeof value !== "undefined" && typeof value === "function") { value = $.proxy(value, this); } this[key] = value; return this; }, /** * 重新配置 * Resetting editor options * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ config : function(key, value) { var settings = this.settings; if (typeof key === "object") { settings = $.extend(true, settings, key); } if (typeof key === "string") { settings[key] = value; } this.settings = settings; this.recreate(); return this; }, /** * 注册事件处理方法 * Bind editor event handle * * @param {String} eventType event type * @param {Function} callback 回调函数 * @returns {editormd} this(editormd instance object.) */ on : function(eventType, callback) { var settings = this.settings; if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = $.proxy(callback, this); } return this; }, /** * 解除事件处理方法 * Unbind editor event handle * * @param {String} eventType event type * @returns {editormd} this(editormd instance object.) */ off : function(eventType) { var settings = this.settings; if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = function(){}; } return this; }, /** * 显示工具栏 * Display toolbar * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ showToolbar : function(callback) { var settings = this.settings; if(settings.readOnly) { return this; } if (settings.toolbar && (this.toolbar.length < 1 || this.toolbar.find("." + this.classPrefix + "menu").html() === "") ) { this.setToolbar(); } settings.toolbar = true; this.toolbar.show(); this.resize(); $.proxy(callback || function(){}, this)(); return this; }, /** * 隐藏工具栏 * Hide toolbar * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} this(editormd instance object.) */ hideToolbar : function(callback) { var settings = this.settings; settings.toolbar = false; this.toolbar.hide(); this.resize(); $.proxy(callback || function(){}, this)(); return this; }, /** * 页面滚动时工具栏的固定定位 * Set toolbar in window scroll auto fixed position * * @returns {editormd} 返回editormd的实例对象 */ setToolbarAutoFixed : function(fixed) { var state = this.state; var editor = this.editor; var toolbar = this.toolbar; var settings = this.settings; if (typeof fixed !== "undefined") { settings.toolbarAutoFixed = fixed; } var autoFixedHandle = function(){ var $window = $(window); var top = $window.scrollTop(); if (!settings.toolbarAutoFixed) { return false; } if (top - editor.offset().top > 10 && top < editor.height()) { toolbar.css({ position : "fixed", width : editor.width() + "px", left : ($window.width() - editor.width()) / 2 + "px" }); } else { toolbar.css({ position : "absolute", width : "100%", left : 0 }); } }; if (!state.fullscreen && !state.preview && settings.toolbar && settings.toolbarAutoFixed) { $(window).bind("scroll", autoFixedHandle); } return this; }, /** * 配置和初始化工具栏 * Set toolbar and Initialization * * @returns {editormd} 返回editormd的实例对象 */ setToolbar : function() { var settings = this.settings; if(settings.readOnly) { return this; } var editor = this.editor; var preview = this.preview; var classPrefix = this.classPrefix; var toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); if (settings.toolbar && toolbar.length < 1) { var toolbarHTML = "
    "; editor.append(toolbarHTML); toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); } if (!settings.toolbar) { toolbar.hide(); return this; } toolbar.show(); var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() : ((typeof settings.toolbarIcons === "string") ? editormd.toolbarModes[settings.toolbarIcons] : settings.toolbarIcons); var toolbarMenu = toolbar.find("." + this.classPrefix + "menu"), menu = ""; var pullRight = false; for (var i = 0, len = icons.length; i < len; i++) { var name = icons[i]; if (name === "||") { pullRight = true; } else if (name === "|") { menu += "
  • |
  • "; } else { var isHeader = (/h(\d)/.test(name)); var index = name; if (name === "watch" && !settings.watch) { index = "unwatch"; } var title = settings.lang.toolbar[index]; var iconTexts = settings.toolbarIconTexts[index]; var iconClass = settings.toolbarIconsClass[index]; title = (typeof title === "undefined") ? "" : title; iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; iconClass = (typeof iconClass === "undefined") ? "" : iconClass; var menuItem = pullRight ? "
  • " : "
  • "; if (typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") { menuItem += settings.toolbarCustomIcons[name]; } else { menuItem += ""; menuItem += ""+((isHeader) ? name.toUpperCase() : ( (iconClass === "") ? iconTexts : "") ) + ""; menuItem += ""; } menuItem += "
  • "; menu = pullRight ? menuItem + menu : menu + menuItem; } } toolbarMenu.html(menu); toolbarMenu.find("[title=\"Lowercase\"]").attr("title", settings.lang.toolbar.lowercase); toolbarMenu.find("[title=\"ucwords\"]").attr("title", settings.lang.toolbar.ucwords); this.setToolbarHandler(); this.setToolbarAutoFixed(); return this; }, /** * 工具栏图标事件处理对象序列 * Get toolbar icons event handlers * * @param {Object} cm CodeMirror的实例对象 * @param {String} name 要获取的事件处理器名称 * @returns {Object} 返回处理对象序列 */ dialogLockScreen : function() { $.proxy(editormd.dialogLockScreen, this)(); return this; }, dialogShowMask : function(dialog) { $.proxy(editormd.dialogShowMask, this)(dialog); return this; }, getToolbarHandles : function(name) { var toolbarHandlers = this.toolbarHandlers = editormd.toolbarHandlers; return (name && typeof toolbarIconHandlers[name] !== "undefined") ? toolbarHandlers[name] : toolbarHandlers; }, /** * 工具栏图标事件处理器 * Bind toolbar icons event handle * * @returns {editormd} 返回editormd的实例对象 */ setToolbarHandler : function() { var _this = this; var settings = this.settings; if (!settings.toolbar || settings.readOnly) { return this; } var toolbar = this.toolbar; var cm = this.cm; var classPrefix = this.classPrefix; var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); var toolbarIconHandlers = this.getToolbarHandles(); toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function(event) { var icon = $(this).children(".fa"); var name = icon.attr("name"); var cursor = cm.getCursor(); var selection = cm.getSelection(); if (name === "") { return ; } _this.activeIcon = icon; if (typeof toolbarIconHandlers[name] !== "undefined") { $.proxy(toolbarIconHandlers[name], _this)(cm); } else { if (typeof settings.toolbarHandlers[name] !== "undefined") { $.proxy(settings.toolbarHandlers[name], _this)(cm, icon, cursor, selection); } } if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") { cm.focus(); } return false; }); return this; }, /** * 动态创建对话框 * Creating custom dialogs * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ createDialog : function(options) { return $.proxy(editormd.createDialog, this)(options); }, /** * 创建关于Editor.md的对话框 * Create about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ createInfoDialog : function() { var _this = this; var editor = this.editor; var classPrefix = this.classPrefix; var infoDialogHTML = [ "
    ", "
    ", "

    " + editormd.title + "v" + editormd.version + "

    ", "

    " + this.lang.description + "

    ", "

    " + editormd.homePage + "

    ", "

    Copyright © 2015 Pandao, The MIT License.

    ", "
    ", "", "
    " ].join("\n"); editor.append(infoDialogHTML); var infoDialog = this.infoDialog = editor.children("." + classPrefix + "dialog-info"); infoDialog.find("." + classPrefix + "dialog-close").bind(editormd.mouseOrTouch("click", "touchend"), function() { _this.hideInfoDialog(); }); infoDialog.css("border", (editormd.isIE8) ? "1px solid #ddd" : "").css("z-index", editormd.dialogZindex).show(); this.infoDialogPosition(); return this; }, /** * 关于Editor.md对话居中定位 * Editor.md dialog position handle * * @returns {editormd} 返回editormd的实例对象 */ infoDialogPosition : function() { var infoDialog = this.infoDialog; var _infoDialogPosition = function() { infoDialog.css({ top : ($(window).height() - infoDialog.height()) / 2 + "px", left : ($(window).width() - infoDialog.width()) / 2 + "px" }); }; _infoDialogPosition(); $(window).resize(_infoDialogPosition); return this; }, /** * 显示关于Editor.md * Display about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ showInfoDialog : function() { $("html,body").css("overflow-x", "hidden"); var _this = this; var editor = this.editor; var settings = this.settings; var infoDialog = this.infoDialog = editor.children("." + this.classPrefix + "dialog-info"); if (infoDialog.length < 1) { this.createInfoDialog(); } this.lockScreen(true); this.mask.css({ opacity : settings.dialogMaskOpacity, backgroundColor : settings.dialogMaskBgColor }).show(); infoDialog.css("z-index", editormd.dialogZindex).show(); this.infoDialogPosition(); return this; }, /** * 隐藏关于Editor.md * Hide about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ hideInfoDialog : function() { $("html,body").css("overflow-x", ""); this.infoDialog.hide(); this.mask.hide(); this.lockScreen(false); return this; }, /** * 锁屏 * lock screen * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {editormd} 返回editormd的实例对象 */ lockScreen : function(lock) { editormd.lockScreen(lock); this.resize(); return this; }, /** * 编辑器界面重建,用于动态语言包或模块加载等 * Recreate editor * * @returns {editormd} 返回editormd的实例对象 */ recreate : function() { var _this = this; var editor = this.editor; var settings = this.settings; this.codeMirror.remove(); this.setCodeMirror(); if (!settings.readOnly) { if (editor.find(".editormd-dialog").length > 0) { editor.find(".editormd-dialog").remove(); } if (settings.toolbar) { this.getToolbarHandles(); this.setToolbar(); } } this.loadedDisplay(true); return this; }, /** * 高亮预览HTML的pre代码部分 * highlight of preview codes * * @returns {editormd} 返回editormd的实例对象 */ previewCodeHighlight : function() { var settings = this.settings; var previewContainer = this.previewContainer; if (settings.previewCodeHighlight) { previewContainer.find("pre").addClass("prettyprint linenums"); if (typeof prettyPrint !== "undefined") { prettyPrint(); } } return this; }, /** * 解析TeX(KaTeX)科学公式 * TeX(KaTeX) Renderer * * @returns {editormd} 返回editormd的实例对象 */ katexRender : function() { if (timer === null) { return this; } this.previewContainer.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); editormd.$katex.render(tex.text(), tex[0]); tex.find(".katex").css("font-size", "1.6em"); }); return this; }, /** * 解析和渲染流程图及时序图 * FlowChart and SequenceDiagram Renderer * * @returns {editormd} 返回editormd的实例对象 */ flowChartAndSequenceDiagramRender : function() { var $this = this; var settings = this.settings; var previewContainer = this.previewContainer; if (editormd.isIE8) { return this; } if (settings.flowChart) { if (flowchartTimer === null) { return this; } previewContainer.find(".flowchart").flowChart(); } if (settings.sequenceDiagram) { previewContainer.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); } var preview = $this.preview; var codeMirror = $this.codeMirror; var codeView = codeMirror.find(".CodeMirror-scroll"); var height = codeView.height(); var scrollTop = codeView.scrollTop(); var percent = (scrollTop / codeView[0].scrollHeight); var tocHeight = 0; preview.find(".markdown-toc-list").each(function(){ tocHeight += $(this).height(); }); var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= codeView[0].scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } return this; }, /** * 注册键盘快捷键处理 * Register CodeMirror keyMaps (keyboard shortcuts). * * @param {Object} keyMap KeyMap key/value {"(Ctrl/Shift/Alt)-Key" : function(){}} * @returns {editormd} return this */ registerKeyMaps : function(keyMap) { var _this = this; var cm = this.cm; var settings = this.settings; var toolbarHandlers = editormd.toolbarHandlers; var disabledKeyMaps = settings.disabledKeyMaps; keyMap = keyMap || null; if (keyMap) { for (var i in keyMap) { if ($.inArray(i, disabledKeyMaps) < 0) { var map = {}; map[i] = keyMap[i]; cm.addKeyMap(keyMap); } } } else { for (var k in editormd.keyMaps) { var _keyMap = editormd.keyMaps[k]; var handle = (typeof _keyMap === "string") ? $.proxy(toolbarHandlers[_keyMap], _this) : $.proxy(_keyMap, _this); if ($.inArray(k, ["F9", "F10", "F11"]) < 0 && $.inArray(k, disabledKeyMaps) < 0) { var _map = {}; _map[k] = handle; cm.addKeyMap(_map); } } $(window).keydown(function(event) { var keymaps = { "120" : "F9", "121" : "F10", "122" : "F11" }; if ( $.inArray(keymaps[event.keyCode], disabledKeyMaps) < 0 ) { switch (event.keyCode) { case 120: $.proxy(toolbarHandlers["watch"], _this)(); return false; break; case 121: $.proxy(toolbarHandlers["preview"], _this)(); return false; break; case 122: $.proxy(toolbarHandlers["fullscreen"], _this)(); return false; break; default: break; } } }); } return this; }, /** * 绑定同步滚动 * * @returns {editormd} return this */ bindScrollEvent : function() { var _this = this; var preview = this.preview; var settings = this.settings; var codeMirror = this.codeMirror; var mouseOrTouch = editormd.mouseOrTouch; if (!settings.syncScrolling) { return this; } var cmBindScroll = function() { codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); var tocHeight = 0; preview.find(".markdown-toc-list").each(function(){ tocHeight += $(this).height(); }); var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= $(this)[0].scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } $.proxy(settings.onscroll, _this)(event); }); }; var cmUnbindScroll = function() { codeMirror.find(".CodeMirror-scroll").unbind(mouseOrTouch("scroll", "touchmove")); }; var previewBindScroll = function() { preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); var codeView = codeMirror.find(".CodeMirror-scroll"); if(scrollTop === 0) { codeView.scrollTop(0); } else if (scrollTop + height >= $(this)[0].scrollHeight) { codeView.scrollTop(codeView[0].scrollHeight); } else { codeView.scrollTop(codeView[0].scrollHeight * percent); } $.proxy(settings.onpreviewscroll, _this)(event); }); }; var previewUnbindScroll = function() { preview.unbind(mouseOrTouch("scroll", "touchmove")); }; codeMirror.bind({ mouseover : cmBindScroll, mouseout : cmUnbindScroll, touchstart : cmBindScroll, touchend : cmUnbindScroll }); if (settings.syncScrolling === "single") { return this; } preview.bind({ mouseover : previewBindScroll, mouseout : previewUnbindScroll, touchstart : previewBindScroll, touchend : previewUnbindScroll }); return this; }, bindChangeEvent : function() { var _this = this; var cm = this.cm; var settings = this.settings; if (!settings.syncScrolling) { return this; } cm.on("change", function(_cm, changeObj) { if (settings.watch) { _this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); } timer = setTimeout(function() { clearTimeout(timer); _this.save(); timer = null; }, settings.delay); }); return this; }, /** * 加载队列完成之后的显示处理 * Display handle of the module queues loaded after. * * @param {Boolean} recreate 是否为重建编辑器 * @returns {editormd} 返回editormd的实例对象 */ loadedDisplay : function(recreate) { recreate = recreate || false; var _this = this; var editor = this.editor; var preview = this.preview; var settings = this.settings; this.containerMask.hide(); this.save(); if (settings.watch) { preview.show(); } editor.data("oldWidth", editor.width()).data("oldHeight", editor.height()); // 为了兼容Zepto this.resize(); this.registerKeyMaps(); $(window).resize(function(){ _this.resize(); }); this.bindScrollEvent().bindChangeEvent(); if (!recreate) { $.proxy(settings.onload, this)(); } this.state.loaded = true; return this; }, /** * 设置编辑器的宽度 * Set editor width * * @param {Number|String} width 编辑器宽度值 * @returns {editormd} 返回editormd的实例对象 */ width : function(width) { this.editor.css("width", (typeof width === "number") ? width + "px" : width); this.resize(); return this; }, /** * 设置编辑器的高度 * Set editor height * * @param {Number|String} height 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ height : function(height) { this.editor.css("height", (typeof height === "number") ? height + "px" : height); this.resize(); return this; }, /** * 调整编辑器的尺寸和布局 * Resize editor layout * * @param {Number|String} [width=null] 编辑器宽度值 * @param {Number|String} [height=null] 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ resize : function(width, height) { width = width || null; height = height || null; var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; if (width) { editor.css("width", (typeof width === "number") ? width + "px" : width); } if (settings.autoHeight && !state.fullscreen && !state.preview) { editor.css("height", "auto"); codeMirror.css("height", "auto"); } else { if (height) { editor.css("height", (typeof height === "number") ? height + "px" : height); } if (state.fullscreen) { editor.height($(window).height()); } if (settings.toolbar && !settings.readOnly) { codeMirror.css("margin-top", toolbar.height() + 1).height(editor.height() - toolbar.height()); } else { codeMirror.css("margin-top", 0).height(editor.height()); } } if(settings.watch) { codeMirror.width(editor.width() / 2); preview.width((!state.preview) ? editor.width() / 2 : editor.width()); this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); if (settings.toolbar && !settings.readOnly) { preview.css("top", toolbar.height() + 1); } else { preview.css("top", 0); } if (settings.autoHeight && !state.fullscreen && !state.preview) { preview.height(""); } else { var previewHeight = (settings.toolbar && !settings.readOnly) ? editor.height() - toolbar.height() : editor.height(); preview.height(previewHeight); } } else { codeMirror.width(editor.width()); preview.hide(); } if (state.loaded) { $.proxy(settings.onresize, this)(); } return this; }, /** * 解析和保存Markdown代码 * Parse & Saving Markdown source code * * @returns {editormd} 返回editormd的实例对象 */ save : function() { if (timer === null) { return this; } var _this = this; var state = this.state; var settings = this.settings; var cm = this.cm; var cmValue = cm.getValue(); var previewContainer = this.previewContainer; if (settings.mode !== "gfm" && settings.mode !== "markdown") { this.markdownTextarea.val(cmValue); return this; } var marked = editormd.$marked; var markdownToC = this.markdownToC = []; var rendererOptions = this.markedRendererOptions = { toc : settings.toc, tocm : settings.tocm, tocStartLevel : settings.tocStartLevel, pageBreak : settings.pageBreak, taskList : settings.taskList, emoji : settings.emoji, tex : settings.tex, atLink : settings.atLink, // for @link emailLink : settings.emailLink, // for mail address auto link flowChart : settings.flowChart, sequenceDiagram : settings.sequenceDiagram, previewCodeHighlight : settings.previewCodeHighlight, }; var markedOptions = this.markedOptions = { renderer : editormd.markedRenderer(markdownToC, rendererOptions), gfm : true, tables : true, breaks : true, pedantic : false, sanitize : (settings.htmlDecode) ? false : true, // 关闭忽略HTML标签,即开启识别HTML标签,默认为false smartLists : true, smartypants : true }; marked.setOptions(markedOptions); var newMarkdownDoc = editormd.$marked(cmValue, markedOptions); //console.info("cmValue", cmValue, newMarkdownDoc); newMarkdownDoc = editormd.filterHTMLTags(newMarkdownDoc, settings.htmlDecode); //console.error("cmValue", cmValue, newMarkdownDoc); this.markdownTextarea.text(cmValue); cm.save(); if (settings.saveHTMLToTextarea) { this.htmlTextarea.text(newMarkdownDoc); } if(settings.watch || (!settings.watch && state.preview)) { previewContainer.html(newMarkdownDoc); this.previewCodeHighlight(); if (settings.toc) { var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); if (settings.tocContainer !== "" && tocMenu.length > 0) { tocMenu.remove(); } editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) { editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); } if (settings.tocContainer !== "") { previewContainer.find(".markdown-toc").css("border", "none"); } } if (settings.tex) { if (!editormd.kaTeXLoaded && settings.autoLoadModules) { editormd.loadKaTeX(function() { editormd.$katex = katex; editormd.kaTeXLoaded = true; _this.katexRender(); }); } else { editormd.$katex = katex; this.katexRender(); } } if (settings.flowChart || settings.sequenceDiagram) { flowchartTimer = setTimeout(function(){ clearTimeout(flowchartTimer); _this.flowChartAndSequenceDiagramRender(); flowchartTimer = null; }, 10); } if (state.loaded) { $.proxy(settings.onchange, this)(); } } return this; }, /** * 聚焦光标位置 * Focusing the cursor position * * @returns {editormd} 返回editormd的实例对象 */ focus : function() { this.cm.focus(); return this; }, /** * 设置光标的位置 * Set cursor position * * @param {Object} cursor 要设置的光标位置键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ setCursor : function(cursor) { this.cm.setCursor(cursor); return this; }, /** * 获取当前光标的位置 * Get the current position of the cursor * * @returns {Cursor} 返回一个光标Cursor对象 */ getCursor : function() { return this.cm.getCursor(); }, /** * 设置光标选中的范围 * Set cursor selected ranges * * @param {Object} from 开始位置的光标键值对象,例:{line:1, ch:0} * @param {Object} to 结束位置的光标键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ setSelection : function(from, to) { this.cm.setSelection(from, to); return this; }, /** * 获取光标选中的文本 * Get the texts from cursor selected * * @returns {String} 返回选中文本的字符串形式 */ getSelection : function() { return this.cm.getSelection(); }, /** * 设置光标选中的文本范围 * Set the cursor selection ranges * * @param {Array} ranges cursor selection ranges array * @returns {Array} return this */ setSelections : function(ranges) { this.cm.setSelections(ranges); return this; }, /** * 获取光标选中的文本范围 * Get the cursor selection ranges * * @returns {Array} return selection ranges array */ getSelections : function() { return this.cm.getSelections(); }, /** * 替换当前光标选中的文本或在当前光标处插入新字符 * Replace the text at the current cursor selected or insert a new character at the current cursor position * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ replaceSelection : function(value) { this.cm.replaceSelection(value); return this; }, /** * 在当前光标处插入新字符 * Insert a new character at the current cursor position * * 同replaceSelection()方法 * With the replaceSelection() method * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ insertValue : function(value) { this.replaceSelection(value); return this; }, /** * 追加markdown * append Markdown to editor * * @param {String} md 要追加的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ appendMarkdown : function(md) { var settings = this.settings; var cm = this.cm; cm.setValue(cm.getValue() + md); return this; }, /** * 设置和传入编辑器的markdown源文档 * Set Markdown source document * * @param {String} md 要传入的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ setMarkdown : function(md) { this.cm.setValue(md || this.settings.markdown); return this; }, /** * 获取编辑器的markdown源文档 * Set Editor.md markdown/CodeMirror value * * @returns {editormd} 返回editormd的实例对象 */ getMarkdown : function() { return this.cm.getValue(); }, /** * 获取编辑器的源文档 * Get CodeMirror value * * @returns {editormd} 返回editormd的实例对象 */ getValue : function() { return this.cm.getValue(); }, /** * 设置编辑器的源文档 * Set CodeMirror value * * @param {String} value set code/value/string/text * @returns {editormd} 返回editormd的实例对象 */ setValue : function(value) { this.cm.setValue(value); return this; }, /** * 清空编辑器 * Empty CodeMirror editor container * * @returns {editormd} 返回editormd的实例对象 */ clear : function() { this.cm.setValue(""); return this; }, /** * 获取解析后存放在Textarea的HTML源码 * Get parsed html code from Textarea * * @returns {String} 返回HTML源码 */ getHTML : function() { if (!this.settings.saveHTMLToTextarea) { alert("Error: settings.saveHTMLToTextarea == false"); return false; } return this.htmlTextarea.val(); }, /** * getHTML()的别名 * getHTML (alias) * * @returns {String} Return html code 返回HTML源码 */ getTextareaSavedHTML : function() { return this.getHTML(); }, /** * 获取预览窗口的HTML源码 * Get html from preview container * * @returns {editormd} 返回editormd的实例对象 */ getPreviewedHTML : function() { if (!this.settings.watch) { alert("Error: settings.watch == false"); return false; } return this.previewContainer.html(); }, /** * 开启实时预览 * Enable real-time watching * * @returns {editormd} 返回editormd的实例对象 */ watch : function(callback) { var settings = this.settings; if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } this.state.watching = settings.watch = true; this.preview.show(); if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.watch); icon.removeClass(unWatchIcon).addClass(watchIcon); } this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); timer = 0; this.save().resize(); if (!settings.onwatch) { settings.onwatch = callback || function() {}; } $.proxy(settings.onwatch, this)(); return this; }, /** * 关闭实时预览 * Disable real-time watching * * @returns {editormd} 返回editormd的实例对象 */ unwatch : function(callback) { var settings = this.settings; this.state.watching = settings.watch = false; this.preview.hide(); if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.unwatch); icon.removeClass(watchIcon).addClass(unWatchIcon); } this.codeMirror.css("border-right", "none").width(this.editor.width()); this.resize(); if (!settings.onunwatch) { settings.onunwatch = callback || function() {}; } $.proxy(settings.onunwatch, this)(); return this; }, /** * 显示编辑器 * Show editor * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ show : function(callback) { callback = callback || function() {}; var _this = this; this.editor.show(0, function() { $.proxy(callback, _this)(); }); return this; }, /** * 隐藏编辑器 * Hide editor * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ hide : function(callback) { callback = callback || function() {}; var _this = this; this.editor.hide(0, function() { $.proxy(callback, _this)(); }); return this; }, /** * 隐藏编辑器部分,只预览HTML * Enter preview html state * * @returns {editormd} 返回editormd的实例对象 */ previewing : function() { var _this = this; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; var previewContainer = this.previewContainer; if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } if (settings.toolbar && toolbar) { toolbar.toggle(); toolbar.find(".fa[name=preview]").toggleClass("active"); } codeMirror.toggle(); var escHandle = function(event) { if (event.shiftKey && event.keyCode === 27) { _this.previewed(); } }; if (codeMirror.css("display") === "none") // 为了兼容Zepto,而不使用codeMirror.is(":hidden") { this.state.preview = true; if (this.state.fullscreen) { preview.css("background", "#fff"); } editor.find("." + this.classPrefix + "preview-close-btn").show().bind(editormd.mouseOrTouch("click", "touchend"), function(){ _this.previewed(); }); if (!settings.watch) { this.save(); } else { previewContainer.css("padding", ""); } previewContainer.addClass(this.classPrefix + "preview-active"); preview.show().css({ position : "", top : 0, width : editor.width(), height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() }); if (this.state.loaded) { $.proxy(settings.onpreviewing, this)(); } $(window).bind("keyup", escHandle); } else { $(window).unbind("keyup", escHandle); this.previewed(); } }, /** * 显示编辑器部分,退出只预览HTML * Exit preview html state * * @returns {editormd} 返回editormd的实例对象 */ previewed : function() { var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var previewContainer = this.previewContainer; var previewCloseBtn = editor.find("." + this.classPrefix + "preview-close-btn"); this.state.preview = false; this.codeMirror.show(); if (settings.toolbar) { toolbar.show(); } preview[(settings.watch) ? "show" : "hide"](); previewCloseBtn.hide().unbind(editormd.mouseOrTouch("click", "touchend")); previewContainer.removeClass(this.classPrefix + "preview-active"); if (settings.watch) { previewContainer.css("padding", "20px"); } preview.css({ background : null, position : "absolute", width : editor.width() / 2, height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbar.height(), top : (settings.toolbar) ? toolbar.height() : 0 }); if (this.state.loaded) { $.proxy(settings.onpreviewed, this)(); } return this; }, /** * 编辑器全屏显示 * Fullscreen show * * @returns {editormd} 返回editormd的实例对象 */ fullscreen : function() { var _this = this; var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var fullscreenClass = this.classPrefix + "fullscreen"; if (toolbar) { toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); } var escHandle = function(event) { if (!event.shiftKey && event.keyCode === 27) { if (state.fullscreen) { _this.fullscreenExit(); } } }; if (!editor.hasClass(fullscreenClass)) { state.fullscreen = true; $("html,body").css("overflow", "hidden"); editor.css({ width : $(window).width(), height : $(window).height() }).addClass(fullscreenClass); this.resize(); $.proxy(settings.onfullscreen, this)(); $(window).bind("keyup", escHandle); } else { $(window).unbind("keyup", escHandle); this.fullscreenExit(); } return this; }, /** * 编辑器退出全屏显示 * Exit fullscreen state * * @returns {editormd} 返回editormd的实例对象 */ fullscreenExit : function() { var editor = this.editor; var settings = this.settings; var toolbar = this.toolbar; var fullscreenClass = this.classPrefix + "fullscreen"; this.state.fullscreen = false; if (toolbar) { toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); } $("html,body").css("overflow", ""); editor.css({ width : editor.data("oldWidth"), height : editor.data("oldHeight") }).removeClass(fullscreenClass); this.resize(); $.proxy(settings.onfullscreenExit, this)(); return this; }, /** * 加载并执行插件 * Load and execute the plugin * * @param {String} name plugin name / function name * @param {String} path plugin load path * @returns {editormd} 返回editormd的实例对象 */ executePlugin : function(name, path) { var _this = this; var cm = this.cm; var settings = this.settings; path = settings.pluginPath + path; if (typeof define === "function") { if (typeof this[name] === "undefined") { alert("Error: " + name + " plugin is not found, you are not load this plugin."); return this; } this[name](cm); return this; } if ($.inArray(path, editormd.loadFiles.plugin) < 0) { editormd.loadPlugin(path, function() { editormd.loadPlugins[name] = _this[name]; _this[name](cm); }); } else { $.proxy(editormd.loadPlugins[name], this)(cm); } return this; }, /** * 搜索替换 * Search & replace * * @param {String} command CodeMirror serach commands, "find, fintNext, fintPrev, clearSearch, replace, replaceAll" * @returns {editormd} return this */ search : function(command) { var settings = this.settings; if (!settings.searchReplace) { alert("Error: settings.searchReplace == false"); return this; } if (!settings.readOnly) { this.cm.execCommand(command || "find"); } return this; }, searchReplace : function() { this.search("replace"); return this; }, searchReplaceAll : function() { this.search("replaceAll"); return this; } }; editormd.fn.init.prototype = editormd.fn; /** * 锁屏 * lock screen when dialog opening * * @returns {void} */ editormd.dialogLockScreen = function() { var settings = this.settings || {dialogLockScreen : true}; if (settings.dialogLockScreen) { $("html,body").css("overflow", "hidden"); this.resize(); } }; /** * 显示透明背景层 * Display mask layer when dialog opening * * @param {Object} dialog dialog jQuery object * @returns {void} */ editormd.dialogShowMask = function(dialog) { var editor = this.editor; var settings = this.settings || {dialogShowMask : true}; dialog.css({ top : ($(window).height() - dialog.height()) / 2 + "px", left : ($(window).width() - dialog.width()) / 2 + "px" }); if (settings.dialogShowMask) { editor.children("." + this.classPrefix + "mask").css("z-index", parseInt(dialog.css("z-index")) - 1).show(); } }; editormd.toolbarHandlers = { undo : function() { this.cm.undo(); }, redo : function() { this.cm.redo(); }, bold : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("**" + selection + "**"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, del : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("~~" + selection + "~~"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, italic : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("*" + selection + "*"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, quote : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("> " + selection); cm.setCursor(cursor.line, cursor.ch + 2); } else { cm.replaceSelection("> " + selection); } //cm.replaceSelection("> " + selection); //cm.setCursor(cursor.line, (selection === "") ? cursor.ch + 2 : cursor.ch + selection.length + 2); }, ucfirst : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(editormd.firstUpperCase(selection)); cm.setSelections(selections); }, ucwords : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(editormd.wordsFirstUpperCase(selection)); cm.setSelections(selections); }, uppercase : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(selection.toUpperCase()); cm.setSelections(selections); }, lowercase : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(selection.toLowerCase()); cm.setSelections(selections); }, h1 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("# " + selection); cm.setCursor(cursor.line, cursor.ch + 2); } else { cm.replaceSelection("# " + selection); } }, h2 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("## " + selection); cm.setCursor(cursor.line, cursor.ch + 3); } else { cm.replaceSelection("## " + selection); } }, h3 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("### " + selection); cm.setCursor(cursor.line, cursor.ch + 4); } else { cm.replaceSelection("### " + selection); } }, h4 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("#### " + selection); cm.setCursor(cursor.line, cursor.ch + 5); } else { cm.replaceSelection("#### " + selection); } }, h5 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("##### " + selection); cm.setCursor(cursor.line, cursor.ch + 6); } else { cm.replaceSelection("##### " + selection); } }, h6 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("###### " + selection); cm.setCursor(cursor.line, cursor.ch + 7); } else { cm.replaceSelection("###### " + selection); } }, "list-ul" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (selection === "") { cm.replaceSelection("- " + selection); } else { var selectionText = selection.split("\n"); for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i]; } cm.replaceSelection(selectionText.join("\n")); } }, "list-ol" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if(selection === "") { cm.replaceSelection("1. " + selection); } else { var selectionText = selection.split("\n"); for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i]; } cm.replaceSelection(selectionText.join("\n")); } }, hr : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection(((cursor.ch !== 0) ? "\n\n" : "\n") + "------------\n\n"); }, tex : function() { if (!this.settings.tex) { alert("settings.tex === false"); return this; } var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("$$" + selection + "$$"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, link : function() { this.executePlugin("linkDialog", "link-dialog/link-dialog"); }, "reference-link" : function() { this.executePlugin("referenceLinkDialog", "reference-link-dialog/reference-link-dialog"); }, pagebreak : function() { if (!this.settings.pageBreak) { alert("settings.pageBreak === false"); return this; } var cm = this.cm; var selection = cm.getSelection(); cm.replaceSelection("\r\n[========]\r\n"); }, image : function() { this.executePlugin("imageDialog", "image-dialog/image-dialog"); }, code : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("`" + selection + "`"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "code-block" : function() { this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); }, "preformatted-text" : function() { this.executePlugin("preformattedTextDialog", "preformatted-text-dialog/preformatted-text-dialog"); }, table : function() { this.executePlugin("tableDialog", "table-dialog/table-dialog"); }, datetime : function() { var cm = this.cm; var selection = cm.getSelection(); var date = new Date(); var langName = this.settings.lang.name; var datefmt = editormd.dateFormat() + " " + editormd.dateFormat((langName === "zh-cn" || langName === "zh-tw") ? "cn-week-day" : "week-day"); cm.replaceSelection(datefmt); }, emoji : function() { this.executePlugin("emojiDialog", "emoji-dialog/emoji-dialog"); }, "html-entities" : function() { this.executePlugin("htmlEntitiesDialog", "html-entities-dialog/html-entities-dialog"); }, "goto-line" : function() { this.executePlugin("gotoLineDialog", "goto-line-dialog/goto-line-dialog"); }, watch : function() { this[this.settings.watch ? "unwatch" : "watch"](); }, preview : function() { this.previewing(); }, fullscreen : function() { this.fullscreen(); }, clear : function() { this.clear(); }, search : function() { this.search(); }, help : function() { this.executePlugin("helpDialog", "help-dialog/help-dialog"); }, info : function() { this.showInfoDialog(); } }; editormd.keyMaps = { "Ctrl-1" : "h1", "Ctrl-2" : "h2", "Ctrl-3" : "h3", "Ctrl-4" : "h4", "Ctrl-5" : "h5", "Ctrl-6" : "h6", "Ctrl-B" : "bold", // if this is string == editormd.toolbarHandlers.xxxx "Ctrl-D" : "datetime", "Ctrl-E" : function() { // emoji var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (!this.settings.emoji) { alert("Error: settings.emoji == false"); return ; } cm.replaceSelection(":" + selection + ":"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Ctrl-Alt-G" : "goto-line", "Ctrl-H" : "hr", "Ctrl-I" : "italic", "Ctrl-K" : "code", "Ctrl-L" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("[" + selection + "]("+title+")"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Ctrl-U" : "list-ul", "Shift-Ctrl-A" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (!this.settings.atLink) { alert("Error: settings.atLink == false"); return ; } cm.replaceSelection("@" + selection); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Shift-Ctrl-C" : "code", "Shift-Ctrl-Q" : "quote", "Shift-Ctrl-S" : "del", "Shift-Ctrl-K" : "tex", // KaTeX "Shift-Alt-C" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection(["```", selection, "```"].join("\n")); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 3); } }, "Shift-Ctrl-Alt-C" : "code-block", "Shift-Ctrl-H" : "html-entities", "Shift-Alt-H" : "help", "Shift-Ctrl-E" : "emoji", "Shift-Ctrl-U" : "uppercase", "Shift-Alt-U" : "ucwords", "Shift-Ctrl-Alt-U" : "ucfirst", "Shift-Alt-L" : "lowercase", "Shift-Ctrl-I" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("![" + selection + "]("+title+")"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 4); } }, "Shift-Ctrl-Alt-I" : "image", "Shift-Ctrl-L" : "link", "Shift-Ctrl-O" : "list-ol", "Shift-Ctrl-P" : "preformatted-text", "Shift-Ctrl-T" : "table", "Shift-Alt-P" : "pagebreak", "F9" : "watch", "F10" : "preview", "F11" : "fullscreen", }; /** * 清除字符串两边的空格 * Clear the space of strings both sides. * * @param {String} str string * @returns {String} trimed string */ var trim = function(str) { return (!String.prototype.trim) ? str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") : str.trim(); }; editormd.trim = trim; /** * 所有单词首字母大写 * Words first to uppercase * * @param {String} str string * @returns {String} string */ var ucwords = function (str) { return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { return $1.toUpperCase(); }); }; editormd.ucwords = editormd.wordsFirstUpperCase = ucwords; /** * 字符串首字母大写 * Only string first char to uppercase * * @param {String} str string * @returns {String} string */ var firstUpperCase = function(str) { return str.toLowerCase().replace(/\b(\w)/, function($1){ return $1.toUpperCase(); }); }; var ucfirst = firstUpperCase; editormd.firstUpperCase = editormd.ucfirst = firstUpperCase; editormd.urls = { atLinkBase : "https://github.com/" }; editormd.regexs = { atLink : /@(\w+)/g, email : /(\w+)@(\w+)\.(\w+)\.?(\w+)?/g, emailLink : /(mailto:)?([\w\.\_]+)@(\w+)\.(\w+)\.?(\w+)?/g, emoji : /:([\w\+-]+):/g, emojiDatetime : /(\d{2}:\d{2}:\d{2})/g, twemoji : /:(tw-([\w]+)-?(\w+)?):/g, fontAwesome : /:(fa-([\w]+)(-(\w+)){0,}):/g, editormdLogo : /:(editormd-logo-?(\w+)?):/g, pageBreak : /^\[[=]{8,}\]$/ }; // Emoji graphics files url path editormd.emoji = { path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", ext : ".png" }; // Twitter Emoji (Twemoji) graphics files url path editormd.twemoji = { path : "http://twemoji.maxcdn.com/36x36/", ext : ".png" }; /** * 自定义marked的解析器 * Custom Marked renderer rules * * @param {Array} markdownToC 传入用于接收TOC的数组 * @returns {Renderer} markedRenderer 返回marked的Renderer自定义对象 */ editormd.markedRenderer = function(markdownToC, options) { var defaults = { toc : true, // Table of contents tocm : false, tocStartLevel : 1, // Said from H1 to create ToC pageBreak : true, atLink : true, // for @link emailLink : true, // for mail address auto link taskList : false, // Enable Github Flavored Markdown task lists emoji : false, // :emoji: , Support Twemoji, fontAwesome, Editor.md logo emojis. tex : false, // TeX(LaTeX), based on KaTeX flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ }; var settings = $.extend(defaults, options || {}); var marked = editormd.$marked; var markedRenderer = new marked.Renderer(); markdownToC = markdownToC || []; var regexs = editormd.regexs; var atLinkReg = regexs.atLink; var emojiReg = regexs.emoji; var emailReg = regexs.email; var emailLinkReg = regexs.emailLink; var twemojiReg = regexs.twemoji; var faIconReg = regexs.fontAwesome; var editormdLogoReg = regexs.editormdLogo; var pageBreakReg = regexs.pageBreak; markedRenderer.emoji = function(text) { text = text.replace(editormd.regexs.emojiDatetime, function($1) { return $1.replace(/:/g, ":"); }); var matchs = text.match(emojiReg); if (!matchs || !settings.emoji) { return text; } for (var i = 0, len = matchs.length; i < len; i++) { if (matchs[i] === ":+1:") { matchs[i] = ":\\+1:"; } text = text.replace(new RegExp(matchs[i]), function($1, $2){ var faMatchs = $1.match(faIconReg); var name = $1.replace(/:/g, ""); if (faMatchs) { for (var fa = 0, len1 = faMatchs.length; fa < len1; fa++) { var faName = faMatchs[fa].replace(/:/g, ""); return ""; } } else { var emdlogoMathcs = $1.match(editormdLogoReg); var twemojiMatchs = $1.match(twemojiReg); if (emdlogoMathcs) { for (var x = 0, len2 = emdlogoMathcs.length; x < len2; x++) { var logoName = emdlogoMathcs[x].replace(/:/g, ""); return ""; } } else if (twemojiMatchs) { for (var t = 0, len3 = twemojiMatchs.length; t < len3; t++) { var twe = twemojiMatchs[t].replace(/:/g, "").replace("tw-", ""); return "\"twemoji-""; } } else { var src = (name === "+1") ? "plus1" : name; src = (src === "black_large_square") ? "black_square" : src; src = (src === "moon") ? "waxing_gibbous_moon" : src; return "\":""; } } }); } return text; }; markedRenderer.atLink = function(text) { if (atLinkReg.test(text)) { if (settings.atLink) { text = text.replace(emailReg, function($1, $2, $3, $4) { return $1.replace(/@/g, "_#_@_#_"); }); text = text.replace(atLinkReg, function($1, $2) { return "" + $1 + ""; }).replace(/_#_@_#_/g, "@"); } if (settings.emailLink) { text = text.replace(emailLinkReg, function($1, $2, $3, $4, $5) { return (!$2 && $.inArray($5, "jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|")) < 0) ? ""+$1+"" : $1; }); } return text; } return text; }; markedRenderer.link = function (href, title, text) { if (this.options.sanitize) { try { var prot = decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase(); } catch(e) { return ""; } if (prot.indexOf("javascript:") === 0) { return ""; } } var out = "" + text.replace(/@/g, "@") + ""; } if (title) { out += " title=\"" + title + "\""; } out += ">" + text + ""; return out; }; markedRenderer.heading = function(text, level, raw) { var linkText = text; var hasLinkReg = /\s*\]*)\>(.*)\<\/a\>\s*/; var getLinkTextReg = /\s*\]+)\>([^\>]*)\<\/a\>\s*/g; if (hasLinkReg.test(text)) { var tempText = []; text = text.split(/\]+)\>([^\>]*)\<\/a\>/); for (var i = 0, len = text.length; i < len; i++) { tempText.push(text[i].replace(/\s*href\=\"(.*)\"\s*/g, "")); } text = tempText.join(" "); } text = trim(text); var escapedText = text.toLowerCase().replace(/[^\w]+/g, "-"); var toc = { text : text, level : level, slug : escapedText }; var isChinese = /^[\u4e00-\u9fa5]+$/.test(text); var id = (isChinese) ? escape(text).replace(/\%/g, "") : text.toLowerCase().replace(/[^\w]+/g, "-"); markdownToC.push(toc); var headingHTML = ""; headingHTML += ""; headingHTML += ""; headingHTML += (hasLinkReg) ? this.atLink(this.emoji(linkText)) : this.atLink(this.emoji(text)); headingHTML += ""; return headingHTML; }; markedRenderer.pageBreak = function(text) { if (pageBreakReg.test(text) && settings.pageBreak) { text = "
    "; } return text; }; markedRenderer.paragraph = function(text) { var isTeXInline = /\$\$(.*)\$\$/g.test(text); var isTeXLine = /^\$\$(.*)\$\$$/.test(text); var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : ""; var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text); if (!isTeXLine && isTeXInline) { text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function($1, $2) { return "" + $2.replace(/\$/g, "") + ""; }); } else { text = (isTeXLine) ? text.replace(/\$/g, "") : text; } var tocHTML = "
    " + text + "
    "; return (isToC) ? ( (isToCMenu) ? "
    " + tocHTML + "

    " : tocHTML ) : ( (pageBreakReg.test(text)) ? this.pageBreak(text) : "" + this.atLink(this.emoji(text)) + "

    \n" ); }; markedRenderer.code = function (code, lang, escaped) { if (lang === "seq" || lang === "sequence") { return "
    " + code + "
    "; } else if ( lang === "flow") { return "
    " + code + "
    "; } else if ( lang === "math" || lang === "latex" || lang === "katex") { return "

    " + code + "

    "; } else { return marked.Renderer.prototype.code.apply(this, arguments); } }; markedRenderer.tablecell = function(content, flags) { var type = (flags.header) ? "th" : "td"; var tag = (flags.align) ? "<" + type +" style=\"text-align:" + flags.align + "\">" : "<" + type + ">"; return tag + this.atLink(this.emoji(content)) + "\n"; }; markedRenderer.listitem = function(text) { if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) { text = text.replace(/^\s*\[\s\]\s*/, " ") .replace(/^\s*\[x\]\s*/, " "); return "
  • " + this.atLink(this.emoji(text)) + "
  • "; } else { return "
  • " + this.atLink(this.emoji(text)) + "
  • "; } }; return markedRenderer; }; /** * * 生成TOC(Table of Contents) * Creating ToC (Table of Contents) * * @param {Array} toc 从marked获取的TOC数组列表 * @param {Element} container 插入TOC的容器元素 * @param {Integer} startLevel Hx 起始层级 * @returns {Object} tocContainer 返回ToC列表容器层的jQuery对象元素 */ editormd.markdownToCRenderer = function(toc, container, tocDropdown, startLevel) { var html = ""; var lastLevel = 0; var classPrefix = this.classPrefix; startLevel = startLevel || 1; for (var i = 0, len = toc.length; i < len; i++) { var text = toc[i].text; var level = toc[i].level; if (level < startLevel) { continue; } if (level > lastLevel) { html += ""; } else if (level < lastLevel) { html += (new Array(lastLevel - level + 2)).join(""); } else { html += ""; } html += "
  • " + text + "
      "; lastLevel = level; } var tocContainer = container.find(".markdown-toc"); if ((tocContainer.length < 1 && container.attr("previewContainer") === "false")) { var tocHTML = "
      "; tocHTML = (tocDropdown) ? "
      " + tocHTML + "
      " : tocHTML; container.html(tocHTML); tocContainer = container.find(".markdown-toc"); } if (tocDropdown) { tocContainer.wrap("

      "); } tocContainer.html("
        ").children(".markdown-toc-list").html(html.replace(/\r?\n?\\<\/ul\>/g, "")); return tocContainer; }; /** * * 生成TOC下拉菜单 * Creating ToC dropdown menu * * @param {Object} container 插入TOC的容器jQuery对象元素 * @param {String} tocTitle ToC title * @returns {Object} return toc-menu object */ editormd.tocDropdownMenu = function(container, tocTitle) { tocTitle = tocTitle || "Table of Contents"; var zindex = 400; var tocMenus = container.find("." + this.classPrefix + "toc-menu"); tocMenus.each(function() { var $this = $(this); var toc = $this.children(".markdown-toc"); var icon = ""; var btn = "" + icon + tocTitle + ""; var menu = toc.children("ul"); var list = menu.find("li"); toc.append(btn); list.first().before("
      • " + tocTitle + " " + icon + "

      • "); $this.mouseover(function(){ menu.show(); list.each(function(){ var li = $(this); var ul = li.children("ul"); if (ul.html() === "") { ul.remove(); } if (ul.length > 0 && ul.html() !== "") { var firstA = li.children("a").first(); if (firstA.children(".fa").length < 1) { firstA.append( $(icon).css({ float:"right", paddingTop:"4px" }) ); } } li.mouseover(function(){ ul.css("z-index", zindex).show(); zindex += 1; }).mouseleave(function(){ ul.hide(); }); }); }).mouseleave(function(){ menu.hide(); }); }); return tocMenus; }; /** * 简单地过滤指定的HTML标签 * Filter custom html tags * * @param {String} html 要过滤HTML * @param {String} filters 要过滤的标签 * @returns {String} html 返回过滤的HTML */ editormd.filterHTMLTags = function(html, filters) { if (typeof html !== "string") { html = new String(html); } if (typeof filters !== "string") { return html; } var expression = filters.split("|"); var filterTags = expression[0].split(","); var attrs = expression[1]; for (var i = 0, len = filterTags.length; i < len; i++) { var tag = filterTags[i]; html = html.replace(new RegExp("\<\s*" + tag + "\s*([^\>]*)\>([^\>]*)\<\s*\/" + tag + "\s*\>", "igm"), ""); } //return html; if (typeof attrs !== "undefined") { var htmlTagRegex = /\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/ig; if (attrs === "*") { html = html.replace(htmlTagRegex, function($1, $2, $3, $4, $5) { return "<" + $2 + ">" + $4 + ""; }); } else if (attrs === "on*") { html = html.replace(htmlTagRegex, function($1, $2, $3, $4, $5) { var el = $("<" + $2 + ">" + $4 + ""); var _attrs = $($1)[0].attributes; var $attrs = {}; $.each(_attrs, function(i, e) { if (e.nodeName !== '"') $attrs[e.nodeName] = e.nodeValue; }); $.each($attrs, function(i) { if (i.indexOf("on") === 0) { delete $attrs[i]; } }); el.attr($attrs); var text = (typeof el[1] !== "undefined") ? $(el[1]).text() : ""; return el[0].outerHTML + text; }); } else { html = html.replace(htmlTagRegex, function($1, $2, $3, $4) { var filterAttrs = attrs.split(","); var el = $($1); el.html($4); $.each(filterAttrs, function(i) { el.attr(filterAttrs[i], null); }); return el[0].outerHTML; }); } } return html; }; /** * 将Markdown文档解析为HTML用于前台显示 * Parse Markdown to HTML for Font-end preview. * * @param {String} id 用于显示HTML的对象ID * @param {Object} [options={}] 配置选项,可选 * @returns {Object} div 返回jQuery对象元素 */ editormd.markdownToHTML = function(id, options) { var defaults = { gfm : true, toc : true, tocm : false, tocStartLevel : 1, tocTitle : "目录", tocDropdown : false, tocContainer : "", markdown : "", markdownSourceCode : false, htmlDecode : false, autoLoadKaTeX : true, pageBreak : true, atLink : true, // for @link emailLink : true, // for mail address auto link tex : false, taskList : false, // Github Flavored Markdown task lists emoji : false, flowChart : false, sequenceDiagram : false, previewCodeHighlight : true }; editormd.$marked = marked; var div = $("#" + id); var settings = div.settings = $.extend(true, defaults, options || {}); var saveTo = div.find("textarea"); if (saveTo.length < 1) { div.append(""); saveTo = div.find("textarea"); } var markdownDoc = (settings.markdown === "") ? saveTo.val() : settings.markdown; var markdownToC = []; var rendererOptions = { toc : settings.toc, tocm : settings.tocm, tocStartLevel : settings.tocStartLevel, taskList : settings.taskList, emoji : settings.emoji, tex : settings.tex, pageBreak : settings.pageBreak, atLink : settings.atLink, // for @link emailLink : settings.emailLink, // for mail address auto link flowChart : settings.flowChart, sequenceDiagram : settings.sequenceDiagram, previewCodeHighlight : settings.previewCodeHighlight, }; var markedOptions = { renderer : editormd.markedRenderer(markdownToC, rendererOptions), gfm : settings.gfm, tables : true, breaks : true, pedantic : false, sanitize : (settings.htmlDecode) ? false : true, // 是否忽略HTML标签,即是否开启HTML标签解析,为了安全性,默认不开启 smartLists : true, smartypants : true }; markdownDoc = new String(markdownDoc); var markdownParsed = marked(markdownDoc, markedOptions); markdownParsed = editormd.filterHTMLTags(markdownParsed, settings.htmlDecode); if (settings.markdownSourceCode) { saveTo.text(markdownDoc); } else { saveTo.remove(); } div.addClass("markdown-body " + this.classPrefix + "html-preview").append(markdownParsed); var tocContainer = (settings.tocContainer !== "") ? $(settings.tocContainer) : div; if (settings.tocContainer !== "") { tocContainer.attr("previewContainer", false); } if (settings.toc) { div.tocContainer = this.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); if (settings.tocDropdown || div.find("." + this.classPrefix + "toc-menu").length > 0) { this.tocDropdownMenu(div, settings.tocTitle); } if (settings.tocContainer !== "") { div.find(".editormd-toc-menu, .editormd-markdown-toc").remove(); } } if (settings.previewCodeHighlight) { div.find("pre").addClass("prettyprint linenums"); prettyPrint(); } if (!editormd.isIE8) { if (settings.flowChart) { div.find(".flowchart").flowChart(); } if (settings.sequenceDiagram) { div.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); } } if (settings.tex) { var katexHandle = function() { div.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); katex.render(tex.html().replace(/</g, "<").replace(/>/g, ">"), tex[0]); tex.find(".katex").css("font-size", "1.6em"); }); }; if (settings.autoLoadKaTeX && !editormd.$katex && !editormd.kaTeXLoaded) { this.loadKaTeX(function() { editormd.$katex = katex; editormd.kaTeXLoaded = true; katexHandle(); }); } else { katexHandle(); } } div.getMarkdown = function() { return saveTo.val(); }; return div; }; // Editor.md themes, change toolbar themes etc. // added @1.5.0 editormd.themes = ["default", "dark"]; // Preview area themes // added @1.5.0 editormd.previewThemes = ["default", "dark"]; // CodeMirror / editor area themes // @1.5.0 rename -> editorThemes, old version -> themes editormd.editorThemes = [ "default", "3024-day", "3024-night", "ambiance", "ambiance-mobile", "base16-dark", "base16-light", "blackboard", "cobalt", "eclipse", "elegant", "erlang-dark", "lesser-dark", "mbo", "mdn-like", "midnight", "monokai", "neat", "neo", "night", "paraiso-dark", "paraiso-light", "pastel-on-dark", "rubyblue", "solarized", "the-matrix", "tomorrow-night-eighties", "twilight", "vibrant-ink", "xq-dark", "xq-light" ]; editormd.loadPlugins = {}; editormd.loadFiles = { js : [], css : [], plugin : [] }; /** * 动态加载Editor.md插件,但不立即执行 * Load editor.md plugins * * @param {String} fileName 插件文件路径 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 */ editormd.loadPlugin = function(fileName, callback, into) { callback = callback || function() {}; this.loadScript(fileName, function() { editormd.loadFiles.plugin.push(fileName); callback(); }, into); }; /** * 动态加载CSS文件的方法 * Load css file method * * @param {String} fileName CSS文件名 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 */ editormd.loadCSS = function(fileName, callback, into) { into = into || "head"; callback = callback || function() {}; var css = document.createElement("link"); css.type = "text/css"; css.rel = "stylesheet"; css.onload = css.onreadystatechange = function() { editormd.loadFiles.css.push(fileName); callback(); }; css.href = fileName + ".css"; if(into === "head") { document.getElementsByTagName("head")[0].appendChild(css); } else { document.body.appendChild(css); } }; editormd.isIE = (navigator.appName == "Microsoft Internet Explorer"); editormd.isIE8 = (editormd.isIE && navigator.appVersion.match(/8./i) == "8."); /** * 动态加载JS文件的方法 * Load javascript file method * * @param {String} fileName JS文件名 * @param {Function} [callback=function()] 加载成功后执行的回调函数 * @param {String} [into="head"] 嵌入页面的位置 */ editormd.loadScript = function(fileName, callback, into) { into = into || "head"; callback = callback || function() {}; var script = null; script = document.createElement("script"); script.id = fileName.replace(/[\./]+/g, "-"); script.type = "text/javascript"; script.src = fileName + ".js"; if (editormd.isIE8) { script.onreadystatechange = function() { if(script.readyState) { if (script.readyState === "loaded" || script.readyState === "complete") { script.onreadystatechange = null; editormd.loadFiles.js.push(fileName); callback(); } } }; } else { script.onload = function() { editormd.loadFiles.js.push(fileName); callback(); }; } if (into === "head") { document.getElementsByTagName("head")[0].appendChild(script); } else { document.body.appendChild(script); } }; // 使用国外的CDN,加载速度有时会很慢,或者自定义URL // You can custom KaTeX load url. editormd.katexURL = { css : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min", js : "//cdnjs.cloudflare.com/ajax/libs/KaTeX/0.3.0/katex.min" }; editormd.kaTeXLoaded = false; /** * 加载KaTeX文件 * load KaTeX files * * @param {Function} [callback=function()] 加载成功后执行的回调函数 */ editormd.loadKaTeX = function (callback) { editormd.loadCSS(editormd.katexURL.css, function(){ editormd.loadScript(editormd.katexURL.js, callback || function(){}); }); }; /** * 锁屏 * lock screen * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {void} */ editormd.lockScreen = function(lock) { $("html,body").css("overflow", (lock) ? "hidden" : ""); }; /** * 动态创建对话框 * Creating custom dialogs * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ editormd.createDialog = function(options) { var defaults = { name : "", width : 420, height: 240, title : "", drag : true, closed : true, content : "", mask : true, maskStyle : { backgroundColor : "#fff", opacity : 0.1 }, lockScreen : true, footer : true, buttons : false }; options = $.extend(true, defaults, options); var $this = this; var editor = this.editor; var classPrefix = editormd.classPrefix; var guid = (new Date()).getTime(); var dialogName = ( (options.name === "") ? classPrefix + "dialog-" + guid : options.name); var mouseOrTouch = editormd.mouseOrTouch; var html = "
        "; if (options.title !== "") { html += "
        "; html += "" + options.title + ""; html += "
        "; } if (options.closed) { html += ""; } html += "
        " + options.content; if (options.footer || typeof options.footer === "string") { html += "
        " + ( (typeof options.footer === "boolean") ? "" : options.footer) + "
        "; } html += "
        "; html += "
        "; html += "
        "; html += "
        "; editor.append(html); var dialog = editor.find("." + dialogName); dialog.lockScreen = function(lock) { if (options.lockScreen) { $("html,body").css("overflow", (lock) ? "hidden" : ""); $this.resize(); } return dialog; }; dialog.showMask = function() { if (options.mask) { editor.find("." + classPrefix + "mask").css(options.maskStyle).css("z-index", editormd.dialogZindex - 1).show(); } return dialog; }; dialog.hideMask = function() { if (options.mask) { editor.find("." + classPrefix + "mask").hide(); } return dialog; }; dialog.loading = function(show) { var loading = dialog.find("." + classPrefix + "dialog-mask"); loading[(show) ? "show" : "hide"](); return dialog; }; dialog.lockScreen(true).showMask(); dialog.show().css({ zIndex : editormd.dialogZindex, border : (editormd.isIE8) ? "1px solid #ddd" : "", width : (typeof options.width === "number") ? options.width + "px" : options.width, height : (typeof options.height === "number") ? options.height + "px" : options.height }); var dialogPosition = function(){ dialog.css({ top : ($(window).height() - dialog.height()) / 2 + "px", left : ($(window).width() - dialog.width()) / 2 + "px" }); }; dialogPosition(); $(window).resize(dialogPosition); dialog.children("." + classPrefix + "dialog-close").bind(mouseOrTouch("click", "touchend"), function() { dialog.hide().lockScreen(false).hideMask(); }); if (typeof options.buttons === "object") { var footer = dialog.footer = dialog.find("." + classPrefix + "dialog-footer"); for (var key in options.buttons) { var btn = options.buttons[key]; var btnClassName = classPrefix + key + "-btn"; footer.append(""); btn[1] = $.proxy(btn[1], dialog); footer.children("." + btnClassName).bind(mouseOrTouch("click", "touchend"), btn[1]); } } if (options.title !== "" && options.drag) { var posX, posY; var dialogHeader = dialog.children("." + classPrefix + "dialog-header"); if (!options.mask) { dialogHeader.bind(mouseOrTouch("click", "touchend"), function(){ editormd.dialogZindex += 2; dialog.css("z-index", editormd.dialogZindex); }); } dialogHeader.mousedown(function(e) { e = e || window.event; //IE posX = e.clientX - parseInt(dialog[0].style.left); posY = e.clientY - parseInt(dialog[0].style.top); document.onmousemove = moveAction; }); var userCanSelect = function (obj) { obj.removeClass(classPrefix + "user-unselect").off("selectstart"); }; var userUnselect = function (obj) { obj.addClass(classPrefix + "user-unselect").on("selectstart", function(event) { // selectstart for IE return false; }); }; var moveAction = function (e) { e = e || window.event; //IE var left, top, nowLeft = parseInt(dialog[0].style.left), nowTop = parseInt(dialog[0].style.top); if( nowLeft >= 0 ) { if( nowLeft + dialog.width() <= $(window).width()) { left = e.clientX - posX; } else { left = $(window).width() - dialog.width(); document.onmousemove = null; } } else { left = 0; document.onmousemove = null; } if( nowTop >= 0 ) { top = e.clientY - posY; } else { top = 0; document.onmousemove = null; } document.onselectstart = function() { return false; }; userUnselect($("body")); userUnselect(dialog); dialog[0].style.left = left + "px"; dialog[0].style.top = top + "px"; }; document.onmouseup = function() { userCanSelect($("body")); userCanSelect(dialog); document.onselectstart = null; document.onmousemove = null; }; dialogHeader.touchDraggable = function() { var offset = null; var start = function(e) { var orig = e.originalEvent; var pos = $(this).parent().position(); offset = { x : orig.changedTouches[0].pageX - pos.left, y : orig.changedTouches[0].pageY - pos.top }; }; var move = function(e) { e.preventDefault(); var orig = e.originalEvent; $(this).parent().css({ top : orig.changedTouches[0].pageY - offset.y, left : orig.changedTouches[0].pageX - offset.x }); }; this.bind("touchstart", start).bind("touchmove", move); }; dialogHeader.touchDraggable(); } editormd.dialogZindex += 2; return dialog; }; /** * 鼠标和触摸事件的判断/选择方法 * MouseEvent or TouchEvent type switch * * @param {String} [mouseEventType="click"] 供选择的鼠标事件 * @param {String} [touchEventType="touchend"] 供选择的触摸事件 * @returns {String} EventType 返回事件类型名称 */ editormd.mouseOrTouch = function(mouseEventType, touchEventType) { mouseEventType = mouseEventType || "click"; touchEventType = touchEventType || "touchend"; var eventType = mouseEventType; try { document.createEvent("TouchEvent"); eventType = touchEventType; } catch(e) {} return eventType; }; /** * 日期时间的格式化方法 * Datetime format method * * @param {String} [format=""] 日期时间的格式,类似PHP的格式 * @returns {String} datefmt 返回格式化后的日期时间字符串 */ editormd.dateFormat = function(format) { format = format || ""; var addZero = function(d) { return (d < 10) ? "0" + d : d; }; var date = new Date(); var year = date.getFullYear(); var year2 = year.toString().slice(2, 4); var month = addZero(date.getMonth() + 1); var day = addZero(date.getDate()); var weekDay = date.getDay(); var hour = addZero(date.getHours()); var min = addZero(date.getMinutes()); var second = addZero(date.getSeconds()); var ms = addZero(date.getMilliseconds()); var datefmt = ""; var ymd = year2 + "-" + month + "-" + day; var fymd = year + "-" + month + "-" + day; var hms = hour + ":" + min + ":" + second; switch (format) { case "UNIX Time" : datefmt = date.getTime(); break; case "UTC" : datefmt = date.toUTCString(); break; case "yy" : datefmt = year2; break; case "year" : case "yyyy" : datefmt = year; break; case "month" : case "mm" : datefmt = month; break; case "cn-week-day" : case "cn-wd" : var cnWeekDays = ["日", "一", "二", "三", "四", "五", "六"]; datefmt = "星期" + cnWeekDays[weekDay]; break; case "week-day" : case "wd" : var weekDays = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]; datefmt = weekDays[weekDay]; break; case "day" : case "dd" : datefmt = day; break; case "hour" : case "hh" : datefmt = hour; break; case "min" : case "ii" : datefmt = min; break; case "second" : case "ss" : datefmt = second; break; case "ms" : datefmt = ms; break; case "yy-mm-dd" : datefmt = ymd; break; case "yyyy-mm-dd" : datefmt = fymd; break; case "yyyy-mm-dd h:i:s ms" : case "full + ms" : datefmt = fymd + " " + hms + " " + ms; break; case "full" : case "yyyy-mm-dd h:i:s" : default: datefmt = fymd + " " + hms; break; } return datefmt; }; return editormd; })); ================================================ FILE: Public/editor.md/editormd.js ================================================ /* * Editor.md * * @file editormd.js * @version v1.5.0 * @description Open source online markdown editor. * @license MIT License * @author Pandao * {@link https://github.com/pandao/editor.md} * @updateTime 2015-06-09 */ ;(function(factory) { "use strict"; // CommonJS/Node.js if (typeof require === "function" && typeof exports === "object" && typeof module === "object") { module.exports = factory; } else if (typeof define === "function") // AMD/CMD/Sea.js { if (define.amd) // for Require.js { /* Require.js define replace */ } else { define(["jquery"], factory); // for Sea.js } } else { window.editormd = factory(); } }(function() { /* Require.js assignment replace */ "use strict"; var $ = (typeof (jQuery) !== "undefined") ? jQuery : Zepto; if (typeof ($) === "undefined") { return ; } /** * editormd * * @param {String} id 编辑器的ID * @param {Object} options 配置选项 Key/Value * @returns {Object} editormd 返回editormd对象 */ var editormd = function (id, options) { return new editormd.fn.init(id, options); }; editormd.title = editormd.$name = "Editor.md"; editormd.version = "1.5.0"; editormd.homePage = "https://pandao.github.io/editor.md/"; editormd.classPrefix = "editormd-"; editormd.toolbarModes = { full : [ "undo", "redo", "|", "bold", "del", "italic", "quote", "ucwords", "uppercase", "lowercase", "|", "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "link", "reference-link", "image", "code", "preformatted-text", "code-block", "table", "datetime", "emoji", "html-entities", "pagebreak", "|", "goto-line", "watch", "preview", "fullscreen", "clear", "search", "|", "help", "info" ], simple : [ "undo", "redo", "|", "bold", "del", "italic", "quote", "uppercase", "lowercase", "|", "h1", "h2", "h3", "h4", "h5", "h6", "|", "list-ul", "list-ol", "hr", "|", "watch", "preview", "fullscreen", "|", "help", "info" ], mini : [ "undo", "redo", "|", "watch", "preview", "|", "help", "info" ] }; editormd.defaults = { mode : "gfm", //gfm or markdown name : "", // Form element name value : "", // value for CodeMirror, if mode not gfm/markdown theme : "", // Editor.md self themes, before v1.5.0 is CodeMirror theme, default empty editorTheme : "default", // Editor area, this is CodeMirror theme at v1.5.0 previewTheme : "", // Preview area theme, default empty markdown : "", // Markdown source code appendMarkdown : "", // if in init textarea value not empty, append markdown to textarea width : "100%", height : "100%", path : "./lib/", // Dependents module file directory pluginPath : "", // If this empty, default use settings.path + "../plugins/" delay : 300, // Delay parse markdown to html, Uint : ms autoLoadModules : true, // Automatic load dependent module files watch : true, placeholder : "Enjoy Markdown! coding now...", gotoLine : true, codeFold : false, autoHeight : false, autoFocus : true, autoCloseTags : true, searchReplace : true, syncScrolling : true, // true | false | "single", default true readOnly : false, tabSize : 4, indentUnit : 4, lineNumbers : true, lineWrapping : true, autoCloseBrackets : true, showTrailingSpace : true, matchBrackets : true, indentWithTabs : true, styleSelectedText : true, matchWordHighlight : true, // options: true, false, "onselected" styleActiveLine : true, // Highlight the current line dialogLockScreen : true, dialogShowMask : true, dialogDraggable : true, dialogMaskBgColor : "#fff", dialogMaskOpacity : 0.1, fontSize : "13px", saveHTMLToTextarea : false, disabledKeyMaps : [], onload : function() {}, onresize : function() {}, onchange : function() {}, onwatch : null, onunwatch : null, onpreviewing : function() {}, onpreviewed : function() {}, onfullscreen : function() {}, onfullscreenExit : function() {}, onscroll : function() {}, onpreviewscroll : function() {}, imageUpload : false, imageFormats : ["jpg", "jpeg", "gif", "png", "bmp", "webp"], imageUploadURL : "", crossDomainUpload : false, uploadCallbackURL : "", toc : true, // Table of contents tocm : false, // Using [TOCM], auto create ToC dropdown menu tocTitle : "", // for ToC dropdown menu btn tocDropdown : false, tocContainer : "", tocStartLevel : 1, // Said from H1 to create ToC htmlDecode : false, // Open the HTML tag identification pageBreak : true, // Enable parse page break [========] atLink : true, // for @link emailLink : true, // for email address auto link taskList : false, // Enable Github Flavored Markdown task lists emoji : false, // :emoji: , Support Github emoji, Twitter Emoji (Twemoji); // Support FontAwesome icon emoji :fa-xxx: > Using fontAwesome icon web fonts; // Support Editor.md logo icon emoji :editormd-logo: :editormd-logo-1x: > 1~8x; tex : false, // TeX(LaTeX), based on KaTeX flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ previewCodeHighlight : true, toolbar : true, // show/hide toolbar toolbarAutoFixed : true, // on window scroll auto fixed position toolbarIcons : "full", toolbarTitles : {}, toolbarHandlers : { ucwords : function() { return editormd.toolbarHandlers.ucwords; }, lowercase : function() { return editormd.toolbarHandlers.lowercase; } }, toolbarCustomIcons : { // using html tag create toolbar icon, unused default tag. lowercase : "a", "ucwords" : "Aa" }, toolbarIconsClass : { undo : "fa-undo", redo : "fa-repeat", bold : "fa-bold", del : "fa-strikethrough", italic : "fa-italic", quote : "fa-quote-left", uppercase : "fa-font", h1 : editormd.classPrefix + "bold", h2 : editormd.classPrefix + "bold", h3 : editormd.classPrefix + "bold", h4 : editormd.classPrefix + "bold", h5 : editormd.classPrefix + "bold", h6 : editormd.classPrefix + "bold", "list-ul" : "fa-list-ul", "list-ol" : "fa-list-ol", hr : "fa-minus", link : "fa-link", "reference-link" : "fa-anchor", image : "fa-picture-o", code : "fa-code", "preformatted-text" : "fa-file-code-o", "code-block" : "fa-file-code-o", table : "fa-table", datetime : "fa-clock-o", emoji : "fa-smile-o", "html-entities" : "fa-copyright", pagebreak : "fa-newspaper-o", "goto-line" : "fa-terminal", // fa-crosshairs watch : "fa-eye-slash", unwatch : "fa-eye", preview : "fa-desktop", search : "fa-search", fullscreen : "fa-arrows-alt", clear : "fa-eraser", help : "fa-question-circle", info : "fa-info-circle" }, toolbarIconTexts : {}, lang : { name : "zh-cn", description : "开源在线Markdown编辑器
        Open source online Markdown editor.", tocTitle : "目录", toolbar : { undo : "撤销(Ctrl+Z)", redo : "重做(Ctrl+Y)", bold : "粗体", del : "删除线", italic : "斜体", quote : "引用", ucwords : "将每个单词首字母转成大写", uppercase : "将所选转换成大写", lowercase : "将所选转换成小写", h1 : "标题1", h2 : "标题2", h3 : "标题3", h4 : "标题4", h5 : "标题5", h6 : "标题6", "list-ul" : "无序列表", "list-ol" : "有序列表", hr : "横线", link : "链接", "reference-link" : "引用链接", image : "添加图片", code : "行内代码", "preformatted-text" : "预格式文本 / 代码块(缩进风格)", "code-block" : "代码块(多语言风格)", table : "添加表格", datetime : "日期时间", emoji : "Emoji表情", "html-entities" : "HTML实体字符", pagebreak : "插入分页符", "goto-line" : "跳转到行", watch : "关闭实时预览", unwatch : "开启实时预览", preview : "全窗口预览HTML(按 Shift + ESC还原)", fullscreen : "全屏(按ESC还原)", clear : "清空", search : "搜索", help : "使用帮助", info : "关于" + editormd.title }, buttons : { enter : "确定", cancel : "取消", close : "关闭" }, dialog : { link : { title : "添加链接", url : "链接地址", urlTitle : "链接标题", urlEmpty : "错误:请填写链接地址。" }, referenceLink : { title : "添加引用链接", name : "引用名称", url : "链接地址", urlId : "链接ID", urlTitle : "链接标题", nameEmpty: "错误:引用链接的名称不能为空。", idEmpty : "错误:请填写引用链接的ID。", urlEmpty : "错误:请填写引用链接的URL地址。" }, image : { title : "添加图片", url : "图片地址", link : "图片链接", alt : "图片描述", uploadButton : "本地上传", imageURLEmpty : "错误:图片地址不能为空。", uploadFileEmpty : "错误:上传的图片不能为空。", formatNotAllowed : "错误:只允许上传图片文件,允许上传的图片文件格式有:" }, preformattedText : { title : "添加预格式文本或代码块", emptyAlert : "错误:请填写预格式文本或代码的内容。" }, codeBlock : { title : "添加代码块", selectLabel : "代码语言:", selectDefaultText : "请选择代码语言", otherLanguage : "其他语言", unselectedLanguageAlert : "错误:请选择代码所属的语言类型。", codeEmptyAlert : "错误:请填写代码内容。" }, htmlEntities : { title : "HTML 实体字符" }, help : { title : "使用帮助" } } } }; editormd.classNames = { tex : editormd.classPrefix + "tex" }; editormd.dialogZindex = 99999; editormd.$katex = null; editormd.$marked = null; editormd.$CodeMirror = null; editormd.$prettyPrint = null; var timer, flowchartTimer; editormd.prototype = editormd.fn = { state : { watching : false, loaded : false, preview : false, fullscreen : false }, /** * 构造函数/实例初始化 * Constructor / instance initialization * * @param {String} id 编辑器的ID * @param {Object} [options={}] 配置选项 Key/Value * @returns {editormd} 返回editormd的实例对象 */ init : function (id, options) { options = options || {}; if (typeof id === "object") { options = id; } var _this = this; var classPrefix = this.classPrefix = editormd.classPrefix; var settings = this.settings = $.extend(true, editormd.defaults, options); id = (typeof id === "object") ? settings.id : id; var editor = this.editor = $("#" + id); this.id = id; this.lang = settings.lang; var classNames = this.classNames = { textarea : { html : classPrefix + "html-textarea", markdown : classPrefix + "markdown-textarea" } }; settings.pluginPath = (settings.pluginPath === "") ? settings.path + "../plugins/" : settings.pluginPath; this.state.watching = (settings.watch) ? true : false; if ( !editor.hasClass("editormd") ) { editor.addClass("editormd"); } editor.css({ width : (typeof settings.width === "number") ? settings.width + "px" : settings.width, height : (typeof settings.height === "number") ? settings.height + "px" : settings.height }); if (settings.autoHeight) { editor.css("height", "auto"); } var markdownTextarea = this.markdownTextarea = editor.children("textarea"); if (markdownTextarea.length < 1) { editor.append(""); markdownTextarea = this.markdownTextarea = editor.children("textarea"); } markdownTextarea.addClass(classNames.textarea.markdown).attr("placeholder", settings.placeholder); if (typeof markdownTextarea.attr("name") === "undefined" || markdownTextarea.attr("name") === "") { markdownTextarea.attr("name", (settings.name !== "") ? settings.name : id + "-markdown-doc"); } var appendElements = [ (!settings.readOnly) ? "" : "", ( (settings.saveHTMLToTextarea) ? "" : "" ), "
        ", "
        ", "
        " ].join("\n"); editor.append(appendElements).addClass(classPrefix + "vertical"); if (settings.theme !== "") { editor.addClass(classPrefix + "theme-" + settings.theme); } this.mask = editor.children("." + classPrefix + "mask"); this.containerMask = editor.children("." + classPrefix + "container-mask"); if (settings.markdown !== "") { markdownTextarea.val(settings.markdown); } if (settings.appendMarkdown !== "") { markdownTextarea.val(markdownTextarea.val() + settings.appendMarkdown); } this.htmlTextarea = editor.children("." + classNames.textarea.html); this.preview = editor.children("." + classPrefix + "preview"); this.previewContainer = this.preview.children("." + classPrefix + "preview-container"); if (settings.previewTheme !== "") { this.preview.addClass(classPrefix + "preview-theme-" + settings.previewTheme); } if (typeof define === "function" && define.amd) { if (typeof katex !== "undefined") { editormd.$katex = katex; } if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(settings.path + "codemirror/addon/dialog/dialog"); editormd.loadCSS(settings.path + "codemirror/addon/search/matchesonscrollbar"); } } if ((typeof define === "function" && define.amd) || !settings.autoLoadModules) { if (typeof CodeMirror !== "undefined") { editormd.$CodeMirror = CodeMirror; } if (typeof marked !== "undefined") { editormd.$marked = marked; } this.setCodeMirror().setToolbar().loadedDisplay(); } else { this.loadQueues(); } return this; }, /** * 所需组件加载队列 * Required components loading queue * * @returns {editormd} 返回editormd的实例对象 */ loadQueues : function() { var _this = this; var settings = this.settings; var loadPath = settings.path; var loadFlowChartOrSequenceDiagram = function() { if (editormd.isIE8) { _this.loadedDisplay(); return ; } if (settings.flowChart || settings.sequenceDiagram) { editormd.loadScript(loadPath + "raphael.min", function() { editormd.loadScript(loadPath + "underscore.min", function() { if (!settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); } else if (settings.flowChart && !settings.sequenceDiagram) { editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { _this.loadedDisplay(); }); }); } else if (settings.flowChart && settings.sequenceDiagram) { editormd.loadScript(loadPath + "flowchart.min", function() { editormd.loadScript(loadPath + "jquery.flowchart.min", function() { editormd.loadScript(loadPath + "sequence-diagram.min", function() { _this.loadedDisplay(); }); }); }); } }); }); } else { _this.loadedDisplay(); } }; editormd.loadCSS(loadPath + "codemirror/codemirror.min"); if (settings.searchReplace && !settings.readOnly) { editormd.loadCSS(loadPath + "codemirror/addon/dialog/dialog"); editormd.loadCSS(loadPath + "codemirror/addon/search/matchesonscrollbar"); } if (settings.codeFold) { editormd.loadCSS(loadPath + "codemirror/addon/fold/foldgutter"); } editormd.loadScript(loadPath + "codemirror/codemirror.min", function() { editormd.$CodeMirror = CodeMirror; editormd.loadScript(loadPath + "codemirror/modes.min", function() { editormd.loadScript(loadPath + "codemirror/addons.min", function() { _this.setCodeMirror(); if (settings.mode !== "gfm" && settings.mode !== "markdown") { _this.loadedDisplay(); return false; } _this.setToolbar(); editormd.loadScript(loadPath + "marked.min", function() { editormd.$marked = marked; if (settings.previewCodeHighlight) { editormd.loadScript(loadPath + "prettify.min", function() { loadFlowChartOrSequenceDiagram(); }); } else { loadFlowChartOrSequenceDiagram(); } }); }); }); }); return this; }, /** * 设置 Editor.md 的整体主题,主要是工具栏 * Setting Editor.md theme * * @returns {editormd} 返回editormd的实例对象 */ setTheme : function(theme) { var editor = this.editor; var oldTheme = this.settings.theme; var themePrefix = this.classPrefix + "theme-"; editor.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); this.settings.theme = theme; return this; }, /** * 设置 CodeMirror(编辑区)的主题 * Setting CodeMirror (Editor area) theme * * @returns {editormd} 返回editormd的实例对象 */ setEditorTheme : function(theme) { var settings = this.settings; settings.editorTheme = theme; if (theme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } this.cm.setOption("theme", theme); return this; }, /** * setEditorTheme() 的别名 * setEditorTheme() alias * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirrorTheme : function (theme) { this.setEditorTheme(theme); return this; }, /** * 设置 Editor.md 的主题 * Setting Editor.md theme * * @returns {editormd} 返回editormd的实例对象 */ setPreviewTheme : function(theme) { var preview = this.preview; var oldTheme = this.settings.previewTheme; var themePrefix = this.classPrefix + "preview-theme-"; preview.removeClass(themePrefix + oldTheme).addClass(themePrefix + theme); this.settings.previewTheme = theme; return this; }, /** * 配置和初始化CodeMirror组件 * CodeMirror initialization * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirror : function() { var settings = this.settings; var editor = this.editor; if (settings.editorTheme !== "default") { editormd.loadCSS(settings.path + "codemirror/theme/" + settings.editorTheme); } var codeMirrorConfig = { mode : settings.mode, theme : settings.editorTheme, tabSize : settings.tabSize, dragDrop : false, autofocus : settings.autoFocus, autoCloseTags : settings.autoCloseTags, readOnly : (settings.readOnly) ? "nocursor" : false, indentUnit : settings.indentUnit, lineNumbers : settings.lineNumbers, lineWrapping : settings.lineWrapping, extraKeys : { "Ctrl-Q": function(cm) { cm.foldCode(cm.getCursor()); } }, foldGutter : settings.codeFold, gutters : ["CodeMirror-linenumbers", "CodeMirror-foldgutter"], matchBrackets : settings.matchBrackets, indentWithTabs : settings.indentWithTabs, styleActiveLine : settings.styleActiveLine, styleSelectedText : settings.styleSelectedText, autoCloseBrackets : settings.autoCloseBrackets, showTrailingSpace : settings.showTrailingSpace, highlightSelectionMatches : ( (!settings.matchWordHighlight) ? false : { showToken: (settings.matchWordHighlight === "onselected") ? false : /\w/ } ) }; this.codeEditor = this.cm = editormd.$CodeMirror.fromTextArea(this.markdownTextarea[0], codeMirrorConfig); this.codeMirror = this.cmElement = editor.children(".CodeMirror"); if (settings.value !== "") { this.cm.setValue(settings.value); } this.codeMirror.css({ fontSize : settings.fontSize, width : (!settings.watch) ? "100%" : "50%" }); if (settings.autoHeight) { this.codeMirror.css("height", "auto"); this.cm.setOption("viewportMargin", Infinity); } if (!settings.lineNumbers) { this.codeMirror.find(".CodeMirror-gutters").css("border-right", "none"); } return this; }, /** * 获取CodeMirror的配置选项 * Get CodeMirror setting options * * @returns {Mixed} return CodeMirror setting option value */ getCodeMirrorOption : function(key) { return this.cm.getOption(key); }, /** * 配置和重配置CodeMirror的选项 * CodeMirror setting options / resettings * * @returns {editormd} 返回editormd的实例对象 */ setCodeMirrorOption : function(key, value) { this.cm.setOption(key, value); return this; }, /** * 添加 CodeMirror 键盘快捷键 * Add CodeMirror keyboard shortcuts key map * * @returns {editormd} 返回editormd的实例对象 */ addKeyMap : function(map, bottom) { this.cm.addKeyMap(map, bottom); return this; }, /** * 移除 CodeMirror 键盘快捷键 * Remove CodeMirror keyboard shortcuts key map * * @returns {editormd} 返回editormd的实例对象 */ removeKeyMap : function(map) { this.cm.removeKeyMap(map); return this; }, /** * 跳转到指定的行 * Goto CodeMirror line * * @param {String|Intiger} line line number or "first"|"last" * @returns {editormd} 返回editormd的实例对象 */ gotoLine : function (line) { var settings = this.settings; if (!settings.gotoLine) { return this; } var cm = this.cm; var editor = this.editor; var count = cm.lineCount(); var preview = this.preview; if (typeof line === "string") { if(line === "last") { line = count; } if (line === "first") { line = 1; } } if (typeof line !== "number") { alert("Error: The line number must be an integer."); return this; } line = parseInt(line) - 1; if (line > count) { alert("Error: The line number range 1-" + count); return this; } cm.setCursor( {line : line, ch : 0} ); var scrollInfo = cm.getScrollInfo(); var clientHeight = scrollInfo.clientHeight; var coords = cm.charCoords({line : line, ch : 0}, "local"); cm.scrollTo(null, (coords.top + coords.bottom - clientHeight) / 2); if (settings.watch) { var cmScroll = this.codeMirror.find(".CodeMirror-scroll")[0]; var height = $(cmScroll).height(); var scrollTop = cmScroll.scrollTop; var percent = (scrollTop / cmScroll.scrollHeight); if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= cmScroll.scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop(preview[0].scrollHeight * percent); } } cm.focus(); return this; }, /** * 扩展当前实例对象,可同时设置多个或者只设置一个 * Extend editormd instance object, can mutil setting. * * @returns {editormd} this(editormd instance object.) */ extend : function() { if (typeof arguments[1] !== "undefined") { if (typeof arguments[1] === "function") { arguments[1] = $.proxy(arguments[1], this); } this[arguments[0]] = arguments[1]; } if (typeof arguments[0] === "object" && typeof arguments[0].length === "undefined") { $.extend(true, this, arguments[0]); } return this; }, /** * 设置或扩展当前实例对象,单个设置 * Extend editormd instance object, one by one * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ set : function (key, value) { if (typeof value !== "undefined" && typeof value === "function") { value = $.proxy(value, this); } this[key] = value; return this; }, /** * 重新配置 * Resetting editor options * * @param {String|Object} key option key * @param {String|Object} value option value * @returns {editormd} this(editormd instance object.) */ config : function(key, value) { var settings = this.settings; if (typeof key === "object") { settings = $.extend(true, settings, key); } if (typeof key === "string") { settings[key] = value; } this.settings = settings; this.recreate(); return this; }, /** * 注册事件处理方法 * Bind editor event handle * * @param {String} eventType event type * @param {Function} callback 回调函数 * @returns {editormd} this(editormd instance object.) */ on : function(eventType, callback) { var settings = this.settings; if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = $.proxy(callback, this); } return this; }, /** * 解除事件处理方法 * Unbind editor event handle * * @param {String} eventType event type * @returns {editormd} this(editormd instance object.) */ off : function(eventType) { var settings = this.settings; if (typeof settings["on" + eventType] !== "undefined") { settings["on" + eventType] = function(){}; } return this; }, /** * 显示工具栏 * Display toolbar * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ showToolbar : function(callback) { var settings = this.settings; if(settings.readOnly) { return this; } if (settings.toolbar && (this.toolbar.length < 1 || this.toolbar.find("." + this.classPrefix + "menu").html() === "") ) { this.setToolbar(); } settings.toolbar = true; this.toolbar.show(); this.resize(); $.proxy(callback || function(){}, this)(); return this; }, /** * 隐藏工具栏 * Hide toolbar * * @param {Function} [callback=function(){}] 回调函数 * @returns {editormd} this(editormd instance object.) */ hideToolbar : function(callback) { var settings = this.settings; settings.toolbar = false; this.toolbar.hide(); this.resize(); $.proxy(callback || function(){}, this)(); return this; }, /** * 页面滚动时工具栏的固定定位 * Set toolbar in window scroll auto fixed position * * @returns {editormd} 返回editormd的实例对象 */ setToolbarAutoFixed : function(fixed) { var state = this.state; var editor = this.editor; var toolbar = this.toolbar; var settings = this.settings; if (typeof fixed !== "undefined") { settings.toolbarAutoFixed = fixed; } var autoFixedHandle = function(){ var $window = $(window); var top = $window.scrollTop(); if (!settings.toolbarAutoFixed) { return false; } if (top - editor.offset().top > 10 && top < editor.height()) { toolbar.css({ position : "fixed", width : editor.width() + "px", left : ($window.width() - editor.width()) / 2 + "px" }); } else { toolbar.css({ position : "absolute", width : "100%", left : 0 }); } }; if (!state.fullscreen && !state.preview && settings.toolbar && settings.toolbarAutoFixed) { $(window).bind("scroll", autoFixedHandle); } return this; }, /** * 配置和初始化工具栏 * Set toolbar and Initialization * * @returns {editormd} 返回editormd的实例对象 */ setToolbar : function() { var settings = this.settings; if(settings.readOnly) { return this; } var editor = this.editor; var preview = this.preview; var classPrefix = this.classPrefix; var toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); if (settings.toolbar && toolbar.length < 1) { var toolbarHTML = "
          "; editor.append(toolbarHTML); toolbar = this.toolbar = editor.children("." + classPrefix + "toolbar"); } if (!settings.toolbar) { toolbar.hide(); return this; } toolbar.show(); var icons = (typeof settings.toolbarIcons === "function") ? settings.toolbarIcons() : ((typeof settings.toolbarIcons === "string") ? editormd.toolbarModes[settings.toolbarIcons] : settings.toolbarIcons); var toolbarMenu = toolbar.find("." + this.classPrefix + "menu"), menu = ""; var pullRight = false; for (var i = 0, len = icons.length; i < len; i++) { var name = icons[i]; if (name === "||") { pullRight = true; } else if (name === "|") { menu += "
        • |
        • "; } else { var isHeader = (/h(\d)/.test(name)); var index = name; if (name === "watch" && !settings.watch) { index = "unwatch"; } var title = settings.lang.toolbar[index]; var iconTexts = settings.toolbarIconTexts[index]; var iconClass = settings.toolbarIconsClass[index]; title = (typeof title === "undefined") ? "" : title; iconTexts = (typeof iconTexts === "undefined") ? "" : iconTexts; iconClass = (typeof iconClass === "undefined") ? "" : iconClass; var menuItem = pullRight ? "
        • " : "
        • "; if (typeof settings.toolbarCustomIcons[name] !== "undefined" && typeof settings.toolbarCustomIcons[name] !== "function") { menuItem += settings.toolbarCustomIcons[name]; } else { menuItem += ""; menuItem += ""+((isHeader) ? name.toUpperCase() : ( (iconClass === "") ? iconTexts : "") ) + ""; menuItem += ""; } menuItem += "
        • "; menu = pullRight ? menuItem + menu : menu + menuItem; } } toolbarMenu.html(menu); toolbarMenu.find("[title=\"Lowercase\"]").attr("title", settings.lang.toolbar.lowercase); toolbarMenu.find("[title=\"ucwords\"]").attr("title", settings.lang.toolbar.ucwords); this.setToolbarHandler(); this.setToolbarAutoFixed(); return this; }, /** * 工具栏图标事件处理对象序列 * Get toolbar icons event handlers * * @param {Object} cm CodeMirror的实例对象 * @param {String} name 要获取的事件处理器名称 * @returns {Object} 返回处理对象序列 */ dialogLockScreen : function() { $.proxy(editormd.dialogLockScreen, this)(); return this; }, dialogShowMask : function(dialog) { $.proxy(editormd.dialogShowMask, this)(dialog); return this; }, getToolbarHandles : function(name) { var toolbarHandlers = this.toolbarHandlers = editormd.toolbarHandlers; return (name && typeof toolbarIconHandlers[name] !== "undefined") ? toolbarHandlers[name] : toolbarHandlers; }, /** * 工具栏图标事件处理器 * Bind toolbar icons event handle * * @returns {editormd} 返回editormd的实例对象 */ setToolbarHandler : function() { var _this = this; var settings = this.settings; if (!settings.toolbar || settings.readOnly) { return this; } var toolbar = this.toolbar; var cm = this.cm; var classPrefix = this.classPrefix; var toolbarIcons = this.toolbarIcons = toolbar.find("." + classPrefix + "menu > li > a"); var toolbarIconHandlers = this.getToolbarHandles(); toolbarIcons.bind(editormd.mouseOrTouch("click", "touchend"), function(event) { var icon = $(this).children(".fa"); var name = icon.attr("name"); var cursor = cm.getCursor(); var selection = cm.getSelection(); if (name === "") { return ; } _this.activeIcon = icon; if (typeof toolbarIconHandlers[name] !== "undefined") { $.proxy(toolbarIconHandlers[name], _this)(cm); } else { if (typeof settings.toolbarHandlers[name] !== "undefined") { $.proxy(settings.toolbarHandlers[name], _this)(cm, icon, cursor, selection); } } if (name !== "link" && name !== "reference-link" && name !== "image" && name !== "code-block" && name !== "preformatted-text" && name !== "watch" && name !== "preview" && name !== "search" && name !== "fullscreen" && name !== "info") { cm.focus(); } return false; }); return this; }, /** * 动态创建对话框 * Creating custom dialogs * * @param {Object} options 配置项键值对 Key/Value * @returns {dialog} 返回创建的dialog的jQuery实例对象 */ createDialog : function(options) { return $.proxy(editormd.createDialog, this)(options); }, /** * 创建关于Editor.md的对话框 * Create about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ createInfoDialog : function() { var _this = this; var editor = this.editor; var classPrefix = this.classPrefix; var infoDialogHTML = [ "
          ", "
          ", "

          " + editormd.title + "v" + editormd.version + "

          ", "

          " + this.lang.description + "

          ", "

          " + editormd.homePage + "

          ", "

          Copyright © 2015 Pandao, The MIT License.

          ", "
          ", "", "
          " ].join("\n"); editor.append(infoDialogHTML); var infoDialog = this.infoDialog = editor.children("." + classPrefix + "dialog-info"); infoDialog.find("." + classPrefix + "dialog-close").bind(editormd.mouseOrTouch("click", "touchend"), function() { _this.hideInfoDialog(); }); infoDialog.css("border", (editormd.isIE8) ? "1px solid #ddd" : "").css("z-index", editormd.dialogZindex).show(); this.infoDialogPosition(); return this; }, /** * 关于Editor.md对话居中定位 * Editor.md dialog position handle * * @returns {editormd} 返回editormd的实例对象 */ infoDialogPosition : function() { var infoDialog = this.infoDialog; var _infoDialogPosition = function() { infoDialog.css({ top : ($(window).height() - infoDialog.height()) / 2 + "px", left : ($(window).width() - infoDialog.width()) / 2 + "px" }); }; _infoDialogPosition(); $(window).resize(_infoDialogPosition); return this; }, /** * 显示关于Editor.md * Display about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ showInfoDialog : function() { $("html,body").css("overflow-x", "hidden"); var _this = this; var editor = this.editor; var settings = this.settings; var infoDialog = this.infoDialog = editor.children("." + this.classPrefix + "dialog-info"); if (infoDialog.length < 1) { this.createInfoDialog(); } this.lockScreen(true); this.mask.css({ opacity : settings.dialogMaskOpacity, backgroundColor : settings.dialogMaskBgColor }).show(); infoDialog.css("z-index", editormd.dialogZindex).show(); this.infoDialogPosition(); return this; }, /** * 隐藏关于Editor.md * Hide about Editor.md dialog * * @returns {editormd} 返回editormd的实例对象 */ hideInfoDialog : function() { $("html,body").css("overflow-x", ""); this.infoDialog.hide(); this.mask.hide(); this.lockScreen(false); return this; }, /** * 锁屏 * lock screen * * @param {Boolean} lock Boolean 布尔值,是否锁屏 * @returns {editormd} 返回editormd的实例对象 */ lockScreen : function(lock) { editormd.lockScreen(lock); this.resize(); return this; }, /** * 编辑器界面重建,用于动态语言包或模块加载等 * Recreate editor * * @returns {editormd} 返回editormd的实例对象 */ recreate : function() { var _this = this; var editor = this.editor; var settings = this.settings; this.codeMirror.remove(); this.setCodeMirror(); if (!settings.readOnly) { if (editor.find(".editormd-dialog").length > 0) { editor.find(".editormd-dialog").remove(); } if (settings.toolbar) { this.getToolbarHandles(); this.setToolbar(); } } this.loadedDisplay(true); return this; }, /** * 高亮预览HTML的pre代码部分 * highlight of preview codes * * @returns {editormd} 返回editormd的实例对象 */ previewCodeHighlight : function() { var settings = this.settings; var previewContainer = this.previewContainer; if (settings.previewCodeHighlight) { previewContainer.find("pre").addClass("prettyprint linenums"); if (typeof prettyPrint !== "undefined") { prettyPrint(); } } return this; }, /** * 解析TeX(KaTeX)科学公式 * TeX(KaTeX) Renderer * * @returns {editormd} 返回editormd的实例对象 */ katexRender : function() { if (timer === null) { return this; } this.previewContainer.find("." + editormd.classNames.tex).each(function(){ var tex = $(this); editormd.$katex.render(tex.text(), tex[0]); tex.find(".katex").css("font-size", "1.6em"); }); return this; }, /** * 解析和渲染流程图及时序图 * FlowChart and SequenceDiagram Renderer * * @returns {editormd} 返回editormd的实例对象 */ flowChartAndSequenceDiagramRender : function() { var $this = this; var settings = this.settings; var previewContainer = this.previewContainer; if (editormd.isIE8) { return this; } if (settings.flowChart) { if (flowchartTimer === null) { return this; } previewContainer.find(".flowchart").flowChart(); } if (settings.sequenceDiagram) { previewContainer.find(".sequence-diagram").sequenceDiagram({theme: "simple"}); } var preview = $this.preview; var codeMirror = $this.codeMirror; var codeView = codeMirror.find(".CodeMirror-scroll"); var height = codeView.height(); var scrollTop = codeView.scrollTop(); var percent = (scrollTop / codeView[0].scrollHeight); var tocHeight = 0; preview.find(".markdown-toc-list").each(function(){ tocHeight += $(this).height(); }); var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= codeView[0].scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } return this; }, /** * 注册键盘快捷键处理 * Register CodeMirror keyMaps (keyboard shortcuts). * * @param {Object} keyMap KeyMap key/value {"(Ctrl/Shift/Alt)-Key" : function(){}} * @returns {editormd} return this */ registerKeyMaps : function(keyMap) { var _this = this; var cm = this.cm; var settings = this.settings; var toolbarHandlers = editormd.toolbarHandlers; var disabledKeyMaps = settings.disabledKeyMaps; keyMap = keyMap || null; if (keyMap) { for (var i in keyMap) { if ($.inArray(i, disabledKeyMaps) < 0) { var map = {}; map[i] = keyMap[i]; cm.addKeyMap(keyMap); } } } else { for (var k in editormd.keyMaps) { var _keyMap = editormd.keyMaps[k]; var handle = (typeof _keyMap === "string") ? $.proxy(toolbarHandlers[_keyMap], _this) : $.proxy(_keyMap, _this); if ($.inArray(k, ["F9", "F10", "F11"]) < 0 && $.inArray(k, disabledKeyMaps) < 0) { var _map = {}; _map[k] = handle; cm.addKeyMap(_map); } } $(window).keydown(function(event) { var keymaps = { "120" : "F9", "121" : "F10", "122" : "F11" }; if ( $.inArray(keymaps[event.keyCode], disabledKeyMaps) < 0 ) { switch (event.keyCode) { case 120: $.proxy(toolbarHandlers["watch"], _this)(); return false; break; case 121: $.proxy(toolbarHandlers["preview"], _this)(); return false; break; case 122: $.proxy(toolbarHandlers["fullscreen"], _this)(); return false; break; default: break; } } }); } return this; }, /** * 绑定同步滚动 * * @returns {editormd} return this */ bindScrollEvent : function() { var _this = this; var preview = this.preview; var settings = this.settings; var codeMirror = this.codeMirror; var mouseOrTouch = editormd.mouseOrTouch; if (!settings.syncScrolling) { return this; } var cmBindScroll = function() { codeMirror.find(".CodeMirror-scroll").bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); var tocHeight = 0; preview.find(".markdown-toc-list").each(function(){ tocHeight += $(this).height(); }); var tocMenuHeight = preview.find(".editormd-toc-menu").height(); tocMenuHeight = (!tocMenuHeight) ? 0 : tocMenuHeight; if (scrollTop === 0) { preview.scrollTop(0); } else if (scrollTop + height >= $(this)[0].scrollHeight - 16) { preview.scrollTop(preview[0].scrollHeight); } else { preview.scrollTop((preview[0].scrollHeight + tocHeight + tocMenuHeight) * percent); } $.proxy(settings.onscroll, _this)(event); }); }; var cmUnbindScroll = function() { codeMirror.find(".CodeMirror-scroll").unbind(mouseOrTouch("scroll", "touchmove")); }; var previewBindScroll = function() { preview.bind(mouseOrTouch("scroll", "touchmove"), function(event) { var height = $(this).height(); var scrollTop = $(this).scrollTop(); var percent = (scrollTop / $(this)[0].scrollHeight); var codeView = codeMirror.find(".CodeMirror-scroll"); if(scrollTop === 0) { codeView.scrollTop(0); } else if (scrollTop + height >= $(this)[0].scrollHeight) { codeView.scrollTop(codeView[0].scrollHeight); } else { codeView.scrollTop(codeView[0].scrollHeight * percent); } $.proxy(settings.onpreviewscroll, _this)(event); }); }; var previewUnbindScroll = function() { preview.unbind(mouseOrTouch("scroll", "touchmove")); }; codeMirror.bind({ mouseover : cmBindScroll, mouseout : cmUnbindScroll, touchstart : cmBindScroll, touchend : cmUnbindScroll }); if (settings.syncScrolling === "single") { return this; } preview.bind({ mouseover : previewBindScroll, mouseout : previewUnbindScroll, touchstart : previewBindScroll, touchend : previewUnbindScroll }); return this; }, bindChangeEvent : function() { var _this = this; var cm = this.cm; var settings = this.settings; if (!settings.syncScrolling) { return this; } cm.on("change", function(_cm, changeObj) { if (settings.watch) { _this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); } timer = setTimeout(function() { clearTimeout(timer); _this.save(); timer = null; }, settings.delay); }); return this; }, /** * 加载队列完成之后的显示处理 * Display handle of the module queues loaded after. * * @param {Boolean} recreate 是否为重建编辑器 * @returns {editormd} 返回editormd的实例对象 */ loadedDisplay : function(recreate) { recreate = recreate || false; var _this = this; var editor = this.editor; var preview = this.preview; var settings = this.settings; this.containerMask.hide(); this.save(); if (settings.watch) { preview.show(); } editor.data("oldWidth", editor.width()).data("oldHeight", editor.height()); // 为了兼容Zepto this.resize(); this.registerKeyMaps(); $(window).resize(function(){ _this.resize(); }); this.bindScrollEvent().bindChangeEvent(); if (!recreate) { $.proxy(settings.onload, this)(); } this.state.loaded = true; return this; }, /** * 设置编辑器的宽度 * Set editor width * * @param {Number|String} width 编辑器宽度值 * @returns {editormd} 返回editormd的实例对象 */ width : function(width) { this.editor.css("width", (typeof width === "number") ? width + "px" : width); this.resize(); return this; }, /** * 设置编辑器的高度 * Set editor height * * @param {Number|String} height 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ height : function(height) { this.editor.css("height", (typeof height === "number") ? height + "px" : height); this.resize(); return this; }, /** * 调整编辑器的尺寸和布局 * Resize editor layout * * @param {Number|String} [width=null] 编辑器宽度值 * @param {Number|String} [height=null] 编辑器高度值 * @returns {editormd} 返回editormd的实例对象 */ resize : function(width, height) { width = width || null; height = height || null; var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; if (width) { editor.css("width", (typeof width === "number") ? width + "px" : width); } if (settings.autoHeight && !state.fullscreen && !state.preview) { editor.css("height", "auto"); codeMirror.css("height", "auto"); } else { if (height) { editor.css("height", (typeof height === "number") ? height + "px" : height); } if (state.fullscreen) { editor.height($(window).height()); } if (settings.toolbar && !settings.readOnly) { codeMirror.css("margin-top", toolbar.height() + 1).height(editor.height() - toolbar.height()); } else { codeMirror.css("margin-top", 0).height(editor.height()); } } if(settings.watch) { codeMirror.width(editor.width() / 2); preview.width((!state.preview) ? editor.width() / 2 : editor.width()); this.previewContainer.css("padding", settings.autoHeight ? "20px 20px 50px 40px" : "20px"); if (settings.toolbar && !settings.readOnly) { preview.css("top", toolbar.height() + 1); } else { preview.css("top", 0); } if (settings.autoHeight && !state.fullscreen && !state.preview) { preview.height(""); } else { var previewHeight = (settings.toolbar && !settings.readOnly) ? editor.height() - toolbar.height() : editor.height(); preview.height(previewHeight); } } else { codeMirror.width(editor.width()); preview.hide(); } if (state.loaded) { $.proxy(settings.onresize, this)(); } return this; }, /** * 解析和保存Markdown代码 * Parse & Saving Markdown source code * * @returns {editormd} 返回editormd的实例对象 */ save : function() { if (timer === null) { return this; } var _this = this; var state = this.state; var settings = this.settings; var cm = this.cm; var cmValue = cm.getValue(); var previewContainer = this.previewContainer; if (settings.mode !== "gfm" && settings.mode !== "markdown") { this.markdownTextarea.val(cmValue); return this; } var marked = editormd.$marked; var markdownToC = this.markdownToC = []; var rendererOptions = this.markedRendererOptions = { toc : settings.toc, tocm : settings.tocm, tocStartLevel : settings.tocStartLevel, pageBreak : settings.pageBreak, taskList : settings.taskList, emoji : settings.emoji, tex : settings.tex, atLink : settings.atLink, // for @link emailLink : settings.emailLink, // for mail address auto link flowChart : settings.flowChart, sequenceDiagram : settings.sequenceDiagram, previewCodeHighlight : settings.previewCodeHighlight, }; var markedOptions = this.markedOptions = { renderer : editormd.markedRenderer(markdownToC, rendererOptions), gfm : true, tables : true, breaks : true, pedantic : false, sanitize : (settings.htmlDecode) ? false : true, // 关闭忽略HTML标签,即开启识别HTML标签,默认为false smartLists : true, smartypants : true }; marked.setOptions(markedOptions); var newMarkdownDoc = editormd.$marked(cmValue, markedOptions); //console.info("cmValue", cmValue, newMarkdownDoc); newMarkdownDoc = editormd.filterHTMLTags(newMarkdownDoc, settings.htmlDecode); //console.error("cmValue", cmValue, newMarkdownDoc); this.markdownTextarea.text(cmValue); cm.save(); if (settings.saveHTMLToTextarea) { this.htmlTextarea.text(newMarkdownDoc); } if(settings.watch || (!settings.watch && state.preview)) { previewContainer.html(newMarkdownDoc); this.previewCodeHighlight(); if (settings.toc) { var tocContainer = (settings.tocContainer === "") ? previewContainer : $(settings.tocContainer); var tocMenu = tocContainer.find("." + this.classPrefix + "toc-menu"); tocContainer.attr("previewContainer", (settings.tocContainer === "") ? "true" : "false"); if (settings.tocContainer !== "" && tocMenu.length > 0) { tocMenu.remove(); } editormd.markdownToCRenderer(markdownToC, tocContainer, settings.tocDropdown, settings.tocStartLevel); if (settings.tocDropdown || tocContainer.find("." + this.classPrefix + "toc-menu").length > 0) { editormd.tocDropdownMenu(tocContainer, (settings.tocTitle !== "") ? settings.tocTitle : this.lang.tocTitle); } if (settings.tocContainer !== "") { previewContainer.find(".markdown-toc").css("border", "none"); } } if (settings.tex) { if (!editormd.kaTeXLoaded && settings.autoLoadModules) { editormd.loadKaTeX(function() { editormd.$katex = katex; editormd.kaTeXLoaded = true; _this.katexRender(); }); } else { editormd.$katex = katex; this.katexRender(); } } if (settings.flowChart || settings.sequenceDiagram) { flowchartTimer = setTimeout(function(){ clearTimeout(flowchartTimer); _this.flowChartAndSequenceDiagramRender(); flowchartTimer = null; }, 10); } if (state.loaded) { $.proxy(settings.onchange, this)(); } } return this; }, /** * 聚焦光标位置 * Focusing the cursor position * * @returns {editormd} 返回editormd的实例对象 */ focus : function() { this.cm.focus(); return this; }, /** * 设置光标的位置 * Set cursor position * * @param {Object} cursor 要设置的光标位置键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ setCursor : function(cursor) { this.cm.setCursor(cursor); return this; }, /** * 获取当前光标的位置 * Get the current position of the cursor * * @returns {Cursor} 返回一个光标Cursor对象 */ getCursor : function() { return this.cm.getCursor(); }, /** * 设置光标选中的范围 * Set cursor selected ranges * * @param {Object} from 开始位置的光标键值对象,例:{line:1, ch:0} * @param {Object} to 结束位置的光标键值对象,例:{line:1, ch:0} * @returns {editormd} 返回editormd的实例对象 */ setSelection : function(from, to) { this.cm.setSelection(from, to); return this; }, /** * 获取光标选中的文本 * Get the texts from cursor selected * * @returns {String} 返回选中文本的字符串形式 */ getSelection : function() { return this.cm.getSelection(); }, /** * 设置光标选中的文本范围 * Set the cursor selection ranges * * @param {Array} ranges cursor selection ranges array * @returns {Array} return this */ setSelections : function(ranges) { this.cm.setSelections(ranges); return this; }, /** * 获取光标选中的文本范围 * Get the cursor selection ranges * * @returns {Array} return selection ranges array */ getSelections : function() { return this.cm.getSelections(); }, /** * 替换当前光标选中的文本或在当前光标处插入新字符 * Replace the text at the current cursor selected or insert a new character at the current cursor position * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ replaceSelection : function(value) { this.cm.replaceSelection(value); return this; }, /** * 在当前光标处插入新字符 * Insert a new character at the current cursor position * * 同replaceSelection()方法 * With the replaceSelection() method * * @param {String} value 要插入的字符值 * @returns {editormd} 返回editormd的实例对象 */ insertValue : function(value) { this.replaceSelection(value); return this; }, /** * 追加markdown * append Markdown to editor * * @param {String} md 要追加的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ appendMarkdown : function(md) { var settings = this.settings; var cm = this.cm; cm.setValue(cm.getValue() + md); return this; }, /** * 设置和传入编辑器的markdown源文档 * Set Markdown source document * * @param {String} md 要传入的markdown源文档 * @returns {editormd} 返回editormd的实例对象 */ setMarkdown : function(md) { this.cm.setValue(md || this.settings.markdown); return this; }, /** * 获取编辑器的markdown源文档 * Set Editor.md markdown/CodeMirror value * * @returns {editormd} 返回editormd的实例对象 */ getMarkdown : function() { return this.cm.getValue(); }, /** * 获取编辑器的源文档 * Get CodeMirror value * * @returns {editormd} 返回editormd的实例对象 */ getValue : function() { return this.cm.getValue(); }, /** * 设置编辑器的源文档 * Set CodeMirror value * * @param {String} value set code/value/string/text * @returns {editormd} 返回editormd的实例对象 */ setValue : function(value) { this.cm.setValue(value); return this; }, /** * 清空编辑器 * Empty CodeMirror editor container * * @returns {editormd} 返回editormd的实例对象 */ clear : function() { this.cm.setValue(""); return this; }, /** * 获取解析后存放在Textarea的HTML源码 * Get parsed html code from Textarea * * @returns {String} 返回HTML源码 */ getHTML : function() { if (!this.settings.saveHTMLToTextarea) { alert("Error: settings.saveHTMLToTextarea == false"); return false; } return this.htmlTextarea.val(); }, /** * getHTML()的别名 * getHTML (alias) * * @returns {String} Return html code 返回HTML源码 */ getTextareaSavedHTML : function() { return this.getHTML(); }, /** * 获取预览窗口的HTML源码 * Get html from preview container * * @returns {editormd} 返回editormd的实例对象 */ getPreviewedHTML : function() { if (!this.settings.watch) { alert("Error: settings.watch == false"); return false; } return this.previewContainer.html(); }, /** * 开启实时预览 * Enable real-time watching * * @returns {editormd} 返回editormd的实例对象 */ watch : function(callback) { var settings = this.settings; if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } this.state.watching = settings.watch = true; this.preview.show(); if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.watch); icon.removeClass(unWatchIcon).addClass(watchIcon); } this.codeMirror.css("border-right", "1px solid #ddd").width(this.editor.width() / 2); timer = 0; this.save().resize(); if (!settings.onwatch) { settings.onwatch = callback || function() {}; } $.proxy(settings.onwatch, this)(); return this; }, /** * 关闭实时预览 * Disable real-time watching * * @returns {editormd} 返回editormd的实例对象 */ unwatch : function(callback) { var settings = this.settings; this.state.watching = settings.watch = false; this.preview.hide(); if (this.toolbar) { var watchIcon = settings.toolbarIconsClass.watch; var unWatchIcon = settings.toolbarIconsClass.unwatch; var icon = this.toolbar.find(".fa[name=watch]"); icon.parent().attr("title", settings.lang.toolbar.unwatch); icon.removeClass(watchIcon).addClass(unWatchIcon); } this.codeMirror.css("border-right", "none").width(this.editor.width()); this.resize(); if (!settings.onunwatch) { settings.onunwatch = callback || function() {}; } $.proxy(settings.onunwatch, this)(); return this; }, /** * 显示编辑器 * Show editor * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ show : function(callback) { callback = callback || function() {}; var _this = this; this.editor.show(0, function() { $.proxy(callback, _this)(); }); return this; }, /** * 隐藏编辑器 * Hide editor * * @param {Function} [callback=function()] 回调函数 * @returns {editormd} 返回editormd的实例对象 */ hide : function(callback) { callback = callback || function() {}; var _this = this; this.editor.hide(0, function() { $.proxy(callback, _this)(); }); return this; }, /** * 隐藏编辑器部分,只预览HTML * Enter preview html state * * @returns {editormd} 返回editormd的实例对象 */ previewing : function() { var _this = this; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var codeMirror = this.codeMirror; var previewContainer = this.previewContainer; if ($.inArray(settings.mode, ["gfm", "markdown"]) < 0) { return this; } if (settings.toolbar && toolbar) { toolbar.toggle(); toolbar.find(".fa[name=preview]").toggleClass("active"); } codeMirror.toggle(); var escHandle = function(event) { if (event.shiftKey && event.keyCode === 27) { _this.previewed(); } }; if (codeMirror.css("display") === "none") // 为了兼容Zepto,而不使用codeMirror.is(":hidden") { this.state.preview = true; if (this.state.fullscreen) { preview.css("background", "#fff"); } editor.find("." + this.classPrefix + "preview-close-btn").show().bind(editormd.mouseOrTouch("click", "touchend"), function(){ _this.previewed(); }); if (!settings.watch) { this.save(); } else { previewContainer.css("padding", ""); } previewContainer.addClass(this.classPrefix + "preview-active"); preview.show().css({ position : "", top : 0, width : editor.width(), height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() }); if (this.state.loaded) { $.proxy(settings.onpreviewing, this)(); } $(window).bind("keyup", escHandle); } else { $(window).unbind("keyup", escHandle); this.previewed(); } }, /** * 显示编辑器部分,退出只预览HTML * Exit preview html state * * @returns {editormd} 返回editormd的实例对象 */ previewed : function() { var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var previewContainer = this.previewContainer; var previewCloseBtn = editor.find("." + this.classPrefix + "preview-close-btn"); this.state.preview = false; this.codeMirror.show(); if (settings.toolbar) { toolbar.show(); } preview[(settings.watch) ? "show" : "hide"](); previewCloseBtn.hide().unbind(editormd.mouseOrTouch("click", "touchend")); previewContainer.removeClass(this.classPrefix + "preview-active"); if (settings.watch) { previewContainer.css("padding", "20px"); } preview.css({ background : null, position : "absolute", width : editor.width() / 2, height : (settings.autoHeight && !this.state.fullscreen) ? "auto" : editor.height() - toolbar.height(), top : (settings.toolbar) ? toolbar.height() : 0 }); if (this.state.loaded) { $.proxy(settings.onpreviewed, this)(); } return this; }, /** * 编辑器全屏显示 * Fullscreen show * * @returns {editormd} 返回editormd的实例对象 */ fullscreen : function() { var _this = this; var state = this.state; var editor = this.editor; var preview = this.preview; var toolbar = this.toolbar; var settings = this.settings; var fullscreenClass = this.classPrefix + "fullscreen"; if (toolbar) { toolbar.find(".fa[name=fullscreen]").parent().toggleClass("active"); } var escHandle = function(event) { if (!event.shiftKey && event.keyCode === 27) { if (state.fullscreen) { _this.fullscreenExit(); } } }; if (!editor.hasClass(fullscreenClass)) { state.fullscreen = true; $("html,body").css("overflow", "hidden"); editor.css({ width : $(window).width(), height : $(window).height() }).addClass(fullscreenClass); this.resize(); $.proxy(settings.onfullscreen, this)(); $(window).bind("keyup", escHandle); } else { $(window).unbind("keyup", escHandle); this.fullscreenExit(); } return this; }, /** * 编辑器退出全屏显示 * Exit fullscreen state * * @returns {editormd} 返回editormd的实例对象 */ fullscreenExit : function() { var editor = this.editor; var settings = this.settings; var toolbar = this.toolbar; var fullscreenClass = this.classPrefix + "fullscreen"; this.state.fullscreen = false; if (toolbar) { toolbar.find(".fa[name=fullscreen]").parent().removeClass("active"); } $("html,body").css("overflow", ""); editor.css({ width : editor.data("oldWidth"), height : editor.data("oldHeight") }).removeClass(fullscreenClass); this.resize(); $.proxy(settings.onfullscreenExit, this)(); return this; }, /** * 加载并执行插件 * Load and execute the plugin * * @param {String} name plugin name / function name * @param {String} path plugin load path * @returns {editormd} 返回editormd的实例对象 */ executePlugin : function(name, path) { var _this = this; var cm = this.cm; var settings = this.settings; path = settings.pluginPath + path; if (typeof define === "function") { if (typeof this[name] === "undefined") { alert("Error: " + name + " plugin is not found, you are not load this plugin."); return this; } this[name](cm); return this; } if ($.inArray(path, editormd.loadFiles.plugin) < 0) { editormd.loadPlugin(path, function() { editormd.loadPlugins[name] = _this[name]; _this[name](cm); }); } else { $.proxy(editormd.loadPlugins[name], this)(cm); } return this; }, /** * 搜索替换 * Search & replace * * @param {String} command CodeMirror serach commands, "find, fintNext, fintPrev, clearSearch, replace, replaceAll" * @returns {editormd} return this */ search : function(command) { var settings = this.settings; if (!settings.searchReplace) { alert("Error: settings.searchReplace == false"); return this; } if (!settings.readOnly) { this.cm.execCommand(command || "find"); } return this; }, searchReplace : function() { this.search("replace"); return this; }, searchReplaceAll : function() { this.search("replaceAll"); return this; } }; editormd.fn.init.prototype = editormd.fn; /** * 锁屏 * lock screen when dialog opening * * @returns {void} */ editormd.dialogLockScreen = function() { var settings = this.settings || {dialogLockScreen : true}; if (settings.dialogLockScreen) { $("html,body").css("overflow", "hidden"); this.resize(); } }; /** * 显示透明背景层 * Display mask layer when dialog opening * * @param {Object} dialog dialog jQuery object * @returns {void} */ editormd.dialogShowMask = function(dialog) { var editor = this.editor; var settings = this.settings || {dialogShowMask : true}; dialog.css({ top : ($(window).height() - dialog.height()) / 2 + "px", left : ($(window).width() - dialog.width()) / 2 + "px" }); if (settings.dialogShowMask) { editor.children("." + this.classPrefix + "mask").css("z-index", parseInt(dialog.css("z-index")) - 1).show(); } }; editormd.toolbarHandlers = { undo : function() { this.cm.undo(); }, redo : function() { this.cm.redo(); }, bold : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("**" + selection + "**"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, del : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("~~" + selection + "~~"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, italic : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("*" + selection + "*"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, quote : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("> " + selection); cm.setCursor(cursor.line, cursor.ch + 2); } else { cm.replaceSelection("> " + selection); } //cm.replaceSelection("> " + selection); //cm.setCursor(cursor.line, (selection === "") ? cursor.ch + 2 : cursor.ch + selection.length + 2); }, ucfirst : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(editormd.firstUpperCase(selection)); cm.setSelections(selections); }, ucwords : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(editormd.wordsFirstUpperCase(selection)); cm.setSelections(selections); }, uppercase : function() { var cm = this.cm; var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(selection.toUpperCase()); cm.setSelections(selections); }, lowercase : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var selections = cm.listSelections(); cm.replaceSelection(selection.toLowerCase()); cm.setSelections(selections); }, h1 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("# " + selection); cm.setCursor(cursor.line, cursor.ch + 2); } else { cm.replaceSelection("# " + selection); } }, h2 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("## " + selection); cm.setCursor(cursor.line, cursor.ch + 3); } else { cm.replaceSelection("## " + selection); } }, h3 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("### " + selection); cm.setCursor(cursor.line, cursor.ch + 4); } else { cm.replaceSelection("### " + selection); } }, h4 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("#### " + selection); cm.setCursor(cursor.line, cursor.ch + 5); } else { cm.replaceSelection("#### " + selection); } }, h5 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("##### " + selection); cm.setCursor(cursor.line, cursor.ch + 6); } else { cm.replaceSelection("##### " + selection); } }, h6 : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (cursor.ch !== 0) { cm.setCursor(cursor.line, 0); cm.replaceSelection("###### " + selection); cm.setCursor(cursor.line, cursor.ch + 7); } else { cm.replaceSelection("###### " + selection); } }, "list-ul" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (selection === "") { cm.replaceSelection("- " + selection); } else { var selectionText = selection.split("\n"); for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : "- " + selectionText[i]; } cm.replaceSelection(selectionText.join("\n")); } }, "list-ol" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if(selection === "") { cm.replaceSelection("1. " + selection); } else { var selectionText = selection.split("\n"); for (var i = 0, len = selectionText.length; i < len; i++) { selectionText[i] = (selectionText[i] === "") ? "" : (i+1) + ". " + selectionText[i]; } cm.replaceSelection(selectionText.join("\n")); } }, hr : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection(((cursor.ch !== 0) ? "\n\n" : "\n") + "------------\n\n"); }, tex : function() { if (!this.settings.tex) { alert("settings.tex === false"); return this; } var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("$$" + selection + "$$"); if(selection === "") { cm.setCursor(cursor.line, cursor.ch + 2); } }, link : function() { this.executePlugin("linkDialog", "link-dialog/link-dialog"); }, "reference-link" : function() { this.executePlugin("referenceLinkDialog", "reference-link-dialog/reference-link-dialog"); }, pagebreak : function() { if (!this.settings.pageBreak) { alert("settings.pageBreak === false"); return this; } var cm = this.cm; var selection = cm.getSelection(); cm.replaceSelection("\r\n[========]\r\n"); }, image : function() { this.executePlugin("imageDialog", "image-dialog/image-dialog"); }, code : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection("`" + selection + "`"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "code-block" : function() { this.executePlugin("codeBlockDialog", "code-block-dialog/code-block-dialog"); }, "preformatted-text" : function() { this.executePlugin("preformattedTextDialog", "preformatted-text-dialog/preformatted-text-dialog"); }, table : function() { this.executePlugin("tableDialog", "table-dialog/table-dialog"); }, datetime : function() { var cm = this.cm; var selection = cm.getSelection(); var date = new Date(); var langName = this.settings.lang.name; var datefmt = editormd.dateFormat() + " " + editormd.dateFormat((langName === "zh-cn" || langName === "zh-tw") ? "cn-week-day" : "week-day"); cm.replaceSelection(datefmt); }, emoji : function() { this.executePlugin("emojiDialog", "emoji-dialog/emoji-dialog"); }, "html-entities" : function() { this.executePlugin("htmlEntitiesDialog", "html-entities-dialog/html-entities-dialog"); }, "goto-line" : function() { this.executePlugin("gotoLineDialog", "goto-line-dialog/goto-line-dialog"); }, watch : function() { this[this.settings.watch ? "unwatch" : "watch"](); }, preview : function() { this.previewing(); }, fullscreen : function() { this.fullscreen(); }, clear : function() { this.clear(); }, search : function() { this.search(); }, help : function() { this.executePlugin("helpDialog", "help-dialog/help-dialog"); }, info : function() { this.showInfoDialog(); } }; editormd.keyMaps = { "Ctrl-1" : "h1", "Ctrl-2" : "h2", "Ctrl-3" : "h3", "Ctrl-4" : "h4", "Ctrl-5" : "h5", "Ctrl-6" : "h6", "Ctrl-B" : "bold", // if this is string == editormd.toolbarHandlers.xxxx "Ctrl-D" : "datetime", "Ctrl-E" : function() { // emoji var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (!this.settings.emoji) { alert("Error: settings.emoji == false"); return ; } cm.replaceSelection(":" + selection + ":"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Ctrl-Alt-G" : "goto-line", "Ctrl-H" : "hr", "Ctrl-I" : "italic", "Ctrl-K" : "code", "Ctrl-L" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("[" + selection + "]("+title+")"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Ctrl-U" : "list-ul", "Shift-Ctrl-A" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); if (!this.settings.atLink) { alert("Error: settings.atLink == false"); return ; } cm.replaceSelection("@" + selection); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 1); } }, "Shift-Ctrl-C" : "code", "Shift-Ctrl-Q" : "quote", "Shift-Ctrl-S" : "del", "Shift-Ctrl-K" : "tex", // KaTeX "Shift-Alt-C" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); cm.replaceSelection(["```", selection, "```"].join("\n")); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 3); } }, "Shift-Ctrl-Alt-C" : "code-block", "Shift-Ctrl-H" : "html-entities", "Shift-Alt-H" : "help", "Shift-Ctrl-E" : "emoji", "Shift-Ctrl-U" : "uppercase", "Shift-Alt-U" : "ucwords", "Shift-Ctrl-Alt-U" : "ucfirst", "Shift-Alt-L" : "lowercase", "Shift-Ctrl-I" : function() { var cm = this.cm; var cursor = cm.getCursor(); var selection = cm.getSelection(); var title = (selection === "") ? "" : " \""+selection+"\""; cm.replaceSelection("![" + selection + "]("+title+")"); if (selection === "") { cm.setCursor(cursor.line, cursor.ch + 4); } }, "Shift-Ctrl-Alt-I" : "image", "Shift-Ctrl-L" : "link", "Shift-Ctrl-O" : "list-ol", "Shift-Ctrl-P" : "preformatted-text", "Shift-Ctrl-T" : "table", "Shift-Alt-P" : "pagebreak", "F9" : "watch", "F10" : "preview", "F11" : "fullscreen", }; /** * 清除字符串两边的空格 * Clear the space of strings both sides. * * @param {String} str string * @returns {String} trimed string */ var trim = function(str) { return (!String.prototype.trim) ? str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "") : str.trim(); }; editormd.trim = trim; /** * 所有单词首字母大写 * Words first to uppercase * * @param {String} str string * @returns {String} string */ var ucwords = function (str) { return str.toLowerCase().replace(/\b(\w)|\s(\w)/g, function($1) { return $1.toUpperCase(); }); }; editormd.ucwords = editormd.wordsFirstUpperCase = ucwords; /** * 字符串首字母大写 * Only string first char to uppercase * * @param {String} str string * @returns {String} string */ var firstUpperCase = function(str) { return str.toLowerCase().replace(/\b(\w)/, function($1){ return $1.toUpperCase(); }); }; var ucfirst = firstUpperCase; editormd.firstUpperCase = editormd.ucfirst = firstUpperCase; editormd.urls = { atLinkBase : "https://github.com/" }; editormd.regexs = { atLink : /@(\w+)/g, email : /(\w+)@(\w+)\.(\w+)\.?(\w+)?/g, emailLink : /(mailto:)?([\w\.\_]+)@(\w+)\.(\w+)\.?(\w+)?/g, emoji : /:([\w\+-]+):/g, emojiDatetime : /(\d{2}:\d{2}:\d{2})/g, twemoji : /:(tw-([\w]+)-?(\w+)?):/g, fontAwesome : /:(fa-([\w]+)(-(\w+)){0,}):/g, editormdLogo : /:(editormd-logo-?(\w+)?):/g, pageBreak : /^\[[=]{8,}\]$/ }; // Emoji graphics files url path editormd.emoji = { path : "http://www.emoji-cheat-sheet.com/graphics/emojis/", ext : ".png" }; // Twitter Emoji (Twemoji) graphics files url path editormd.twemoji = { path : "http://twemoji.maxcdn.com/36x36/", ext : ".png" }; /** * 自定义marked的解析器 * Custom Marked renderer rules * * @param {Array} markdownToC 传入用于接收TOC的数组 * @returns {Renderer} markedRenderer 返回marked的Renderer自定义对象 */ editormd.markedRenderer = function(markdownToC, options) { var defaults = { toc : true, // Table of contents tocm : false, tocStartLevel : 1, // Said from H1 to create ToC pageBreak : true, atLink : true, // for @link emailLink : true, // for mail address auto link taskList : false, // Enable Github Flavored Markdown task lists emoji : false, // :emoji: , Support Twemoji, fontAwesome, Editor.md logo emojis. tex : false, // TeX(LaTeX), based on KaTeX flowChart : false, // flowChart.js only support IE9+ sequenceDiagram : false, // sequenceDiagram.js only support IE9+ }; var settings = $.extend(defaults, options || {}); var marked = editormd.$marked; var markedRenderer = new marked.Renderer(); markdownToC = markdownToC || []; var regexs = editormd.regexs; var atLinkReg = regexs.atLink; var emojiReg = regexs.emoji; var emailReg = regexs.email; var emailLinkReg = regexs.emailLink; var twemojiReg = regexs.twemoji; var faIconReg = regexs.fontAwesome; var editormdLogoReg = regexs.editormdLogo; var pageBreakReg = regexs.pageBreak; markedRenderer.emoji = function(text) { text = text.replace(editormd.regexs.emojiDatetime, function($1) { return $1.replace(/:/g, ":"); }); var matchs = text.match(emojiReg); if (!matchs || !settings.emoji) { return text; } for (var i = 0, len = matchs.length; i < len; i++) { if (matchs[i] === ":+1:") { matchs[i] = ":\\+1:"; } text = text.replace(new RegExp(matchs[i]), function($1, $2){ var faMatchs = $1.match(faIconReg); var name = $1.replace(/:/g, ""); if (faMatchs) { for (var fa = 0, len1 = faMatchs.length; fa < len1; fa++) { var faName = faMatchs[fa].replace(/:/g, ""); return ""; } } else { var emdlogoMathcs = $1.match(editormdLogoReg); var twemojiMatchs = $1.match(twemojiReg); if (emdlogoMathcs) { for (var x = 0, len2 = emdlogoMathcs.length; x < len2; x++) { var logoName = emdlogoMathcs[x].replace(/:/g, ""); return ""; } } else if (twemojiMatchs) { for (var t = 0, len3 = twemojiMatchs.length; t < len3; t++) { var twe = twemojiMatchs[t].replace(/:/g, "").replace("tw-", ""); return "\"twemoji-""; } } else { var src = (name === "+1") ? "plus1" : name; src = (src === "black_large_square") ? "black_square" : src; src = (src === "moon") ? "waxing_gibbous_moon" : src; return "\":""; } } }); } return text; }; markedRenderer.atLink = function(text) { if (atLinkReg.test(text)) { if (settings.atLink) { text = text.replace(emailReg, function($1, $2, $3, $4) { return $1.replace(/@/g, "_#_@_#_"); }); text = text.replace(atLinkReg, function($1, $2) { return "" + $1 + ""; }).replace(/_#_@_#_/g, "@"); } if (settings.emailLink) { text = text.replace(emailLinkReg, function($1, $2, $3, $4, $5) { return (!$2 && $.inArray($5, "jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|")) < 0) ? ""+$1+"" : $1; }); } return text; } return text; }; markedRenderer.link = function (href, title, text) { if (this.options.sanitize) { try { var prot = decodeURIComponent(unescape(href)).replace(/[^\w:]/g,"").toLowerCase(); } catch(e) { return ""; } if (prot.indexOf("javascript:") === 0) { return ""; } } var out = "" + text.replace(/@/g, "@") + ""; } if (title) { out += " title=\"" + title + "\""; } out += ">" + text + ""; return out; }; markedRenderer.heading = function(text, level, raw) { var linkText = text; var hasLinkReg = /\s*\]*)\>(.*)\<\/a\>\s*/; var getLinkTextReg = /\s*\]+)\>([^\>]*)\<\/a\>\s*/g; if (hasLinkReg.test(text)) { var tempText = []; text = text.split(/\]+)\>([^\>]*)\<\/a\>/); for (var i = 0, len = text.length; i < len; i++) { tempText.push(text[i].replace(/\s*href\=\"(.*)\"\s*/g, "")); } text = tempText.join(" "); } text = trim(text); var escapedText = text.toLowerCase().replace(/[^\w]+/g, "-"); var toc = { text : text, level : level, slug : escapedText }; var isChinese = /^[\u4e00-\u9fa5]+$/.test(text); var id = (isChinese) ? escape(text).replace(/\%/g, "") : text.toLowerCase().replace(/[^\w]+/g, "-"); markdownToC.push(toc); var headingHTML = ""; headingHTML += ""; headingHTML += ""; headingHTML += (hasLinkReg) ? this.atLink(this.emoji(linkText)) : this.atLink(this.emoji(text)); headingHTML += ""; return headingHTML; }; markedRenderer.pageBreak = function(text) { if (pageBreakReg.test(text) && settings.pageBreak) { text = "
          "; } return text; }; markedRenderer.paragraph = function(text) { var isTeXInline = /\$\$(.*)\$\$/g.test(text); var isTeXLine = /^\$\$(.*)\$\$$/.test(text); var isTeXAddClass = (isTeXLine) ? " class=\"" + editormd.classNames.tex + "\"" : ""; var isToC = (settings.tocm) ? /^(\[TOC\]|\[TOCM\])$/.test(text) : /^\[TOC\]$/.test(text); var isToCMenu = /^\[TOCM\]$/.test(text); if (!isTeXLine && isTeXInline) { text = text.replace(/(\$\$([^\$]*)\$\$)+/g, function($1, $2) { return "" + $2.replace(/\$/g, "") + ""; }); } else { text = (isTeXLine) ? text.replace(/\$/g, "") : text; } var tocHTML = "
          " + text + "
          "; return (isToC) ? ( (isToCMenu) ? "
          " + tocHTML + "

          " : tocHTML ) : ( (pageBreakReg.test(text)) ? this.pageBreak(text) : "" + this.atLink(this.emoji(text)) + "

          \n" ); }; markedRenderer.code = function (code, lang, escaped) { if (lang === "seq" || lang === "sequence") { return "
          " + code + "
          "; } else if ( lang === "flow") { return "
          " + code + "
          "; } else if ( lang === "math" || lang === "latex" || lang === "katex") { return "

          " + code + "

          "; } else { return marked.Renderer.prototype.code.apply(this, arguments); } }; markedRenderer.tablecell = function(content, flags) { var type = (flags.header) ? "th" : "td"; var tag = (flags.align) ? "<" + type +" style=\"text-align:" + flags.align + "\">" : "<" + type + ">"; return tag + this.atLink(this.emoji(content)) + "\n"; }; markedRenderer.listitem = function(text) { if (settings.taskList && /^\s*\[[x\s]\]\s*/.test(text)) { text = text.replace(/^\s*\[\s\]\s*/, " ") .replace(/^\s*\[x\]\s*/, " "); return "
        • " + this.atLink(this.emoji(text)) + "
        • "; } else { return "
        • " + this.atLink(this.emoji(text)) + "
        • "; } }; return markedRenderer; }; /** * * 生成TOC(Table of Contents) * Creating ToC (Table of Contents) * * @param {Array} toc 从marked获取的TOC数组列表 * @param {Element} container 插入TOC的容器元素 * @param {Integer} startLevel Hx 起始层级 * @returns {Object} tocContainer 返回ToC列表容器层的jQuery对象元素 */ editormd.markdownToCRenderer = function(toc, container, tocDropdown, startLevel) { var html = ""; var lastLevel = 0; var classPrefix = this.classPrefix; startLevel = startLevel || 1; for (var i = 0, len = toc.length; i < len; i++) { var text = toc[i].text; var level = toc[i].level; if (level < startLevel) { continue; } if (level > lastLevel) { html += ""; } else if (level < lastLevel) { html += (new Array(lastLevel - level + 2)).join("
      • "); } else { html += ""; } html += "
      • " + text + "