From ad5ac788ca9cd4b2640c1ad706a36cfccc9fa942 Mon Sep 17 00:00:00 2001 From: anke1460 Date: Thu, 11 Jun 2020 17:50:15 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=9C=B0=E5=9D=80=E7=BB=B4?= =?UTF-8?q?=E6=8A=A4=EF=BC=8Ceditormd=EF=BC=8C=E5=9B=BE=E7=89=87=E7=AD=89?= =?UTF-8?q?=E8=B5=84=E6=BA=90=E8=BF=81=E7=A7=BB=E5=88=B0=E5=89=8D=E7=AB=AF?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/editormd/.jshintrc | 20 + public/editormd/BUGS.md | 22 + public/editormd/CHANGE.md | 534 + public/editormd/Gulpfile.js | 342 + public/editormd/LICENSE | 22 + public/editormd/README.md | 119 + public/editormd/bower.json | 24 + public/editormd/css/editormd.css | 4451 +++++++++ public/editormd/css/editormd.logo.css | 98 + public/editormd/css/editormd.logo.min.css | 2 + public/editormd/css/editormd.min.css | 5 + public/editormd/css/editormd.preview.css | 3554 +++++++ public/editormd/css/editormd.preview.min.css | 5 + public/editormd/docs/editormd.js.html | 4407 +++++++++ .../docs/fonts/OpenSans-Bold-webfont.eot | Bin 0 -> 19544 bytes .../docs/fonts/OpenSans-Bold-webfont.svg | 1830 ++++ .../docs/fonts/OpenSans-Bold-webfont.woff | Bin 0 -> 22432 bytes .../fonts/OpenSans-BoldItalic-webfont.eot | Bin 0 -> 20133 bytes .../fonts/OpenSans-BoldItalic-webfont.svg | 1830 ++++ .../fonts/OpenSans-BoldItalic-webfont.woff | Bin 0 -> 23048 bytes .../docs/fonts/OpenSans-Italic-webfont.eot | Bin 0 -> 20265 bytes .../docs/fonts/OpenSans-Italic-webfont.svg | 1830 ++++ .../docs/fonts/OpenSans-Italic-webfont.woff | Bin 0 -> 23188 bytes .../docs/fonts/OpenSans-Light-webfont.eot | Bin 0 -> 19514 bytes .../docs/fonts/OpenSans-Light-webfont.svg | 1831 ++++ .../docs/fonts/OpenSans-Light-webfont.woff | Bin 0 -> 22248 bytes .../fonts/OpenSans-LightItalic-webfont.eot | Bin 0 -> 20535 bytes .../fonts/OpenSans-LightItalic-webfont.svg | 1835 ++++ .../fonts/OpenSans-LightItalic-webfont.woff | Bin 0 -> 23400 bytes .../docs/fonts/OpenSans-Regular-webfont.eot | Bin 0 -> 19836 bytes .../docs/fonts/OpenSans-Regular-webfont.svg | 1831 ++++ .../docs/fonts/OpenSans-Regular-webfont.woff | Bin 0 -> 22660 bytes public/editormd/docs/index.html | 65 + public/editormd/docs/scripts/linenumber.js | 25 + .../scripts/prettify/Apache-License-2.0.txt | 202 + .../docs/scripts/prettify/lang-css.js | 2 + .../docs/scripts/prettify/prettify.js | 28 + public/editormd/docs/styles/jsdoc-default.css | 353 + .../editormd/docs/styles/prettify-jsdoc.css | 111 + .../docs/styles/prettify-tomorrow.css | 132 + public/editormd/editormd.amd.js | 4667 +++++++++ public/editormd/editormd.amd.min.js | 4 + public/editormd/editormd.js | 4664 +++++++++ public/editormd/editormd.min.js | 3 + public/editormd/emoji/+1.png | Bin 0 -> 5057 bytes public/editormd/emoji/-1.png | Bin 0 -> 5070 bytes public/editormd/emoji/100.png | Bin 0 -> 3178 bytes public/editormd/emoji/1234.png | Bin 0 -> 4751 bytes public/editormd/emoji/8ball.png | Bin 0 -> 4141 bytes public/editormd/emoji/a.png | Bin 0 -> 3079 bytes public/editormd/emoji/ab.png | Bin 0 -> 3819 bytes public/editormd/emoji/abc.png | Bin 0 -> 4247 bytes public/editormd/emoji/abcd.png | Bin 0 -> 4471 bytes public/editormd/emoji/accept.png | Bin 0 -> 4729 bytes public/editormd/emoji/aerial_tramway.png | Bin 0 -> 3489 bytes public/editormd/emoji/airplane.png | Bin 0 -> 4740 bytes public/editormd/emoji/alarm_clock.png | Bin 0 -> 7062 bytes public/editormd/emoji/alien.png | Bin 0 -> 5345 bytes public/editormd/emoji/ambulance.png | Bin 0 -> 3648 bytes public/editormd/emoji/anchor.png | Bin 0 -> 4474 bytes public/editormd/emoji/angel.png | Bin 0 -> 6648 bytes public/editormd/emoji/anger.png | Bin 0 -> 3079 bytes public/editormd/emoji/angry.png | Bin 0 -> 5024 bytes public/editormd/emoji/anguished.png | Bin 0 -> 5031 bytes public/editormd/emoji/ant.png | Bin 0 -> 2851 bytes public/editormd/emoji/apple.png | Bin 0 -> 5630 bytes public/editormd/emoji/aquarius.png | Bin 0 -> 5096 bytes public/editormd/emoji/aries.png | Bin 0 -> 4183 bytes public/editormd/emoji/arrow_backward.png | Bin 0 -> 3180 bytes public/editormd/emoji/arrow_double_down.png | Bin 0 -> 3179 bytes public/editormd/emoji/arrow_double_up.png | Bin 0 -> 3611 bytes public/editormd/emoji/arrow_down.png | Bin 0 -> 2899 bytes public/editormd/emoji/arrow_down_small.png | Bin 0 -> 2810 bytes public/editormd/emoji/arrow_forward.png | Bin 0 -> 3201 bytes public/editormd/emoji/arrow_heading_down.png | Bin 0 -> 3482 bytes public/editormd/emoji/arrow_heading_up.png | Bin 0 -> 3520 bytes public/editormd/emoji/arrow_left.png | Bin 0 -> 2938 bytes public/editormd/emoji/arrow_lower_left.png | Bin 0 -> 3254 bytes public/editormd/emoji/arrow_lower_right.png | Bin 0 -> 3235 bytes public/editormd/emoji/arrow_right.png | Bin 0 -> 2938 bytes public/editormd/emoji/arrow_right_hook.png | Bin 0 -> 3712 bytes public/editormd/emoji/arrow_up.png | Bin 0 -> 2975 bytes public/editormd/emoji/arrow_up_down.png | Bin 0 -> 3542 bytes public/editormd/emoji/arrow_up_small.png | Bin 0 -> 3095 bytes public/editormd/emoji/arrow_upper_left.png | Bin 0 -> 3136 bytes public/editormd/emoji/arrow_upper_right.png | Bin 0 -> 3139 bytes public/editormd/emoji/arrows_clockwise.png | Bin 0 -> 1390 bytes .../emoji/arrows_counterclockwise.png | Bin 0 -> 4816 bytes public/editormd/emoji/art.png | Bin 0 -> 6744 bytes public/editormd/emoji/articulated_lorry.png | Bin 0 -> 2908 bytes public/editormd/emoji/astonished.png | Bin 0 -> 5965 bytes public/editormd/emoji/atm.png | Bin 0 -> 4072 bytes public/editormd/emoji/b.png | Bin 0 -> 3001 bytes public/editormd/emoji/baby.png | Bin 0 -> 5921 bytes public/editormd/emoji/baby_bottle.png | Bin 0 -> 4461 bytes public/editormd/emoji/baby_chick.png | Bin 0 -> 3961 bytes public/editormd/emoji/baby_symbol.png | Bin 0 -> 2929 bytes public/editormd/emoji/back.png | Bin 0 -> 2406 bytes public/editormd/emoji/baggage_claim.png | Bin 0 -> 3499 bytes public/editormd/emoji/balloon.png | Bin 0 -> 2300 bytes .../editormd/emoji/ballot_box_with_check.png | Bin 0 -> 1829 bytes public/editormd/emoji/bamboo.png | Bin 0 -> 4672 bytes public/editormd/emoji/banana.png | Bin 0 -> 3915 bytes public/editormd/emoji/bangbang.png | Bin 0 -> 1387 bytes public/editormd/emoji/bank.png | Bin 0 -> 5583 bytes public/editormd/emoji/bar_chart.png | Bin 0 -> 2254 bytes public/editormd/emoji/barber.png | Bin 0 -> 4252 bytes public/editormd/emoji/baseball.png | Bin 0 -> 6032 bytes public/editormd/emoji/basketball.png | Bin 0 -> 6386 bytes public/editormd/emoji/bath.png | Bin 0 -> 3210 bytes public/editormd/emoji/bathtub.png | Bin 0 -> 2784 bytes public/editormd/emoji/battery.png | Bin 0 -> 3812 bytes public/editormd/emoji/bear.png | Bin 0 -> 5561 bytes public/editormd/emoji/bee.png | Bin 0 -> 5808 bytes public/editormd/emoji/beer.png | Bin 0 -> 6097 bytes public/editormd/emoji/beers.png | Bin 0 -> 6591 bytes public/editormd/emoji/beetle.png | Bin 0 -> 5255 bytes public/editormd/emoji/beginner.png | Bin 0 -> 2740 bytes public/editormd/emoji/bell.png | Bin 0 -> 4859 bytes public/editormd/emoji/bento.png | Bin 0 -> 5465 bytes public/editormd/emoji/bicyclist.png | Bin 0 -> 6472 bytes public/editormd/emoji/bike.png | Bin 0 -> 4722 bytes public/editormd/emoji/bikini.png | Bin 0 -> 3890 bytes public/editormd/emoji/bird.png | Bin 0 -> 4878 bytes public/editormd/emoji/birthday.png | Bin 0 -> 5404 bytes public/editormd/emoji/black_circle.png | Bin 0 -> 1827 bytes public/editormd/emoji/black_joker.png | Bin 0 -> 3824 bytes .../emoji/black_medium_small_square.png | Bin 0 -> 1221 bytes public/editormd/emoji/black_medium_square.png | Bin 0 -> 1580 bytes public/editormd/emoji/black_nib.png | Bin 0 -> 2338 bytes public/editormd/emoji/black_small_square.png | Bin 0 -> 946 bytes public/editormd/emoji/black_square.png | Bin 0 -> 1222 bytes public/editormd/emoji/black_square_button.png | Bin 0 -> 1248 bytes public/editormd/emoji/blossom.png | Bin 0 -> 4232 bytes public/editormd/emoji/blowfish.png | Bin 0 -> 3737 bytes public/editormd/emoji/blue_book.png | Bin 0 -> 5066 bytes public/editormd/emoji/blue_car.png | Bin 0 -> 4022 bytes public/editormd/emoji/blue_heart.png | Bin 0 -> 4052 bytes public/editormd/emoji/blush.png | Bin 0 -> 5164 bytes public/editormd/emoji/boar.png | Bin 0 -> 4840 bytes public/editormd/emoji/boat.png | Bin 0 -> 3833 bytes public/editormd/emoji/bomb.png | Bin 0 -> 5141 bytes public/editormd/emoji/book.png | Bin 0 -> 5965 bytes public/editormd/emoji/bookmark.png | Bin 0 -> 4649 bytes public/editormd/emoji/bookmark_tabs.png | Bin 0 -> 3104 bytes public/editormd/emoji/books.png | Bin 0 -> 6515 bytes public/editormd/emoji/boom.png | Bin 0 -> 3772 bytes public/editormd/emoji/boot.png | Bin 0 -> 3327 bytes public/editormd/emoji/bouquet.png | Bin 0 -> 6915 bytes public/editormd/emoji/bow.png | Bin 0 -> 5121 bytes public/editormd/emoji/bowling.png | Bin 0 -> 4184 bytes public/editormd/emoji/bowtie.png | Bin 0 -> 6384 bytes public/editormd/emoji/boy.png | Bin 0 -> 5946 bytes public/editormd/emoji/bread.png | Bin 0 -> 6214 bytes public/editormd/emoji/bride_with_veil.png | Bin 0 -> 8515 bytes public/editormd/emoji/bridge_at_night.png | Bin 0 -> 5061 bytes public/editormd/emoji/briefcase.png | Bin 0 -> 2650 bytes public/editormd/emoji/broken_heart.png | Bin 0 -> 4088 bytes public/editormd/emoji/bug.png | Bin 0 -> 5840 bytes public/editormd/emoji/bulb.png | Bin 0 -> 4490 bytes public/editormd/emoji/bullettrain_front.png | Bin 0 -> 4992 bytes public/editormd/emoji/bullettrain_side.png | Bin 0 -> 3842 bytes public/editormd/emoji/bus.png | Bin 0 -> 3921 bytes public/editormd/emoji/busstop.png | Bin 0 -> 1676 bytes public/editormd/emoji/bust_in_silhouette.png | Bin 0 -> 2005 bytes public/editormd/emoji/busts_in_silhouette.png | Bin 0 -> 2989 bytes public/editormd/emoji/cactus.png | Bin 0 -> 4509 bytes public/editormd/emoji/cake.png | Bin 0 -> 6129 bytes public/editormd/emoji/calendar.png | Bin 0 -> 2898 bytes public/editormd/emoji/calling.png | Bin 0 -> 3971 bytes public/editormd/emoji/camel.png | Bin 0 -> 4485 bytes public/editormd/emoji/camera.png | Bin 0 -> 4630 bytes public/editormd/emoji/cancer.png | Bin 0 -> 5361 bytes public/editormd/emoji/candy.png | Bin 0 -> 4502 bytes public/editormd/emoji/capital_abcd.png | Bin 0 -> 5136 bytes public/editormd/emoji/capricorn.png | Bin 0 -> 4648 bytes public/editormd/emoji/car.png | Bin 0 -> 4267 bytes public/editormd/emoji/card_index.png | Bin 0 -> 3746 bytes public/editormd/emoji/carousel_horse.png | Bin 0 -> 5823 bytes public/editormd/emoji/cat.png | Bin 0 -> 5987 bytes public/editormd/emoji/cat2.png | Bin 0 -> 5644 bytes public/editormd/emoji/cd.png | Bin 0 -> 6606 bytes public/editormd/emoji/chart.png | Bin 0 -> 4312 bytes .../emoji/chart_with_downwards_trend.png | Bin 0 -> 2708 bytes .../emoji/chart_with_upwards_trend.png | Bin 0 -> 2737 bytes public/editormd/emoji/checkered_flag.png | Bin 0 -> 1625 bytes public/editormd/emoji/cherries.png | Bin 0 -> 5542 bytes public/editormd/emoji/cherry_blossom.png | Bin 0 -> 7133 bytes public/editormd/emoji/chestnut.png | Bin 0 -> 5854 bytes public/editormd/emoji/chicken.png | Bin 0 -> 3988 bytes public/editormd/emoji/children_crossing.png | Bin 0 -> 3429 bytes public/editormd/emoji/chocolate_bar.png | Bin 0 -> 5249 bytes public/editormd/emoji/christmas_tree.png | Bin 0 -> 4721 bytes public/editormd/emoji/church.png | Bin 0 -> 4642 bytes public/editormd/emoji/cinema.png | Bin 0 -> 3553 bytes public/editormd/emoji/circus_tent.png | Bin 0 -> 4683 bytes public/editormd/emoji/city_sunrise.png | Bin 0 -> 4261 bytes public/editormd/emoji/city_sunset.png | Bin 0 -> 3760 bytes public/editormd/emoji/cl.png | Bin 0 -> 3492 bytes public/editormd/emoji/clap.png | Bin 0 -> 7110 bytes public/editormd/emoji/clapper.png | Bin 0 -> 4185 bytes public/editormd/emoji/clipboard.png | Bin 0 -> 4647 bytes public/editormd/emoji/clock1.png | Bin 0 -> 2590 bytes public/editormd/emoji/clock10.png | Bin 0 -> 2590 bytes public/editormd/emoji/clock1030.png | Bin 0 -> 2817 bytes public/editormd/emoji/clock11.png | Bin 0 -> 2587 bytes public/editormd/emoji/clock1130.png | Bin 0 -> 2854 bytes public/editormd/emoji/clock12.png | Bin 0 -> 2504 bytes public/editormd/emoji/clock1230.png | Bin 0 -> 2797 bytes public/editormd/emoji/clock130.png | Bin 0 -> 2814 bytes public/editormd/emoji/clock2.png | Bin 0 -> 2595 bytes public/editormd/emoji/clock230.png | Bin 0 -> 2847 bytes public/editormd/emoji/clock3.png | Bin 0 -> 2492 bytes public/editormd/emoji/clock330.png | Bin 0 -> 2717 bytes public/editormd/emoji/clock4.png | Bin 0 -> 2619 bytes public/editormd/emoji/clock430.png | Bin 0 -> 2803 bytes public/editormd/emoji/clock5.png | Bin 0 -> 2624 bytes public/editormd/emoji/clock530.png | Bin 0 -> 2829 bytes public/editormd/emoji/clock6.png | Bin 0 -> 2577 bytes public/editormd/emoji/clock630.png | Bin 0 -> 2726 bytes public/editormd/emoji/clock7.png | Bin 0 -> 2615 bytes public/editormd/emoji/clock730.png | Bin 0 -> 2794 bytes public/editormd/emoji/clock8.png | Bin 0 -> 2603 bytes public/editormd/emoji/clock830.png | Bin 0 -> 2792 bytes public/editormd/emoji/clock9.png | Bin 0 -> 2486 bytes public/editormd/emoji/clock930.png | Bin 0 -> 2742 bytes public/editormd/emoji/closed_book.png | Bin 0 -> 4763 bytes .../editormd/emoji/closed_lock_with_key.png | Bin 0 -> 5672 bytes public/editormd/emoji/closed_umbrella.png | Bin 0 -> 3868 bytes public/editormd/emoji/cloud.png | Bin 0 -> 3810 bytes public/editormd/emoji/clubs.png | Bin 0 -> 1652 bytes public/editormd/emoji/cn.png | Bin 0 -> 3561 bytes public/editormd/emoji/cocktail.png | Bin 0 -> 2949 bytes public/editormd/emoji/coffee.png | Bin 0 -> 4177 bytes public/editormd/emoji/cold_sweat.png | Bin 0 -> 5880 bytes public/editormd/emoji/collision.png | Bin 0 -> 3772 bytes public/editormd/emoji/computer.png | Bin 0 -> 1705 bytes public/editormd/emoji/confetti_ball.png | Bin 0 -> 5484 bytes public/editormd/emoji/confounded.png | Bin 0 -> 5855 bytes public/editormd/emoji/confused.png | Bin 0 -> 4563 bytes public/editormd/emoji/congratulations.png | Bin 0 -> 4879 bytes public/editormd/emoji/construction.png | Bin 0 -> 3700 bytes public/editormd/emoji/construction_worker.png | Bin 0 -> 6134 bytes public/editormd/emoji/convenience_store.png | Bin 0 -> 4073 bytes public/editormd/emoji/cookie.png | Bin 0 -> 8051 bytes public/editormd/emoji/cool.png | Bin 0 -> 4182 bytes public/editormd/emoji/cop.png | Bin 0 -> 7141 bytes public/editormd/emoji/copyright.png | Bin 0 -> 1579 bytes public/editormd/emoji/corn.png | Bin 0 -> 6694 bytes public/editormd/emoji/couple.png | Bin 0 -> 7615 bytes public/editormd/emoji/couple_with_heart.png | Bin 0 -> 7255 bytes public/editormd/emoji/couplekiss.png | Bin 0 -> 7196 bytes public/editormd/emoji/cow.png | Bin 0 -> 5745 bytes public/editormd/emoji/cow2.png | Bin 0 -> 5303 bytes public/editormd/emoji/credit_card.png | Bin 0 -> 2536 bytes public/editormd/emoji/crescent_moon.png | Bin 0 -> 3541 bytes public/editormd/emoji/crocodile.png | Bin 0 -> 6125 bytes public/editormd/emoji/crossed_flags.png | Bin 0 -> 4015 bytes public/editormd/emoji/crown.png | Bin 0 -> 5655 bytes public/editormd/emoji/cry.png | Bin 0 -> 5624 bytes public/editormd/emoji/crying_cat_face.png | Bin 0 -> 6682 bytes public/editormd/emoji/crystal_ball.png | Bin 0 -> 6213 bytes public/editormd/emoji/cupid.png | Bin 0 -> 5413 bytes public/editormd/emoji/curly_loop.png | Bin 0 -> 1129 bytes public/editormd/emoji/currency_exchange.png | Bin 0 -> 1959 bytes public/editormd/emoji/curry.png | Bin 0 -> 5261 bytes public/editormd/emoji/custard.png | Bin 0 -> 5692 bytes public/editormd/emoji/customs.png | Bin 0 -> 3899 bytes public/editormd/emoji/cyclone.png | Bin 0 -> 4890 bytes public/editormd/emoji/dancer.png | Bin 0 -> 3687 bytes public/editormd/emoji/dancers.png | Bin 0 -> 7918 bytes public/editormd/emoji/dango.png | Bin 0 -> 4449 bytes public/editormd/emoji/dart.png | Bin 0 -> 5437 bytes public/editormd/emoji/dash.png | Bin 0 -> 5411 bytes public/editormd/emoji/date.png | Bin 0 -> 2881 bytes public/editormd/emoji/de.png | Bin 0 -> 2554 bytes public/editormd/emoji/deciduous_tree.png | Bin 0 -> 7243 bytes public/editormd/emoji/department_store.png | Bin 0 -> 5159 bytes .../emoji/diamond_shape_with_a_dot_inside.png | Bin 0 -> 5676 bytes public/editormd/emoji/diamonds.png | Bin 0 -> 2732 bytes public/editormd/emoji/disappointed.png | Bin 0 -> 4658 bytes .../editormd/emoji/disappointed_relieved.png | Bin 0 -> 5539 bytes public/editormd/emoji/dizzy.png | Bin 0 -> 2990 bytes public/editormd/emoji/dizzy_face.png | Bin 0 -> 6221 bytes public/editormd/emoji/do_not_litter.png | Bin 0 -> 5277 bytes public/editormd/emoji/dog.png | Bin 0 -> 5945 bytes public/editormd/emoji/dog2.png | Bin 0 -> 5931 bytes public/editormd/emoji/dollar.png | Bin 0 -> 4562 bytes public/editormd/emoji/dolls.png | Bin 0 -> 7118 bytes public/editormd/emoji/dolphin.png | Bin 0 -> 4343 bytes public/editormd/emoji/donut.png | Bin 0 -> 5123 bytes public/editormd/emoji/door.png | Bin 0 -> 3310 bytes public/editormd/emoji/doughnut.png | Bin 0 -> 5123 bytes public/editormd/emoji/dragon.png | Bin 0 -> 7749 bytes public/editormd/emoji/dragon_face.png | Bin 0 -> 6737 bytes public/editormd/emoji/dress.png | Bin 0 -> 3631 bytes public/editormd/emoji/dromedary_camel.png | Bin 0 -> 5139 bytes public/editormd/emoji/droplet.png | Bin 0 -> 3139 bytes public/editormd/emoji/dvd.png | Bin 0 -> 6864 bytes public/editormd/emoji/e-mail.png | Bin 0 -> 2096 bytes public/editormd/emoji/ear.png | Bin 0 -> 4335 bytes public/editormd/emoji/ear_of_rice.png | Bin 0 -> 4758 bytes public/editormd/emoji/earth_africa.png | Bin 0 -> 7164 bytes public/editormd/emoji/earth_americas.png | Bin 0 -> 7039 bytes public/editormd/emoji/earth_asia.png | Bin 0 -> 7303 bytes public/editormd/emoji/egg.png | Bin 0 -> 5211 bytes public/editormd/emoji/eggplant.png | Bin 0 -> 4672 bytes public/editormd/emoji/eight.png | Bin 0 -> 3826 bytes .../emoji/eight_pointed_black_star.png | Bin 0 -> 3220 bytes .../editormd/emoji/eight_spoked_asterisk.png | Bin 0 -> 4012 bytes public/editormd/emoji/electric_plug.png | Bin 0 -> 2758 bytes public/editormd/emoji/elephant.png | Bin 0 -> 5086 bytes public/editormd/emoji/email.png | Bin 0 -> 2639 bytes public/editormd/emoji/end.png | Bin 0 -> 1086 bytes public/editormd/emoji/envelope.png | Bin 0 -> 1233 bytes public/editormd/emoji/es.png | Bin 0 -> 4234 bytes public/editormd/emoji/euro.png | Bin 0 -> 3878 bytes public/editormd/emoji/european_castle.png | Bin 0 -> 5313 bytes .../editormd/emoji/european_post_office.png | Bin 0 -> 4816 bytes public/editormd/emoji/evergreen_tree.png | Bin 0 -> 4924 bytes public/editormd/emoji/exclamation.png | Bin 0 -> 1122 bytes public/editormd/emoji/expressionless.png | Bin 0 -> 3952 bytes public/editormd/emoji/eyeglasses.png | Bin 0 -> 4929 bytes public/editormd/emoji/eyes.png | Bin 0 -> 4332 bytes public/editormd/emoji/facepunch.png | Bin 0 -> 4833 bytes public/editormd/emoji/factory.png | Bin 0 -> 5473 bytes public/editormd/emoji/fallen_leaf.png | Bin 0 -> 4890 bytes public/editormd/emoji/family.png | Bin 0 -> 7197 bytes public/editormd/emoji/fast_forward.png | Bin 0 -> 2979 bytes public/editormd/emoji/fax.png | Bin 0 -> 4650 bytes public/editormd/emoji/fearful.png | Bin 0 -> 5514 bytes public/editormd/emoji/feelsgood.png | Bin 0 -> 1096 bytes public/editormd/emoji/feet.png | Bin 0 -> 1529 bytes public/editormd/emoji/ferris_wheel.png | Bin 0 -> 6133 bytes public/editormd/emoji/file_folder.png | Bin 0 -> 4013 bytes public/editormd/emoji/finnadie.png | Bin 0 -> 1140 bytes public/editormd/emoji/fire.png | Bin 0 -> 3886 bytes public/editormd/emoji/fire_engine.png | Bin 0 -> 4771 bytes public/editormd/emoji/fireworks.png | Bin 0 -> 6248 bytes public/editormd/emoji/first_quarter_moon.png | Bin 0 -> 5967 bytes .../emoji/first_quarter_moon_with_face.png | Bin 0 -> 4280 bytes public/editormd/emoji/fish.png | Bin 0 -> 4687 bytes public/editormd/emoji/fish_cake.png | Bin 0 -> 5818 bytes .../editormd/emoji/fishing_pole_and_fish.png | Bin 0 -> 4470 bytes public/editormd/emoji/fist.png | Bin 0 -> 5758 bytes public/editormd/emoji/five.png | Bin 0 -> 3593 bytes public/editormd/emoji/flags.png | Bin 0 -> 6124 bytes public/editormd/emoji/flashlight.png | Bin 0 -> 4960 bytes public/editormd/emoji/floppy_disk.png | Bin 0 -> 3181 bytes .../editormd/emoji/flower_playing_cards.png | Bin 0 -> 3352 bytes public/editormd/emoji/flushed.png | Bin 0 -> 5553 bytes public/editormd/emoji/foggy.png | Bin 0 -> 4507 bytes public/editormd/emoji/football.png | Bin 0 -> 6712 bytes public/editormd/emoji/fork_and_knife.png | Bin 0 -> 3608 bytes public/editormd/emoji/fountain.png | Bin 0 -> 5037 bytes public/editormd/emoji/four.png | Bin 0 -> 3162 bytes public/editormd/emoji/four_leaf_clover.png | Bin 0 -> 5995 bytes public/editormd/emoji/fr.png | Bin 0 -> 3262 bytes public/editormd/emoji/free.png | Bin 0 -> 3605 bytes public/editormd/emoji/fried_shrimp.png | Bin 0 -> 7550 bytes public/editormd/emoji/fries.png | Bin 0 -> 6405 bytes public/editormd/emoji/frog.png | Bin 0 -> 4823 bytes public/editormd/emoji/frowning.png | Bin 0 -> 4657 bytes public/editormd/emoji/fu.png | Bin 0 -> 4101 bytes public/editormd/emoji/fuelpump.png | Bin 0 -> 4296 bytes public/editormd/emoji/full_moon.png | Bin 0 -> 6458 bytes public/editormd/emoji/full_moon_with_face.png | Bin 0 -> 7165 bytes public/editormd/emoji/game_die.png | Bin 0 -> 2956 bytes public/editormd/emoji/gb.png | Bin 0 -> 5842 bytes public/editormd/emoji/gem.png | Bin 0 -> 4807 bytes public/editormd/emoji/gemini.png | Bin 0 -> 4296 bytes public/editormd/emoji/ghost.png | Bin 0 -> 4513 bytes public/editormd/emoji/gift.png | Bin 0 -> 6712 bytes public/editormd/emoji/gift_heart.png | Bin 0 -> 6013 bytes public/editormd/emoji/girl.png | Bin 0 -> 6228 bytes .../editormd/emoji/globe_with_meridians.png | Bin 0 -> 5837 bytes public/editormd/emoji/goat.png | Bin 0 -> 4889 bytes public/editormd/emoji/goberserk.png | Bin 0 -> 1302 bytes public/editormd/emoji/godmode.png | Bin 0 -> 1001 bytes public/editormd/emoji/golf.png | Bin 0 -> 3548 bytes public/editormd/emoji/grapes.png | Bin 0 -> 5423 bytes public/editormd/emoji/green_apple.png | Bin 0 -> 6182 bytes public/editormd/emoji/green_book.png | Bin 0 -> 5071 bytes public/editormd/emoji/green_heart.png | Bin 0 -> 4412 bytes public/editormd/emoji/grey_exclamation.png | Bin 0 -> 742 bytes public/editormd/emoji/grey_question.png | Bin 0 -> 1057 bytes public/editormd/emoji/grimacing.png | Bin 0 -> 5263 bytes public/editormd/emoji/grin.png | Bin 0 -> 5627 bytes public/editormd/emoji/grinning.png | Bin 0 -> 5456 bytes public/editormd/emoji/guardsman.png | Bin 0 -> 3495 bytes public/editormd/emoji/guitar.png | Bin 0 -> 4375 bytes public/editormd/emoji/gun.png | Bin 0 -> 3146 bytes public/editormd/emoji/haircut.png | Bin 0 -> 7047 bytes public/editormd/emoji/hamburger.png | Bin 0 -> 5653 bytes public/editormd/emoji/hammer.png | Bin 0 -> 3670 bytes public/editormd/emoji/hamster.png | Bin 0 -> 7221 bytes public/editormd/emoji/hand.png | Bin 0 -> 4118 bytes public/editormd/emoji/handbag.png | Bin 0 -> 5449 bytes public/editormd/emoji/hankey.png | Bin 0 -> 4754 bytes public/editormd/emoji/hash.png | Bin 0 -> 3742 bytes public/editormd/emoji/hatched_chick.png | Bin 0 -> 5646 bytes public/editormd/emoji/hatching_chick.png | Bin 0 -> 5871 bytes public/editormd/emoji/headphones.png | Bin 0 -> 1894 bytes public/editormd/emoji/hear_no_evil.png | Bin 0 -> 6550 bytes public/editormd/emoji/heart.png | Bin 0 -> 3270 bytes public/editormd/emoji/heart_decoration.png | Bin 0 -> 3507 bytes public/editormd/emoji/heart_eyes.png | Bin 0 -> 5683 bytes public/editormd/emoji/heart_eyes_cat.png | Bin 0 -> 6176 bytes public/editormd/emoji/heartbeat.png | Bin 0 -> 4005 bytes public/editormd/emoji/heartpulse.png | Bin 0 -> 6235 bytes public/editormd/emoji/hearts.png | Bin 0 -> 2884 bytes public/editormd/emoji/heavy_check_mark.png | Bin 0 -> 924 bytes public/editormd/emoji/heavy_division_sign.png | Bin 0 -> 254 bytes public/editormd/emoji/heavy_dollar_sign.png | Bin 0 -> 1093 bytes .../editormd/emoji/heavy_exclamation_mark.png | Bin 0 -> 1315 bytes public/editormd/emoji/heavy_minus_sign.png | Bin 0 -> 155 bytes .../editormd/emoji/heavy_multiplication_x.png | Bin 0 -> 492 bytes public/editormd/emoji/heavy_plus_sign.png | Bin 0 -> 251 bytes public/editormd/emoji/helicopter.png | Bin 0 -> 4070 bytes public/editormd/emoji/herb.png | Bin 0 -> 5889 bytes public/editormd/emoji/hibiscus.png | Bin 0 -> 8322 bytes public/editormd/emoji/high_brightness.png | Bin 0 -> 4060 bytes public/editormd/emoji/high_heel.png | Bin 0 -> 4520 bytes public/editormd/emoji/hocho.png | Bin 0 -> 2455 bytes public/editormd/emoji/honey_pot.png | Bin 0 -> 5830 bytes public/editormd/emoji/honeybee.png | Bin 0 -> 5808 bytes public/editormd/emoji/horse.png | Bin 0 -> 4582 bytes public/editormd/emoji/horse_racing.png | Bin 0 -> 5905 bytes public/editormd/emoji/hospital.png | Bin 0 -> 4887 bytes public/editormd/emoji/hotel.png | Bin 0 -> 5123 bytes public/editormd/emoji/hotsprings.png | Bin 0 -> 3538 bytes public/editormd/emoji/hourglass.png | Bin 0 -> 4492 bytes .../editormd/emoji/hourglass_flowing_sand.png | Bin 0 -> 4291 bytes public/editormd/emoji/house.png | Bin 0 -> 3510 bytes public/editormd/emoji/house_with_garden.png | Bin 0 -> 6089 bytes public/editormd/emoji/hurtrealbad.png | Bin 0 -> 1424 bytes public/editormd/emoji/hushed.png | Bin 0 -> 4890 bytes public/editormd/emoji/ice_cream.png | Bin 0 -> 5468 bytes public/editormd/emoji/icecream.png | Bin 0 -> 4603 bytes public/editormd/emoji/id.png | Bin 0 -> 3905 bytes public/editormd/emoji/ideograph_advantage.png | Bin 0 -> 3088 bytes public/editormd/emoji/imp.png | Bin 0 -> 6207 bytes public/editormd/emoji/inbox_tray.png | Bin 0 -> 3686 bytes public/editormd/emoji/incoming_envelope.png | Bin 0 -> 2188 bytes .../emoji/information_desk_person.png | Bin 0 -> 6605 bytes public/editormd/emoji/information_source.png | Bin 0 -> 3670 bytes public/editormd/emoji/innocent.png | Bin 0 -> 6941 bytes public/editormd/emoji/interrobang.png | Bin 0 -> 2875 bytes public/editormd/emoji/iphone.png | Bin 0 -> 3449 bytes public/editormd/emoji/it.png | Bin 0 -> 3345 bytes public/editormd/emoji/izakaya_lantern.png | Bin 0 -> 4064 bytes public/editormd/emoji/jack_o_lantern.png | Bin 0 -> 5633 bytes public/editormd/emoji/japan.png | Bin 0 -> 4013 bytes public/editormd/emoji/japanese_castle.png | Bin 0 -> 4920 bytes public/editormd/emoji/japanese_goblin.png | Bin 0 -> 5159 bytes public/editormd/emoji/japanese_ogre.png | Bin 0 -> 7147 bytes public/editormd/emoji/jeans.png | Bin 0 -> 3470 bytes public/editormd/emoji/joy.png | Bin 0 -> 6278 bytes public/editormd/emoji/joy_cat.png | Bin 0 -> 7190 bytes public/editormd/emoji/jp.png | Bin 0 -> 2735 bytes public/editormd/emoji/key.png | Bin 0 -> 3452 bytes public/editormd/emoji/keycap_ten.png | Bin 0 -> 4093 bytes public/editormd/emoji/kimono.png | Bin 0 -> 4938 bytes public/editormd/emoji/kiss.png | Bin 0 -> 6276 bytes public/editormd/emoji/kissing.png | Bin 0 -> 4730 bytes public/editormd/emoji/kissing_cat.png | Bin 0 -> 6801 bytes public/editormd/emoji/kissing_closed_eyes.png | Bin 0 -> 5470 bytes public/editormd/emoji/kissing_face.png | Bin 0 -> 5470 bytes public/editormd/emoji/kissing_heart.png | Bin 0 -> 5660 bytes .../editormd/emoji/kissing_smiling_eyes.png | Bin 0 -> 4941 bytes public/editormd/emoji/koala.png | Bin 0 -> 5687 bytes public/editormd/emoji/koko.png | Bin 0 -> 2854 bytes public/editormd/emoji/kr.png | Bin 0 -> 4989 bytes public/editormd/emoji/large_blue_circle.png | Bin 0 -> 4637 bytes public/editormd/emoji/large_blue_diamond.png | Bin 0 -> 3732 bytes .../editormd/emoji/large_orange_diamond.png | Bin 0 -> 3788 bytes public/editormd/emoji/last_quarter_moon.png | Bin 0 -> 6149 bytes .../emoji/last_quarter_moon_with_face.png | Bin 0 -> 4328 bytes public/editormd/emoji/laughing.png | Bin 0 -> 6249 bytes public/editormd/emoji/leaves.png | Bin 0 -> 5571 bytes public/editormd/emoji/ledger.png | Bin 0 -> 5921 bytes public/editormd/emoji/left_luggage.png | Bin 0 -> 4025 bytes public/editormd/emoji/left_right_arrow.png | Bin 0 -> 3413 bytes .../emoji/leftwards_arrow_with_hook.png | Bin 0 -> 3775 bytes public/editormd/emoji/lemon.png | Bin 0 -> 6055 bytes public/editormd/emoji/leo.png | Bin 0 -> 4896 bytes public/editormd/emoji/leopard.png | Bin 0 -> 5348 bytes public/editormd/emoji/libra.png | Bin 0 -> 4202 bytes public/editormd/emoji/light_rail.png | Bin 0 -> 3792 bytes public/editormd/emoji/link.png | Bin 0 -> 2619 bytes public/editormd/emoji/lips.png | Bin 0 -> 3618 bytes public/editormd/emoji/lipstick.png | Bin 0 -> 3384 bytes public/editormd/emoji/lock.png | Bin 0 -> 3676 bytes public/editormd/emoji/lock_with_ink_pen.png | Bin 0 -> 4967 bytes public/editormd/emoji/lollipop.png | Bin 0 -> 5770 bytes public/editormd/emoji/loop.png | Bin 0 -> 3417 bytes public/editormd/emoji/loudspeaker.png | Bin 0 -> 6001 bytes public/editormd/emoji/love_hotel.png | Bin 0 -> 5941 bytes public/editormd/emoji/love_letter.png | Bin 0 -> 2402 bytes public/editormd/emoji/low_brightness.png | Bin 0 -> 2498 bytes public/editormd/emoji/m.png | Bin 0 -> 4734 bytes public/editormd/emoji/mag.png | Bin 0 -> 3023 bytes public/editormd/emoji/mag_right.png | Bin 0 -> 3629 bytes public/editormd/emoji/mahjong.png | Bin 0 -> 3265 bytes public/editormd/emoji/mailbox.png | Bin 0 -> 4196 bytes public/editormd/emoji/mailbox_closed.png | Bin 0 -> 4289 bytes public/editormd/emoji/mailbox_with_mail.png | Bin 0 -> 4581 bytes .../editormd/emoji/mailbox_with_no_mail.png | Bin 0 -> 3101 bytes public/editormd/emoji/man.png | Bin 0 -> 5943 bytes public/editormd/emoji/man_with_gua_pi_mao.png | Bin 0 -> 5324 bytes public/editormd/emoji/man_with_turban.png | Bin 0 -> 6452 bytes public/editormd/emoji/mans_shoe.png | Bin 0 -> 4749 bytes public/editormd/emoji/maple_leaf.png | Bin 0 -> 4450 bytes public/editormd/emoji/mask.png | Bin 0 -> 5165 bytes public/editormd/emoji/massage.png | Bin 0 -> 6036 bytes public/editormd/emoji/meat_on_bone.png | Bin 0 -> 5425 bytes public/editormd/emoji/mega.png | Bin 0 -> 4680 bytes public/editormd/emoji/melon.png | Bin 0 -> 8233 bytes public/editormd/emoji/memo.png | Bin 0 -> 4945 bytes public/editormd/emoji/mens.png | Bin 0 -> 3363 bytes public/editormd/emoji/metal.png | Bin 0 -> 3098 bytes public/editormd/emoji/metro.png | Bin 0 -> 3262 bytes public/editormd/emoji/microphone.png | Bin 0 -> 3680 bytes public/editormd/emoji/microscope.png | Bin 0 -> 4130 bytes public/editormd/emoji/milky_way.png | Bin 0 -> 5841 bytes public/editormd/emoji/minibus.png | Bin 0 -> 3097 bytes public/editormd/emoji/minidisc.png | Bin 0 -> 5594 bytes public/editormd/emoji/mobile_phone_off.png | Bin 0 -> 3445 bytes public/editormd/emoji/money_with_wings.png | Bin 0 -> 7584 bytes public/editormd/emoji/moneybag.png | Bin 0 -> 5500 bytes public/editormd/emoji/monkey.png | Bin 0 -> 4973 bytes public/editormd/emoji/monkey_face.png | Bin 0 -> 5348 bytes public/editormd/emoji/monorail.png | Bin 0 -> 4311 bytes public/editormd/emoji/mortar_board.png | Bin 0 -> 4164 bytes public/editormd/emoji/mount_fuji.png | Bin 0 -> 4880 bytes public/editormd/emoji/mountain_bicyclist.png | Bin 0 -> 9471 bytes public/editormd/emoji/mountain_cableway.png | Bin 0 -> 4313 bytes public/editormd/emoji/mountain_railway.png | Bin 0 -> 7262 bytes public/editormd/emoji/mouse.png | Bin 0 -> 6606 bytes public/editormd/emoji/mouse2.png | Bin 0 -> 4075 bytes public/editormd/emoji/movie_camera.png | Bin 0 -> 4029 bytes public/editormd/emoji/moyai.png | Bin 0 -> 2166 bytes public/editormd/emoji/muscle.png | Bin 0 -> 4652 bytes public/editormd/emoji/mushroom.png | Bin 0 -> 4887 bytes public/editormd/emoji/musical_keyboard.png | Bin 0 -> 1919 bytes public/editormd/emoji/musical_note.png | Bin 0 -> 3153 bytes public/editormd/emoji/musical_score.png | Bin 0 -> 1434 bytes public/editormd/emoji/mute.png | Bin 0 -> 6635 bytes public/editormd/emoji/nail_care.png | Bin 0 -> 5800 bytes public/editormd/emoji/name_badge.png | Bin 0 -> 3985 bytes public/editormd/emoji/neckbeard.png | Bin 0 -> 6225 bytes public/editormd/emoji/necktie.png | Bin 0 -> 6116 bytes .../emoji/negative_squared_cross_mark.png | Bin 0 -> 3853 bytes public/editormd/emoji/neutral_face.png | Bin 0 -> 4705 bytes public/editormd/emoji/new.png | Bin 0 -> 3927 bytes public/editormd/emoji/new_moon.png | Bin 0 -> 5276 bytes public/editormd/emoji/new_moon_with_face.png | Bin 0 -> 6708 bytes public/editormd/emoji/newspaper.png | Bin 0 -> 5137 bytes public/editormd/emoji/ng.png | Bin 0 -> 4201 bytes public/editormd/emoji/nine.png | Bin 0 -> 3757 bytes public/editormd/emoji/no_bell.png | Bin 0 -> 5944 bytes public/editormd/emoji/no_bicycles.png | Bin 0 -> 5661 bytes public/editormd/emoji/no_entry.png | Bin 0 -> 3512 bytes public/editormd/emoji/no_entry_sign.png | Bin 0 -> 3287 bytes public/editormd/emoji/no_good.png | Bin 0 -> 7034 bytes public/editormd/emoji/no_mobile_phones.png | Bin 0 -> 5083 bytes public/editormd/emoji/no_mouth.png | Bin 0 -> 4559 bytes public/editormd/emoji/no_pedestrians.png | Bin 0 -> 5485 bytes public/editormd/emoji/no_smoking.png | Bin 0 -> 4088 bytes public/editormd/emoji/non-potable_water.png | Bin 0 -> 5202 bytes public/editormd/emoji/nose.png | Bin 0 -> 3687 bytes public/editormd/emoji/notebook.png | Bin 0 -> 6001 bytes .../emoji/notebook_with_decorative_cover.png | Bin 0 -> 5262 bytes public/editormd/emoji/notes.png | Bin 0 -> 1518 bytes public/editormd/emoji/nut_and_bolt.png | Bin 0 -> 2169 bytes public/editormd/emoji/o.png | Bin 0 -> 2538 bytes public/editormd/emoji/o2.png | Bin 0 -> 3498 bytes public/editormd/emoji/ocean.png | Bin 0 -> 5777 bytes public/editormd/emoji/octocat.png | Bin 0 -> 3721 bytes public/editormd/emoji/octopus.png | Bin 0 -> 5779 bytes public/editormd/emoji/oden.png | Bin 0 -> 5543 bytes public/editormd/emoji/office.png | Bin 0 -> 5156 bytes public/editormd/emoji/ok.png | Bin 0 -> 4140 bytes public/editormd/emoji/ok_hand.png | Bin 0 -> 4598 bytes public/editormd/emoji/ok_woman.png | Bin 0 -> 7527 bytes public/editormd/emoji/older_man.png | Bin 0 -> 6698 bytes public/editormd/emoji/older_woman.png | Bin 0 -> 5977 bytes public/editormd/emoji/on.png | Bin 0 -> 1423 bytes public/editormd/emoji/oncoming_automobile.png | Bin 0 -> 7469 bytes public/editormd/emoji/oncoming_bus.png | Bin 0 -> 5300 bytes public/editormd/emoji/oncoming_police_car.png | Bin 0 -> 5683 bytes public/editormd/emoji/oncoming_taxi.png | Bin 0 -> 6287 bytes public/editormd/emoji/one.png | Bin 0 -> 2825 bytes public/editormd/emoji/open_file_folder.png | Bin 0 -> 4292 bytes public/editormd/emoji/open_hands.png | Bin 0 -> 4932 bytes public/editormd/emoji/open_mouth.png | Bin 0 -> 4422 bytes public/editormd/emoji/ophiuchus.png | Bin 0 -> 4434 bytes public/editormd/emoji/orange_book.png | Bin 0 -> 4991 bytes public/editormd/emoji/outbox_tray.png | Bin 0 -> 3682 bytes public/editormd/emoji/ox.png | Bin 0 -> 5935 bytes public/editormd/emoji/package.png | Bin 0 -> 5720 bytes public/editormd/emoji/page_facing_up.png | Bin 0 -> 1722 bytes public/editormd/emoji/page_with_curl.png | Bin 0 -> 3715 bytes public/editormd/emoji/pager.png | Bin 0 -> 3957 bytes public/editormd/emoji/palm_tree.png | Bin 0 -> 3645 bytes public/editormd/emoji/panda_face.png | Bin 0 -> 4814 bytes public/editormd/emoji/paperclip.png | Bin 0 -> 2478 bytes public/editormd/emoji/parking.png | Bin 0 -> 3083 bytes .../editormd/emoji/part_alternation_mark.png | Bin 0 -> 2681 bytes public/editormd/emoji/partly_sunny.png | Bin 0 -> 5169 bytes public/editormd/emoji/passport_control.png | Bin 0 -> 4018 bytes public/editormd/emoji/paw_prints.png | Bin 0 -> 2417 bytes public/editormd/emoji/peach.png | Bin 0 -> 5918 bytes public/editormd/emoji/pear.png | Bin 0 -> 6934 bytes public/editormd/emoji/pencil.png | Bin 0 -> 4945 bytes public/editormd/emoji/pencil2.png | Bin 0 -> 4348 bytes public/editormd/emoji/penguin.png | Bin 0 -> 4679 bytes public/editormd/emoji/pensive.png | Bin 0 -> 5060 bytes public/editormd/emoji/performing_arts.png | Bin 0 -> 6287 bytes public/editormd/emoji/persevere.png | Bin 0 -> 5213 bytes public/editormd/emoji/person_frowning.png | Bin 0 -> 4826 bytes .../editormd/emoji/person_with_blond_hair.png | Bin 0 -> 6568 bytes .../emoji/person_with_pouting_face.png | Bin 0 -> 5428 bytes public/editormd/emoji/phone.png | Bin 0 -> 5495 bytes public/editormd/emoji/pig.png | Bin 0 -> 5996 bytes public/editormd/emoji/pig2.png | Bin 0 -> 4677 bytes public/editormd/emoji/pig_nose.png | Bin 0 -> 4622 bytes public/editormd/emoji/pill.png | Bin 0 -> 5022 bytes public/editormd/emoji/pineapple.png | Bin 0 -> 5634 bytes public/editormd/emoji/pisces.png | Bin 0 -> 4301 bytes public/editormd/emoji/pizza.png | Bin 0 -> 5273 bytes public/editormd/emoji/plus1.png | Bin 0 -> 5057 bytes public/editormd/emoji/point_down.png | Bin 0 -> 3225 bytes public/editormd/emoji/point_left.png | Bin 0 -> 3026 bytes public/editormd/emoji/point_right.png | Bin 0 -> 3048 bytes public/editormd/emoji/point_up.png | Bin 0 -> 3431 bytes public/editormd/emoji/point_up_2.png | Bin 0 -> 3181 bytes public/editormd/emoji/police_car.png | Bin 0 -> 3349 bytes public/editormd/emoji/poodle.png | Bin 0 -> 6852 bytes public/editormd/emoji/poop.png | Bin 0 -> 4754 bytes public/editormd/emoji/post_office.png | Bin 0 -> 5136 bytes public/editormd/emoji/postal_horn.png | Bin 0 -> 4735 bytes public/editormd/emoji/postbox.png | Bin 0 -> 3388 bytes public/editormd/emoji/potable_water.png | Bin 0 -> 3934 bytes public/editormd/emoji/pouch.png | Bin 0 -> 4642 bytes public/editormd/emoji/poultry_leg.png | Bin 0 -> 4200 bytes public/editormd/emoji/pound.png | Bin 0 -> 4167 bytes public/editormd/emoji/pouting_cat.png | Bin 0 -> 4918 bytes public/editormd/emoji/pray.png | Bin 0 -> 6203 bytes public/editormd/emoji/princess.png | Bin 0 -> 7920 bytes public/editormd/emoji/punch.png | Bin 0 -> 4833 bytes public/editormd/emoji/purple_heart.png | Bin 0 -> 4244 bytes public/editormd/emoji/purse.png | Bin 0 -> 5033 bytes public/editormd/emoji/pushpin.png | Bin 0 -> 3793 bytes .../emoji/put_litter_in_its_place.png | Bin 0 -> 4091 bytes public/editormd/emoji/question.png | Bin 0 -> 1711 bytes public/editormd/emoji/rabbit.png | Bin 0 -> 5677 bytes public/editormd/emoji/rabbit2.png | Bin 0 -> 4425 bytes public/editormd/emoji/racehorse.png | Bin 0 -> 4681 bytes public/editormd/emoji/radio.png | Bin 0 -> 6150 bytes public/editormd/emoji/radio_button.png | Bin 0 -> 2198 bytes public/editormd/emoji/rage.png | Bin 0 -> 5277 bytes public/editormd/emoji/rage1.png | Bin 0 -> 1065 bytes public/editormd/emoji/rage2.png | Bin 0 -> 1065 bytes public/editormd/emoji/rage3.png | Bin 0 -> 1099 bytes public/editormd/emoji/rage4.png | Bin 0 -> 1255 bytes public/editormd/emoji/railway_car.png | Bin 0 -> 3628 bytes public/editormd/emoji/rainbow.png | Bin 0 -> 5238 bytes public/editormd/emoji/raised_hand.png | Bin 0 -> 4118 bytes public/editormd/emoji/raised_hands.png | Bin 0 -> 5375 bytes public/editormd/emoji/raising_hand.png | Bin 0 -> 6177 bytes public/editormd/emoji/ram.png | Bin 0 -> 6531 bytes public/editormd/emoji/ramen.png | Bin 0 -> 6416 bytes public/editormd/emoji/rat.png | Bin 0 -> 5434 bytes public/editormd/emoji/recycle.png | Bin 0 -> 3704 bytes public/editormd/emoji/red_car.png | Bin 0 -> 4267 bytes public/editormd/emoji/red_circle.png | Bin 0 -> 3937 bytes public/editormd/emoji/registered.png | Bin 0 -> 1613 bytes public/editormd/emoji/relaxed.png | Bin 0 -> 5360 bytes public/editormd/emoji/relieved.png | Bin 0 -> 5363 bytes public/editormd/emoji/repeat.png | Bin 0 -> 4009 bytes public/editormd/emoji/repeat_one.png | Bin 0 -> 4287 bytes public/editormd/emoji/restroom.png | Bin 0 -> 4135 bytes public/editormd/emoji/revolving_hearts.png | Bin 0 -> 5472 bytes public/editormd/emoji/rewind.png | Bin 0 -> 2937 bytes public/editormd/emoji/ribbon.png | Bin 0 -> 5581 bytes public/editormd/emoji/rice.png | Bin 0 -> 4606 bytes public/editormd/emoji/rice_ball.png | Bin 0 -> 5371 bytes public/editormd/emoji/rice_cracker.png | Bin 0 -> 7787 bytes public/editormd/emoji/rice_scene.png | Bin 0 -> 6245 bytes public/editormd/emoji/ring.png | Bin 0 -> 5232 bytes public/editormd/emoji/rocket.png | Bin 0 -> 5388 bytes public/editormd/emoji/roller_coaster.png | Bin 0 -> 5052 bytes public/editormd/emoji/rooster.png | Bin 0 -> 6168 bytes public/editormd/emoji/rose.png | Bin 0 -> 4167 bytes public/editormd/emoji/rotating_light.png | Bin 0 -> 6620 bytes public/editormd/emoji/round_pushpin.png | Bin 0 -> 1915 bytes public/editormd/emoji/rowboat.png | Bin 0 -> 5309 bytes public/editormd/emoji/ru.png | Bin 0 -> 3866 bytes public/editormd/emoji/rugby_football.png | Bin 0 -> 7781 bytes public/editormd/emoji/runner.png | Bin 0 -> 3137 bytes public/editormd/emoji/running.png | Bin 0 -> 3137 bytes .../emoji/running_shirt_with_sash.png | Bin 0 -> 5701 bytes public/editormd/emoji/sa.png | Bin 0 -> 3556 bytes public/editormd/emoji/sagittarius.png | Bin 0 -> 4505 bytes public/editormd/emoji/sailboat.png | Bin 0 -> 3833 bytes public/editormd/emoji/sake.png | Bin 0 -> 5073 bytes public/editormd/emoji/sandal.png | Bin 0 -> 3974 bytes public/editormd/emoji/santa.png | Bin 0 -> 6271 bytes public/editormd/emoji/satellite.png | Bin 0 -> 4867 bytes public/editormd/emoji/satisfied.png | Bin 0 -> 6249 bytes public/editormd/emoji/saxophone.png | Bin 0 -> 4252 bytes public/editormd/emoji/school.png | Bin 0 -> 5446 bytes public/editormd/emoji/school_satchel.png | Bin 0 -> 5734 bytes public/editormd/emoji/scissors.png | Bin 0 -> 3837 bytes public/editormd/emoji/scorpius.png | Bin 0 -> 4566 bytes public/editormd/emoji/scream.png | Bin 0 -> 6305 bytes public/editormd/emoji/scream_cat.png | Bin 0 -> 6844 bytes public/editormd/emoji/scroll.png | Bin 0 -> 6749 bytes public/editormd/emoji/seat.png | Bin 0 -> 6059 bytes public/editormd/emoji/secret.png | Bin 0 -> 5364 bytes public/editormd/emoji/see_no_evil.png | Bin 0 -> 6828 bytes public/editormd/emoji/seedling.png | Bin 0 -> 2190 bytes public/editormd/emoji/seven.png | Bin 0 -> 3055 bytes public/editormd/emoji/shaved_ice.png | Bin 0 -> 5803 bytes public/editormd/emoji/sheep.png | Bin 0 -> 4732 bytes public/editormd/emoji/shell.png | Bin 0 -> 5115 bytes public/editormd/emoji/ship.png | Bin 0 -> 4157 bytes public/editormd/emoji/shipit.png | Bin 0 -> 9351 bytes public/editormd/emoji/shirt.png | Bin 0 -> 4676 bytes public/editormd/emoji/shit.png | Bin 0 -> 4754 bytes public/editormd/emoji/shoe.png | Bin 0 -> 4799 bytes public/editormd/emoji/shower.png | Bin 0 -> 7520 bytes public/editormd/emoji/signal_strength.png | Bin 0 -> 3231 bytes public/editormd/emoji/simple_smile.png | Bin 0 -> 2648 bytes public/editormd/emoji/six.png | Bin 0 -> 3785 bytes public/editormd/emoji/six_pointed_star.png | Bin 0 -> 4854 bytes public/editormd/emoji/ski.png | Bin 0 -> 4167 bytes public/editormd/emoji/skull.png | Bin 0 -> 2428 bytes public/editormd/emoji/sleeping.png | Bin 0 -> 5338 bytes public/editormd/emoji/sleepy.png | Bin 0 -> 5797 bytes public/editormd/emoji/slot_machine.png | Bin 0 -> 4590 bytes public/editormd/emoji/small_blue_diamond.png | Bin 0 -> 1817 bytes .../editormd/emoji/small_orange_diamond.png | Bin 0 -> 1936 bytes public/editormd/emoji/small_red_triangle.png | Bin 0 -> 2054 bytes .../emoji/small_red_triangle_down.png | Bin 0 -> 2157 bytes public/editormd/emoji/smile.png | Bin 0 -> 5801 bytes public/editormd/emoji/smile_cat.png | Bin 0 -> 6117 bytes public/editormd/emoji/smiley.png | Bin 0 -> 5675 bytes public/editormd/emoji/smiley_cat.png | Bin 0 -> 6083 bytes public/editormd/emoji/smiling_imp.png | Bin 0 -> 7040 bytes public/editormd/emoji/smirk.png | Bin 0 -> 5217 bytes public/editormd/emoji/smirk_cat.png | Bin 0 -> 6062 bytes public/editormd/emoji/smoking.png | Bin 0 -> 2738 bytes public/editormd/emoji/snail.png | Bin 0 -> 6657 bytes public/editormd/emoji/snake.png | Bin 0 -> 4069 bytes public/editormd/emoji/snowboarder.png | Bin 0 -> 5356 bytes public/editormd/emoji/snowflake.png | Bin 0 -> 5539 bytes public/editormd/emoji/snowman.png | Bin 0 -> 4658 bytes public/editormd/emoji/sob.png | Bin 0 -> 5402 bytes public/editormd/emoji/soccer.png | Bin 0 -> 4846 bytes public/editormd/emoji/soon.png | Bin 0 -> 1472 bytes public/editormd/emoji/sos.png | Bin 0 -> 4262 bytes public/editormd/emoji/sound.png | Bin 0 -> 5024 bytes public/editormd/emoji/space_invader.png | Bin 0 -> 4296 bytes public/editormd/emoji/spades.png | Bin 0 -> 1649 bytes public/editormd/emoji/spaghetti.png | Bin 0 -> 6929 bytes public/editormd/emoji/sparkle.png | Bin 0 -> 6237 bytes public/editormd/emoji/sparkler.png | Bin 0 -> 5662 bytes public/editormd/emoji/sparkles.png | Bin 0 -> 2209 bytes public/editormd/emoji/sparkling_heart.png | Bin 0 -> 5357 bytes public/editormd/emoji/speak_no_evil.png | Bin 0 -> 5977 bytes public/editormd/emoji/speaker.png | Bin 0 -> 5173 bytes public/editormd/emoji/speech_balloon.png | Bin 0 -> 2130 bytes public/editormd/emoji/speedboat.png | Bin 0 -> 3474 bytes public/editormd/emoji/squirrel.png | Bin 0 -> 9351 bytes public/editormd/emoji/star.png | Bin 0 -> 3628 bytes public/editormd/emoji/star2.png | Bin 0 -> 4068 bytes public/editormd/emoji/stars.png | Bin 0 -> 4341 bytes public/editormd/emoji/station.png | Bin 0 -> 4836 bytes public/editormd/emoji/statue_of_liberty.png | Bin 0 -> 5996 bytes public/editormd/emoji/steam_locomotive.png | Bin 0 -> 5159 bytes public/editormd/emoji/stew.png | Bin 0 -> 5299 bytes public/editormd/emoji/straight_ruler.png | Bin 0 -> 3704 bytes public/editormd/emoji/strawberry.png | Bin 0 -> 5477 bytes public/editormd/emoji/stuck_out_tongue.png | Bin 0 -> 5126 bytes .../emoji/stuck_out_tongue_closed_eyes.png | Bin 0 -> 5706 bytes .../emoji/stuck_out_tongue_winking_eye.png | Bin 0 -> 5919 bytes public/editormd/emoji/sun_with_face.png | Bin 0 -> 7958 bytes public/editormd/emoji/sunflower.png | Bin 0 -> 6567 bytes public/editormd/emoji/sunglasses.png | Bin 0 -> 5664 bytes public/editormd/emoji/sunny.png | Bin 0 -> 3709 bytes public/editormd/emoji/sunrise.png | Bin 0 -> 3731 bytes .../editormd/emoji/sunrise_over_mountains.png | Bin 0 -> 6455 bytes public/editormd/emoji/surfer.png | Bin 0 -> 6259 bytes public/editormd/emoji/sushi.png | Bin 0 -> 5234 bytes public/editormd/emoji/suspect.png | Bin 0 -> 988 bytes public/editormd/emoji/suspension_railway.png | Bin 0 -> 3937 bytes public/editormd/emoji/sweat.png | Bin 0 -> 5447 bytes public/editormd/emoji/sweat_drops.png | Bin 0 -> 4782 bytes public/editormd/emoji/sweat_smile.png | Bin 0 -> 6476 bytes public/editormd/emoji/sweet_potato.png | Bin 0 -> 5551 bytes public/editormd/emoji/swimmer.png | Bin 0 -> 4335 bytes public/editormd/emoji/symbols.png | Bin 0 -> 5434 bytes public/editormd/emoji/syringe.png | Bin 0 -> 3027 bytes public/editormd/emoji/tada.png | Bin 0 -> 5918 bytes public/editormd/emoji/tanabata_tree.png | Bin 0 -> 4296 bytes public/editormd/emoji/tangerine.png | Bin 0 -> 6640 bytes public/editormd/emoji/taurus.png | Bin 0 -> 4733 bytes public/editormd/emoji/taxi.png | Bin 0 -> 3712 bytes public/editormd/emoji/tea.png | Bin 0 -> 5946 bytes public/editormd/emoji/telephone.png | Bin 0 -> 5495 bytes public/editormd/emoji/telephone_receiver.png | Bin 0 -> 2001 bytes public/editormd/emoji/telescope.png | Bin 0 -> 3252 bytes public/editormd/emoji/tennis.png | Bin 0 -> 5945 bytes public/editormd/emoji/tent.png | Bin 0 -> 4372 bytes public/editormd/emoji/thought_balloon.png | Bin 0 -> 2495 bytes public/editormd/emoji/three.png | Bin 0 -> 3758 bytes public/editormd/emoji/thumbsdown.png | Bin 0 -> 5070 bytes public/editormd/emoji/thumbsup.png | Bin 0 -> 5057 bytes public/editormd/emoji/ticket.png | Bin 0 -> 3047 bytes public/editormd/emoji/tiger.png | Bin 0 -> 6051 bytes public/editormd/emoji/tiger2.png | Bin 0 -> 5744 bytes public/editormd/emoji/tired_face.png | Bin 0 -> 6105 bytes public/editormd/emoji/tm.png | Bin 0 -> 836 bytes public/editormd/emoji/toilet.png | Bin 0 -> 1733 bytes public/editormd/emoji/tokyo_tower.png | Bin 0 -> 4698 bytes public/editormd/emoji/tomato.png | Bin 0 -> 5683 bytes public/editormd/emoji/tongue.png | Bin 0 -> 3573 bytes public/editormd/emoji/top.png | Bin 0 -> 3785 bytes public/editormd/emoji/tophat.png | Bin 0 -> 3009 bytes public/editormd/emoji/tractor.png | Bin 0 -> 5670 bytes public/editormd/emoji/traffic_light.png | Bin 0 -> 3515 bytes public/editormd/emoji/train.png | Bin 0 -> 3821 bytes public/editormd/emoji/train2.png | Bin 0 -> 4817 bytes public/editormd/emoji/tram.png | Bin 0 -> 4869 bytes .../emoji/triangular_flag_on_post.png | Bin 0 -> 1399 bytes public/editormd/emoji/triangular_ruler.png | Bin 0 -> 2706 bytes public/editormd/emoji/trident.png | Bin 0 -> 4827 bytes public/editormd/emoji/triumph.png | Bin 0 -> 6136 bytes public/editormd/emoji/trolleybus.png | Bin 0 -> 4304 bytes public/editormd/emoji/trollface.png | Bin 0 -> 4845 bytes public/editormd/emoji/trophy.png | Bin 0 -> 5520 bytes public/editormd/emoji/tropical_drink.png | Bin 0 -> 4189 bytes public/editormd/emoji/tropical_fish.png | Bin 0 -> 5797 bytes public/editormd/emoji/truck.png | Bin 0 -> 3671 bytes public/editormd/emoji/trumpet.png | Bin 0 -> 4373 bytes public/editormd/emoji/tshirt.png | Bin 0 -> 4676 bytes public/editormd/emoji/tulip.png | Bin 0 -> 6065 bytes public/editormd/emoji/turtle.png | Bin 0 -> 5328 bytes public/editormd/emoji/tv.png | Bin 0 -> 5242 bytes .../emoji/twisted_rightwards_arrows.png | Bin 0 -> 4313 bytes public/editormd/emoji/two.png | Bin 0 -> 3518 bytes public/editormd/emoji/two_hearts.png | Bin 0 -> 3512 bytes .../editormd/emoji/two_men_holding_hands.png | Bin 0 -> 6994 bytes .../emoji/two_women_holding_hands.png | Bin 0 -> 7633 bytes public/editormd/emoji/u5272.png | Bin 0 -> 4533 bytes public/editormd/emoji/u5408.png | Bin 0 -> 3890 bytes public/editormd/emoji/u55b6.png | Bin 0 -> 3398 bytes public/editormd/emoji/u6307.png | Bin 0 -> 4075 bytes public/editormd/emoji/u6708.png | Bin 0 -> 2954 bytes public/editormd/emoji/u6709.png | Bin 0 -> 3164 bytes public/editormd/emoji/u6e80.png | Bin 0 -> 4389 bytes public/editormd/emoji/u7121.png | Bin 0 -> 3921 bytes public/editormd/emoji/u7533.png | Bin 0 -> 3035 bytes public/editormd/emoji/u7981.png | Bin 0 -> 5175 bytes public/editormd/emoji/u7a7a.png | Bin 0 -> 4179 bytes public/editormd/emoji/uk.png | Bin 0 -> 5842 bytes public/editormd/emoji/umbrella.png | Bin 0 -> 4745 bytes public/editormd/emoji/unamused.png | Bin 0 -> 5222 bytes public/editormd/emoji/underage.png | Bin 0 -> 5722 bytes public/editormd/emoji/unlock.png | Bin 0 -> 3551 bytes public/editormd/emoji/up.png | Bin 0 -> 3721 bytes public/editormd/emoji/us.png | Bin 0 -> 6191 bytes public/editormd/emoji/v.png | Bin 0 -> 4669 bytes .../editormd/emoji/vertical_traffic_light.png | Bin 0 -> 3362 bytes public/editormd/emoji/vhs.png | Bin 0 -> 3009 bytes public/editormd/emoji/vibration_mode.png | Bin 0 -> 3848 bytes public/editormd/emoji/video_camera.png | Bin 0 -> 5061 bytes public/editormd/emoji/video_game.png | Bin 0 -> 4947 bytes public/editormd/emoji/violin.png | Bin 0 -> 4915 bytes public/editormd/emoji/virgo.png | Bin 0 -> 4869 bytes public/editormd/emoji/volcano.png | Bin 0 -> 6146 bytes public/editormd/emoji/vs.png | Bin 0 -> 3380 bytes public/editormd/emoji/walking.png | Bin 0 -> 2468 bytes .../editormd/emoji/waning_crescent_moon.png | Bin 0 -> 5885 bytes public/editormd/emoji/waning_gibbous_moon.png | Bin 0 -> 6443 bytes public/editormd/emoji/warning.png | Bin 0 -> 3085 bytes public/editormd/emoji/watch.png | Bin 0 -> 5189 bytes public/editormd/emoji/water_buffalo.png | Bin 0 -> 4774 bytes public/editormd/emoji/watermelon.png | Bin 0 -> 5501 bytes public/editormd/emoji/wave.png | Bin 0 -> 5046 bytes public/editormd/emoji/wavy_dash.png | Bin 0 -> 676 bytes .../editormd/emoji/waxing_crescent_moon.png | Bin 0 -> 6198 bytes public/editormd/emoji/waxing_gibbous_moon.png | Bin 0 -> 6357 bytes public/editormd/emoji/wc.png | Bin 0 -> 4068 bytes public/editormd/emoji/weary.png | Bin 0 -> 6198 bytes public/editormd/emoji/wedding.png | Bin 0 -> 5842 bytes public/editormd/emoji/whale.png | Bin 0 -> 4923 bytes public/editormd/emoji/whale2.png | Bin 0 -> 5944 bytes public/editormd/emoji/wheelchair.png | Bin 0 -> 4206 bytes public/editormd/emoji/white_check_mark.png | Bin 0 -> 3445 bytes public/editormd/emoji/white_circle.png | Bin 0 -> 2470 bytes public/editormd/emoji/white_flower.png | Bin 0 -> 4391 bytes public/editormd/emoji/white_large_square.png | Bin 0 -> 1297 bytes .../emoji/white_medium_small_square.png | Bin 0 -> 1262 bytes public/editormd/emoji/white_medium_square.png | Bin 0 -> 1608 bytes public/editormd/emoji/white_small_square.png | Bin 0 -> 961 bytes public/editormd/emoji/white_square_button.png | Bin 0 -> 1583 bytes public/editormd/emoji/wind_chime.png | Bin 0 -> 3487 bytes public/editormd/emoji/wine_glass.png | Bin 0 -> 3151 bytes public/editormd/emoji/wink.png | Bin 0 -> 5126 bytes public/editormd/emoji/wolf.png | Bin 0 -> 4845 bytes public/editormd/emoji/woman.png | Bin 0 -> 6895 bytes public/editormd/emoji/womans_clothes.png | Bin 0 -> 4075 bytes public/editormd/emoji/womans_hat.png | Bin 0 -> 8101 bytes public/editormd/emoji/womens.png | Bin 0 -> 3765 bytes public/editormd/emoji/worried.png | Bin 0 -> 5100 bytes public/editormd/emoji/wrench.png | Bin 0 -> 2775 bytes public/editormd/emoji/x.png | Bin 0 -> 2044 bytes public/editormd/emoji/yellow_heart.png | Bin 0 -> 4331 bytes public/editormd/emoji/yen.png | Bin 0 -> 4926 bytes public/editormd/emoji/yum.png | Bin 0 -> 5777 bytes public/editormd/emoji/zap.png | Bin 0 -> 2233 bytes public/editormd/emoji/zero.png | Bin 0 -> 3590 bytes public/editormd/emoji/zzz.png | Bin 0 -> 1983 bytes public/editormd/examples/@links.html | 135 + public/editormd/examples/auto-height.html | 55 + public/editormd/examples/change-mode.html | 508 + public/editormd/examples/code-fold.html | 44 + public/editormd/examples/css/style.css | 94 + .../examples/custom-keyboard-shortcuts.html | 118 + public/editormd/examples/custom-toolbar.html | 178 + public/editormd/examples/define-plugin.html | 151 + .../examples/delay-renderer-preview.html | 56 + .../examples/dynamic-create-editormd.html | 47 + public/editormd/examples/emoji.html | 191 + public/editormd/examples/extends.html | 153 + public/editormd/examples/external-use.html | 119 + public/editormd/examples/flowchart.html | 53 + public/editormd/examples/form-get-value.html | 92 + public/editormd/examples/full.html | 231 + public/editormd/examples/goto-line.html | 84 + ...markdown-to-html-custom-toc-container.html | 180 + .../html-preview-markdown-to-html.html | 142 + .../editormd/examples/html-tags-decode.html | 119 + .../examples/image-cross-domain-upload.html | 109 + public/editormd/examples/image-upload.html | 68 + public/editormd/examples/images/4.jpg | Bin 0 -> 121969 bytes public/editormd/examples/images/7.jpg | Bin 0 -> 95090 bytes public/editormd/examples/images/8.jpg | Bin 0 -> 17555 bytes .../examples/images/editormd-screenshot.png | Bin 0 -> 81096 bytes public/editormd/examples/index.html | 356 + public/editormd/examples/js/jquery.min.js | 4 + public/editormd/examples/js/require.min.js | 36 + public/editormd/examples/js/sea.js | 2 + public/editormd/examples/js/seajs-main.js | 74 + public/editormd/examples/js/zepto.min.js | 2 + public/editormd/examples/katex.html | 192 + .../examples/manually-load-modules.html | 109 + public/editormd/examples/multi-editormd.html | 64 + public/editormd/examples/multi-languages.html | 89 + public/editormd/examples/on-off.html | 103 + public/editormd/examples/onchange.html | 49 + public/editormd/examples/onfullscreen.html | 55 + public/editormd/examples/onload.html | 52 + .../examples/onpreviewing-onpreviewed.html | 55 + public/editormd/examples/onresize.html | 49 + .../examples/onscroll-onpreviewscroll.html | 63 + .../editormd/examples/onwatch-onunwatch.html | 51 + public/editormd/examples/page-break.html | 87 + .../examples/php/cross-domain-upload.php | 54 + .../examples/php/editormd.uploader.class.php | 341 + public/editormd/examples/php/post.php | 18 + public/editormd/examples/php/upload.php | 51 + .../examples/php/upload_callback.html | 35 + public/editormd/examples/readonly.html | 60 + public/editormd/examples/resettings.html | 144 + public/editormd/examples/search-replace.html | 46 + .../editormd/examples/sequence-diagram.html | 65 + .../examples/set-get-replace-selection.html | 110 + public/editormd/examples/simple.html | 76 + public/editormd/examples/sync-scrolling.html | 70 + public/editormd/examples/task-lists.html | 65 + public/editormd/examples/test.md | 365 + public/editormd/examples/themes.html | 207 + public/editormd/examples/toc.html | 199 + .../editormd/examples/toolbar-auto-fixed.html | 122 + public/editormd/examples/use-requirejs.html | 174 + public/editormd/examples/use-seajs.html | 176 + public/editormd/examples/use-zepto.html | 126 + public/editormd/fonts/FontAwesome.otf | Bin 0 -> 93888 bytes public/editormd/fonts/editormd-logo.eot | Bin 0 -> 1320 bytes public/editormd/fonts/editormd-logo.svg | 11 + public/editormd/fonts/editormd-logo.ttf | Bin 0 -> 1156 bytes public/editormd/fonts/editormd-logo.woff | Bin 0 -> 1232 bytes public/editormd/fonts/fontawesome-webfont.eot | Bin 0 -> 60767 bytes public/editormd/fonts/fontawesome-webfont.svg | 565 ++ public/editormd/fonts/fontawesome-webfont.ttf | Bin 0 -> 122092 bytes .../editormd/fonts/fontawesome-webfont.woff | Bin 0 -> 71508 bytes .../editormd/fonts/fontawesome-webfont.woff2 | Bin 0 -> 56780 bytes public/editormd/images/loading.gif | Bin 0 -> 7726 bytes public/editormd/images/loading@2x.gif | Bin 0 -> 16166 bytes public/editormd/images/loading@3x.gif | Bin 0 -> 21727 bytes .../images/logos/editormd-favicon-16x16.ico | Bin 0 -> 1150 bytes .../images/logos/editormd-favicon-24x24.ico | Bin 0 -> 1150 bytes .../images/logos/editormd-favicon-32x32.ico | Bin 0 -> 5430 bytes .../images/logos/editormd-favicon-48x48.ico | Bin 0 -> 15086 bytes .../images/logos/editormd-favicon-64x64.ico | Bin 0 -> 32038 bytes .../images/logos/editormd-logo-114x114.png | Bin 0 -> 5869 bytes .../images/logos/editormd-logo-120x120.png | Bin 0 -> 6141 bytes .../images/logos/editormd-logo-144x144.png | Bin 0 -> 7545 bytes .../images/logos/editormd-logo-16x16.png | Bin 0 -> 1448 bytes .../images/logos/editormd-logo-180x180.png | Bin 0 -> 7963 bytes .../images/logos/editormd-logo-240x240.png | Bin 0 -> 10470 bytes .../images/logos/editormd-logo-24x24.png | Bin 0 -> 1790 bytes .../images/logos/editormd-logo-320x320.png | Bin 0 -> 14714 bytes .../images/logos/editormd-logo-32x32.png | Bin 0 -> 2064 bytes .../images/logos/editormd-logo-48x48.png | Bin 0 -> 2701 bytes .../images/logos/editormd-logo-57x57.png | Bin 0 -> 3054 bytes .../images/logos/editormd-logo-64x64.png | Bin 0 -> 3408 bytes .../images/logos/editormd-logo-72x72.png | Bin 0 -> 3691 bytes .../images/logos/editormd-logo-96x96.png | Bin 0 -> 4857 bytes public/editormd/images/logos/vi.png | Bin 0 -> 46203 bytes public/editormd/languages/en.js | 127 + public/editormd/languages/zh-tw.js | 127 + public/editormd/lib/codemirror/AUTHORS | 436 + public/editormd/lib/codemirror/LICENSE | 19 + public/editormd/lib/codemirror/README.md | 12 + .../lib/codemirror/addon/comment/comment.js | 183 + .../addon/comment/continuecomment.js | 85 + .../lib/codemirror/addon/dialog/dialog.css | 32 + .../lib/codemirror/addon/dialog/dialog.js | 155 + .../codemirror/addon/display/fullscreen.css | 6 + .../codemirror/addon/display/fullscreen.js | 41 + .../lib/codemirror/addon/display/panel.js | 94 + .../codemirror/addon/display/placeholder.js | 58 + .../lib/codemirror/addon/display/rulers.js | 64 + .../codemirror/addon/edit/closebrackets.js | 161 + .../lib/codemirror/addon/edit/closetag.js | 166 + .../lib/codemirror/addon/edit/continuelist.js | 51 + .../codemirror/addon/edit/matchbrackets.js | 120 + .../lib/codemirror/addon/edit/matchtags.js | 66 + .../codemirror/addon/edit/trailingspace.js | 27 + .../lib/codemirror/addon/fold/brace-fold.js | 105 + .../lib/codemirror/addon/fold/comment-fold.js | 57 + .../lib/codemirror/addon/fold/foldcode.js | 149 + .../lib/codemirror/addon/fold/foldgutter.css | 20 + .../lib/codemirror/addon/fold/foldgutter.js | 144 + .../lib/codemirror/addon/fold/indent-fold.js | 44 + .../codemirror/addon/fold/markdown-fold.js | 49 + .../lib/codemirror/addon/fold/xml-fold.js | 182 + .../lib/codemirror/addon/hint/anyword-hint.js | 41 + .../lib/codemirror/addon/hint/css-hint.js | 56 + .../lib/codemirror/addon/hint/html-hint.js | 348 + .../codemirror/addon/hint/javascript-hint.js | 146 + .../lib/codemirror/addon/hint/show-hint.css | 38 + .../lib/codemirror/addon/hint/show-hint.js | 394 + .../lib/codemirror/addon/hint/sql-hint.js | 240 + .../lib/codemirror/addon/hint/xml-hint.js | 110 + .../addon/lint/coffeescript-lint.js | 41 + .../lib/codemirror/addon/lint/css-lint.js | 35 + .../codemirror/addon/lint/javascript-lint.js | 136 + .../lib/codemirror/addon/lint/json-lint.js | 31 + .../lib/codemirror/addon/lint/lint.css | 73 + .../lib/codemirror/addon/lint/lint.js | 205 + .../lib/codemirror/addon/lint/yaml-lint.js | 28 + .../lib/codemirror/addon/merge/merge.css | 112 + .../lib/codemirror/addon/merge/merge.js | 735 ++ .../lib/codemirror/addon/mode/loadmode.js | 64 + .../lib/codemirror/addon/mode/multiplex.js | 118 + .../codemirror/addon/mode/multiplex_test.js | 33 + .../lib/codemirror/addon/mode/overlay.js | 85 + .../lib/codemirror/addon/mode/simple.js | 213 + .../lib/codemirror/addon/runmode/colorize.js | 40 + .../addon/runmode/runmode-standalone.js | 157 + .../lib/codemirror/addon/runmode/runmode.js | 72 + .../codemirror/addon/runmode/runmode.node.js | 120 + .../addon/scroll/annotatescrollbar.js | 100 + .../codemirror/addon/scroll/scrollpastend.js | 46 + .../addon/scroll/simplescrollbars.css | 66 + .../addon/scroll/simplescrollbars.js | 141 + .../addon/search/match-highlighter.js | 128 + .../addon/search/matchesonscrollbar.css | 8 + .../addon/search/matchesonscrollbar.js | 95 + .../lib/codemirror/addon/search/search.js | 164 + .../codemirror/addon/search/searchcursor.js | 189 + .../codemirror/addon/selection/active-line.js | 71 + .../addon/selection/mark-selection.js | 118 + .../addon/selection/selection-pointer.js | 98 + .../lib/codemirror/addon/tern/tern.css | 86 + .../lib/codemirror/addon/tern/tern.js | 697 ++ .../lib/codemirror/addon/tern/worker.js | 44 + .../lib/codemirror/addon/wrap/hardwrap.js | 139 + public/editormd/lib/codemirror/addons.min.js | 4 + public/editormd/lib/codemirror/bower.json | 16 + .../lib/codemirror/codemirror.min.css | 3 + .../editormd/lib/codemirror/codemirror.min.js | 54 + .../lib/codemirror/lib/codemirror.css | 331 + .../editormd/lib/codemirror/lib/codemirror.js | 8645 +++++++++++++++++ .../editormd/lib/codemirror/mode/apl/apl.js | 175 + .../lib/codemirror/mode/apl/index.html | 72 + .../lib/codemirror/mode/asterisk/asterisk.js | 198 + .../lib/codemirror/mode/asterisk/index.html | 154 + .../lib/codemirror/mode/clike/clike.js | 493 + .../lib/codemirror/mode/clike/index.html | 251 + .../lib/codemirror/mode/clike/scala.html | 767 ++ .../lib/codemirror/mode/clojure/clojure.js | 243 + .../lib/codemirror/mode/clojure/index.html | 88 + .../lib/codemirror/mode/cobol/cobol.js | 255 + .../lib/codemirror/mode/cobol/index.html | 210 + .../mode/coffeescript/coffeescript.js | 369 + .../codemirror/mode/coffeescript/index.html | 740 ++ .../codemirror/mode/commonlisp/commonlisp.js | 122 + .../lib/codemirror/mode/commonlisp/index.html | 177 + .../editormd/lib/codemirror/mode/css/css.js | 766 ++ .../lib/codemirror/mode/css/index.html | 75 + .../lib/codemirror/mode/css/less.html | 152 + .../lib/codemirror/mode/css/less_test.js | 51 + .../lib/codemirror/mode/css/scss.html | 157 + .../lib/codemirror/mode/css/scss_test.js | 110 + .../editormd/lib/codemirror/mode/css/test.js | 195 + .../lib/codemirror/mode/cypher/cypher.js | 146 + .../lib/codemirror/mode/cypher/index.html | 63 + public/editormd/lib/codemirror/mode/d/d.js | 218 + .../editormd/lib/codemirror/mode/d/index.html | 273 + .../editormd/lib/codemirror/mode/dart/dart.js | 50 + .../lib/codemirror/mode/dart/index.html | 71 + .../editormd/lib/codemirror/mode/diff/diff.js | 47 + .../lib/codemirror/mode/diff/index.html | 117 + .../lib/codemirror/mode/django/django.js | 67 + .../lib/codemirror/mode/django/index.html | 63 + .../codemirror/mode/dockerfile/dockerfile.js | 76 + .../lib/codemirror/mode/dockerfile/index.html | 73 + .../editormd/lib/codemirror/mode/dtd/dtd.js | 142 + .../lib/codemirror/mode/dtd/index.html | 89 + .../lib/codemirror/mode/dylan/dylan.js | 299 + .../lib/codemirror/mode/dylan/index.html | 407 + .../editormd/lib/codemirror/mode/ebnf/ebnf.js | 195 + .../lib/codemirror/mode/ebnf/index.html | 102 + .../editormd/lib/codemirror/mode/ecl/ecl.js | 207 + .../lib/codemirror/mode/ecl/index.html | 52 + .../lib/codemirror/mode/eiffel/eiffel.js | 162 + .../lib/codemirror/mode/eiffel/index.html | 429 + .../lib/codemirror/mode/erlang/erlang.js | 622 ++ .../lib/codemirror/mode/erlang/index.html | 76 + .../lib/codemirror/mode/forth/forth.js | 180 + .../lib/codemirror/mode/forth/index.html | 75 + .../lib/codemirror/mode/fortran/fortran.js | 188 + .../lib/codemirror/mode/fortran/index.html | 81 + .../editormd/lib/codemirror/mode/gas/gas.js | 345 + .../lib/codemirror/mode/gas/index.html | 68 + .../editormd/lib/codemirror/mode/gfm/gfm.js | 123 + .../lib/codemirror/mode/gfm/index.html | 93 + .../editormd/lib/codemirror/mode/gfm/test.js | 213 + .../lib/codemirror/mode/gherkin/gherkin.js | 178 + .../lib/codemirror/mode/gherkin/index.html | 48 + public/editormd/lib/codemirror/mode/go/go.js | 185 + .../lib/codemirror/mode/go/index.html | 85 + .../lib/codemirror/mode/groovy/groovy.js | 226 + .../lib/codemirror/mode/groovy/index.html | 84 + .../editormd/lib/codemirror/mode/haml/haml.js | 159 + .../lib/codemirror/mode/haml/index.html | 79 + .../editormd/lib/codemirror/mode/haml/test.js | 97 + .../lib/codemirror/mode/haskell/haskell.js | 267 + .../lib/codemirror/mode/haskell/index.html | 73 + .../editormd/lib/codemirror/mode/haxe/haxe.js | 518 + .../lib/codemirror/mode/haxe/index.html | 124 + .../mode/htmlembedded/htmlembedded.js | 86 + .../codemirror/mode/htmlembedded/index.html | 58 + .../codemirror/mode/htmlmixed/htmlmixed.js | 121 + .../lib/codemirror/mode/htmlmixed/index.html | 89 + .../editormd/lib/codemirror/mode/http/http.js | 113 + .../lib/codemirror/mode/http/index.html | 45 + .../editormd/lib/codemirror/mode/idl/idl.js | 290 + .../lib/codemirror/mode/idl/index.html | 64 + .../editormd/lib/codemirror/mode/index.html | 134 + .../lib/codemirror/mode/jade/index.html | 70 + .../editormd/lib/codemirror/mode/jade/jade.js | 590 ++ .../lib/codemirror/mode/javascript/index.html | 114 + .../codemirror/mode/javascript/javascript.js | 692 ++ .../codemirror/mode/javascript/json-ld.html | 72 + .../lib/codemirror/mode/javascript/test.js | 200 + .../mode/javascript/typescript.html | 61 + .../lib/codemirror/mode/jinja2/index.html | 54 + .../lib/codemirror/mode/jinja2/jinja2.js | 142 + .../lib/codemirror/mode/julia/index.html | 195 + .../lib/codemirror/mode/julia/julia.js | 301 + .../lib/codemirror/mode/kotlin/index.html | 89 + .../lib/codemirror/mode/kotlin/kotlin.js | 280 + .../lib/codemirror/mode/livescript/index.html | 459 + .../codemirror/mode/livescript/livescript.js | 280 + .../lib/codemirror/mode/lua/index.html | 85 + .../editormd/lib/codemirror/mode/lua/lua.js | 159 + .../lib/codemirror/mode/markdown/index.html | 359 + .../lib/codemirror/mode/markdown/markdown.js | 765 ++ .../lib/codemirror/mode/markdown/test.js | 754 ++ public/editormd/lib/codemirror/mode/meta.js | 177 + .../lib/codemirror/mode/mirc/index.html | 160 + .../editormd/lib/codemirror/mode/mirc/mirc.js | 193 + .../lib/codemirror/mode/mllike/index.html | 179 + .../lib/codemirror/mode/mllike/mllike.js | 205 + .../lib/codemirror/mode/modelica/index.html | 67 + .../lib/codemirror/mode/modelica/modelica.js | 245 + .../lib/codemirror/mode/nginx/index.html | 181 + .../lib/codemirror/mode/nginx/nginx.js | 178 + .../lib/codemirror/mode/ntriples/index.html | 45 + .../lib/codemirror/mode/ntriples/ntriples.js | 186 + .../lib/codemirror/mode/octave/index.html | 83 + .../lib/codemirror/mode/octave/octave.js | 135 + .../lib/codemirror/mode/pascal/index.html | 61 + .../lib/codemirror/mode/pascal/pascal.js | 109 + .../lib/codemirror/mode/pegjs/index.html | 66 + .../lib/codemirror/mode/pegjs/pegjs.js | 114 + .../lib/codemirror/mode/perl/index.html | 75 + .../editormd/lib/codemirror/mode/perl/perl.js | 837 ++ .../lib/codemirror/mode/php/index.html | 64 + .../editormd/lib/codemirror/mode/php/php.js | 226 + .../editormd/lib/codemirror/mode/php/test.js | 154 + .../lib/codemirror/mode/pig/index.html | 55 + .../editormd/lib/codemirror/mode/pig/pig.js | 188 + .../lib/codemirror/mode/properties/index.html | 53 + .../codemirror/mode/properties/properties.js | 78 + .../lib/codemirror/mode/puppet/index.html | 121 + .../lib/codemirror/mode/puppet/puppet.js | 220 + .../lib/codemirror/mode/python/index.html | 198 + .../lib/codemirror/mode/python/python.js | 359 + .../editormd/lib/codemirror/mode/q/index.html | 144 + public/editormd/lib/codemirror/mode/q/q.js | 139 + .../editormd/lib/codemirror/mode/r/index.html | 85 + public/editormd/lib/codemirror/mode/r/r.js | 162 + .../codemirror/mode/rpm/changes/index.html | 66 + .../lib/codemirror/mode/rpm/index.html | 149 + .../editormd/lib/codemirror/mode/rpm/rpm.js | 101 + .../lib/codemirror/mode/rst/index.html | 535 + .../editormd/lib/codemirror/mode/rst/rst.js | 557 ++ .../lib/codemirror/mode/ruby/index.html | 183 + .../editormd/lib/codemirror/mode/ruby/ruby.js | 285 + .../editormd/lib/codemirror/mode/ruby/test.js | 14 + .../lib/codemirror/mode/rust/index.html | 60 + .../editormd/lib/codemirror/mode/rust/rust.js | 451 + .../lib/codemirror/mode/sass/index.html | 66 + .../editormd/lib/codemirror/mode/sass/sass.js | 414 + .../lib/codemirror/mode/scheme/index.html | 77 + .../lib/codemirror/mode/scheme/scheme.js | 248 + .../lib/codemirror/mode/shell/index.html | 66 + .../lib/codemirror/mode/shell/shell.js | 139 + .../lib/codemirror/mode/shell/test.js | 58 + .../lib/codemirror/mode/sieve/index.html | 93 + .../lib/codemirror/mode/sieve/sieve.js | 193 + .../lib/codemirror/mode/slim/index.html | 96 + .../editormd/lib/codemirror/mode/slim/slim.js | 575 ++ .../editormd/lib/codemirror/mode/slim/test.js | 96 + .../lib/codemirror/mode/smalltalk/index.html | 68 + .../codemirror/mode/smalltalk/smalltalk.js | 168 + .../lib/codemirror/mode/smarty/index.html | 136 + .../lib/codemirror/mode/smarty/smarty.js | 221 + .../codemirror/mode/smartymixed/index.html | 114 + .../mode/smartymixed/smartymixed.js | 197 + .../lib/codemirror/mode/solr/index.html | 57 + .../editormd/lib/codemirror/mode/solr/solr.js | 104 + .../lib/codemirror/mode/soy/index.html | 68 + .../editormd/lib/codemirror/mode/soy/soy.js | 198 + .../lib/codemirror/mode/sparql/index.html | 61 + .../lib/codemirror/mode/sparql/sparql.js | 174 + .../codemirror/mode/spreadsheet/index.html | 42 + .../mode/spreadsheet/spreadsheet.js | 109 + .../lib/codemirror/mode/sql/index.html | 84 + .../editormd/lib/codemirror/mode/sql/sql.js | 391 + .../lib/codemirror/mode/stex/index.html | 110 + .../editormd/lib/codemirror/mode/stex/stex.js | 251 + .../editormd/lib/codemirror/mode/stex/test.js | 123 + .../lib/codemirror/mode/stylus/index.html | 104 + .../lib/codemirror/mode/stylus/stylus.js | 444 + .../lib/codemirror/mode/tcl/index.html | 142 + .../editormd/lib/codemirror/mode/tcl/tcl.js | 147 + .../lib/codemirror/mode/textile/index.html | 191 + .../lib/codemirror/mode/textile/test.js | 417 + .../lib/codemirror/mode/textile/textile.js | 469 + .../lib/codemirror/mode/tiddlywiki/index.html | 154 + .../codemirror/mode/tiddlywiki/tiddlywiki.css | 14 + .../codemirror/mode/tiddlywiki/tiddlywiki.js | 369 + .../lib/codemirror/mode/tiki/index.html | 95 + .../lib/codemirror/mode/tiki/tiki.css | 26 + .../editormd/lib/codemirror/mode/tiki/tiki.js | 323 + .../lib/codemirror/mode/toml/index.html | 73 + .../editormd/lib/codemirror/mode/toml/toml.js | 88 + .../lib/codemirror/mode/tornado/index.html | 63 + .../lib/codemirror/mode/tornado/tornado.js | 68 + .../lib/codemirror/mode/turtle/index.html | 50 + .../lib/codemirror/mode/turtle/turtle.js | 162 + .../lib/codemirror/mode/vb/index.html | 102 + public/editormd/lib/codemirror/mode/vb/vb.js | 274 + .../lib/codemirror/mode/vbscript/index.html | 55 + .../lib/codemirror/mode/vbscript/vbscript.js | 350 + .../lib/codemirror/mode/velocity/index.html | 118 + .../lib/codemirror/mode/velocity/velocity.js | 201 + .../lib/codemirror/mode/verilog/index.html | 120 + .../lib/codemirror/mode/verilog/test.js | 273 + .../lib/codemirror/mode/verilog/verilog.js | 537 + .../lib/codemirror/mode/xml/index.html | 57 + .../editormd/lib/codemirror/mode/xml/test.js | 51 + .../editormd/lib/codemirror/mode/xml/xml.js | 384 + .../lib/codemirror/mode/xquery/index.html | 210 + .../lib/codemirror/mode/xquery/test.js | 67 + .../lib/codemirror/mode/xquery/xquery.js | 447 + .../lib/codemirror/mode/yaml/index.html | 80 + .../editormd/lib/codemirror/mode/yaml/yaml.js | 117 + .../lib/codemirror/mode/z80/index.html | 52 + .../editormd/lib/codemirror/mode/z80/z80.js | 100 + public/editormd/lib/codemirror/modes.min.js | 10 + public/editormd/lib/codemirror/package.json | 21 + .../lib/codemirror/theme/3024-day.css | 40 + .../lib/codemirror/theme/3024-night.css | 39 + .../lib/codemirror/theme/ambiance-mobile.css | 5 + .../lib/codemirror/theme/ambiance.css | 75 + .../lib/codemirror/theme/base16-dark.css | 38 + .../lib/codemirror/theme/base16-light.css | 38 + .../lib/codemirror/theme/blackboard.css | 32 + .../editormd/lib/codemirror/theme/cobalt.css | 25 + .../lib/codemirror/theme/colorforth.css | 33 + .../editormd/lib/codemirror/theme/eclipse.css | 23 + .../editormd/lib/codemirror/theme/elegant.css | 13 + .../lib/codemirror/theme/erlang-dark.css | 34 + .../lib/codemirror/theme/lesser-dark.css | 47 + public/editormd/lib/codemirror/theme/mbo.css | 37 + .../lib/codemirror/theme/mdn-like.css | 46 + .../lib/codemirror/theme/midnight.css | 47 + .../editormd/lib/codemirror/theme/monokai.css | 33 + public/editormd/lib/codemirror/theme/neat.css | 12 + public/editormd/lib/codemirror/theme/neo.css | 43 + .../editormd/lib/codemirror/theme/night.css | 28 + .../lib/codemirror/theme/paraiso-dark.css | 38 + .../lib/codemirror/theme/paraiso-light.css | 38 + .../lib/codemirror/theme/pastel-on-dark.css | 53 + .../lib/codemirror/theme/rubyblue.css | 25 + .../lib/codemirror/theme/solarized.css | 165 + .../lib/codemirror/theme/the-matrix.css | 30 + .../theme/tomorrow-night-bright.css | 35 + .../theme/tomorrow-night-eighties.css | 38 + .../lib/codemirror/theme/twilight.css | 32 + .../lib/codemirror/theme/vibrant-ink.css | 34 + .../editormd/lib/codemirror/theme/xq-dark.css | 53 + .../lib/codemirror/theme/xq-light.css | 43 + .../editormd/lib/codemirror/theme/zenburn.css | 37 + public/editormd/lib/flowchart.min.js | 5 + public/editormd/lib/jquery.flowchart.min.js | 2 + public/editormd/lib/marked.min.backup.js | 18 + public/editormd/lib/marked.min.js | 22 + public/editormd/lib/prettify.min.js | 15 + public/editormd/lib/raphael.min.js | 12 + public/editormd/lib/readme-marked.txt | 36 + public/editormd/lib/sequence-diagram.min.js | 7 + public/editormd/lib/underscore.min.js | 5 + public/editormd/package.json | 42 + .../code-block-dialog/code-block-dialog.js | 238 + .../plugins/emoji-dialog/emoji-dialog.js | 329 + .../editormd/plugins/emoji-dialog/emoji.json | 28 + .../goto-line-dialog/goto-line-dialog.js | 159 + .../plugins/help-dialog/help-dialog.js | 104 + public/editormd/plugins/help-dialog/help.md | 77 + .../html-entities-dialog.js | 173 + .../html-entities-dialog/html-entities.json | 936 ++ .../plugins/image-dialog/image-dialog.js | 236 + .../plugins/link-dialog/link-dialog.js | 134 + public/editormd/plugins/plugin-template.js | 111 + .../preformatted-text-dialog.js | 174 + .../reference-link-dialog.js | 155 + .../plugins/table-dialog/table-dialog.js | 220 + .../plugins/test-plugin/test-plugin.js | 66 + public/editormd/scss/editormd.codemirror.scss | 89 + public/editormd/scss/editormd.dialog.scss | 184 + public/editormd/scss/editormd.form.scss | 130 + public/editormd/scss/editormd.grid.scss | 36 + public/editormd/scss/editormd.logo.scss | 89 + public/editormd/scss/editormd.menu.scss | 113 + public/editormd/scss/editormd.preview.scss | 322 + .../scss/editormd.preview.themes.scss | 131 + public/editormd/scss/editormd.scss | 137 + public/editormd/scss/editormd.tab.scss | 49 + public/editormd/scss/editormd.themes.scss | 28 + public/editormd/scss/font-awesome.scss | 1801 ++++ public/editormd/scss/github-markdown.scss | 665 ++ public/editormd/scss/lib/prefixes.scss | 784 ++ public/editormd/scss/lib/variables.scss | 11 + public/editormd/scss/prettify.scss | 53 + public/editormd/src/editormd.js | 4585 +++++++++ public/editormd/tests/bootstrap-test.html | 63 + .../tests/codemirror-searchbox-test.html | 109 + public/editormd/tests/codemirror-test.html | 75 + .../tests/css/bootstrap-theme.min.css | 5 + public/editormd/tests/css/bootstrap.min.css | 5 + public/editormd/tests/js/bootstrap.min.js | 7 + public/editormd/tests/js/searchbox.js | 674 ++ public/editormd/tests/katex-tests.html | 132 + public/editormd/tests/marked-@at-test.html | 221 + public/editormd/tests/marked-emoji-test.html | 231 + .../tests/marked-heading-link-test.html | 138 + .../editormd/tests/marked-todo-list-test.html | 61 + public/editormd/tests/qunit/qunit-1.16.0.css | 264 + public/editormd/tests/qunit/qunit-1.16.0.js | 2819 ++++++ src/AppConfig.js | 42 +- src/common/Env.js | 8 + src/common/UrlTool.js | 118 +- src/common/educoder.js | 2 +- src/images/warn/pic_403.jpg | Bin 0 -> 41657 bytes src/images/warn/pic_404.jpg | Bin 0 -> 58211 bytes src/images/warn/pic_500.jpg | Bin 0 -> 74703 bytes src/images/warn/update.jpeg | Bin 0 -> 196378 bytes src/modules/403/Shixunauthority.js | 3 +- src/modules/404/Shixunnopage.js | 3 +- src/modules/500/http500.js | 3 +- src/modules/forums/MemoNew.js | 13 +- src/modules/tpm/challengesnew/TPMMDEditor.js | 2 +- .../tpm/challengesnew/tpm-md-editor.js | 2 +- 1415 files changed, 118560 insertions(+), 142 deletions(-) create mode 100644 public/editormd/.jshintrc create mode 100644 public/editormd/BUGS.md create mode 100644 public/editormd/CHANGE.md create mode 100644 public/editormd/Gulpfile.js create mode 100644 public/editormd/LICENSE create mode 100644 public/editormd/README.md create mode 100644 public/editormd/bower.json create mode 100644 public/editormd/css/editormd.css create mode 100644 public/editormd/css/editormd.logo.css create mode 100644 public/editormd/css/editormd.logo.min.css create mode 100644 public/editormd/css/editormd.min.css create mode 100644 public/editormd/css/editormd.preview.css create mode 100644 public/editormd/css/editormd.preview.min.css create mode 100644 public/editormd/docs/editormd.js.html create mode 100644 public/editormd/docs/fonts/OpenSans-Bold-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-Bold-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-Bold-webfont.woff create mode 100644 public/editormd/docs/fonts/OpenSans-BoldItalic-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-BoldItalic-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-BoldItalic-webfont.woff create mode 100644 public/editormd/docs/fonts/OpenSans-Italic-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-Italic-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-Italic-webfont.woff create mode 100644 public/editormd/docs/fonts/OpenSans-Light-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-Light-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-Light-webfont.woff create mode 100644 public/editormd/docs/fonts/OpenSans-LightItalic-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-LightItalic-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-LightItalic-webfont.woff create mode 100644 public/editormd/docs/fonts/OpenSans-Regular-webfont.eot create mode 100644 public/editormd/docs/fonts/OpenSans-Regular-webfont.svg create mode 100644 public/editormd/docs/fonts/OpenSans-Regular-webfont.woff create mode 100644 public/editormd/docs/index.html create mode 100644 public/editormd/docs/scripts/linenumber.js create mode 100644 public/editormd/docs/scripts/prettify/Apache-License-2.0.txt create mode 100644 public/editormd/docs/scripts/prettify/lang-css.js create mode 100644 public/editormd/docs/scripts/prettify/prettify.js create mode 100644 public/editormd/docs/styles/jsdoc-default.css create mode 100644 public/editormd/docs/styles/prettify-jsdoc.css create mode 100644 public/editormd/docs/styles/prettify-tomorrow.css create mode 100644 public/editormd/editormd.amd.js create mode 100644 public/editormd/editormd.amd.min.js create mode 100644 public/editormd/editormd.js create mode 100644 public/editormd/editormd.min.js create mode 100644 public/editormd/emoji/+1.png create mode 100644 public/editormd/emoji/-1.png create mode 100644 public/editormd/emoji/100.png create mode 100644 public/editormd/emoji/1234.png create mode 100644 public/editormd/emoji/8ball.png create mode 100644 public/editormd/emoji/a.png create mode 100644 public/editormd/emoji/ab.png create mode 100644 public/editormd/emoji/abc.png create mode 100644 public/editormd/emoji/abcd.png create mode 100644 public/editormd/emoji/accept.png create mode 100644 public/editormd/emoji/aerial_tramway.png create mode 100644 public/editormd/emoji/airplane.png create mode 100644 public/editormd/emoji/alarm_clock.png create mode 100644 public/editormd/emoji/alien.png create mode 100644 public/editormd/emoji/ambulance.png create mode 100644 public/editormd/emoji/anchor.png create mode 100644 public/editormd/emoji/angel.png create mode 100644 public/editormd/emoji/anger.png create mode 100644 public/editormd/emoji/angry.png create mode 100644 public/editormd/emoji/anguished.png create mode 100644 public/editormd/emoji/ant.png create mode 100644 public/editormd/emoji/apple.png create mode 100644 public/editormd/emoji/aquarius.png create mode 100644 public/editormd/emoji/aries.png create mode 100644 public/editormd/emoji/arrow_backward.png create mode 100644 public/editormd/emoji/arrow_double_down.png create mode 100644 public/editormd/emoji/arrow_double_up.png create mode 100644 public/editormd/emoji/arrow_down.png create mode 100644 public/editormd/emoji/arrow_down_small.png create mode 100644 public/editormd/emoji/arrow_forward.png create mode 100644 public/editormd/emoji/arrow_heading_down.png create mode 100644 public/editormd/emoji/arrow_heading_up.png create mode 100644 public/editormd/emoji/arrow_left.png create mode 100644 public/editormd/emoji/arrow_lower_left.png create mode 100644 public/editormd/emoji/arrow_lower_right.png create mode 100644 public/editormd/emoji/arrow_right.png create mode 100644 public/editormd/emoji/arrow_right_hook.png create mode 100644 public/editormd/emoji/arrow_up.png create mode 100644 public/editormd/emoji/arrow_up_down.png create mode 100644 public/editormd/emoji/arrow_up_small.png create mode 100644 public/editormd/emoji/arrow_upper_left.png create mode 100644 public/editormd/emoji/arrow_upper_right.png create mode 100644 public/editormd/emoji/arrows_clockwise.png create mode 100644 public/editormd/emoji/arrows_counterclockwise.png create mode 100644 public/editormd/emoji/art.png create mode 100644 public/editormd/emoji/articulated_lorry.png create mode 100644 public/editormd/emoji/astonished.png create mode 100644 public/editormd/emoji/atm.png create mode 100644 public/editormd/emoji/b.png create mode 100644 public/editormd/emoji/baby.png create mode 100644 public/editormd/emoji/baby_bottle.png create mode 100644 public/editormd/emoji/baby_chick.png create mode 100644 public/editormd/emoji/baby_symbol.png create mode 100644 public/editormd/emoji/back.png create mode 100644 public/editormd/emoji/baggage_claim.png create mode 100644 public/editormd/emoji/balloon.png create mode 100644 public/editormd/emoji/ballot_box_with_check.png create mode 100644 public/editormd/emoji/bamboo.png create mode 100644 public/editormd/emoji/banana.png create mode 100644 public/editormd/emoji/bangbang.png create mode 100644 public/editormd/emoji/bank.png create mode 100644 public/editormd/emoji/bar_chart.png create mode 100644 public/editormd/emoji/barber.png create mode 100644 public/editormd/emoji/baseball.png create mode 100644 public/editormd/emoji/basketball.png create mode 100644 public/editormd/emoji/bath.png create mode 100644 public/editormd/emoji/bathtub.png create mode 100644 public/editormd/emoji/battery.png create mode 100644 public/editormd/emoji/bear.png create mode 100644 public/editormd/emoji/bee.png create mode 100644 public/editormd/emoji/beer.png create mode 100644 public/editormd/emoji/beers.png create mode 100644 public/editormd/emoji/beetle.png create mode 100644 public/editormd/emoji/beginner.png create mode 100644 public/editormd/emoji/bell.png create mode 100644 public/editormd/emoji/bento.png create mode 100644 public/editormd/emoji/bicyclist.png create mode 100644 public/editormd/emoji/bike.png create mode 100644 public/editormd/emoji/bikini.png create mode 100644 public/editormd/emoji/bird.png create mode 100644 public/editormd/emoji/birthday.png create mode 100644 public/editormd/emoji/black_circle.png create mode 100644 public/editormd/emoji/black_joker.png create mode 100644 public/editormd/emoji/black_medium_small_square.png create mode 100644 public/editormd/emoji/black_medium_square.png create mode 100644 public/editormd/emoji/black_nib.png create mode 100644 public/editormd/emoji/black_small_square.png create mode 100644 public/editormd/emoji/black_square.png create mode 100644 public/editormd/emoji/black_square_button.png create mode 100644 public/editormd/emoji/blossom.png create mode 100644 public/editormd/emoji/blowfish.png create mode 100644 public/editormd/emoji/blue_book.png create mode 100644 public/editormd/emoji/blue_car.png create mode 100644 public/editormd/emoji/blue_heart.png create mode 100644 public/editormd/emoji/blush.png create mode 100644 public/editormd/emoji/boar.png create mode 100644 public/editormd/emoji/boat.png create mode 100644 public/editormd/emoji/bomb.png create mode 100644 public/editormd/emoji/book.png create mode 100644 public/editormd/emoji/bookmark.png create mode 100644 public/editormd/emoji/bookmark_tabs.png create mode 100644 public/editormd/emoji/books.png create mode 100644 public/editormd/emoji/boom.png create mode 100644 public/editormd/emoji/boot.png create mode 100644 public/editormd/emoji/bouquet.png create mode 100644 public/editormd/emoji/bow.png create mode 100644 public/editormd/emoji/bowling.png create mode 100644 public/editormd/emoji/bowtie.png create mode 100644 public/editormd/emoji/boy.png create mode 100644 public/editormd/emoji/bread.png create mode 100644 public/editormd/emoji/bride_with_veil.png create mode 100644 public/editormd/emoji/bridge_at_night.png create mode 100644 public/editormd/emoji/briefcase.png create mode 100644 public/editormd/emoji/broken_heart.png create mode 100644 public/editormd/emoji/bug.png create mode 100644 public/editormd/emoji/bulb.png create mode 100644 public/editormd/emoji/bullettrain_front.png create mode 100644 public/editormd/emoji/bullettrain_side.png create mode 100644 public/editormd/emoji/bus.png create mode 100644 public/editormd/emoji/busstop.png create mode 100644 public/editormd/emoji/bust_in_silhouette.png create mode 100644 public/editormd/emoji/busts_in_silhouette.png create mode 100644 public/editormd/emoji/cactus.png create mode 100644 public/editormd/emoji/cake.png create mode 100644 public/editormd/emoji/calendar.png create mode 100644 public/editormd/emoji/calling.png create mode 100644 public/editormd/emoji/camel.png create mode 100644 public/editormd/emoji/camera.png create mode 100644 public/editormd/emoji/cancer.png create mode 100644 public/editormd/emoji/candy.png create mode 100644 public/editormd/emoji/capital_abcd.png create mode 100644 public/editormd/emoji/capricorn.png create mode 100644 public/editormd/emoji/car.png create mode 100644 public/editormd/emoji/card_index.png create mode 100644 public/editormd/emoji/carousel_horse.png create mode 100644 public/editormd/emoji/cat.png create mode 100644 public/editormd/emoji/cat2.png create mode 100644 public/editormd/emoji/cd.png create mode 100644 public/editormd/emoji/chart.png create mode 100644 public/editormd/emoji/chart_with_downwards_trend.png create mode 100644 public/editormd/emoji/chart_with_upwards_trend.png create mode 100644 public/editormd/emoji/checkered_flag.png create mode 100644 public/editormd/emoji/cherries.png create mode 100644 public/editormd/emoji/cherry_blossom.png create mode 100644 public/editormd/emoji/chestnut.png create mode 100644 public/editormd/emoji/chicken.png create mode 100644 public/editormd/emoji/children_crossing.png create mode 100644 public/editormd/emoji/chocolate_bar.png create mode 100644 public/editormd/emoji/christmas_tree.png create mode 100644 public/editormd/emoji/church.png create mode 100644 public/editormd/emoji/cinema.png create mode 100644 public/editormd/emoji/circus_tent.png create mode 100644 public/editormd/emoji/city_sunrise.png create mode 100644 public/editormd/emoji/city_sunset.png create mode 100644 public/editormd/emoji/cl.png create mode 100644 public/editormd/emoji/clap.png create mode 100644 public/editormd/emoji/clapper.png create mode 100644 public/editormd/emoji/clipboard.png create mode 100644 public/editormd/emoji/clock1.png create mode 100644 public/editormd/emoji/clock10.png create mode 100644 public/editormd/emoji/clock1030.png create mode 100644 public/editormd/emoji/clock11.png create mode 100644 public/editormd/emoji/clock1130.png create mode 100644 public/editormd/emoji/clock12.png create mode 100644 public/editormd/emoji/clock1230.png create mode 100644 public/editormd/emoji/clock130.png create mode 100644 public/editormd/emoji/clock2.png create mode 100644 public/editormd/emoji/clock230.png create mode 100644 public/editormd/emoji/clock3.png create mode 100644 public/editormd/emoji/clock330.png create mode 100644 public/editormd/emoji/clock4.png create mode 100644 public/editormd/emoji/clock430.png create mode 100644 public/editormd/emoji/clock5.png create mode 100644 public/editormd/emoji/clock530.png create mode 100644 public/editormd/emoji/clock6.png create mode 100644 public/editormd/emoji/clock630.png create mode 100644 public/editormd/emoji/clock7.png create mode 100644 public/editormd/emoji/clock730.png create mode 100644 public/editormd/emoji/clock8.png create mode 100644 public/editormd/emoji/clock830.png create mode 100644 public/editormd/emoji/clock9.png create mode 100644 public/editormd/emoji/clock930.png create mode 100644 public/editormd/emoji/closed_book.png create mode 100644 public/editormd/emoji/closed_lock_with_key.png create mode 100644 public/editormd/emoji/closed_umbrella.png create mode 100644 public/editormd/emoji/cloud.png create mode 100644 public/editormd/emoji/clubs.png create mode 100644 public/editormd/emoji/cn.png create mode 100644 public/editormd/emoji/cocktail.png create mode 100644 public/editormd/emoji/coffee.png create mode 100644 public/editormd/emoji/cold_sweat.png create mode 100644 public/editormd/emoji/collision.png create mode 100644 public/editormd/emoji/computer.png create mode 100644 public/editormd/emoji/confetti_ball.png create mode 100644 public/editormd/emoji/confounded.png create mode 100644 public/editormd/emoji/confused.png create mode 100644 public/editormd/emoji/congratulations.png create mode 100644 public/editormd/emoji/construction.png create mode 100644 public/editormd/emoji/construction_worker.png create mode 100644 public/editormd/emoji/convenience_store.png create mode 100644 public/editormd/emoji/cookie.png create mode 100644 public/editormd/emoji/cool.png create mode 100644 public/editormd/emoji/cop.png create mode 100644 public/editormd/emoji/copyright.png create mode 100644 public/editormd/emoji/corn.png create mode 100644 public/editormd/emoji/couple.png create mode 100644 public/editormd/emoji/couple_with_heart.png create mode 100644 public/editormd/emoji/couplekiss.png create mode 100644 public/editormd/emoji/cow.png create mode 100644 public/editormd/emoji/cow2.png create mode 100644 public/editormd/emoji/credit_card.png create mode 100644 public/editormd/emoji/crescent_moon.png create mode 100644 public/editormd/emoji/crocodile.png create mode 100644 public/editormd/emoji/crossed_flags.png create mode 100644 public/editormd/emoji/crown.png create mode 100644 public/editormd/emoji/cry.png create mode 100644 public/editormd/emoji/crying_cat_face.png create mode 100644 public/editormd/emoji/crystal_ball.png create mode 100644 public/editormd/emoji/cupid.png create mode 100644 public/editormd/emoji/curly_loop.png create mode 100644 public/editormd/emoji/currency_exchange.png create mode 100644 public/editormd/emoji/curry.png create mode 100644 public/editormd/emoji/custard.png create mode 100644 public/editormd/emoji/customs.png create mode 100644 public/editormd/emoji/cyclone.png create mode 100644 public/editormd/emoji/dancer.png create mode 100644 public/editormd/emoji/dancers.png create mode 100644 public/editormd/emoji/dango.png create mode 100644 public/editormd/emoji/dart.png create mode 100644 public/editormd/emoji/dash.png create mode 100644 public/editormd/emoji/date.png create mode 100644 public/editormd/emoji/de.png create mode 100644 public/editormd/emoji/deciduous_tree.png create mode 100644 public/editormd/emoji/department_store.png create mode 100644 public/editormd/emoji/diamond_shape_with_a_dot_inside.png create mode 100644 public/editormd/emoji/diamonds.png create mode 100644 public/editormd/emoji/disappointed.png create mode 100644 public/editormd/emoji/disappointed_relieved.png create mode 100644 public/editormd/emoji/dizzy.png create mode 100644 public/editormd/emoji/dizzy_face.png create mode 100644 public/editormd/emoji/do_not_litter.png create mode 100644 public/editormd/emoji/dog.png create mode 100644 public/editormd/emoji/dog2.png create mode 100644 public/editormd/emoji/dollar.png create mode 100644 public/editormd/emoji/dolls.png create mode 100644 public/editormd/emoji/dolphin.png create mode 100644 public/editormd/emoji/donut.png create mode 100644 public/editormd/emoji/door.png create mode 100644 public/editormd/emoji/doughnut.png create mode 100644 public/editormd/emoji/dragon.png create mode 100644 public/editormd/emoji/dragon_face.png create mode 100644 public/editormd/emoji/dress.png create mode 100644 public/editormd/emoji/dromedary_camel.png create mode 100644 public/editormd/emoji/droplet.png create mode 100644 public/editormd/emoji/dvd.png create mode 100644 public/editormd/emoji/e-mail.png create mode 100644 public/editormd/emoji/ear.png create mode 100644 public/editormd/emoji/ear_of_rice.png create mode 100644 public/editormd/emoji/earth_africa.png create mode 100644 public/editormd/emoji/earth_americas.png create mode 100644 public/editormd/emoji/earth_asia.png create mode 100644 public/editormd/emoji/egg.png create mode 100644 public/editormd/emoji/eggplant.png create mode 100644 public/editormd/emoji/eight.png create mode 100644 public/editormd/emoji/eight_pointed_black_star.png create mode 100644 public/editormd/emoji/eight_spoked_asterisk.png create mode 100644 public/editormd/emoji/electric_plug.png create mode 100644 public/editormd/emoji/elephant.png create mode 100644 public/editormd/emoji/email.png create mode 100644 public/editormd/emoji/end.png create mode 100644 public/editormd/emoji/envelope.png create mode 100644 public/editormd/emoji/es.png create mode 100644 public/editormd/emoji/euro.png create mode 100644 public/editormd/emoji/european_castle.png create mode 100644 public/editormd/emoji/european_post_office.png create mode 100644 public/editormd/emoji/evergreen_tree.png create mode 100644 public/editormd/emoji/exclamation.png create mode 100644 public/editormd/emoji/expressionless.png create mode 100644 public/editormd/emoji/eyeglasses.png create mode 100644 public/editormd/emoji/eyes.png create mode 100644 public/editormd/emoji/facepunch.png create mode 100644 public/editormd/emoji/factory.png create mode 100644 public/editormd/emoji/fallen_leaf.png create mode 100644 public/editormd/emoji/family.png create mode 100644 public/editormd/emoji/fast_forward.png create mode 100644 public/editormd/emoji/fax.png create mode 100644 public/editormd/emoji/fearful.png create mode 100644 public/editormd/emoji/feelsgood.png create mode 100644 public/editormd/emoji/feet.png create mode 100644 public/editormd/emoji/ferris_wheel.png create mode 100644 public/editormd/emoji/file_folder.png create mode 100644 public/editormd/emoji/finnadie.png create mode 100644 public/editormd/emoji/fire.png create mode 100644 public/editormd/emoji/fire_engine.png create mode 100644 public/editormd/emoji/fireworks.png create mode 100644 public/editormd/emoji/first_quarter_moon.png create mode 100644 public/editormd/emoji/first_quarter_moon_with_face.png create mode 100644 public/editormd/emoji/fish.png create mode 100644 public/editormd/emoji/fish_cake.png create mode 100644 public/editormd/emoji/fishing_pole_and_fish.png create mode 100644 public/editormd/emoji/fist.png create mode 100644 public/editormd/emoji/five.png create mode 100644 public/editormd/emoji/flags.png create mode 100644 public/editormd/emoji/flashlight.png create mode 100644 public/editormd/emoji/floppy_disk.png create mode 100644 public/editormd/emoji/flower_playing_cards.png create mode 100644 public/editormd/emoji/flushed.png create mode 100644 public/editormd/emoji/foggy.png create mode 100644 public/editormd/emoji/football.png create mode 100644 public/editormd/emoji/fork_and_knife.png create mode 100644 public/editormd/emoji/fountain.png create mode 100644 public/editormd/emoji/four.png create mode 100644 public/editormd/emoji/four_leaf_clover.png create mode 100644 public/editormd/emoji/fr.png create mode 100644 public/editormd/emoji/free.png create mode 100644 public/editormd/emoji/fried_shrimp.png create mode 100644 public/editormd/emoji/fries.png create mode 100644 public/editormd/emoji/frog.png create mode 100644 public/editormd/emoji/frowning.png create mode 100644 public/editormd/emoji/fu.png create mode 100644 public/editormd/emoji/fuelpump.png create mode 100644 public/editormd/emoji/full_moon.png create mode 100644 public/editormd/emoji/full_moon_with_face.png create mode 100644 public/editormd/emoji/game_die.png create mode 100644 public/editormd/emoji/gb.png create mode 100644 public/editormd/emoji/gem.png create mode 100644 public/editormd/emoji/gemini.png create mode 100644 public/editormd/emoji/ghost.png create mode 100644 public/editormd/emoji/gift.png create mode 100644 public/editormd/emoji/gift_heart.png create mode 100644 public/editormd/emoji/girl.png create mode 100644 public/editormd/emoji/globe_with_meridians.png create mode 100644 public/editormd/emoji/goat.png create mode 100644 public/editormd/emoji/goberserk.png create mode 100644 public/editormd/emoji/godmode.png create mode 100644 public/editormd/emoji/golf.png create mode 100644 public/editormd/emoji/grapes.png create mode 100644 public/editormd/emoji/green_apple.png create mode 100644 public/editormd/emoji/green_book.png create mode 100644 public/editormd/emoji/green_heart.png create mode 100644 public/editormd/emoji/grey_exclamation.png create mode 100644 public/editormd/emoji/grey_question.png create mode 100644 public/editormd/emoji/grimacing.png create mode 100644 public/editormd/emoji/grin.png create mode 100644 public/editormd/emoji/grinning.png create mode 100644 public/editormd/emoji/guardsman.png create mode 100644 public/editormd/emoji/guitar.png create mode 100644 public/editormd/emoji/gun.png create mode 100644 public/editormd/emoji/haircut.png create mode 100644 public/editormd/emoji/hamburger.png create mode 100644 public/editormd/emoji/hammer.png create mode 100644 public/editormd/emoji/hamster.png create mode 100644 public/editormd/emoji/hand.png create mode 100644 public/editormd/emoji/handbag.png create mode 100644 public/editormd/emoji/hankey.png create mode 100644 public/editormd/emoji/hash.png create mode 100644 public/editormd/emoji/hatched_chick.png create mode 100644 public/editormd/emoji/hatching_chick.png create mode 100644 public/editormd/emoji/headphones.png create mode 100644 public/editormd/emoji/hear_no_evil.png create mode 100644 public/editormd/emoji/heart.png create mode 100644 public/editormd/emoji/heart_decoration.png create mode 100644 public/editormd/emoji/heart_eyes.png create mode 100644 public/editormd/emoji/heart_eyes_cat.png create mode 100644 public/editormd/emoji/heartbeat.png create mode 100644 public/editormd/emoji/heartpulse.png create mode 100644 public/editormd/emoji/hearts.png create mode 100644 public/editormd/emoji/heavy_check_mark.png create mode 100644 public/editormd/emoji/heavy_division_sign.png create mode 100644 public/editormd/emoji/heavy_dollar_sign.png create mode 100644 public/editormd/emoji/heavy_exclamation_mark.png create mode 100644 public/editormd/emoji/heavy_minus_sign.png create mode 100644 public/editormd/emoji/heavy_multiplication_x.png create mode 100644 public/editormd/emoji/heavy_plus_sign.png create mode 100644 public/editormd/emoji/helicopter.png create mode 100644 public/editormd/emoji/herb.png create mode 100644 public/editormd/emoji/hibiscus.png create mode 100644 public/editormd/emoji/high_brightness.png create mode 100644 public/editormd/emoji/high_heel.png create mode 100644 public/editormd/emoji/hocho.png create mode 100644 public/editormd/emoji/honey_pot.png create mode 100644 public/editormd/emoji/honeybee.png create mode 100644 public/editormd/emoji/horse.png create mode 100644 public/editormd/emoji/horse_racing.png create mode 100644 public/editormd/emoji/hospital.png create mode 100644 public/editormd/emoji/hotel.png create mode 100644 public/editormd/emoji/hotsprings.png create mode 100644 public/editormd/emoji/hourglass.png create mode 100644 public/editormd/emoji/hourglass_flowing_sand.png create mode 100644 public/editormd/emoji/house.png create mode 100644 public/editormd/emoji/house_with_garden.png create mode 100644 public/editormd/emoji/hurtrealbad.png create mode 100644 public/editormd/emoji/hushed.png create mode 100644 public/editormd/emoji/ice_cream.png create mode 100644 public/editormd/emoji/icecream.png create mode 100644 public/editormd/emoji/id.png create mode 100644 public/editormd/emoji/ideograph_advantage.png create mode 100644 public/editormd/emoji/imp.png create mode 100644 public/editormd/emoji/inbox_tray.png create mode 100644 public/editormd/emoji/incoming_envelope.png create mode 100644 public/editormd/emoji/information_desk_person.png create mode 100644 public/editormd/emoji/information_source.png create mode 100644 public/editormd/emoji/innocent.png create mode 100644 public/editormd/emoji/interrobang.png create mode 100644 public/editormd/emoji/iphone.png create mode 100644 public/editormd/emoji/it.png create mode 100644 public/editormd/emoji/izakaya_lantern.png create mode 100644 public/editormd/emoji/jack_o_lantern.png create mode 100644 public/editormd/emoji/japan.png create mode 100644 public/editormd/emoji/japanese_castle.png create mode 100644 public/editormd/emoji/japanese_goblin.png create mode 100644 public/editormd/emoji/japanese_ogre.png create mode 100644 public/editormd/emoji/jeans.png create mode 100644 public/editormd/emoji/joy.png create mode 100644 public/editormd/emoji/joy_cat.png create mode 100644 public/editormd/emoji/jp.png create mode 100644 public/editormd/emoji/key.png create mode 100644 public/editormd/emoji/keycap_ten.png create mode 100644 public/editormd/emoji/kimono.png create mode 100644 public/editormd/emoji/kiss.png create mode 100644 public/editormd/emoji/kissing.png create mode 100644 public/editormd/emoji/kissing_cat.png create mode 100644 public/editormd/emoji/kissing_closed_eyes.png create mode 100644 public/editormd/emoji/kissing_face.png create mode 100644 public/editormd/emoji/kissing_heart.png create mode 100644 public/editormd/emoji/kissing_smiling_eyes.png create mode 100644 public/editormd/emoji/koala.png create mode 100644 public/editormd/emoji/koko.png create mode 100644 public/editormd/emoji/kr.png create mode 100644 public/editormd/emoji/large_blue_circle.png create mode 100644 public/editormd/emoji/large_blue_diamond.png create mode 100644 public/editormd/emoji/large_orange_diamond.png create mode 100644 public/editormd/emoji/last_quarter_moon.png create mode 100644 public/editormd/emoji/last_quarter_moon_with_face.png create mode 100644 public/editormd/emoji/laughing.png create mode 100644 public/editormd/emoji/leaves.png create mode 100644 public/editormd/emoji/ledger.png create mode 100644 public/editormd/emoji/left_luggage.png create mode 100644 public/editormd/emoji/left_right_arrow.png create mode 100644 public/editormd/emoji/leftwards_arrow_with_hook.png create mode 100644 public/editormd/emoji/lemon.png create mode 100644 public/editormd/emoji/leo.png create mode 100644 public/editormd/emoji/leopard.png create mode 100644 public/editormd/emoji/libra.png create mode 100644 public/editormd/emoji/light_rail.png create mode 100644 public/editormd/emoji/link.png create mode 100644 public/editormd/emoji/lips.png create mode 100644 public/editormd/emoji/lipstick.png create mode 100644 public/editormd/emoji/lock.png create mode 100644 public/editormd/emoji/lock_with_ink_pen.png create mode 100644 public/editormd/emoji/lollipop.png create mode 100644 public/editormd/emoji/loop.png create mode 100644 public/editormd/emoji/loudspeaker.png create mode 100644 public/editormd/emoji/love_hotel.png create mode 100644 public/editormd/emoji/love_letter.png create mode 100644 public/editormd/emoji/low_brightness.png create mode 100644 public/editormd/emoji/m.png create mode 100644 public/editormd/emoji/mag.png create mode 100644 public/editormd/emoji/mag_right.png create mode 100644 public/editormd/emoji/mahjong.png create mode 100644 public/editormd/emoji/mailbox.png create mode 100644 public/editormd/emoji/mailbox_closed.png create mode 100644 public/editormd/emoji/mailbox_with_mail.png create mode 100644 public/editormd/emoji/mailbox_with_no_mail.png create mode 100644 public/editormd/emoji/man.png create mode 100644 public/editormd/emoji/man_with_gua_pi_mao.png create mode 100644 public/editormd/emoji/man_with_turban.png create mode 100644 public/editormd/emoji/mans_shoe.png create mode 100644 public/editormd/emoji/maple_leaf.png create mode 100644 public/editormd/emoji/mask.png create mode 100644 public/editormd/emoji/massage.png create mode 100644 public/editormd/emoji/meat_on_bone.png create mode 100644 public/editormd/emoji/mega.png create mode 100644 public/editormd/emoji/melon.png create mode 100644 public/editormd/emoji/memo.png create mode 100644 public/editormd/emoji/mens.png create mode 100644 public/editormd/emoji/metal.png create mode 100644 public/editormd/emoji/metro.png create mode 100644 public/editormd/emoji/microphone.png create mode 100644 public/editormd/emoji/microscope.png create mode 100644 public/editormd/emoji/milky_way.png create mode 100644 public/editormd/emoji/minibus.png create mode 100644 public/editormd/emoji/minidisc.png create mode 100644 public/editormd/emoji/mobile_phone_off.png create mode 100644 public/editormd/emoji/money_with_wings.png create mode 100644 public/editormd/emoji/moneybag.png create mode 100644 public/editormd/emoji/monkey.png create mode 100644 public/editormd/emoji/monkey_face.png create mode 100644 public/editormd/emoji/monorail.png create mode 100644 public/editormd/emoji/mortar_board.png create mode 100644 public/editormd/emoji/mount_fuji.png create mode 100644 public/editormd/emoji/mountain_bicyclist.png create mode 100644 public/editormd/emoji/mountain_cableway.png create mode 100644 public/editormd/emoji/mountain_railway.png create mode 100644 public/editormd/emoji/mouse.png create mode 100644 public/editormd/emoji/mouse2.png create mode 100644 public/editormd/emoji/movie_camera.png create mode 100644 public/editormd/emoji/moyai.png create mode 100644 public/editormd/emoji/muscle.png create mode 100644 public/editormd/emoji/mushroom.png create mode 100644 public/editormd/emoji/musical_keyboard.png create mode 100644 public/editormd/emoji/musical_note.png create mode 100644 public/editormd/emoji/musical_score.png create mode 100644 public/editormd/emoji/mute.png create mode 100644 public/editormd/emoji/nail_care.png create mode 100644 public/editormd/emoji/name_badge.png create mode 100644 public/editormd/emoji/neckbeard.png create mode 100644 public/editormd/emoji/necktie.png create mode 100644 public/editormd/emoji/negative_squared_cross_mark.png create mode 100644 public/editormd/emoji/neutral_face.png create mode 100644 public/editormd/emoji/new.png create mode 100644 public/editormd/emoji/new_moon.png create mode 100644 public/editormd/emoji/new_moon_with_face.png create mode 100644 public/editormd/emoji/newspaper.png create mode 100644 public/editormd/emoji/ng.png create mode 100644 public/editormd/emoji/nine.png create mode 100644 public/editormd/emoji/no_bell.png create mode 100644 public/editormd/emoji/no_bicycles.png create mode 100644 public/editormd/emoji/no_entry.png create mode 100644 public/editormd/emoji/no_entry_sign.png create mode 100644 public/editormd/emoji/no_good.png create mode 100644 public/editormd/emoji/no_mobile_phones.png create mode 100644 public/editormd/emoji/no_mouth.png create mode 100644 public/editormd/emoji/no_pedestrians.png create mode 100644 public/editormd/emoji/no_smoking.png create mode 100644 public/editormd/emoji/non-potable_water.png create mode 100644 public/editormd/emoji/nose.png create mode 100644 public/editormd/emoji/notebook.png create mode 100644 public/editormd/emoji/notebook_with_decorative_cover.png create mode 100644 public/editormd/emoji/notes.png create mode 100644 public/editormd/emoji/nut_and_bolt.png create mode 100644 public/editormd/emoji/o.png create mode 100644 public/editormd/emoji/o2.png create mode 100644 public/editormd/emoji/ocean.png create mode 100644 public/editormd/emoji/octocat.png create mode 100644 public/editormd/emoji/octopus.png create mode 100644 public/editormd/emoji/oden.png create mode 100644 public/editormd/emoji/office.png create mode 100644 public/editormd/emoji/ok.png create mode 100644 public/editormd/emoji/ok_hand.png create mode 100644 public/editormd/emoji/ok_woman.png create mode 100644 public/editormd/emoji/older_man.png create mode 100644 public/editormd/emoji/older_woman.png create mode 100644 public/editormd/emoji/on.png create mode 100644 public/editormd/emoji/oncoming_automobile.png create mode 100644 public/editormd/emoji/oncoming_bus.png create mode 100644 public/editormd/emoji/oncoming_police_car.png create mode 100644 public/editormd/emoji/oncoming_taxi.png create mode 100644 public/editormd/emoji/one.png create mode 100644 public/editormd/emoji/open_file_folder.png create mode 100644 public/editormd/emoji/open_hands.png create mode 100644 public/editormd/emoji/open_mouth.png create mode 100644 public/editormd/emoji/ophiuchus.png create mode 100644 public/editormd/emoji/orange_book.png create mode 100644 public/editormd/emoji/outbox_tray.png create mode 100644 public/editormd/emoji/ox.png create mode 100644 public/editormd/emoji/package.png create mode 100644 public/editormd/emoji/page_facing_up.png create mode 100644 public/editormd/emoji/page_with_curl.png create mode 100644 public/editormd/emoji/pager.png create mode 100644 public/editormd/emoji/palm_tree.png create mode 100644 public/editormd/emoji/panda_face.png create mode 100644 public/editormd/emoji/paperclip.png create mode 100644 public/editormd/emoji/parking.png create mode 100644 public/editormd/emoji/part_alternation_mark.png create mode 100644 public/editormd/emoji/partly_sunny.png create mode 100644 public/editormd/emoji/passport_control.png create mode 100644 public/editormd/emoji/paw_prints.png create mode 100644 public/editormd/emoji/peach.png create mode 100644 public/editormd/emoji/pear.png create mode 100644 public/editormd/emoji/pencil.png create mode 100644 public/editormd/emoji/pencil2.png create mode 100644 public/editormd/emoji/penguin.png create mode 100644 public/editormd/emoji/pensive.png create mode 100644 public/editormd/emoji/performing_arts.png create mode 100644 public/editormd/emoji/persevere.png create mode 100644 public/editormd/emoji/person_frowning.png create mode 100644 public/editormd/emoji/person_with_blond_hair.png create mode 100644 public/editormd/emoji/person_with_pouting_face.png create mode 100644 public/editormd/emoji/phone.png create mode 100644 public/editormd/emoji/pig.png create mode 100644 public/editormd/emoji/pig2.png create mode 100644 public/editormd/emoji/pig_nose.png create mode 100644 public/editormd/emoji/pill.png create mode 100644 public/editormd/emoji/pineapple.png create mode 100644 public/editormd/emoji/pisces.png create mode 100644 public/editormd/emoji/pizza.png create mode 100644 public/editormd/emoji/plus1.png create mode 100644 public/editormd/emoji/point_down.png create mode 100644 public/editormd/emoji/point_left.png create mode 100644 public/editormd/emoji/point_right.png create mode 100644 public/editormd/emoji/point_up.png create mode 100644 public/editormd/emoji/point_up_2.png create mode 100644 public/editormd/emoji/police_car.png create mode 100644 public/editormd/emoji/poodle.png create mode 100644 public/editormd/emoji/poop.png create mode 100644 public/editormd/emoji/post_office.png create mode 100644 public/editormd/emoji/postal_horn.png create mode 100644 public/editormd/emoji/postbox.png create mode 100644 public/editormd/emoji/potable_water.png create mode 100644 public/editormd/emoji/pouch.png create mode 100644 public/editormd/emoji/poultry_leg.png create mode 100644 public/editormd/emoji/pound.png create mode 100644 public/editormd/emoji/pouting_cat.png create mode 100644 public/editormd/emoji/pray.png create mode 100644 public/editormd/emoji/princess.png create mode 100644 public/editormd/emoji/punch.png create mode 100644 public/editormd/emoji/purple_heart.png create mode 100644 public/editormd/emoji/purse.png create mode 100644 public/editormd/emoji/pushpin.png create mode 100644 public/editormd/emoji/put_litter_in_its_place.png create mode 100644 public/editormd/emoji/question.png create mode 100644 public/editormd/emoji/rabbit.png create mode 100644 public/editormd/emoji/rabbit2.png create mode 100644 public/editormd/emoji/racehorse.png create mode 100644 public/editormd/emoji/radio.png create mode 100644 public/editormd/emoji/radio_button.png create mode 100644 public/editormd/emoji/rage.png create mode 100644 public/editormd/emoji/rage1.png create mode 100644 public/editormd/emoji/rage2.png create mode 100644 public/editormd/emoji/rage3.png create mode 100644 public/editormd/emoji/rage4.png create mode 100644 public/editormd/emoji/railway_car.png create mode 100644 public/editormd/emoji/rainbow.png create mode 100644 public/editormd/emoji/raised_hand.png create mode 100644 public/editormd/emoji/raised_hands.png create mode 100644 public/editormd/emoji/raising_hand.png create mode 100644 public/editormd/emoji/ram.png create mode 100644 public/editormd/emoji/ramen.png create mode 100644 public/editormd/emoji/rat.png create mode 100644 public/editormd/emoji/recycle.png create mode 100644 public/editormd/emoji/red_car.png create mode 100644 public/editormd/emoji/red_circle.png create mode 100644 public/editormd/emoji/registered.png create mode 100644 public/editormd/emoji/relaxed.png create mode 100644 public/editormd/emoji/relieved.png create mode 100644 public/editormd/emoji/repeat.png create mode 100644 public/editormd/emoji/repeat_one.png create mode 100644 public/editormd/emoji/restroom.png create mode 100644 public/editormd/emoji/revolving_hearts.png create mode 100644 public/editormd/emoji/rewind.png create mode 100644 public/editormd/emoji/ribbon.png create mode 100644 public/editormd/emoji/rice.png create mode 100644 public/editormd/emoji/rice_ball.png create mode 100644 public/editormd/emoji/rice_cracker.png create mode 100644 public/editormd/emoji/rice_scene.png create mode 100644 public/editormd/emoji/ring.png create mode 100644 public/editormd/emoji/rocket.png create mode 100644 public/editormd/emoji/roller_coaster.png create mode 100644 public/editormd/emoji/rooster.png create mode 100644 public/editormd/emoji/rose.png create mode 100644 public/editormd/emoji/rotating_light.png create mode 100644 public/editormd/emoji/round_pushpin.png create mode 100644 public/editormd/emoji/rowboat.png create mode 100644 public/editormd/emoji/ru.png create mode 100644 public/editormd/emoji/rugby_football.png create mode 100644 public/editormd/emoji/runner.png create mode 100644 public/editormd/emoji/running.png create mode 100644 public/editormd/emoji/running_shirt_with_sash.png create mode 100644 public/editormd/emoji/sa.png create mode 100644 public/editormd/emoji/sagittarius.png create mode 100644 public/editormd/emoji/sailboat.png create mode 100644 public/editormd/emoji/sake.png create mode 100644 public/editormd/emoji/sandal.png create mode 100644 public/editormd/emoji/santa.png create mode 100644 public/editormd/emoji/satellite.png create mode 100644 public/editormd/emoji/satisfied.png create mode 100644 public/editormd/emoji/saxophone.png create mode 100644 public/editormd/emoji/school.png create mode 100644 public/editormd/emoji/school_satchel.png create mode 100644 public/editormd/emoji/scissors.png create mode 100644 public/editormd/emoji/scorpius.png create mode 100644 public/editormd/emoji/scream.png create mode 100644 public/editormd/emoji/scream_cat.png create mode 100644 public/editormd/emoji/scroll.png create mode 100644 public/editormd/emoji/seat.png create mode 100644 public/editormd/emoji/secret.png create mode 100644 public/editormd/emoji/see_no_evil.png create mode 100644 public/editormd/emoji/seedling.png create mode 100644 public/editormd/emoji/seven.png create mode 100644 public/editormd/emoji/shaved_ice.png create mode 100644 public/editormd/emoji/sheep.png create mode 100644 public/editormd/emoji/shell.png create mode 100644 public/editormd/emoji/ship.png create mode 100644 public/editormd/emoji/shipit.png create mode 100644 public/editormd/emoji/shirt.png create mode 100644 public/editormd/emoji/shit.png create mode 100644 public/editormd/emoji/shoe.png create mode 100644 public/editormd/emoji/shower.png create mode 100644 public/editormd/emoji/signal_strength.png create mode 100644 public/editormd/emoji/simple_smile.png create mode 100644 public/editormd/emoji/six.png create mode 100644 public/editormd/emoji/six_pointed_star.png create mode 100644 public/editormd/emoji/ski.png create mode 100644 public/editormd/emoji/skull.png create mode 100644 public/editormd/emoji/sleeping.png create mode 100644 public/editormd/emoji/sleepy.png create mode 100644 public/editormd/emoji/slot_machine.png create mode 100644 public/editormd/emoji/small_blue_diamond.png create mode 100644 public/editormd/emoji/small_orange_diamond.png create mode 100644 public/editormd/emoji/small_red_triangle.png create mode 100644 public/editormd/emoji/small_red_triangle_down.png create mode 100644 public/editormd/emoji/smile.png create mode 100644 public/editormd/emoji/smile_cat.png create mode 100644 public/editormd/emoji/smiley.png create mode 100644 public/editormd/emoji/smiley_cat.png create mode 100644 public/editormd/emoji/smiling_imp.png create mode 100644 public/editormd/emoji/smirk.png create mode 100644 public/editormd/emoji/smirk_cat.png create mode 100644 public/editormd/emoji/smoking.png create mode 100644 public/editormd/emoji/snail.png create mode 100644 public/editormd/emoji/snake.png create mode 100644 public/editormd/emoji/snowboarder.png create mode 100644 public/editormd/emoji/snowflake.png create mode 100644 public/editormd/emoji/snowman.png create mode 100644 public/editormd/emoji/sob.png create mode 100644 public/editormd/emoji/soccer.png create mode 100644 public/editormd/emoji/soon.png create mode 100644 public/editormd/emoji/sos.png create mode 100644 public/editormd/emoji/sound.png create mode 100644 public/editormd/emoji/space_invader.png create mode 100644 public/editormd/emoji/spades.png create mode 100644 public/editormd/emoji/spaghetti.png create mode 100644 public/editormd/emoji/sparkle.png create mode 100644 public/editormd/emoji/sparkler.png create mode 100644 public/editormd/emoji/sparkles.png create mode 100644 public/editormd/emoji/sparkling_heart.png create mode 100644 public/editormd/emoji/speak_no_evil.png create mode 100644 public/editormd/emoji/speaker.png create mode 100644 public/editormd/emoji/speech_balloon.png create mode 100644 public/editormd/emoji/speedboat.png create mode 100644 public/editormd/emoji/squirrel.png create mode 100644 public/editormd/emoji/star.png create mode 100644 public/editormd/emoji/star2.png create mode 100644 public/editormd/emoji/stars.png create mode 100644 public/editormd/emoji/station.png create mode 100644 public/editormd/emoji/statue_of_liberty.png create mode 100644 public/editormd/emoji/steam_locomotive.png create mode 100644 public/editormd/emoji/stew.png create mode 100644 public/editormd/emoji/straight_ruler.png create mode 100644 public/editormd/emoji/strawberry.png create mode 100644 public/editormd/emoji/stuck_out_tongue.png create mode 100644 public/editormd/emoji/stuck_out_tongue_closed_eyes.png create mode 100644 public/editormd/emoji/stuck_out_tongue_winking_eye.png create mode 100644 public/editormd/emoji/sun_with_face.png create mode 100644 public/editormd/emoji/sunflower.png create mode 100644 public/editormd/emoji/sunglasses.png create mode 100644 public/editormd/emoji/sunny.png create mode 100644 public/editormd/emoji/sunrise.png create mode 100644 public/editormd/emoji/sunrise_over_mountains.png create mode 100644 public/editormd/emoji/surfer.png create mode 100644 public/editormd/emoji/sushi.png create mode 100644 public/editormd/emoji/suspect.png create mode 100644 public/editormd/emoji/suspension_railway.png create mode 100644 public/editormd/emoji/sweat.png create mode 100644 public/editormd/emoji/sweat_drops.png create mode 100644 public/editormd/emoji/sweat_smile.png create mode 100644 public/editormd/emoji/sweet_potato.png create mode 100644 public/editormd/emoji/swimmer.png create mode 100644 public/editormd/emoji/symbols.png create mode 100644 public/editormd/emoji/syringe.png create mode 100644 public/editormd/emoji/tada.png create mode 100644 public/editormd/emoji/tanabata_tree.png create mode 100644 public/editormd/emoji/tangerine.png create mode 100644 public/editormd/emoji/taurus.png create mode 100644 public/editormd/emoji/taxi.png create mode 100644 public/editormd/emoji/tea.png create mode 100644 public/editormd/emoji/telephone.png create mode 100644 public/editormd/emoji/telephone_receiver.png create mode 100644 public/editormd/emoji/telescope.png create mode 100644 public/editormd/emoji/tennis.png create mode 100644 public/editormd/emoji/tent.png create mode 100644 public/editormd/emoji/thought_balloon.png create mode 100644 public/editormd/emoji/three.png create mode 100644 public/editormd/emoji/thumbsdown.png create mode 100644 public/editormd/emoji/thumbsup.png create mode 100644 public/editormd/emoji/ticket.png create mode 100644 public/editormd/emoji/tiger.png create mode 100644 public/editormd/emoji/tiger2.png create mode 100644 public/editormd/emoji/tired_face.png create mode 100644 public/editormd/emoji/tm.png create mode 100644 public/editormd/emoji/toilet.png create mode 100644 public/editormd/emoji/tokyo_tower.png create mode 100644 public/editormd/emoji/tomato.png create mode 100644 public/editormd/emoji/tongue.png create mode 100644 public/editormd/emoji/top.png create mode 100644 public/editormd/emoji/tophat.png create mode 100644 public/editormd/emoji/tractor.png create mode 100644 public/editormd/emoji/traffic_light.png create mode 100644 public/editormd/emoji/train.png create mode 100644 public/editormd/emoji/train2.png create mode 100644 public/editormd/emoji/tram.png create mode 100644 public/editormd/emoji/triangular_flag_on_post.png create mode 100644 public/editormd/emoji/triangular_ruler.png create mode 100644 public/editormd/emoji/trident.png create mode 100644 public/editormd/emoji/triumph.png create mode 100644 public/editormd/emoji/trolleybus.png create mode 100644 public/editormd/emoji/trollface.png create mode 100644 public/editormd/emoji/trophy.png create mode 100644 public/editormd/emoji/tropical_drink.png create mode 100644 public/editormd/emoji/tropical_fish.png create mode 100644 public/editormd/emoji/truck.png create mode 100644 public/editormd/emoji/trumpet.png create mode 100644 public/editormd/emoji/tshirt.png create mode 100644 public/editormd/emoji/tulip.png create mode 100644 public/editormd/emoji/turtle.png create mode 100644 public/editormd/emoji/tv.png create mode 100644 public/editormd/emoji/twisted_rightwards_arrows.png create mode 100644 public/editormd/emoji/two.png create mode 100644 public/editormd/emoji/two_hearts.png create mode 100644 public/editormd/emoji/two_men_holding_hands.png create mode 100644 public/editormd/emoji/two_women_holding_hands.png create mode 100644 public/editormd/emoji/u5272.png create mode 100644 public/editormd/emoji/u5408.png create mode 100644 public/editormd/emoji/u55b6.png create mode 100644 public/editormd/emoji/u6307.png create mode 100644 public/editormd/emoji/u6708.png create mode 100644 public/editormd/emoji/u6709.png create mode 100644 public/editormd/emoji/u6e80.png create mode 100644 public/editormd/emoji/u7121.png create mode 100644 public/editormd/emoji/u7533.png create mode 100644 public/editormd/emoji/u7981.png create mode 100644 public/editormd/emoji/u7a7a.png create mode 100644 public/editormd/emoji/uk.png create mode 100644 public/editormd/emoji/umbrella.png create mode 100644 public/editormd/emoji/unamused.png create mode 100644 public/editormd/emoji/underage.png create mode 100644 public/editormd/emoji/unlock.png create mode 100644 public/editormd/emoji/up.png create mode 100644 public/editormd/emoji/us.png create mode 100644 public/editormd/emoji/v.png create mode 100644 public/editormd/emoji/vertical_traffic_light.png create mode 100644 public/editormd/emoji/vhs.png create mode 100644 public/editormd/emoji/vibration_mode.png create mode 100644 public/editormd/emoji/video_camera.png create mode 100644 public/editormd/emoji/video_game.png create mode 100644 public/editormd/emoji/violin.png create mode 100644 public/editormd/emoji/virgo.png create mode 100644 public/editormd/emoji/volcano.png create mode 100644 public/editormd/emoji/vs.png create mode 100644 public/editormd/emoji/walking.png create mode 100644 public/editormd/emoji/waning_crescent_moon.png create mode 100644 public/editormd/emoji/waning_gibbous_moon.png create mode 100644 public/editormd/emoji/warning.png create mode 100644 public/editormd/emoji/watch.png create mode 100644 public/editormd/emoji/water_buffalo.png create mode 100644 public/editormd/emoji/watermelon.png create mode 100644 public/editormd/emoji/wave.png create mode 100644 public/editormd/emoji/wavy_dash.png create mode 100644 public/editormd/emoji/waxing_crescent_moon.png create mode 100644 public/editormd/emoji/waxing_gibbous_moon.png create mode 100644 public/editormd/emoji/wc.png create mode 100644 public/editormd/emoji/weary.png create mode 100644 public/editormd/emoji/wedding.png create mode 100644 public/editormd/emoji/whale.png create mode 100644 public/editormd/emoji/whale2.png create mode 100644 public/editormd/emoji/wheelchair.png create mode 100644 public/editormd/emoji/white_check_mark.png create mode 100644 public/editormd/emoji/white_circle.png create mode 100644 public/editormd/emoji/white_flower.png create mode 100644 public/editormd/emoji/white_large_square.png create mode 100644 public/editormd/emoji/white_medium_small_square.png create mode 100644 public/editormd/emoji/white_medium_square.png create mode 100644 public/editormd/emoji/white_small_square.png create mode 100644 public/editormd/emoji/white_square_button.png create mode 100644 public/editormd/emoji/wind_chime.png create mode 100644 public/editormd/emoji/wine_glass.png create mode 100644 public/editormd/emoji/wink.png create mode 100644 public/editormd/emoji/wolf.png create mode 100644 public/editormd/emoji/woman.png create mode 100644 public/editormd/emoji/womans_clothes.png create mode 100644 public/editormd/emoji/womans_hat.png create mode 100644 public/editormd/emoji/womens.png create mode 100644 public/editormd/emoji/worried.png create mode 100644 public/editormd/emoji/wrench.png create mode 100644 public/editormd/emoji/x.png create mode 100644 public/editormd/emoji/yellow_heart.png create mode 100644 public/editormd/emoji/yen.png create mode 100644 public/editormd/emoji/yum.png create mode 100644 public/editormd/emoji/zap.png create mode 100644 public/editormd/emoji/zero.png create mode 100644 public/editormd/emoji/zzz.png create mode 100644 public/editormd/examples/@links.html create mode 100644 public/editormd/examples/auto-height.html create mode 100644 public/editormd/examples/change-mode.html create mode 100644 public/editormd/examples/code-fold.html create mode 100644 public/editormd/examples/css/style.css create mode 100644 public/editormd/examples/custom-keyboard-shortcuts.html create mode 100644 public/editormd/examples/custom-toolbar.html create mode 100644 public/editormd/examples/define-plugin.html create mode 100644 public/editormd/examples/delay-renderer-preview.html create mode 100644 public/editormd/examples/dynamic-create-editormd.html create mode 100644 public/editormd/examples/emoji.html create mode 100644 public/editormd/examples/extends.html create mode 100644 public/editormd/examples/external-use.html create mode 100644 public/editormd/examples/flowchart.html create mode 100644 public/editormd/examples/form-get-value.html create mode 100644 public/editormd/examples/full.html create mode 100644 public/editormd/examples/goto-line.html create mode 100644 public/editormd/examples/html-preview-markdown-to-html-custom-toc-container.html create mode 100644 public/editormd/examples/html-preview-markdown-to-html.html create mode 100644 public/editormd/examples/html-tags-decode.html create mode 100644 public/editormd/examples/image-cross-domain-upload.html create mode 100644 public/editormd/examples/image-upload.html create mode 100644 public/editormd/examples/images/4.jpg create mode 100644 public/editormd/examples/images/7.jpg create mode 100644 public/editormd/examples/images/8.jpg create mode 100644 public/editormd/examples/images/editormd-screenshot.png create mode 100644 public/editormd/examples/index.html create mode 100644 public/editormd/examples/js/jquery.min.js create mode 100644 public/editormd/examples/js/require.min.js create mode 100644 public/editormd/examples/js/sea.js create mode 100644 public/editormd/examples/js/seajs-main.js create mode 100644 public/editormd/examples/js/zepto.min.js create mode 100644 public/editormd/examples/katex.html create mode 100644 public/editormd/examples/manually-load-modules.html create mode 100644 public/editormd/examples/multi-editormd.html create mode 100644 public/editormd/examples/multi-languages.html create mode 100644 public/editormd/examples/on-off.html create mode 100644 public/editormd/examples/onchange.html create mode 100644 public/editormd/examples/onfullscreen.html create mode 100644 public/editormd/examples/onload.html create mode 100644 public/editormd/examples/onpreviewing-onpreviewed.html create mode 100644 public/editormd/examples/onresize.html create mode 100644 public/editormd/examples/onscroll-onpreviewscroll.html create mode 100644 public/editormd/examples/onwatch-onunwatch.html create mode 100644 public/editormd/examples/page-break.html create mode 100644 public/editormd/examples/php/cross-domain-upload.php create mode 100644 public/editormd/examples/php/editormd.uploader.class.php create mode 100644 public/editormd/examples/php/post.php create mode 100644 public/editormd/examples/php/upload.php create mode 100644 public/editormd/examples/php/upload_callback.html create mode 100644 public/editormd/examples/readonly.html create mode 100644 public/editormd/examples/resettings.html create mode 100644 public/editormd/examples/search-replace.html create mode 100644 public/editormd/examples/sequence-diagram.html create mode 100644 public/editormd/examples/set-get-replace-selection.html create mode 100644 public/editormd/examples/simple.html create mode 100644 public/editormd/examples/sync-scrolling.html create mode 100644 public/editormd/examples/task-lists.html create mode 100644 public/editormd/examples/test.md create mode 100644 public/editormd/examples/themes.html create mode 100644 public/editormd/examples/toc.html create mode 100644 public/editormd/examples/toolbar-auto-fixed.html create mode 100644 public/editormd/examples/use-requirejs.html create mode 100644 public/editormd/examples/use-seajs.html create mode 100644 public/editormd/examples/use-zepto.html create mode 100644 public/editormd/fonts/FontAwesome.otf create mode 100644 public/editormd/fonts/editormd-logo.eot create mode 100644 public/editormd/fonts/editormd-logo.svg create mode 100644 public/editormd/fonts/editormd-logo.ttf create mode 100644 public/editormd/fonts/editormd-logo.woff create mode 100644 public/editormd/fonts/fontawesome-webfont.eot create mode 100644 public/editormd/fonts/fontawesome-webfont.svg create mode 100644 public/editormd/fonts/fontawesome-webfont.ttf create mode 100644 public/editormd/fonts/fontawesome-webfont.woff create mode 100644 public/editormd/fonts/fontawesome-webfont.woff2 create mode 100644 public/editormd/images/loading.gif create mode 100644 public/editormd/images/loading@2x.gif create mode 100644 public/editormd/images/loading@3x.gif create mode 100644 public/editormd/images/logos/editormd-favicon-16x16.ico create mode 100644 public/editormd/images/logos/editormd-favicon-24x24.ico create mode 100644 public/editormd/images/logos/editormd-favicon-32x32.ico create mode 100644 public/editormd/images/logos/editormd-favicon-48x48.ico create mode 100644 public/editormd/images/logos/editormd-favicon-64x64.ico create mode 100644 public/editormd/images/logos/editormd-logo-114x114.png create mode 100644 public/editormd/images/logos/editormd-logo-120x120.png create mode 100644 public/editormd/images/logos/editormd-logo-144x144.png create mode 100644 public/editormd/images/logos/editormd-logo-16x16.png create mode 100644 public/editormd/images/logos/editormd-logo-180x180.png create mode 100644 public/editormd/images/logos/editormd-logo-240x240.png create mode 100644 public/editormd/images/logos/editormd-logo-24x24.png create mode 100644 public/editormd/images/logos/editormd-logo-320x320.png create mode 100644 public/editormd/images/logos/editormd-logo-32x32.png create mode 100644 public/editormd/images/logos/editormd-logo-48x48.png create mode 100644 public/editormd/images/logos/editormd-logo-57x57.png create mode 100644 public/editormd/images/logos/editormd-logo-64x64.png create mode 100644 public/editormd/images/logos/editormd-logo-72x72.png create mode 100644 public/editormd/images/logos/editormd-logo-96x96.png create mode 100644 public/editormd/images/logos/vi.png create mode 100644 public/editormd/languages/en.js create mode 100644 public/editormd/languages/zh-tw.js create mode 100644 public/editormd/lib/codemirror/AUTHORS create mode 100644 public/editormd/lib/codemirror/LICENSE create mode 100644 public/editormd/lib/codemirror/README.md create mode 100644 public/editormd/lib/codemirror/addon/comment/comment.js create mode 100644 public/editormd/lib/codemirror/addon/comment/continuecomment.js create mode 100644 public/editormd/lib/codemirror/addon/dialog/dialog.css create mode 100644 public/editormd/lib/codemirror/addon/dialog/dialog.js create mode 100644 public/editormd/lib/codemirror/addon/display/fullscreen.css create mode 100644 public/editormd/lib/codemirror/addon/display/fullscreen.js create mode 100644 public/editormd/lib/codemirror/addon/display/panel.js create mode 100644 public/editormd/lib/codemirror/addon/display/placeholder.js create mode 100644 public/editormd/lib/codemirror/addon/display/rulers.js create mode 100644 public/editormd/lib/codemirror/addon/edit/closebrackets.js create mode 100644 public/editormd/lib/codemirror/addon/edit/closetag.js create mode 100644 public/editormd/lib/codemirror/addon/edit/continuelist.js create mode 100644 public/editormd/lib/codemirror/addon/edit/matchbrackets.js create mode 100644 public/editormd/lib/codemirror/addon/edit/matchtags.js create mode 100644 public/editormd/lib/codemirror/addon/edit/trailingspace.js create mode 100644 public/editormd/lib/codemirror/addon/fold/brace-fold.js create mode 100644 public/editormd/lib/codemirror/addon/fold/comment-fold.js create mode 100644 public/editormd/lib/codemirror/addon/fold/foldcode.js create mode 100644 public/editormd/lib/codemirror/addon/fold/foldgutter.css create mode 100644 public/editormd/lib/codemirror/addon/fold/foldgutter.js create mode 100644 public/editormd/lib/codemirror/addon/fold/indent-fold.js create mode 100644 public/editormd/lib/codemirror/addon/fold/markdown-fold.js create mode 100644 public/editormd/lib/codemirror/addon/fold/xml-fold.js create mode 100644 public/editormd/lib/codemirror/addon/hint/anyword-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/css-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/html-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/javascript-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/show-hint.css create mode 100644 public/editormd/lib/codemirror/addon/hint/show-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/sql-hint.js create mode 100644 public/editormd/lib/codemirror/addon/hint/xml-hint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/coffeescript-lint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/css-lint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/javascript-lint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/json-lint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/lint.css create mode 100644 public/editormd/lib/codemirror/addon/lint/lint.js create mode 100644 public/editormd/lib/codemirror/addon/lint/yaml-lint.js create mode 100644 public/editormd/lib/codemirror/addon/merge/merge.css create mode 100644 public/editormd/lib/codemirror/addon/merge/merge.js create mode 100644 public/editormd/lib/codemirror/addon/mode/loadmode.js create mode 100644 public/editormd/lib/codemirror/addon/mode/multiplex.js create mode 100644 public/editormd/lib/codemirror/addon/mode/multiplex_test.js create mode 100644 public/editormd/lib/codemirror/addon/mode/overlay.js create mode 100644 public/editormd/lib/codemirror/addon/mode/simple.js create mode 100644 public/editormd/lib/codemirror/addon/runmode/colorize.js create mode 100644 public/editormd/lib/codemirror/addon/runmode/runmode-standalone.js create mode 100644 public/editormd/lib/codemirror/addon/runmode/runmode.js create mode 100644 public/editormd/lib/codemirror/addon/runmode/runmode.node.js create mode 100644 public/editormd/lib/codemirror/addon/scroll/annotatescrollbar.js create mode 100644 public/editormd/lib/codemirror/addon/scroll/scrollpastend.js create mode 100644 public/editormd/lib/codemirror/addon/scroll/simplescrollbars.css create mode 100644 public/editormd/lib/codemirror/addon/scroll/simplescrollbars.js create mode 100644 public/editormd/lib/codemirror/addon/search/match-highlighter.js create mode 100644 public/editormd/lib/codemirror/addon/search/matchesonscrollbar.css create mode 100644 public/editormd/lib/codemirror/addon/search/matchesonscrollbar.js create mode 100644 public/editormd/lib/codemirror/addon/search/search.js create mode 100644 public/editormd/lib/codemirror/addon/search/searchcursor.js create mode 100644 public/editormd/lib/codemirror/addon/selection/active-line.js create mode 100644 public/editormd/lib/codemirror/addon/selection/mark-selection.js create mode 100644 public/editormd/lib/codemirror/addon/selection/selection-pointer.js create mode 100644 public/editormd/lib/codemirror/addon/tern/tern.css create mode 100644 public/editormd/lib/codemirror/addon/tern/tern.js create mode 100644 public/editormd/lib/codemirror/addon/tern/worker.js create mode 100644 public/editormd/lib/codemirror/addon/wrap/hardwrap.js create mode 100644 public/editormd/lib/codemirror/addons.min.js create mode 100644 public/editormd/lib/codemirror/bower.json create mode 100644 public/editormd/lib/codemirror/codemirror.min.css create mode 100644 public/editormd/lib/codemirror/codemirror.min.js create mode 100644 public/editormd/lib/codemirror/lib/codemirror.css create mode 100644 public/editormd/lib/codemirror/lib/codemirror.js create mode 100644 public/editormd/lib/codemirror/mode/apl/apl.js create mode 100644 public/editormd/lib/codemirror/mode/apl/index.html create mode 100644 public/editormd/lib/codemirror/mode/asterisk/asterisk.js create mode 100644 public/editormd/lib/codemirror/mode/asterisk/index.html create mode 100644 public/editormd/lib/codemirror/mode/clike/clike.js create mode 100644 public/editormd/lib/codemirror/mode/clike/index.html create mode 100644 public/editormd/lib/codemirror/mode/clike/scala.html create mode 100644 public/editormd/lib/codemirror/mode/clojure/clojure.js create mode 100644 public/editormd/lib/codemirror/mode/clojure/index.html create mode 100644 public/editormd/lib/codemirror/mode/cobol/cobol.js create mode 100644 public/editormd/lib/codemirror/mode/cobol/index.html create mode 100644 public/editormd/lib/codemirror/mode/coffeescript/coffeescript.js create mode 100644 public/editormd/lib/codemirror/mode/coffeescript/index.html create mode 100644 public/editormd/lib/codemirror/mode/commonlisp/commonlisp.js create mode 100644 public/editormd/lib/codemirror/mode/commonlisp/index.html create mode 100644 public/editormd/lib/codemirror/mode/css/css.js create mode 100644 public/editormd/lib/codemirror/mode/css/index.html create mode 100644 public/editormd/lib/codemirror/mode/css/less.html create mode 100644 public/editormd/lib/codemirror/mode/css/less_test.js create mode 100644 public/editormd/lib/codemirror/mode/css/scss.html create mode 100644 public/editormd/lib/codemirror/mode/css/scss_test.js create mode 100644 public/editormd/lib/codemirror/mode/css/test.js create mode 100644 public/editormd/lib/codemirror/mode/cypher/cypher.js create mode 100644 public/editormd/lib/codemirror/mode/cypher/index.html create mode 100644 public/editormd/lib/codemirror/mode/d/d.js create mode 100644 public/editormd/lib/codemirror/mode/d/index.html create mode 100644 public/editormd/lib/codemirror/mode/dart/dart.js create mode 100644 public/editormd/lib/codemirror/mode/dart/index.html create mode 100644 public/editormd/lib/codemirror/mode/diff/diff.js create mode 100644 public/editormd/lib/codemirror/mode/diff/index.html create mode 100644 public/editormd/lib/codemirror/mode/django/django.js create mode 100644 public/editormd/lib/codemirror/mode/django/index.html create mode 100644 public/editormd/lib/codemirror/mode/dockerfile/dockerfile.js create mode 100644 public/editormd/lib/codemirror/mode/dockerfile/index.html create mode 100644 public/editormd/lib/codemirror/mode/dtd/dtd.js create mode 100644 public/editormd/lib/codemirror/mode/dtd/index.html create mode 100644 public/editormd/lib/codemirror/mode/dylan/dylan.js create mode 100644 public/editormd/lib/codemirror/mode/dylan/index.html create mode 100644 public/editormd/lib/codemirror/mode/ebnf/ebnf.js create mode 100644 public/editormd/lib/codemirror/mode/ebnf/index.html create mode 100644 public/editormd/lib/codemirror/mode/ecl/ecl.js create mode 100644 public/editormd/lib/codemirror/mode/ecl/index.html create mode 100644 public/editormd/lib/codemirror/mode/eiffel/eiffel.js create mode 100644 public/editormd/lib/codemirror/mode/eiffel/index.html create mode 100644 public/editormd/lib/codemirror/mode/erlang/erlang.js create mode 100644 public/editormd/lib/codemirror/mode/erlang/index.html create mode 100644 public/editormd/lib/codemirror/mode/forth/forth.js create mode 100644 public/editormd/lib/codemirror/mode/forth/index.html create mode 100644 public/editormd/lib/codemirror/mode/fortran/fortran.js create mode 100644 public/editormd/lib/codemirror/mode/fortran/index.html create mode 100644 public/editormd/lib/codemirror/mode/gas/gas.js create mode 100644 public/editormd/lib/codemirror/mode/gas/index.html create mode 100644 public/editormd/lib/codemirror/mode/gfm/gfm.js create mode 100644 public/editormd/lib/codemirror/mode/gfm/index.html create mode 100644 public/editormd/lib/codemirror/mode/gfm/test.js create mode 100644 public/editormd/lib/codemirror/mode/gherkin/gherkin.js create mode 100644 public/editormd/lib/codemirror/mode/gherkin/index.html create mode 100644 public/editormd/lib/codemirror/mode/go/go.js create mode 100644 public/editormd/lib/codemirror/mode/go/index.html create mode 100644 public/editormd/lib/codemirror/mode/groovy/groovy.js create mode 100644 public/editormd/lib/codemirror/mode/groovy/index.html create mode 100644 public/editormd/lib/codemirror/mode/haml/haml.js create mode 100644 public/editormd/lib/codemirror/mode/haml/index.html create mode 100644 public/editormd/lib/codemirror/mode/haml/test.js create mode 100644 public/editormd/lib/codemirror/mode/haskell/haskell.js create mode 100644 public/editormd/lib/codemirror/mode/haskell/index.html create mode 100644 public/editormd/lib/codemirror/mode/haxe/haxe.js create mode 100644 public/editormd/lib/codemirror/mode/haxe/index.html create mode 100644 public/editormd/lib/codemirror/mode/htmlembedded/htmlembedded.js create mode 100644 public/editormd/lib/codemirror/mode/htmlembedded/index.html create mode 100644 public/editormd/lib/codemirror/mode/htmlmixed/htmlmixed.js create mode 100644 public/editormd/lib/codemirror/mode/htmlmixed/index.html create mode 100644 public/editormd/lib/codemirror/mode/http/http.js create mode 100644 public/editormd/lib/codemirror/mode/http/index.html create mode 100644 public/editormd/lib/codemirror/mode/idl/idl.js create mode 100644 public/editormd/lib/codemirror/mode/idl/index.html create mode 100644 public/editormd/lib/codemirror/mode/index.html create mode 100644 public/editormd/lib/codemirror/mode/jade/index.html create mode 100644 public/editormd/lib/codemirror/mode/jade/jade.js create mode 100644 public/editormd/lib/codemirror/mode/javascript/index.html create mode 100644 public/editormd/lib/codemirror/mode/javascript/javascript.js create mode 100644 public/editormd/lib/codemirror/mode/javascript/json-ld.html create mode 100644 public/editormd/lib/codemirror/mode/javascript/test.js create mode 100644 public/editormd/lib/codemirror/mode/javascript/typescript.html create mode 100644 public/editormd/lib/codemirror/mode/jinja2/index.html create mode 100644 public/editormd/lib/codemirror/mode/jinja2/jinja2.js create mode 100644 public/editormd/lib/codemirror/mode/julia/index.html create mode 100644 public/editormd/lib/codemirror/mode/julia/julia.js create mode 100644 public/editormd/lib/codemirror/mode/kotlin/index.html create mode 100644 public/editormd/lib/codemirror/mode/kotlin/kotlin.js create mode 100644 public/editormd/lib/codemirror/mode/livescript/index.html create mode 100644 public/editormd/lib/codemirror/mode/livescript/livescript.js create mode 100644 public/editormd/lib/codemirror/mode/lua/index.html create mode 100644 public/editormd/lib/codemirror/mode/lua/lua.js create mode 100644 public/editormd/lib/codemirror/mode/markdown/index.html create mode 100644 public/editormd/lib/codemirror/mode/markdown/markdown.js create mode 100644 public/editormd/lib/codemirror/mode/markdown/test.js create mode 100644 public/editormd/lib/codemirror/mode/meta.js create mode 100644 public/editormd/lib/codemirror/mode/mirc/index.html create mode 100644 public/editormd/lib/codemirror/mode/mirc/mirc.js create mode 100644 public/editormd/lib/codemirror/mode/mllike/index.html create mode 100644 public/editormd/lib/codemirror/mode/mllike/mllike.js create mode 100644 public/editormd/lib/codemirror/mode/modelica/index.html create mode 100644 public/editormd/lib/codemirror/mode/modelica/modelica.js create mode 100644 public/editormd/lib/codemirror/mode/nginx/index.html create mode 100644 public/editormd/lib/codemirror/mode/nginx/nginx.js create mode 100644 public/editormd/lib/codemirror/mode/ntriples/index.html create mode 100644 public/editormd/lib/codemirror/mode/ntriples/ntriples.js create mode 100644 public/editormd/lib/codemirror/mode/octave/index.html create mode 100644 public/editormd/lib/codemirror/mode/octave/octave.js create mode 100644 public/editormd/lib/codemirror/mode/pascal/index.html create mode 100644 public/editormd/lib/codemirror/mode/pascal/pascal.js create mode 100644 public/editormd/lib/codemirror/mode/pegjs/index.html create mode 100644 public/editormd/lib/codemirror/mode/pegjs/pegjs.js create mode 100644 public/editormd/lib/codemirror/mode/perl/index.html create mode 100644 public/editormd/lib/codemirror/mode/perl/perl.js create mode 100644 public/editormd/lib/codemirror/mode/php/index.html create mode 100644 public/editormd/lib/codemirror/mode/php/php.js create mode 100644 public/editormd/lib/codemirror/mode/php/test.js create mode 100644 public/editormd/lib/codemirror/mode/pig/index.html create mode 100644 public/editormd/lib/codemirror/mode/pig/pig.js create mode 100644 public/editormd/lib/codemirror/mode/properties/index.html create mode 100644 public/editormd/lib/codemirror/mode/properties/properties.js create mode 100644 public/editormd/lib/codemirror/mode/puppet/index.html create mode 100644 public/editormd/lib/codemirror/mode/puppet/puppet.js create mode 100644 public/editormd/lib/codemirror/mode/python/index.html create mode 100644 public/editormd/lib/codemirror/mode/python/python.js create mode 100644 public/editormd/lib/codemirror/mode/q/index.html create mode 100644 public/editormd/lib/codemirror/mode/q/q.js create mode 100644 public/editormd/lib/codemirror/mode/r/index.html create mode 100644 public/editormd/lib/codemirror/mode/r/r.js create mode 100644 public/editormd/lib/codemirror/mode/rpm/changes/index.html create mode 100644 public/editormd/lib/codemirror/mode/rpm/index.html create mode 100644 public/editormd/lib/codemirror/mode/rpm/rpm.js create mode 100644 public/editormd/lib/codemirror/mode/rst/index.html create mode 100644 public/editormd/lib/codemirror/mode/rst/rst.js create mode 100644 public/editormd/lib/codemirror/mode/ruby/index.html create mode 100644 public/editormd/lib/codemirror/mode/ruby/ruby.js create mode 100644 public/editormd/lib/codemirror/mode/ruby/test.js create mode 100644 public/editormd/lib/codemirror/mode/rust/index.html create mode 100644 public/editormd/lib/codemirror/mode/rust/rust.js create mode 100644 public/editormd/lib/codemirror/mode/sass/index.html create mode 100644 public/editormd/lib/codemirror/mode/sass/sass.js create mode 100644 public/editormd/lib/codemirror/mode/scheme/index.html create mode 100644 public/editormd/lib/codemirror/mode/scheme/scheme.js create mode 100644 public/editormd/lib/codemirror/mode/shell/index.html create mode 100644 public/editormd/lib/codemirror/mode/shell/shell.js create mode 100644 public/editormd/lib/codemirror/mode/shell/test.js create mode 100644 public/editormd/lib/codemirror/mode/sieve/index.html create mode 100644 public/editormd/lib/codemirror/mode/sieve/sieve.js create mode 100644 public/editormd/lib/codemirror/mode/slim/index.html create mode 100644 public/editormd/lib/codemirror/mode/slim/slim.js create mode 100644 public/editormd/lib/codemirror/mode/slim/test.js create mode 100644 public/editormd/lib/codemirror/mode/smalltalk/index.html create mode 100644 public/editormd/lib/codemirror/mode/smalltalk/smalltalk.js create mode 100644 public/editormd/lib/codemirror/mode/smarty/index.html create mode 100644 public/editormd/lib/codemirror/mode/smarty/smarty.js create mode 100644 public/editormd/lib/codemirror/mode/smartymixed/index.html create mode 100644 public/editormd/lib/codemirror/mode/smartymixed/smartymixed.js create mode 100644 public/editormd/lib/codemirror/mode/solr/index.html create mode 100644 public/editormd/lib/codemirror/mode/solr/solr.js create mode 100644 public/editormd/lib/codemirror/mode/soy/index.html create mode 100644 public/editormd/lib/codemirror/mode/soy/soy.js create mode 100644 public/editormd/lib/codemirror/mode/sparql/index.html create mode 100644 public/editormd/lib/codemirror/mode/sparql/sparql.js create mode 100644 public/editormd/lib/codemirror/mode/spreadsheet/index.html create mode 100644 public/editormd/lib/codemirror/mode/spreadsheet/spreadsheet.js create mode 100644 public/editormd/lib/codemirror/mode/sql/index.html create mode 100644 public/editormd/lib/codemirror/mode/sql/sql.js create mode 100644 public/editormd/lib/codemirror/mode/stex/index.html create mode 100644 public/editormd/lib/codemirror/mode/stex/stex.js create mode 100644 public/editormd/lib/codemirror/mode/stex/test.js create mode 100644 public/editormd/lib/codemirror/mode/stylus/index.html create mode 100644 public/editormd/lib/codemirror/mode/stylus/stylus.js create mode 100644 public/editormd/lib/codemirror/mode/tcl/index.html create mode 100644 public/editormd/lib/codemirror/mode/tcl/tcl.js create mode 100644 public/editormd/lib/codemirror/mode/textile/index.html create mode 100644 public/editormd/lib/codemirror/mode/textile/test.js create mode 100644 public/editormd/lib/codemirror/mode/textile/textile.js create mode 100644 public/editormd/lib/codemirror/mode/tiddlywiki/index.html create mode 100644 public/editormd/lib/codemirror/mode/tiddlywiki/tiddlywiki.css create mode 100644 public/editormd/lib/codemirror/mode/tiddlywiki/tiddlywiki.js create mode 100644 public/editormd/lib/codemirror/mode/tiki/index.html create mode 100644 public/editormd/lib/codemirror/mode/tiki/tiki.css create mode 100644 public/editormd/lib/codemirror/mode/tiki/tiki.js create mode 100644 public/editormd/lib/codemirror/mode/toml/index.html create mode 100644 public/editormd/lib/codemirror/mode/toml/toml.js create mode 100644 public/editormd/lib/codemirror/mode/tornado/index.html create mode 100644 public/editormd/lib/codemirror/mode/tornado/tornado.js create mode 100644 public/editormd/lib/codemirror/mode/turtle/index.html create mode 100644 public/editormd/lib/codemirror/mode/turtle/turtle.js create mode 100644 public/editormd/lib/codemirror/mode/vb/index.html create mode 100644 public/editormd/lib/codemirror/mode/vb/vb.js create mode 100644 public/editormd/lib/codemirror/mode/vbscript/index.html create mode 100644 public/editormd/lib/codemirror/mode/vbscript/vbscript.js create mode 100644 public/editormd/lib/codemirror/mode/velocity/index.html create mode 100644 public/editormd/lib/codemirror/mode/velocity/velocity.js create mode 100644 public/editormd/lib/codemirror/mode/verilog/index.html create mode 100644 public/editormd/lib/codemirror/mode/verilog/test.js create mode 100644 public/editormd/lib/codemirror/mode/verilog/verilog.js create mode 100644 public/editormd/lib/codemirror/mode/xml/index.html create mode 100644 public/editormd/lib/codemirror/mode/xml/test.js create mode 100644 public/editormd/lib/codemirror/mode/xml/xml.js create mode 100644 public/editormd/lib/codemirror/mode/xquery/index.html create mode 100644 public/editormd/lib/codemirror/mode/xquery/test.js create mode 100644 public/editormd/lib/codemirror/mode/xquery/xquery.js create mode 100644 public/editormd/lib/codemirror/mode/yaml/index.html create mode 100644 public/editormd/lib/codemirror/mode/yaml/yaml.js create mode 100644 public/editormd/lib/codemirror/mode/z80/index.html create mode 100644 public/editormd/lib/codemirror/mode/z80/z80.js create mode 100644 public/editormd/lib/codemirror/modes.min.js create mode 100644 public/editormd/lib/codemirror/package.json create mode 100644 public/editormd/lib/codemirror/theme/3024-day.css create mode 100644 public/editormd/lib/codemirror/theme/3024-night.css create mode 100644 public/editormd/lib/codemirror/theme/ambiance-mobile.css create mode 100644 public/editormd/lib/codemirror/theme/ambiance.css create mode 100644 public/editormd/lib/codemirror/theme/base16-dark.css create mode 100644 public/editormd/lib/codemirror/theme/base16-light.css create mode 100644 public/editormd/lib/codemirror/theme/blackboard.css create mode 100644 public/editormd/lib/codemirror/theme/cobalt.css create mode 100644 public/editormd/lib/codemirror/theme/colorforth.css create mode 100644 public/editormd/lib/codemirror/theme/eclipse.css create mode 100644 public/editormd/lib/codemirror/theme/elegant.css create mode 100644 public/editormd/lib/codemirror/theme/erlang-dark.css create mode 100644 public/editormd/lib/codemirror/theme/lesser-dark.css create mode 100644 public/editormd/lib/codemirror/theme/mbo.css create mode 100644 public/editormd/lib/codemirror/theme/mdn-like.css create mode 100644 public/editormd/lib/codemirror/theme/midnight.css create mode 100644 public/editormd/lib/codemirror/theme/monokai.css create mode 100644 public/editormd/lib/codemirror/theme/neat.css create mode 100644 public/editormd/lib/codemirror/theme/neo.css create mode 100644 public/editormd/lib/codemirror/theme/night.css create mode 100644 public/editormd/lib/codemirror/theme/paraiso-dark.css create mode 100644 public/editormd/lib/codemirror/theme/paraiso-light.css create mode 100644 public/editormd/lib/codemirror/theme/pastel-on-dark.css create mode 100644 public/editormd/lib/codemirror/theme/rubyblue.css create mode 100644 public/editormd/lib/codemirror/theme/solarized.css create mode 100644 public/editormd/lib/codemirror/theme/the-matrix.css create mode 100644 public/editormd/lib/codemirror/theme/tomorrow-night-bright.css create mode 100644 public/editormd/lib/codemirror/theme/tomorrow-night-eighties.css create mode 100644 public/editormd/lib/codemirror/theme/twilight.css create mode 100644 public/editormd/lib/codemirror/theme/vibrant-ink.css create mode 100644 public/editormd/lib/codemirror/theme/xq-dark.css create mode 100644 public/editormd/lib/codemirror/theme/xq-light.css create mode 100644 public/editormd/lib/codemirror/theme/zenburn.css create mode 100644 public/editormd/lib/flowchart.min.js create mode 100644 public/editormd/lib/jquery.flowchart.min.js create mode 100644 public/editormd/lib/marked.min.backup.js create mode 100644 public/editormd/lib/marked.min.js create mode 100644 public/editormd/lib/prettify.min.js create mode 100644 public/editormd/lib/raphael.min.js create mode 100644 public/editormd/lib/readme-marked.txt create mode 100644 public/editormd/lib/sequence-diagram.min.js create mode 100644 public/editormd/lib/underscore.min.js create mode 100644 public/editormd/package.json create mode 100644 public/editormd/plugins/code-block-dialog/code-block-dialog.js create mode 100644 public/editormd/plugins/emoji-dialog/emoji-dialog.js create mode 100644 public/editormd/plugins/emoji-dialog/emoji.json create mode 100644 public/editormd/plugins/goto-line-dialog/goto-line-dialog.js create mode 100644 public/editormd/plugins/help-dialog/help-dialog.js create mode 100644 public/editormd/plugins/help-dialog/help.md create mode 100644 public/editormd/plugins/html-entities-dialog/html-entities-dialog.js create mode 100644 public/editormd/plugins/html-entities-dialog/html-entities.json create mode 100644 public/editormd/plugins/image-dialog/image-dialog.js create mode 100644 public/editormd/plugins/link-dialog/link-dialog.js create mode 100644 public/editormd/plugins/plugin-template.js create mode 100644 public/editormd/plugins/preformatted-text-dialog/preformatted-text-dialog.js create mode 100644 public/editormd/plugins/reference-link-dialog/reference-link-dialog.js create mode 100644 public/editormd/plugins/table-dialog/table-dialog.js create mode 100644 public/editormd/plugins/test-plugin/test-plugin.js create mode 100644 public/editormd/scss/editormd.codemirror.scss create mode 100644 public/editormd/scss/editormd.dialog.scss create mode 100644 public/editormd/scss/editormd.form.scss create mode 100644 public/editormd/scss/editormd.grid.scss create mode 100644 public/editormd/scss/editormd.logo.scss create mode 100644 public/editormd/scss/editormd.menu.scss create mode 100644 public/editormd/scss/editormd.preview.scss create mode 100644 public/editormd/scss/editormd.preview.themes.scss create mode 100644 public/editormd/scss/editormd.scss create mode 100644 public/editormd/scss/editormd.tab.scss create mode 100644 public/editormd/scss/editormd.themes.scss create mode 100644 public/editormd/scss/font-awesome.scss create mode 100644 public/editormd/scss/github-markdown.scss create mode 100644 public/editormd/scss/lib/prefixes.scss create mode 100644 public/editormd/scss/lib/variables.scss create mode 100644 public/editormd/scss/prettify.scss create mode 100644 public/editormd/src/editormd.js create mode 100644 public/editormd/tests/bootstrap-test.html create mode 100644 public/editormd/tests/codemirror-searchbox-test.html create mode 100644 public/editormd/tests/codemirror-test.html create mode 100644 public/editormd/tests/css/bootstrap-theme.min.css create mode 100644 public/editormd/tests/css/bootstrap.min.css create mode 100644 public/editormd/tests/js/bootstrap.min.js create mode 100644 public/editormd/tests/js/searchbox.js create mode 100644 public/editormd/tests/katex-tests.html create mode 100644 public/editormd/tests/marked-@at-test.html create mode 100644 public/editormd/tests/marked-emoji-test.html create mode 100644 public/editormd/tests/marked-heading-link-test.html create mode 100644 public/editormd/tests/marked-todo-list-test.html create mode 100644 public/editormd/tests/qunit/qunit-1.16.0.css create mode 100644 public/editormd/tests/qunit/qunit-1.16.0.js create mode 100644 src/images/warn/pic_403.jpg create mode 100644 src/images/warn/pic_404.jpg create mode 100644 src/images/warn/pic_500.jpg create mode 100644 src/images/warn/update.jpeg diff --git a/public/editormd/.jshintrc b/public/editormd/.jshintrc new file mode 100644 index 0000000..d689d8f --- /dev/null +++ b/public/editormd/.jshintrc @@ -0,0 +1,20 @@ +{ + "esnext": true, + "bitwise": true, + "camelcase": true, + "curly": true, + "eqeqeq": true, + "immed": true, + "indent": 4, + "latedef": true, + "newcap": true, + "noarg": true, + "quotmark": "double", + "regexp": true, + "undef": true, + "unused": true, + "strict": true, + "trailing": true, + "smarttabs": true, + "white": true +} \ No newline at end of file diff --git a/public/editormd/BUGS.md b/public/editormd/BUGS.md new file mode 100644 index 0000000..f16f9ad --- /dev/null +++ b/public/editormd/BUGS.md @@ -0,0 +1,22 @@ +#Bugs + +> 说明:删除线表示已经解决。 + +####IE8 + +- ~~不能加载;~~ +- flowChart(流程图)、sequenceDiagram(序列图)不支持IE8; +- ~~不支持Markdown转HTML页面解析预览;~~ + +####IE8 & IE9 & IE10 + +- KaTeX会出现解析错误,但不影响程序运行; + +####Sea.js + +- ~~Raphael.js无法加载;~~ + +####Require.js + +- ~~CodeMirror编辑器的代码无法高亮;~~ +- ~~sequenceDiagram不支持: `Uncaught TypeError: Cannot call method 'isArray' of undefined.`~~ diff --git a/public/editormd/CHANGE.md b/public/editormd/CHANGE.md new file mode 100644 index 0000000..5198137 --- /dev/null +++ b/public/editormd/CHANGE.md @@ -0,0 +1,534 @@ +## 更新日志 + +### v1.0.x + +##### v1.0.0 beta + +预览版:基本功能完成; + +##### v1.0.0 releases + +发布 v1.0.0 正式版。 + +主要更新: + +- 新建分支 `mathjax-version`,但不打算继续对此分支进行开发; + +- 移除 MathJax,改用 KaTeX [#2](https://github.com/pandao/editor.md/issues/2),解析和预览响应速度大幅度提高 [#3](https://github.com/pandao/editor.md/issues/3); + - 移除 `mathjax` 配置项; + - 移除 `mathjaxURL` 属性; + - 移除 `setMathJaxConfig()` 方法; + - 移除 `loadMathJax()` 方法; + - 移除MathJax的所有示例; + - 新增 `tex` 配置项,表示是否开启支持科学公式 TeX ,基于 KaTeX; + - 新增 `katexURL` 属性; + - 新增 `loadKaTeX` 方法; + - 新增 KaTeX 的示例; + +- `setCodeEditor()` 方法更名为 `setCodeMirror()`; + +- 合并 CodeMirror 使用到的多个 JS 模块文件,大幅减少 HTTP 请求,加快下载速度; + - 新增合并后的两个模块文件:`./lib/codemirror/modes.min.js`、`./lib/codemirror/addons.min.js` ; + - `Gulpfile.js` 新增合并 CodeMirror 模块文件的任务方法 `codemirror-mode` 和 `codemirror-addon` ; + - 另外在使用 Require.js 时,因为 CodeMirror 的严格模块依赖的限制,不能使用上述合并的模块文件,仍然采用动态加载多个模块文件; + +- 更新 `README.md` 等相关文档和示例; + +- 解决 Sea.js 环境下 Raphael.js 无法运行导致不支持流程图和时序图的问题,即必须先加载 Raphael.js ,后加载 Sea.js ; + +### v1.1.x + +##### v1.1.0 + +主要更新: + +- 设计并更换了 Logo; +- 新增添加图片、链接、锚点链接、代码块、预格式文本等操作弹出对话框层及示例; +- 新增支持图片(跨域)上传; +- 改用 ` + +``` + +> 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; + +})); diff --git a/public/editormd/editormd.amd.min.js b/public/editormd/editormd.amd.min.js new file mode 100644 index 0000000..2301369 --- /dev/null +++ b/public/editormd/editormd.amd.min.js @@ -0,0 +1,4 @@ +/*! Editor.md v1.5.0 | editormd.amd.min.js | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ +!function(e){"use strict";if("function"==typeof require&&"object"==typeof exports&&"object"==typeof module)module.exports=e;else if("function"==typeof define)if(define.amd){var t="codemirror/mode/",i="codemirror/addon/",o=["jquery","marked","prettify","katex","raphael","underscore","flowchart","jqueryflowchart","sequenceDiagram","codemirror/lib/codemirror",t+"css/css",t+"sass/sass",t+"shell/shell",t+"sql/sql",t+"clike/clike",t+"php/php",t+"xml/xml",t+"markdown/markdown",t+"javascript/javascript",t+"htmlmixed/htmlmixed",t+"gfm/gfm",t+"http/http",t+"go/go",t+"dart/dart",t+"coffeescript/coffeescript",t+"nginx/nginx",t+"python/python",t+"perl/perl",t+"lua/lua",t+"r/r",t+"ruby/ruby",t+"rst/rst",t+"smartymixed/smartymixed",t+"vb/vb",t+"vbscript/vbscript",t+"velocity/velocity",t+"xquery/xquery",t+"yaml/yaml",t+"erlang/erlang",t+"jade/jade",i+"edit/trailingspace",i+"dialog/dialog",i+"search/searchcursor",i+"search/search",i+"scroll/annotatescrollbar",i+"search/matchesonscrollbar",i+"display/placeholder",i+"edit/closetag",i+"fold/foldcode",i+"fold/foldgutter",i+"fold/indent-fold",i+"fold/brace-fold",i+"fold/xml-fold",i+"fold/markdown-fold",i+"fold/comment-fold",i+"mode/overlay",i+"selection/active-line",i+"edit/closebrackets",i+"display/fullscreen",i+"search/match-highlighter"];define(o,e)}else define(["jquery"],e);else window.editormd=e()}(function(){"function"==typeof define&&define.amd&&(e=arguments[0],marked=arguments[1],prettify=arguments[2],katex=arguments[3],Raphael=arguments[4],_=arguments[5],flowchart=arguments[6],CodeMirror=arguments[9]);var e="undefined"!=typeof jQuery?jQuery:Zepto;if("undefined"!=typeof e){var t=function(e,i){return new t.fn.init(e,i)};t.title=t.$name="Editor.md",t.version="1.5.0",t.homePage="https://pandao.github.io/editor.md/",t.classPrefix="editormd-",t.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"]},t.defaults={mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:"",appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",delay:300,autoLoadModules:!0,watch:!0,placeholder:"Enjoy Markdown! coding now...",gotoLine:!0,codeFold:!1,autoHeight:!1,autoFocus:!0,autoCloseTags:!0,searchReplace:!0,syncScrolling:!0,readOnly:!1,tabSize:4,indentUnit:4,lineNumbers:!0,lineWrapping:!0,autoCloseBrackets:!0,showTrailingSpace:!0,matchBrackets:!0,indentWithTabs:!0,styleSelectedText:!0,matchWordHighlight:!0,styleActiveLine:!0,dialogLockScreen:!0,dialogShowMask:!0,dialogDraggable:!0,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:!1,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:!1,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:!1,uploadCallbackURL:"",toc:!0,tocm:!1,tocTitle:"",tocDropdown:!1,tocContainer:"",tocStartLevel:1,htmlDecode:!1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0,toolbar:!0,toolbarAutoFixed:!0,toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return t.toolbarHandlers.ucwords},lowercase:function(){return t.toolbarHandlers.lowercase}},toolbarCustomIcons:{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:t.classPrefix+"bold",h2:t.classPrefix+"bold",h3:t.classPrefix+"bold",h4:t.classPrefix+"bold",h5:t.classPrefix+"bold",h6:t.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",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:"关于"+t.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:"使用帮助"}}}},t.classNames={tex:t.classPrefix+"tex"},t.dialogZindex=99999,t.$katex=null,t.$marked=null,t.$CodeMirror=null,t.$prettyPrint=null;var i,o;t.prototype=t.fn={state:{watching:!1,loaded:!1,preview:!1,fullscreen:!1},init:function(i,o){o=o||{},"object"==typeof i&&(o=i);var r=this.classPrefix=t.classPrefix,n=this.settings=e.extend(!0,t.defaults,o);i="object"==typeof i?n.id:i;var a=this.editor=e("#"+i);this.id=i,this.lang=n.lang;var s=this.classNames={textarea:{html:r+"html-textarea",markdown:r+"markdown-textarea"}};n.pluginPath=""===n.pluginPath?n.path+"../plugins/":n.pluginPath,this.state.watching=n.watch?!0:!1,a.hasClass("editormd")||a.addClass("editormd"),a.css({width:"number"==typeof n.width?n.width+"px":n.width,height:"number"==typeof n.height?n.height+"px":n.height}),n.autoHeight&&a.css("height","auto");var l=this.markdownTextarea=a.children("textarea");l.length<1&&(a.append(""),l=this.markdownTextarea=a.children("textarea")),l.addClass(s.textarea.markdown).attr("placeholder",n.placeholder),("undefined"==typeof l.attr("name")||""===l.attr("name"))&&l.attr("name",""!==n.name?n.name:i+"-markdown-doc");var c=[n.readOnly?"":'',n.saveHTMLToTextarea?'':"",'
        ','
        ','
        '].join("\n");return a.append(c).addClass(r+"vertical"),""!==n.theme&&a.addClass(r+"theme-"+n.theme),this.mask=a.children("."+r+"mask"),this.containerMask=a.children("."+r+"container-mask"),""!==n.markdown&&l.val(n.markdown),""!==n.appendMarkdown&&l.val(l.val()+n.appendMarkdown),this.htmlTextarea=a.children("."+s.textarea.html),this.preview=a.children("."+r+"preview"),this.previewContainer=this.preview.children("."+r+"preview-container"),""!==n.previewTheme&&this.preview.addClass(r+"preview-theme-"+n.previewTheme),"function"==typeof define&&define.amd&&("undefined"!=typeof katex&&(t.$katex=katex),n.searchReplace&&!n.readOnly&&(t.loadCSS(n.path+"codemirror/addon/dialog/dialog"),t.loadCSS(n.path+"codemirror/addon/search/matchesonscrollbar"))),"function"==typeof define&&define.amd||!n.autoLoadModules?("undefined"!=typeof CodeMirror&&(t.$CodeMirror=CodeMirror),"undefined"!=typeof marked&&(t.$marked=marked),this.setCodeMirror().setToolbar().loadedDisplay()):this.loadQueues(),this},loadQueues:function(){var e=this,i=this.settings,o=i.path,r=function(){return t.isIE8?void e.loadedDisplay():void(i.flowChart||i.sequenceDiagram?t.loadScript(o+"raphael.min",function(){t.loadScript(o+"underscore.min",function(){!i.flowChart&&i.sequenceDiagram?t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()}):i.flowChart&&!i.sequenceDiagram?t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){e.loadedDisplay()})}):i.flowChart&&i.sequenceDiagram&&t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()})})})})}):e.loadedDisplay())};return t.loadCSS(o+"codemirror/codemirror.min"),i.searchReplace&&!i.readOnly&&(t.loadCSS(o+"codemirror/addon/dialog/dialog"),t.loadCSS(o+"codemirror/addon/search/matchesonscrollbar")),i.codeFold&&t.loadCSS(o+"codemirror/addon/fold/foldgutter"),t.loadScript(o+"codemirror/codemirror.min",function(){t.$CodeMirror=CodeMirror,t.loadScript(o+"codemirror/modes.min",function(){t.loadScript(o+"codemirror/addons.min",function(){return e.setCodeMirror(),"gfm"!==i.mode&&"markdown"!==i.mode?(e.loadedDisplay(),!1):(e.setToolbar(),void t.loadScript(o+"marked.min",function(){t.$marked=marked,i.previewCodeHighlight?t.loadScript(o+"prettify.min",function(){r()}):r()}))})})}),this},setTheme:function(e){var t=this.editor,i=this.settings.theme,o=this.classPrefix+"theme-";return t.removeClass(o+i).addClass(o+e),this.settings.theme=e,this},setEditorTheme:function(e){var i=this.settings;return i.editorTheme=e,"default"!==e&&t.loadCSS(i.path+"codemirror/theme/"+i.editorTheme),this.cm.setOption("theme",e),this},setCodeMirrorTheme:function(e){return this.setEditorTheme(e),this},setPreviewTheme:function(e){var t=this.preview,i=this.settings.previewTheme,o=this.classPrefix+"preview-theme-";return t.removeClass(o+i).addClass(o+e),this.settings.previewTheme=e,this},setCodeMirror:function(){var e=this.settings,i=this.editor;"default"!==e.editorTheme&&t.loadCSS(e.path+"codemirror/theme/"+e.editorTheme);var o={mode:e.mode,theme:e.editorTheme,tabSize:e.tabSize,dragDrop:!1,autofocus:e.autoFocus,autoCloseTags:e.autoCloseTags,readOnly:e.readOnly?"nocursor":!1,indentUnit:e.indentUnit,lineNumbers:e.lineNumbers,lineWrapping:e.lineWrapping,extraKeys:{"Ctrl-Q":function(e){e.foldCode(e.getCursor())}},foldGutter:e.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:e.matchBrackets,indentWithTabs:e.indentWithTabs,styleActiveLine:e.styleActiveLine,styleSelectedText:e.styleSelectedText,autoCloseBrackets:e.autoCloseBrackets,showTrailingSpace:e.showTrailingSpace,highlightSelectionMatches:e.matchWordHighlight?{showToken:"onselected"===e.matchWordHighlight?!1:/\w/}:!1};return this.codeEditor=this.cm=t.$CodeMirror.fromTextArea(this.markdownTextarea[0],o),this.codeMirror=this.cmElement=i.children(".CodeMirror"),""!==e.value&&this.cm.setValue(e.value),this.codeMirror.css({fontSize:e.fontSize,width:e.watch?"50%":"100%"}),e.autoHeight&&(this.codeMirror.css("height","auto"),this.cm.setOption("viewportMargin",1/0)),e.lineNumbers||this.codeMirror.find(".CodeMirror-gutters").css("border-right","none"),this},getCodeMirrorOption:function(e){return this.cm.getOption(e)},setCodeMirrorOption:function(e,t){return this.cm.setOption(e,t),this},addKeyMap:function(e,t){return this.cm.addKeyMap(e,t),this},removeKeyMap:function(e){return this.cm.removeKeyMap(e),this},gotoLine:function(t){var i=this.settings;if(!i.gotoLine)return this;var o=this.cm,r=(this.editor,o.lineCount()),n=this.preview;if("string"==typeof t&&("last"===t&&(t=r),"first"===t&&(t=1)),"number"!=typeof t)return alert("Error: The line number must be an integer."),this;if(t=parseInt(t)-1,t>r)return alert("Error: The line number range 1-"+r),this;o.setCursor({line:t,ch:0});var a=o.getScrollInfo(),s=a.clientHeight,l=o.charCoords({line:t,ch:0},"local");if(o.scrollTo(null,(l.top+l.bottom-s)/2),i.watch){var c=this.codeMirror.find(".CodeMirror-scroll")[0],h=e(c).height(),d=c.scrollTop,u=d/c.scrollHeight;n.scrollTop(0===d?0:d+h>=c.scrollHeight-16?n[0].scrollHeight:n[0].scrollHeight*u)}return o.focus(),this},extend:function(){return"undefined"!=typeof arguments[1]&&("function"==typeof arguments[1]&&(arguments[1]=e.proxy(arguments[1],this)),this[arguments[0]]=arguments[1]),"object"==typeof arguments[0]&&"undefined"==typeof arguments[0].length&&e.extend(!0,this,arguments[0]),this},set:function(t,i){return"undefined"!=typeof i&&"function"==typeof i&&(i=e.proxy(i,this)),this[t]=i,this},config:function(t,i){var o=this.settings;return"object"==typeof t&&(o=e.extend(!0,o,t)),"string"==typeof t&&(o[t]=i),this.settings=o,this.recreate(),this},on:function(t,i){var o=this.settings;return"undefined"!=typeof o["on"+t]&&(o["on"+t]=e.proxy(i,this)),this},off:function(e){var t=this.settings;return"undefined"!=typeof t["on"+e]&&(t["on"+e]=function(){}),this},showToolbar:function(t){var i=this.settings;return i.readOnly?this:(i.toolbar&&(this.toolbar.length<1||""===this.toolbar.find("."+this.classPrefix+"menu").html())&&this.setToolbar(),i.toolbar=!0,this.toolbar.show(),this.resize(),e.proxy(t||function(){},this)(),this)},hideToolbar:function(t){var i=this.settings;return i.toolbar=!1,this.toolbar.hide(),this.resize(),e.proxy(t||function(){},this)(),this},setToolbarAutoFixed:function(t){var i=this.state,o=this.editor,r=this.toolbar,n=this.settings;"undefined"!=typeof t&&(n.toolbarAutoFixed=t);var a=function(){var t=e(window),i=t.scrollTop();return n.toolbarAutoFixed?void r.css(i-o.offset().top>10&&i
          ';i.append(n),r=this.toolbar=i.children("."+o+"toolbar")}if(!e.toolbar)return r.hide(),this;r.show();for(var a="function"==typeof e.toolbarIcons?e.toolbarIcons():"string"==typeof e.toolbarIcons?t.toolbarModes[e.toolbarIcons]:e.toolbarIcons,s=r.find("."+this.classPrefix+"menu"),l="",c=!1,h=0,d=a.length;d>h;h++){var u=a[h];if("||"===u)c=!0;else if("|"===u)l+='
        • |
        • ';else{var f=/h(\d)/.test(u),g=u;"watch"!==u||e.watch||(g="unwatch");var p=e.lang.toolbar[g],m=e.toolbarIconTexts[g],w=e.toolbarIconsClass[g];p="undefined"==typeof p?"":p,m="undefined"==typeof m?"":m,w="undefined"==typeof w?"":w;var v=c?'
        • ':"
        • ";"undefined"!=typeof e.toolbarCustomIcons[u]&&"function"!=typeof e.toolbarCustomIcons[u]?v+=e.toolbarCustomIcons[u]:(v+='',v+=''+(f?u.toUpperCase():""===w?m:"")+"",v+=""),v+="
        • ",l=c?v+l:l+v}}return s.html(l),s.find('[title="Lowercase"]').attr("title",e.lang.toolbar.lowercase),s.find('[title="ucwords"]').attr("title",e.lang.toolbar.ucwords),this.setToolbarHandler(),this.setToolbarAutoFixed(),this},dialogLockScreen:function(){return e.proxy(t.dialogLockScreen,this)(),this},dialogShowMask:function(i){return e.proxy(t.dialogShowMask,this)(i),this},getToolbarHandles:function(e){var i=this.toolbarHandlers=t.toolbarHandlers;return e&&"undefined"!=typeof toolbarIconHandlers[e]?i[e]:i},setToolbarHandler:function(){var i=this,o=this.settings;if(!o.toolbar||o.readOnly)return this;var r=this.toolbar,n=this.cm,a=this.classPrefix,s=this.toolbarIcons=r.find("."+a+"menu > li > a"),l=this.getToolbarHandles();return s.bind(t.mouseOrTouch("click","touchend"),function(t){var r=e(this).children(".fa"),a=r.attr("name"),s=n.getCursor(),c=n.getSelection();return""!==a?(i.activeIcon=r,"undefined"!=typeof l[a]?e.proxy(l[a],i)(n):"undefined"!=typeof o.toolbarHandlers[a]&&e.proxy(o.toolbarHandlers[a],i)(n,r,s,c),"link"!==a&&"reference-link"!==a&&"image"!==a&&"code-block"!==a&&"preformatted-text"!==a&&"watch"!==a&&"preview"!==a&&"search"!==a&&"fullscreen"!==a&&"info"!==a&&n.focus(),!1):void 0}),this},createDialog:function(i){return e.proxy(t.createDialog,this)(i)},createInfoDialog:function(){var e=this,i=this.editor,o=this.classPrefix,r=['
          ','
          ','

          '+t.title+"v"+t.version+"

          ","

          "+this.lang.description+"

          ",'

          '+t.homePage+'

          ','

          Copyright © 2015 Pandao, The MIT License.

          ',"
          ",'',"
          "].join("\n");i.append(r);var n=this.infoDialog=i.children("."+o+"dialog-info");return n.find("."+o+"dialog-close").bind(t.mouseOrTouch("click","touchend"),function(){e.hideInfoDialog()}),n.css("border",t.isIE8?"1px solid #ddd":"").css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},infoDialogPosition:function(){var t=this.infoDialog,i=function(){t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"})};return i(),e(window).resize(i),this},showInfoDialog:function(){e("html,body").css("overflow-x","hidden");var i=this.editor,o=this.settings,r=this.infoDialog=i.children("."+this.classPrefix+"dialog-info");return r.length<1&&this.createInfoDialog(),this.lockScreen(!0),this.mask.css({opacity:o.dialogMaskOpacity,backgroundColor:o.dialogMaskBgColor}).show(),r.css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},hideInfoDialog:function(){return e("html,body").css("overflow-x",""),this.infoDialog.hide(),this.mask.hide(),this.lockScreen(!1),this},lockScreen:function(e){return t.lockScreen(e),this.resize(),this},recreate:function(){var e=this.editor,t=this.settings;return this.codeMirror.remove(),this.setCodeMirror(),t.readOnly||(e.find(".editormd-dialog").length>0&&e.find(".editormd-dialog").remove(),t.toolbar&&(this.getToolbarHandles(),this.setToolbar())),this.loadedDisplay(!0),this},previewCodeHighlight:function(){var e=this.settings,t=this.previewContainer;return e.previewCodeHighlight&&(t.find("pre").addClass("prettyprint linenums"),"undefined"!=typeof prettyPrint&&prettyPrint()),this},katexRender:function(){return null===i?this:(this.previewContainer.find("."+t.classNames.tex).each(function(){var i=e(this);t.$katex.render(i.text(),i[0]),i.find(".katex").css("font-size","1.6em")}),this)},flowChartAndSequenceDiagramRender:function(){var i=this,r=this.settings,n=this.previewContainer;if(t.isIE8)return this;if(r.flowChart){if(null===o)return this;n.find(".flowchart").flowChart()}r.sequenceDiagram&&n.find(".sequence-diagram").sequenceDiagram({theme:"simple"});var a=i.preview,s=i.codeMirror,l=s.find(".CodeMirror-scroll"),c=l.height(),h=l.scrollTop(),d=h/l[0].scrollHeight,u=0;a.find(".markdown-toc-list").each(function(){u+=e(this).height()});var f=a.find(".editormd-toc-menu").height();return f=f?f:0,a.scrollTop(0===h?0:h+c>=l[0].scrollHeight-16?a[0].scrollHeight:(a[0].scrollHeight+u+f)*d),this},registerKeyMaps:function(i){var o=this,r=this.cm,n=this.settings,a=t.toolbarHandlers,s=n.disabledKeyMaps;if(i=i||null){for(var l in i)if(e.inArray(l,s)<0){var c={};c[l]=i[l],r.addKeyMap(i)}}else{for(var h in t.keyMaps){var d=t.keyMaps[h],u="string"==typeof d?e.proxy(a[d],o):e.proxy(d,o);if(e.inArray(h,["F9","F10","F11"])<0&&e.inArray(h,s)<0){var f={};f[h]=u,r.addKeyMap(f)}}e(window).keydown(function(t){var i={120:"F9",121:"F10",122:"F11"};if(e.inArray(i[t.keyCode],s)<0)switch(t.keyCode){case 120:return e.proxy(a.watch,o)(),!1;case 121:return e.proxy(a.preview,o)(),!1;case 122:return e.proxy(a.fullscreen,o)(),!1}})}return this},bindScrollEvent:function(){var i=this,o=this.preview,r=this.settings,n=this.codeMirror,a=t.mouseOrTouch;if(!r.syncScrolling)return this;var s=function(){n.find(".CodeMirror-scroll").bind(a("scroll","touchmove"),function(t){var n=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=0;o.find(".markdown-toc-list").each(function(){l+=e(this).height()});var c=o.find(".editormd-toc-menu").height();c=c?c:0,o.scrollTop(0===a?0:a+n>=e(this)[0].scrollHeight-16?o[0].scrollHeight:(o[0].scrollHeight+l+c)*s),e.proxy(r.onscroll,i)(t)})},l=function(){n.find(".CodeMirror-scroll").unbind(a("scroll","touchmove"))},c=function(){o.bind(a("scroll","touchmove"),function(t){var o=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=n.find(".CodeMirror-scroll");l.scrollTop(0===a?0:a+o>=e(this)[0].scrollHeight?l[0].scrollHeight:l[0].scrollHeight*s),e.proxy(r.onpreviewscroll,i)(t)})},h=function(){o.unbind(a("scroll","touchmove"))};return n.bind({mouseover:s,mouseout:l,touchstart:s,touchend:l}),"single"===r.syncScrolling?this:(o.bind({mouseover:c,mouseout:h,touchstart:c,touchend:h}),this)},bindChangeEvent:function(){var e=this,t=this.cm,o=this.settings;return o.syncScrolling?(t.on("change",function(t,r){o.watch&&e.previewContainer.css("padding",o.autoHeight?"20px 20px 50px 40px":"20px"),i=setTimeout(function(){clearTimeout(i),e.save(),i=null},o.delay)}),this):this},loadedDisplay:function(t){t=t||!1;var i=this,o=this.editor,r=this.preview,n=this.settings;return this.containerMask.hide(),this.save(),n.watch&&r.show(),o.data("oldWidth",o.width()).data("oldHeight",o.height()),this.resize(),this.registerKeyMaps(),e(window).resize(function(){i.resize()}),this.bindScrollEvent().bindChangeEvent(),t||e.proxy(n.onload,this)(),this.state.loaded=!0,this},width:function(e){return this.editor.css("width","number"==typeof e?e+"px":e),this.resize(),this},height:function(e){return this.editor.css("height","number"==typeof e?e+"px":e),this.resize(),this},resize:function(t,i){t=t||null,i=i||null;var o=this.state,r=this.editor,n=this.preview,a=this.toolbar,s=this.settings,l=this.codeMirror;if(t&&r.css("width","number"==typeof t?t+"px":t),!s.autoHeight||o.fullscreen||o.preview?(i&&r.css("height","number"==typeof i?i+"px":i),o.fullscreen&&r.height(e(window).height()),s.toolbar&&!s.readOnly?l.css("margin-top",a.height()+1).height(r.height()-a.height()):l.css("margin-top",0).height(r.height())):(r.css("height","auto"),l.css("height","auto")),s.watch)if(l.width(r.width()/2),n.width(o.preview?r.width():r.width()/2),this.previewContainer.css("padding",s.autoHeight?"20px 20px 50px 40px":"20px"),s.toolbar&&!s.readOnly?n.css("top",a.height()+1):n.css("top",0),!s.autoHeight||o.fullscreen||o.preview){var c=s.toolbar&&!s.readOnly?r.height()-a.height():r.height();n.height(c)}else n.height("");else l.width(r.width()),n.hide();return o.loaded&&e.proxy(s.onresize,this)(),this},save:function(){if(null===i)return this;var r=this,n=this.state,a=this.settings,s=this.cm,l=s.getValue(),c=this.previewContainer;if("gfm"!==a.mode&&"markdown"!==a.mode)return this.markdownTextarea.val(l),this;var h=t.$marked,d=this.markdownToC=[],u=this.markedRendererOptions={toc:a.toc,tocm:a.tocm,tocStartLevel:a.tocStartLevel,pageBreak:a.pageBreak,taskList:a.taskList,emoji:a.emoji,tex:a.tex,atLink:a.atLink,emailLink:a.emailLink,flowChart:a.flowChart,sequenceDiagram:a.sequenceDiagram,previewCodeHighlight:a.previewCodeHighlight},f=this.markedOptions={renderer:t.markedRenderer(d,u),gfm:!0,tables:!0,breaks:!0,pedantic:!1,sanitize:a.htmlDecode?!1:!0,smartLists:!0,smartypants:!0};h.setOptions(f);var g=t.$marked(l,f);if(g=t.filterHTMLTags(g,a.htmlDecode),this.markdownTextarea.text(l),s.save(),a.saveHTMLToTextarea&&this.htmlTextarea.text(g),a.watch||!a.watch&&n.preview){if(c.html(g),this.previewCodeHighlight(),a.toc){var p=""===a.tocContainer?c:e(a.tocContainer),m=p.find("."+this.classPrefix+"toc-menu");p.attr("previewContainer",""===a.tocContainer?"true":"false"),""!==a.tocContainer&&m.length>0&&m.remove(),t.markdownToCRenderer(d,p,a.tocDropdown,a.tocStartLevel),(a.tocDropdown||p.find("."+this.classPrefix+"toc-menu").length>0)&&t.tocDropdownMenu(p,""!==a.tocTitle?a.tocTitle:this.lang.tocTitle),""!==a.tocContainer&&c.find(".markdown-toc").css("border","none")}a.tex&&(!t.kaTeXLoaded&&a.autoLoadModules?t.loadKaTeX(function(){t.$katex=katex,t.kaTeXLoaded=!0,r.katexRender()}):(t.$katex=katex,this.katexRender())),(a.flowChart||a.sequenceDiagram)&&(o=setTimeout(function(){clearTimeout(o),r.flowChartAndSequenceDiagramRender(),o=null},10)),n.loaded&&e.proxy(a.onchange,this)()}return this},focus:function(){return this.cm.focus(),this},setCursor:function(e){return this.cm.setCursor(e),this},getCursor:function(){return this.cm.getCursor()},setSelection:function(e,t){return this.cm.setSelection(e,t),this},getSelection:function(){return this.cm.getSelection()},setSelections:function(e){return this.cm.setSelections(e),this},getSelections:function(){return this.cm.getSelections()},replaceSelection:function(e){return this.cm.replaceSelection(e),this},insertValue:function(e){return this.replaceSelection(e),this},appendMarkdown:function(e){var t=(this.settings,this.cm);return t.setValue(t.getValue()+e),this},setMarkdown:function(e){return this.cm.setValue(e||this.settings.markdown),this},getMarkdown:function(){return this.cm.getValue()},getValue:function(){return this.cm.getValue()},setValue:function(e){return this.cm.setValue(e),this},clear:function(){return this.cm.setValue(""),this},getHTML:function(){return this.settings.saveHTMLToTextarea?this.htmlTextarea.val():(alert("Error: settings.saveHTMLToTextarea == false"),!1)},getTextareaSavedHTML:function(){return this.getHTML()},getPreviewedHTML:function(){return this.settings.watch?this.previewContainer.html():(alert("Error: settings.watch == false"),!1)},watch:function(t){var o=this.settings;if(e.inArray(o.mode,["gfm","markdown"])<0)return this;if(this.state.watching=o.watch=!0,this.preview.show(),this.toolbar){var r=o.toolbarIconsClass.watch,n=o.toolbarIconsClass.unwatch,a=this.toolbar.find(".fa[name=watch]");a.parent().attr("title",o.lang.toolbar.watch),a.removeClass(n).addClass(r)}return this.codeMirror.css("border-right","1px solid #ddd").width(this.editor.width()/2),i=0,this.save().resize(),o.onwatch||(o.onwatch=t||function(){}),e.proxy(o.onwatch,this)(),this},unwatch:function(t){var i=this.settings;if(this.state.watching=i.watch=!1,this.preview.hide(),this.toolbar){var o=i.toolbarIconsClass.watch,r=i.toolbarIconsClass.unwatch,n=this.toolbar.find(".fa[name=watch]");n.parent().attr("title",i.lang.toolbar.unwatch),n.removeClass(o).addClass(r)}return this.codeMirror.css("border-right","none").width(this.editor.width()),this.resize(),i.onunwatch||(i.onunwatch=t||function(){}),e.proxy(i.onunwatch,this)(),this},show:function(t){t=t||function(){};var i=this;return this.editor.show(0,function(){e.proxy(t,i)()}),this},hide:function(t){t=t||function(){};var i=this;return this.editor.hide(0,function(){e.proxy(t,i)()}),this},previewing:function(){var i=this,o=this.editor,r=this.preview,n=this.toolbar,a=this.settings,s=this.codeMirror,l=this.previewContainer;if(e.inArray(a.mode,["gfm","markdown"])<0)return this;a.toolbar&&n&&(n.toggle(),n.find(".fa[name=preview]").toggleClass("active")),s.toggle();var c=function(e){e.shiftKey&&27===e.keyCode&&i.previewed()};"none"===s.css("display")?(this.state.preview=!0,this.state.fullscreen&&r.css("background","#fff"),o.find("."+this.classPrefix+"preview-close-btn").show().bind(t.mouseOrTouch("click","touchend"),function(){i.previewed()}),a.watch?l.css("padding",""):this.save(),l.addClass(this.classPrefix+"preview-active"),r.show().css({position:"",top:0,width:o.width(),height:a.autoHeight&&!this.state.fullscreen?"auto":o.height()}),this.state.loaded&&e.proxy(a.onpreviewing,this)(),e(window).bind("keyup",c)):(e(window).unbind("keyup",c),this.previewed())},previewed:function(){var i=this.editor,o=this.preview,r=this.toolbar,n=this.settings,a=this.previewContainer,s=i.find("."+this.classPrefix+"preview-close-btn");return this.state.preview=!1,this.codeMirror.show(),n.toolbar&&r.show(),o[n.watch?"show":"hide"](),s.hide().unbind(t.mouseOrTouch("click","touchend")),a.removeClass(this.classPrefix+"preview-active"),n.watch&&a.css("padding","20px"),o.css({background:null,position:"absolute",width:i.width()/2,height:n.autoHeight&&!this.state.fullscreen?"auto":i.height()-r.height(),top:n.toolbar?r.height():0}),this.state.loaded&&e.proxy(n.onpreviewed,this)(),this},fullscreen:function(){var t=this,i=this.state,o=this.editor,r=(this.preview,this.toolbar),n=this.settings,a=this.classPrefix+"fullscreen";r&&r.find(".fa[name=fullscreen]").parent().toggleClass("active");var s=function(e){e.shiftKey||27!==e.keyCode||i.fullscreen&&t.fullscreenExit()};return o.hasClass(a)?(e(window).unbind("keyup",s),this.fullscreenExit()):(i.fullscreen=!0,e("html,body").css("overflow","hidden"),o.css({width:e(window).width(),height:e(window).height()}).addClass(a),this.resize(),e.proxy(n.onfullscreen,this)(),e(window).bind("keyup",s)),this},fullscreenExit:function(){var t=this.editor,i=this.settings,o=this.toolbar,r=this.classPrefix+"fullscreen";return this.state.fullscreen=!1,o&&o.find(".fa[name=fullscreen]").parent().removeClass("active"),e("html,body").css("overflow",""),t.css({width:t.data("oldWidth"),height:t.data("oldHeight")}).removeClass(r),this.resize(),e.proxy(i.onfullscreenExit,this)(),this},executePlugin:function(i,o){var r=this,n=this.cm,a=this.settings;return o=a.pluginPath+o,"function"==typeof define?"undefined"==typeof this[i]?(alert("Error: "+i+" plugin is not found, you are not load this plugin."),this):(this[i](n),this):(e.inArray(o,t.loadFiles.plugin)<0?t.loadPlugin(o,function(){t.loadPlugins[i]=r[i],r[i](n)}):e.proxy(t.loadPlugins[i],this)(n),this)},search:function(e){var t=this.settings;return t.searchReplace?(t.readOnly||this.cm.execCommand(e||"find"),this):(alert("Error: settings.searchReplace == false"),this)},searchReplace:function(){return this.search("replace"),this},searchReplaceAll:function(){return this.search("replaceAll"),this}},t.fn.init.prototype=t.fn,t.dialogLockScreen=function(){var t=this.settings||{dialogLockScreen:!0};t.dialogLockScreen&&(e("html,body").css("overflow","hidden"),this.resize())},t.dialogShowMask=function(t){var i=this.editor,o=this.settings||{dialogShowMask:!0};t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"}),o.dialogShowMask&&i.children("."+this.classPrefix+"mask").css("z-index",parseInt(t.css("z-index"))-1).show()},t.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(); + +e.replaceSelection("**"+i+"**"),""===i&&e.setCursor(t.line,t.ch+2)},del:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("~~"+i+"~~"),""===i&&e.setCursor(t.line,t.ch+2)},italic:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("*"+i+"*"),""===i&&e.setCursor(t.line,t.ch+1)},quote:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("> "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("> "+i)},ucfirst:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.firstUpperCase(i)),e.setSelections(o)},ucwords:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.wordsFirstUpperCase(i)),e.setSelections(o)},uppercase:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(t.toUpperCase()),e.setSelections(i)},lowercase:function(){var e=this.cm,t=(e.getCursor(),e.getSelection()),i=e.listSelections();e.replaceSelection(t.toLowerCase()),e.setSelections(i)},h1:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("# "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("# "+i)},h2:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("## "+i),e.setCursor(t.line,t.ch+3)):e.replaceSelection("## "+i)},h3:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("### "+i),e.setCursor(t.line,t.ch+4)):e.replaceSelection("### "+i)},h4:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("#### "+i),e.setCursor(t.line,t.ch+5)):e.replaceSelection("#### "+i)},h5:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("##### "+i),e.setCursor(t.line,t.ch+6)):e.replaceSelection("##### "+i)},h6:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("###### "+i),e.setCursor(t.line,t.ch+7)):e.replaceSelection("###### "+i)},"list-ul":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("- "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":"- "+i[o];e.replaceSelection(i.join("\n"))}},"list-ol":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("1. "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":o+1+". "+i[o];e.replaceSelection(i.join("\n"))}},hr:function(){{var e=this.cm,t=e.getCursor();e.getSelection()}e.replaceSelection((0!==t.ch?"\n\n":"\n")+"------------\n\n")},tex:function(){if(!this.settings.tex)return alert("settings.tex === false"),this;var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("$$"+i+"$$"),""===i&&e.setCursor(t.line,t.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)return alert("settings.pageBreak === false"),this;{var e=this.cm;e.getSelection()}e.replaceSelection("\r\n[========]\r\n")},image:function(){this.executePlugin("imageDialog","image-dialog/image-dialog")},code:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("`"+i+"`"),""===i&&e.setCursor(t.line,t.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 e=this.cm,i=(e.getSelection(),new Date,this.settings.lang.name),o=t.dateFormat()+" "+t.dateFormat("zh-cn"===i||"zh-tw"===i?"cn-week-day":"week-day");e.replaceSelection(o)},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()}},t.keyMaps={"Ctrl-1":"h1","Ctrl-2":"h2","Ctrl-3":"h3","Ctrl-4":"h4","Ctrl-5":"h5","Ctrl-6":"h6","Ctrl-B":"bold","Ctrl-D":"datetime","Ctrl-E":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.emoji?(e.replaceSelection(":"+i+":"),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.emoji == false")},"Ctrl-Alt-G":"goto-line","Ctrl-H":"hr","Ctrl-I":"italic","Ctrl-K":"code","Ctrl-L":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.ch+1)},"Ctrl-U":"list-ul","Shift-Ctrl-A":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.atLink?(e.replaceSelection("@"+i),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.atLink == false")},"Shift-Ctrl-C":"code","Shift-Ctrl-Q":"quote","Shift-Ctrl-S":"del","Shift-Ctrl-K":"tex","Shift-Alt-C":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection(["```",i,"```"].join("\n")),""===i&&e.setCursor(t.line,t.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 e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("!["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.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"};var r=function(e){return String.prototype.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};t.trim=r;var n=function(e){return e.toLowerCase().replace(/\b(\w)|\s(\w)/g,function(e){return e.toUpperCase()})};t.ucwords=t.wordsFirstUpperCase=n;var a=function(e){return e.toLowerCase().replace(/\b(\w)/,function(e){return e.toUpperCase()})};return t.firstUpperCase=t.ucfirst=a,t.urls={atLinkBase:"https://github.com/"},t.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,}\]$/},t.emoji={path:"http://www.emoji-cheat-sheet.com/graphics/emojis/",ext:".png"},t.twemoji={path:"http://twemoji.maxcdn.com/36x36/",ext:".png"},t.markedRenderer=function(i,o){var n={toc:!0,tocm:!1,tocStartLevel:1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1},a=e.extend(n,o||{}),s=t.$marked,l=new s.Renderer;i=i||[];var c=t.regexs,h=c.atLink,d=c.emoji,u=c.email,f=c.emailLink,g=c.twemoji,p=c.fontAwesome,m=c.editormdLogo,w=c.pageBreak;return l.emoji=function(e){e=e.replace(t.regexs.emojiDatetime,function(e){return e.replace(/:/g,":")});var i=e.match(d);if(!i||!a.emoji)return e;for(var o=0,r=i.length;r>o;o++)":+1:"===i[o]&&(i[o]=":\\+1:"),e=e.replace(new RegExp(i[o]),function(e,i){var o=e.match(p),r=e.replace(/:/g,"");if(o)for(var n=0,a=o.length;a>n;n++){var s=o[n].replace(/:/g,"");return''}else{var l=e.match(m),c=e.match(g);if(l)for(var h=0,d=l.length;d>h;h++){var u=l[h].replace(/:/g,"");return''}else{if(!c){var f="+1"===r?"plus1":r;return f="black_large_square"===f?"black_square":f,f="moon"===f?"waxing_gibbous_moon":f,':'+r+':'}for(var w=0,v=c.length;v>w;w++){var k=c[w].replace(/:/g,"").replace("tw-","");return'twemoji-'+k+''}}}});return e},l.atLink=function(i){return h.test(i)?(a.atLink&&(i=i.replace(u,function(e,t,i,o){return e.replace(/@/g,"_#_@_#_")}),i=i.replace(h,function(e,i){return''+e+""}).replace(/_#_@_#_/g,"@")),a.emailLink&&(i=i.replace(f,function(t,i,o,r,n){return!i&&e.inArray(n,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+t+"":t})),i):i},l.link=function(e,t,i){if(this.options.sanitize){try{var o=decodeURIComponent(unescape(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(r){return""}if(0===o.indexOf("javascript:"))return""}var n=''+i.replace(/@/g,"@")+""):(t&&(n+=' title="'+t+'"'),n+=">"+i+"")},l.heading=function(e,t,o){var n=e,a=/\s*\]*)\>(.*)\<\/a\>\s*/;if(a.test(e)){var s=[];e=e.split(/\]+)\>([^\>]*)\<\/a\>/);for(var l=0,c=e.length;c>l;l++)s.push(e[l].replace(/\s*href\=\"(.*)\"\s*/g,""));e=s.join(" ")}e=r(e);var h=e.toLowerCase().replace(/[^\w]+/g,"-"),d={text:e,level:t,slug:h},u=/^[\u4e00-\u9fa5]+$/.test(e),f=u?escape(e).replace(/\%/g,""):e.toLowerCase().replace(/[^\w]+/g,"-");i.push(d);var g="';return g+='',g+='',g+=this.atLink(a?this.emoji(n):this.emoji(e)),g+=""},l.pageBreak=function(e){return w.test(e)&&a.pageBreak&&(e='
          '),e},l.paragraph=function(e){var i=/\$\$(.*)\$\$/g.test(e),o=/^\$\$(.*)\$\$$/.test(e),r=o?' class="'+t.classNames.tex+'"':"",n=a.tocm?/^(\[TOC\]|\[TOCM\])$/.test(e):/^\[TOC\]$/.test(e),s=/^\[TOCM\]$/.test(e);e=!o&&i?e.replace(/(\$\$([^\$]*)\$\$)+/g,function(e,i){return''+i.replace(/\$/g,"")+""}):o?e.replace(/\$/g,""):e;var l='
          '+e+"
          ";return n?s?'
          '+l+"

          ":l:w.test(e)?this.pageBreak(e):""+this.atLink(this.emoji(e))+"

          \n"},l.code=function(e,i,o){return"seq"===i||"sequence"===i?'
          '+e+"
          ":"flow"===i?'
          '+e+"
          ":"math"===i||"latex"===i||"katex"===i?'

          '+e+"

          ":s.Renderer.prototype.code.apply(this,arguments)},l.tablecell=function(e,t){var i=t.header?"th":"td",o=t.align?"<"+i+' style="text-align:'+t.align+'">':"<"+i+">";return o+this.atLink(this.emoji(e))+"\n"},l.listitem=function(e){return a.taskList&&/^\s*\[[x\s]\]\s*/.test(e)?(e=e.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' '),'
        • '+this.atLink(this.emoji(e))+"
        • "):"
        • "+this.atLink(this.emoji(e))+"
        • "},l},t.markdownToCRenderer=function(e,t,i,o){var r="",n=0,a=this.classPrefix;o=o||1;for(var s=0,l=e.length;l>s;s++){var c=e[s].text,h=e[s].level;o>h||(r+=h>n?"":n>h?new Array(n-h+2).join("
      • "):"",r+='
      • '+c+"
          ",n=h)}var d=t.find(".markdown-toc");if(d.length<1&&"false"===t.attr("previewContainer")){var u='
          ';u=i?'
          '+u+"
          ":u,t.html(u),d=t.find(".markdown-toc")}return i&&d.wrap('

          '),d.html('
            ').children(".markdown-toc-list").html(r.replace(/\r?\n?\\<\/ul\>/g,"")),d},t.tocDropdownMenu=function(t,i){i=i||"Table of Contents";var o=400,r=t.find("."+this.classPrefix+"toc-menu");return r.each(function(){var t=e(this),r=t.children(".markdown-toc"),n='',a=''+n+i+"",s=r.children("ul"),l=s.find("li");r.append(a),l.first().before("
          • "+i+" "+n+"

          • "),t.mouseover(function(){s.show(),l.each(function(){var t=e(this),i=t.children("ul");if(""===i.html()&&i.remove(),i.length>0&&""!==i.html()){var r=t.children("a").first();r.children(".fa").length<1&&r.append(e(n).css({"float":"right",paddingTop:"4px"}))}t.mouseover(function(){i.css("z-index",o).show(),o+=1}).mouseleave(function(){i.hide()})})}).mouseleave(function(){s.hide()})}),r},t.filterHTMLTags=function(t,i){if("string"!=typeof t&&(t=new String(t)),"string"!=typeof i)return t;for(var o=i.split("|"),r=o[0].split(","),n=o[1],a=0,s=r.length;s>a;a++){var l=r[a];t=t.replace(new RegExp("]*)>([^>]*)","igm"),"")}if("undefined"!=typeof n){var c=/\<(\w+)\s*([^\>]*)\>([^\>]*)\<\/(\w+)\>/gi;t="*"===n?t.replace(c,function(e,t,i,o,r){return"<"+t+">"+o+""}):"on*"===n?t.replace(c,function(t,i,o,r,n){var a=e("<"+i+">"+r+""),s=e(t)[0].attributes,l={};e.each(s,function(e,t){'"'!==t.nodeName&&(l[t.nodeName]=t.nodeValue)}),e.each(l,function(e){0===e.indexOf("on")&&delete l[e]}),a.attr(l);var c="undefined"!=typeof a[1]?e(a[1]).text():"";return a[0].outerHTML+c}):t.replace(c,function(t,i,o,r){var a=n.split(","),s=e(t);return s.html(r),e.each(a,function(e){s.attr(a[e],null)}),s[0].outerHTML})}return t},t.markdownToHTML=function(i,o){var r={gfm:!0,toc:!0,tocm:!1,tocStartLevel:1,tocTitle:"目录",tocDropdown:!1,tocContainer:"",markdown:"",markdownSourceCode:!1,htmlDecode:!1,autoLoadKaTeX:!0,pageBreak:!0,atLink:!0,emailLink:!0,tex:!1,taskList:!1,emoji:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0};t.$marked=marked;var n=e("#"+i),a=n.settings=e.extend(!0,r,o||{}),s=n.find("textarea");s.length<1&&(n.append(""),s=n.find("textarea"));var l=""===a.markdown?s.val():a.markdown,c=[],h={toc:a.toc,tocm:a.tocm,tocStartLevel:a.tocStartLevel,taskList:a.taskList,emoji:a.emoji,tex:a.tex,pageBreak:a.pageBreak,atLink:a.atLink,emailLink:a.emailLink,flowChart:a.flowChart,sequenceDiagram:a.sequenceDiagram,previewCodeHighlight:a.previewCodeHighlight},d={renderer:t.markedRenderer(c,h),gfm:a.gfm,tables:!0,breaks:!0,pedantic:!1,sanitize:a.htmlDecode?!1:!0,smartLists:!0,smartypants:!0};l=new String(l);var u=marked(l,d);u=t.filterHTMLTags(u,a.htmlDecode),a.markdownSourceCode?s.text(l):s.remove(),n.addClass("markdown-body "+this.classPrefix+"html-preview").append(u);var f=""!==a.tocContainer?e(a.tocContainer):n;if(""!==a.tocContainer&&f.attr("previewContainer",!1),a.toc&&(n.tocContainer=this.markdownToCRenderer(c,f,a.tocDropdown,a.tocStartLevel),(a.tocDropdown||n.find("."+this.classPrefix+"toc-menu").length>0)&&this.tocDropdownMenu(n,a.tocTitle),""!==a.tocContainer&&n.find(".editormd-toc-menu, .editormd-markdown-toc").remove()),a.previewCodeHighlight&&(n.find("pre").addClass("prettyprint linenums"),prettyPrint()),t.isIE8||(a.flowChart&&n.find(".flowchart").flowChart(),a.sequenceDiagram&&n.find(".sequence-diagram").sequenceDiagram({theme:"simple"})),a.tex){var g=function(){n.find("."+t.classNames.tex).each(function(){var t=e(this);katex.render(t.html().replace(/</g,"<").replace(/>/g,">"),t[0]),t.find(".katex").css("font-size","1.6em")})};!a.autoLoadKaTeX||t.$katex||t.kaTeXLoaded?g():this.loadKaTeX(function(){t.$katex=katex,t.kaTeXLoaded=!0,g()})}return n.getMarkdown=function(){return s.val()},n},t.themes=["default","dark"],t.previewThemes=["default","dark"],t.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"],t.loadPlugins={},t.loadFiles={js:[],css:[],plugin:[]},t.loadPlugin=function(e,i,o){i=i||function(){},this.loadScript(e,function(){t.loadFiles.plugin.push(e),i()},o)},t.loadCSS=function(e,i,o){o=o||"head",i=i||function(){};var r=document.createElement("link");r.type="text/css",r.rel="stylesheet",r.onload=r.onreadystatechange=function(){t.loadFiles.css.push(e),i()},r.href=e+".css","head"===o?document.getElementsByTagName("head")[0].appendChild(r):document.body.appendChild(r)},t.isIE="Microsoft Internet Explorer"==navigator.appName,t.isIE8=t.isIE&&"8."==navigator.appVersion.match(/8./i),t.loadScript=function(e,i,o){o=o||"head",i=i||function(){};var r=null;r=document.createElement("script"),r.id=e.replace(/[\./]+/g,"-"),r.type="text/javascript",r.src=e+".js",t.isIE8?r.onreadystatechange=function(){r.readyState&&("loaded"===r.readyState||"complete"===r.readyState)&&(r.onreadystatechange=null,t.loadFiles.js.push(e),i())}:r.onload=function(){t.loadFiles.js.push(e),i()},"head"===o?document.getElementsByTagName("head")[0].appendChild(r):document.body.appendChild(r)},t.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"},t.kaTeXLoaded=!1,t.loadKaTeX=function(e){t.loadCSS(t.katexURL.css,function(){t.loadScript(t.katexURL.js,e||function(){})})},t.lockScreen=function(t){e("html,body").css("overflow",t?"hidden":"")},t.createDialog=function(i){var o={name:"",width:420,height:240,title:"",drag:!0,closed:!0,content:"",mask:!0,maskStyle:{backgroundColor:"#fff",opacity:.1},lockScreen:!0,footer:!0,buttons:!1};i=e.extend(!0,o,i);var r=this,n=this.editor,a=t.classPrefix,s=(new Date).getTime(),l=""===i.name?a+"dialog-"+s:i.name,c=t.mouseOrTouch,h='
            ';""!==i.title&&(h+='
            ",h+=''+i.title+"",h+="
            "),i.closed&&(h+=''),h+='
            '+i.content,(i.footer||"string"==typeof i.footer)&&(h+='"),h+="
            ",h+='
            ',h+='
            ',h+="
            ",n.append(h);var d=n.find("."+l);d.lockScreen=function(t){return i.lockScreen&&(e("html,body").css("overflow",t?"hidden":""),r.resize()),d},d.showMask=function(){return i.mask&&n.find("."+a+"mask").css(i.maskStyle).css("z-index",t.dialogZindex-1).show(),d},d.hideMask=function(){return i.mask&&n.find("."+a+"mask").hide(),d},d.loading=function(e){var t=d.find("."+a+"dialog-mask");return t[e?"show":"hide"](),d},d.lockScreen(!0).showMask(),d.show().css({zIndex:t.dialogZindex,border:t.isIE8?"1px solid #ddd":"",width:"number"==typeof i.width?i.width+"px":i.width,height:"number"==typeof i.height?i.height+"px":i.height});var u=function(){d.css({top:(e(window).height()-d.height())/2+"px",left:(e(window).width()-d.width())/2+"px"})};if(u(),e(window).resize(u),d.children("."+a+"dialog-close").bind(c("click","touchend"),function(){d.hide().lockScreen(!1).hideMask()}),"object"==typeof i.buttons){var f=d.footer=d.find("."+a+"dialog-footer");for(var g in i.buttons){var p=i.buttons[g],m=a+g+"-btn";f.append('"),p[1]=e.proxy(p[1],d),f.children("."+m).bind(c("click","touchend"),p[1])}}if(""!==i.title&&i.drag){var w,v,k=d.children("."+a+"dialog-header");i.mask||k.bind(c("click","touchend"),function(){t.dialogZindex+=2,d.css("z-index",t.dialogZindex)}),k.mousedown(function(e){e=e||window.event,w=e.clientX-parseInt(d[0].style.left),v=e.clientY-parseInt(d[0].style.top),document.onmousemove=y});var b=function(e){e.removeClass(a+"user-unselect").off("selectstart")},x=function(e){e.addClass(a+"user-unselect").on("selectstart",function(e){return!1})},y=function(t){t=t||window.event;var i,o,r=parseInt(d[0].style.left),n=parseInt(d[0].style.top);r>=0?r+d.width()<=e(window).width()?i=t.clientX-w:(i=e(window).width()-d.width(),document.onmousemove=null):(i=0,document.onmousemove=null),n>=0?o=t.clientY-v:(o=0,document.onmousemove=null),document.onselectstart=function(){return!1},x(e("body")),x(d),d[0].style.left=i+"px",d[0].style.top=o+"px"};document.onmouseup=function(){b(e("body")),b(d),document.onselectstart=null,document.onmousemove=null},k.touchDraggable=function(){var t=null,i=function(i){var o=i.originalEvent,r=e(this).parent().position();t={x:o.changedTouches[0].pageX-r.left,y:o.changedTouches[0].pageY-r.top}},o=function(i){i.preventDefault();var o=i.originalEvent;e(this).parent().css({top:o.changedTouches[0].pageY-t.y,left:o.changedTouches[0].pageX-t.x})};this.bind("touchstart",i).bind("touchmove",o)},k.touchDraggable()}return t.dialogZindex+=2,d},t.mouseOrTouch=function(e,t){e=e||"click",t=t||"touchend";var i=e;try{document.createEvent("TouchEvent"),i=t}catch(o){}return i},t.dateFormat=function(e){e=e||"";var t=function(e){return 10>e?"0"+e:e},i=new Date,o=i.getFullYear(),r=o.toString().slice(2,4),n=t(i.getMonth()+1),a=t(i.getDate()),s=i.getDay(),l=t(i.getHours()),c=t(i.getMinutes()),h=t(i.getSeconds()),d=t(i.getMilliseconds()),u="",f=r+"-"+n+"-"+a,g=o+"-"+n+"-"+a,p=l+":"+c+":"+h;switch(e){case"UNIX Time":u=i.getTime();break;case"UTC":u=i.toUTCString();break;case"yy":u=r;break;case"year":case"yyyy":u=o;break;case"month":case"mm":u=n;break;case"cn-week-day":case"cn-wd":var m=["日","一","二","三","四","五","六"];u="星期"+m[s];break;case"week-day":case"wd":var w=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];u=w[s];break;case"day":case"dd":u=a;break;case"hour":case"hh":u=l;break;case"min":case"ii":u=c;break;case"second":case"ss":u=h;break;case"ms":u=d;break;case"yy-mm-dd":u=f;break;case"yyyy-mm-dd":u=g;break;case"yyyy-mm-dd h:i:s ms":case"full + ms":u=g+" "+p+" "+d;break;case"full":case"yyyy-mm-dd h:i:s":default:u=g+" "+p}return u},t}}); \ No newline at end of file diff --git a/public/editormd/editormd.js b/public/editormd/editormd.js new file mode 100644 index 0000000..cbb1b6c --- /dev/null +++ b/public/editormd/editormd.js @@ -0,0 +1,4664 @@ +/* + * 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, // false, // 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 : "style,iframe|on*", // 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.0em"); + }); + + 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) + { + // TODO url完善 + settings.imageUploadURL && initEditormdPasteUpload( this , settings.imageUploadURL) + $.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.text(), tex[0]); + tex.find(".katex").css("font-size", "1.0em"); + }); + }; + + 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 : "/katex/katex.min", + js : "/katex/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; + $("body").removeAttr("style"); + 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; + +})); + +/** + cm paste事件上传图片的封装 + event : paste事件的event + action: 图片上传url + callback: 图片上传xhr回调 + */ +window._whenPasterDoUpload = function(event, action, callback){ + var clipboardData = event.clipboardData, + i = 0, items, item, types; + if( clipboardData ){ + items = clipboardData.items; + if( !items ) + return; + item = items[0]; + // 保存在剪贴板中的数据类型 + types = clipboardData.types || []; + + for( ; i < types.length; i++ ){ + if( types[i] === 'Files' ){ + item = items[i]; + break; + } + } + // 判断是否为图片数据 + if( item && item.kind === 'file' && item.type.match(/^image\//i) ){ + // 读取该图片 + var file = item.getAsFile(); + var oMyForm = new FormData(); + oMyForm.append("editormd-image-file",file); + oMyForm.append("byxhr","true"); + var xhr = new window.XMLHttpRequest(); + xhr.addEventListener("load", + function(_xhr){ + var response=_xhr.target, json=JSON.parse(response.responseText); + + if (json.success === 1) { + callback && callback(json) + // input.value=json.url; + } + else + { + callback && callback(json) + console.log(json.message); + } + }, false); + xhr.addEventListener("error", function(){console.error("error");}, false); + xhr.open("POST", action); + xhr.send(oMyForm); + } + } +} + +function initEditormdPasteUpload(editormd, url, callback) { + editormd.cm.getInputField().addEventListener("paste", function(event) { + _whenPasterDoUpload(event, url, function(resJson) { + // TODO 插入图片url到cm + if (resJson.success === 1) { + editormd.cm.replaceSelection("![](" + resJson.url + ")") + } + }); + }) +} \ No newline at end of file diff --git a/public/editormd/editormd.min.js b/public/editormd/editormd.min.js new file mode 100644 index 0000000..03d4c96 --- /dev/null +++ b/public/editormd/editormd.min.js @@ -0,0 +1,3 @@ +/*! Editor.md v1.5.0 | editormd.min.js | Open source online markdown editor. | MIT License | By: Pandao | https://github.com/pandao/editor.md | 2015-06-09 */ +!function(e){"use strict";"function"==typeof require&&"object"==typeof exports&&"object"==typeof module?module.exports=e:"function"==typeof define?define.amd||define(["jquery"],e):window.editormd=e()}(function(){"use strict";var e="undefined"!=typeof jQuery?jQuery:Zepto;if("undefined"!=typeof e){var t=function(e,i){return new t.fn.init(e,i)};t.title=t.$name="Editor.md",t.version="1.5.0",t.homePage="https://pandao.github.io/editor.md/",t.classPrefix="editormd-",t.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"]},t.defaults={mode:"gfm",name:"",value:"",theme:"",editorTheme:"default",previewTheme:"",markdown:"",appendMarkdown:"",width:"100%",height:"100%",path:"./lib/",pluginPath:"",delay:300,autoLoadModules:!0,watch:!0,placeholder:"Enjoy Markdown! coding now...",gotoLine:!0,codeFold:!1,autoHeight:!1,autoFocus:!0,autoCloseTags:!0,searchReplace:!0,syncScrolling:!0,readOnly:!1,tabSize:4,indentUnit:4,lineNumbers:!0,lineWrapping:!0,autoCloseBrackets:!0,showTrailingSpace:!0,matchBrackets:!0,indentWithTabs:!0,styleSelectedText:!0,matchWordHighlight:!0,styleActiveLine:!0,dialogLockScreen:!0,dialogShowMask:!0,dialogDraggable:!0,dialogMaskBgColor:"#fff",dialogMaskOpacity:.1,fontSize:"13px",saveHTMLToTextarea:!1,disabledKeyMaps:[],onload:function(){},onresize:function(){},onchange:function(){},onwatch:null,onunwatch:null,onpreviewing:function(){},onpreviewed:function(){},onfullscreen:function(){},onfullscreenExit:function(){},onscroll:function(){},onpreviewscroll:function(){},imageUpload:!1,imageFormats:["jpg","jpeg","gif","png","bmp","webp"],imageUploadURL:"",crossDomainUpload:!1,uploadCallbackURL:"",toc:!0,tocm:!1,tocTitle:"",tocDropdown:!1,tocContainer:"",tocStartLevel:1,htmlDecode:!1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1,previewCodeHighlight:!0,toolbar:!0,toolbarAutoFixed:!0,toolbarIcons:"full",toolbarTitles:{},toolbarHandlers:{ucwords:function(){return t.toolbarHandlers.ucwords},lowercase:function(){return t.toolbarHandlers.lowercase}},toolbarCustomIcons:{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:t.classPrefix+"bold",h2:t.classPrefix+"bold",h3:t.classPrefix+"bold",h4:t.classPrefix+"bold",h5:t.classPrefix+"bold",h6:t.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",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:"关于"+t.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:"使用帮助"}}}},t.classNames={tex:t.classPrefix+"tex"},t.dialogZindex=99999,t.$katex=null,t.$marked=null,t.$CodeMirror=null,t.$prettyPrint=null;var i,o;t.prototype=t.fn={state:{watching:!1,loaded:!1,preview:!1,fullscreen:!1},init:function(i,o){o=o||{},"object"==typeof i&&(o=i);var r=this.classPrefix=t.classPrefix,n=this.settings=e.extend(!0,t.defaults,o);i="object"==typeof i?n.id:i;var a=this.editor=e("#"+i);this.id=i,this.lang=n.lang;var s=this.classNames={textarea:{html:r+"html-textarea",markdown:r+"markdown-textarea"}};n.pluginPath=""===n.pluginPath?n.path+"../plugins/":n.pluginPath,this.state.watching=n.watch?!0:!1,a.hasClass("editormd")||a.addClass("editormd"),a.css({width:"number"==typeof n.width?n.width+"px":n.width,height:"number"==typeof n.height?n.height+"px":n.height}),n.autoHeight&&a.css("height","auto");var l=this.markdownTextarea=a.children("textarea");l.length<1&&(a.append(""),l=this.markdownTextarea=a.children("textarea")),l.addClass(s.textarea.markdown).attr("placeholder",n.placeholder),("undefined"==typeof l.attr("name")||""===l.attr("name"))&&l.attr("name",""!==n.name?n.name:i+"-markdown-doc");var c=[n.readOnly?"":'',n.saveHTMLToTextarea?'':"",'
                ','
                ','
                '].join("\n");return a.append(c).addClass(r+"vertical"),""!==n.theme&&a.addClass(r+"theme-"+n.theme),this.mask=a.children("."+r+"mask"),this.containerMask=a.children("."+r+"container-mask"),""!==n.markdown&&l.val(n.markdown),""!==n.appendMarkdown&&l.val(l.val()+n.appendMarkdown),this.htmlTextarea=a.children("."+s.textarea.html),this.preview=a.children("."+r+"preview"),this.previewContainer=this.preview.children("."+r+"preview-container"),""!==n.previewTheme&&this.preview.addClass(r+"preview-theme-"+n.previewTheme),"function"==typeof define&&define.amd&&("undefined"!=typeof katex&&(t.$katex=katex),n.searchReplace&&!n.readOnly&&(t.loadCSS(n.path+"codemirror/addon/dialog/dialog"),t.loadCSS(n.path+"codemirror/addon/search/matchesonscrollbar"))),"function"==typeof define&&define.amd||!n.autoLoadModules?("undefined"!=typeof CodeMirror&&(t.$CodeMirror=CodeMirror),"undefined"!=typeof marked&&(t.$marked=marked),this.setCodeMirror().setToolbar().loadedDisplay()):this.loadQueues(),this},loadQueues:function(){var e=this,i=this.settings,o=i.path,r=function(){return t.isIE8?void e.loadedDisplay():void(i.flowChart||i.sequenceDiagram?t.loadScript(o+"raphael.min",function(){t.loadScript(o+"underscore.min",function(){!i.flowChart&&i.sequenceDiagram?t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()}):i.flowChart&&!i.sequenceDiagram?t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){e.loadedDisplay()})}):i.flowChart&&i.sequenceDiagram&&t.loadScript(o+"flowchart.min",function(){t.loadScript(o+"jquery.flowchart.min",function(){t.loadScript(o+"sequence-diagram.min",function(){e.loadedDisplay()})})})})}):e.loadedDisplay())};return t.loadCSS(o+"codemirror/codemirror.min"),i.searchReplace&&!i.readOnly&&(t.loadCSS(o+"codemirror/addon/dialog/dialog"),t.loadCSS(o+"codemirror/addon/search/matchesonscrollbar")),i.codeFold&&t.loadCSS(o+"codemirror/addon/fold/foldgutter"),t.loadScript(o+"codemirror/codemirror.min",function(){t.$CodeMirror=CodeMirror,t.loadScript(o+"codemirror/modes.min",function(){t.loadScript(o+"codemirror/addons.min",function(){return e.setCodeMirror(),"gfm"!==i.mode&&"markdown"!==i.mode?(e.loadedDisplay(),!1):(e.setToolbar(),void t.loadScript(o+"marked.min",function(){t.$marked=marked,i.previewCodeHighlight?t.loadScript(o+"prettify.min",function(){r()}):r()}))})})}),this},setTheme:function(e){var t=this.editor,i=this.settings.theme,o=this.classPrefix+"theme-";return t.removeClass(o+i).addClass(o+e),this.settings.theme=e,this},setEditorTheme:function(e){var i=this.settings;return i.editorTheme=e,"default"!==e&&t.loadCSS(i.path+"codemirror/theme/"+i.editorTheme),this.cm.setOption("theme",e),this},setCodeMirrorTheme:function(e){return this.setEditorTheme(e),this},setPreviewTheme:function(e){var t=this.preview,i=this.settings.previewTheme,o=this.classPrefix+"preview-theme-";return t.removeClass(o+i).addClass(o+e),this.settings.previewTheme=e,this},setCodeMirror:function(){var e=this.settings,i=this.editor;"default"!==e.editorTheme&&t.loadCSS(e.path+"codemirror/theme/"+e.editorTheme);var o={mode:e.mode,theme:e.editorTheme,tabSize:e.tabSize,dragDrop:!1,autofocus:e.autoFocus,autoCloseTags:e.autoCloseTags,readOnly:e.readOnly?"nocursor":!1,indentUnit:e.indentUnit,lineNumbers:e.lineNumbers,lineWrapping:e.lineWrapping,extraKeys:{"Ctrl-Q":function(e){e.foldCode(e.getCursor())}},foldGutter:e.codeFold,gutters:["CodeMirror-linenumbers","CodeMirror-foldgutter"],matchBrackets:e.matchBrackets,indentWithTabs:e.indentWithTabs,styleActiveLine:e.styleActiveLine,styleSelectedText:e.styleSelectedText,autoCloseBrackets:e.autoCloseBrackets,showTrailingSpace:e.showTrailingSpace,highlightSelectionMatches:e.matchWordHighlight?{showToken:"onselected"===e.matchWordHighlight?!1:/\w/}:!1};return this.codeEditor=this.cm=t.$CodeMirror.fromTextArea(this.markdownTextarea[0],o),this.codeMirror=this.cmElement=i.children(".CodeMirror"),""!==e.value&&this.cm.setValue(e.value),this.codeMirror.css({fontSize:e.fontSize,width:e.watch?"50%":"100%"}),e.autoHeight&&(this.codeMirror.css("height","auto"),this.cm.setOption("viewportMargin",1/0)),e.lineNumbers||this.codeMirror.find(".CodeMirror-gutters").css("border-right","none"),this},getCodeMirrorOption:function(e){return this.cm.getOption(e)},setCodeMirrorOption:function(e,t){return this.cm.setOption(e,t),this},addKeyMap:function(e,t){return this.cm.addKeyMap(e,t),this},removeKeyMap:function(e){return this.cm.removeKeyMap(e),this},gotoLine:function(t){var i=this.settings;if(!i.gotoLine)return this;var o=this.cm,r=(this.editor,o.lineCount()),n=this.preview;if("string"==typeof t&&("last"===t&&(t=r),"first"===t&&(t=1)),"number"!=typeof t)return alert("Error: The line number must be an integer."),this;if(t=parseInt(t)-1,t>r)return alert("Error: The line number range 1-"+r),this;o.setCursor({line:t,ch:0});var a=o.getScrollInfo(),s=a.clientHeight,l=o.charCoords({line:t,ch:0},"local");if(o.scrollTo(null,(l.top+l.bottom-s)/2),i.watch){var c=this.codeMirror.find(".CodeMirror-scroll")[0],h=e(c).height(),d=c.scrollTop,u=d/c.scrollHeight;n.scrollTop(0===d?0:d+h>=c.scrollHeight-16?n[0].scrollHeight:n[0].scrollHeight*u)}return o.focus(),this},extend:function(){return"undefined"!=typeof arguments[1]&&("function"==typeof arguments[1]&&(arguments[1]=e.proxy(arguments[1],this)),this[arguments[0]]=arguments[1]),"object"==typeof arguments[0]&&"undefined"==typeof arguments[0].length&&e.extend(!0,this,arguments[0]),this},set:function(t,i){return"undefined"!=typeof i&&"function"==typeof i&&(i=e.proxy(i,this)),this[t]=i,this},config:function(t,i){var o=this.settings;return"object"==typeof t&&(o=e.extend(!0,o,t)),"string"==typeof t&&(o[t]=i),this.settings=o,this.recreate(),this},on:function(t,i){var o=this.settings;return"undefined"!=typeof o["on"+t]&&(o["on"+t]=e.proxy(i,this)),this},off:function(e){var t=this.settings;return"undefined"!=typeof t["on"+e]&&(t["on"+e]=function(){}),this},showToolbar:function(t){var i=this.settings;return i.readOnly?this:(i.toolbar&&(this.toolbar.length<1||""===this.toolbar.find("."+this.classPrefix+"menu").html())&&this.setToolbar(),i.toolbar=!0,this.toolbar.show(),this.resize(),e.proxy(t||function(){},this)(),this)},hideToolbar:function(t){var i=this.settings;return i.toolbar=!1,this.toolbar.hide(),this.resize(),e.proxy(t||function(){},this)(),this},setToolbarAutoFixed:function(t){var i=this.state,o=this.editor,r=this.toolbar,n=this.settings;"undefined"!=typeof t&&(n.toolbarAutoFixed=t);var a=function(){var t=e(window),i=t.scrollTop();return n.toolbarAutoFixed?void r.css(i-o.offset().top>10&&i
                  ';i.append(n),r=this.toolbar=i.children("."+o+"toolbar")}if(!e.toolbar)return r.hide(),this;r.show();for(var a="function"==typeof e.toolbarIcons?e.toolbarIcons():"string"==typeof e.toolbarIcons?t.toolbarModes[e.toolbarIcons]:e.toolbarIcons,s=r.find("."+this.classPrefix+"menu"),l="",c=!1,h=0,d=a.length;d>h;h++){var u=a[h];if("||"===u)c=!0;else if("|"===u)l+='
                • |
                • ';else{var f=/h(\d)/.test(u),g=u;"watch"!==u||e.watch||(g="unwatch");var p=e.lang.toolbar[g],m=e.toolbarIconTexts[g],w=e.toolbarIconsClass[g];p="undefined"==typeof p?"":p,m="undefined"==typeof m?"":m,w="undefined"==typeof w?"":w;var v=c?'
                • ':"
                • ";"undefined"!=typeof e.toolbarCustomIcons[u]&&"function"!=typeof e.toolbarCustomIcons[u]?v+=e.toolbarCustomIcons[u]:(v+='',v+=''+(f?u.toUpperCase():""===w?m:"")+"",v+=""),v+="
                • ",l=c?v+l:l+v}}return s.html(l),s.find('[title="Lowercase"]').attr("title",e.lang.toolbar.lowercase),s.find('[title="ucwords"]').attr("title",e.lang.toolbar.ucwords),this.setToolbarHandler(),this.setToolbarAutoFixed(),this},dialogLockScreen:function(){return e.proxy(t.dialogLockScreen,this)(),this},dialogShowMask:function(i){return e.proxy(t.dialogShowMask,this)(i),this},getToolbarHandles:function(e){var i=this.toolbarHandlers=t.toolbarHandlers;return e&&"undefined"!=typeof toolbarIconHandlers[e]?i[e]:i},setToolbarHandler:function(){var i=this,o=this.settings;if(!o.toolbar||o.readOnly)return this;var r=this.toolbar,n=this.cm,a=this.classPrefix,s=this.toolbarIcons=r.find("."+a+"menu > li > a"),l=this.getToolbarHandles();return s.bind(t.mouseOrTouch("click","touchend"),function(t){var r=e(this).children(".fa"),a=r.attr("name"),s=n.getCursor(),c=n.getSelection();return""!==a?(i.activeIcon=r,"undefined"!=typeof l[a]?e.proxy(l[a],i)(n):"undefined"!=typeof o.toolbarHandlers[a]&&e.proxy(o.toolbarHandlers[a],i)(n,r,s,c),"link"!==a&&"reference-link"!==a&&"image"!==a&&"code-block"!==a&&"preformatted-text"!==a&&"watch"!==a&&"preview"!==a&&"search"!==a&&"fullscreen"!==a&&"info"!==a&&n.focus(),!1):void 0}),this},createDialog:function(i){return e.proxy(t.createDialog,this)(i)},createInfoDialog:function(){var e=this,i=this.editor,o=this.classPrefix,r=['
                  ','
                  ','

                  '+t.title+"v"+t.version+"

                  ","

                  "+this.lang.description+"

                  ",'

                  '+t.homePage+'

                  ','

                  Copyright © 2015 Pandao, The MIT License.

                  ',"
                  ",'',"
                  "].join("\n");i.append(r);var n=this.infoDialog=i.children("."+o+"dialog-info");return n.find("."+o+"dialog-close").bind(t.mouseOrTouch("click","touchend"),function(){e.hideInfoDialog()}),n.css("border",t.isIE8?"1px solid #ddd":"").css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},infoDialogPosition:function(){var t=this.infoDialog,i=function(){t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"})};return i(),e(window).resize(i),this},showInfoDialog:function(){e("html,body").css("overflow-x","hidden");var i=this.editor,o=this.settings,r=this.infoDialog=i.children("."+this.classPrefix+"dialog-info");return r.length<1&&this.createInfoDialog(),this.lockScreen(!0),this.mask.css({opacity:o.dialogMaskOpacity,backgroundColor:o.dialogMaskBgColor}).show(),r.css("z-index",t.dialogZindex).show(),this.infoDialogPosition(),this},hideInfoDialog:function(){return e("html,body").css("overflow-x",""),this.infoDialog.hide(),this.mask.hide(),this.lockScreen(!1),this},lockScreen:function(e){return t.lockScreen(e),this.resize(),this},recreate:function(){var e=this.editor,t=this.settings;return this.codeMirror.remove(),this.setCodeMirror(),t.readOnly||(e.find(".editormd-dialog").length>0&&e.find(".editormd-dialog").remove(),t.toolbar&&(this.getToolbarHandles(),this.setToolbar())),this.loadedDisplay(!0),this},previewCodeHighlight:function(){var e=this.settings,t=this.previewContainer;return e.previewCodeHighlight&&(t.find("pre").addClass("prettyprint linenums"),"undefined"!=typeof prettyPrint&&prettyPrint()),this},katexRender:function(){return null===i?this:(this.previewContainer.find("."+t.classNames.tex).each(function(){var i=e(this);t.$katex.render(i.text(),i[0]),i.find(".katex").css("font-size","1.6em")}),this)},flowChartAndSequenceDiagramRender:function(){var i=this,r=this.settings,n=this.previewContainer;if(t.isIE8)return this;if(r.flowChart){if(null===o)return this;n.find(".flowchart").flowChart()}r.sequenceDiagram&&n.find(".sequence-diagram").sequenceDiagram({theme:"simple"});var a=i.preview,s=i.codeMirror,l=s.find(".CodeMirror-scroll"),c=l.height(),h=l.scrollTop(),d=h/l[0].scrollHeight,u=0;a.find(".markdown-toc-list").each(function(){u+=e(this).height()});var f=a.find(".editormd-toc-menu").height();return f=f?f:0,a.scrollTop(0===h?0:h+c>=l[0].scrollHeight-16?a[0].scrollHeight:(a[0].scrollHeight+u+f)*d),this},registerKeyMaps:function(i){var o=this,r=this.cm,n=this.settings,a=t.toolbarHandlers,s=n.disabledKeyMaps;if(i=i||null){for(var l in i)if(e.inArray(l,s)<0){var c={};c[l]=i[l],r.addKeyMap(i)}}else{for(var h in t.keyMaps){var d=t.keyMaps[h],u="string"==typeof d?e.proxy(a[d],o):e.proxy(d,o);if(e.inArray(h,["F9","F10","F11"])<0&&e.inArray(h,s)<0){var f={};f[h]=u,r.addKeyMap(f)}}e(window).keydown(function(t){var i={120:"F9",121:"F10",122:"F11"};if(e.inArray(i[t.keyCode],s)<0)switch(t.keyCode){case 120:return e.proxy(a.watch,o)(),!1;case 121:return e.proxy(a.preview,o)(),!1;case 122:return e.proxy(a.fullscreen,o)(),!1}})}return this},bindScrollEvent:function(){var i=this,o=this.preview,r=this.settings,n=this.codeMirror,a=t.mouseOrTouch;if(!r.syncScrolling)return this;var s=function(){n.find(".CodeMirror-scroll").bind(a("scroll","touchmove"),function(t){var n=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=0;o.find(".markdown-toc-list").each(function(){l+=e(this).height()});var c=o.find(".editormd-toc-menu").height();c=c?c:0,o.scrollTop(0===a?0:a+n>=e(this)[0].scrollHeight-16?o[0].scrollHeight:(o[0].scrollHeight+l+c)*s),e.proxy(r.onscroll,i)(t)})},l=function(){n.find(".CodeMirror-scroll").unbind(a("scroll","touchmove"))},c=function(){o.bind(a("scroll","touchmove"),function(t){var o=e(this).height(),a=e(this).scrollTop(),s=a/e(this)[0].scrollHeight,l=n.find(".CodeMirror-scroll");l.scrollTop(0===a?0:a+o>=e(this)[0].scrollHeight?l[0].scrollHeight:l[0].scrollHeight*s),e.proxy(r.onpreviewscroll,i)(t)})},h=function(){o.unbind(a("scroll","touchmove"))};return n.bind({mouseover:s,mouseout:l,touchstart:s,touchend:l}),"single"===r.syncScrolling?this:(o.bind({mouseover:c,mouseout:h,touchstart:c,touchend:h}),this)},bindChangeEvent:function(){var e=this,t=this.cm,o=this.settings;return o.syncScrolling?(t.on("change",function(t,r){o.watch&&e.previewContainer.css("padding",o.autoHeight?"20px 20px 50px 40px":"20px"),i=setTimeout(function(){clearTimeout(i),e.save(),i=null},o.delay)}),this):this},loadedDisplay:function(t){t=t||!1;var i=this,o=this.editor,r=this.preview,n=this.settings;return this.containerMask.hide(),this.save(),n.watch&&r.show(),o.data("oldWidth",o.width()).data("oldHeight",o.height()),this.resize(),this.registerKeyMaps(),e(window).resize(function(){i.resize()}),this.bindScrollEvent().bindChangeEvent(),t||e.proxy(n.onload,this)(),this.state.loaded=!0,this},width:function(e){return this.editor.css("width","number"==typeof e?e+"px":e),this.resize(),this},height:function(e){return this.editor.css("height","number"==typeof e?e+"px":e),this.resize(),this},resize:function(t,i){t=t||null,i=i||null;var o=this.state,r=this.editor,n=this.preview,a=this.toolbar,s=this.settings,l=this.codeMirror;if(t&&r.css("width","number"==typeof t?t+"px":t),!s.autoHeight||o.fullscreen||o.preview?(i&&r.css("height","number"==typeof i?i+"px":i),o.fullscreen&&r.height(e(window).height()),s.toolbar&&!s.readOnly?l.css("margin-top",a.height()+1).height(r.height()-a.height()):l.css("margin-top",0).height(r.height())):(r.css("height","auto"),l.css("height","auto")),s.watch)if(l.width(r.width()/2),n.width(o.preview?r.width():r.width()/2),this.previewContainer.css("padding",s.autoHeight?"20px 20px 50px 40px":"20px"),s.toolbar&&!s.readOnly?n.css("top",a.height()+1):n.css("top",0),!s.autoHeight||o.fullscreen||o.preview){var c=s.toolbar&&!s.readOnly?r.height()-a.height():r.height();n.height(c)}else n.height("");else l.width(r.width()),n.hide();return o.loaded&&e.proxy(s.onresize,this)(),this},save:function(){if(null===i)return this;var r=this,n=this.state,a=this.settings,s=this.cm,l=s.getValue(),c=this.previewContainer;if("gfm"!==a.mode&&"markdown"!==a.mode)return this.markdownTextarea.val(l),this;var h=t.$marked,d=this.markdownToC=[],u=this.markedRendererOptions={toc:a.toc,tocm:a.tocm,tocStartLevel:a.tocStartLevel,pageBreak:a.pageBreak,taskList:a.taskList,emoji:a.emoji,tex:a.tex,atLink:a.atLink,emailLink:a.emailLink,flowChart:a.flowChart,sequenceDiagram:a.sequenceDiagram,previewCodeHighlight:a.previewCodeHighlight},f=this.markedOptions={renderer:t.markedRenderer(d,u),gfm:!0,tables:!0,breaks:!0,pedantic:!1,sanitize:a.htmlDecode?!1:!0,smartLists:!0,smartypants:!0};h.setOptions(f);var g=t.$marked(l,f);if(g=t.filterHTMLTags(g,a.htmlDecode),this.markdownTextarea.text(l),s.save(),a.saveHTMLToTextarea&&this.htmlTextarea.text(g),a.watch||!a.watch&&n.preview){if(c.html(g),this.previewCodeHighlight(),a.toc){var p=""===a.tocContainer?c:e(a.tocContainer),m=p.find("."+this.classPrefix+"toc-menu");p.attr("previewContainer",""===a.tocContainer?"true":"false"),""!==a.tocContainer&&m.length>0&&m.remove(),t.markdownToCRenderer(d,p,a.tocDropdown,a.tocStartLevel),(a.tocDropdown||p.find("."+this.classPrefix+"toc-menu").length>0)&&t.tocDropdownMenu(p,""!==a.tocTitle?a.tocTitle:this.lang.tocTitle),""!==a.tocContainer&&c.find(".markdown-toc").css("border","none")}a.tex&&(!t.kaTeXLoaded&&a.autoLoadModules?t.loadKaTeX(function(){t.$katex=katex,t.kaTeXLoaded=!0,r.katexRender()}):(t.$katex=katex,this.katexRender())),(a.flowChart||a.sequenceDiagram)&&(o=setTimeout(function(){clearTimeout(o),r.flowChartAndSequenceDiagramRender(),o=null},10)),n.loaded&&e.proxy(a.onchange,this)()}return this},focus:function(){return this.cm.focus(),this},setCursor:function(e){return this.cm.setCursor(e),this},getCursor:function(){return this.cm.getCursor()},setSelection:function(e,t){return this.cm.setSelection(e,t),this},getSelection:function(){return this.cm.getSelection()},setSelections:function(e){return this.cm.setSelections(e),this},getSelections:function(){return this.cm.getSelections()},replaceSelection:function(e){return this.cm.replaceSelection(e),this},insertValue:function(e){return this.replaceSelection(e),this},appendMarkdown:function(e){var t=(this.settings,this.cm);return t.setValue(t.getValue()+e),this},setMarkdown:function(e){return this.cm.setValue(e||this.settings.markdown),this},getMarkdown:function(){return this.cm.getValue()},getValue:function(){return this.cm.getValue()},setValue:function(e){return this.cm.setValue(e),this},clear:function(){return this.cm.setValue(""),this},getHTML:function(){return this.settings.saveHTMLToTextarea?this.htmlTextarea.val():(alert("Error: settings.saveHTMLToTextarea == false"),!1)},getTextareaSavedHTML:function(){return this.getHTML()},getPreviewedHTML:function(){return this.settings.watch?this.previewContainer.html():(alert("Error: settings.watch == false"),!1)},watch:function(t){var o=this.settings;if(e.inArray(o.mode,["gfm","markdown"])<0)return this;if(this.state.watching=o.watch=!0,this.preview.show(),this.toolbar){var r=o.toolbarIconsClass.watch,n=o.toolbarIconsClass.unwatch,a=this.toolbar.find(".fa[name=watch]");a.parent().attr("title",o.lang.toolbar.watch),a.removeClass(n).addClass(r)}return this.codeMirror.css("border-right","1px solid #ddd").width(this.editor.width()/2),i=0,this.save().resize(),o.onwatch||(o.onwatch=t||function(){}),e.proxy(o.onwatch,this)(),this},unwatch:function(t){var i=this.settings;if(this.state.watching=i.watch=!1,this.preview.hide(),this.toolbar){var o=i.toolbarIconsClass.watch,r=i.toolbarIconsClass.unwatch,n=this.toolbar.find(".fa[name=watch]");n.parent().attr("title",i.lang.toolbar.unwatch),n.removeClass(o).addClass(r)}return this.codeMirror.css("border-right","none").width(this.editor.width()),this.resize(),i.onunwatch||(i.onunwatch=t||function(){}),e.proxy(i.onunwatch,this)(),this},show:function(t){t=t||function(){};var i=this;return this.editor.show(0,function(){e.proxy(t,i)()}),this},hide:function(t){t=t||function(){};var i=this;return this.editor.hide(0,function(){e.proxy(t,i)()}),this},previewing:function(){var i=this,o=this.editor,r=this.preview,n=this.toolbar,a=this.settings,s=this.codeMirror,l=this.previewContainer;if(e.inArray(a.mode,["gfm","markdown"])<0)return this;a.toolbar&&n&&(n.toggle(),n.find(".fa[name=preview]").toggleClass("active")),s.toggle();var c=function(e){e.shiftKey&&27===e.keyCode&&i.previewed()};"none"===s.css("display")?(this.state.preview=!0,this.state.fullscreen&&r.css("background","#fff"),o.find("."+this.classPrefix+"preview-close-btn").show().bind(t.mouseOrTouch("click","touchend"),function(){i.previewed()}),a.watch?l.css("padding",""):this.save(),l.addClass(this.classPrefix+"preview-active"),r.show().css({position:"",top:0,width:o.width(),height:a.autoHeight&&!this.state.fullscreen?"auto":o.height()}),this.state.loaded&&e.proxy(a.onpreviewing,this)(),e(window).bind("keyup",c)):(e(window).unbind("keyup",c),this.previewed())},previewed:function(){var i=this.editor,o=this.preview,r=this.toolbar,n=this.settings,a=this.previewContainer,s=i.find("."+this.classPrefix+"preview-close-btn");return this.state.preview=!1,this.codeMirror.show(),n.toolbar&&r.show(),o[n.watch?"show":"hide"](),s.hide().unbind(t.mouseOrTouch("click","touchend")),a.removeClass(this.classPrefix+"preview-active"),n.watch&&a.css("padding","20px"),o.css({background:null,position:"absolute",width:i.width()/2,height:n.autoHeight&&!this.state.fullscreen?"auto":i.height()-r.height(),top:n.toolbar?r.height():0}),this.state.loaded&&e.proxy(n.onpreviewed,this)(),this},fullscreen:function(){var t=this,i=this.state,o=this.editor,r=(this.preview,this.toolbar),n=this.settings,a=this.classPrefix+"fullscreen";r&&r.find(".fa[name=fullscreen]").parent().toggleClass("active");var s=function(e){e.shiftKey||27!==e.keyCode||i.fullscreen&&t.fullscreenExit()};return o.hasClass(a)?(e(window).unbind("keyup",s),this.fullscreenExit()):(i.fullscreen=!0,e("html,body").css("overflow","hidden"),o.css({width:e(window).width(),height:e(window).height()}).addClass(a),this.resize(),e.proxy(n.onfullscreen,this)(),e(window).bind("keyup",s)),this},fullscreenExit:function(){var t=this.editor,i=this.settings,o=this.toolbar,r=this.classPrefix+"fullscreen";return this.state.fullscreen=!1,o&&o.find(".fa[name=fullscreen]").parent().removeClass("active"),e("html,body").css("overflow",""),t.css({width:t.data("oldWidth"),height:t.data("oldHeight")}).removeClass(r),this.resize(),e.proxy(i.onfullscreenExit,this)(),this},executePlugin:function(i,o){var r=this,n=this.cm,a=this.settings;return o=a.pluginPath+o,"function"==typeof define?"undefined"==typeof this[i]?(alert("Error: "+i+" plugin is not found, you are not load this plugin."),this):(this[i](n),this):(e.inArray(o,t.loadFiles.plugin)<0?t.loadPlugin(o,function(){t.loadPlugins[i]=r[i],r[i](n)}):e.proxy(t.loadPlugins[i],this)(n),this)},search:function(e){var t=this.settings;return t.searchReplace?(t.readOnly||this.cm.execCommand(e||"find"),this):(alert("Error: settings.searchReplace == false"),this)},searchReplace:function(){return this.search("replace"),this},searchReplaceAll:function(){return this.search("replaceAll"),this}},t.fn.init.prototype=t.fn,t.dialogLockScreen=function(){var t=this.settings||{dialogLockScreen:!0};t.dialogLockScreen&&(e("html,body").css("overflow","hidden"),this.resize())},t.dialogShowMask=function(t){var i=this.editor,o=this.settings||{dialogShowMask:!0};t.css({top:(e(window).height()-t.height())/2+"px",left:(e(window).width()-t.width())/2+"px"}),o.dialogShowMask&&i.children("."+this.classPrefix+"mask").css("z-index",parseInt(t.css("z-index"))-1).show()},t.toolbarHandlers={undo:function(){this.cm.undo()},redo:function(){this.cm.redo()},bold:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("**"+i+"**"),""===i&&e.setCursor(t.line,t.ch+2)},del:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("~~"+i+"~~"),""===i&&e.setCursor(t.line,t.ch+2)},italic:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("*"+i+"*"),""===i&&e.setCursor(t.line,t.ch+1)},quote:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("> "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("> "+i)},ucfirst:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.firstUpperCase(i)),e.setSelections(o)},ucwords:function(){var e=this.cm,i=e.getSelection(),o=e.listSelections();e.replaceSelection(t.wordsFirstUpperCase(i)),e.setSelections(o)},uppercase:function(){var e=this.cm,t=e.getSelection(),i=e.listSelections();e.replaceSelection(t.toUpperCase()),e.setSelections(i)},lowercase:function(){var e=this.cm,t=(e.getCursor(),e.getSelection()),i=e.listSelections();e.replaceSelection(t.toLowerCase()),e.setSelections(i)},h1:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("# "+i),e.setCursor(t.line,t.ch+2)):e.replaceSelection("# "+i)},h2:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0), +e.replaceSelection("## "+i),e.setCursor(t.line,t.ch+3)):e.replaceSelection("## "+i)},h3:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("### "+i),e.setCursor(t.line,t.ch+4)):e.replaceSelection("### "+i)},h4:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("#### "+i),e.setCursor(t.line,t.ch+5)):e.replaceSelection("#### "+i)},h5:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("##### "+i),e.setCursor(t.line,t.ch+6)):e.replaceSelection("##### "+i)},h6:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();0!==t.ch?(e.setCursor(t.line,0),e.replaceSelection("###### "+i),e.setCursor(t.line,t.ch+7)):e.replaceSelection("###### "+i)},"list-ul":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("- "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":"- "+i[o];e.replaceSelection(i.join("\n"))}},"list-ol":function(){var e=this.cm,t=(e.getCursor(),e.getSelection());if(""===t)e.replaceSelection("1. "+t);else{for(var i=t.split("\n"),o=0,r=i.length;r>o;o++)i[o]=""===i[o]?"":o+1+". "+i[o];e.replaceSelection(i.join("\n"))}},hr:function(){{var e=this.cm,t=e.getCursor();e.getSelection()}e.replaceSelection((0!==t.ch?"\n\n":"\n")+"------------\n\n")},tex:function(){if(!this.settings.tex)return alert("settings.tex === false"),this;var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("$$"+i+"$$"),""===i&&e.setCursor(t.line,t.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)return alert("settings.pageBreak === false"),this;{var e=this.cm;e.getSelection()}e.replaceSelection("\r\n[========]\r\n")},image:function(){this.executePlugin("imageDialog","image-dialog/image-dialog")},code:function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection("`"+i+"`"),""===i&&e.setCursor(t.line,t.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 e=this.cm,i=(e.getSelection(),new Date,this.settings.lang.name),o=t.dateFormat()+" "+t.dateFormat("zh-cn"===i||"zh-tw"===i?"cn-week-day":"week-day");e.replaceSelection(o)},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()}},t.keyMaps={"Ctrl-1":"h1","Ctrl-2":"h2","Ctrl-3":"h3","Ctrl-4":"h4","Ctrl-5":"h5","Ctrl-6":"h6","Ctrl-B":"bold","Ctrl-D":"datetime","Ctrl-E":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.emoji?(e.replaceSelection(":"+i+":"),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.emoji == false")},"Ctrl-Alt-G":"goto-line","Ctrl-H":"hr","Ctrl-I":"italic","Ctrl-K":"code","Ctrl-L":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.ch+1)},"Ctrl-U":"list-ul","Shift-Ctrl-A":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();return this.settings.atLink?(e.replaceSelection("@"+i),void(""===i&&e.setCursor(t.line,t.ch+1))):void alert("Error: settings.atLink == false")},"Shift-Ctrl-C":"code","Shift-Ctrl-Q":"quote","Shift-Ctrl-S":"del","Shift-Ctrl-K":"tex","Shift-Alt-C":function(){var e=this.cm,t=e.getCursor(),i=e.getSelection();e.replaceSelection(["```",i,"```"].join("\n")),""===i&&e.setCursor(t.line,t.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 e=this.cm,t=e.getCursor(),i=e.getSelection(),o=""===i?"":' "'+i+'"';e.replaceSelection("!["+i+"]("+o+")"),""===i&&e.setCursor(t.line,t.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"};var r=function(e){return String.prototype.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"")};t.trim=r;var n=function(e){return e.toLowerCase().replace(/\b(\w)|\s(\w)/g,function(e){return e.toUpperCase()})};t.ucwords=t.wordsFirstUpperCase=n;var a=function(e){return e.toLowerCase().replace(/\b(\w)/,function(e){return e.toUpperCase()})};return t.firstUpperCase=t.ucfirst=a,t.urls={atLinkBase:"https://github.com/"},t.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,}\]$/},t.emoji={path:"http://www.emoji-cheat-sheet.com/graphics/emojis/",ext:".png"},t.twemoji={path:"http://twemoji.maxcdn.com/36x36/",ext:".png"},t.markedRenderer=function(i,o){var n={toc:!0,tocm:!1,tocStartLevel:1,pageBreak:!0,atLink:!0,emailLink:!0,taskList:!1,emoji:!1,tex:!1,flowChart:!1,sequenceDiagram:!1},a=e.extend(n,o||{}),s=t.$marked,l=new s.Renderer;i=i||[];var c=t.regexs,h=c.atLink,d=c.emoji,u=c.email,f=c.emailLink,g=c.twemoji,p=c.fontAwesome,m=c.editormdLogo,w=c.pageBreak;return l.emoji=function(e){e=e.replace(t.regexs.emojiDatetime,function(e){return e.replace(/:/g,":")});var i=e.match(d);if(!i||!a.emoji)return e;for(var o=0,r=i.length;r>o;o++)":+1:"===i[o]&&(i[o]=":\\+1:"),e=e.replace(new RegExp(i[o]),function(e,i){var o=e.match(p),r=e.replace(/:/g,"");if(o)for(var n=0,a=o.length;a>n;n++){var s=o[n].replace(/:/g,"");return''}else{var l=e.match(m),c=e.match(g);if(l)for(var h=0,d=l.length;d>h;h++){var u=l[h].replace(/:/g,"");return''}else{if(!c){var f="+1"===r?"plus1":r;return f="black_large_square"===f?"black_square":f,f="moon"===f?"waxing_gibbous_moon":f,':'+r+':'}for(var w=0,v=c.length;v>w;w++){var k=c[w].replace(/:/g,"").replace("tw-","");return'twemoji-'+k+''}}}});return e},l.atLink=function(i){return h.test(i)?(a.atLink&&(i=i.replace(u,function(e,t,i,o){return e.replace(/@/g,"_#_@_#_")}),i=i.replace(h,function(e,i){return''+e+""}).replace(/_#_@_#_/g,"@")),a.emailLink&&(i=i.replace(f,function(t,i,o,r,n){return!i&&e.inArray(n,"jpg|jpeg|png|gif|webp|ico|icon|pdf".split("|"))<0?''+t+"":t})),i):i},l.link=function(e,t,i){if(this.options.sanitize){try{var o=decodeURIComponent(unescape(e)).replace(/[^\w:]/g,"").toLowerCase()}catch(r){return""}if(0===o.indexOf("javascript:"))return""}var n=''+i.replace(/@/g,"@")+""):(t&&(n+=' title="'+t+'"'),n+=">"+i+"")},l.heading=function(e,t,o){var n=e,a=/\s*\]*)\>(.*)\<\/a\>\s*/;if(a.test(e)){var s=[];e=e.split(/\]+)\>([^\>]*)\<\/a\>/);for(var l=0,c=e.length;c>l;l++)s.push(e[l].replace(/\s*href\=\"(.*)\"\s*/g,""));e=s.join(" ")}e=r(e);var h=e.toLowerCase().replace(/[^\w]+/g,"-"),d={text:e,level:t,slug:h},u=/^[\u4e00-\u9fa5]+$/.test(e),f=u?escape(e).replace(/\%/g,""):e.toLowerCase().replace(/[^\w]+/g,"-");i.push(d);var g="';return g+='',g+='',g+=this.atLink(a?this.emoji(n):this.emoji(e)),g+=""},l.pageBreak=function(e){return w.test(e)&&a.pageBreak&&(e='
                  '),e},l.paragraph=function(e){var i=/\$\$(.*)\$\$/g.test(e),o=/^\$\$(.*)\$\$$/.test(e),r=o?' class="'+t.classNames.tex+'"':"",n=a.tocm?/^(\[TOC\]|\[TOCM\])$/.test(e):/^\[TOC\]$/.test(e),s=/^\[TOCM\]$/.test(e);e=!o&&i?e.replace(/(\$\$([^\$]*)\$\$)+/g,function(e,i){return''+i.replace(/\$/g,"")+""}):o?e.replace(/\$/g,""):e;var l='
                  '+e+"
                  ";return n?s?'
                  '+l+"

                  ":l:w.test(e)?this.pageBreak(e):""+this.atLink(this.emoji(e))+"

                  \n"},l.code=function(e,i,o){return"seq"===i||"sequence"===i?'
                  '+e+"
                  ":"flow"===i?'
                  '+e+"
                  ":"math"===i||"latex"===i||"katex"===i?'

                  '+e+"

                  ":s.Renderer.prototype.code.apply(this,arguments)},l.tablecell=function(e,t){var i=t.header?"th":"td",o=t.align?"<"+i+' style="text-align:'+t.align+'">':"<"+i+">";return o+this.atLink(this.emoji(e))+"\n"},l.listitem=function(e){return a.taskList&&/^\s*\[[x\s]\]\s*/.test(e)?(e=e.replace(/^\s*\[\s\]\s*/,' ').replace(/^\s*\[x\]\s*/,' '),'
                • '+this.atLink(this.emoji(e))+"
                • "):"
                • "+this.atLink(this.emoji(e))+"
                • "},l},t.markdownToCRenderer=function(e,t,i,o){var r="",n=0,a=this.classPrefix;o=o||1;for(var s=0,l=e.length;l>s;s++){var c=e[s].text,h=e[s].level;o>h||(r+=h>n?"":n>h?new Array(n-h+2).join("
              • "):"",r+='
              • '+c+"