├── .babelrc ├── .circleci └── config.yml ├── .dockerignore ├── .editorconfig ├── .eslintrc ├── .gitignore ├── .nsprc ├── .prettierignore ├── .prettierrc ├── .storybook ├── addons.js ├── config.js ├── decorators │ └── index.js └── webpack.config.js ├── .well-known └── assetlinks.json ├── CONTRIBUTING.md ├── Dockerfile ├── Makefile ├── README.md ├── Vagrantfile ├── api_mockdata ├── get_content.js ├── get_content_empty.js ├── get_state.js └── get_state_empty.js ├── blackboxtest ├── Dockerfile ├── nightwatch-tests │ ├── homepage.js │ └── ssr.js ├── nightwatch.json ├── package.json └── yarn.lock ├── component_counter.sh ├── config ├── custom-environment-variables.json ├── default.json ├── development.json └── production.json ├── doc ├── CONTRIBUTORS.md └── LICENSE.md ├── grep ├── mocha.setup.js ├── package-lock.json ├── package.json ├── scripts └── check_translations.js ├── src ├── __mocks__ │ └── fileMock.js ├── app │ ├── Main.js │ ├── ResolveRoute.js │ ├── ResolveRoute.test.js │ ├── RootRoute.js │ ├── Translator.js │ ├── assets │ │ ├── ads.txt │ │ ├── fonts │ │ │ ├── Roboto-Bold.ttf │ │ │ ├── Roboto-Regular.ttf │ │ │ └── RobotoMono-Regular.ttf │ │ ├── icons │ │ │ ├── 100.svg │ │ │ ├── account-group.svg │ │ │ ├── account-heart.svg │ │ │ ├── account-settings-variant.svg │ │ │ ├── bitcoin.svg │ │ │ ├── bitshares.svg │ │ │ ├── calendar.svg │ │ │ ├── chain.svg │ │ │ ├── chatbox.svg │ │ │ ├── chatboxes.svg │ │ │ ├── chevron-down-circle.svg │ │ │ ├── chevron-left.svg │ │ │ ├── chevron-up-circle.svg │ │ │ ├── clock.svg │ │ │ ├── close.svg │ │ │ ├── cog.svg │ │ │ ├── communities.svg │ │ │ ├── compass-outline.svg │ │ │ ├── currency-usd.svg │ │ │ ├── dropdown-arrow.svg │ │ │ ├── empty.svg │ │ │ ├── enter.svg │ │ │ ├── ether.svg │ │ │ ├── extlink.svg │ │ │ ├── eye.svg │ │ │ ├── facebook.svg │ │ │ ├── flag1.svg │ │ │ ├── flag2.svg │ │ │ ├── home.svg │ │ │ ├── key.svg │ │ │ ├── library-books.svg │ │ │ ├── line.svg │ │ │ ├── link.svg │ │ │ ├── linkedin.svg │ │ │ ├── location.svg │ │ │ ├── logo.svg │ │ │ ├── logotype.svg │ │ │ ├── menu.svg │ │ │ ├── pencil.svg │ │ │ ├── pencil2.svg │ │ │ ├── person.svg │ │ │ ├── photo.svg │ │ │ ├── pin-disabled.svg │ │ │ ├── pin.svg │ │ │ ├── printer.svg │ │ │ ├── profile.svg │ │ │ ├── quill.svg │ │ │ ├── reblog.svg │ │ │ ├── reddit.svg │ │ │ ├── replies.svg │ │ │ ├── reply.svg │ │ │ ├── search.svg │ │ │ ├── share.svg │ │ │ ├── steem.svg │ │ │ ├── steemd.svg │ │ │ ├── steemdb.svg │ │ │ ├── steempower.svg │ │ │ ├── twitter.svg │ │ │ ├── user.svg │ │ │ ├── video.svg │ │ │ ├── voter.svg │ │ │ ├── voters.svg │ │ │ ├── wallet.svg │ │ │ ├── wallet_2.svg │ │ │ ├── zoom-in.svg │ │ │ ├── zoom-out.svg │ │ │ └── zoom-reset.svg │ │ ├── images │ │ │ ├── 404.svg │ │ │ ├── 500.jpg │ │ │ ├── about │ │ │ │ ├── About-hero-small.jpg │ │ │ │ ├── coin.jpg │ │ │ │ ├── conf.jpg │ │ │ │ ├── mission.jpg │ │ │ │ ├── priorities.jpg │ │ │ │ ├── talk.jpg │ │ │ │ ├── values.jpg │ │ │ │ ├── vision.jpg │ │ │ │ ├── x-dev-priorities.jpg │ │ │ │ ├── x-mission.jpg │ │ │ │ └── xx-values.jpg │ │ │ ├── dlive.png │ │ │ ├── facebook.svg │ │ │ ├── favicon.ico │ │ │ ├── favicons │ │ │ │ ├── android-chrome-144x144.png │ │ │ │ ├── android-chrome-192x192.png │ │ │ │ ├── android-chrome-36x36.png │ │ │ │ ├── android-chrome-48x48.png │ │ │ │ ├── android-chrome-72x72.png │ │ │ │ ├── android-chrome-96x96.png │ │ │ │ ├── apple-touch-icon-114x114.png │ │ │ │ ├── apple-touch-icon-120x120.png │ │ │ │ ├── apple-touch-icon-144x144.png │ │ │ │ ├── apple-touch-icon-152x152.png │ │ │ │ ├── apple-touch-icon-180x180.png │ │ │ │ ├── apple-touch-icon-57x57.png │ │ │ │ ├── apple-touch-icon-60x60.png │ │ │ │ ├── apple-touch-icon-72x72.png │ │ │ │ ├── apple-touch-icon-76x76.png │ │ │ │ ├── apple-touch-icon.png │ │ │ │ ├── browserconfig.xml │ │ │ │ ├── chrome-web-store-128x128.png │ │ │ │ ├── favicon-128.png │ │ │ │ ├── favicon-144x144.png │ │ │ │ ├── favicon-16x16.png │ │ │ │ ├── favicon-196x196.png │ │ │ │ ├── favicon-24x24.png │ │ │ │ ├── favicon-32x32.png │ │ │ │ ├── favicon-64x64.png │ │ │ │ ├── favicon-72x72.png │ │ │ │ ├── favicon-96x96.png │ │ │ │ ├── favicon.ico │ │ │ │ ├── manifest.json │ │ │ │ ├── mstile-144x144.png │ │ │ │ ├── mstile-150x150.png │ │ │ │ ├── mstile-310x150.png │ │ │ │ ├── mstile-310x310.png │ │ │ │ ├── mstile-70x70.png │ │ │ │ └── opera-speed-dial-195x195.png │ │ │ ├── justswap-sider.png │ │ │ ├── justswap.png │ │ │ ├── loading.gif │ │ │ ├── lp-bottom.jpg │ │ │ ├── pdf-logo.svg │ │ │ ├── poloniex.png │ │ │ ├── qrcode.png │ │ │ ├── reddit.svg │ │ │ ├── steemit-1024x1024.png │ │ │ ├── steemit-halloween.png │ │ │ ├── steemit-share.png │ │ │ ├── steemit-twshare-2.png │ │ │ ├── steemit-twshare.png │ │ │ ├── steemit.png │ │ │ ├── steemit.svg │ │ │ ├── tron-steem-240_240.png │ │ │ ├── user-static.png │ │ │ ├── user.png │ │ │ └── welcome-hero.png │ │ ├── js │ │ │ ├── editormd.js │ │ │ ├── editormd.min.js │ │ │ ├── jquery-3.6.0.min.js │ │ │ ├── jquery-3.6.0.min.map │ │ │ ├── tron-ads-sdk-1.0.49.js │ │ │ └── zepto.min.js │ │ ├── plugins │ │ │ └── editor.md │ │ │ │ ├── .gitignore │ │ │ │ ├── .jshintrc │ │ │ │ ├── BUGS.md │ │ │ │ ├── CHANGE.md │ │ │ │ ├── Gulpfile.js │ │ │ │ ├── LICENSE │ │ │ │ ├── README.md │ │ │ │ ├── bower.json │ │ │ │ ├── css │ │ │ │ ├── editormd.css │ │ │ │ ├── editormd.logo.css │ │ │ │ ├── editormd.logo.min.css │ │ │ │ ├── editormd.min.css │ │ │ │ ├── editormd.preview.css │ │ │ │ └── editormd.preview.min.css │ │ │ │ ├── editormd.amd.js │ │ │ │ ├── editormd.amd.min.js │ │ │ │ ├── editormd.js │ │ │ │ ├── editormd.min.js │ │ │ │ ├── fonts │ │ │ │ ├── FontAwesome.otf │ │ │ │ ├── editormd-logo.eot │ │ │ │ ├── editormd-logo.svg │ │ │ │ ├── editormd-logo.ttf │ │ │ │ ├── editormd-logo.woff │ │ │ │ ├── fontawesome-webfont.eot │ │ │ │ ├── fontawesome-webfont.svg │ │ │ │ ├── fontawesome-webfont.ttf │ │ │ │ ├── fontawesome-webfont.woff │ │ │ │ └── fontawesome-webfont.woff2 │ │ │ │ ├── images │ │ │ │ ├── loading.gif │ │ │ │ ├── loading@2x.gif │ │ │ │ ├── loading@3x.gif │ │ │ │ └── logos │ │ │ │ │ ├── editormd-favicon-16x16.ico │ │ │ │ │ ├── editormd-favicon-24x24.ico │ │ │ │ │ ├── editormd-favicon-32x32.ico │ │ │ │ │ ├── editormd-favicon-48x48.ico │ │ │ │ │ ├── editormd-favicon-64x64.ico │ │ │ │ │ ├── editormd-logo-114x114.png │ │ │ │ │ ├── editormd-logo-120x120.png │ │ │ │ │ ├── editormd-logo-144x144.png │ │ │ │ │ ├── editormd-logo-16x16.png │ │ │ │ │ ├── editormd-logo-180x180.png │ │ │ │ │ ├── editormd-logo-240x240.png │ │ │ │ │ ├── editormd-logo-24x24.png │ │ │ │ │ ├── editormd-logo-320x320.png │ │ │ │ │ ├── editormd-logo-32x32.png │ │ │ │ │ ├── editormd-logo-48x48.png │ │ │ │ │ ├── editormd-logo-57x57.png │ │ │ │ │ ├── editormd-logo-64x64.png │ │ │ │ │ ├── editormd-logo-72x72.png │ │ │ │ │ ├── editormd-logo-96x96.png │ │ │ │ │ └── vi.png │ │ │ │ ├── languages │ │ │ │ ├── en.js │ │ │ │ └── zh-tw.js │ │ │ │ ├── lib │ │ │ │ ├── codemirror │ │ │ │ │ ├── AUTHORS │ │ │ │ │ ├── LICENSE │ │ │ │ │ ├── README.md │ │ │ │ │ ├── addon │ │ │ │ │ │ ├── comment │ │ │ │ │ │ │ ├── comment.js │ │ │ │ │ │ │ └── continuecomment.js │ │ │ │ │ │ ├── dialog │ │ │ │ │ │ │ ├── dialog.css │ │ │ │ │ │ │ └── dialog.js │ │ │ │ │ │ ├── display │ │ │ │ │ │ │ ├── fullscreen.css │ │ │ │ │ │ │ ├── fullscreen.js │ │ │ │ │ │ │ ├── panel.js │ │ │ │ │ │ │ ├── placeholder.js │ │ │ │ │ │ │ └── rulers.js │ │ │ │ │ │ ├── edit │ │ │ │ │ │ │ ├── closebrackets.js │ │ │ │ │ │ │ ├── closetag.js │ │ │ │ │ │ │ ├── continuelist.js │ │ │ │ │ │ │ ├── matchbrackets.js │ │ │ │ │ │ │ ├── matchtags.js │ │ │ │ │ │ │ └── trailingspace.js │ │ │ │ │ │ ├── fold │ │ │ │ │ │ │ ├── brace-fold.js │ │ │ │ │ │ │ ├── comment-fold.js │ │ │ │ │ │ │ ├── foldcode.js │ │ │ │ │ │ │ ├── foldgutter.css │ │ │ │ │ │ │ ├── foldgutter.js │ │ │ │ │ │ │ ├── indent-fold.js │ │ │ │ │ │ │ ├── markdown-fold.js │ │ │ │ │ │ │ └── xml-fold.js │ │ │ │ │ │ ├── hint │ │ │ │ │ │ │ ├── anyword-hint.js │ │ │ │ │ │ │ ├── css-hint.js │ │ │ │ │ │ │ ├── html-hint.js │ │ │ │ │ │ │ ├── javascript-hint.js │ │ │ │ │ │ │ ├── show-hint.css │ │ │ │ │ │ │ ├── show-hint.js │ │ │ │ │ │ │ ├── sql-hint.js │ │ │ │ │ │ │ └── xml-hint.js │ │ │ │ │ │ ├── lint │ │ │ │ │ │ │ ├── coffeescript-lint.js │ │ │ │ │ │ │ ├── css-lint.js │ │ │ │ │ │ │ ├── javascript-lint.js │ │ │ │ │ │ │ ├── json-lint.js │ │ │ │ │ │ │ ├── lint.css │ │ │ │ │ │ │ ├── lint.js │ │ │ │ │ │ │ └── yaml-lint.js │ │ │ │ │ │ ├── merge │ │ │ │ │ │ │ ├── merge.css │ │ │ │ │ │ │ └── merge.js │ │ │ │ │ │ ├── mode │ │ │ │ │ │ │ ├── loadmode.js │ │ │ │ │ │ │ ├── multiplex.js │ │ │ │ │ │ │ ├── multiplex_test.js │ │ │ │ │ │ │ ├── overlay.js │ │ │ │ │ │ │ └── simple.js │ │ │ │ │ │ ├── runmode │ │ │ │ │ │ │ ├── colorize.js │ │ │ │ │ │ │ ├── runmode-standalone.js │ │ │ │ │ │ │ ├── runmode.js │ │ │ │ │ │ │ └── runmode.node.js │ │ │ │ │ │ ├── scroll │ │ │ │ │ │ │ ├── annotatescrollbar.js │ │ │ │ │ │ │ ├── scrollpastend.js │ │ │ │ │ │ │ ├── simplescrollbars.css │ │ │ │ │ │ │ └── simplescrollbars.js │ │ │ │ │ │ ├── search │ │ │ │ │ │ │ ├── match-highlighter.js │ │ │ │ │ │ │ ├── matchesonscrollbar.css │ │ │ │ │ │ │ ├── matchesonscrollbar.js │ │ │ │ │ │ │ ├── search.js │ │ │ │ │ │ │ └── searchcursor.js │ │ │ │ │ │ ├── selection │ │ │ │ │ │ │ ├── active-line.js │ │ │ │ │ │ │ ├── mark-selection.js │ │ │ │ │ │ │ └── selection-pointer.js │ │ │ │ │ │ ├── tern │ │ │ │ │ │ │ ├── tern.css │ │ │ │ │ │ │ ├── tern.js │ │ │ │ │ │ │ └── worker.js │ │ │ │ │ │ └── wrap │ │ │ │ │ │ │ └── hardwrap.js │ │ │ │ │ ├── addons.min.js │ │ │ │ │ ├── bower.json │ │ │ │ │ ├── codemirror.min.css │ │ │ │ │ ├── codemirror.min.js │ │ │ │ │ ├── mode │ │ │ │ │ │ ├── apl │ │ │ │ │ │ │ ├── apl.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── asterisk │ │ │ │ │ │ │ ├── asterisk.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── clike │ │ │ │ │ │ │ ├── clike.js │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── scala.html │ │ │ │ │ │ ├── clojure │ │ │ │ │ │ │ ├── clojure.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── cobol │ │ │ │ │ │ │ ├── cobol.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── coffeescript │ │ │ │ │ │ │ ├── coffeescript.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── commonlisp │ │ │ │ │ │ │ ├── commonlisp.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── css │ │ │ │ │ │ │ ├── css.js │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── less.html │ │ │ │ │ │ │ ├── less_test.js │ │ │ │ │ │ │ ├── scss.html │ │ │ │ │ │ │ ├── scss_test.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── cypher │ │ │ │ │ │ │ ├── cypher.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── d │ │ │ │ │ │ │ ├── d.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── dart │ │ │ │ │ │ │ ├── dart.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── diff │ │ │ │ │ │ │ ├── diff.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── django │ │ │ │ │ │ │ ├── django.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── dockerfile │ │ │ │ │ │ │ ├── dockerfile.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── dtd │ │ │ │ │ │ │ ├── dtd.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── dylan │ │ │ │ │ │ │ ├── dylan.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── ebnf │ │ │ │ │ │ │ ├── ebnf.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── ecl │ │ │ │ │ │ │ ├── ecl.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── eiffel │ │ │ │ │ │ │ ├── eiffel.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── erlang │ │ │ │ │ │ │ ├── erlang.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── forth │ │ │ │ │ │ │ ├── forth.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── fortran │ │ │ │ │ │ │ ├── fortran.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── gas │ │ │ │ │ │ │ ├── gas.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── gfm │ │ │ │ │ │ │ ├── gfm.js │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── gherkin │ │ │ │ │ │ │ ├── gherkin.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── go │ │ │ │ │ │ │ ├── go.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── groovy │ │ │ │ │ │ │ ├── groovy.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── haml │ │ │ │ │ │ │ ├── haml.js │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── haskell │ │ │ │ │ │ │ ├── haskell.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── haxe │ │ │ │ │ │ │ ├── haxe.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── htmlembedded │ │ │ │ │ │ │ ├── htmlembedded.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── htmlmixed │ │ │ │ │ │ │ ├── htmlmixed.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── http │ │ │ │ │ │ │ ├── http.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── idl │ │ │ │ │ │ │ ├── idl.js │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ ├── jade │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── jade.js │ │ │ │ │ │ ├── javascript │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── javascript.js │ │ │ │ │ │ │ ├── json-ld.html │ │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ │ └── typescript.html │ │ │ │ │ │ ├── jinja2 │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── jinja2.js │ │ │ │ │ │ ├── julia │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── julia.js │ │ │ │ │ │ ├── kotlin │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── kotlin.js │ │ │ │ │ │ ├── livescript │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── livescript.js │ │ │ │ │ │ ├── lua │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── lua.js │ │ │ │ │ │ ├── markdown │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── markdown.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── meta.js │ │ │ │ │ │ ├── mirc │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── mirc.js │ │ │ │ │ │ ├── mllike │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── mllike.js │ │ │ │ │ │ ├── modelica │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── modelica.js │ │ │ │ │ │ ├── nginx │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── nginx.js │ │ │ │ │ │ ├── ntriples │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── ntriples.js │ │ │ │ │ │ ├── octave │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── octave.js │ │ │ │ │ │ ├── pascal │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── pascal.js │ │ │ │ │ │ ├── pegjs │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── pegjs.js │ │ │ │ │ │ ├── perl │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── perl.js │ │ │ │ │ │ ├── php │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── php.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── pig │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── pig.js │ │ │ │ │ │ ├── properties │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── properties.js │ │ │ │ │ │ ├── puppet │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── puppet.js │ │ │ │ │ │ ├── python │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── python.js │ │ │ │ │ │ ├── q │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── q.js │ │ │ │ │ │ ├── r │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── r.js │ │ │ │ │ │ ├── rpm │ │ │ │ │ │ │ ├── changes │ │ │ │ │ │ │ │ └── index.html │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── rpm.js │ │ │ │ │ │ ├── rst │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── rst.js │ │ │ │ │ │ ├── ruby │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── ruby.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── rust │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── rust.js │ │ │ │ │ │ ├── sass │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── sass.js │ │ │ │ │ │ ├── scheme │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── scheme.js │ │ │ │ │ │ ├── shell │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── shell.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── sieve │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── sieve.js │ │ │ │ │ │ ├── slim │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── slim.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── smalltalk │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── smalltalk.js │ │ │ │ │ │ ├── smarty │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── smarty.js │ │ │ │ │ │ ├── smartymixed │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── smartymixed.js │ │ │ │ │ │ ├── solr │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── solr.js │ │ │ │ │ │ ├── soy │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── soy.js │ │ │ │ │ │ ├── sparql │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── sparql.js │ │ │ │ │ │ ├── spreadsheet │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── spreadsheet.js │ │ │ │ │ │ ├── sql │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── sql.js │ │ │ │ │ │ ├── stex │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── stex.js │ │ │ │ │ │ │ └── test.js │ │ │ │ │ │ ├── stylus │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── stylus.js │ │ │ │ │ │ ├── tcl │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── tcl.js │ │ │ │ │ │ ├── textile │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ │ └── textile.js │ │ │ │ │ │ ├── tiddlywiki │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── tiddlywiki.css │ │ │ │ │ │ │ └── tiddlywiki.js │ │ │ │ │ │ ├── tiki │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── tiki.css │ │ │ │ │ │ │ └── tiki.js │ │ │ │ │ │ ├── toml │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── toml.js │ │ │ │ │ │ ├── tornado │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── tornado.js │ │ │ │ │ │ ├── turtle │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── turtle.js │ │ │ │ │ │ ├── vb │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── vb.js │ │ │ │ │ │ ├── vbscript │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── vbscript.js │ │ │ │ │ │ ├── velocity │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── velocity.js │ │ │ │ │ │ ├── verilog │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ │ └── verilog.js │ │ │ │ │ │ ├── xml │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ │ └── xml.js │ │ │ │ │ │ ├── xquery │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ ├── test.js │ │ │ │ │ │ │ └── xquery.js │ │ │ │ │ │ ├── yaml │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── yaml.js │ │ │ │ │ │ └── z80 │ │ │ │ │ │ │ ├── index.html │ │ │ │ │ │ │ └── z80.js │ │ │ │ │ ├── modes.min.js │ │ │ │ │ ├── package.json │ │ │ │ │ └── theme │ │ │ │ │ │ ├── 3024-day.css │ │ │ │ │ │ ├── 3024-night.css │ │ │ │ │ │ ├── ambiance-mobile.css │ │ │ │ │ │ ├── ambiance.css │ │ │ │ │ │ ├── base16-dark.css │ │ │ │ │ │ ├── base16-light.css │ │ │ │ │ │ ├── blackboard.css │ │ │ │ │ │ ├── cobalt.css │ │ │ │ │ │ ├── colorforth.css │ │ │ │ │ │ ├── eclipse.css │ │ │ │ │ │ ├── elegant.css │ │ │ │ │ │ ├── erlang-dark.css │ │ │ │ │ │ ├── lesser-dark.css │ │ │ │ │ │ ├── mbo.css │ │ │ │ │ │ ├── mdn-like.css │ │ │ │ │ │ ├── midnight.css │ │ │ │ │ │ ├── monokai.css │ │ │ │ │ │ ├── neat.css │ │ │ │ │ │ ├── neo.css │ │ │ │ │ │ ├── night.css │ │ │ │ │ │ ├── paraiso-dark.css │ │ │ │ │ │ ├── paraiso-light.css │ │ │ │ │ │ ├── pastel-on-dark.css │ │ │ │ │ │ ├── rubyblue.css │ │ │ │ │ │ ├── solarized.css │ │ │ │ │ │ ├── the-matrix.css │ │ │ │ │ │ ├── tomorrow-night-bright.css │ │ │ │ │ │ ├── tomorrow-night-eighties.css │ │ │ │ │ │ ├── twilight.css │ │ │ │ │ │ ├── vibrant-ink.css │ │ │ │ │ │ ├── xq-dark.css │ │ │ │ │ │ ├── xq-light.css │ │ │ │ │ │ └── zenburn.css │ │ │ │ ├── flowchart.min.js │ │ │ │ ├── jquery.flowchart.min.js │ │ │ │ ├── marked.min.js │ │ │ │ ├── prettify.min.js │ │ │ │ ├── raphael.min.js │ │ │ │ ├── sequence-diagram.min.js │ │ │ │ └── underscore.min.js │ │ │ │ ├── package.json │ │ │ │ └── plugins │ │ │ │ ├── code-block-dialog │ │ │ │ └── code-block-dialog.js │ │ │ │ ├── emoji-dialog │ │ │ │ ├── emoji-dialog.js │ │ │ │ └── emoji.json │ │ │ │ ├── goto-line-dialog │ │ │ │ └── goto-line-dialog.js │ │ │ │ ├── help-dialog │ │ │ │ ├── help-dialog.js │ │ │ │ └── help.md │ │ │ │ ├── html-entities-dialog │ │ │ │ ├── html-entities-dialog.js │ │ │ │ └── html-entities.json │ │ │ │ ├── image-dialog │ │ │ │ └── image-dialog.js │ │ │ │ ├── link-dialog │ │ │ │ └── link-dialog.js │ │ │ │ ├── plugin-template.js │ │ │ │ ├── preformatted-text-dialog │ │ │ │ └── preformatted-text-dialog.js │ │ │ │ ├── reference-link-dialog │ │ │ │ └── reference-link-dialog.js │ │ │ │ ├── table-dialog │ │ │ │ └── table-dialog.js │ │ │ │ └── test-plugin │ │ │ │ └── test-plugin.js │ │ ├── static │ │ │ ├── Roboto-Bold-normal.js │ │ │ ├── Roboto-Regular-normal.js │ │ │ ├── RobotoMono-Regular-normal.js │ │ │ ├── manifest.json │ │ │ └── search.html │ │ └── stylesheets │ │ │ ├── _animation.scss │ │ │ ├── _layout.scss │ │ │ ├── _themes.scss │ │ │ ├── _variables.scss │ │ │ ├── app.scss │ │ │ ├── fonts.scss │ │ │ ├── forms.scss │ │ │ ├── foundation-overrides.scss │ │ │ ├── foundation-settings.scss │ │ │ ├── markdown.scss │ │ │ └── mixins.scss │ ├── client_config.js │ ├── components │ │ ├── App.jsx │ │ ├── App.scss │ │ ├── all.scss │ │ ├── cards │ │ │ ├── BeneficiarySelector.jsx │ │ │ ├── BeneficiarySelector.scss │ │ │ ├── BeneficiarySelector.test.jsx │ │ │ ├── Comment.jsx │ │ │ ├── Comment.scss │ │ │ ├── DraftSummary.jsx │ │ │ ├── DraftSummary.scss │ │ │ ├── MarkdownViewer.jsx │ │ │ ├── MarkdownViewer.scss │ │ │ ├── NotificationsList.jsx │ │ │ ├── NotificationsList.scss │ │ │ ├── PostFull.jsx │ │ │ ├── PostFull.scss │ │ │ ├── PostSummary.jsx │ │ │ ├── PostSummary.scss │ │ │ ├── PostsList.jsx │ │ │ ├── PostsList.scss │ │ │ ├── PrimaryNavigation.jsx │ │ │ ├── PrimaryNavigation.scss │ │ │ ├── SearchUserList.jsx │ │ │ ├── SearchUserList.scss │ │ │ ├── SubscriptionsList.jsx │ │ │ ├── TagInput.jsx │ │ │ ├── UserListRow.jsx │ │ │ └── UserProfileHeader.jsx │ │ ├── elements │ │ │ ├── Ad.scss │ │ │ ├── AdSwipe.jsx │ │ │ ├── Announcement.jsx │ │ │ ├── Author │ │ │ │ ├── Author.story.jsx │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── spec.js.snap │ │ │ │ ├── index.jsx │ │ │ │ ├── spec.js │ │ │ │ └── styles.scss │ │ │ ├── AuthorDropdown.jsx │ │ │ ├── AuthorDropdown.scss │ │ │ ├── AutocompleteInput.jsx │ │ │ ├── BiddingAd.jsx │ │ │ ├── Callout.jsx │ │ │ ├── Callout.story.jsx │ │ │ ├── CheckLoginOwner.jsx │ │ │ ├── ClaimBox.jsx │ │ │ ├── CloseButton.jsx │ │ │ ├── CommunityBanner.jsx │ │ │ ├── CommunityBanner.scss │ │ │ ├── CommunityPane.jsx │ │ │ ├── CommunityPaneMobile.jsx │ │ │ ├── ContentEditedWrapper │ │ │ │ ├── index.jsx │ │ │ │ └── story.jsx │ │ │ ├── DateJoinWrapper.jsx │ │ │ ├── Dropdown.jsx │ │ │ ├── Dropdown.scss │ │ │ ├── DropdownMenu.jsx │ │ │ ├── DropdownMenu.scss │ │ │ ├── DropdownMenu.story.jsx │ │ │ ├── Editor │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── ElasticSearchInput │ │ │ │ ├── SearchHistory.jsx │ │ │ │ ├── SearchHistory.scss │ │ │ │ ├── SearchInput.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── FlagButton.jsx │ │ │ ├── FlagButton.scss │ │ │ ├── Follow │ │ │ │ ├── Follow.story.jsx │ │ │ │ ├── __snapshots__ │ │ │ │ │ └── spec.js.snap │ │ │ │ ├── index.jsx │ │ │ │ └── spec.js │ │ │ ├── FormattedAsset.jsx │ │ │ ├── FormattedAsset.scss │ │ │ ├── GoogleAd.jsx │ │ │ ├── GoogleAd.scss │ │ │ ├── GptAd.jsx │ │ │ ├── GptAd.scss │ │ │ ├── HelpContent.jsx │ │ │ ├── Icon.jsx │ │ │ ├── Icon.scss │ │ │ ├── Icon.story.jsx │ │ │ ├── IconButton │ │ │ │ ├── IconButton.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── Link.js │ │ │ ├── LoadingIndicator.jsx │ │ │ ├── LoadingIndicator.scss │ │ │ ├── LoadingIndicator.story.jsx │ │ │ ├── Memo │ │ │ │ ├── Memo.test.jsx │ │ │ │ └── index.jsx │ │ │ ├── MuteButton.jsx │ │ │ ├── MuteList.jsx │ │ │ ├── NativeSelect │ │ │ │ ├── NativeSelect.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── Notices.jsx │ │ │ ├── Notices.scss │ │ │ ├── PageViewsCounter.jsx │ │ │ ├── PdfDownload.jsx │ │ │ ├── PostCategoryBanner.jsx │ │ │ ├── PostCategoryBanner.scss │ │ │ ├── QrReader.jsx │ │ │ ├── Reblog.jsx │ │ │ ├── Reblog.scss │ │ │ ├── Reblog.story.jsx │ │ │ ├── ReplyEditor.jsx │ │ │ ├── ReplyEditor.scss │ │ │ ├── ReplyEditorNew.jsx │ │ │ ├── Reputation.jsx │ │ │ ├── Reputation.scss │ │ │ ├── Reputation.story.jsx │ │ │ ├── Reveal.jsx │ │ │ ├── SanitizedLink │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── SearchInput │ │ │ │ ├── SearchInput.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── SearchTabs │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── SettingsEditButton.jsx │ │ │ ├── ShareMenu.jsx │ │ │ ├── ShareMenu.scss │ │ │ ├── SidebarLinks.jsx │ │ │ ├── SidebarNewUsers.jsx │ │ │ ├── SlateEditor.jsx │ │ │ ├── SlateEditor.scss │ │ │ ├── SortOrder │ │ │ │ ├── SortOrder.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── SteemLogo │ │ │ │ ├── SteemLogo.story.jsx │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── SteemMarket.jsx │ │ │ ├── SteemMarket.scss │ │ │ ├── SubscribeButton.jsx │ │ │ ├── SvgImage.jsx │ │ │ ├── SvgImage.story.jsx │ │ │ ├── Tag.jsx │ │ │ ├── TagList.jsx │ │ │ ├── TagList.scss │ │ │ ├── TagList.story.jsx │ │ │ ├── TimeAgoWrapper │ │ │ │ ├── index.jsx │ │ │ │ └── story.jsx │ │ │ ├── Tooltip.jsx │ │ │ ├── Tooltip.story.jsx │ │ │ ├── TronAd.jsx │ │ │ ├── UserList.jsx │ │ │ ├── UserList.scss │ │ │ ├── UserList.story.jsx │ │ │ ├── UserNames.jsx │ │ │ ├── UserNames.scss │ │ │ ├── UserTitle.jsx │ │ │ ├── Userpic.jsx │ │ │ ├── Userpic.scss │ │ │ ├── Userpic.story.jsx │ │ │ ├── VerticalMenu.jsx │ │ │ ├── VerticalMenu.scss │ │ │ ├── VideoAd.jsx │ │ │ ├── VideoAd.scss │ │ │ ├── VotesAndComments.jsx │ │ │ ├── VotesAndComments.scss │ │ │ ├── Voting.jsx │ │ │ ├── Voting.scss │ │ │ ├── Voting.story.jsx │ │ │ ├── Voting.test.jsx │ │ │ ├── WelcomePanel.jsx │ │ │ ├── YoutubePreview.jsx │ │ │ └── YoutubePreview.scss │ │ ├── modules │ │ │ ├── ArticleLayoutSelector.jsx │ │ │ ├── CommunitySettings.jsx │ │ │ ├── CommunitySettings.scss │ │ │ ├── CommunitySubscriberList.jsx │ │ │ ├── ConfirmTransactionForm.jsx │ │ │ ├── ConfirmTransactionForm.scss │ │ │ ├── ConnectedSidePanel │ │ │ │ └── index.jsx │ │ │ ├── Dialogs.jsx │ │ │ ├── ExplorePost.jsx │ │ │ ├── FlagCommunityPost.jsx │ │ │ ├── Header │ │ │ │ ├── Header.test.js │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── LoginForm.jsx │ │ │ ├── LoginForm.scss │ │ │ ├── Modals.jsx │ │ │ ├── Modals_BackUp.jsx │ │ │ ├── MutePost.jsx │ │ │ ├── PostAdvancedSettings.jsx │ │ │ ├── PostDrafts.jsx │ │ │ ├── PostDrafts.scss │ │ │ ├── PostTemplates.jsx │ │ │ ├── PostTemplates.scss │ │ │ ├── PromotePost.jsx │ │ │ ├── Settings.jsx │ │ │ ├── Settings.scss │ │ │ ├── SidePanel │ │ │ │ ├── index.jsx │ │ │ │ └── styles.scss │ │ │ ├── TermsAgree.jsx │ │ │ ├── Transfer.scss │ │ │ ├── UserRole.jsx │ │ │ ├── UserTitleEditor.jsx │ │ │ └── UserWallet.scss │ │ ├── pages │ │ │ ├── About.jsx │ │ │ ├── About.scss │ │ │ ├── Announcement.jsx │ │ │ ├── Announcement.scss │ │ │ ├── Benchmark.jsx │ │ │ ├── CommunitiesIndex.jsx │ │ │ ├── CommunitiesIndex.scss │ │ │ ├── CommunityRoles.jsx │ │ │ ├── CommunityRoles.scss │ │ │ ├── Faq.jsx │ │ │ ├── Index.jsx │ │ │ ├── Login.jsx │ │ │ ├── NotFound.jsx │ │ │ ├── Post.jsx │ │ │ ├── Post.scss │ │ │ ├── PostPage.jsx │ │ │ ├── PostPageNoCategory.jsx │ │ │ ├── PostsIndex.jsx │ │ │ ├── PostsIndex.scss │ │ │ ├── PostsIndexLayout.jsx │ │ │ ├── Privacy.jsx │ │ │ ├── Privacy.scss │ │ │ ├── Rewards.jsx │ │ │ ├── Rewards.scss │ │ │ ├── SearchIndex.jsx │ │ │ ├── SearchIndex.scss │ │ │ ├── SubmitPost.jsx │ │ │ ├── SubmitPostServerRender.jsx │ │ │ ├── Support.jsx │ │ │ ├── TagsIndex.jsx │ │ │ ├── TagsIndex.scss │ │ │ ├── Topics.jsx │ │ │ ├── Topics.scss │ │ │ ├── Tos.jsx │ │ │ ├── Tos.scss │ │ │ ├── UserProfile.jsx │ │ │ ├── UserProfile.scss │ │ │ ├── Welcome.jsx │ │ │ ├── Welcome.scss │ │ │ └── XSS.jsx │ │ └── utils │ │ │ └── ReactMutationObserver.jsx │ ├── help │ │ └── en │ │ │ ├── faq.md │ │ │ ├── tos.md │ │ │ └── welcome.md │ ├── locales │ │ ├── README.md │ │ ├── counterpart │ │ │ ├── es.js │ │ │ ├── fr.js │ │ │ ├── it.js │ │ │ ├── ja.js │ │ │ ├── ko.js │ │ │ ├── pl.js │ │ │ ├── uk.js │ │ │ └── zh.js │ │ ├── en.json │ │ ├── es.json │ │ ├── fr.json │ │ ├── it.json │ │ ├── ja.json │ │ ├── ko.json │ │ ├── normalize.sh │ │ ├── pl.json │ │ ├── ru.json │ │ ├── uk.json │ │ └── zh.json.remove │ ├── redux │ │ ├── AppReducer.js │ │ ├── AppReducer.test.js │ │ ├── AuthSaga.js │ │ ├── CommunityReducer.js │ │ ├── CommunitySaga.js │ │ ├── CommunitySearchReducer.js │ │ ├── CommunitySearchSaga.js │ │ ├── FetchDataSaga.js │ │ ├── FetchDataSaga.test.js │ │ ├── FollowSaga.js │ │ ├── GlobalReducer.js │ │ ├── GlobalReducer.test.js │ │ ├── GlobalSaga.js │ │ ├── OffchainReducer.js │ │ ├── OffchainReducer.test.js │ │ ├── PollingSaga.js │ │ ├── RootReducer.js │ │ ├── SagaShared.js │ │ ├── SearchReducer.js │ │ ├── SearchSaga.js │ │ ├── TransactionReducer.js │ │ ├── TransactionSaga.js │ │ ├── TransactionSaga.test.js │ │ ├── UserProfilesReducer.js │ │ ├── UserProfilesSaga.js │ │ ├── UserReducer.js │ │ ├── UserSaga.js │ │ ├── adReducer.js │ │ ├── constants.js │ │ ├── stateCleaner.js │ │ └── tests │ │ │ ├── global.json │ │ │ └── global.test.js │ └── utils │ │ ├── Accessors.js │ │ ├── ActivityTracker.js │ │ ├── AffiliationMap.js │ │ ├── AppPropTypes.js │ │ ├── BadActorList.js │ │ ├── BrowserTests.js │ │ ├── CanonicalLinker.js │ │ ├── CanonicalLinker.test.js │ │ ├── ChainValidation.js │ │ ├── Common.js │ │ ├── Community.js │ │ ├── ConsoleExports.js │ │ ├── ContentPreview.js │ │ ├── DMCAList.js │ │ ├── DMCAUserList.js │ │ ├── DomUtils.js │ │ ├── ExtractContent.js │ │ ├── ExtractMeta.js │ │ ├── FormatCoins.js │ │ ├── FormatDecimal.test.js │ │ ├── FrontendLogger.js │ │ ├── FrontendLogger.test.js │ │ ├── GDPRUserList.js │ │ ├── GptUtils.js │ │ ├── Html.js │ │ ├── ImageUserBlockList.js │ │ ├── JsPlugins.js │ │ ├── Links.js │ │ ├── Links.test.js │ │ ├── ParsersAndFormatters.js │ │ ├── Phishing.js │ │ ├── ProxifyUrl.js │ │ ├── ProxifyUrl.test.js │ │ ├── RPCNode.js │ │ ├── ReactForm.js │ │ ├── ReduxForms.js │ │ ├── RegisterServiceWorker.js │ │ ├── RemarkablePlugin.js │ │ ├── RemarkableStripper.js │ │ ├── SanitizeConfig.js │ │ ├── ServerApiClient.js │ │ ├── SlateEditor │ │ ├── Align.js │ │ ├── DemoState.js │ │ ├── HRule.js │ │ ├── Helpers.js │ │ ├── Iframe.js │ │ ├── Image.js │ │ ├── Link.js │ │ └── Schema.js │ │ ├── StateFunctions.js │ │ ├── SteemKeychain.js │ │ ├── Unicode.js │ │ ├── UserUtil.js │ │ ├── VerifiedExchangeList.js │ │ ├── __mocks__ │ │ └── GDPRUserList.js │ │ ├── emit.js │ │ ├── shouldComponentUpdate.js │ │ ├── steemApi.js │ │ └── userIllegalContent.js ├── server │ ├── api │ │ └── general.js │ ├── app_render.jsx │ ├── hardwarestats.js │ ├── index.js │ ├── json │ │ ├── post_json.jsx │ │ └── user_json.jsx │ ├── prod_logger.js │ ├── redirects.js │ ├── requesttimings.js │ ├── server-error.jsx │ ├── server-html.jsx │ ├── server.js │ └── utils │ │ ├── RequestTimer.js │ │ ├── SpecialPosts.js │ │ ├── StatsLoggerClient.js │ │ ├── SteemMarket.js │ │ └── misc.js └── shared │ ├── HtmlReady.js │ ├── HtmlReady.test.js │ ├── RootSaga.js │ ├── UniversalRender.jsx │ ├── api_client │ ├── ChainConfig.js │ └── index.js │ ├── clash │ └── object2json.js │ └── constants.js ├── webpack ├── base.config.js ├── debug.config.js ├── dev-server.js ├── dev.config.js ├── prod.config.js ├── storybook.config.js ├── utils │ ├── start-koa.js │ └── write-stats.js └── webpack-isotools-config.js └── yarn.lock /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015", "stage-0", "react"], 3 | "plugins": ["transform-runtime", "transform-decorators-legacy"], 4 | "ignore": [ 5 | "src/app/assets/plugins/**/*.js" 6 | ] 7 | } 8 | -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | tmp 3 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | 9 | # Change these settings to your own preference 10 | indent_style = space 11 | indent_size = 4 12 | 13 | # We recommend you to keep these unchanged 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.md] 20 | trim_trailing_whitespace = false 21 | 22 | [*.json] 23 | indent_size = 2 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .idea 3 | coverage 4 | node_modules 5 | *.log 6 | dist 7 | vendor/* 8 | tmp/* 9 | .vagrant 10 | lib 11 | !src/app/assets/plugins/editor.md/lib 12 | .env 13 | 14 | -------------------------------------------------------------------------------- /.nsprc: -------------------------------------------------------------------------------- 1 | { 2 | "exceptions": ["https://nodesecurity.io/advisories/566"] 3 | } 4 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | src/app/assets/static/jspdf.min.js 2 | src/app/assets/plugins/* 3 | src/app/locales/zh.json.remove -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "tabWidth" : 4, 3 | "singleQuote" : true, 4 | "trailingComma" : "es5" 5 | } 6 | -------------------------------------------------------------------------------- /.storybook/addons.js: -------------------------------------------------------------------------------- 1 | import '@storybook/addon-knobs/register'; 2 | import 'storybook-addon-intl/register'; -------------------------------------------------------------------------------- /.storybook/decorators/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | const container = { 4 | display: 'table', 5 | position: 'absolute', 6 | height: '100%', 7 | width: '100%', 8 | }; 9 | 10 | const middle = { 11 | display: 'table-cell', 12 | verticalAlign: 'middle', 13 | }; 14 | 15 | const center = { 16 | marginLeft: 'auto', 17 | marginRight: 'auto', 18 | //border: 'solid black', 19 | width: '300px', 20 | }; 21 | 22 | export const Center = (storyFn) => ( 23 |
24 |
25 |
{storyFn()}
26 |
27 |
28 | ); 29 | -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | require('babel-register'); 2 | module.exports = require('../webpack/storybook.config.js'); -------------------------------------------------------------------------------- /.well-known/assetlinks.json: -------------------------------------------------------------------------------- 1 | [{ 2 | "relation": ["lookalikes/allowlist"], 3 | "target" : { "namespace": "web", "site": "https://steemit.com"} 4 | },{ 5 | "relation": ["lookalikes/allowlist"], 6 | "target" : { "namespace": "web", "site": "https://steemitwallet.com"} 7 | }] -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:10.0 2 | 3 | ARG SOURCE_COMMIT 4 | ENV SOURCE_COMMIT ${SOURCE_COMMIT} 5 | ARG DOCKER_TAG 6 | ENV DOCKER_TAG ${DOCKER_TAG} 7 | 8 | # yarn > npm 9 | #RUN npm install --global yarn 10 | 11 | RUN npm install -g yarn 12 | 13 | WORKDIR /var/app 14 | RUN mkdir -p /var/app 15 | ADD package.json yarn.lock /var/app/ 16 | RUN chmod +x /usr/local/lib/node_modules/yarn/bin/yarn.js && \ 17 | yarn install --non-interactive --frozen-lockfile 18 | 19 | COPY . /var/app 20 | 21 | # FIXME TODO: fix eslint warnings 22 | 23 | #RUN mkdir tmp && \ 24 | # npm test && \ 25 | # ./node_modules/.bin/eslint . && \ 26 | # npm run build 27 | 28 | RUN mkdir tmp && \ 29 | yarn test && yarn build 30 | 31 | ENV PORT 8080 32 | ENV NODE_ENV production 33 | 34 | EXPOSE 8080 35 | 36 | CMD [ "yarn", "run", "production" ] 37 | 38 | # uncomment the lines below to run it in development mode 39 | # ENV NODE_ENV development 40 | # CMD [ "yarn", "run", "start" ] 41 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: test 2 | 3 | test: node_modules 4 | npm test 5 | 6 | node_modules: 7 | yarn install 8 | 9 | build: 10 | docker build -t steemit/steemit.com . 11 | 12 | clean: 13 | rm -rf node_modules *.log tmp npm-debug.log.* 14 | 15 | vagrant: 16 | vagrant destroy -f 17 | vagrant up 18 | -------------------------------------------------------------------------------- /blackboxtest/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM circleci/openjdk:jdk-node-browsers 2 | 3 | WORKDIR /home/circleci 4 | COPY package.json yarn.lock /home/circleci/ 5 | RUN yarn install --non-interactive --frozen-lockfile 6 | RUN curl -s https://selenium-release.storage.googleapis.com/3.9/selenium-server-standalone-3.9.1.jar > /home/circleci/selenium-server-standalone.jar 7 | RUN curl -s https://chromedriver.storage.googleapis.com/2.36/chromedriver_linux64.zip | funzip > /home/circleci/chromedriver && chmod +x /home/circleci/chromedriver 8 | 9 | COPY . /home/circleci/ 10 | 11 | 12 | CMD [ "yarn", "start" ] 13 | 14 | 15 | -------------------------------------------------------------------------------- /blackboxtest/nightwatch-tests/homepage.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'Ensure homepage loads without strange errors': browser => { 3 | browser 4 | .url('http://localhost:8080') 5 | .pause(300) 6 | //.assert.containsText('h1.articles__h1', 'Trending: All tags') 7 | .assert.containsText('a.Header__login-link', 'Login') 8 | .getLog('browser', function(result) { 9 | this.assert.ok( 10 | reasonableErrorLog(result), 11 | 'error log is reasonable' 12 | ); 13 | }) 14 | .end(); 15 | }, 16 | }; 17 | 18 | function reasonableErrorLog(logs) { 19 | const logsMinusNetworkErrors = logs.filter(log => log.source !== 'network'); 20 | return logsMinusNetworkErrors.length === 0; 21 | } 22 | -------------------------------------------------------------------------------- /blackboxtest/nightwatch.json: -------------------------------------------------------------------------------- 1 | { 2 | "src_folders" : ["./nightwatch-tests"], 3 | "output_folder" : "./nightwatch-reports", 4 | "custom_commands_path" : "", 5 | "custom_assertions_path" : "", 6 | "page_objects_path" : "", 7 | "globals_path" : "", 8 | 9 | "selenium" : { 10 | "start_process" : true, 11 | "server_path" : "./selenium-server-standalone.jar", 12 | "log_path" : "", 13 | "port" : 4444, 14 | "cli_args" : { 15 | "webdriver.chrome.driver" : "./chromedriver" 16 | } 17 | }, 18 | 19 | "test_settings" : { 20 | "default" : { 21 | "launch_url" : "http://localhost", 22 | "selenium_port" : 4444, 23 | "selenium_host" : "localhost", 24 | "silent": true, 25 | "screenshots" : { 26 | "enabled" : false, 27 | "path" : "" 28 | }, 29 | "desiredCapabilities": { 30 | "browserName": "chrome", 31 | "javascriptEnabled": true, 32 | "acceptSslCerts": true 33 | } 34 | }, 35 | 36 | "chrome" : { 37 | "desiredCapabilities": { 38 | "browserName": "chrome", 39 | "javascriptEnabled": true, 40 | "acceptSslCerts": true 41 | } 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /blackboxtest/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "condenser-blackboxtest", 3 | "version": "1.0.0", 4 | "main": false, 5 | "scripts": { 6 | "start": "nightwatch --config nightwatch.json" 7 | }, 8 | "license": "MIT", 9 | "dependencies": { 10 | "nightwatch": "0.9.19", 11 | "phantomjs-prebuilt": "2.1.16" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /component_counter.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | declare -A components 4 | 5 | for file in $1/*.jsx 6 | do 7 | name=${file##*/} 8 | base=${name%.jsx} 9 | cd ./src 10 | count=$(grep -r -o "<$base" | wc -l) 11 | components+=([$base]=$count) 12 | cd ../ 13 | done 14 | 15 | for i in "${!components[@]}" 16 | do 17 | echo "$i: ${components[$i]}" 18 | done | 19 | sort -rn -k2 -------------------------------------------------------------------------------- /doc/CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | This file contains a list of people who have made 2 | large contributions to the Steemit.com codebase. 3 | 4 | 5 | 6 | (not complete) 7 | 8 | 9 | 10 | ## Internationalization 11 | - @Undeadlol1 (Mihail Paley) 12 | - @ekitcho 13 | - @heimindanger 14 | - @fernando-sanz 15 | - @jza 16 | - @cheftony 17 | - @jumpeiyamane 18 | * Japanese 19 | -------------------------------------------------------------------------------- /grep: -------------------------------------------------------------------------------- 1 | grep -rin $1 --color=always --exclude-dir=node_modules --exclude-dir=dist --exclude-dir=tmp * 2 | find src | grep -i $1 3 | -------------------------------------------------------------------------------- /mocha.setup.js: -------------------------------------------------------------------------------- 1 | require('babel-register')(); 2 | 3 | process.env.NODE_PATH = require('path').resolve(__dirname, './src'); 4 | require('module').Module._initPaths(); 5 | 6 | const jsdom = require('jsdom').jsdom; 7 | 8 | const exposedProperties = ['window', 'navigator', 'document']; 9 | 10 | global.document = jsdom(''); 11 | global.window = document.defaultView; 12 | Object.keys(document.defaultView).forEach((property) => { 13 | if (typeof global[property] === 'undefined') { 14 | exposedProperties.push(property); 15 | global[property] = document.defaultView[property]; 16 | } 17 | }); 18 | 19 | global.navigator = { 20 | userAgent: 'node.js' 21 | }; 22 | 23 | documentRef = document; 24 | 25 | function donothing() { 26 | return null; 27 | } 28 | require.extensions['.svg'] = donothing; 29 | require.extensions['.css'] = donothing; 30 | require.extensions['.scss'] = donothing; 31 | -------------------------------------------------------------------------------- /src/__mocks__/fileMock.js: -------------------------------------------------------------------------------- 1 | module.exports = 'test-file-stub'; 2 | -------------------------------------------------------------------------------- /src/app/assets/fonts/Roboto-Bold.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/fonts/Roboto-Bold.ttf -------------------------------------------------------------------------------- /src/app/assets/fonts/Roboto-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/fonts/Roboto-Regular.ttf -------------------------------------------------------------------------------- /src/app/assets/fonts/RobotoMono-Regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/fonts/RobotoMono-Regular.ttf -------------------------------------------------------------------------------- /src/app/assets/icons/account-group.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/account-heart.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/calendar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/assets/icons/chatbox.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/assets/icons/chatboxes.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 9 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /src/app/assets/icons/chevron-down-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/app/assets/icons/chevron-left.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/assets/icons/chevron-up-circle.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/assets/icons/close.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | -------------------------------------------------------------------------------- /src/app/assets/icons/cog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | cog 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/compass-outline.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/currency-usd.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/dropdown-arrow.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/assets/icons/empty.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/app/assets/icons/enter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | enter 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/extlink.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/assets/icons/eye.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/app/assets/icons/facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/flag1.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/app/assets/icons/flag2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/assets/icons/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | home 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/key.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | key 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/library-books.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/line.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/assets/icons/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 11 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/app/assets/icons/location.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/app/assets/icons/menu.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /src/app/assets/icons/pencil.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/app/assets/icons/pencil2.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /src/app/assets/icons/person.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /src/app/assets/icons/photo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/assets/icons/pin-disabled.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/app/assets/icons/pin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/app/assets/icons/printer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/assets/icons/profile.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | profile 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/quill.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | quill 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/reblog.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 8 | 9 | -------------------------------------------------------------------------------- /src/app/assets/icons/replies.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | indent-increase 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/reply.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | reply 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/search.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /src/app/assets/icons/steemd.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 15 | 16 | SD 17 | 18 | -------------------------------------------------------------------------------- /src/app/assets/icons/steemdb.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 12 | 13 | 15 | 16 | SDb 17 | 18 | -------------------------------------------------------------------------------- /src/app/assets/icons/twitter.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/user.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 10 | 11 | -------------------------------------------------------------------------------- /src/app/assets/icons/video.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/icons/voter.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /src/app/assets/icons/wallet.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | wallet 4 | 5 | 6 | -------------------------------------------------------------------------------- /src/app/assets/icons/wallet_2.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/images/500.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/500.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/About-hero-small.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/About-hero-small.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/coin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/coin.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/conf.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/conf.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/mission.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/mission.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/priorities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/priorities.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/talk.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/talk.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/values.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/values.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/vision.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/vision.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/x-dev-priorities.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/x-dev-priorities.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/x-mission.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/x-mission.jpg -------------------------------------------------------------------------------- /src/app/assets/images/about/xx-values.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/about/xx-values.jpg -------------------------------------------------------------------------------- /src/app/assets/images/dlive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/dlive.png -------------------------------------------------------------------------------- /src/app/assets/images/facebook.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/assets/images/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicon.ico -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-144x144.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-192x192.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-36x36.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-36x36.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-48x48.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-72x72.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/android-chrome-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/android-chrome-96x96.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-114x114.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-120x120.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-144x144.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-152x152.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-152x152.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-180x180.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-57x57.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-60x60.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-72x72.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon-76x76.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon-76x76.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #ffffff 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/app/assets/images/favicons/chrome-web-store-128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/chrome-web-store-128x128.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-128.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-144x144.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-196x196.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-196x196.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-24x24.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-64x64.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-72x72.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon-96x96.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/favicon.ico -------------------------------------------------------------------------------- /src/app/assets/images/favicons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Golos", 3 | "icons": [ 4 | { 5 | "src": "/images/favicons/android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image/png" 8 | }, 9 | { 10 | "src": "/images/favicons/android-chrome-512x512.png", 11 | "sizes": "512x512", 12 | "type": "image/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "display": "standalone" 17 | } 18 | -------------------------------------------------------------------------------- /src/app/assets/images/favicons/mstile-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/mstile-144x144.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/mstile-150x150.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/mstile-310x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/mstile-310x150.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/mstile-310x310.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/mstile-310x310.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/mstile-70x70.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/mstile-70x70.png -------------------------------------------------------------------------------- /src/app/assets/images/favicons/opera-speed-dial-195x195.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/favicons/opera-speed-dial-195x195.png -------------------------------------------------------------------------------- /src/app/assets/images/justswap-sider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/justswap-sider.png -------------------------------------------------------------------------------- /src/app/assets/images/justswap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/justswap.png -------------------------------------------------------------------------------- /src/app/assets/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/loading.gif -------------------------------------------------------------------------------- /src/app/assets/images/lp-bottom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/lp-bottom.jpg -------------------------------------------------------------------------------- /src/app/assets/images/poloniex.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/poloniex.png -------------------------------------------------------------------------------- /src/app/assets/images/qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/qrcode.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit-1024x1024.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit-1024x1024.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit-halloween.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit-halloween.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit-share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit-share.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit-twshare-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit-twshare-2.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit-twshare.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit-twshare.png -------------------------------------------------------------------------------- /src/app/assets/images/steemit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/steemit.png -------------------------------------------------------------------------------- /src/app/assets/images/tron-steem-240_240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/tron-steem-240_240.png -------------------------------------------------------------------------------- /src/app/assets/images/user-static.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/user-static.png -------------------------------------------------------------------------------- /src/app/assets/images/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/user.png -------------------------------------------------------------------------------- /src/app/assets/images/welcome-hero.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/images/welcome-hero.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/.gitignore: -------------------------------------------------------------------------------- 1 | logs 2 | *.log 3 | *.pid 4 | *.seed 5 | node_modules/ 6 | .sass-cache/ 7 | research/ 8 | test/ 9 | backup/ 10 | examples/uploads/**/* 11 | *.bat 12 | *.sh 13 | .project 14 | .url 15 | css/*.map -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "bitwise": true, 4 | "camelcase": true, 5 | "curly": true, 6 | "eqeqeq": true, 7 | "immed": true, 8 | "indent": 4, 9 | "latedef": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "quotmark": "double", 13 | "regexp": true, 14 | "undef": true, 15 | "unused": true, 16 | "strict": true, 17 | "trailing": true, 18 | "smarttabs": true, 19 | "white": true 20 | } 21 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/BUGS.md: -------------------------------------------------------------------------------- 1 | #Bugs 2 | 3 | > 说明:删除线表示已经解决。 4 | 5 | ####IE8 6 | 7 | - ~~不能加载;~~ 8 | - flowChart(流程图)、sequenceDiagram(序列图)不支持IE8; 9 | - ~~不支持Markdown转HTML页面解析预览;~~ 10 | 11 | ####IE8 & IE9 & IE10 12 | 13 | - KaTeX会出现解析错误,但不影响程序运行; 14 | 15 | ####Sea.js 16 | 17 | - ~~Raphael.js无法加载;~~ 18 | 19 | ####Require.js 20 | 21 | - ~~CodeMirror编辑器的代码无法高亮;~~ 22 | - ~~sequenceDiagram不支持: `Uncaught TypeError: Cannot call method 'isArray' of undefined.`~~ 23 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 pandao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "editor.md", 3 | "version": "1.5.0", 4 | "homepage": "https://github.com/pandao/editor.md", 5 | "authors": ["Pandao "], 6 | "description": "Open source online markdown editor.", 7 | "keywords": ["editor.md", "markdown", "editor"], 8 | "license": "MIT", 9 | "ignore": [ 10 | "**/.*", 11 | "research", 12 | "docs", 13 | "node_modules", 14 | "bower_components", 15 | "test", 16 | "tests" 17 | ] 18 | } 19 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/editormd-logo.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/editormd-logo.eot -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/editormd-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Generated by IcoMoon 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/editormd-logo.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/editormd-logo.ttf -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/editormd-logo.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/editormd-logo.woff -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/fonts/fontawesome-webfont.woff2 -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/loading.gif -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/loading@2x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/loading@2x.gif -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/loading@3x.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/loading@3x.gif -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-favicon-16x16.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-favicon-16x16.ico -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-favicon-24x24.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-favicon-24x24.ico -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-favicon-32x32.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-favicon-32x32.ico -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-favicon-48x48.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-favicon-48x48.ico -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-favicon-64x64.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-favicon-64x64.ico -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-114x114.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-114x114.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-120x120.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-120x120.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-144x144.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-144x144.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-16x16.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-180x180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-180x180.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-240x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-240x240.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-24x24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-24x24.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-320x320.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-320x320.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-32x32.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-48x48.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-57x57.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-57x57.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-64x64.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-72x72.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-72x72.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/editormd-logo-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/editormd-logo-96x96.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/images/logos/vi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/plugins/editor.md/images/logos/vi.png -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2014 by Marijn Haverbeke and others 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/README.md: -------------------------------------------------------------------------------- 1 | # CodeMirror 2 | [![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror) 3 | [![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror) 4 | [Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png)](https://marijnhaverbeke.nl/fund/) 5 | 6 | CodeMirror is a JavaScript component that provides a code editor in 7 | the browser. When a mode is available for the language you are coding 8 | in, it will color your code, and optionally help with indentation. 9 | 10 | The project page is http://codemirror.net 11 | The manual is at http://codemirror.net/doc/manual.html 12 | The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md) 13 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/dialog/dialog.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-dialog { 2 | position: absolute; 3 | left: 0; right: 0; 4 | background: white; 5 | z-index: 15; 6 | padding: .1em .8em; 7 | overflow: hidden; 8 | color: #333; 9 | } 10 | 11 | .CodeMirror-dialog-top { 12 | border-bottom: 1px solid #eee; 13 | top: 0; 14 | } 15 | 16 | .CodeMirror-dialog-bottom { 17 | border-top: 1px solid #eee; 18 | bottom: 0; 19 | } 20 | 21 | .CodeMirror-dialog input { 22 | border: none; 23 | outline: none; 24 | background: transparent; 25 | width: 20em; 26 | color: inherit; 27 | font-family: monospace; 28 | } 29 | 30 | .CodeMirror-dialog button { 31 | font-size: 70%; 32 | } 33 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/display/fullscreen.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-fullscreen { 2 | position: fixed; 3 | top: 0; left: 0; right: 0; bottom: 0; 4 | height: auto; 5 | z-index: 9; 6 | } 7 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/fold/foldgutter.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-foldmarker { 2 | color: blue; 3 | text-shadow: #b9f 1px 1px 2px, #b9f -1px -1px 2px, #b9f 1px -1px 2px, #b9f -1px 1px 2px; 4 | font-family: arial; 5 | line-height: .3; 6 | cursor: pointer; 7 | } 8 | .CodeMirror-foldgutter { 9 | width: .7em; 10 | } 11 | .CodeMirror-foldgutter-open, 12 | .CodeMirror-foldgutter-folded { 13 | cursor: pointer; 14 | } 15 | .CodeMirror-foldgutter-open:after { 16 | content: "\25BE"; 17 | } 18 | .CodeMirror-foldgutter-folded:after { 19 | content: "\25B8"; 20 | } 21 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/hint/show-hint.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-hints { 2 | position: absolute; 3 | z-index: 10; 4 | overflow: hidden; 5 | list-style: none; 6 | 7 | margin: 0; 8 | padding: 2px; 9 | 10 | -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 11 | -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2); 12 | box-shadow: 2px 3px 5px rgba(0,0,0,.2); 13 | border-radius: 3px; 14 | border: 1px solid silver; 15 | 16 | background: white; 17 | font-size: 90%; 18 | font-family: monospace; 19 | 20 | max-height: 20em; 21 | overflow-y: auto; 22 | } 23 | 24 | .CodeMirror-hint { 25 | margin: 0; 26 | padding: 0 4px; 27 | border-radius: 2px; 28 | max-width: 19em; 29 | overflow: hidden; 30 | white-space: pre; 31 | color: black; 32 | cursor: pointer; 33 | } 34 | 35 | li.CodeMirror-hint-active { 36 | background: #08f; 37 | color: white; 38 | } 39 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/lint/yaml-lint.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function(mod) { 5 | if (typeof exports == 'object' && typeof module == 'object') 6 | // CommonJS 7 | mod(require('../../lib/codemirror')); 8 | else if (typeof define == 'function' && define.amd) 9 | // AMD 10 | define(['../../lib/codemirror'], mod); // Plain browser env 11 | else mod(CodeMirror); 12 | })(function(CodeMirror) { 13 | 'use strict'; 14 | 15 | // Depends on js-yaml.js from https://github.com/nodeca/js-yaml 16 | 17 | // declare global: jsyaml 18 | 19 | CodeMirror.registerHelper('lint', 'yaml', function(text) { 20 | var found = []; 21 | try { 22 | jsyaml.load(text); 23 | } catch (e) { 24 | var loc = e.mark; 25 | found.push({ 26 | from: CodeMirror.Pos(loc.line, loc.column), 27 | to: CodeMirror.Pos(loc.line, loc.column), 28 | message: e.message, 29 | }); 30 | } 31 | return found; 32 | }); 33 | }); 34 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/mode/multiplex_test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | CodeMirror.defineMode('markdown_with_stex', function() { 6 | var inner = CodeMirror.getMode({}, 'stex'); 7 | var outer = CodeMirror.getMode({}, 'markdown'); 8 | 9 | var innerOptions = { 10 | open: '$', 11 | close: '$', 12 | mode: inner, 13 | delimStyle: 'delim', 14 | innerStyle: 'inner', 15 | }; 16 | 17 | return CodeMirror.multiplexingMode(outer, innerOptions); 18 | }); 19 | 20 | var mode = CodeMirror.getMode({}, 'markdown_with_stex'); 21 | 22 | function MT(name) { 23 | test.mode( 24 | name, 25 | mode, 26 | Array.prototype.slice.call(arguments, 1), 27 | 'multiplexing' 28 | ); 29 | } 30 | 31 | MT( 32 | 'stexInsideMarkdown', 33 | '[strong **Equation:**] [delim $][inner&tag \\pi][delim $]' 34 | ); 35 | })(); 36 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/addon/search/matchesonscrollbar.css: -------------------------------------------------------------------------------- 1 | .CodeMirror-search-match { 2 | background: gold; 3 | border-top: 1px solid orange; 4 | border-bottom: 1px solid orange; 5 | -moz-box-sizing: border-box; 6 | box-sizing: border-box; 7 | opacity: .5; 8 | } 9 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror", 3 | "version": "5.0.0", 4 | "main": ["lib/codemirror.js", "lib/codemirror.css"], 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components", 9 | "bin", 10 | "demo", 11 | "doc", 12 | "test", 13 | "index.html", 14 | "package.json" 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/mode/ruby/test.js: -------------------------------------------------------------------------------- 1 | // CodeMirror, copyright (c) by Marijn Haverbeke and others 2 | // Distributed under an MIT license: http://codemirror.net/LICENSE 3 | 4 | (function() { 5 | var mode = CodeMirror.getMode({ indentUnit: 2 }, 'ruby'); 6 | function MT(name) { 7 | test.mode(name, mode, Array.prototype.slice.call(arguments, 1)); 8 | } 9 | 10 | MT('divide_equal_operator', '[variable bar] [operator /=] [variable foo]'); 11 | 12 | MT( 13 | 'divide_equal_operator_no_spacing', 14 | '[variable foo][operator /=][number 42]' 15 | ); 16 | })(); 17 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/mode/tiddlywiki/tiddlywiki.css: -------------------------------------------------------------------------------- 1 | span.cm-underlined { 2 | text-decoration: underline; 3 | } 4 | span.cm-strikethrough { 5 | text-decoration: line-through; 6 | } 7 | span.cm-brace { 8 | color: #170; 9 | font-weight: bold; 10 | } 11 | span.cm-table { 12 | color: blue; 13 | font-weight: bold; 14 | } 15 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/mode/tiki/tiki.css: -------------------------------------------------------------------------------- 1 | .cm-tw-syntaxerror { 2 | color: #FFF; 3 | background-color: #900; 4 | } 5 | 6 | .cm-tw-deleted { 7 | text-decoration: line-through; 8 | } 9 | 10 | .cm-tw-header5 { 11 | font-weight: bold; 12 | } 13 | .cm-tw-listitem:first-child { /*Added first child to fix duplicate padding when highlighting*/ 14 | padding-left: 10px; 15 | } 16 | 17 | .cm-tw-box { 18 | border-top-width: 0px ! important; 19 | border-style: solid; 20 | border-width: 1px; 21 | border-color: inherit; 22 | } 23 | 24 | .cm-tw-underline { 25 | text-decoration: underline; 26 | } -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "codemirror", 3 | "version": "5.0.0", 4 | "main": "lib/codemirror.js", 5 | "description": "In-browser code editing made bearable", 6 | "licenses": [ 7 | { 8 | "type": "MIT", 9 | "url": "http://codemirror.net/LICENSE" 10 | } 11 | ], 12 | "directories": { "lib": "./lib" }, 13 | "scripts": { "test": "node ./test/run.js" }, 14 | "devDependencies": { 15 | "node-static": "0.6.0", 16 | "phantomjs": "1.9.2-5", 17 | "blint": ">=0.1.1" 18 | }, 19 | "bugs": "http://github.com/codemirror/CodeMirror/issues", 20 | "keywords": ["JavaScript", "CodeMirror", "Editor"], 21 | "homepage": "http://codemirror.net", 22 | "maintainers": [ 23 | { 24 | "name": "Marijn Haverbeke", 25 | "email": "marijnh@gmail.com", 26 | "web": "http://marijnhaverbeke.nl" 27 | } 28 | ], 29 | "repository": { 30 | "type": "git", 31 | "url": "https://github.com/codemirror/CodeMirror.git" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/theme/ambiance-mobile.css: -------------------------------------------------------------------------------- 1 | .cm-s-ambiance.CodeMirror { 2 | -webkit-box-shadow: none; 3 | -moz-box-shadow: none; 4 | box-shadow: none; 5 | } 6 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/theme/elegant.css: -------------------------------------------------------------------------------- 1 | .cm-s-elegant span.cm-number, .cm-s-elegant span.cm-string, .cm-s-elegant span.cm-atom {color: #762;} 2 | .cm-s-elegant span.cm-comment {color: #262; font-style: italic; line-height: 1em;} 3 | .cm-s-elegant span.cm-meta {color: #555; font-style: italic; line-height: 1em;} 4 | .cm-s-elegant span.cm-variable {color: black;} 5 | .cm-s-elegant span.cm-variable-2 {color: #b11;} 6 | .cm-s-elegant span.cm-qualifier {color: #555;} 7 | .cm-s-elegant span.cm-keyword {color: #730;} 8 | .cm-s-elegant span.cm-builtin {color: #30a;} 9 | .cm-s-elegant span.cm-link {color: #762;} 10 | .cm-s-elegant span.cm-error {background-color: #fdd;} 11 | 12 | .cm-s-elegant .CodeMirror-activeline-background {background: #e8f2ff !important;} 13 | .cm-s-elegant .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} 14 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/theme/neat.css: -------------------------------------------------------------------------------- 1 | .cm-s-neat span.cm-comment { color: #a86; } 2 | .cm-s-neat span.cm-keyword { line-height: 1em; font-weight: bold; color: blue; } 3 | .cm-s-neat span.cm-string { color: #a22; } 4 | .cm-s-neat span.cm-builtin { line-height: 1em; font-weight: bold; color: #077; } 5 | .cm-s-neat span.cm-special { line-height: 1em; font-weight: bold; color: #0aa; } 6 | .cm-s-neat span.cm-variable { color: black; } 7 | .cm-s-neat span.cm-number, .cm-s-neat span.cm-atom { color: #3a3; } 8 | .cm-s-neat span.cm-meta {color: #555;} 9 | .cm-s-neat span.cm-link { color: #3a3; } 10 | 11 | .cm-s-neat .CodeMirror-activeline-background {background: #e8f2ff !important;} 12 | .cm-s-neat .CodeMirror-matchingbracket {outline:1px solid grey; color:black !important;} 13 | -------------------------------------------------------------------------------- /src/app/assets/plugins/editor.md/lib/codemirror/theme/neo.css: -------------------------------------------------------------------------------- 1 | /* neo theme for codemirror */ 2 | 3 | /* Color scheme */ 4 | 5 | .cm-s-neo.CodeMirror { 6 | background-color:#ffffff; 7 | color:#2e383c; 8 | line-height:1.4375; 9 | } 10 | .cm-s-neo .cm-comment {color:#75787b} 11 | .cm-s-neo .cm-keyword, .cm-s-neo .cm-property {color:#1d75b3} 12 | .cm-s-neo .cm-atom,.cm-s-neo .cm-number {color:#75438a} 13 | .cm-s-neo .cm-node,.cm-s-neo .cm-tag {color:#9c3328} 14 | .cm-s-neo .cm-string {color:#b35e14} 15 | .cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier {color:#047d65} 16 | 17 | 18 | /* Editor styling */ 19 | 20 | .cm-s-neo pre { 21 | padding:0; 22 | } 23 | 24 | .cm-s-neo .CodeMirror-gutters { 25 | border:none; 26 | border-right:10px solid transparent; 27 | background-color:transparent; 28 | } 29 | 30 | .cm-s-neo .CodeMirror-linenumber { 31 | padding:0; 32 | color:#e0e2e5; 33 | } 34 | 35 | .cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; } 36 | .cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; } 37 | 38 | .cm-s-neo div.CodeMirror-cursor { 39 | width: auto; 40 | border: 0; 41 | background: rgba(155,157,162,0.37); 42 | z-index: 1; 43 | } 44 | -------------------------------------------------------------------------------- /src/app/assets/static/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Steemit", 3 | "short_name": "Steemit", 4 | "theme_color": "#FFFFFF", 5 | "background_color": "#FFFFFF", 6 | "start_url": "/", 7 | "display": "standalone", 8 | "icons": [ 9 | { 10 | "src": "/images/favicons/favicon-72x72.png", 11 | "sizes": "72x72", 12 | "type": "image/png" 13 | }, 14 | { 15 | "src": "/images/favicons/favicon-96x96.png", 16 | "sizes": "96x96", 17 | "type": "image/png" 18 | }, 19 | { 20 | "src": "/images/favicons/favicon-144x144.png", 21 | "sizes": "144x144", 22 | "type": "image/png" 23 | }, 24 | { 25 | "src": "/images/favicons/favicon-196x196.png", 26 | "sizes": "196x196", 27 | "type": "image/png" 28 | } 29 | ], 30 | "gcm_sender_id": "724829305784", 31 | "gcm_user_visible_only": true 32 | } 33 | -------------------------------------------------------------------------------- /src/app/assets/stylesheets/_animation.scss: -------------------------------------------------------------------------------- 1 | // Animation helpers 2 | 3 | $fade-in-animation-length: 1s; 4 | $fade-in-animation-delay: 0.03s; 5 | 6 | 7 | .fade-in { 8 | @include opacity(0); 9 | @for $i from 1 through 10 { 10 | &--#{$i} { 11 | animation: fade-in 12 | $fade-in-animation-length ease-in-out $fade-in-animation-delay*$i both; 13 | } 14 | } 15 | } 16 | 17 | @keyframes fade-in { 18 | 0% { 19 | @include opacity(0); 20 | } 21 | 100% { 22 | @include opacity(1); 23 | } 24 | } 25 | 26 | 27 | @keyframes fade-in-up { 28 | 0% { 29 | @include opacity(0); 30 | transform: translate(-24px, 24px); 31 | } 32 | 100% { 33 | @include opacity(1); 34 | transform: translate(0px, 0px); 35 | } 36 | } -------------------------------------------------------------------------------- /src/app/assets/stylesheets/fonts.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/assets/stylesheets/fonts.scss -------------------------------------------------------------------------------- /src/app/assets/stylesheets/mixins.scss: -------------------------------------------------------------------------------- 1 | @mixin hoverUnderline() { 2 | &:hover { 3 | text-decoration: underline; 4 | } 5 | } 6 | 7 | // rem fallback - credits: http://zerosixthree.se/ 8 | 9 | @function calculateRem($size) { 10 | $remSize: $size / 16px; 11 | @return $remSize * 1rem; 12 | } 13 | 14 | @mixin font-size($size) { 15 | font-size: $size; 16 | font-size: calculateRem($size); 17 | } 18 | 19 | // Enables opacity to be safely used with older browsers 20 | 21 | @mixin opacity($opacity) { 22 | opacity: $opacity; 23 | $opacity-ie: $opacity * 100; 24 | filter: alpha(opacity=$opacity-ie); //IE8 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/app/components/cards/BeneficiarySelector.scss: -------------------------------------------------------------------------------- 1 | .BeneficiarySelector__percentbox { 2 | max-width: 2.6rem; 3 | } 4 | .BeneficiarySelector__percentrow { 5 | padding-top: 5px; 6 | padding-left: 2px; 7 | } 8 | 9 | .BeneficiarySelector .input-group { 10 | margin-bottom: 1.25rem; 11 | } 12 | 13 | .react-autocomplete-input { 14 | overflow-y: scroll; 15 | max-height: 16em; 16 | background-clip: padding-box; 17 | background-color: #fff; 18 | border: 1px solid rgba(0,0,0,0.15); 19 | bottom: auto; 20 | box-shadow: 0 6px 12px rgba(0,0,0,0.175); 21 | display: block; 22 | font-size: 14px; 23 | list-style: none; 24 | padding: 1px; 25 | position: absolute; 26 | text-align: left; 27 | z-index: 20000; 28 | } 29 | 30 | .react-autocomplete-input > div { 31 | cursor: pointer; 32 | padding: 10px; 33 | min-width: 100px; 34 | } 35 | 36 | .react-autocomplete-input > .active { 37 | background-color: #06D6A9; 38 | color: #333; 39 | @include themify($themes) { 40 | color: theme('textColorPrimary'); 41 | background-color: themed('textColorAccentHover'); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/app/components/cards/MarkdownViewer.scss: -------------------------------------------------------------------------------- 1 | .MarkdownViewer__negative_group { 2 | color: crimson; 3 | border-top: 1px solid $medium-gray; 4 | padding-top: 1rem; 5 | } 6 | 7 | .MarkdownViewer { 8 | height: 100%; 9 | overflow: hidden; 10 | } 11 | -------------------------------------------------------------------------------- /src/app/components/cards/SearchUserList.scss: -------------------------------------------------------------------------------- 1 | .search-userlist { 2 | display: flex; 3 | padding: .6rem; 4 | .search-userlist-left { 5 | .search-userlist-left-top { 6 | margin-bottom: .6rem; 7 | .user-logo { 8 | width: 40px; 9 | height: 40px; 10 | border-radius: 50%; 11 | margin-right: .6rem; 12 | } 13 | .user-name { 14 | margin-right: .6rem; 15 | } 16 | } 17 | .search-userlist-left-bottom { 18 | .user-follower { 19 | margin-right: 1.4rem; 20 | } 21 | } 22 | } 23 | .search-userlist-right { 24 | margin-left: auto; 25 | align-self: center; 26 | .follow-btn { 27 | border: 1px solid gray; 28 | border-radius: 4px; 29 | padding: .4rem .6rem; 30 | color: #333; 31 | @include themify($themes) { 32 | background: themed('colorWhite'); 33 | } 34 | 35 | &:hover { 36 | cursor: pointer; 37 | color: #06D6A9; 38 | border: 1px solid #06D6A9; 39 | } 40 | 41 | } 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /src/app/components/cards/UserListRow.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | import Follow from 'app/components/elements/Follow'; 4 | 5 | class UserListRow extends React.Component { 6 | render() { 7 | const { user, loggedIn, title } = this.props; 8 | const username = title === 'Followers' ? user.follower : user.following; 9 | return ( 10 | 11 | 12 | 13 | {username} 14 | {user.reputation && `(${Math.floor(user.reputation)})`} 15 | 16 | 17 | {loggedIn && ( 18 | 19 | 20 | 21 | )} 22 | 23 | ); 24 | } 25 | } 26 | 27 | import { connect } from 'react-redux'; 28 | 29 | export default connect((state, ownProps) => { 30 | const loggedIn = state.user.hasIn(['current', 'username']); 31 | return { 32 | ...ownProps, 33 | loggedIn, 34 | }; 35 | })(UserListRow); 36 | -------------------------------------------------------------------------------- /src/app/components/elements/Ad.scss: -------------------------------------------------------------------------------- 1 | .ad-carousel { 2 | .hide { 3 | visibility: hidden; 4 | } 5 | img { 6 | border-radius: 5px; 7 | } 8 | overflow: hidden; 9 | } 10 | 11 | .tron-ad-box { 12 | width: 100%; 13 | .ad-ratio-wrapper { 14 | width: 100%; 15 | } 16 | .ratio-10-1, .ratio-375-80 { 17 | display: none; 18 | } 19 | 20 | @media (max-width: 760px) { 21 | .ratio-375-80 { 22 | display: block; 23 | } 24 | } 25 | 26 | @media (min-width: 761px) { 27 | .ratio-10-1 { 28 | display: block; 29 | } 30 | } 31 | } -------------------------------------------------------------------------------- /src/app/components/elements/Announcement.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; 3 | 4 | export const Announcement = ({ onClose }) => ( 5 |
6 |

7 | Communities are live!{' '} 8 | 12 | Read more 13 | . 14 |

15 | 18 |
19 | ); 20 | 21 | Announcement.propTypes = { 22 | onClose: PropTypes.func.isRequired, 23 | }; 24 | 25 | export default Announcement; 26 | -------------------------------------------------------------------------------- /src/app/components/elements/Author/Author.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs } from '@storybook/addon-knobs'; 4 | import rootReducer from 'app/redux/RootReducer'; 5 | import { Provider } from 'react-redux'; 6 | import { createStore } from 'redux'; 7 | import Author from './index'; 8 | import { Center } from 'decorators'; 9 | import { IntlProvider } from 'react-intl'; 10 | 11 | const store = createStore(rootReducer); 12 | 13 | storiesOf('Elements', module) 14 | .addDecorator(withKnobs) 15 | .addDecorator(Center) 16 | .addDecorator(getStory => {getStory()}) 17 | .add('Author', () => ( 18 | 19 | 20 | 21 | )); 22 | -------------------------------------------------------------------------------- /src/app/components/elements/Author/spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Provider } from 'react-redux'; 3 | import { createStore } from 'redux'; 4 | import Author from './index'; 5 | import rootReducer from 'app/redux/RootReducer'; 6 | import { configure, shallow } from 'enzyme'; 7 | 8 | import Adapter from 'enzyme-adapter-react-15'; 9 | 10 | configure({ adapter: new Adapter() }); 11 | 12 | const store = createStore(rootReducer); 13 | 14 | describe('', () => { 15 | const wrapper = shallow( 16 | 17 | 18 | 19 | ); 20 | const container = wrapper.instance(); 21 | 22 | it('renders without crashing', () => { 23 | expect(wrapper).toBeTruthy(); 24 | expect(container).toBeTruthy(); 25 | expect(wrapper).toMatchSnapshot(); 26 | }); 27 | }); 28 | -------------------------------------------------------------------------------- /src/app/components/elements/Author/styles.scss: -------------------------------------------------------------------------------- 1 | .Author { 2 | display: inline-block; 3 | 4 | .dropdown-arrow { 5 | position: relative; 6 | top: 3px; 7 | left: -2px; 8 | } 9 | 10 | /* coax footer link to behave similarly */ 11 | > span > strong > a { 12 | transition: 0.2s all ease-in-out; 13 | @include themify($themes) { 14 | color: themed('textColorPrimary'); 15 | } 16 | 17 | &:hover, &:focus { 18 | @include themify($themes) { 19 | color: themed('textColorAccent'); 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/app/components/elements/Callout.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({ title, children, type }) => { 4 | return ( 5 |
6 |
7 |
8 |

{title}

9 |
{children}
10 |
11 |
12 |
13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/components/elements/Callout.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, select } from '@storybook/addon-knobs'; 4 | import Callout from './Callout'; 5 | import { Center } from 'decorators'; 6 | 7 | const selectOptions = ['error', 'default']; 8 | 9 | storiesOf('Elements', module) 10 | .addDecorator(withKnobs) 11 | .addDecorator(Center) 12 | .add('Callout', () => ( 13 | 14 | Callout, you can add an error style with the knob 15 | 16 | )); 17 | -------------------------------------------------------------------------------- /src/app/components/elements/CloseButton.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; 3 | 4 | export const CloseButton = ({ className, ...restProps }) => { 5 | return ( 6 | 9 | ); 10 | }; 11 | 12 | CloseButton.propTypes = { 13 | className: PropTypes.string, 14 | }; 15 | 16 | export default CloseButton; 17 | -------------------------------------------------------------------------------- /src/app/components/elements/ContentEditedWrapper/index.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/prop-types: 0 */ 2 | import React from 'react'; 3 | import { FormattedRelative } from 'react-intl'; 4 | import Tooltip from 'app/components/elements/Tooltip'; 5 | import tt from 'counterpart'; 6 | import { injectIntl } from 'react-intl'; 7 | 8 | class ContentEditedWrapper extends React.Component { 9 | render() { 10 | let { createDate, updateDate, className } = this.props; 11 | if (createDate === updateDate) return null; 12 | 13 | if (updateDate && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$/.test(updateDate)) { 14 | updateDate = updateDate + 'Z'; // Firefox really wants this Z (Zulu) 15 | } 16 | const dt = new Date(updateDate); 17 | const date_time = `${this.props.intl.formatDate( 18 | dt 19 | )} ${this.props.intl.formatTime(dt)}`; 20 | return ( 21 | 22 | ({tt('g.edited')}) 23 | 24 | ); 25 | } 26 | } 27 | 28 | export default injectIntl(ContentEditedWrapper); 29 | -------------------------------------------------------------------------------- /src/app/components/elements/ContentEditedWrapper/story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, date } from '@storybook/addon-knobs'; 4 | import { Center } from 'decorators'; 5 | 6 | import { IntlProvider } from 'react-intl'; 7 | 8 | import ContentEditedWrapper from './'; 9 | 10 | storiesOf('Elements', module) 11 | .addDecorator(withKnobs) 12 | .addDecorator(Center) 13 | .add('ContentEditedWrapper', () => ( 14 | 15 | 16 | 17 | )); 18 | -------------------------------------------------------------------------------- /src/app/components/elements/DateJoinWrapper.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import tt from 'counterpart'; 3 | import { FormattedDate } from 'react-intl'; 4 | 5 | export default class DateJoinWrapper extends React.Component { 6 | render() { 7 | let date = this.props.date.replace(' ', 'T'); 8 | if (date[date.length - 1] != 'Z') date += 'Z'; 9 | 10 | return ( 11 | 12 | {tt('g.joined')}{' '} 13 | 18 | 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/components/elements/Editor/styles.scss: -------------------------------------------------------------------------------- 1 | .ql-container { 2 | @include themify($themes) { 3 | background: themed('backgroundColor'); 4 | } 5 | min-height: 140px; 6 | } 7 | .ql-tooltip { 8 | left: 0 !important; 9 | } -------------------------------------------------------------------------------- /src/app/components/elements/ElasticSearchInput/SearchHistory.scss: -------------------------------------------------------------------------------- 1 | .search-history { 2 | margin: 0; 3 | list-style: none; 4 | border: 1px solid #eee; 5 | border-radius: 6px; 6 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.05); 7 | background: #fff; 8 | margin-top: 2px; 9 | max-width: 220px; 10 | overflow: hidden; 11 | z-index: 99; 12 | @include themify($themes) { 13 | background: themed('moduleBackgroundColor'); 14 | color: themed('textColorPrimary'); 15 | } 16 | li { 17 | padding: 6px 12px; 18 | white-space: nowrap; 19 | overflow: hidden; 20 | text-overflow: ellipsis; 21 | &:hover { 22 | cursor: pointer; 23 | background-color: rgba(0, 0, 0, 0.05); 24 | } 25 | } 26 | .search-history-first { 27 | display: flex; 28 | justify-content: space-between; 29 | border-bottom: 1px solid #eee; 30 | &:hover { 31 | cursor: auto; 32 | } 33 | .search-history-clear { 34 | font-size: 14px; 35 | &:hover { 36 | cursor: pointer; 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /src/app/components/elements/ElasticSearchInput/SearchInput.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import ElasticSearchInput from './index'; 4 | import { Center } from 'decorators'; 5 | 6 | storiesOf('Elements', module) 7 | .addDecorator(Center) 8 | .add('ElasticSearchInput', () => ); 9 | -------------------------------------------------------------------------------- /src/app/components/elements/FlagButton.scss: -------------------------------------------------------------------------------- 1 | .flag__button { 2 | cursor: pointer; 3 | .flag2 { 4 | display: none !important; 5 | visibility: hidden; 6 | } 7 | &:hover { 8 | .flag1 { 9 | display: none !important; 10 | visibility: hidden; 11 | } 12 | .flag2 { 13 | visibility: visible; 14 | display: inline-block !important; 15 | } 16 | svg { 17 | fill: red; 18 | } 19 | } 20 | } 21 | 22 | .flag__button--post { 23 | position: absolute; 24 | right: 1em; 25 | } 26 | -------------------------------------------------------------------------------- /src/app/components/elements/Follow/Follow.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, boolean } from '@storybook/addon-knobs'; 4 | import rootReducer from 'app/redux/RootReducer'; 5 | import { Provider } from 'react-redux'; 6 | import { createStore } from 'redux'; 7 | import Follow from './index'; 8 | import { Center } from 'decorators'; 9 | 10 | const store = createStore(rootReducer); 11 | 12 | storiesOf('Elements', module) 13 | .addDecorator(withKnobs) 14 | .addDecorator(Center) 15 | .addDecorator(getStory => {getStory()}) 16 | .add('Follow', () => ( 17 | 25 | )); 26 | -------------------------------------------------------------------------------- /src/app/components/elements/Follow/spec.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { mount, configure, shallow } from 'enzyme'; 3 | import { Provider } from 'react-redux'; 4 | import { createStore } from 'redux'; 5 | import Follow from './index'; 6 | import rootReducer from 'app/redux/RootReducer'; 7 | import Adapter from 'enzyme-adapter-react-15'; 8 | 9 | const store = createStore(rootReducer); 10 | 11 | configure({ adapter: new Adapter() }); 12 | 13 | describe('', () => { 14 | const wrapper = shallow( 15 | 16 | 17 | 18 | ); 19 | const container = wrapper.instance(); 20 | 21 | it('renders without crashing', () => { 22 | expect(wrapper).toBeTruthy(); 23 | expect(container).toBeTruthy(); 24 | expect(wrapper).toMatchSnapshot(); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /src/app/components/elements/FormattedAsset.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { 3 | formatDecimal, 4 | parsePayoutAmount, 5 | } from 'app/utils/ParsersAndFormatters'; 6 | 7 | const FormattedAsset = ({ amount, asset, classname }) => { 8 | if (amount && typeof amount === 'string') { 9 | amount = parsePayoutAmount(amount); 10 | } 11 | 12 | const amnt = formatDecimal(amount); 13 | return asset === '$' ? ( 14 | 15 | $ 16 | {amnt[0]} 17 | {amnt[1]} 18 | 19 | ) : ( 20 | 21 | {amnt[0]} 22 | {amnt[1]}{' '} 23 | {asset} 24 | 25 | ); 26 | }; 27 | 28 | export default FormattedAsset; 29 | -------------------------------------------------------------------------------- /src/app/components/elements/FormattedAsset.scss: -------------------------------------------------------------------------------- 1 | .FormattedAsset { 2 | .prefix { 3 | padding-right: 0.1rem; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /src/app/components/elements/GoogleAd.scss: -------------------------------------------------------------------------------- 1 | .adsbygoogle.ad-dev { 2 | background-color: #ddd; 3 | min-height: 64px; 4 | } 5 | 6 | .c-sidebar .sidebar-ad { 7 | text-align: center; 8 | } 9 | 10 | .articles__content-block--ad { 11 | text-align: center; 12 | margin-top: 1em; 13 | margin-bottom: 2.5em; 14 | } 15 | 16 | .Post_footer__ad { 17 | max-width: 50rem; 18 | margin-right: auto; 19 | margin-left: auto; 20 | margin-bottom: 1.5rem; 21 | margin-top: 1.5rem; 22 | } 23 | -------------------------------------------------------------------------------- /src/app/components/elements/GptAd.scss: -------------------------------------------------------------------------------- 1 | .gpt-ad { 2 | text-align: center; 3 | } 4 | -------------------------------------------------------------------------------- /src/app/components/elements/Icon.scss: -------------------------------------------------------------------------------- 1 | .Icon { 2 | vertical-align: middle; 3 | 4 | > svg, span.icon { 5 | width: 1.12rem; 6 | height: 1.12rem; 7 | vertical-align: top; 8 | } 9 | 10 | &.fill-black > svg > path { 11 | fill:black; 12 | } 13 | } 14 | 15 | .Icon_0_8x > svg, span.Icon_0_8x { 16 | width: 0.8rem; 17 | height: 0.8rem; 18 | } 19 | 20 | .Icon_1_5x > svg, span.Icon_1_5x { 21 | width: 1.5rem; 22 | height: 1.5rem; 23 | } 24 | 25 | .Icon_2x > svg, span.Icon_2x { 26 | width: 2rem; 27 | height: 2rem; 28 | } 29 | 30 | .Icon_3x > svg, span.Icon_3x { 31 | width: 3rem; 32 | height: 3rem; 33 | } 34 | 35 | .Icon_4x > svg, span.Icon_4x { 36 | width: 4.60rem; 37 | height: 4.60rem; 38 | } 39 | 40 | .Icon_5x > svg, span.Icon_5x { 41 | width: 5.75rem; 42 | height: 5.75rem; 43 | margin: 24px 0 24px 0; 44 | } 45 | 46 | .Icon_10x > svg, span.Icon_10x { 47 | width: 10rem; 48 | height: 10rem; 49 | margin: 24px 0 24px 0; 50 | } 51 | 52 | .Icon.dropdown-arrow polygon { 53 | fill: $dark-gray; 54 | } 55 | -------------------------------------------------------------------------------- /src/app/components/elements/Icon.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, select } from '@storybook/addon-knobs'; 4 | import Icon from './Icon'; 5 | import { icons } from './Icon'; 6 | 7 | const styles = { 8 | textAlign: 'center', 9 | display: 'grid', 10 | gridTemplateColumns: 'repeat(3, 1fr)', 11 | gridAutoRows: 'minmax(80px, auto)', 12 | }; 13 | 14 | export const Grid = ({ children }) =>
{children}
; 15 | 16 | const options = ['1x', '1_5x', '2x', '3x', '4x', '5x', '10x']; 17 | 18 | storiesOf('Elements', module) 19 | .addDecorator(withKnobs) 20 | .add('Icon', () => ( 21 | 22 | {icons.map(icon => ( 23 |
24 | 25 |

{icon}

26 |
27 | ))} 28 |
29 | )); 30 | -------------------------------------------------------------------------------- /src/app/components/elements/IconButton/IconButton.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import IconButton from './index'; 4 | import { Center } from 'decorators'; 5 | 6 | storiesOf('Elements', module) 7 | .addDecorator(Center) 8 | .add('IconButton', () => ( 9 | 10 | 11 | 12 | 13 | 14 | )); 15 | -------------------------------------------------------------------------------- /src/app/components/elements/Link.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | import React from 'react'; 3 | import links from 'app/utils/Links'; 4 | import { browserHistory } from 'react-router'; 5 | import shouldComponentUpdate from 'app/utils/shouldComponentUpdate'; 6 | 7 | export default class Link extends React.Component { 8 | static propTypes = { 9 | // HTML properties 10 | href: PropTypes.string, 11 | }; 12 | constructor(props) { 13 | super(); 14 | const { href } = props; 15 | this.shouldComponentUpdate = shouldComponentUpdate(this, 'Link'); 16 | this.localLink = href && links.local.test(href); 17 | this.onLocalClick = e => { 18 | e.preventDefault(); 19 | browserHistory.push(this.props.href); 20 | }; 21 | } 22 | render() { 23 | const { props: { href, children }, onLocalClick } = this; 24 | if (this.localLink) return {children}; 25 | return ( 26 | 27 | {children} 28 | 29 | ); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/components/elements/LoadingIndicator.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import LoadingIndicator from './LoadingIndicator'; 4 | import styles from './LoadingIndicator.scss'; 5 | 6 | storiesOf('Elements', module).add('LoadingIndicator', () => ( 7 | 8 | )); 9 | -------------------------------------------------------------------------------- /src/app/components/elements/Memo/Memo.test.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { configure, shallow } from 'enzyme'; 3 | import Adapter from 'enzyme-adapter-react-15'; 4 | 5 | import { Memo } from './index'; 6 | 7 | configure({ adapter: new Adapter() }); 8 | 9 | describe('Memo', () => { 10 | it('should return an empty span if no text is provided', () => { 11 | const wrapper = shallow(); 12 | expect(wrapper.html()).toEqual(''); 13 | }); 14 | 15 | it('should render a plain ol memo', () => { 16 | const wrapper = shallow( 17 | 18 | ); 19 | expect(wrapper.html()).toEqual('hi dude'); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/app/components/elements/NativeSelect/NativeSelect.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import NativeSelect from './index'; 4 | import { Center } from 'decorators'; 5 | 6 | const opts = topic => [ 7 | { 8 | value: 'trending', 9 | label: 'TRENDY', 10 | link: `/trending/${topic}`, 11 | }, 12 | { 13 | value: 'created', 14 | label: 'FRESH', 15 | link: `/created/${topic}`, 16 | }, 17 | { 18 | value: 'hot', 19 | label: 'HOTTT!!!', 20 | link: `/hot/${topic}`, 21 | }, 22 | { 23 | value: 'promoted', 24 | label: '$$$ SOLD OUT $$$', 25 | link: `/promoted/${topic}`, 26 | }, 27 | ]; 28 | 29 | storiesOf('Elements', module) 30 | .addDecorator(Center) 31 | .add('NativeSelect', () => ( 32 | { 35 | console.log('arg:', e.value); 36 | }} 37 | options={opts('cool')} 38 | /> 39 | )); 40 | -------------------------------------------------------------------------------- /src/app/components/elements/NativeSelect/styles.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/components/elements/NativeSelect/styles.scss -------------------------------------------------------------------------------- /src/app/components/elements/PageViewsCounter.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { recordPageView } from 'app/utils/ServerApiClient'; 3 | 4 | export default class PageViewsCounter extends React.Component { 5 | constructor(props) { 6 | super(props); 7 | this.last_page = null; 8 | } 9 | 10 | pageView() { 11 | let ref = document.referrer || ''; 12 | recordPageView(window.location.pathname, ref); 13 | this.last_page = window.location.pathname; 14 | } 15 | 16 | componentDidMount() { 17 | this.pageView(); 18 | } 19 | 20 | shouldComponentUpdate(nextProps, nextState) { 21 | return window.location.pathname !== this.last_page; 22 | } 23 | 24 | componentDidUpdate() { 25 | this.pageView(); 26 | } 27 | 28 | render() { 29 | return null; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/components/elements/PostCategoryBanner.scss: -------------------------------------------------------------------------------- 1 | .PostCategoryBanner{ 2 | 3 | margin: .5em 0 1em; 4 | .postTo { 5 | small { 6 | font-size: 100%; 7 | color: #666; 8 | .smallLabel { 9 | color: #333; 10 | font-weight: bold; 11 | } 12 | } 13 | } 14 | 15 | .categoryName { 16 | display: flex; 17 | justify-content: flex-start; 18 | align-items: center; 19 | } 20 | h3 { 21 | line-height: normal !important; 22 | padding: 0 0 0 .5em; 23 | overflow: hidden; 24 | text-overflow: ellipsis; 25 | white-space: nowrap; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/components/elements/Reblog.scss: -------------------------------------------------------------------------------- 1 | .Reblog__button { 2 | path { 3 | @include themify($themes) { 4 | fill: themed('iconColorSecondary'); 5 | } 6 | } 7 | } 8 | 9 | .Reblog__button-active { 10 | path { 11 | @include themify($themes) { 12 | fill: themed('colorAccent'); 13 | } 14 | } 15 | } 16 | 17 | .Reblog__button.loading { 18 | padding-right: 0.5rem; 19 | svg { 20 | border: 1px solid $color-teal; 21 | border-radius: 100%; 22 | border-right-color: transparent; 23 | border-top-color: transparent; 24 | animation: loading 500ms infinite linear; 25 | path {opacity: 0} 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/components/elements/Reblog.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs } from '@storybook/addon-knobs'; 4 | import rootReducer from 'app/redux/RootReducer'; 5 | import { Provider } from 'react-redux'; 6 | import { createStore } from 'redux'; 7 | import Reblog from './Reblog'; 8 | import { Center } from 'decorators'; 9 | 10 | const store = createStore(rootReducer); 11 | 12 | storiesOf('Elements', module) 13 | .addDecorator(withKnobs) 14 | .addDecorator(Center) 15 | .addDecorator(getStory => {getStory()}) 16 | .add('Reblog', () => ( 17 | alert('STEEM WAZ HERE')} 21 | /> 22 | )); 23 | -------------------------------------------------------------------------------- /src/app/components/elements/Reputation.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import tt from 'counterpart'; 3 | 4 | export default ({ value }) => { 5 | if (isNaN(value)) { 6 | console.log('Unexpected rep value:', value); 7 | return null; 8 | } 9 | return ( 10 | 11 | ({Math.floor(value)}) 12 | 13 | ); 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/components/elements/Reputation.scss: -------------------------------------------------------------------------------- 1 | .Reputation { 2 | @include font-size(13px); 3 | line-height: 1; 4 | padding: 0; 5 | margin-left: -1px; 6 | font-weight: normal; 7 | transition: 0.3s all ease-in-out; 8 | @include themify($themes) { 9 | color: themed('textColorPrimary'); 10 | } 11 | @include MQ(M) { 12 | @include font-size(14px); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/app/components/elements/Reputation.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import Reputation from './Reputation'; 4 | import { Center } from 'decorators'; 5 | 6 | storiesOf('Elements', module) 7 | .addDecorator(Center) 8 | .add('Reputation', () => ); 9 | -------------------------------------------------------------------------------- /src/app/components/elements/SanitizedLink/styles.scss: -------------------------------------------------------------------------------- 1 | .SanitizedLink--phishyLink { 2 | color: darken($color-red, 10%); 3 | font-size: 75%; 4 | font-weight: bold; 5 | text-transform: uppercase; 6 | letter-spacing: 1px; 7 | .phishylink-reveal-link { 8 | padding-left: .5em; 9 | opacity: .5; 10 | font-size: 75%; 11 | text-decoration: underline; 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/app/components/elements/SearchInput/SearchInput.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import SearchInput from './index'; 4 | import { Center } from 'decorators'; 5 | 6 | storiesOf('Elements', module) 7 | .addDecorator(Center) 8 | .add('SearchInput', () => ); 9 | -------------------------------------------------------------------------------- /src/app/components/elements/SearchTabs/styles.scss: -------------------------------------------------------------------------------- 1 | .search-nav { 2 | .search-tabs { 3 | display: flex; 4 | padding: .8rem; 5 | list-style: none; 6 | margin-left: 0; 7 | @include themify($themes) { 8 | background: themed('moduleBackgroundColor'); 9 | color: themed('textColorPrimary'); 10 | } 11 | li { 12 | margin-right: 2.8rem; 13 | font-weight: 500; 14 | cursor: pointer; 15 | @media screen and (max-width: 456px) { 16 | margin-right: 1rem; 17 | } 18 | } 19 | .active { 20 | color: #00FFC8; 21 | border-bottom: 4px solid #00FFC8; 22 | } 23 | .li-right { 24 | margin-left: auto; 25 | .search-sort { 26 | font-size: 14px; 27 | height: 2.2rem; 28 | } 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/components/elements/ShareMenu.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | import { Link } from 'react-router'; 4 | import Icon from 'app/components/elements/Icon'; 5 | 6 | export default class ShareMenu extends React.Component { 7 | static propTypes = { 8 | menu: PropTypes.arrayOf(PropTypes.object).isRequired, 9 | }; 10 | 11 | render() { 12 | const { menu } = this.props; 13 | return ( 14 | 15 |
    16 | {menu.map(i => ( 17 |
  • 18 | 19 | 20 | 21 |
  • 22 | ))} 23 |
24 |
25 | ); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/app/components/elements/ShareMenu.scss: -------------------------------------------------------------------------------- 1 | .shareMenu { 2 | display: inline-block; 3 | vertical-align: middle; 4 | height: 2em; 5 | 6 | > ul { 7 | list-style: none; 8 | display: inline; 9 | margin: 0; 10 | li { 11 | float: left; 12 | padding: 2px; 13 | } 14 | li > a:hover svg { 15 | @include themify($themes) { 16 | fill: themed('colorAccent'); 17 | } 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/components/elements/SortOrder/SortOrder.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, boolean } from '@storybook/addon-knobs'; 4 | import SortOrder from './index'; 5 | import { Center } from 'decorators'; 6 | 7 | storiesOf('Elements', module) 8 | .addDecorator(withKnobs) 9 | .addDecorator(Center) 10 | .add('SortOrder', () => ( 11 | 16 | )); 17 | -------------------------------------------------------------------------------- /src/app/components/elements/SortOrder/styles.scss: -------------------------------------------------------------------------------- 1 | .nav__block-list { 2 | margin: 0px; 3 | display: flex; 4 | } 5 | 6 | li.nav__block-list-item { 7 | margin: 0 10px; 8 | list-style: none; 9 | padding: 1.125rem 0.25rem; 10 | transition: 0.3s all ease-in-out; 11 | font-size: 1.125rem; 12 | a { 13 | @extend .link; 14 | @extend .link--primary; 15 | font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; 16 | } 17 | &--active { 18 | box-shadow: 0px 5px 0px -2px $color-teal; 19 | a { 20 | color: $color-teal; 21 | } 22 | } 23 | &:hover, &:focus { 24 | box-shadow: 0px 5px 0px -2px $color-teal; 25 | a { 26 | color: $color-teal; 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/app/components/elements/SteemLogo/SteemLogo.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, boolean } from '@storybook/addon-knobs'; 4 | import SteemLogo from './index'; 5 | import { Center } from 'decorators'; 6 | 7 | storiesOf('Elements', module) 8 | .addDecorator(withKnobs) 9 | .addDecorator(Center) 10 | .add('SteemLogo', () => ); 11 | -------------------------------------------------------------------------------- /src/app/components/elements/SteemLogo/styles.scss: -------------------------------------------------------------------------------- 1 | .logo { 2 | cursor: pointer; 3 | transition: all 0.3s ease-in-out; 4 | .logo__steemit{ 5 | fill: $color-teal; 6 | transition: 0.25s all ease-in-out; 7 | } 8 | // Fixes #2639 - Don't apply hover styles on devices that do not support it. 9 | @media (hover: hover) { 10 | &:hover, &:active { 11 | .logo__steemit{ 12 | @include themify($themes) { 13 | fill: themed('colorAccentReverse'); 14 | } 15 | } 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /src/app/components/elements/SteemMarket.scss: -------------------------------------------------------------------------------- 1 | .steem-market { 2 | h4 { 3 | font-size: 1.125rem; 4 | } 5 | .coin { 6 | margin-bottom: 1em; 7 | } 8 | .chart { 9 | position: relative; 10 | .caption { 11 | position: absolute; 12 | bottom: 0; 13 | margin-bottom: 10px; 14 | padding-left: 2px; 15 | padding-right: 2px; 16 | pointer-events: none; 17 | background-color: rgba(51, 51, 51, 0.1); 18 | color: #333333; 19 | font-size: 0.5em; 20 | font-weight: bold; 21 | text-shadow: 0 1px 1px rgba(255, 255, 255, 0.5); 22 | } 23 | } 24 | .coin-label { 25 | margin-top: -0.5em; 26 | font-size: 0.875rem; 27 | .symbol { 28 | color: #788187; 29 | } 30 | .price { 31 | color: #09d6a8; 32 | } 33 | } 34 | .brought { 35 | font-size: 0.675em; 36 | color: #788187; 37 | } 38 | } 39 | 40 | .theme-dark { 41 | .steem-market { 42 | .chart { 43 | .caption { 44 | background-color: rgba(255, 255, 255, 0.2); 45 | color: white; 46 | text-shadow: 0 1px 1px rgba(0, 0, 0, 0.5); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/components/elements/SvgImage.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PropTypes from 'prop-types'; 3 | 4 | export default class SvgImage extends React.Component { 5 | static propTypes = { 6 | name: PropTypes.string.isRequired, 7 | width: PropTypes.string.isRequired, 8 | height: PropTypes.string.isRequired, 9 | className: PropTypes.string, 10 | }; 11 | render() { 12 | const style = { 13 | display: 'inline-block', 14 | width: this.props.width, 15 | height: this.props.height, 16 | }; 17 | const image = require(`assets/images/${this.props.name}.svg`); 18 | const cn = 19 | 'SvgImage' + 20 | (this.props.className ? ' ' + this.props.className : ''); 21 | return ( 22 | 27 | ); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/app/components/elements/SvgImage.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, number } from '@storybook/addon-knobs'; 4 | import SvgImage from './SvgImage'; 5 | import { Grid } from './Icon.story'; 6 | 7 | const svgs = ['404', 'facebook', 'reddit', 'steemit']; 8 | 9 | const options = { 10 | range: true, 11 | min: 10, 12 | max: 200, 13 | step: 1, 14 | }; 15 | 16 | storiesOf('Elements', module) 17 | .addDecorator(withKnobs) 18 | .add('SvgImage', () => ( 19 | 20 | {svgs.map(svg => ( 21 |
22 | 27 |

{svg}

28 |
29 | ))} 30 |
31 | )); 32 | -------------------------------------------------------------------------------- /src/app/components/elements/Tag.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { Link } from 'react-router'; 3 | 4 | const Tag = ({ post }) => { 5 | const tag = post.get('category'); 6 | const name = post.get('community_title', '#' + tag); 7 | return ( 8 | 9 | {name} 10 | 11 | ); 12 | }; 13 | 14 | export default Tag; 15 | -------------------------------------------------------------------------------- /src/app/components/elements/TagList.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | import { connect } from 'react-redux'; 3 | import { Link } from 'react-router'; 4 | import { normalizeTags } from 'app/utils/StateFunctions'; 5 | 6 | class TagList extends Component { 7 | render() { 8 | const { post } = this.props; 9 | const category = post.get('category'); 10 | 11 | const link = tag => { 12 | if (tag == category) return null; 13 | return {` #${tag} `}; 14 | }; 15 | 16 | return ( 17 |
18 | {normalizeTags(post.get('json_metadata'), category).map(link)} 19 |
20 | ); 21 | } 22 | } 23 | 24 | export default connect( 25 | // mapStateToProps 26 | (state, ownProps) => ({ 27 | post: ownProps.post, 28 | }) 29 | )(TagList); 30 | -------------------------------------------------------------------------------- /src/app/components/elements/TagList.scss: -------------------------------------------------------------------------------- 1 | .TagList__horizontal { 2 | max-width: 40rem; 3 | margin: 0 auto 0.5rem; 4 | a { 5 | font-size: 95%; 6 | display: inline-block; 7 | margin: 0.1rem 0.4rem 0.1rem 0; 8 | padding: 0.1rem 0.3rem; 9 | border-radius: 0.3rem; 10 | transition: 0.2s all ease-in-out; 11 | @include themify($themes) { 12 | background: themed('backgroundColorOpaque'); 13 | color: themed('textColorPrimary'); 14 | border: themed('border'); 15 | } 16 | &:hover { 17 | @include themify($themes) { 18 | background: themed('backgroundColor'); 19 | color: themed('textColorPrimary'); 20 | border: themed('borderDark'); 21 | } 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/app/components/elements/TagList.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import TagList from './TagList'; 4 | import { Center } from 'decorators'; 5 | 6 | const mockPost = { 7 | json_metadata: { 8 | tags: ['water', 'snow', 'ice', 'steam'], 9 | }, 10 | }; 11 | 12 | storiesOf('Elements', module) 13 | .addDecorator(Center) 14 | .add('TagList', () => ); 15 | -------------------------------------------------------------------------------- /src/app/components/elements/TimeAgoWrapper/index.jsx: -------------------------------------------------------------------------------- 1 | /* eslint react/prop-types: 0 */ 2 | import React from 'react'; 3 | import { FormattedRelative } from 'react-intl'; 4 | import Tooltip from 'app/components/elements/Tooltip'; 5 | import { injectIntl } from 'react-intl'; 6 | 7 | class TimeAgoWrapper extends React.Component { 8 | render() { 9 | let { date, className } = this.props; 10 | if (date && /^\d{4}-\d\d-\d\dT\d\d:\d\d:\d\d$/.test(date)) { 11 | date = date + 'Z'; // Firefox really wants this Z (Zulu) 12 | } 13 | const dt = new Date(date); 14 | const date_time = `${this.props.intl.formatDate( 15 | dt 16 | )} ${this.props.intl.formatTime(dt)}`; 17 | return ( 18 | 19 | 20 | 21 | ); 22 | } 23 | } 24 | 25 | export default injectIntl(TimeAgoWrapper); 26 | -------------------------------------------------------------------------------- /src/app/components/elements/TimeAgoWrapper/story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, date } from '@storybook/addon-knobs'; 4 | import { Center } from 'decorators'; 5 | 6 | import { IntlProvider } from 'react-intl'; 7 | 8 | import TimeAgoWrapper from './'; 9 | 10 | storiesOf('Elements', module) 11 | .addDecorator(withKnobs) 12 | .addDecorator(Center) 13 | .add('TimeAgoWrapper', () => ( 14 | 15 | 16 | 17 | )); 18 | -------------------------------------------------------------------------------- /src/app/components/elements/Tooltip.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default ({ children, className, t }) => { 4 | return ( 5 | 6 | {children} 7 | 8 | ); 9 | }; 10 | -------------------------------------------------------------------------------- /src/app/components/elements/Tooltip.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, text } from '@storybook/addon-knobs'; 4 | import { Center } from 'decorators'; 5 | import Tooltip from './Tooltip'; 6 | 7 | const widthOptions = { 8 | range: true, 9 | min: 300, 10 | max: 1200, 11 | step: 1, 12 | }; 13 | 14 | storiesOf('Elements', module) 15 | .addDecorator(withKnobs) 16 | .addDecorator(Center) 17 | .add('Tooltip', () => ( 18 | 19 | Hover Over Me To See The Tooltip. 20 | 21 | )); 22 | -------------------------------------------------------------------------------- /src/app/components/elements/UserList.scss: -------------------------------------------------------------------------------- 1 | .UserList { 2 | .pag-active { 3 | background-color:#e6e6e6; 4 | } 5 | a:focus { 6 | outline: none !important; 7 | } 8 | .pagination { 9 | position: relative; 10 | text-align: right; 11 | .previous { 12 | position: absolute; 13 | right: 50px 14 | } 15 | .disabled { 16 | padding: 0 !important; 17 | } 18 | } 19 | li:nth-last-child(2){ 20 | margin-right: 72px; 21 | } 22 | } -------------------------------------------------------------------------------- /src/app/components/elements/UserList.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs, number } from '@storybook/addon-knobs'; 4 | import { Map, List } from 'immutable'; 5 | import rootReducer from 'app/redux/RootReducer'; 6 | import { Provider } from 'react-redux'; 7 | import { createStore } from 'redux'; 8 | import { Center } from 'decorators'; 9 | import UserList from './UserList'; 10 | 11 | const store = createStore(rootReducer); 12 | 13 | const options = { 14 | range: true, 15 | min: 0, 16 | max: 150, 17 | step: 1, 18 | }; 19 | 20 | storiesOf('Elements', module) 21 | .addDecorator(withKnobs) 22 | .addDecorator(Center) 23 | .addDecorator(getStory => {getStory()}) 24 | .add('UserList', () => { 25 | let mockUsers = List( 26 | Array(number('number of users', 10, options)).fill('test') 27 | ); 28 | return ; 29 | }); 30 | -------------------------------------------------------------------------------- /src/app/components/elements/UserNames.scss: -------------------------------------------------------------------------------- 1 | .UserNames .VerticalMenu { 2 | li > a { 3 | padding: 0.25rem 0.5rem; 4 | line-height: 1.25; 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/app/components/elements/Userpic.scss: -------------------------------------------------------------------------------- 1 | .Userpic { 2 | display: inline-block; 3 | 4 | background-size: cover; 5 | background-repeat: no-repeat; 6 | background-position: 50% 50%; 7 | border-radius: 50%; 8 | 9 | width: 48px; 10 | height: 48px; 11 | } 12 | -------------------------------------------------------------------------------- /src/app/components/elements/Userpic.story.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { storiesOf } from '@storybook/react'; 3 | import { withKnobs } from '@storybook/addon-knobs'; 4 | import rootReducer from 'app/redux/RootReducer'; 5 | import { Provider } from 'react-redux'; 6 | import { createStore } from 'redux'; 7 | import Userpic from './Userpic'; 8 | import { Center } from 'decorators'; 9 | 10 | const store = createStore(rootReducer); 11 | global.$STM_Config = { img_proxy_prefix: 'https://steemitimages.com/' }; 12 | 13 | storiesOf('Elements', module) 14 | .addDecorator(withKnobs) 15 | .addDecorator(Center) 16 | .addDecorator(getStory => {getStory()}) 17 | .add('Userpic', () => ); 18 | -------------------------------------------------------------------------------- /src/app/components/elements/VerticalMenu.scss: -------------------------------------------------------------------------------- 1 | .VerticalMenu { 2 | 3 | width: 200px; 4 | 5 | overflow: hidden; 6 | 7 | .Icon { 8 | padding-left: 0.1rem; 9 | margin-right: 14px; 10 | top: 0; 11 | } 12 | 13 | svg path, svg polygon { 14 | @include themify($themes) { 15 | fill: themed('textColorSecondary'); 16 | } 17 | } 18 | 19 | > li > a { 20 | color: $black; 21 | line-height: 1rem; 22 | position: relative; 23 | transition: 0.2s all ease-in-out; 24 | } 25 | 26 | > li > a:hover { 27 | text-decoration: none; 28 | @include themify($themes) { 29 | background-color: themed('backgroundColorOpaque'); 30 | } 31 | } 32 | 33 | > li.title { 34 | padding: 0.4rem; 35 | font-weight: bold; 36 | text-align:left; 37 | padding-left: 16px; 38 | @include themify($themes) { 39 | border-bottom: themed('border'); 40 | } 41 | } 42 | 43 | @media screen and (max-width: 450px) { 44 | left: -58px; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /src/app/components/elements/VideoAd.scss: -------------------------------------------------------------------------------- 1 | .video-ad { 2 | div {margin: 0 auto;} 3 | } 4 | -------------------------------------------------------------------------------- /src/app/components/elements/VotesAndComments.scss: -------------------------------------------------------------------------------- 1 | .VotesAndComments { 2 | path { 3 | transition: 0.2s all ease-in-out; 4 | @include themify($themes) { 5 | fill: themed('iconColorSecondary'); 6 | } 7 | } 8 | circle { 9 | stroke: none; 10 | } 11 | a { 12 | font-weight: normal; 13 | } 14 | white-space: nowrap; 15 | } 16 | 17 | .VotesAndComments__votes { 18 | padding-right: 1rem; 19 | @include themify($themes) { 20 | border-right: themed('borderLight'); 21 | } 22 | } 23 | 24 | .VotesAndComments__comments { 25 | padding: 0 1rem; 26 | } 27 | 28 | /* Small only */ 29 | @media screen and (max-width: 39.9375em) { 30 | .VotesAndComments { 31 | display: block; 32 | width: auto; 33 | float: right; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/app/components/modules/CommunitySettings.scss: -------------------------------------------------------------------------------- 1 | .communitySettings { 2 | label { 3 | margin: 1em 0 0; 4 | } 5 | } -------------------------------------------------------------------------------- /src/app/components/modules/ConfirmTransactionForm.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steemit/condenser/e8202015da794fc383f6dacdcfb5d0b2bbfd4a79/src/app/components/modules/ConfirmTransactionForm.scss -------------------------------------------------------------------------------- /src/app/components/modules/ConnectedSidePanel/index.jsx: -------------------------------------------------------------------------------- 1 | import { connect } from 'react-redux'; 2 | import * as userActions from 'app/redux/UserReducer'; 3 | import SidePanel from 'app/components/modules/SidePanel'; 4 | 5 | const mapStateToProps = (state, ownProps) => { 6 | return { 7 | visible: state.user.get('show_side_panel'), 8 | current: state.user.get('current'), 9 | username: state.user.getIn(['current', 'username']), 10 | ...ownProps, 11 | }; 12 | }; 13 | 14 | const mapDispatchToProps = dispatch => ({ 15 | hideSidePanel: () => dispatch(userActions.hideSidePanel()), 16 | showSidePanel: () => dispatch(userActions.showSidePanel()), 17 | }); 18 | 19 | const ConnectedSideBar = connect(mapStateToProps, mapDispatchToProps)( 20 | SidePanel 21 | ); 22 | 23 | export default ConnectedSideBar; 24 | -------------------------------------------------------------------------------- /src/app/components/modules/Header/Header.test.js: -------------------------------------------------------------------------------- 1 | /*global describe, it, before, beforeEach, after, afterEach */ 2 | import React from 'react'; 3 | import { configure, shallow } from 'enzyme'; 4 | import Adapter from 'enzyme-adapter-react-15'; 5 | 6 | import { _Header_ } from './index'; 7 | 8 | configure({ adapter: new Adapter() }); 9 | 10 | beforeEach(() => { 11 | global.$STM_Config = {}; 12 | }); 13 | 14 | describe('Header', () => { 15 | it('contains class .header', () => { 16 | global.$STM_Config = { read_only_mode: false }; 17 | const header = shallow(<_Header_ pathname={'whatever'} />); 18 | console.log(header.closest('header.header')); 19 | expect(header.closest('header.header').length).toBe(1); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/app/components/modules/LoginForm.scss: -------------------------------------------------------------------------------- 1 | .LoginForm { 2 | max-width: 28rem; 3 | margin: 1rem auto 0.5rem auto; 4 | label { 5 | text-transform: none; 6 | } 7 | form { 8 | margin-top: 1.5rem; 9 | } 10 | } 11 | .pdf-download { 12 | margin-top: 1em; 13 | margin-bottom: 1em; 14 | button { 15 | color: #1A5099; 16 | text-transform: initial; 17 | cursor: pointer; 18 | } 19 | } 20 | .sign-up { 21 | .button { 22 | background-color: transparent; 23 | padding-top: 1rem; 24 | padding-bottom: 1rem; 25 | font-size: 1.2rem; 26 | text-transform: none; 27 | } 28 | .button.hollow { 29 | border: 1px solid #ddd; 30 | color: $color-blue-black; 31 | transition: 0.2s all ease-in-out; 32 | @include font-size(16px); 33 | 34 | &:hover { 35 | border: 1px solid $color-teal-dark; 36 | color: $color-teal-dark; 37 | box-shadow: 0 2px 4px 0 rgba(0,0,0,0.05); 38 | } 39 | } 40 | em { 41 | font-weight: bold; 42 | font-style: normal; 43 | } 44 | hr { 45 | margin: 1.75rem auto 2rem auto; 46 | } 47 | p { 48 | margin-bottom: 1rem; 49 | } 50 | } 51 | 52 | .LoginForm__save-login { 53 | margin-top: 0.5rem; 54 | } 55 | -------------------------------------------------------------------------------- /src/app/components/modules/PostDrafts.scss: -------------------------------------------------------------------------------- 1 | .drafts-list { 2 | max-height: 800px; 3 | overflow-y: auto; 4 | } 5 | 6 | .drafts-option { 7 | padding: 8px; 8 | border-bottom: 1px solid #ccc; 9 | } 10 | 11 | ul.Drafts__summaries { 12 | margin-left: 0; 13 | } 14 | 15 | ul.Drafts__summaries > li { 16 | padding: 0.1em 0.5em 0 0.5em; 17 | margin-bottom: 0.8em; 18 | 19 | @include themify($themes) { 20 | border-radius: themed('roundedCorners'); 21 | border: themed('border'); 22 | background-color: themed('moduleBackgroundColor'); 23 | } 24 | 25 | &:hover { 26 | @include MQ(L) { 27 | @include themify($themes) { 28 | box-shadow: 2px 2px 3px 0 themed('contentBorderAccent'); 29 | } 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/app/components/modules/Transfer.scss: -------------------------------------------------------------------------------- 1 | .react-autocomplete-input { 2 | overflow-y: scroll; 3 | max-height: 16em; 4 | background-clip: padding-box; 5 | background-color: #fff; 6 | border: 1px solid rgba(0,0,0,0.15); 7 | bottom: auto; 8 | box-shadow: 0 6px 12px rgba(0,0,0,0.175); 9 | display: block; 10 | font-size: 14px; 11 | list-style: none; 12 | padding: 1px; 13 | position: absolute; 14 | text-align: left; 15 | z-index: 20000; 16 | } 17 | 18 | .react-autocomplete-input > div { 19 | cursor: pointer; 20 | padding: 10px; 21 | min-width: 100px; 22 | } 23 | 24 | .react-autocomplete-input > .active { 25 | background-color: #06D6A9; 26 | color: #333; 27 | @include themify($themes) { 28 | color: theme('textColorPrimary'); 29 | background-color: themed('textColorAccentHover'); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/app/components/modules/UserWallet.scss: -------------------------------------------------------------------------------- 1 | .UserWallet__claimbox { 2 | margin: 1rem 0; 3 | padding: 0.5rem 1rem; 4 | border-radius: 8px; 5 | display: flex; 6 | align-items: center; 7 | justify-content: space-between; 8 | flex-wrap: wrap; 9 | 10 | @include themify($themes) { 11 | border: themed('border'); 12 | background-color: themed('highlightBackgroundColor'); 13 | color: themed('textColorPrimary'); 14 | } 15 | 16 | .button { 17 | @extend .e-btn; 18 | @include font-size(14px); 19 | margin: 0; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/components/pages/Announcement.scss: -------------------------------------------------------------------------------- 1 | .c-sidebar__list_ann { 2 | max-width: 10rem; 3 | margin-left: 0; 4 | > li { 5 | list-style-type: none; 6 | } 7 | > li > a.active { 8 | font-weight: bold; 9 | overflow: hidden; 10 | } 11 | .show-more { 12 | font-size: 0.9rem; 13 | font-weight: bold; 14 | color: $dark-gray; 15 | } 16 | } 17 | 18 | .c-sidebar__header { 19 | font-weight: bold; 20 | font-size: 1.125rem; 21 | margin: 0 0 1rem 0; 22 | } 23 | -------------------------------------------------------------------------------- /src/app/components/pages/Benchmark.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Icon, { icons } from 'app/components/elements/Icon'; 3 | 4 | const styles = { 5 | textAlign: 'center', 6 | display: 'grid', 7 | gridTemplateColumns: 'repeat(3, 1fr)', 8 | gridAutoRows: 'minmax(80px, auto)', 9 | }; 10 | 11 | const Grid = ({ children }) =>
{children}
; 12 | 13 | class Benchmark extends React.Component { 14 | render() { 15 | return ( 16 | 17 | {icons.map(icon => ( 18 |
19 | 20 |

{icon}

21 |
22 | ))} 23 |
24 | ); 25 | } 26 | } 27 | 28 | module.exports = { 29 | path: '/benchmark', 30 | component: Benchmark, 31 | }; 32 | -------------------------------------------------------------------------------- /src/app/components/pages/CommunitiesIndex.scss: -------------------------------------------------------------------------------- 1 | .CommunitiesIndex { 2 | table {margin-top: 1em;} 3 | table tbody {background: transparent;} 4 | table tbody tr {background: transparent !important;} 5 | table th {text-align: left; font-weight: normal} 6 | table th a.title {font-weight: 400; font-size: 1.3em;} 7 | table td {vertical-align: middle; color: #666; text-align: center;} 8 | table small {color: #999; display: block;} 9 | table .button {margin: 0} 10 | 11 | &.c-sidebar__module { 12 | /* Larger than Medium */ 13 | @media screen and (min-width: 64.0625em) { 14 | padding: 1.5em 4em; 15 | } 16 | } 17 | 18 | table th { 19 | width: 600px; 20 | 21 | /* Larger than Small */ 22 | @media screen and (min-width: 40.0625em) { 23 | padding-right: 6%; 24 | } 25 | } 26 | 27 | table td { 28 | width: 40px; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/app/components/pages/CommunityRoles.scss: -------------------------------------------------------------------------------- 1 | .CommunityRoles { 2 | table tbody {background: transparent;} 3 | table tbody tr {background: transparent !important;} 4 | } 5 | 6 | .community-user--role { 7 | cursor: pointer; 8 | } -------------------------------------------------------------------------------- /src/app/components/pages/Faq.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import HelpContent from 'app/components/elements/HelpContent'; 4 | import * as appActions from 'app/redux/AppReducer'; 5 | 6 | class Faq extends React.Component { 7 | componentWillMount() { 8 | this.props.setRouteTag(); 9 | } 10 | render() { 11 | return ( 12 |
13 |
14 | 15 |
16 |
17 | ); 18 | } 19 | } 20 | 21 | module.exports = { 22 | path: 'faq.html', 23 | component: connect( 24 | (state, ownProps) => ({}), 25 | dispatch => ({ 26 | setRouteTag: () => 27 | dispatch(appActions.setRouteTag({ routeTag: 'faq' })), 28 | }) 29 | )(Faq), 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/components/pages/Index.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import SvgImage from 'app/components/elements/SvgImage'; 3 | import { translateHtml } from 'app/Translator'; 4 | 5 | export default class Index extends React.Component { 6 | render() { 7 | return ( 8 |
9 |
10 | 11 |
12 |

13 | {translateHtml( 14 | 'APP_NAME_is_a_social_media_platform_where_everyone_gets_paid_for_creating_and_curating_content' 15 | )}. 16 |

17 |
18 |
19 |
20 | ); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/app/components/pages/Login.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import LoginForm from 'app/components/modules/LoginForm'; 3 | import tt from 'counterpart'; 4 | 5 | class Login extends React.Component { 6 | render() { 7 | if (!process.env.BROWSER) { 8 | // don't render this page on the server 9 | return ( 10 |
11 |
{tt('g.loading')}..
12 |
13 | ); 14 | } 15 | return ( 16 |
17 |
18 | 19 |
20 |
21 | ); 22 | } 23 | } 24 | 25 | module.exports = { 26 | path: 'login.html', 27 | component: Login, 28 | }; 29 | -------------------------------------------------------------------------------- /src/app/components/pages/PostPage.jsx: -------------------------------------------------------------------------------- 1 | import Post from 'app/components/pages/Post'; 2 | 3 | module.exports = { 4 | path: '/(:category/)@:username/:slug', 5 | component: Post, 6 | }; 7 | -------------------------------------------------------------------------------- /src/app/components/pages/Privacy.scss: -------------------------------------------------------------------------------- 1 | .Privacy { 2 | max-width: 800px; 3 | padding: 1.5em 0 3em; 4 | .section { 5 | font-size: 100%; 6 | @include themify($themes) { 7 | fill: themed('textColorPrimary'); 8 | } 9 | padding-right: 0.5rem; 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/app/components/pages/SearchIndex.scss: -------------------------------------------------------------------------------- 1 | .search-diplay{ 2 | display: none; 3 | @media screen and (max-width: 765px) { 4 | display: block; 5 | } 6 | } -------------------------------------------------------------------------------- /src/app/components/pages/SubmitPostServerRender.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import tt from 'counterpart'; 3 | 4 | class SubmitPostServerRender extends React.Component { 5 | render() { 6 | return
{tt('g.loading')}...
; 7 | } 8 | } 9 | 10 | module.exports = { 11 | path: 'submit.html', 12 | component: SubmitPostServerRender, 13 | }; 14 | -------------------------------------------------------------------------------- /src/app/components/pages/Support.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import tt from 'counterpart'; 3 | import { APP_NAME } from 'app/client_config'; 4 | 5 | class Support extends React.Component { 6 | render() { 7 | return ( 8 |
9 |
10 |

{tt('g.APP_NAME_support', { APP_NAME })}

11 |

12 | {tt('g.please_email_questions_to')}{' '} 13 | 14 | contact@steemit.com 15 | . 16 |

17 |
18 |
19 | ); 20 | } 21 | } 22 | 23 | module.exports = { 24 | path: 'support.html', 25 | component: Support, 26 | }; 27 | -------------------------------------------------------------------------------- /src/app/components/pages/TagsIndex.scss: -------------------------------------------------------------------------------- 1 | .TagsIndex { 2 | input { 3 | margin-bottom: 0.5rem!important; 4 | } 5 | 6 | table tr { 7 | th a { 8 | position: relative; 9 | transition: 0.3s all ease-in-out; 10 | @include font-size(17px); 11 | } 12 | th a:hover::after { 13 | content: '\2193'; 14 | position: absolute; 15 | left: 100%; 16 | padding-left: 4px; 17 | } 18 | 19 | td, th { 20 | padding-right: 20px; 21 | text-align: right; 22 | &:first-child {text-align: left;} 23 | } 24 | } 25 | } 26 | 27 | -------------------------------------------------------------------------------- /src/app/components/pages/Topics.scss: -------------------------------------------------------------------------------- 1 | ul.Topics { 2 | max-width: 10rem; 3 | > li { 4 | list-style-type: none; 5 | } 6 | > li > a.active { 7 | font-weight: bold; 8 | overflow: hidden; 9 | } 10 | .show-more { 11 | font-size: 0.9rem; 12 | font-weight: bold; 13 | color: $dark-gray; 14 | } 15 | } 16 | 17 | .c-sidebar__header { 18 | font-weight: bold; 19 | font-size: 1.125rem; 20 | margin: 0 0 1rem 0; 21 | } 22 | -------------------------------------------------------------------------------- /src/app/components/pages/Tos.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import HelpContent from 'app/components/elements/HelpContent'; 4 | import * as appActions from 'app/redux/AppReducer'; 5 | 6 | class Tos extends React.Component { 7 | componentWillMount() { 8 | this.props.setRouteTag(); 9 | } 10 | render() { 11 | return ( 12 |
13 |
14 | 15 |
16 |
17 | ); 18 | } 19 | } 20 | 21 | module.exports = { 22 | path: 'tos.html', 23 | component: connect( 24 | (state, ownProps) => ({}), 25 | dispatch => ({ 26 | setRouteTag: () => 27 | dispatch(appActions.setRouteTag({ routeTag: 'tos' })), 28 | }) 29 | )(Tos), 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/components/pages/Tos.scss: -------------------------------------------------------------------------------- 1 | // FIXME this needs design review 2 | 3 | .Tos { 4 | max-width: 800px; 5 | padding: 1.5em 0 3em; 6 | .c1.h { 7 | font-weight: 600; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/app/components/pages/Welcome.jsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { connect } from 'react-redux'; 3 | import HelpContent from 'app/components/elements/HelpContent'; 4 | import * as appActions from 'app/redux/AppReducer'; 5 | 6 | class Welcome extends React.Component { 7 | componentWillMount() { 8 | this.props.setRouteTag(); 9 | } 10 | render() { 11 | return ( 12 |
13 |
14 | 15 |
16 |
17 | ); 18 | } 19 | } 20 | 21 | module.exports = { 22 | path: 'welcome', 23 | component: connect( 24 | (state, ownProps) => ({}), 25 | dispatch => ({ 26 | setRouteTag: () => 27 | dispatch(appActions.setRouteTag({ routeTag: 'welcome' })), 28 | }) 29 | )(Welcome), 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/components/pages/Welcome.scss: -------------------------------------------------------------------------------- 1 | .Welcome__banner { 2 | 3 | position: relative; 4 | 5 | .Welcome__welcome { 6 | position: absolute; 7 | width: 100%; 8 | bottom: 70%; 9 | color: white; 10 | font-size: 160%; 11 | padding-left: 38%; 12 | } 13 | 14 | .Welcome__caption { 15 | position: absolute; 16 | width: 100%; 17 | top: 65%; 18 | color: white; 19 | font-size: 115%; 20 | padding-left: 44%; 21 | padding-right: 2%; 22 | } 23 | 24 | } 25 | 26 | .HelpContent { 27 | 28 | height: inherit; 29 | 30 | p { 31 | position: relative; 32 | } 33 | h2 { 34 | margin-top: 8px; 35 | } 36 | h3 { 37 | margin-top: 0; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/es.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/fr.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/it.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%e %b', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/ja.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%e %b', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/ko.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/pl.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/uk.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/counterpart/zh.js: -------------------------------------------------------------------------------- 1 | // The translations in this file are added by default. 2 | 3 | 'use strict'; 4 | 5 | module.exports = { 6 | counterpart: { 7 | names: require('date-names/en'), 8 | pluralize: require('pluralizers/en'), 9 | 10 | formats: { 11 | date: { 12 | default: '%a, %e %b %Y', 13 | long: '%A, %B %o, %Y', 14 | short: '%b %e', 15 | }, 16 | 17 | time: { 18 | default: '%H:%M', 19 | long: '%H:%M:%S %z', 20 | short: '%H:%M', 21 | }, 22 | 23 | datetime: { 24 | default: '%a, %e %b %Y %H:%M', 25 | long: '%A, %B %o, %Y %H:%M:%S %z', 26 | short: '%e %b %H:%M', 27 | }, 28 | }, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /src/app/locales/normalize.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Normalize whitespace: replace 4 spaces at beginning of locale.js lines with tabs 4 | sed -i '' -e 's/^ / /g' *.js 5 | -------------------------------------------------------------------------------- /src/app/redux/CommunitySearchSaga.js: -------------------------------------------------------------------------------- 1 | import { put, takeEvery, call } from 'redux-saga/effects'; 2 | import * as reducer from 'app/redux/CommunitySearchReducer'; 3 | 4 | export const searchWatches = [ 5 | takeEvery('communitySearch/COMMUNITY_SEARCH_DISPATCH', communitySearchSaga), 6 | ]; 7 | 8 | export function* communitySearchSaga(action) { 9 | // const { q, s, scroll_id } = action.payload; 10 | yield put(reducer.communitySearchPending({ pending: true })); 11 | try { 12 | // TODO: Search Call goes here, waiting on API endpoint 13 | //yield put(reducer.searchResult({ , append })); 14 | } catch (error) { 15 | console.log('Search error', error); 16 | yield put(reducer.communitySearchError({ error })); 17 | } 18 | yield put(reducer.communitySearchPending({ pending: false })); 19 | } 20 | -------------------------------------------------------------------------------- /src/app/redux/GlobalSaga.js: -------------------------------------------------------------------------------- 1 | import { put, takeEvery, select } from 'redux-saga/effects'; 2 | import { fromJS, Set, List } from 'immutable'; 3 | import { getDynamicGlobalProperties } from 'app/utils/steemApi'; 4 | import * as globalActions from 'app/redux/GlobalReducer'; 5 | 6 | export const globalWatches = [takeEvery(globalActions.GET_DGP, getDGP)]; 7 | 8 | export function* getDGP() { 9 | let dgp = yield select(state => state.global.get('dgp')); 10 | if (!dgp) { 11 | dgp = yield getDynamicGlobalProperties(); 12 | yield put(globalActions.setDGP(dgp)); 13 | yield put( 14 | globalActions.setVestsPerSteem( 15 | dgp.total_vesting_shares.split(' ')[0] / 16 | dgp.total_vesting_fund_steem.split(' ')[0] 17 | ) 18 | ); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/app/redux/OffchainReducer.js: -------------------------------------------------------------------------------- 1 | import Immutable from 'immutable'; 2 | import { PropTypes } from 'react'; 3 | 4 | const defaultState = Immutable.fromJS({ user: {} }); 5 | 6 | export default function reducer(state = defaultState, action = {}) { 7 | if (action.type === 'user/SAVE_LOGIN_CONFIRM') { 8 | if (!action.payload) { 9 | state = state.set('account', null); 10 | } 11 | } 12 | return state; 13 | } 14 | -------------------------------------------------------------------------------- /src/app/redux/OffchainReducer.test.js: -------------------------------------------------------------------------------- 1 | import { Map } from 'immutable'; 2 | import reducer from './OffchainReducer'; 3 | 4 | const mockAction = { 5 | type: 'user/SAVE_LOGIN_CONFIRM', 6 | }; 7 | 8 | const mockActionWithPayload = { ...mockAction, payload: 'Foo Barman' }; 9 | 10 | describe('offchain reducer', () => { 11 | it('should provide a nice initial state, with any payload', () => { 12 | const initial = reducer(); 13 | const expected = Map({ user: Map({}) }); 14 | expect(initial).toEqual(expected); 15 | const withPayload = reducer(initial, mockActionWithPayload); 16 | expect(withPayload).toEqual(expected); 17 | }); 18 | it('should return an account of null when action has no payload', () => { 19 | const initial = reducer(); 20 | const account = reducer(initial, mockAction); 21 | expect(account).toEqual(Map({ user: Map({}), account: null })); 22 | }); 23 | }); 24 | -------------------------------------------------------------------------------- /src/app/redux/PollingSaga.js: -------------------------------------------------------------------------------- 1 | import { put, call, take, race } from 'redux-saga/effects'; 2 | import { delay } from 'redux-saga'; 3 | 4 | const START_POLLING = 'START_POLLING'; 5 | const STOP_POLLING = 'STOP_POLLING'; 6 | 7 | function* poll(action) { 8 | const params = { ...action.payload }; 9 | while (true) { 10 | try { 11 | yield put(params.pollAction(params.pollPayload)); 12 | yield call(delay, params.delay); 13 | } catch (e) { 14 | // If there's an error, polling will stop. 15 | yield put(stopPolling()); 16 | } 17 | } 18 | } 19 | 20 | export function* watchPollingTasks() { 21 | while (true) { 22 | const action = yield take(START_POLLING); 23 | yield race([call(poll, action), take(STOP_POLLING)]); 24 | } 25 | } 26 | 27 | export const startPolling = payload => { 28 | return { 29 | type: START_POLLING, 30 | payload, 31 | }; 32 | }; 33 | 34 | export const stopPolling = payload => { 35 | return { 36 | type: STOP_POLLING, 37 | payload, 38 | }; 39 | }; 40 | -------------------------------------------------------------------------------- /src/app/redux/UserProfilesReducer.js: -------------------------------------------------------------------------------- 1 | import { fromJS } from 'immutable'; 2 | 3 | // Action constants 4 | const ADD_USER_PROFILE = 'user_profile/ADD'; 5 | 6 | const defaultState = fromJS({ 7 | profiles: {}, 8 | }); 9 | 10 | export default function reducer(state = defaultState, action) { 11 | const payload = action.payload; 12 | 13 | switch (action.type) { 14 | case ADD_USER_PROFILE: { 15 | if (payload) { 16 | return state.setIn( 17 | ['profiles', payload.username], 18 | fromJS(payload.account) 19 | ); 20 | } 21 | return state; 22 | } 23 | 24 | default: 25 | return state; 26 | } 27 | } 28 | 29 | // Action creators 30 | export const addProfile = payload => ({ 31 | type: ADD_USER_PROFILE, 32 | payload, 33 | }); 34 | -------------------------------------------------------------------------------- /src/app/redux/UserProfilesSaga.js: -------------------------------------------------------------------------------- 1 | import { call, put, takeLatest } from 'redux-saga/effects'; 2 | import * as userProfileActions from './UserProfilesReducer'; 3 | import { callBridge } from 'app/utils/steemApi'; 4 | 5 | const FETCH_PROFILE = 'userProfilesSaga/FETCH_PROFILE'; 6 | 7 | export const userProfilesWatches = [ 8 | takeLatest(FETCH_PROFILE, fetchUserProfile), 9 | ]; 10 | 11 | export function* fetchUserProfile(action) { 12 | const { account, observer } = action.payload; 13 | const ret = yield call(callBridge, 'get_profile', { account, observer }); 14 | if (!ret) throw new Error('Account not found'); 15 | yield put( 16 | userProfileActions.addProfile({ username: account, account: ret }) 17 | ); 18 | } 19 | 20 | // Action creators 21 | export const actions = { 22 | fetchProfile: payload => ({ 23 | type: FETCH_PROFILE, 24 | payload, 25 | }), 26 | }; 27 | -------------------------------------------------------------------------------- /src/app/redux/constants.js: -------------------------------------------------------------------------------- 1 | export default { 2 | FETCH_DATA_BATCH_SIZE: 20, 3 | MAX_BATCHES: 10, 4 | FETCH_DATA_EXPIRE_SEC: 30, 5 | }; 6 | -------------------------------------------------------------------------------- /src/app/redux/tests/global.test.js: -------------------------------------------------------------------------------- 1 | /*global describe, it, before, beforeEach, after, afterEach */ 2 | import Immutable from 'immutable'; 3 | import reducer, * as globalActions from '../GlobalReducer'; 4 | 5 | describe('global reducer', () => { 6 | it('should return empty state', () => { 7 | const reduced = reducer(undefined, {}); 8 | 9 | expect(reduced.toJS()).toEqual({ status: {} }); 10 | }); 11 | 12 | it('should apply new global state', () => { 13 | const state = Immutable.fromJS(require('./global.json')); 14 | const reduced = reducer(undefined, globalActions.receiveState(state)); 15 | //const action = {type: 'global/RECEIVE_STATE', payload: state}; 16 | expect(reduced.toJS()).toEqual(state.toJS()); 17 | }); 18 | }); 19 | -------------------------------------------------------------------------------- /src/app/utils/Accessors.js: -------------------------------------------------------------------------------- 1 | export function immutableAccessor(obj, ...keys) { 2 | if (!obj) return {}; 3 | if (keys.length === 1) return obj.get(keys[0]); 4 | return keys.reduce((res, key) => { 5 | res[key] = obj.get(key); 6 | return res; 7 | }, {}); 8 | } 9 | 10 | export function objAccessor(obj, ...keys) { 11 | if (!obj) return {}; 12 | if (keys.length === 1) return obj[keys[0]]; 13 | return keys.reduce((res, key) => { 14 | res[key] = obj[key]; 15 | return res; 16 | }, {}); 17 | } 18 | -------------------------------------------------------------------------------- /src/app/utils/AffiliationMap.js: -------------------------------------------------------------------------------- 1 | const map = { 2 | //steemit 3 | justinw: 'steemit', 4 | elipowell: 'steemit', 5 | maitland: 'steemit', 6 | steemitblog: 'steemit', 7 | steemitdev: 'steemit', 8 | justinsunsteemit: 'steemit', 9 | 10 | /* 11 | //steem monsters 12 | steemmonsters: 'sm', 13 | 'steem.monsters': 'sm', 14 | aggroed: 'sm', 15 | yabapmatt: 'sm', 16 | */ 17 | }; 18 | 19 | export default map; 20 | -------------------------------------------------------------------------------- /src/app/utils/AppPropTypes.js: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | const Children = PropTypes.oneOfType([ 4 | PropTypes.arrayOf(PropTypes.node), 5 | PropTypes.node, 6 | ]); 7 | 8 | export default { Children }; 9 | -------------------------------------------------------------------------------- /src/app/utils/Common.js: -------------------------------------------------------------------------------- 1 | export function isPhone() { 2 | if (/(iPhone|iPad|iPod|iOS|Android)/i.test(navigator.userAgent)) { 3 | //移动端 4 | return true; 5 | } 6 | return false; 7 | } 8 | -------------------------------------------------------------------------------- /src/app/utils/ContentPreview.js: -------------------------------------------------------------------------------- 1 | export default function contentPreview(content, length) { 2 | const txt = content.replace(/ +/g, ' '); // only 1 space in a row 3 | const max_words = length / 7; 4 | let words = 0; 5 | let res = ''; 6 | for (let i = 0; i < txt.length; i++) { 7 | const ch = txt.charAt(i); 8 | if (ch === '.') break; 9 | if (ch === ' ' || ch === '\n') { 10 | words++; 11 | if (words > max_words) break; 12 | if (i > length) break; 13 | } 14 | res += ch; 15 | } 16 | return res; 17 | } 18 | -------------------------------------------------------------------------------- /src/app/utils/DMCAUserList.js: -------------------------------------------------------------------------------- 1 | const list = ` 2 | the-gaming-llama 3 | cmgsteems 4 | iamgod 5 | bl-transporter 6 | braini 7 | cracked-games 8 | gautampartapsoni 9 | jimreitz 10 | bitchminer 11 | nikapelex 12 | ` 13 | .trim() 14 | .split('\n'); 15 | 16 | export default list; 17 | -------------------------------------------------------------------------------- /src/app/utils/DomUtils.js: -------------------------------------------------------------------------------- 1 | export function findParent(el, class_name) { 2 | if ( 3 | el.className && 4 | el.className.indexOf && 5 | el.className.indexOf(class_name) !== -1 6 | ) 7 | return el; 8 | if (el.parentNode) return findParent(el.parentNode, class_name); 9 | return null; 10 | } 11 | 12 | // From https://stackoverflow.com/a/18284182 13 | export function getViewportDimensions(w) { 14 | // Bail if server-side 15 | if (!process.env.BROWSER) return { w: 0, h: 0 }; 16 | 17 | // Use the specified window or the current window if no argument 18 | w = w || window; 19 | 20 | // This works for all browsers except IE8 and before 21 | if (w.innerWidth != null) return { w: w.innerWidth, h: w.innerHeight }; 22 | 23 | // For IE (or any browser) in Standards mode 24 | var d = w.document; 25 | if (document.compatMode == 'CSS1Compat') 26 | return { 27 | w: d.documentElement.clientWidth, 28 | h: d.documentElement.clientHeight, 29 | }; 30 | 31 | // For browsers in Quirks mode 32 | return { w: d.body.clientWidth, h: d.body.clientHeight }; 33 | } 34 | -------------------------------------------------------------------------------- /src/app/utils/FormatCoins.js: -------------------------------------------------------------------------------- 1 | import { 2 | APP_NAME, 3 | LIQUID_TOKEN, 4 | LIQUID_TOKEN_UPPERCASE, 5 | DEBT_TOKEN, 6 | DEBT_TOKEN_SHORT, 7 | CURRENCY_SIGN, 8 | VESTING_TOKEN, 9 | } from 'app/client_config'; 10 | 11 | // TODO add comments and explanations 12 | // TODO change name to formatCoinTypes? 13 | // TODO make use of DEBT_TICKER etc defined in config/clietn_config 14 | export function formatCoins(string) { 15 | // return null or undefined if string is not provided 16 | if (!string) return string; 17 | // TODO use .to:owerCase() ? for string normalisation 18 | string = string 19 | .replace('SBD', DEBT_TOKEN_SHORT) 20 | .replace('SD', DEBT_TOKEN_SHORT) 21 | .replace('Steem Power', VESTING_TOKEN) 22 | .replace('STEEM POWER', VESTING_TOKEN) 23 | .replace('Steem', LIQUID_TOKEN) 24 | .replace('STEEM', LIQUID_TOKEN_UPPERCASE) 25 | .replace('$', CURRENCY_SIGN); 26 | return string; 27 | } 28 | -------------------------------------------------------------------------------- /src/app/utils/FormatDecimal.test.js: -------------------------------------------------------------------------------- 1 | import { formatDecimal } from './ParsersAndFormatters'; 2 | 3 | describe('formatDecimal', () => { 4 | it('should format decimals', () => { 5 | const test_cases = [ 6 | [100.0, '100.00'], 7 | [101, '101.00'], 8 | ['102', '102.00'], 9 | [1000.12, '1,000.12'], 10 | [100000, '100,000.00'], 11 | [1000000000000.0, '1,000,000,000,000.00'], 12 | [-1000, '-1,000.00'], 13 | [501695.505, '501,695.51'], 14 | [5.0, '5.00'], 15 | [5, '5.00'], 16 | ]; 17 | test_cases.forEach(v => { 18 | expect(formatDecimal(v[0]).join('')).toBe(v[1]); 19 | }); 20 | }); 21 | }); 22 | -------------------------------------------------------------------------------- /src/app/utils/FrontendLogger.js: -------------------------------------------------------------------------------- 1 | import { serverApiRecordEvent } from 'app/utils/ServerApiClient'; 2 | 3 | /** 4 | * Handles window error events by logging to overseer. 5 | * 6 | * This function relies on these globals: 7 | * - process.env.VERSION 8 | * - window.location.href 9 | * 10 | * @param {ErrorEvent} event 11 | */ 12 | export default function frontendLogger(event) { 13 | if (window.$STM_csrf) { 14 | const report = formatEventReport( 15 | event, 16 | window.location.href, 17 | process.env.VERSION 18 | ); 19 | serverApiRecordEvent('client_error', report); 20 | } 21 | } 22 | 23 | /** 24 | * Format a browser error event report 25 | * 26 | * @param {ErrorEvent} event 27 | * @param {string} href 28 | * @param {string} version 29 | * 30 | * @return {object} 31 | */ 32 | export function formatEventReport(event, href, version) { 33 | const trace = 34 | typeof event.error === 'object' && 35 | event.error !== null && 36 | typeof event.error.stack === 'string' 37 | ? event.error.stack 38 | : false; 39 | return { 40 | trace, 41 | message: event.message, 42 | href, 43 | version, 44 | }; 45 | } 46 | -------------------------------------------------------------------------------- /src/app/utils/GDPRUserList.js: -------------------------------------------------------------------------------- 1 | const list = ` 2 | mateja.klaric 3 | xondra 4 | tgylhn 5 | vichkovski 6 | wizzymt 7 | thedarkoverlord 8 | twoblokestrading 9 | ruttydm 10 | mlcuk 11 | m4r1a 12 | bridgenit 13 | bitchminer 14 | bisade 15 | boy666 16 | casually 17 | nayardu92 18 | djdarkstorm 19 | cristinaluchi 20 | dennis.spiedt 21 | sebtarnowski 22 | mihailm 23 | ardaia 24 | jemand 25 | chiefadu 26 | nikapelex 27 | ` 28 | .trim() 29 | .split('\n'); 30 | 31 | export default list; 32 | -------------------------------------------------------------------------------- /src/app/utils/Html.js: -------------------------------------------------------------------------------- 1 | export const htmlDecode = txt => 2 | txt.replace(/&[a-z]+;/g, ch => { 3 | const char = htmlCharMap[ch.substring(1, ch.length - 1)]; 4 | return char ? char : ch; 5 | }); 6 | 7 | const htmlCharMap = { 8 | amp: '&', 9 | quot: '"', 10 | lsquo: '‘', 11 | rsquo: '’', 12 | sbquo: '‚', 13 | ldquo: '“', 14 | rdquo: '”', 15 | bdquo: '„', 16 | hearts: '♥', 17 | trade: '™', 18 | hellip: '…', 19 | pound: '£', 20 | copy: '', 21 | }; 22 | -------------------------------------------------------------------------------- /src/app/utils/ImageUserBlockList.js: -------------------------------------------------------------------------------- 1 | const list = ` 2 | iamgod 3 | ` 4 | .trim() 5 | .split('\n'); 6 | 7 | export default list; 8 | -------------------------------------------------------------------------------- /src/app/utils/RPCNode.js: -------------------------------------------------------------------------------- 1 | import { api } from '@steemit/steem-js'; 2 | 3 | export const LOCALSTORAGE_RPC_NODE_KEY = 'steemSelectedRpc'; 4 | 5 | export function changeRPCNodeToDefault( 6 | rpcNode = $STM_Config.steemd_connection_client 7 | ) { 8 | console.log(`>> RPC Node changed to ${rpcNode}`); 9 | 10 | localStorage.setItem(LOCALSTORAGE_RPC_NODE_KEY, rpcNode); 11 | 12 | api.setOptions({ 13 | url: rpcNode, 14 | }); 15 | } 16 | 17 | export function getCurrentRPCNode() { 18 | return localStorage.getItem(LOCALSTORAGE_RPC_NODE_KEY); 19 | } 20 | -------------------------------------------------------------------------------- /src/app/utils/ReduxForms.js: -------------------------------------------------------------------------------- 1 | export const cleanReduxInput = i => { 2 | // Remove all props that don't belong. Triggers React warnings. 3 | const { 4 | name, 5 | placeholder, 6 | label, 7 | value, 8 | checked, 9 | onChange, 10 | onBlur, 11 | onFocus, 12 | } = i; 13 | const ret = { 14 | name, 15 | placeholder, 16 | label, 17 | value, 18 | checked, 19 | onChange, 20 | onBlur, 21 | onFocus, 22 | }; 23 | if (ret.value == null) delete ret.value; 24 | if (ret.label == null) delete ret.label; 25 | if (ret.type == null) delete ret.type; 26 | return ret; 27 | }; 28 | -------------------------------------------------------------------------------- /src/app/utils/RemarkableStripper.js: -------------------------------------------------------------------------------- 1 | import Remarkable from 'remarkable'; 2 | 3 | const remarkable = new Remarkable(); 4 | export default remarkable; 5 | 6 | /** Removes all markdown leaving just plain text */ 7 | const remarkableStripper = md => { 8 | md.renderer.render = (tokens, options, env) => { 9 | let str = ''; 10 | for (let i = 0; i < tokens.length; i++) { 11 | if (tokens[i].type === 'inline') { 12 | str += md.renderer.render(tokens[i].children, options, env); 13 | } else { 14 | // console.log('content', tokens[i]) 15 | const content = tokens[i].content; 16 | str += (content || '') + ' '; 17 | } 18 | } 19 | return str; 20 | }; 21 | }; 22 | 23 | remarkable.use(remarkableStripper); // removes all markdown 24 | -------------------------------------------------------------------------------- /src/app/utils/SlateEditor/Align.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class Align extends React.Component { 4 | getAlignClass = () => { 5 | const { node } = this.props; 6 | switch (node.data.get('align')) { 7 | case 'text-right': 8 | return 'text-right'; 9 | case 'text-left': 10 | return 'text-left'; 11 | case 'text-center': 12 | return 'text-center'; 13 | case 'pull-right': 14 | return 'pull-right'; 15 | case 'pull-left': 16 | return 'pull-left'; 17 | } 18 | }; 19 | 20 | render = () => { 21 | const { node, attributes, children } = this.props; 22 | const className = this.getAlignClass(); 23 | 24 | return ( 25 |
26 | {children} 27 |
28 | ); 29 | }; 30 | } 31 | -------------------------------------------------------------------------------- /src/app/utils/SlateEditor/DemoState.js: -------------------------------------------------------------------------------- 1 | export default { 2 | nodes: [ 3 | { 4 | kind: 'block', 5 | type: 'paragraph', 6 | nodes: [ 7 | { 8 | kind: 'text', 9 | text: '', 10 | }, 11 | ], 12 | }, 13 | ], 14 | }; 15 | -------------------------------------------------------------------------------- /src/app/utils/SlateEditor/HRule.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class HRule extends React.Component { 4 | render() { 5 | const { node, state } = this.props; 6 | const isFocused = state.selection.hasEdgeIn(node); 7 | const className = isFocused ? 'active' : null; 8 | return
; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/app/utils/SlateEditor/Helpers.js: -------------------------------------------------------------------------------- 1 | const findParentTag = (el, tag, depth = 0) => { 2 | if (!el) return null; 3 | if (el.tagName == tag) return el; 4 | return findParentTag(el.parentNode, tag, depth + 1); 5 | }; 6 | 7 | export const getCollapsedClientRect = () => { 8 | const selection = document.getSelection(); 9 | if ( 10 | selection.rangeCount === 0 || 11 | !selection.getRangeAt || 12 | !selection.getRangeAt(0) || 13 | !selection.getRangeAt(0).startContainer || 14 | !selection.getRangeAt(0).startContainer.getBoundingClientRect 15 | ) { 16 | return null; 17 | } 18 | 19 | const node = selection.getRangeAt(0).startContainer; 20 | if (!findParentTag(node, 'P')) return; // only show sidebar at the beginning of an empty

21 | 22 | const rect = node.getBoundingClientRect(); 23 | return rect; 24 | }; 25 | -------------------------------------------------------------------------------- /src/app/utils/SlateEditor/Link.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class Link extends React.Component { 4 | state = {}; 5 | 6 | componentDidMount() {} 7 | 8 | render() { 9 | const { node, state, attributes, children } = this.props; 10 | 11 | const isFocused = state.selection.hasEdgeIn(node); 12 | const className = isFocused ? 'active' : null; 13 | const href = node.data.get('href'); 14 | 15 | return ( 16 | 17 | {children} 18 | 19 | ); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/app/utils/SteemKeychain.js: -------------------------------------------------------------------------------- 1 | import { isLoggedIn, extractLoginData } from 'app/utils/UserUtil'; 2 | 3 | /** 4 | * 5 | * @returns {boolean} 6 | */ 7 | export function hasCompatibleKeychain() { 8 | return ( 9 | window.steem_keychain && 10 | window.steem_keychain.requestSignBuffer && 11 | window.steem_keychain.requestBroadcast && 12 | window.steem_keychain.requestSignedCall 13 | ); 14 | } 15 | 16 | /** 17 | * 18 | * @returns {boolean} 19 | */ 20 | export function isLoggedInWithKeychain() { 21 | if (!isLoggedIn()) { 22 | return false; 23 | } 24 | if (!hasCompatibleKeychain()) { 25 | // possible to log in w/ keychain, then disable plugin 26 | return false; 27 | } 28 | const data = localStorage.getItem('autopost2'); 29 | const [ 30 | username, 31 | password, 32 | memoWif, 33 | login_owner_pubkey, 34 | login_with_keychain, 35 | ] = extractLoginData(data); 36 | return !!login_with_keychain; 37 | } 38 | -------------------------------------------------------------------------------- /src/app/utils/UserUtil.js: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * @returns {boolean} 4 | */ 5 | export const isLoggedIn = () => 6 | typeof localStorage !== 'undefined' && !!localStorage.getItem('autopost2'); 7 | 8 | /** 9 | * 10 | * @returns {string} 11 | */ 12 | export const packLoginData = ( 13 | username, 14 | password, 15 | memoWif, 16 | login_owner_pubkey, 17 | login_with_keychain 18 | ) => 19 | new Buffer( 20 | `${username}\t${password}\t${memoWif || ''}\t${login_owner_pubkey || 21 | ''}\t${login_with_keychain || ''}` 22 | ).toString('hex'); 23 | 24 | /** 25 | * 26 | * @returns {array} [username, password, memoWif, login_owner_pubkey, login_with_keychain] 27 | */ 28 | export const extractLoginData = data => 29 | new Buffer(data, 'hex').toString().split('\t'); 30 | 31 | export default { 32 | isLoggedIn, 33 | extractLoginData, 34 | }; 35 | -------------------------------------------------------------------------------- /src/app/utils/VerifiedExchangeList.js: -------------------------------------------------------------------------------- 1 | const list = ` 2 | bittrex 3 | blocktrades 4 | changelly 5 | deepcrypto8 6 | gopax-deposit 7 | hitbtc-exchange 8 | poloniex 9 | upbit-exchange 10 | ` 11 | .trim() 12 | .split('\n'); 13 | 14 | export default list; 15 | -------------------------------------------------------------------------------- /src/app/utils/__mocks__/GDPRUserList.js: -------------------------------------------------------------------------------- 1 | export default ['gdpr']; 2 | -------------------------------------------------------------------------------- /src/app/utils/emit.js: -------------------------------------------------------------------------------- 1 | const EventEmitter = require('events').EventEmitter; 2 | const emit = new EventEmitter(); 3 | export { emit }; 4 | -------------------------------------------------------------------------------- /src/app/utils/userIllegalContent.js: -------------------------------------------------------------------------------- 1 | const list = ` 2 | aplomb 3 | ` 4 | .trim() 5 | .split('\n'); 6 | 7 | export default list; 8 | -------------------------------------------------------------------------------- /src/server/redirects.js: -------------------------------------------------------------------------------- 1 | import koa_router from 'koa-router'; 2 | 3 | const redirects = [ 4 | // example: [/\/about(\d+)-(.+)/, '/about?$0:$1', 302], 5 | [/^\/recent\/?$/, '/created'], 6 | [/^\/pick_account.*/, 'https://signup.steemit.com'], 7 | ]; 8 | 9 | export default function useRedirects(app) { 10 | const router = koa_router(); 11 | 12 | app.use(router.routes()); 13 | 14 | redirects.forEach(r => { 15 | router.get(r[0], function*() { 16 | const dest = Object.keys(this.params).reduce( 17 | (value, key) => value.replace('$' + key, this.params[key]), 18 | r[1] 19 | ); 20 | console.log( 21 | `server redirect: [${r[0]}] ${this.request.url} -> ${dest}` 22 | ); 23 | this.status = r[2] || 301; 24 | this.redirect(dest); 25 | }); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /src/server/requesttimings.js: -------------------------------------------------------------------------------- 1 | import RequestTimer from './utils/RequestTimer'; 2 | 3 | function requestTime(statsLoggerClient) { 4 | return function*(next) { 5 | this.state.requestTimer = new RequestTimer( 6 | statsLoggerClient, 7 | 'request', 8 | `method=${this.request.method} path=${this.request.path}` 9 | ); 10 | 11 | yield* next; 12 | 13 | this.state.requestTimer.finish(); 14 | }; 15 | } 16 | 17 | module.exports = requestTime; 18 | -------------------------------------------------------------------------------- /src/server/server-error.jsx: -------------------------------------------------------------------------------- 1 | import React, { Component } from 'react'; 2 | 3 | class ServerError extends Component { 4 | render() { 5 | return ( 6 |

10 | 11 |
20 |

Sorry.

21 |

Looks like something went wrong on our end.

22 |

23 | Head back to Steemit homepage. 24 |

25 |
26 |
27 | ); 28 | } 29 | } 30 | 31 | export default ServerError; 32 | -------------------------------------------------------------------------------- /src/server/utils/StatsLoggerClient.js: -------------------------------------------------------------------------------- 1 | import SDC from 'statsd-client'; 2 | 3 | /** 4 | * In production, log stats to statsd. 5 | * In dev, console.log 'em. 6 | */ 7 | export default class StatsLoggerClient { 8 | constructor(STATSD_IP) { 9 | if (STATSD_IP) { 10 | this.SDC = new SDC({ 11 | host: STATSD_IP, 12 | prefix: 'condenser', 13 | }); 14 | } else { 15 | console.log( 16 | 'StatsLoggerClient: no server available, logging to console.' 17 | ); 18 | // Implement debug loggers here, as any new calls are added in methods below. 19 | this.SDC = { 20 | timing() { 21 | console.log('StatsLoggerClient call: ', arguments); 22 | }, 23 | }; 24 | } 25 | } 26 | 27 | /** 28 | * Given an array of timer tuples that look like [namespace, value] 29 | * log them all to statsd. 30 | */ 31 | logTimers(tuples) { 32 | const timestamp = +new Date(); 33 | tuples.map(tuple => { 34 | this.SDC.timing(tuple[0], tuple[1]); 35 | }); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/shared/RootSaga.js: -------------------------------------------------------------------------------- 1 | import { all } from 'redux-saga/effects'; 2 | import { globalWatches } from 'app/redux/GlobalSaga'; 3 | import { fetchDataWatches } from 'app/redux/FetchDataSaga'; 4 | import { sharedWatches } from 'app/redux/SagaShared'; 5 | import { userWatches } from 'app/redux/UserSaga'; 6 | import { authWatches } from 'app/redux/AuthSaga'; 7 | import { transactionWatches } from 'app/redux/TransactionSaga'; 8 | import { communityWatches } from 'app/redux/CommunitySaga'; 9 | import { userProfilesWatches } from 'app/redux/UserProfilesSaga'; 10 | import { searchWatches } from 'app/redux/SearchSaga'; 11 | import { watchPollingTasks } from 'app/redux/PollingSaga'; 12 | 13 | export default function* rootSaga() { 14 | yield all([ 15 | ...userWatches, // keep first to remove keys early when a page change happens 16 | ...globalWatches, 17 | ...fetchDataWatches, 18 | ...sharedWatches, 19 | ...authWatches, 20 | ...transactionWatches, 21 | ...communityWatches, 22 | ...userProfilesWatches, 23 | ...searchWatches, 24 | watchPollingTasks(), 25 | ]); 26 | } 27 | -------------------------------------------------------------------------------- /src/shared/api_client/ChainConfig.js: -------------------------------------------------------------------------------- 1 | import * as steem from '@steemit/steem-js'; 2 | 3 | steem.config.set('address_prefix', 'STM'); 4 | 5 | let chain_id = ''; 6 | for (let i = 0; i < 32; i++) chain_id += '00'; 7 | 8 | module.exports = { 9 | address_prefix: 'STM', 10 | expire_in_secs: 15, 11 | chain_id, 12 | }; 13 | -------------------------------------------------------------------------------- /src/shared/api_client/index.js: -------------------------------------------------------------------------------- 1 | import ChainConfig from './ChainConfig'; 2 | 3 | module.exports = { 4 | ChainConfig, 5 | }; 6 | -------------------------------------------------------------------------------- /src/shared/clash/object2json.js: -------------------------------------------------------------------------------- 1 | const expo = { 2 | ifObjectToJSON: item => { 3 | if (typeof item === 'object') { 4 | try { 5 | return JSON.stringify(item); 6 | } catch (e) { 7 | return item; 8 | } 9 | } 10 | return item; 11 | }, 12 | 13 | ifStringParseJSON: item => { 14 | if (typeof item === 'string') { 15 | try { 16 | return JSON.parse(item); 17 | } catch (e) { 18 | return item; 19 | } 20 | } 21 | return item; 22 | }, 23 | }; 24 | export { expo as default }; 25 | 26 | exports.test = { 27 | run: () => { 28 | let ob = { a: 2 }, 29 | st = '{"a":2}'; 30 | console.log('test eq1', expo.ifObjectToJSON(ob) == st); 31 | console.log('test eq2', expo.ifStringParseJSON(st).a == ob.a); 32 | }, 33 | }; 34 | -------------------------------------------------------------------------------- /src/shared/constants.js: -------------------------------------------------------------------------------- 1 | export const PARAM_VIEW_MODE = 'view_mode'; 2 | export const VIEW_MODE_WHISTLE = 'whistle'; 3 | export const WHISTLE_SIGNUP_COMPLETE = 'whistle_signup_complete'; 4 | let signupUrl = 'https://signup.steemit.com'; 5 | if (typeof window !== 'undefined') { 6 | signupUrl = 7 | window.location.hostname.indexOf('steemitdev.com') === -1 8 | ? 'https://signup.steemit.com' 9 | : 'https://signup.steemitdev.com'; 10 | } else if (process.env.SERVER_NAME) { 11 | signupUrl = `https://signup.${process.env.SERVER_NAME}`; 12 | } 13 | export const SIGNUP_URL = signupUrl; 14 | export const SUBMIT_FORM_ID = 'submitStory'; 15 | -------------------------------------------------------------------------------- /webpack/debug.config.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack'); 2 | const git = require('git-rev-sync'); 3 | const baseConfig = require('./base.config'); 4 | 5 | module.exports = { 6 | ...baseConfig, 7 | devtool: 'cheap-module-eval-source-map', 8 | output: { 9 | ...baseConfig.output, 10 | publicPath: '/assets/', 11 | }, 12 | module: { 13 | ...baseConfig.module, 14 | rules: [ 15 | ...baseConfig.module.rules, 16 | ], 17 | }, 18 | plugins: [ 19 | new webpack.DefinePlugin({ 20 | 'process.env': { 21 | BROWSER: JSON.stringify(true), 22 | NODE_ENV: JSON.stringify('development'), 23 | VERSION: JSON.stringify(git.long()), 24 | } 25 | }), 26 | ...baseConfig.plugins, 27 | ], 28 | }; 29 | -------------------------------------------------------------------------------- /webpack/dev-server.js: -------------------------------------------------------------------------------- 1 | var fs = require('fs'); 2 | if(!fs.existsSync('tmp')) 3 | fs.mkdirSync('tmp'); 4 | 5 | process.env.BABEL_ENV = 'browser'; 6 | process.env.NODE_ENV = 'development'; 7 | 8 | const Koa = require('koa'); 9 | const webpack = require('webpack'); 10 | 11 | const webpackDevConfig = require('./dev.config'); 12 | 13 | const app = new Koa(); 14 | const compiler = webpack(webpackDevConfig); 15 | 16 | const PORT = process.env.PORT ? parseInt(process.env.PORT)+1 : 8081; 17 | 18 | const server_options = { 19 | publicPath: '/assets/', 20 | hot: true, 21 | stats: { 22 | assets: true, 23 | colors: true, 24 | version: false, 25 | hash: false, 26 | timings: true, 27 | chunks: false, 28 | chunkModules: false 29 | } 30 | }; 31 | 32 | app.use(require('koa-webpack-dev-middleware')(compiler, server_options)); 33 | app.use(require('koa-webpack-hot-middleware')(compiler)); 34 | 35 | app.listen(PORT, '0.0.0.0', () => { 36 | console.log('`webpack-dev-server` listening on port %s', PORT); 37 | }); 38 | --------------------------------------------------------------------------------