diff options
Diffstat (limited to 'packages/website')
87 files changed, 805 insertions, 8522 deletions
diff --git a/packages/website/less/all.less b/packages/website/less/all.less index 113dff0be..c62db0d20 100644 --- a/packages/website/less/all.less +++ b/packages/website/less/all.less @@ -2,10 +2,6 @@ body { font-family: 'Roboto'; } -.robotoMono { - font-family: 'Roboto Mono'; -} - a { color: black; } diff --git a/packages/website/package.json b/packages/website/package.json index ca1b596f3..248f9d14c 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -18,20 +18,20 @@ "author": "Fabio Berger", "license": "Apache-2.0", "dependencies": { - "0x.js": "^0.33.0", + "@0xproject/react-docs": "^0.0.1", + "@0xproject/react-shared": "^0.0.1", "@0xproject/subproviders": "^0.6.0", "@0xproject/utils": "^0.4.0", + "0x.js": "^0.33.0", "accounting": "^0.4.1", "basscss": "^8.0.3", "blockies": "^0.0.2", - "compare-versions": "^3.0.1", "dateformat": "^2.0.0", "deep-equal": "^1.0.1", "dharma-loan-frame": "^0.0.12", "ethereumjs-tx": "^1.3.3", "ethereumjs-util": "^5.1.1", "find-versions": "^2.0.0", - "is-mobile": "^0.2.2", "jsonschema": "^1.2.0", "less": "^2.7.2", "lodash": "^4.17.4", @@ -43,7 +43,6 @@ "react-document-title": "^2.0.3", "react-dom": "15.6.1", "react-ga": "^2.4.1", - "react-highlight": "0xproject/react-highlight", "react-html5video": "^2.1.0", "react-inlinesvg": "^0.5.5", "react-markdown": "^3.2.2", diff --git a/packages/website/public/css/atom-one-light.css b/packages/website/public/css/atom-one-light.css deleted file mode 100644 index d5bd1d2a9..000000000 --- a/packages/website/public/css/atom-one-light.css +++ /dev/null @@ -1,96 +0,0 @@ -/* - -Atom One Light by Daniel Gamage -Original One Light Syntax theme from https://github.com/atom/one-light-syntax - -base: #fafafa -mono-1: #383a42 -mono-2: #686b77 -mono-3: #a0a1a7 -hue-1: #0184bb -hue-2: #4078f2 -hue-3: #a626a4 -hue-4: #50a14f -hue-5: #e45649 -hue-5-2: #c91243 -hue-6: #986801 -hue-6-2: #c18401 - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - color: #383a42; - background: #fafafa; -} - -.hljs-comment, -.hljs-quote { - color: #a0a1a7; - font-style: italic; -} - -.hljs-doctag, -.hljs-keyword, -.hljs-formula { - color: #a626a4; -} - -.hljs-section, -.hljs-name, -.hljs-selector-tag, -.hljs-deletion, -.hljs-subst { - color: #e45649; -} - -.hljs-literal { - color: #0184bb; -} - -.hljs-string, -.hljs-regexp, -.hljs-addition, -.hljs-attribute, -.hljs-meta-string { - color: #50a14f; -} - -.hljs-built_in, -.hljs-class .hljs-title { - color: #c18401; -} - -.hljs-attr, -.hljs-variable, -.hljs-template-variable, -.hljs-type, -.hljs-selector-class, -.hljs-selector-attr, -.hljs-selector-pseudo, -.hljs-number { - color: #986801; -} - -.hljs-symbol, -.hljs-bullet, -.hljs-link, -.hljs-meta, -.hljs-selector-id, -.hljs-title { - color: #4078f2; -} - -.hljs-emphasis { - font-style: italic; -} - -.hljs-strong { - font-weight: bold; -} - -.hljs-link { - text-decoration: underline; -} diff --git a/packages/website/public/css/basscss_responsive_margin.css b/packages/website/public/css/basscss_responsive_margin.css index b601bd491..c9f3e855c 100644 --- a/packages/website/public/css/basscss_responsive_margin.css +++ b/packages/website/public/css/basscss_responsive_margin.css @@ -1,160 +1,453 @@ /* Basscss Responsive Margin */ -@media (max-width: 52em) { /* Modified by Fabio Berger to max-width from min-width */ - - .sm-m0 { margin: 0 } - .sm-mt0 { margin-top: 0 } - .sm-mr0 { margin-right: 0 } - .sm-mb0 { margin-bottom: 0 } - .sm-ml0 { margin-left: 0 } - .sm-mx0 { margin-left: 0; margin-right: 0 } - .sm-my0 { margin-top: 0; margin-bottom: 0 } - - .sm-m1 { margin: .5rem } - .sm-mt1 { margin-top: .5rem } - .sm-mr1 { margin-right: .5rem } - .sm-mb1 { margin-bottom: .5rem } - .sm-ml1 { margin-left: .5rem } - .sm-mx1 { margin-left: .5rem; margin-right: .5rem } - .sm-my1 { margin-top: .5rem; margin-bottom: .5rem } - - .sm-m2 { margin: 1rem } - .sm-mt2 { margin-top: 1rem } - .sm-mr2 { margin-right: 1rem } - .sm-mb2 { margin-bottom: 1rem } - .sm-ml2 { margin-left: 1rem } - .sm-mx2 { margin-left: 1rem; margin-right: 1rem } - .sm-my2 { margin-top: 1rem; margin-bottom: 1rem } - - .sm-m3 { margin: 2rem } - .sm-mt3 { margin-top: 2rem } - .sm-mr3 { margin-right: 2rem } - .sm-mb3 { margin-bottom: 2rem } - .sm-ml3 { margin-left: 2rem } - .sm-mx3 { margin-left: 2rem; margin-right: 2rem } - .sm-my3 { margin-top: 2rem; margin-bottom: 2rem } - - .sm-m4 { margin: 4rem } - .sm-mt4 { margin-top: 4rem } - .sm-mr4 { margin-right: 4rem } - .sm-mb4 { margin-bottom: 4rem } - .sm-ml4 { margin-left: 4rem } - .sm-mx4 { margin-left: 4rem; margin-right: 4rem } - .sm-my4 { margin-top: 4rem; margin-bottom: 4rem } - - .sm-mxn1 { margin-left: -.5rem; margin-right: -.5rem } - .sm-mxn2 { margin-left: -1rem; margin-right: -1rem } - .sm-mxn3 { margin-left: -2rem; margin-right: -2rem } - .sm-mxn4 { margin-left: -4rem; margin-right: -4rem } - - .sm-ml-auto { margin-left: auto } - .sm-mr-auto { margin-right: auto } - .sm-mx-auto { margin-left: auto; margin-right: auto } +@media (max-width: 52em) { + /* Modified by Fabio Berger to max-width from min-width */ + .sm-m0 { + margin: 0; + } + .sm-mt0 { + margin-top: 0; + } + .sm-mr0 { + margin-right: 0; + } + .sm-mb0 { + margin-bottom: 0; + } + .sm-ml0 { + margin-left: 0; + } + .sm-mx0 { + margin-left: 0; + margin-right: 0; + } + .sm-my0 { + margin-top: 0; + margin-bottom: 0; + } + + .sm-m1 { + margin: 0.5rem; + } + .sm-mt1 { + margin-top: 0.5rem; + } + .sm-mr1 { + margin-right: 0.5rem; + } + .sm-mb1 { + margin-bottom: 0.5rem; + } + .sm-ml1 { + margin-left: 0.5rem; + } + .sm-mx1 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .sm-my1 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .sm-m2 { + margin: 1rem; + } + .sm-mt2 { + margin-top: 1rem; + } + .sm-mr2 { + margin-right: 1rem; + } + .sm-mb2 { + margin-bottom: 1rem; + } + .sm-ml2 { + margin-left: 1rem; + } + .sm-mx2 { + margin-left: 1rem; + margin-right: 1rem; + } + .sm-my2 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .sm-m3 { + margin: 2rem; + } + .sm-mt3 { + margin-top: 2rem; + } + .sm-mr3 { + margin-right: 2rem; + } + .sm-mb3 { + margin-bottom: 2rem; + } + .sm-ml3 { + margin-left: 2rem; + } + .sm-mx3 { + margin-left: 2rem; + margin-right: 2rem; + } + .sm-my3 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .sm-m4 { + margin: 4rem; + } + .sm-mt4 { + margin-top: 4rem; + } + .sm-mr4 { + margin-right: 4rem; + } + .sm-mb4 { + margin-bottom: 4rem; + } + .sm-ml4 { + margin-left: 4rem; + } + .sm-mx4 { + margin-left: 4rem; + margin-right: 4rem; + } + .sm-my4 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .sm-mxn1 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + .sm-mxn2 { + margin-left: -1rem; + margin-right: -1rem; + } + .sm-mxn3 { + margin-left: -2rem; + margin-right: -2rem; + } + .sm-mxn4 { + margin-left: -4rem; + margin-right: -4rem; + } + + .sm-ml-auto { + margin-left: auto; + } + .sm-mr-auto { + margin-right: auto; + } + .sm-mx-auto { + margin-left: auto; + margin-right: auto; + } } @media (min-width: 52em) { + .md-m0 { + margin: 0; + } + .md-mt0 { + margin-top: 0; + } + .md-mr0 { + margin-right: 0; + } + .md-mb0 { + margin-bottom: 0; + } + .md-ml0 { + margin-left: 0; + } + .md-mx0 { + margin-left: 0; + margin-right: 0; + } + .md-my0 { + margin-top: 0; + margin-bottom: 0; + } + + .md-m1 { + margin: 0.5rem; + } + .md-mt1 { + margin-top: 0.5rem; + } + .md-mr1 { + margin-right: 0.5rem; + } + .md-mb1 { + margin-bottom: 0.5rem; + } + .md-ml1 { + margin-left: 0.5rem; + } + .md-mx1 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .md-my1 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } - .md-m0 { margin: 0 } - .md-mt0 { margin-top: 0 } - .md-mr0 { margin-right: 0 } - .md-mb0 { margin-bottom: 0 } - .md-ml0 { margin-left: 0 } - .md-mx0 { margin-left: 0; margin-right: 0 } - .md-my0 { margin-top: 0; margin-bottom: 0 } - - .md-m1 { margin: .5rem } - .md-mt1 { margin-top: .5rem } - .md-mr1 { margin-right: .5rem } - .md-mb1 { margin-bottom: .5rem } - .md-ml1 { margin-left: .5rem } - .md-mx1 { margin-left: .5rem; margin-right: .5rem } - .md-my1 { margin-top: .5rem; margin-bottom: .5rem } - - .md-m2 { margin: 1rem } - .md-mt2 { margin-top: 1rem } - .md-mr2 { margin-right: 1rem } - .md-mb2 { margin-bottom: 1rem } - .md-ml2 { margin-left: 1rem } - .md-mx2 { margin-left: 1rem; margin-right: 1rem } - .md-my2 { margin-top: 1rem; margin-bottom: 1rem } - - .md-m3 { margin: 2rem } - .md-mt3 { margin-top: 2rem } - .md-mr3 { margin-right: 2rem } - .md-mb3 { margin-bottom: 2rem } - .md-ml3 { margin-left: 2rem } - .md-mx3 { margin-left: 2rem; margin-right: 2rem } - .md-my3 { margin-top: 2rem; margin-bottom: 2rem } - - .md-m4 { margin: 4rem } - .md-mt4 { margin-top: 4rem } - .md-mr4 { margin-right: 4rem } - .md-mb4 { margin-bottom: 4rem } - .md-ml4 { margin-left: 4rem } - .md-mx4 { margin-left: 4rem; margin-right: 4rem } - .md-my4 { margin-top: 4rem; margin-bottom: 4rem } - - .md-mxn1 { margin-left: -.5rem; margin-right: -.5rem; } - .md-mxn2 { margin-left: -1rem; margin-right: -1rem; } - .md-mxn3 { margin-left: -2rem; margin-right: -2rem; } - .md-mxn4 { margin-left: -4rem; margin-right: -4rem; } - - .md-ml-auto { margin-left: auto } - .md-mr-auto { margin-right: auto } - .md-mx-auto { margin-left: auto; margin-right: auto; } + .md-m2 { + margin: 1rem; + } + .md-mt2 { + margin-top: 1rem; + } + .md-mr2 { + margin-right: 1rem; + } + .md-mb2 { + margin-bottom: 1rem; + } + .md-ml2 { + margin-left: 1rem; + } + .md-mx2 { + margin-left: 1rem; + margin-right: 1rem; + } + .md-my2 { + margin-top: 1rem; + margin-bottom: 1rem; + } + .md-m3 { + margin: 2rem; + } + .md-mt3 { + margin-top: 2rem; + } + .md-mr3 { + margin-right: 2rem; + } + .md-mb3 { + margin-bottom: 2rem; + } + .md-ml3 { + margin-left: 2rem; + } + .md-mx3 { + margin-left: 2rem; + margin-right: 2rem; + } + .md-my3 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .md-m4 { + margin: 4rem; + } + .md-mt4 { + margin-top: 4rem; + } + .md-mr4 { + margin-right: 4rem; + } + .md-mb4 { + margin-bottom: 4rem; + } + .md-ml4 { + margin-left: 4rem; + } + .md-mx4 { + margin-left: 4rem; + margin-right: 4rem; + } + .md-my4 { + margin-top: 4rem; + margin-bottom: 4rem; + } + + .md-mxn1 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + .md-mxn2 { + margin-left: -1rem; + margin-right: -1rem; + } + .md-mxn3 { + margin-left: -2rem; + margin-right: -2rem; + } + .md-mxn4 { + margin-left: -4rem; + margin-right: -4rem; + } + + .md-ml-auto { + margin-left: auto; + } + .md-mr-auto { + margin-right: auto; + } + .md-mx-auto { + margin-left: auto; + margin-right: auto; + } } @media (min-width: 64em) { + .lg-m0 { + margin: 0; + } + .lg-mt0 { + margin-top: 0; + } + .lg-mr0 { + margin-right: 0; + } + .lg-mb0 { + margin-bottom: 0; + } + .lg-ml0 { + margin-left: 0; + } + .lg-mx0 { + margin-left: 0; + margin-right: 0; + } + .lg-my0 { + margin-top: 0; + margin-bottom: 0; + } + + .lg-m1 { + margin: 0.5rem; + } + .lg-mt1 { + margin-top: 0.5rem; + } + .lg-mr1 { + margin-right: 0.5rem; + } + .lg-mb1 { + margin-bottom: 0.5rem; + } + .lg-ml1 { + margin-left: 0.5rem; + } + .lg-mx1 { + margin-left: 0.5rem; + margin-right: 0.5rem; + } + .lg-my1 { + margin-top: 0.5rem; + margin-bottom: 0.5rem; + } + + .lg-m2 { + margin: 1rem; + } + .lg-mt2 { + margin-top: 1rem; + } + .lg-mr2 { + margin-right: 1rem; + } + .lg-mb2 { + margin-bottom: 1rem; + } + .lg-ml2 { + margin-left: 1rem; + } + .lg-mx2 { + margin-left: 1rem; + margin-right: 1rem; + } + .lg-my2 { + margin-top: 1rem; + margin-bottom: 1rem; + } + + .lg-m3 { + margin: 2rem; + } + .lg-mt3 { + margin-top: 2rem; + } + .lg-mr3 { + margin-right: 2rem; + } + .lg-mb3 { + margin-bottom: 2rem; + } + .lg-ml3 { + margin-left: 2rem; + } + .lg-mx3 { + margin-left: 2rem; + margin-right: 2rem; + } + .lg-my3 { + margin-top: 2rem; + margin-bottom: 2rem; + } + + .lg-m4 { + margin: 4rem; + } + .lg-mt4 { + margin-top: 4rem; + } + .lg-mr4 { + margin-right: 4rem; + } + .lg-mb4 { + margin-bottom: 4rem; + } + .lg-ml4 { + margin-left: 4rem; + } + .lg-mx4 { + margin-left: 4rem; + margin-right: 4rem; + } + .lg-my4 { + margin-top: 4rem; + margin-bottom: 4rem; + } - .lg-m0 { margin: 0 } - .lg-mt0 { margin-top: 0 } - .lg-mr0 { margin-right: 0 } - .lg-mb0 { margin-bottom: 0 } - .lg-ml0 { margin-left: 0 } - .lg-mx0 { margin-left: 0; margin-right: 0 } - .lg-my0 { margin-top: 0; margin-bottom: 0 } - - .lg-m1 { margin: .5rem } - .lg-mt1 { margin-top: .5rem } - .lg-mr1 { margin-right: .5rem } - .lg-mb1 { margin-bottom: .5rem } - .lg-ml1 { margin-left: .5rem } - .lg-mx1 { margin-left: .5rem; margin-right: .5rem } - .lg-my1 { margin-top: .5rem; margin-bottom: .5rem } - - .lg-m2 { margin: 1rem } - .lg-mt2 { margin-top: 1rem } - .lg-mr2 { margin-right: 1rem } - .lg-mb2 { margin-bottom: 1rem } - .lg-ml2 { margin-left: 1rem } - .lg-mx2 { margin-left: 1rem; margin-right: 1rem } - .lg-my2 { margin-top: 1rem; margin-bottom: 1rem } - - .lg-m3 { margin: 2rem } - .lg-mt3 { margin-top: 2rem } - .lg-mr3 { margin-right: 2rem } - .lg-mb3 { margin-bottom: 2rem } - .lg-ml3 { margin-left: 2rem } - .lg-mx3 { margin-left: 2rem; margin-right: 2rem } - .lg-my3 { margin-top: 2rem; margin-bottom: 2rem } - - .lg-m4 { margin: 4rem } - .lg-mt4 { margin-top: 4rem } - .lg-mr4 { margin-right: 4rem } - .lg-mb4 { margin-bottom: 4rem } - .lg-ml4 { margin-left: 4rem } - .lg-mx4 { margin-left: 4rem; margin-right: 4rem } - .lg-my4 { margin-top: 4rem; margin-bottom: 4rem } - - .lg-mxn1 { margin-left: -.5rem; margin-right: -.5rem; } - .lg-mxn2 { margin-left: -1rem; margin-right: -1rem; } - .lg-mxn3 { margin-left: -2rem; margin-right: -2rem; } - .lg-mxn4 { margin-left: -4rem; margin-right: -4rem; } - - .lg-ml-auto { margin-left: auto } - .lg-mr-auto { margin-right: auto } - .lg-mx-auto { margin-left: auto; margin-right: auto; } + .lg-mxn1 { + margin-left: -0.5rem; + margin-right: -0.5rem; + } + .lg-mxn2 { + margin-left: -1rem; + margin-right: -1rem; + } + .lg-mxn3 { + margin-left: -2rem; + margin-right: -2rem; + } + .lg-mxn4 { + margin-left: -4rem; + margin-right: -4rem; + } + .lg-ml-auto { + margin-left: auto; + } + .lg-mr-auto { + margin-right: auto; + } + .lg-mx-auto { + margin-left: auto; + margin-right: auto; + } } diff --git a/packages/website/public/css/material-design-iconic-font.css b/packages/website/public/css/material-design-iconic-font.css deleted file mode 100755 index 81d090a8b..000000000 --- a/packages/website/public/css/material-design-iconic-font.css +++ /dev/null @@ -1,5166 +0,0 @@ -/*!
- * Material Design Iconic Font by Sergey Kupletsky (@zavoloklom) - http://zavoloklom.github.io/material-design-iconic-font/
- * License - http://zavoloklom.github.io/material-design-iconic-font/license (Font: SIL OFL 1.1, CSS: MIT License)
- */
-@font-face {
- font-family: 'Material-Design-Iconic-Font';
- src: url('../fonts/Material-Design-Iconic-Font.woff2?v=2.2.0') format('woff2'), url('../fonts/Material-Design-Iconic-Font.woff?v=2.2.0') format('woff'), url('../fonts/Material-Design-Iconic-Font.ttf?v=2.2.0') format('truetype');
- font-weight: normal;
- font-style: normal;
-}
-.zmdi {
- display: inline-block;
- font: normal normal normal 14px/1 'Material-Design-Iconic-Font';
- font-size: inherit;
- text-rendering: auto;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
-}
-.zmdi-hc-lg {
- font-size: 1.33333333em;
- line-height: 0.75em;
- vertical-align: -15%;
-}
-.zmdi-hc-2x {
- font-size: 2em;
-}
-.zmdi-hc-3x {
- font-size: 3em;
-}
-.zmdi-hc-4x {
- font-size: 4em;
-}
-.zmdi-hc-5x {
- font-size: 5em;
-}
-.zmdi-hc-fw {
- width: 1.28571429em;
- text-align: center;
-}
-.zmdi-hc-ul {
- padding-left: 0;
- margin-left: 2.14285714em;
- list-style-type: none;
-}
-.zmdi-hc-ul > li {
- position: relative;
-}
-.zmdi-hc-li {
- position: absolute;
- left: -2.14285714em;
- width: 2.14285714em;
- top: 0.14285714em;
- text-align: center;
-}
-.zmdi-hc-li.zmdi-hc-lg {
- left: -1.85714286em;
-}
-.zmdi-hc-border {
- padding: .1em .25em;
- border: solid 0.1em #9e9e9e;
- border-radius: 2px;
-}
-.zmdi-hc-border-circle {
- padding: .1em .25em;
- border: solid 0.1em #9e9e9e;
- border-radius: 50%;
-}
-.zmdi.pull-left {
- float: left;
- margin-right: .15em;
-}
-.zmdi.pull-right {
- float: right;
- margin-left: .15em;
-}
-.zmdi-hc-spin {
- -webkit-animation: zmdi-spin 1.5s infinite linear;
- animation: zmdi-spin 1.5s infinite linear;
-}
-.zmdi-hc-spin-reverse {
- -webkit-animation: zmdi-spin-reverse 1.5s infinite linear;
- animation: zmdi-spin-reverse 1.5s infinite linear;
-}
-@-webkit-keyframes zmdi-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@keyframes zmdi-spin {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(359deg);
- transform: rotate(359deg);
- }
-}
-@-webkit-keyframes zmdi-spin-reverse {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(-359deg);
- transform: rotate(-359deg);
- }
-}
-@keyframes zmdi-spin-reverse {
- 0% {
- -webkit-transform: rotate(0deg);
- transform: rotate(0deg);
- }
- 100% {
- -webkit-transform: rotate(-359deg);
- transform: rotate(-359deg);
- }
-}
-.zmdi-hc-rotate-90 {
- -webkit-transform: rotate(90deg);
- -ms-transform: rotate(90deg);
- transform: rotate(90deg);
-}
-.zmdi-hc-rotate-180 {
- -webkit-transform: rotate(180deg);
- -ms-transform: rotate(180deg);
- transform: rotate(180deg);
-}
-.zmdi-hc-rotate-270 {
- -webkit-transform: rotate(270deg);
- -ms-transform: rotate(270deg);
- transform: rotate(270deg);
-}
-.zmdi-hc-flip-horizontal {
- -webkit-transform: scale(-1, 1);
- -ms-transform: scale(-1, 1);
- transform: scale(-1, 1);
-}
-.zmdi-hc-flip-vertical {
- -webkit-transform: scale(1, -1);
- -ms-transform: scale(1, -1);
- transform: scale(1, -1);
-}
-.zmdi-hc-stack {
- position: relative;
- display: inline-block;
- width: 2em;
- height: 2em;
- line-height: 2em;
- vertical-align: middle;
-}
-.zmdi-hc-stack-1x,
-.zmdi-hc-stack-2x {
- position: absolute;
- left: 0;
- width: 100%;
- text-align: center;
-}
-.zmdi-hc-stack-1x {
- line-height: inherit;
-}
-.zmdi-hc-stack-2x {
- font-size: 2em;
-}
-.zmdi-hc-inverse {
- color: #ffffff;
-}
-/* Material Design Iconic Font uses the Unicode Private Use Area (PUA) to ensure screen
- readers do not read off random characters that represent icons */
-.zmdi-3d-rotation:before {
- content: '\f101';
-}
-.zmdi-airplane-off:before {
- content: '\f102';
-}
-.zmdi-airplane:before {
- content: '\f103';
-}
-.zmdi-album:before {
- content: '\f104';
-}
-.zmdi-archive:before {
- content: '\f105';
-}
-.zmdi-assignment-account:before {
- content: '\f106';
-}
-.zmdi-assignment-alert:before {
- content: '\f107';
-}
-.zmdi-assignment-check:before {
- content: '\f108';
-}
-.zmdi-assignment-o:before {
- content: '\f109';
-}
-.zmdi-assignment-return:before {
- content: '\f10a';
-}
-.zmdi-assignment-returned:before {
- content: '\f10b';
-}
-.zmdi-assignment:before {
- content: '\f10c';
-}
-.zmdi-attachment-alt:before {
- content: '\f10d';
-}
-.zmdi-attachment:before {
- content: '\f10e';
-}
-.zmdi-audio:before {
- content: '\f10f';
-}
-.zmdi-badge-check:before {
- content: '\f110';
-}
-.zmdi-balance-wallet:before {
- content: '\f111';
-}
-.zmdi-balance:before {
- content: '\f112';
-}
-.zmdi-battery-alert:before {
- content: '\f113';
-}
-.zmdi-battery-flash:before {
- content: '\f114';
-}
-.zmdi-battery-unknown:before {
- content: '\f115';
-}
-.zmdi-battery:before {
- content: '\f116';
-}
-.zmdi-bike:before {
- content: '\f117';
-}
-.zmdi-block-alt:before {
- content: '\f118';
-}
-.zmdi-block:before {
- content: '\f119';
-}
-.zmdi-boat:before {
- content: '\f11a';
-}
-.zmdi-book-image:before {
- content: '\f11b';
-}
-.zmdi-book:before {
- content: '\f11c';
-}
-.zmdi-bookmark-outline:before {
- content: '\f11d';
-}
-.zmdi-bookmark:before {
- content: '\f11e';
-}
-.zmdi-brush:before {
- content: '\f11f';
-}
-.zmdi-bug:before {
- content: '\f120';
-}
-.zmdi-bus:before {
- content: '\f121';
-}
-.zmdi-cake:before {
- content: '\f122';
-}
-.zmdi-car-taxi:before {
- content: '\f123';
-}
-.zmdi-car-wash:before {
- content: '\f124';
-}
-.zmdi-car:before {
- content: '\f125';
-}
-.zmdi-card-giftcard:before {
- content: '\f126';
-}
-.zmdi-card-membership:before {
- content: '\f127';
-}
-.zmdi-card-travel:before {
- content: '\f128';
-}
-.zmdi-card:before {
- content: '\f129';
-}
-.zmdi-case-check:before {
- content: '\f12a';
-}
-.zmdi-case-download:before {
- content: '\f12b';
-}
-.zmdi-case-play:before {
- content: '\f12c';
-}
-.zmdi-case:before {
- content: '\f12d';
-}
-.zmdi-cast-connected:before {
- content: '\f12e';
-}
-.zmdi-cast:before {
- content: '\f12f';
-}
-.zmdi-chart-donut:before {
- content: '\f130';
-}
-.zmdi-chart:before {
- content: '\f131';
-}
-.zmdi-city-alt:before {
- content: '\f132';
-}
-.zmdi-city:before {
- content: '\f133';
-}
-.zmdi-close-circle-o:before {
- content: '\f134';
-}
-.zmdi-close-circle:before {
- content: '\f135';
-}
-.zmdi-close:before {
- content: '\f136';
-}
-.zmdi-cocktail:before {
- content: '\f137';
-}
-.zmdi-code-setting:before {
- content: '\f138';
-}
-.zmdi-code-smartphone:before {
- content: '\f139';
-}
-.zmdi-code:before {
- content: '\f13a';
-}
-.zmdi-coffee:before {
- content: '\f13b';
-}
-.zmdi-collection-bookmark:before {
- content: '\f13c';
-}
-.zmdi-collection-case-play:before {
- content: '\f13d';
-}
-.zmdi-collection-folder-image:before {
- content: '\f13e';
-}
-.zmdi-collection-image-o:before {
- content: '\f13f';
-}
-.zmdi-collection-image:before {
- content: '\f140';
-}
-.zmdi-collection-item-1:before {
- content: '\f141';
-}
-.zmdi-collection-item-2:before {
- content: '\f142';
-}
-.zmdi-collection-item-3:before {
- content: '\f143';
-}
-.zmdi-collection-item-4:before {
- content: '\f144';
-}
-.zmdi-collection-item-5:before {
- content: '\f145';
-}
-.zmdi-collection-item-6:before {
- content: '\f146';
-}
-.zmdi-collection-item-7:before {
- content: '\f147';
-}
-.zmdi-collection-item-8:before {
- content: '\f148';
-}
-.zmdi-collection-item-9-plus:before {
- content: '\f149';
-}
-.zmdi-collection-item-9:before {
- content: '\f14a';
-}
-.zmdi-collection-item:before {
- content: '\f14b';
-}
-.zmdi-collection-music:before {
- content: '\f14c';
-}
-.zmdi-collection-pdf:before {
- content: '\f14d';
-}
-.zmdi-collection-plus:before {
- content: '\f14e';
-}
-.zmdi-collection-speaker:before {
- content: '\f14f';
-}
-.zmdi-collection-text:before {
- content: '\f150';
-}
-.zmdi-collection-video:before {
- content: '\f151';
-}
-.zmdi-compass:before {
- content: '\f152';
-}
-.zmdi-cutlery:before {
- content: '\f153';
-}
-.zmdi-delete:before {
- content: '\f154';
-}
-.zmdi-dialpad:before {
- content: '\f155';
-}
-.zmdi-dns:before {
- content: '\f156';
-}
-.zmdi-drink:before {
- content: '\f157';
-}
-.zmdi-edit:before {
- content: '\f158';
-}
-.zmdi-email-open:before {
- content: '\f159';
-}
-.zmdi-email:before {
- content: '\f15a';
-}
-.zmdi-eye-off:before {
- content: '\f15b';
-}
-.zmdi-eye:before {
- content: '\f15c';
-}
-.zmdi-eyedropper:before {
- content: '\f15d';
-}
-.zmdi-favorite-outline:before {
- content: '\f15e';
-}
-.zmdi-favorite:before {
- content: '\f15f';
-}
-.zmdi-filter-list:before {
- content: '\f160';
-}
-.zmdi-fire:before {
- content: '\f161';
-}
-.zmdi-flag:before {
- content: '\f162';
-}
-.zmdi-flare:before {
- content: '\f163';
-}
-.zmdi-flash-auto:before {
- content: '\f164';
-}
-.zmdi-flash-off:before {
- content: '\f165';
-}
-.zmdi-flash:before {
- content: '\f166';
-}
-.zmdi-flip:before {
- content: '\f167';
-}
-.zmdi-flower-alt:before {
- content: '\f168';
-}
-.zmdi-flower:before {
- content: '\f169';
-}
-.zmdi-font:before {
- content: '\f16a';
-}
-.zmdi-fullscreen-alt:before {
- content: '\f16b';
-}
-.zmdi-fullscreen-exit:before {
- content: '\f16c';
-}
-.zmdi-fullscreen:before {
- content: '\f16d';
-}
-.zmdi-functions:before {
- content: '\f16e';
-}
-.zmdi-gas-station:before {
- content: '\f16f';
-}
-.zmdi-gesture:before {
- content: '\f170';
-}
-.zmdi-globe-alt:before {
- content: '\f171';
-}
-.zmdi-globe-lock:before {
- content: '\f172';
-}
-.zmdi-globe:before {
- content: '\f173';
-}
-.zmdi-graduation-cap:before {
- content: '\f174';
-}
-.zmdi-home:before {
- content: '\f175';
-}
-.zmdi-hospital-alt:before {
- content: '\f176';
-}
-.zmdi-hospital:before {
- content: '\f177';
-}
-.zmdi-hotel:before {
- content: '\f178';
-}
-.zmdi-hourglass-alt:before {
- content: '\f179';
-}
-.zmdi-hourglass-outline:before {
- content: '\f17a';
-}
-.zmdi-hourglass:before {
- content: '\f17b';
-}
-.zmdi-http:before {
- content: '\f17c';
-}
-.zmdi-image-alt:before {
- content: '\f17d';
-}
-.zmdi-image-o:before {
- content: '\f17e';
-}
-.zmdi-image:before {
- content: '\f17f';
-}
-.zmdi-inbox:before {
- content: '\f180';
-}
-.zmdi-invert-colors-off:before {
- content: '\f181';
-}
-.zmdi-invert-colors:before {
- content: '\f182';
-}
-.zmdi-key:before {
- content: '\f183';
-}
-.zmdi-label-alt-outline:before {
- content: '\f184';
-}
-.zmdi-label-alt:before {
- content: '\f185';
-}
-.zmdi-label-heart:before {
- content: '\f186';
-}
-.zmdi-label:before {
- content: '\f187';
-}
-.zmdi-labels:before {
- content: '\f188';
-}
-.zmdi-lamp:before {
- content: '\f189';
-}
-.zmdi-landscape:before {
- content: '\f18a';
-}
-.zmdi-layers-off:before {
- content: '\f18b';
-}
-.zmdi-layers:before {
- content: '\f18c';
-}
-.zmdi-library:before {
- content: '\f18d';
-}
-.zmdi-link:before {
- content: '\f18e';
-}
-.zmdi-lock-open:before {
- content: '\f18f';
-}
-.zmdi-lock-outline:before {
- content: '\f190';
-}
-.zmdi-lock:before {
- content: '\f191';
-}
-.zmdi-mail-reply-all:before {
- content: '\f192';
-}
-.zmdi-mail-reply:before {
- content: '\f193';
-}
-.zmdi-mail-send:before {
- content: '\f194';
-}
-.zmdi-mall:before {
- content: '\f195';
-}
-.zmdi-map:before {
- content: '\f196';
-}
-.zmdi-menu:before {
- content: '\f197';
-}
-.zmdi-money-box:before {
- content: '\f198';
-}
-.zmdi-money-off:before {
- content: '\f199';
-}
-.zmdi-money:before {
- content: '\f19a';
-}
-.zmdi-more-vert:before {
- content: '\f19b';
-}
-.zmdi-more:before {
- content: '\f19c';
-}
-.zmdi-movie-alt:before {
- content: '\f19d';
-}
-.zmdi-movie:before {
- content: '\f19e';
-}
-.zmdi-nature-people:before {
- content: '\f19f';
-}
-.zmdi-nature:before {
- content: '\f1a0';
-}
-.zmdi-navigation:before {
- content: '\f1a1';
-}
-.zmdi-open-in-browser:before {
- content: '\f1a2';
-}
-.zmdi-open-in-new:before {
- content: '\f1a3';
-}
-.zmdi-palette:before {
- content: '\f1a4';
-}
-.zmdi-parking:before {
- content: '\f1a5';
-}
-.zmdi-pin-account:before {
- content: '\f1a6';
-}
-.zmdi-pin-assistant:before {
- content: '\f1a7';
-}
-.zmdi-pin-drop:before {
- content: '\f1a8';
-}
-.zmdi-pin-help:before {
- content: '\f1a9';
-}
-.zmdi-pin-off:before {
- content: '\f1aa';
-}
-.zmdi-pin:before {
- content: '\f1ab';
-}
-.zmdi-pizza:before {
- content: '\f1ac';
-}
-.zmdi-plaster:before {
- content: '\f1ad';
-}
-.zmdi-power-setting:before {
- content: '\f1ae';
-}
-.zmdi-power:before {
- content: '\f1af';
-}
-.zmdi-print:before {
- content: '\f1b0';
-}
-.zmdi-puzzle-piece:before {
- content: '\f1b1';
-}
-.zmdi-quote:before {
- content: '\f1b2';
-}
-.zmdi-railway:before {
- content: '\f1b3';
-}
-.zmdi-receipt:before {
- content: '\f1b4';
-}
-.zmdi-refresh-alt:before {
- content: '\f1b5';
-}
-.zmdi-refresh-sync-alert:before {
- content: '\f1b6';
-}
-.zmdi-refresh-sync-off:before {
- content: '\f1b7';
-}
-.zmdi-refresh-sync:before {
- content: '\f1b8';
-}
-.zmdi-refresh:before {
- content: '\f1b9';
-}
-.zmdi-roller:before {
- content: '\f1ba';
-}
-.zmdi-ruler:before {
- content: '\f1bb';
-}
-.zmdi-scissors:before {
- content: '\f1bc';
-}
-.zmdi-screen-rotation-lock:before {
- content: '\f1bd';
-}
-.zmdi-screen-rotation:before {
- content: '\f1be';
-}
-.zmdi-search-for:before {
- content: '\f1bf';
-}
-.zmdi-search-in-file:before {
- content: '\f1c0';
-}
-.zmdi-search-in-page:before {
- content: '\f1c1';
-}
-.zmdi-search-replace:before {
- content: '\f1c2';
-}
-.zmdi-search:before {
- content: '\f1c3';
-}
-.zmdi-seat:before {
- content: '\f1c4';
-}
-.zmdi-settings-square:before {
- content: '\f1c5';
-}
-.zmdi-settings:before {
- content: '\f1c6';
-}
-.zmdi-shield-check:before {
- content: '\f1c7';
-}
-.zmdi-shield-security:before {
- content: '\f1c8';
-}
-.zmdi-shopping-basket:before {
- content: '\f1c9';
-}
-.zmdi-shopping-cart-plus:before {
- content: '\f1ca';
-}
-.zmdi-shopping-cart:before {
- content: '\f1cb';
-}
-.zmdi-sign-in:before {
- content: '\f1cc';
-}
-.zmdi-sort-amount-asc:before {
- content: '\f1cd';
-}
-.zmdi-sort-amount-desc:before {
- content: '\f1ce';
-}
-.zmdi-sort-asc:before {
- content: '\f1cf';
-}
-.zmdi-sort-desc:before {
- content: '\f1d0';
-}
-.zmdi-spellcheck:before {
- content: '\f1d1';
-}
-.zmdi-storage:before {
- content: '\f1d2';
-}
-.zmdi-store-24:before {
- content: '\f1d3';
-}
-.zmdi-store:before {
- content: '\f1d4';
-}
-.zmdi-subway:before {
- content: '\f1d5';
-}
-.zmdi-sun:before {
- content: '\f1d6';
-}
-.zmdi-tab-unselected:before {
- content: '\f1d7';
-}
-.zmdi-tab:before {
- content: '\f1d8';
-}
-.zmdi-tag-close:before {
- content: '\f1d9';
-}
-.zmdi-tag-more:before {
- content: '\f1da';
-}
-.zmdi-tag:before {
- content: '\f1db';
-}
-.zmdi-thumb-down:before {
- content: '\f1dc';
-}
-.zmdi-thumb-up-down:before {
- content: '\f1dd';
-}
-.zmdi-thumb-up:before {
- content: '\f1de';
-}
-.zmdi-ticket-star:before {
- content: '\f1df';
-}
-.zmdi-toll:before {
- content: '\f1e0';
-}
-.zmdi-toys:before {
- content: '\f1e1';
-}
-.zmdi-traffic:before {
- content: '\f1e2';
-}
-.zmdi-translate:before {
- content: '\f1e3';
-}
-.zmdi-triangle-down:before {
- content: '\f1e4';
-}
-.zmdi-triangle-up:before {
- content: '\f1e5';
-}
-.zmdi-truck:before {
- content: '\f1e6';
-}
-.zmdi-turning-sign:before {
- content: '\f1e7';
-}
-.zmdi-wallpaper:before {
- content: '\f1e8';
-}
-.zmdi-washing-machine:before {
- content: '\f1e9';
-}
-.zmdi-window-maximize:before {
- content: '\f1ea';
-}
-.zmdi-window-minimize:before {
- content: '\f1eb';
-}
-.zmdi-window-restore:before {
- content: '\f1ec';
-}
-.zmdi-wrench:before {
- content: '\f1ed';
-}
-.zmdi-zoom-in:before {
- content: '\f1ee';
-}
-.zmdi-zoom-out:before {
- content: '\f1ef';
-}
-.zmdi-alert-circle-o:before {
- content: '\f1f0';
-}
-.zmdi-alert-circle:before {
- content: '\f1f1';
-}
-.zmdi-alert-octagon:before {
- content: '\f1f2';
-}
-.zmdi-alert-polygon:before {
- content: '\f1f3';
-}
-.zmdi-alert-triangle:before {
- content: '\f1f4';
-}
-.zmdi-help-outline:before {
- content: '\f1f5';
-}
-.zmdi-help:before {
- content: '\f1f6';
-}
-.zmdi-info-outline:before {
- content: '\f1f7';
-}
-.zmdi-info:before {
- content: '\f1f8';
-}
-.zmdi-notifications-active:before {
- content: '\f1f9';
-}
-.zmdi-notifications-add:before {
- content: '\f1fa';
-}
-.zmdi-notifications-none:before {
- content: '\f1fb';
-}
-.zmdi-notifications-off:before {
- content: '\f1fc';
-}
-.zmdi-notifications-paused:before {
- content: '\f1fd';
-}
-.zmdi-notifications:before {
- content: '\f1fe';
-}
-.zmdi-account-add:before {
- content: '\f1ff';
-}
-.zmdi-account-box-mail:before {
- content: '\f200';
-}
-.zmdi-account-box-o:before {
- content: '\f201';
-}
-.zmdi-account-box-phone:before {
- content: '\f202';
-}
-.zmdi-account-box:before {
- content: '\f203';
-}
-.zmdi-account-calendar:before {
- content: '\f204';
-}
-.zmdi-account-circle:before {
- content: '\f205';
-}
-.zmdi-account-o:before {
- content: '\f206';
-}
-.zmdi-account:before {
- content: '\f207';
-}
-.zmdi-accounts-add:before {
- content: '\f208';
-}
-.zmdi-accounts-alt:before {
- content: '\f209';
-}
-.zmdi-accounts-list-alt:before {
- content: '\f20a';
-}
-.zmdi-accounts-list:before {
- content: '\f20b';
-}
-.zmdi-accounts-outline:before {
- content: '\f20c';
-}
-.zmdi-accounts:before {
- content: '\f20d';
-}
-.zmdi-face:before {
- content: '\f20e';
-}
-.zmdi-female:before {
- content: '\f20f';
-}
-.zmdi-male-alt:before {
- content: '\f210';
-}
-.zmdi-male-female:before {
- content: '\f211';
-}
-.zmdi-male:before {
- content: '\f212';
-}
-.zmdi-mood-bad:before {
- content: '\f213';
-}
-.zmdi-mood:before {
- content: '\f214';
-}
-.zmdi-run:before {
- content: '\f215';
-}
-.zmdi-walk:before {
- content: '\f216';
-}
-.zmdi-cloud-box:before {
- content: '\f217';
-}
-.zmdi-cloud-circle:before {
- content: '\f218';
-}
-.zmdi-cloud-done:before {
- content: '\f219';
-}
-.zmdi-cloud-download:before {
- content: '\f21a';
-}
-.zmdi-cloud-off:before {
- content: '\f21b';
-}
-.zmdi-cloud-outline-alt:before {
- content: '\f21c';
-}
-.zmdi-cloud-outline:before {
- content: '\f21d';
-}
-.zmdi-cloud-upload:before {
- content: '\f21e';
-}
-.zmdi-cloud:before {
- content: '\f21f';
-}
-.zmdi-download:before {
- content: '\f220';
-}
-.zmdi-file-plus:before {
- content: '\f221';
-}
-.zmdi-file-text:before {
- content: '\f222';
-}
-.zmdi-file:before {
- content: '\f223';
-}
-.zmdi-folder-outline:before {
- content: '\f224';
-}
-.zmdi-folder-person:before {
- content: '\f225';
-}
-.zmdi-folder-star-alt:before {
- content: '\f226';
-}
-.zmdi-folder-star:before {
- content: '\f227';
-}
-.zmdi-folder:before {
- content: '\f228';
-}
-.zmdi-gif:before {
- content: '\f229';
-}
-.zmdi-upload:before {
- content: '\f22a';
-}
-.zmdi-border-all:before {
- content: '\f22b';
-}
-.zmdi-border-bottom:before {
- content: '\f22c';
-}
-.zmdi-border-clear:before {
- content: '\f22d';
-}
-.zmdi-border-color:before {
- content: '\f22e';
-}
-.zmdi-border-horizontal:before {
- content: '\f22f';
-}
-.zmdi-border-inner:before {
- content: '\f230';
-}
-.zmdi-border-left:before {
- content: '\f231';
-}
-.zmdi-border-outer:before {
- content: '\f232';
-}
-.zmdi-border-right:before {
- content: '\f233';
-}
-.zmdi-border-style:before {
- content: '\f234';
-}
-.zmdi-border-top:before {
- content: '\f235';
-}
-.zmdi-border-vertical:before {
- content: '\f236';
-}
-.zmdi-copy:before {
- content: '\f237';
-}
-.zmdi-crop:before {
- content: '\f238';
-}
-.zmdi-format-align-center:before {
- content: '\f239';
-}
-.zmdi-format-align-justify:before {
- content: '\f23a';
-}
-.zmdi-format-align-left:before {
- content: '\f23b';
-}
-.zmdi-format-align-right:before {
- content: '\f23c';
-}
-.zmdi-format-bold:before {
- content: '\f23d';
-}
-.zmdi-format-clear-all:before {
- content: '\f23e';
-}
-.zmdi-format-clear:before {
- content: '\f23f';
-}
-.zmdi-format-color-fill:before {
- content: '\f240';
-}
-.zmdi-format-color-reset:before {
- content: '\f241';
-}
-.zmdi-format-color-text:before {
- content: '\f242';
-}
-.zmdi-format-indent-decrease:before {
- content: '\f243';
-}
-.zmdi-format-indent-increase:before {
- content: '\f244';
-}
-.zmdi-format-italic:before {
- content: '\f245';
-}
-.zmdi-format-line-spacing:before {
- content: '\f246';
-}
-.zmdi-format-list-bulleted:before {
- content: '\f247';
-}
-.zmdi-format-list-numbered:before {
- content: '\f248';
-}
-.zmdi-format-ltr:before {
- content: '\f249';
-}
-.zmdi-format-rtl:before {
- content: '\f24a';
-}
-.zmdi-format-size:before {
- content: '\f24b';
-}
-.zmdi-format-strikethrough-s:before {
- content: '\f24c';
-}
-.zmdi-format-strikethrough:before {
- content: '\f24d';
-}
-.zmdi-format-subject:before {
- content: '\f24e';
-}
-.zmdi-format-underlined:before {
- content: '\f24f';
-}
-.zmdi-format-valign-bottom:before {
- content: '\f250';
-}
-.zmdi-format-valign-center:before {
- content: '\f251';
-}
-.zmdi-format-valign-top:before {
- content: '\f252';
-}
-.zmdi-redo:before {
- content: '\f253';
-}
-.zmdi-select-all:before {
- content: '\f254';
-}
-.zmdi-space-bar:before {
- content: '\f255';
-}
-.zmdi-text-format:before {
- content: '\f256';
-}
-.zmdi-transform:before {
- content: '\f257';
-}
-.zmdi-undo:before {
- content: '\f258';
-}
-.zmdi-wrap-text:before {
- content: '\f259';
-}
-.zmdi-comment-alert:before {
- content: '\f25a';
-}
-.zmdi-comment-alt-text:before {
- content: '\f25b';
-}
-.zmdi-comment-alt:before {
- content: '\f25c';
-}
-.zmdi-comment-edit:before {
- content: '\f25d';
-}
-.zmdi-comment-image:before {
- content: '\f25e';
-}
-.zmdi-comment-list:before {
- content: '\f25f';
-}
-.zmdi-comment-more:before {
- content: '\f260';
-}
-.zmdi-comment-outline:before {
- content: '\f261';
-}
-.zmdi-comment-text-alt:before {
- content: '\f262';
-}
-.zmdi-comment-text:before {
- content: '\f263';
-}
-.zmdi-comment-video:before {
- content: '\f264';
-}
-.zmdi-comment:before {
- content: '\f265';
-}
-.zmdi-comments:before {
- content: '\f266';
-}
-.zmdi-check-all:before {
- content: '\f267';
-}
-.zmdi-check-circle-u:before {
- content: '\f268';
-}
-.zmdi-check-circle:before {
- content: '\f269';
-}
-.zmdi-check-square:before {
- content: '\f26a';
-}
-.zmdi-check:before {
- content: '\f26b';
-}
-.zmdi-circle-o:before {
- content: '\f26c';
-}
-.zmdi-circle:before {
- content: '\f26d';
-}
-.zmdi-dot-circle-alt:before {
- content: '\f26e';
-}
-.zmdi-dot-circle:before {
- content: '\f26f';
-}
-.zmdi-minus-circle-outline:before {
- content: '\f270';
-}
-.zmdi-minus-circle:before {
- content: '\f271';
-}
-.zmdi-minus-square:before {
- content: '\f272';
-}
-.zmdi-minus:before {
- content: '\f273';
-}
-.zmdi-plus-circle-o-duplicate:before {
- content: '\f274';
-}
-.zmdi-plus-circle-o:before {
- content: '\f275';
-}
-.zmdi-plus-circle:before {
- content: '\f276';
-}
-.zmdi-plus-square:before {
- content: '\f277';
-}
-.zmdi-plus:before {
- content: '\f278';
-}
-.zmdi-square-o:before {
- content: '\f279';
-}
-.zmdi-star-circle:before {
- content: '\f27a';
-}
-.zmdi-star-half:before {
- content: '\f27b';
-}
-.zmdi-star-outline:before {
- content: '\f27c';
-}
-.zmdi-star:before {
- content: '\f27d';
-}
-.zmdi-bluetooth-connected:before {
- content: '\f27e';
-}
-.zmdi-bluetooth-off:before {
- content: '\f27f';
-}
-.zmdi-bluetooth-search:before {
- content: '\f280';
-}
-.zmdi-bluetooth-setting:before {
- content: '\f281';
-}
-.zmdi-bluetooth:before {
- content: '\f282';
-}
-.zmdi-camera-add:before {
- content: '\f283';
-}
-.zmdi-camera-alt:before {
- content: '\f284';
-}
-.zmdi-camera-bw:before {
- content: '\f285';
-}
-.zmdi-camera-front:before {
- content: '\f286';
-}
-.zmdi-camera-mic:before {
- content: '\f287';
-}
-.zmdi-camera-party-mode:before {
- content: '\f288';
-}
-.zmdi-camera-rear:before {
- content: '\f289';
-}
-.zmdi-camera-roll:before {
- content: '\f28a';
-}
-.zmdi-camera-switch:before {
- content: '\f28b';
-}
-.zmdi-camera:before {
- content: '\f28c';
-}
-.zmdi-card-alert:before {
- content: '\f28d';
-}
-.zmdi-card-off:before {
- content: '\f28e';
-}
-.zmdi-card-sd:before {
- content: '\f28f';
-}
-.zmdi-card-sim:before {
- content: '\f290';
-}
-.zmdi-desktop-mac:before {
- content: '\f291';
-}
-.zmdi-desktop-windows:before {
- content: '\f292';
-}
-.zmdi-device-hub:before {
- content: '\f293';
-}
-.zmdi-devices-off:before {
- content: '\f294';
-}
-.zmdi-devices:before {
- content: '\f295';
-}
-.zmdi-dock:before {
- content: '\f296';
-}
-.zmdi-floppy:before {
- content: '\f297';
-}
-.zmdi-gamepad:before {
- content: '\f298';
-}
-.zmdi-gps-dot:before {
- content: '\f299';
-}
-.zmdi-gps-off:before {
- content: '\f29a';
-}
-.zmdi-gps:before {
- content: '\f29b';
-}
-.zmdi-headset-mic:before {
- content: '\f29c';
-}
-.zmdi-headset:before {
- content: '\f29d';
-}
-.zmdi-input-antenna:before {
- content: '\f29e';
-}
-.zmdi-input-composite:before {
- content: '\f29f';
-}
-.zmdi-input-hdmi:before {
- content: '\f2a0';
-}
-.zmdi-input-power:before {
- content: '\f2a1';
-}
-.zmdi-input-svideo:before {
- content: '\f2a2';
-}
-.zmdi-keyboard-hide:before {
- content: '\f2a3';
-}
-.zmdi-keyboard:before {
- content: '\f2a4';
-}
-.zmdi-laptop-chromebook:before {
- content: '\f2a5';
-}
-.zmdi-laptop-mac:before {
- content: '\f2a6';
-}
-.zmdi-laptop:before {
- content: '\f2a7';
-}
-.zmdi-mic-off:before {
- content: '\f2a8';
-}
-.zmdi-mic-outline:before {
- content: '\f2a9';
-}
-.zmdi-mic-setting:before {
- content: '\f2aa';
-}
-.zmdi-mic:before {
- content: '\f2ab';
-}
-.zmdi-mouse:before {
- content: '\f2ac';
-}
-.zmdi-network-alert:before {
- content: '\f2ad';
-}
-.zmdi-network-locked:before {
- content: '\f2ae';
-}
-.zmdi-network-off:before {
- content: '\f2af';
-}
-.zmdi-network-outline:before {
- content: '\f2b0';
-}
-.zmdi-network-setting:before {
- content: '\f2b1';
-}
-.zmdi-network:before {
- content: '\f2b2';
-}
-.zmdi-phone-bluetooth:before {
- content: '\f2b3';
-}
-.zmdi-phone-end:before {
- content: '\f2b4';
-}
-.zmdi-phone-forwarded:before {
- content: '\f2b5';
-}
-.zmdi-phone-in-talk:before {
- content: '\f2b6';
-}
-.zmdi-phone-locked:before {
- content: '\f2b7';
-}
-.zmdi-phone-missed:before {
- content: '\f2b8';
-}
-.zmdi-phone-msg:before {
- content: '\f2b9';
-}
-.zmdi-phone-paused:before {
- content: '\f2ba';
-}
-.zmdi-phone-ring:before {
- content: '\f2bb';
-}
-.zmdi-phone-setting:before {
- content: '\f2bc';
-}
-.zmdi-phone-sip:before {
- content: '\f2bd';
-}
-.zmdi-phone:before {
- content: '\f2be';
-}
-.zmdi-portable-wifi-changes:before {
- content: '\f2bf';
-}
-.zmdi-portable-wifi-off:before {
- content: '\f2c0';
-}
-.zmdi-portable-wifi:before {
- content: '\f2c1';
-}
-.zmdi-radio:before {
- content: '\f2c2';
-}
-.zmdi-reader:before {
- content: '\f2c3';
-}
-.zmdi-remote-control-alt:before {
- content: '\f2c4';
-}
-.zmdi-remote-control:before {
- content: '\f2c5';
-}
-.zmdi-router:before {
- content: '\f2c6';
-}
-.zmdi-scanner:before {
- content: '\f2c7';
-}
-.zmdi-smartphone-android:before {
- content: '\f2c8';
-}
-.zmdi-smartphone-download:before {
- content: '\f2c9';
-}
-.zmdi-smartphone-erase:before {
- content: '\f2ca';
-}
-.zmdi-smartphone-info:before {
- content: '\f2cb';
-}
-.zmdi-smartphone-iphone:before {
- content: '\f2cc';
-}
-.zmdi-smartphone-landscape-lock:before {
- content: '\f2cd';
-}
-.zmdi-smartphone-landscape:before {
- content: '\f2ce';
-}
-.zmdi-smartphone-lock:before {
- content: '\f2cf';
-}
-.zmdi-smartphone-portrait-lock:before {
- content: '\f2d0';
-}
-.zmdi-smartphone-ring:before {
- content: '\f2d1';
-}
-.zmdi-smartphone-setting:before {
- content: '\f2d2';
-}
-.zmdi-smartphone-setup:before {
- content: '\f2d3';
-}
-.zmdi-smartphone:before {
- content: '\f2d4';
-}
-.zmdi-speaker:before {
- content: '\f2d5';
-}
-.zmdi-tablet-android:before {
- content: '\f2d6';
-}
-.zmdi-tablet-mac:before {
- content: '\f2d7';
-}
-.zmdi-tablet:before {
- content: '\f2d8';
-}
-.zmdi-tv-alt-play:before {
- content: '\f2d9';
-}
-.zmdi-tv-list:before {
- content: '\f2da';
-}
-.zmdi-tv-play:before {
- content: '\f2db';
-}
-.zmdi-tv:before {
- content: '\f2dc';
-}
-.zmdi-usb:before {
- content: '\f2dd';
-}
-.zmdi-videocam-off:before {
- content: '\f2de';
-}
-.zmdi-videocam-switch:before {
- content: '\f2df';
-}
-.zmdi-videocam:before {
- content: '\f2e0';
-}
-.zmdi-watch:before {
- content: '\f2e1';
-}
-.zmdi-wifi-alt-2:before {
- content: '\f2e2';
-}
-.zmdi-wifi-alt:before {
- content: '\f2e3';
-}
-.zmdi-wifi-info:before {
- content: '\f2e4';
-}
-.zmdi-wifi-lock:before {
- content: '\f2e5';
-}
-.zmdi-wifi-off:before {
- content: '\f2e6';
-}
-.zmdi-wifi-outline:before {
- content: '\f2e7';
-}
-.zmdi-wifi:before {
- content: '\f2e8';
-}
-.zmdi-arrow-left-bottom:before {
- content: '\f2e9';
-}
-.zmdi-arrow-left:before {
- content: '\f2ea';
-}
-.zmdi-arrow-merge:before {
- content: '\f2eb';
-}
-.zmdi-arrow-missed:before {
- content: '\f2ec';
-}
-.zmdi-arrow-right-top:before {
- content: '\f2ed';
-}
-.zmdi-arrow-right:before {
- content: '\f2ee';
-}
-.zmdi-arrow-split:before {
- content: '\f2ef';
-}
-.zmdi-arrows:before {
- content: '\f2f0';
-}
-.zmdi-caret-down-circle:before {
- content: '\f2f1';
-}
-.zmdi-caret-down:before {
- content: '\f2f2';
-}
-.zmdi-caret-left-circle:before {
- content: '\f2f3';
-}
-.zmdi-caret-left:before {
- content: '\f2f4';
-}
-.zmdi-caret-right-circle:before {
- content: '\f2f5';
-}
-.zmdi-caret-right:before {
- content: '\f2f6';
-}
-.zmdi-caret-up-circle:before {
- content: '\f2f7';
-}
-.zmdi-caret-up:before {
- content: '\f2f8';
-}
-.zmdi-chevron-down:before {
- content: '\f2f9';
-}
-.zmdi-chevron-left:before {
- content: '\f2fa';
-}
-.zmdi-chevron-right:before {
- content: '\f2fb';
-}
-.zmdi-chevron-up:before {
- content: '\f2fc';
-}
-.zmdi-forward:before {
- content: '\f2fd';
-}
-.zmdi-long-arrow-down:before {
- content: '\f2fe';
-}
-.zmdi-long-arrow-left:before {
- content: '\f2ff';
-}
-.zmdi-long-arrow-return:before {
- content: '\f300';
-}
-.zmdi-long-arrow-right:before {
- content: '\f301';
-}
-.zmdi-long-arrow-tab:before {
- content: '\f302';
-}
-.zmdi-long-arrow-up:before {
- content: '\f303';
-}
-.zmdi-rotate-ccw:before {
- content: '\f304';
-}
-.zmdi-rotate-cw:before {
- content: '\f305';
-}
-.zmdi-rotate-left:before {
- content: '\f306';
-}
-.zmdi-rotate-right:before {
- content: '\f307';
-}
-.zmdi-square-down:before {
- content: '\f308';
-}
-.zmdi-square-right:before {
- content: '\f309';
-}
-.zmdi-swap-alt:before {
- content: '\f30a';
-}
-.zmdi-swap-vertical-circle:before {
- content: '\f30b';
-}
-.zmdi-swap-vertical:before {
- content: '\f30c';
-}
-.zmdi-swap:before {
- content: '\f30d';
-}
-.zmdi-trending-down:before {
- content: '\f30e';
-}
-.zmdi-trending-flat:before {
- content: '\f30f';
-}
-.zmdi-trending-up:before {
- content: '\f310';
-}
-.zmdi-unfold-less:before {
- content: '\f311';
-}
-.zmdi-unfold-more:before {
- content: '\f312';
-}
-.zmdi-apps:before {
- content: '\f313';
-}
-.zmdi-grid-off:before {
- content: '\f314';
-}
-.zmdi-grid:before {
- content: '\f315';
-}
-.zmdi-view-agenda:before {
- content: '\f316';
-}
-.zmdi-view-array:before {
- content: '\f317';
-}
-.zmdi-view-carousel:before {
- content: '\f318';
-}
-.zmdi-view-column:before {
- content: '\f319';
-}
-.zmdi-view-comfy:before {
- content: '\f31a';
-}
-.zmdi-view-compact:before {
- content: '\f31b';
-}
-.zmdi-view-dashboard:before {
- content: '\f31c';
-}
-.zmdi-view-day:before {
- content: '\f31d';
-}
-.zmdi-view-headline:before {
- content: '\f31e';
-}
-.zmdi-view-list-alt:before {
- content: '\f31f';
-}
-.zmdi-view-list:before {
- content: '\f320';
-}
-.zmdi-view-module:before {
- content: '\f321';
-}
-.zmdi-view-quilt:before {
- content: '\f322';
-}
-.zmdi-view-stream:before {
- content: '\f323';
-}
-.zmdi-view-subtitles:before {
- content: '\f324';
-}
-.zmdi-view-toc:before {
- content: '\f325';
-}
-.zmdi-view-web:before {
- content: '\f326';
-}
-.zmdi-view-week:before {
- content: '\f327';
-}
-.zmdi-widgets:before {
- content: '\f328';
-}
-.zmdi-alarm-check:before {
- content: '\f329';
-}
-.zmdi-alarm-off:before {
- content: '\f32a';
-}
-.zmdi-alarm-plus:before {
- content: '\f32b';
-}
-.zmdi-alarm-snooze:before {
- content: '\f32c';
-}
-.zmdi-alarm:before {
- content: '\f32d';
-}
-.zmdi-calendar-alt:before {
- content: '\f32e';
-}
-.zmdi-calendar-check:before {
- content: '\f32f';
-}
-.zmdi-calendar-close:before {
- content: '\f330';
-}
-.zmdi-calendar-note:before {
- content: '\f331';
-}
-.zmdi-calendar:before {
- content: '\f332';
-}
-.zmdi-time-countdown:before {
- content: '\f333';
-}
-.zmdi-time-interval:before {
- content: '\f334';
-}
-.zmdi-time-restore-setting:before {
- content: '\f335';
-}
-.zmdi-time-restore:before {
- content: '\f336';
-}
-.zmdi-time:before {
- content: '\f337';
-}
-.zmdi-timer-off:before {
- content: '\f338';
-}
-.zmdi-timer:before {
- content: '\f339';
-}
-.zmdi-android-alt:before {
- content: '\f33a';
-}
-.zmdi-android:before {
- content: '\f33b';
-}
-.zmdi-apple:before {
- content: '\f33c';
-}
-.zmdi-behance:before {
- content: '\f33d';
-}
-.zmdi-codepen:before {
- content: '\f33e';
-}
-.zmdi-dribbble:before {
- content: '\f33f';
-}
-.zmdi-dropbox:before {
- content: '\f340';
-}
-.zmdi-evernote:before {
- content: '\f341';
-}
-.zmdi-facebook-box:before {
- content: '\f342';
-}
-.zmdi-facebook:before {
- content: '\f343';
-}
-.zmdi-github-box:before {
- content: '\f344';
-}
-.zmdi-github:before {
- content: '\f345';
-}
-.zmdi-google-drive:before {
- content: '\f346';
-}
-.zmdi-google-earth:before {
- content: '\f347';
-}
-.zmdi-google-glass:before {
- content: '\f348';
-}
-.zmdi-google-maps:before {
- content: '\f349';
-}
-.zmdi-google-pages:before {
- content: '\f34a';
-}
-.zmdi-google-play:before {
- content: '\f34b';
-}
-.zmdi-google-plus-box:before {
- content: '\f34c';
-}
-.zmdi-google-plus:before {
- content: '\f34d';
-}
-.zmdi-google:before {
- content: '\f34e';
-}
-.zmdi-instagram:before {
- content: '\f34f';
-}
-.zmdi-language-css3:before {
- content: '\f350';
-}
-.zmdi-language-html5:before {
- content: '\f351';
-}
-.zmdi-language-javascript:before {
- content: '\f352';
-}
-.zmdi-language-python-alt:before {
- content: '\f353';
-}
-.zmdi-language-python:before {
- content: '\f354';
-}
-.zmdi-lastfm:before {
- content: '\f355';
-}
-.zmdi-linkedin-box:before {
- content: '\f356';
-}
-.zmdi-paypal:before {
- content: '\f357';
-}
-.zmdi-pinterest-box:before {
- content: '\f358';
-}
-.zmdi-pocket:before {
- content: '\f359';
-}
-.zmdi-polymer:before {
- content: '\f35a';
-}
-.zmdi-share:before {
- content: '\f35b';
-}
-.zmdi-stackoverflow:before {
- content: '\f35c';
-}
-.zmdi-steam-square:before {
- content: '\f35d';
-}
-.zmdi-steam:before {
- content: '\f35e';
-}
-.zmdi-twitter-box:before {
- content: '\f35f';
-}
-.zmdi-twitter:before {
- content: '\f360';
-}
-.zmdi-vk:before {
- content: '\f361';
-}
-.zmdi-wikipedia:before {
- content: '\f362';
-}
-.zmdi-windows:before {
- content: '\f363';
-}
-.zmdi-aspect-ratio-alt:before {
- content: '\f364';
-}
-.zmdi-aspect-ratio:before {
- content: '\f365';
-}
-.zmdi-blur-circular:before {
- content: '\f366';
-}
-.zmdi-blur-linear:before {
- content: '\f367';
-}
-.zmdi-blur-off:before {
- content: '\f368';
-}
-.zmdi-blur:before {
- content: '\f369';
-}
-.zmdi-brightness-2:before {
- content: '\f36a';
-}
-.zmdi-brightness-3:before {
- content: '\f36b';
-}
-.zmdi-brightness-4:before {
- content: '\f36c';
-}
-.zmdi-brightness-5:before {
- content: '\f36d';
-}
-.zmdi-brightness-6:before {
- content: '\f36e';
-}
-.zmdi-brightness-7:before {
- content: '\f36f';
-}
-.zmdi-brightness-auto:before {
- content: '\f370';
-}
-.zmdi-brightness-setting:before {
- content: '\f371';
-}
-.zmdi-broken-image:before {
- content: '\f372';
-}
-.zmdi-center-focus-strong:before {
- content: '\f373';
-}
-.zmdi-center-focus-weak:before {
- content: '\f374';
-}
-.zmdi-compare:before {
- content: '\f375';
-}
-.zmdi-crop-16-9:before {
- content: '\f376';
-}
-.zmdi-crop-3-2:before {
- content: '\f377';
-}
-.zmdi-crop-5-4:before {
- content: '\f378';
-}
-.zmdi-crop-7-5:before {
- content: '\f379';
-}
-.zmdi-crop-din:before {
- content: '\f37a';
-}
-.zmdi-crop-free:before {
- content: '\f37b';
-}
-.zmdi-crop-landscape:before {
- content: '\f37c';
-}
-.zmdi-crop-portrait:before {
- content: '\f37d';
-}
-.zmdi-crop-square:before {
- content: '\f37e';
-}
-.zmdi-exposure-alt:before {
- content: '\f37f';
-}
-.zmdi-exposure:before {
- content: '\f380';
-}
-.zmdi-filter-b-and-w:before {
- content: '\f381';
-}
-.zmdi-filter-center-focus:before {
- content: '\f382';
-}
-.zmdi-filter-frames:before {
- content: '\f383';
-}
-.zmdi-filter-tilt-shift:before {
- content: '\f384';
-}
-.zmdi-gradient:before {
- content: '\f385';
-}
-.zmdi-grain:before {
- content: '\f386';
-}
-.zmdi-graphic-eq:before {
- content: '\f387';
-}
-.zmdi-hdr-off:before {
- content: '\f388';
-}
-.zmdi-hdr-strong:before {
- content: '\f389';
-}
-.zmdi-hdr-weak:before {
- content: '\f38a';
-}
-.zmdi-hdr:before {
- content: '\f38b';
-}
-.zmdi-iridescent:before {
- content: '\f38c';
-}
-.zmdi-leak-off:before {
- content: '\f38d';
-}
-.zmdi-leak:before {
- content: '\f38e';
-}
-.zmdi-looks:before {
- content: '\f38f';
-}
-.zmdi-loupe:before {
- content: '\f390';
-}
-.zmdi-panorama-horizontal:before {
- content: '\f391';
-}
-.zmdi-panorama-vertical:before {
- content: '\f392';
-}
-.zmdi-panorama-wide-angle:before {
- content: '\f393';
-}
-.zmdi-photo-size-select-large:before {
- content: '\f394';
-}
-.zmdi-photo-size-select-small:before {
- content: '\f395';
-}
-.zmdi-picture-in-picture:before {
- content: '\f396';
-}
-.zmdi-slideshow:before {
- content: '\f397';
-}
-.zmdi-texture:before {
- content: '\f398';
-}
-.zmdi-tonality:before {
- content: '\f399';
-}
-.zmdi-vignette:before {
- content: '\f39a';
-}
-.zmdi-wb-auto:before {
- content: '\f39b';
-}
-.zmdi-eject-alt:before {
- content: '\f39c';
-}
-.zmdi-eject:before {
- content: '\f39d';
-}
-.zmdi-equalizer:before {
- content: '\f39e';
-}
-.zmdi-fast-forward:before {
- content: '\f39f';
-}
-.zmdi-fast-rewind:before {
- content: '\f3a0';
-}
-.zmdi-forward-10:before {
- content: '\f3a1';
-}
-.zmdi-forward-30:before {
- content: '\f3a2';
-}
-.zmdi-forward-5:before {
- content: '\f3a3';
-}
-.zmdi-hearing:before {
- content: '\f3a4';
-}
-.zmdi-pause-circle-outline:before {
- content: '\f3a5';
-}
-.zmdi-pause-circle:before {
- content: '\f3a6';
-}
-.zmdi-pause:before {
- content: '\f3a7';
-}
-.zmdi-play-circle-outline:before {
- content: '\f3a8';
-}
-.zmdi-play-circle:before {
- content: '\f3a9';
-}
-.zmdi-play:before {
- content: '\f3aa';
-}
-.zmdi-playlist-audio:before {
- content: '\f3ab';
-}
-.zmdi-playlist-plus:before {
- content: '\f3ac';
-}
-.zmdi-repeat-one:before {
- content: '\f3ad';
-}
-.zmdi-repeat:before {
- content: '\f3ae';
-}
-.zmdi-replay-10:before {
- content: '\f3af';
-}
-.zmdi-replay-30:before {
- content: '\f3b0';
-}
-.zmdi-replay-5:before {
- content: '\f3b1';
-}
-.zmdi-replay:before {
- content: '\f3b2';
-}
-.zmdi-shuffle:before {
- content: '\f3b3';
-}
-.zmdi-skip-next:before {
- content: '\f3b4';
-}
-.zmdi-skip-previous:before {
- content: '\f3b5';
-}
-.zmdi-stop:before {
- content: '\f3b6';
-}
-.zmdi-surround-sound:before {
- content: '\f3b7';
-}
-.zmdi-tune:before {
- content: '\f3b8';
-}
-.zmdi-volume-down:before {
- content: '\f3b9';
-}
-.zmdi-volume-mute:before {
- content: '\f3ba';
-}
-.zmdi-volume-off:before {
- content: '\f3bb';
-}
-.zmdi-volume-up:before {
- content: '\f3bc';
-}
-.zmdi-n-1-square:before {
- content: '\f3bd';
-}
-.zmdi-n-2-square:before {
- content: '\f3be';
-}
-.zmdi-n-3-square:before {
- content: '\f3bf';
-}
-.zmdi-n-4-square:before {
- content: '\f3c0';
-}
-.zmdi-n-5-square:before {
- content: '\f3c1';
-}
-.zmdi-n-6-square:before {
- content: '\f3c2';
-}
-.zmdi-neg-1:before {
- content: '\f3c3';
-}
-.zmdi-neg-2:before {
- content: '\f3c4';
-}
-.zmdi-plus-1:before {
- content: '\f3c5';
-}
-.zmdi-plus-2:before {
- content: '\f3c6';
-}
-.zmdi-sec-10:before {
- content: '\f3c7';
-}
-.zmdi-sec-3:before {
- content: '\f3c8';
-}
-.zmdi-zero:before {
- content: '\f3c9';
-}
-.zmdi-airline-seat-flat-angled:before {
- content: '\f3ca';
-}
-.zmdi-airline-seat-flat:before {
- content: '\f3cb';
-}
-.zmdi-airline-seat-individual-suite:before {
- content: '\f3cc';
-}
-.zmdi-airline-seat-legroom-extra:before {
- content: '\f3cd';
-}
-.zmdi-airline-seat-legroom-normal:before {
- content: '\f3ce';
-}
-.zmdi-airline-seat-legroom-reduced:before {
- content: '\f3cf';
-}
-.zmdi-airline-seat-recline-extra:before {
- content: '\f3d0';
-}
-.zmdi-airline-seat-recline-normal:before {
- content: '\f3d1';
-}
-.zmdi-airplay:before {
- content: '\f3d2';
-}
-.zmdi-closed-caption:before {
- content: '\f3d3';
-}
-.zmdi-confirmation-number:before {
- content: '\f3d4';
-}
-.zmdi-developer-board:before {
- content: '\f3d5';
-}
-.zmdi-disc-full:before {
- content: '\f3d6';
-}
-.zmdi-explicit:before {
- content: '\f3d7';
-}
-.zmdi-flight-land:before {
- content: '\f3d8';
-}
-.zmdi-flight-takeoff:before {
- content: '\f3d9';
-}
-.zmdi-flip-to-back:before {
- content: '\f3da';
-}
-.zmdi-flip-to-front:before {
- content: '\f3db';
-}
-.zmdi-group-work:before {
- content: '\f3dc';
-}
-.zmdi-hd:before {
- content: '\f3dd';
-}
-.zmdi-hq:before {
- content: '\f3de';
-}
-.zmdi-markunread-mailbox:before {
- content: '\f3df';
-}
-.zmdi-memory:before {
- content: '\f3e0';
-}
-.zmdi-nfc:before {
- content: '\f3e1';
-}
-.zmdi-play-for-work:before {
- content: '\f3e2';
-}
-.zmdi-power-input:before {
- content: '\f3e3';
-}
-.zmdi-present-to-all:before {
- content: '\f3e4';
-}
-.zmdi-satellite:before {
- content: '\f3e5';
-}
-.zmdi-tap-and-play:before {
- content: '\f3e6';
-}
-.zmdi-vibration:before {
- content: '\f3e7';
-}
-.zmdi-voicemail:before {
- content: '\f3e8';
-}
-.zmdi-group:before {
- content: '\f3e9';
-}
-.zmdi-rss:before {
- content: '\f3ea';
-}
-.zmdi-shape:before {
- content: '\f3eb';
-}
-.zmdi-spinner:before {
- content: '\f3ec';
-}
-.zmdi-ungroup:before {
- content: '\f3ed';
-}
-.zmdi-500px:before {
- content: '\f3ee';
-}
-.zmdi-8tracks:before {
- content: '\f3ef';
-}
-.zmdi-amazon:before {
- content: '\f3f0';
-}
-.zmdi-blogger:before {
- content: '\f3f1';
-}
-.zmdi-delicious:before {
- content: '\f3f2';
-}
-.zmdi-disqus:before {
- content: '\f3f3';
-}
-.zmdi-flattr:before {
- content: '\f3f4';
-}
-.zmdi-flickr:before {
- content: '\f3f5';
-}
-.zmdi-github-alt:before {
- content: '\f3f6';
-}
-.zmdi-google-old:before {
- content: '\f3f7';
-}
-.zmdi-linkedin:before {
- content: '\f3f8';
-}
-.zmdi-odnoklassniki:before {
- content: '\f3f9';
-}
-.zmdi-outlook:before {
- content: '\f3fa';
-}
-.zmdi-paypal-alt:before {
- content: '\f3fb';
-}
-.zmdi-pinterest:before {
- content: '\f3fc';
-}
-.zmdi-playstation:before {
- content: '\f3fd';
-}
-.zmdi-reddit:before {
- content: '\f3fe';
-}
-.zmdi-skype:before {
- content: '\f3ff';
-}
-.zmdi-slideshare:before {
- content: '\f400';
-}
-.zmdi-soundcloud:before {
- content: '\f401';
-}
-.zmdi-tumblr:before {
- content: '\f402';
-}
-.zmdi-twitch:before {
- content: '\f403';
-}
-.zmdi-vimeo:before {
- content: '\f404';
-}
-.zmdi-whatsapp:before {
- content: '\f405';
-}
-.zmdi-xbox:before {
- content: '\f406';
-}
-.zmdi-yahoo:before {
- content: '\f407';
-}
-.zmdi-youtube-play:before {
- content: '\f408';
-}
-.zmdi-youtube:before {
- content: '\f409';
-}
-.zmdi-3d-rotation:before {
- content: '\f101';
-}
-.zmdi-airplane-off:before {
- content: '\f102';
-}
-.zmdi-airplane:before {
- content: '\f103';
-}
-.zmdi-album:before {
- content: '\f104';
-}
-.zmdi-archive:before {
- content: '\f105';
-}
-.zmdi-assignment-account:before {
- content: '\f106';
-}
-.zmdi-assignment-alert:before {
- content: '\f107';
-}
-.zmdi-assignment-check:before {
- content: '\f108';
-}
-.zmdi-assignment-o:before {
- content: '\f109';
-}
-.zmdi-assignment-return:before {
- content: '\f10a';
-}
-.zmdi-assignment-returned:before {
- content: '\f10b';
-}
-.zmdi-assignment:before {
- content: '\f10c';
-}
-.zmdi-attachment-alt:before {
- content: '\f10d';
-}
-.zmdi-attachment:before {
- content: '\f10e';
-}
-.zmdi-audio:before {
- content: '\f10f';
-}
-.zmdi-badge-check:before {
- content: '\f110';
-}
-.zmdi-balance-wallet:before {
- content: '\f111';
-}
-.zmdi-balance:before {
- content: '\f112';
-}
-.zmdi-battery-alert:before {
- content: '\f113';
-}
-.zmdi-battery-flash:before {
- content: '\f114';
-}
-.zmdi-battery-unknown:before {
- content: '\f115';
-}
-.zmdi-battery:before {
- content: '\f116';
-}
-.zmdi-bike:before {
- content: '\f117';
-}
-.zmdi-block-alt:before {
- content: '\f118';
-}
-.zmdi-block:before {
- content: '\f119';
-}
-.zmdi-boat:before {
- content: '\f11a';
-}
-.zmdi-book-image:before {
- content: '\f11b';
-}
-.zmdi-book:before {
- content: '\f11c';
-}
-.zmdi-bookmark-outline:before {
- content: '\f11d';
-}
-.zmdi-bookmark:before {
- content: '\f11e';
-}
-.zmdi-brush:before {
- content: '\f11f';
-}
-.zmdi-bug:before {
- content: '\f120';
-}
-.zmdi-bus:before {
- content: '\f121';
-}
-.zmdi-cake:before {
- content: '\f122';
-}
-.zmdi-car-taxi:before {
- content: '\f123';
-}
-.zmdi-car-wash:before {
- content: '\f124';
-}
-.zmdi-car:before {
- content: '\f125';
-}
-.zmdi-card-giftcard:before {
- content: '\f126';
-}
-.zmdi-card-membership:before {
- content: '\f127';
-}
-.zmdi-card-travel:before {
- content: '\f128';
-}
-.zmdi-card:before {
- content: '\f129';
-}
-.zmdi-case-check:before {
- content: '\f12a';
-}
-.zmdi-case-download:before {
- content: '\f12b';
-}
-.zmdi-case-play:before {
- content: '\f12c';
-}
-.zmdi-case:before {
- content: '\f12d';
-}
-.zmdi-cast-connected:before {
- content: '\f12e';
-}
-.zmdi-cast:before {
- content: '\f12f';
-}
-.zmdi-chart-donut:before {
- content: '\f130';
-}
-.zmdi-chart:before {
- content: '\f131';
-}
-.zmdi-city-alt:before {
- content: '\f132';
-}
-.zmdi-city:before {
- content: '\f133';
-}
-.zmdi-close-circle-o:before {
- content: '\f134';
-}
-.zmdi-close-circle:before {
- content: '\f135';
-}
-.zmdi-close:before {
- content: '\f136';
-}
-.zmdi-cocktail:before {
- content: '\f137';
-}
-.zmdi-code-setting:before {
- content: '\f138';
-}
-.zmdi-code-smartphone:before {
- content: '\f139';
-}
-.zmdi-code:before {
- content: '\f13a';
-}
-.zmdi-coffee:before {
- content: '\f13b';
-}
-.zmdi-collection-bookmark:before {
- content: '\f13c';
-}
-.zmdi-collection-case-play:before {
- content: '\f13d';
-}
-.zmdi-collection-folder-image:before {
- content: '\f13e';
-}
-.zmdi-collection-image-o:before {
- content: '\f13f';
-}
-.zmdi-collection-image:before {
- content: '\f140';
-}
-.zmdi-collection-item-1:before {
- content: '\f141';
-}
-.zmdi-collection-item-2:before {
- content: '\f142';
-}
-.zmdi-collection-item-3:before {
- content: '\f143';
-}
-.zmdi-collection-item-4:before {
- content: '\f144';
-}
-.zmdi-collection-item-5:before {
- content: '\f145';
-}
-.zmdi-collection-item-6:before {
- content: '\f146';
-}
-.zmdi-collection-item-7:before {
- content: '\f147';
-}
-.zmdi-collection-item-8:before {
- content: '\f148';
-}
-.zmdi-collection-item-9-plus:before {
- content: '\f149';
-}
-.zmdi-collection-item-9:before {
- content: '\f14a';
-}
-.zmdi-collection-item:before {
- content: '\f14b';
-}
-.zmdi-collection-music:before {
- content: '\f14c';
-}
-.zmdi-collection-pdf:before {
- content: '\f14d';
-}
-.zmdi-collection-plus:before {
- content: '\f14e';
-}
-.zmdi-collection-speaker:before {
- content: '\f14f';
-}
-.zmdi-collection-text:before {
- content: '\f150';
-}
-.zmdi-collection-video:before {
- content: '\f151';
-}
-.zmdi-compass:before {
- content: '\f152';
-}
-.zmdi-cutlery:before {
- content: '\f153';
-}
-.zmdi-delete:before {
- content: '\f154';
-}
-.zmdi-dialpad:before {
- content: '\f155';
-}
-.zmdi-dns:before {
- content: '\f156';
-}
-.zmdi-drink:before {
- content: '\f157';
-}
-.zmdi-edit:before {
- content: '\f158';
-}
-.zmdi-email-open:before {
- content: '\f159';
-}
-.zmdi-email:before {
- content: '\f15a';
-}
-.zmdi-eye-off:before {
- content: '\f15b';
-}
-.zmdi-eye:before {
- content: '\f15c';
-}
-.zmdi-eyedropper:before {
- content: '\f15d';
-}
-.zmdi-favorite-outline:before {
- content: '\f15e';
-}
-.zmdi-favorite:before {
- content: '\f15f';
-}
-.zmdi-filter-list:before {
- content: '\f160';
-}
-.zmdi-fire:before {
- content: '\f161';
-}
-.zmdi-flag:before {
- content: '\f162';
-}
-.zmdi-flare:before {
- content: '\f163';
-}
-.zmdi-flash-auto:before {
- content: '\f164';
-}
-.zmdi-flash-off:before {
- content: '\f165';
-}
-.zmdi-flash:before {
- content: '\f166';
-}
-.zmdi-flip:before {
- content: '\f167';
-}
-.zmdi-flower-alt:before {
- content: '\f168';
-}
-.zmdi-flower:before {
- content: '\f169';
-}
-.zmdi-font:before {
- content: '\f16a';
-}
-.zmdi-fullscreen-alt:before {
- content: '\f16b';
-}
-.zmdi-fullscreen-exit:before {
- content: '\f16c';
-}
-.zmdi-fullscreen:before {
- content: '\f16d';
-}
-.zmdi-functions:before {
- content: '\f16e';
-}
-.zmdi-gas-station:before {
- content: '\f16f';
-}
-.zmdi-gesture:before {
- content: '\f170';
-}
-.zmdi-globe-alt:before {
- content: '\f171';
-}
-.zmdi-globe-lock:before {
- content: '\f172';
-}
-.zmdi-globe:before {
- content: '\f173';
-}
-.zmdi-graduation-cap:before {
- content: '\f174';
-}
-.zmdi-home:before {
- content: '\f175';
-}
-.zmdi-hospital-alt:before {
- content: '\f176';
-}
-.zmdi-hospital:before {
- content: '\f177';
-}
-.zmdi-hotel:before {
- content: '\f178';
-}
-.zmdi-hourglass-alt:before {
- content: '\f179';
-}
-.zmdi-hourglass-outline:before {
- content: '\f17a';
-}
-.zmdi-hourglass:before {
- content: '\f17b';
-}
-.zmdi-http:before {
- content: '\f17c';
-}
-.zmdi-image-alt:before {
- content: '\f17d';
-}
-.zmdi-image-o:before {
- content: '\f17e';
-}
-.zmdi-image:before {
- content: '\f17f';
-}
-.zmdi-inbox:before {
- content: '\f180';
-}
-.zmdi-invert-colors-off:before {
- content: '\f181';
-}
-.zmdi-invert-colors:before {
- content: '\f182';
-}
-.zmdi-key:before {
- content: '\f183';
-}
-.zmdi-label-alt-outline:before {
- content: '\f184';
-}
-.zmdi-label-alt:before {
- content: '\f185';
-}
-.zmdi-label-heart:before {
- content: '\f186';
-}
-.zmdi-label:before {
- content: '\f187';
-}
-.zmdi-labels:before {
- content: '\f188';
-}
-.zmdi-lamp:before {
- content: '\f189';
-}
-.zmdi-landscape:before {
- content: '\f18a';
-}
-.zmdi-layers-off:before {
- content: '\f18b';
-}
-.zmdi-layers:before {
- content: '\f18c';
-}
-.zmdi-library:before {
- content: '\f18d';
-}
-.zmdi-link:before {
- content: '\f18e';
-}
-.zmdi-lock-open:before {
- content: '\f18f';
-}
-.zmdi-lock-outline:before {
- content: '\f190';
-}
-.zmdi-lock:before {
- content: '\f191';
-}
-.zmdi-mail-reply-all:before {
- content: '\f192';
-}
-.zmdi-mail-reply:before {
- content: '\f193';
-}
-.zmdi-mail-send:before {
- content: '\f194';
-}
-.zmdi-mall:before {
- content: '\f195';
-}
-.zmdi-map:before {
- content: '\f196';
-}
-.zmdi-menu:before {
- content: '\f197';
-}
-.zmdi-money-box:before {
- content: '\f198';
-}
-.zmdi-money-off:before {
- content: '\f199';
-}
-.zmdi-money:before {
- content: '\f19a';
-}
-.zmdi-more-vert:before {
- content: '\f19b';
-}
-.zmdi-more:before {
- content: '\f19c';
-}
-.zmdi-movie-alt:before {
- content: '\f19d';
-}
-.zmdi-movie:before {
- content: '\f19e';
-}
-.zmdi-nature-people:before {
- content: '\f19f';
-}
-.zmdi-nature:before {
- content: '\f1a0';
-}
-.zmdi-navigation:before {
- content: '\f1a1';
-}
-.zmdi-open-in-browser:before {
- content: '\f1a2';
-}
-.zmdi-open-in-new:before {
- content: '\f1a3';
-}
-.zmdi-palette:before {
- content: '\f1a4';
-}
-.zmdi-parking:before {
- content: '\f1a5';
-}
-.zmdi-pin-account:before {
- content: '\f1a6';
-}
-.zmdi-pin-assistant:before {
- content: '\f1a7';
-}
-.zmdi-pin-drop:before {
- content: '\f1a8';
-}
-.zmdi-pin-help:before {
- content: '\f1a9';
-}
-.zmdi-pin-off:before {
- content: '\f1aa';
-}
-.zmdi-pin:before {
- content: '\f1ab';
-}
-.zmdi-pizza:before {
- content: '\f1ac';
-}
-.zmdi-plaster:before {
- content: '\f1ad';
-}
-.zmdi-power-setting:before {
- content: '\f1ae';
-}
-.zmdi-power:before {
- content: '\f1af';
-}
-.zmdi-print:before {
- content: '\f1b0';
-}
-.zmdi-puzzle-piece:before {
- content: '\f1b1';
-}
-.zmdi-quote:before {
- content: '\f1b2';
-}
-.zmdi-railway:before {
- content: '\f1b3';
-}
-.zmdi-receipt:before {
- content: '\f1b4';
-}
-.zmdi-refresh-alt:before {
- content: '\f1b5';
-}
-.zmdi-refresh-sync-alert:before {
- content: '\f1b6';
-}
-.zmdi-refresh-sync-off:before {
- content: '\f1b7';
-}
-.zmdi-refresh-sync:before {
- content: '\f1b8';
-}
-.zmdi-refresh:before {
- content: '\f1b9';
-}
-.zmdi-roller:before {
- content: '\f1ba';
-}
-.zmdi-ruler:before {
- content: '\f1bb';
-}
-.zmdi-scissors:before {
- content: '\f1bc';
-}
-.zmdi-screen-rotation-lock:before {
- content: '\f1bd';
-}
-.zmdi-screen-rotation:before {
- content: '\f1be';
-}
-.zmdi-search-for:before {
- content: '\f1bf';
-}
-.zmdi-search-in-file:before {
- content: '\f1c0';
-}
-.zmdi-search-in-page:before {
- content: '\f1c1';
-}
-.zmdi-search-replace:before {
- content: '\f1c2';
-}
-.zmdi-search:before {
- content: '\f1c3';
-}
-.zmdi-seat:before {
- content: '\f1c4';
-}
-.zmdi-settings-square:before {
- content: '\f1c5';
-}
-.zmdi-settings:before {
- content: '\f1c6';
-}
-.zmdi-shield-check:before {
- content: '\f1c7';
-}
-.zmdi-shield-security:before {
- content: '\f1c8';
-}
-.zmdi-shopping-basket:before {
- content: '\f1c9';
-}
-.zmdi-shopping-cart-plus:before {
- content: '\f1ca';
-}
-.zmdi-shopping-cart:before {
- content: '\f1cb';
-}
-.zmdi-sign-in:before {
- content: '\f1cc';
-}
-.zmdi-sort-amount-asc:before {
- content: '\f1cd';
-}
-.zmdi-sort-amount-desc:before {
- content: '\f1ce';
-}
-.zmdi-sort-asc:before {
- content: '\f1cf';
-}
-.zmdi-sort-desc:before {
- content: '\f1d0';
-}
-.zmdi-spellcheck:before {
- content: '\f1d1';
-}
-.zmdi-storage:before {
- content: '\f1d2';
-}
-.zmdi-store-24:before {
- content: '\f1d3';
-}
-.zmdi-store:before {
- content: '\f1d4';
-}
-.zmdi-subway:before {
- content: '\f1d5';
-}
-.zmdi-sun:before {
- content: '\f1d6';
-}
-.zmdi-tab-unselected:before {
- content: '\f1d7';
-}
-.zmdi-tab:before {
- content: '\f1d8';
-}
-.zmdi-tag-close:before {
- content: '\f1d9';
-}
-.zmdi-tag-more:before {
- content: '\f1da';
-}
-.zmdi-tag:before {
- content: '\f1db';
-}
-.zmdi-thumb-down:before {
- content: '\f1dc';
-}
-.zmdi-thumb-up-down:before {
- content: '\f1dd';
-}
-.zmdi-thumb-up:before {
- content: '\f1de';
-}
-.zmdi-ticket-star:before {
- content: '\f1df';
-}
-.zmdi-toll:before {
- content: '\f1e0';
-}
-.zmdi-toys:before {
- content: '\f1e1';
-}
-.zmdi-traffic:before {
- content: '\f1e2';
-}
-.zmdi-translate:before {
- content: '\f1e3';
-}
-.zmdi-triangle-down:before {
- content: '\f1e4';
-}
-.zmdi-triangle-up:before {
- content: '\f1e5';
-}
-.zmdi-truck:before {
- content: '\f1e6';
-}
-.zmdi-turning-sign:before {
- content: '\f1e7';
-}
-.zmdi-wallpaper:before {
- content: '\f1e8';
-}
-.zmdi-washing-machine:before {
- content: '\f1e9';
-}
-.zmdi-window-maximize:before {
- content: '\f1ea';
-}
-.zmdi-window-minimize:before {
- content: '\f1eb';
-}
-.zmdi-window-restore:before {
- content: '\f1ec';
-}
-.zmdi-wrench:before {
- content: '\f1ed';
-}
-.zmdi-zoom-in:before {
- content: '\f1ee';
-}
-.zmdi-zoom-out:before {
- content: '\f1ef';
-}
-.zmdi-alert-circle-o:before {
- content: '\f1f0';
-}
-.zmdi-alert-circle:before {
- content: '\f1f1';
-}
-.zmdi-alert-octagon:before {
- content: '\f1f2';
-}
-.zmdi-alert-polygon:before {
- content: '\f1f3';
-}
-.zmdi-alert-triangle:before {
- content: '\f1f4';
-}
-.zmdi-help-outline:before {
- content: '\f1f5';
-}
-.zmdi-help:before {
- content: '\f1f6';
-}
-.zmdi-info-outline:before {
- content: '\f1f7';
-}
-.zmdi-info:before {
- content: '\f1f8';
-}
-.zmdi-notifications-active:before {
- content: '\f1f9';
-}
-.zmdi-notifications-add:before {
- content: '\f1fa';
-}
-.zmdi-notifications-none:before {
- content: '\f1fb';
-}
-.zmdi-notifications-off:before {
- content: '\f1fc';
-}
-.zmdi-notifications-paused:before {
- content: '\f1fd';
-}
-.zmdi-notifications:before {
- content: '\f1fe';
-}
-.zmdi-account-add:before {
- content: '\f1ff';
-}
-.zmdi-account-box-mail:before {
- content: '\f200';
-}
-.zmdi-account-box-o:before {
- content: '\f201';
-}
-.zmdi-account-box-phone:before {
- content: '\f202';
-}
-.zmdi-account-box:before {
- content: '\f203';
-}
-.zmdi-account-calendar:before {
- content: '\f204';
-}
-.zmdi-account-circle:before {
- content: '\f205';
-}
-.zmdi-account-o:before {
- content: '\f206';
-}
-.zmdi-account:before {
- content: '\f207';
-}
-.zmdi-accounts-add:before {
- content: '\f208';
-}
-.zmdi-accounts-alt:before {
- content: '\f209';
-}
-.zmdi-accounts-list-alt:before {
- content: '\f20a';
-}
-.zmdi-accounts-list:before {
- content: '\f20b';
-}
-.zmdi-accounts-outline:before {
- content: '\f20c';
-}
-.zmdi-accounts:before {
- content: '\f20d';
-}
-.zmdi-face:before {
- content: '\f20e';
-}
-.zmdi-female:before {
- content: '\f20f';
-}
-.zmdi-male-alt:before {
- content: '\f210';
-}
-.zmdi-male-female:before {
- content: '\f211';
-}
-.zmdi-male:before {
- content: '\f212';
-}
-.zmdi-mood-bad:before {
- content: '\f213';
-}
-.zmdi-mood:before {
- content: '\f214';
-}
-.zmdi-run:before {
- content: '\f215';
-}
-.zmdi-walk:before {
- content: '\f216';
-}
-.zmdi-cloud-box:before {
- content: '\f217';
-}
-.zmdi-cloud-circle:before {
- content: '\f218';
-}
-.zmdi-cloud-done:before {
- content: '\f219';
-}
-.zmdi-cloud-download:before {
- content: '\f21a';
-}
-.zmdi-cloud-off:before {
- content: '\f21b';
-}
-.zmdi-cloud-outline-alt:before {
- content: '\f21c';
-}
-.zmdi-cloud-outline:before {
- content: '\f21d';
-}
-.zmdi-cloud-upload:before {
- content: '\f21e';
-}
-.zmdi-cloud:before {
- content: '\f21f';
-}
-.zmdi-download:before {
- content: '\f220';
-}
-.zmdi-file-plus:before {
- content: '\f221';
-}
-.zmdi-file-text:before {
- content: '\f222';
-}
-.zmdi-file:before {
- content: '\f223';
-}
-.zmdi-folder-outline:before {
- content: '\f224';
-}
-.zmdi-folder-person:before {
- content: '\f225';
-}
-.zmdi-folder-star-alt:before {
- content: '\f226';
-}
-.zmdi-folder-star:before {
- content: '\f227';
-}
-.zmdi-folder:before {
- content: '\f228';
-}
-.zmdi-gif:before {
- content: '\f229';
-}
-.zmdi-upload:before {
- content: '\f22a';
-}
-.zmdi-border-all:before {
- content: '\f22b';
-}
-.zmdi-border-bottom:before {
- content: '\f22c';
-}
-.zmdi-border-clear:before {
- content: '\f22d';
-}
-.zmdi-border-color:before {
- content: '\f22e';
-}
-.zmdi-border-horizontal:before {
- content: '\f22f';
-}
-.zmdi-border-inner:before {
- content: '\f230';
-}
-.zmdi-border-left:before {
- content: '\f231';
-}
-.zmdi-border-outer:before {
- content: '\f232';
-}
-.zmdi-border-right:before {
- content: '\f233';
-}
-.zmdi-border-style:before {
- content: '\f234';
-}
-.zmdi-border-top:before {
- content: '\f235';
-}
-.zmdi-border-vertical:before {
- content: '\f236';
-}
-.zmdi-copy:before {
- content: '\f237';
-}
-.zmdi-crop:before {
- content: '\f238';
-}
-.zmdi-format-align-center:before {
- content: '\f239';
-}
-.zmdi-format-align-justify:before {
- content: '\f23a';
-}
-.zmdi-format-align-left:before {
- content: '\f23b';
-}
-.zmdi-format-align-right:before {
- content: '\f23c';
-}
-.zmdi-format-bold:before {
- content: '\f23d';
-}
-.zmdi-format-clear-all:before {
- content: '\f23e';
-}
-.zmdi-format-clear:before {
- content: '\f23f';
-}
-.zmdi-format-color-fill:before {
- content: '\f240';
-}
-.zmdi-format-color-reset:before {
- content: '\f241';
-}
-.zmdi-format-color-text:before {
- content: '\f242';
-}
-.zmdi-format-indent-decrease:before {
- content: '\f243';
-}
-.zmdi-format-indent-increase:before {
- content: '\f244';
-}
-.zmdi-format-italic:before {
- content: '\f245';
-}
-.zmdi-format-line-spacing:before {
- content: '\f246';
-}
-.zmdi-format-list-bulleted:before {
- content: '\f247';
-}
-.zmdi-format-list-numbered:before {
- content: '\f248';
-}
-.zmdi-format-ltr:before {
- content: '\f249';
-}
-.zmdi-format-rtl:before {
- content: '\f24a';
-}
-.zmdi-format-size:before {
- content: '\f24b';
-}
-.zmdi-format-strikethrough-s:before {
- content: '\f24c';
-}
-.zmdi-format-strikethrough:before {
- content: '\f24d';
-}
-.zmdi-format-subject:before {
- content: '\f24e';
-}
-.zmdi-format-underlined:before {
- content: '\f24f';
-}
-.zmdi-format-valign-bottom:before {
- content: '\f250';
-}
-.zmdi-format-valign-center:before {
- content: '\f251';
-}
-.zmdi-format-valign-top:before {
- content: '\f252';
-}
-.zmdi-redo:before {
- content: '\f253';
-}
-.zmdi-select-all:before {
- content: '\f254';
-}
-.zmdi-space-bar:before {
- content: '\f255';
-}
-.zmdi-text-format:before {
- content: '\f256';
-}
-.zmdi-transform:before {
- content: '\f257';
-}
-.zmdi-undo:before {
- content: '\f258';
-}
-.zmdi-wrap-text:before {
- content: '\f259';
-}
-.zmdi-comment-alert:before {
- content: '\f25a';
-}
-.zmdi-comment-alt-text:before {
- content: '\f25b';
-}
-.zmdi-comment-alt:before {
- content: '\f25c';
-}
-.zmdi-comment-edit:before {
- content: '\f25d';
-}
-.zmdi-comment-image:before {
- content: '\f25e';
-}
-.zmdi-comment-list:before {
- content: '\f25f';
-}
-.zmdi-comment-more:before {
- content: '\f260';
-}
-.zmdi-comment-outline:before {
- content: '\f261';
-}
-.zmdi-comment-text-alt:before {
- content: '\f262';
-}
-.zmdi-comment-text:before {
- content: '\f263';
-}
-.zmdi-comment-video:before {
- content: '\f264';
-}
-.zmdi-comment:before {
- content: '\f265';
-}
-.zmdi-comments:before {
- content: '\f266';
-}
-.zmdi-check-all:before {
- content: '\f267';
-}
-.zmdi-check-circle-u:before {
- content: '\f268';
-}
-.zmdi-check-circle:before {
- content: '\f269';
-}
-.zmdi-check-square:before {
- content: '\f26a';
-}
-.zmdi-check:before {
- content: '\f26b';
-}
-.zmdi-circle-o:before {
- content: '\f26c';
-}
-.zmdi-circle:before {
- content: '\f26d';
-}
-.zmdi-dot-circle-alt:before {
- content: '\f26e';
-}
-.zmdi-dot-circle:before {
- content: '\f26f';
-}
-.zmdi-minus-circle-outline:before {
- content: '\f270';
-}
-.zmdi-minus-circle:before {
- content: '\f271';
-}
-.zmdi-minus-square:before {
- content: '\f272';
-}
-.zmdi-minus:before {
- content: '\f273';
-}
-.zmdi-plus-circle-o-duplicate:before {
- content: '\f274';
-}
-.zmdi-plus-circle-o:before {
- content: '\f275';
-}
-.zmdi-plus-circle:before {
- content: '\f276';
-}
-.zmdi-plus-square:before {
- content: '\f277';
-}
-.zmdi-plus:before {
- content: '\f278';
-}
-.zmdi-square-o:before {
- content: '\f279';
-}
-.zmdi-star-circle:before {
- content: '\f27a';
-}
-.zmdi-star-half:before {
- content: '\f27b';
-}
-.zmdi-star-outline:before {
- content: '\f27c';
-}
-.zmdi-star:before {
- content: '\f27d';
-}
-.zmdi-bluetooth-connected:before {
- content: '\f27e';
-}
-.zmdi-bluetooth-off:before {
- content: '\f27f';
-}
-.zmdi-bluetooth-search:before {
- content: '\f280';
-}
-.zmdi-bluetooth-setting:before {
- content: '\f281';
-}
-.zmdi-bluetooth:before {
- content: '\f282';
-}
-.zmdi-camera-add:before {
- content: '\f283';
-}
-.zmdi-camera-alt:before {
- content: '\f284';
-}
-.zmdi-camera-bw:before {
- content: '\f285';
-}
-.zmdi-camera-front:before {
- content: '\f286';
-}
-.zmdi-camera-mic:before {
- content: '\f287';
-}
-.zmdi-camera-party-mode:before {
- content: '\f288';
-}
-.zmdi-camera-rear:before {
- content: '\f289';
-}
-.zmdi-camera-roll:before {
- content: '\f28a';
-}
-.zmdi-camera-switch:before {
- content: '\f28b';
-}
-.zmdi-camera:before {
- content: '\f28c';
-}
-.zmdi-card-alert:before {
- content: '\f28d';
-}
-.zmdi-card-off:before {
- content: '\f28e';
-}
-.zmdi-card-sd:before {
- content: '\f28f';
-}
-.zmdi-card-sim:before {
- content: '\f290';
-}
-.zmdi-desktop-mac:before {
- content: '\f291';
-}
-.zmdi-desktop-windows:before {
- content: '\f292';
-}
-.zmdi-device-hub:before {
- content: '\f293';
-}
-.zmdi-devices-off:before {
- content: '\f294';
-}
-.zmdi-devices:before {
- content: '\f295';
-}
-.zmdi-dock:before {
- content: '\f296';
-}
-.zmdi-floppy:before {
- content: '\f297';
-}
-.zmdi-gamepad:before {
- content: '\f298';
-}
-.zmdi-gps-dot:before {
- content: '\f299';
-}
-.zmdi-gps-off:before {
- content: '\f29a';
-}
-.zmdi-gps:before {
- content: '\f29b';
-}
-.zmdi-headset-mic:before {
- content: '\f29c';
-}
-.zmdi-headset:before {
- content: '\f29d';
-}
-.zmdi-input-antenna:before {
- content: '\f29e';
-}
-.zmdi-input-composite:before {
- content: '\f29f';
-}
-.zmdi-input-hdmi:before {
- content: '\f2a0';
-}
-.zmdi-input-power:before {
- content: '\f2a1';
-}
-.zmdi-input-svideo:before {
- content: '\f2a2';
-}
-.zmdi-keyboard-hide:before {
- content: '\f2a3';
-}
-.zmdi-keyboard:before {
- content: '\f2a4';
-}
-.zmdi-laptop-chromebook:before {
- content: '\f2a5';
-}
-.zmdi-laptop-mac:before {
- content: '\f2a6';
-}
-.zmdi-laptop:before {
- content: '\f2a7';
-}
-.zmdi-mic-off:before {
- content: '\f2a8';
-}
-.zmdi-mic-outline:before {
- content: '\f2a9';
-}
-.zmdi-mic-setting:before {
- content: '\f2aa';
-}
-.zmdi-mic:before {
- content: '\f2ab';
-}
-.zmdi-mouse:before {
- content: '\f2ac';
-}
-.zmdi-network-alert:before {
- content: '\f2ad';
-}
-.zmdi-network-locked:before {
- content: '\f2ae';
-}
-.zmdi-network-off:before {
- content: '\f2af';
-}
-.zmdi-network-outline:before {
- content: '\f2b0';
-}
-.zmdi-network-setting:before {
- content: '\f2b1';
-}
-.zmdi-network:before {
- content: '\f2b2';
-}
-.zmdi-phone-bluetooth:before {
- content: '\f2b3';
-}
-.zmdi-phone-end:before {
- content: '\f2b4';
-}
-.zmdi-phone-forwarded:before {
- content: '\f2b5';
-}
-.zmdi-phone-in-talk:before {
- content: '\f2b6';
-}
-.zmdi-phone-locked:before {
- content: '\f2b7';
-}
-.zmdi-phone-missed:before {
- content: '\f2b8';
-}
-.zmdi-phone-msg:before {
- content: '\f2b9';
-}
-.zmdi-phone-paused:before {
- content: '\f2ba';
-}
-.zmdi-phone-ring:before {
- content: '\f2bb';
-}
-.zmdi-phone-setting:before {
- content: '\f2bc';
-}
-.zmdi-phone-sip:before {
- content: '\f2bd';
-}
-.zmdi-phone:before {
- content: '\f2be';
-}
-.zmdi-portable-wifi-changes:before {
- content: '\f2bf';
-}
-.zmdi-portable-wifi-off:before {
- content: '\f2c0';
-}
-.zmdi-portable-wifi:before {
- content: '\f2c1';
-}
-.zmdi-radio:before {
- content: '\f2c2';
-}
-.zmdi-reader:before {
- content: '\f2c3';
-}
-.zmdi-remote-control-alt:before {
- content: '\f2c4';
-}
-.zmdi-remote-control:before {
- content: '\f2c5';
-}
-.zmdi-router:before {
- content: '\f2c6';
-}
-.zmdi-scanner:before {
- content: '\f2c7';
-}
-.zmdi-smartphone-android:before {
- content: '\f2c8';
-}
-.zmdi-smartphone-download:before {
- content: '\f2c9';
-}
-.zmdi-smartphone-erase:before {
- content: '\f2ca';
-}
-.zmdi-smartphone-info:before {
- content: '\f2cb';
-}
-.zmdi-smartphone-iphone:before {
- content: '\f2cc';
-}
-.zmdi-smartphone-landscape-lock:before {
- content: '\f2cd';
-}
-.zmdi-smartphone-landscape:before {
- content: '\f2ce';
-}
-.zmdi-smartphone-lock:before {
- content: '\f2cf';
-}
-.zmdi-smartphone-portrait-lock:before {
- content: '\f2d0';
-}
-.zmdi-smartphone-ring:before {
- content: '\f2d1';
-}
-.zmdi-smartphone-setting:before {
- content: '\f2d2';
-}
-.zmdi-smartphone-setup:before {
- content: '\f2d3';
-}
-.zmdi-smartphone:before {
- content: '\f2d4';
-}
-.zmdi-speaker:before {
- content: '\f2d5';
-}
-.zmdi-tablet-android:before {
- content: '\f2d6';
-}
-.zmdi-tablet-mac:before {
- content: '\f2d7';
-}
-.zmdi-tablet:before {
- content: '\f2d8';
-}
-.zmdi-tv-alt-play:before {
- content: '\f2d9';
-}
-.zmdi-tv-list:before {
- content: '\f2da';
-}
-.zmdi-tv-play:before {
- content: '\f2db';
-}
-.zmdi-tv:before {
- content: '\f2dc';
-}
-.zmdi-usb:before {
- content: '\f2dd';
-}
-.zmdi-videocam-off:before {
- content: '\f2de';
-}
-.zmdi-videocam-switch:before {
- content: '\f2df';
-}
-.zmdi-videocam:before {
- content: '\f2e0';
-}
-.zmdi-watch:before {
- content: '\f2e1';
-}
-.zmdi-wifi-alt-2:before {
- content: '\f2e2';
-}
-.zmdi-wifi-alt:before {
- content: '\f2e3';
-}
-.zmdi-wifi-info:before {
- content: '\f2e4';
-}
-.zmdi-wifi-lock:before {
- content: '\f2e5';
-}
-.zmdi-wifi-off:before {
- content: '\f2e6';
-}
-.zmdi-wifi-outline:before {
- content: '\f2e7';
-}
-.zmdi-wifi:before {
- content: '\f2e8';
-}
-.zmdi-arrow-left-bottom:before {
- content: '\f2e9';
-}
-.zmdi-arrow-left:before {
- content: '\f2ea';
-}
-.zmdi-arrow-merge:before {
- content: '\f2eb';
-}
-.zmdi-arrow-missed:before {
- content: '\f2ec';
-}
-.zmdi-arrow-right-top:before {
- content: '\f2ed';
-}
-.zmdi-arrow-right:before {
- content: '\f2ee';
-}
-.zmdi-arrow-split:before {
- content: '\f2ef';
-}
-.zmdi-arrows:before {
- content: '\f2f0';
-}
-.zmdi-caret-down-circle:before {
- content: '\f2f1';
-}
-.zmdi-caret-down:before {
- content: '\f2f2';
-}
-.zmdi-caret-left-circle:before {
- content: '\f2f3';
-}
-.zmdi-caret-left:before {
- content: '\f2f4';
-}
-.zmdi-caret-right-circle:before {
- content: '\f2f5';
-}
-.zmdi-caret-right:before {
- content: '\f2f6';
-}
-.zmdi-caret-up-circle:before {
- content: '\f2f7';
-}
-.zmdi-caret-up:before {
- content: '\f2f8';
-}
-.zmdi-chevron-down:before {
- content: '\f2f9';
-}
-.zmdi-chevron-left:before {
- content: '\f2fa';
-}
-.zmdi-chevron-right:before {
- content: '\f2fb';
-}
-.zmdi-chevron-up:before {
- content: '\f2fc';
-}
-.zmdi-forward:before {
- content: '\f2fd';
-}
-.zmdi-long-arrow-down:before {
- content: '\f2fe';
-}
-.zmdi-long-arrow-left:before {
- content: '\f2ff';
-}
-.zmdi-long-arrow-return:before {
- content: '\f300';
-}
-.zmdi-long-arrow-right:before {
- content: '\f301';
-}
-.zmdi-long-arrow-tab:before {
- content: '\f302';
-}
-.zmdi-long-arrow-up:before {
- content: '\f303';
-}
-.zmdi-rotate-ccw:before {
- content: '\f304';
-}
-.zmdi-rotate-cw:before {
- content: '\f305';
-}
-.zmdi-rotate-left:before {
- content: '\f306';
-}
-.zmdi-rotate-right:before {
- content: '\f307';
-}
-.zmdi-square-down:before {
- content: '\f308';
-}
-.zmdi-square-right:before {
- content: '\f309';
-}
-.zmdi-swap-alt:before {
- content: '\f30a';
-}
-.zmdi-swap-vertical-circle:before {
- content: '\f30b';
-}
-.zmdi-swap-vertical:before {
- content: '\f30c';
-}
-.zmdi-swap:before {
- content: '\f30d';
-}
-.zmdi-trending-down:before {
- content: '\f30e';
-}
-.zmdi-trending-flat:before {
- content: '\f30f';
-}
-.zmdi-trending-up:before {
- content: '\f310';
-}
-.zmdi-unfold-less:before {
- content: '\f311';
-}
-.zmdi-unfold-more:before {
- content: '\f312';
-}
-.zmdi-apps:before {
- content: '\f313';
-}
-.zmdi-grid-off:before {
- content: '\f314';
-}
-.zmdi-grid:before {
- content: '\f315';
-}
-.zmdi-view-agenda:before {
- content: '\f316';
-}
-.zmdi-view-array:before {
- content: '\f317';
-}
-.zmdi-view-carousel:before {
- content: '\f318';
-}
-.zmdi-view-column:before {
- content: '\f319';
-}
-.zmdi-view-comfy:before {
- content: '\f31a';
-}
-.zmdi-view-compact:before {
- content: '\f31b';
-}
-.zmdi-view-dashboard:before {
- content: '\f31c';
-}
-.zmdi-view-day:before {
- content: '\f31d';
-}
-.zmdi-view-headline:before {
- content: '\f31e';
-}
-.zmdi-view-list-alt:before {
- content: '\f31f';
-}
-.zmdi-view-list:before {
- content: '\f320';
-}
-.zmdi-view-module:before {
- content: '\f321';
-}
-.zmdi-view-quilt:before {
- content: '\f322';
-}
-.zmdi-view-stream:before {
- content: '\f323';
-}
-.zmdi-view-subtitles:before {
- content: '\f324';
-}
-.zmdi-view-toc:before {
- content: '\f325';
-}
-.zmdi-view-web:before {
- content: '\f326';
-}
-.zmdi-view-week:before {
- content: '\f327';
-}
-.zmdi-widgets:before {
- content: '\f328';
-}
-.zmdi-alarm-check:before {
- content: '\f329';
-}
-.zmdi-alarm-off:before {
- content: '\f32a';
-}
-.zmdi-alarm-plus:before {
- content: '\f32b';
-}
-.zmdi-alarm-snooze:before {
- content: '\f32c';
-}
-.zmdi-alarm:before {
- content: '\f32d';
-}
-.zmdi-calendar-alt:before {
- content: '\f32e';
-}
-.zmdi-calendar-check:before {
- content: '\f32f';
-}
-.zmdi-calendar-close:before {
- content: '\f330';
-}
-.zmdi-calendar-note:before {
- content: '\f331';
-}
-.zmdi-calendar:before {
- content: '\f332';
-}
-.zmdi-time-countdown:before {
- content: '\f333';
-}
-.zmdi-time-interval:before {
- content: '\f334';
-}
-.zmdi-time-restore-setting:before {
- content: '\f335';
-}
-.zmdi-time-restore:before {
- content: '\f336';
-}
-.zmdi-time:before {
- content: '\f337';
-}
-.zmdi-timer-off:before {
- content: '\f338';
-}
-.zmdi-timer:before {
- content: '\f339';
-}
-.zmdi-android-alt:before {
- content: '\f33a';
-}
-.zmdi-android:before {
- content: '\f33b';
-}
-.zmdi-apple:before {
- content: '\f33c';
-}
-.zmdi-behance:before {
- content: '\f33d';
-}
-.zmdi-codepen:before {
- content: '\f33e';
-}
-.zmdi-dribbble:before {
- content: '\f33f';
-}
-.zmdi-dropbox:before {
- content: '\f340';
-}
-.zmdi-evernote:before {
- content: '\f341';
-}
-.zmdi-facebook-box:before {
- content: '\f342';
-}
-.zmdi-facebook:before {
- content: '\f343';
-}
-.zmdi-github-box:before {
- content: '\f344';
-}
-.zmdi-github:before {
- content: '\f345';
-}
-.zmdi-google-drive:before {
- content: '\f346';
-}
-.zmdi-google-earth:before {
- content: '\f347';
-}
-.zmdi-google-glass:before {
- content: '\f348';
-}
-.zmdi-google-maps:before {
- content: '\f349';
-}
-.zmdi-google-pages:before {
- content: '\f34a';
-}
-.zmdi-google-play:before {
- content: '\f34b';
-}
-.zmdi-google-plus-box:before {
- content: '\f34c';
-}
-.zmdi-google-plus:before {
- content: '\f34d';
-}
-.zmdi-google:before {
- content: '\f34e';
-}
-.zmdi-instagram:before {
- content: '\f34f';
-}
-.zmdi-language-css3:before {
- content: '\f350';
-}
-.zmdi-language-html5:before {
- content: '\f351';
-}
-.zmdi-language-javascript:before {
- content: '\f352';
-}
-.zmdi-language-python-alt:before {
- content: '\f353';
-}
-.zmdi-language-python:before {
- content: '\f354';
-}
-.zmdi-lastfm:before {
- content: '\f355';
-}
-.zmdi-linkedin-box:before {
- content: '\f356';
-}
-.zmdi-paypal:before {
- content: '\f357';
-}
-.zmdi-pinterest-box:before {
- content: '\f358';
-}
-.zmdi-pocket:before {
- content: '\f359';
-}
-.zmdi-polymer:before {
- content: '\f35a';
-}
-.zmdi-share:before {
- content: '\f35b';
-}
-.zmdi-stackoverflow:before {
- content: '\f35c';
-}
-.zmdi-steam-square:before {
- content: '\f35d';
-}
-.zmdi-steam:before {
- content: '\f35e';
-}
-.zmdi-twitter-box:before {
- content: '\f35f';
-}
-.zmdi-twitter:before {
- content: '\f360';
-}
-.zmdi-vk:before {
- content: '\f361';
-}
-.zmdi-wikipedia:before {
- content: '\f362';
-}
-.zmdi-windows:before {
- content: '\f363';
-}
-.zmdi-aspect-ratio-alt:before {
- content: '\f364';
-}
-.zmdi-aspect-ratio:before {
- content: '\f365';
-}
-.zmdi-blur-circular:before {
- content: '\f366';
-}
-.zmdi-blur-linear:before {
- content: '\f367';
-}
-.zmdi-blur-off:before {
- content: '\f368';
-}
-.zmdi-blur:before {
- content: '\f369';
-}
-.zmdi-brightness-2:before {
- content: '\f36a';
-}
-.zmdi-brightness-3:before {
- content: '\f36b';
-}
-.zmdi-brightness-4:before {
- content: '\f36c';
-}
-.zmdi-brightness-5:before {
- content: '\f36d';
-}
-.zmdi-brightness-6:before {
- content: '\f36e';
-}
-.zmdi-brightness-7:before {
- content: '\f36f';
-}
-.zmdi-brightness-auto:before {
- content: '\f370';
-}
-.zmdi-brightness-setting:before {
- content: '\f371';
-}
-.zmdi-broken-image:before {
- content: '\f372';
-}
-.zmdi-center-focus-strong:before {
- content: '\f373';
-}
-.zmdi-center-focus-weak:before {
- content: '\f374';
-}
-.zmdi-compare:before {
- content: '\f375';
-}
-.zmdi-crop-16-9:before {
- content: '\f376';
-}
-.zmdi-crop-3-2:before {
- content: '\f377';
-}
-.zmdi-crop-5-4:before {
- content: '\f378';
-}
-.zmdi-crop-7-5:before {
- content: '\f379';
-}
-.zmdi-crop-din:before {
- content: '\f37a';
-}
-.zmdi-crop-free:before {
- content: '\f37b';
-}
-.zmdi-crop-landscape:before {
- content: '\f37c';
-}
-.zmdi-crop-portrait:before {
- content: '\f37d';
-}
-.zmdi-crop-square:before {
- content: '\f37e';
-}
-.zmdi-exposure-alt:before {
- content: '\f37f';
-}
-.zmdi-exposure:before {
- content: '\f380';
-}
-.zmdi-filter-b-and-w:before {
- content: '\f381';
-}
-.zmdi-filter-center-focus:before {
- content: '\f382';
-}
-.zmdi-filter-frames:before {
- content: '\f383';
-}
-.zmdi-filter-tilt-shift:before {
- content: '\f384';
-}
-.zmdi-gradient:before {
- content: '\f385';
-}
-.zmdi-grain:before {
- content: '\f386';
-}
-.zmdi-graphic-eq:before {
- content: '\f387';
-}
-.zmdi-hdr-off:before {
- content: '\f388';
-}
-.zmdi-hdr-strong:before {
- content: '\f389';
-}
-.zmdi-hdr-weak:before {
- content: '\f38a';
-}
-.zmdi-hdr:before {
- content: '\f38b';
-}
-.zmdi-iridescent:before {
- content: '\f38c';
-}
-.zmdi-leak-off:before {
- content: '\f38d';
-}
-.zmdi-leak:before {
- content: '\f38e';
-}
-.zmdi-looks:before {
- content: '\f38f';
-}
-.zmdi-loupe:before {
- content: '\f390';
-}
-.zmdi-panorama-horizontal:before {
- content: '\f391';
-}
-.zmdi-panorama-vertical:before {
- content: '\f392';
-}
-.zmdi-panorama-wide-angle:before {
- content: '\f393';
-}
-.zmdi-photo-size-select-large:before {
- content: '\f394';
-}
-.zmdi-photo-size-select-small:before {
- content: '\f395';
-}
-.zmdi-picture-in-picture:before {
- content: '\f396';
-}
-.zmdi-slideshow:before {
- content: '\f397';
-}
-.zmdi-texture:before {
- content: '\f398';
-}
-.zmdi-tonality:before {
- content: '\f399';
-}
-.zmdi-vignette:before {
- content: '\f39a';
-}
-.zmdi-wb-auto:before {
- content: '\f39b';
-}
-.zmdi-eject-alt:before {
- content: '\f39c';
-}
-.zmdi-eject:before {
- content: '\f39d';
-}
-.zmdi-equalizer:before {
- content: '\f39e';
-}
-.zmdi-fast-forward:before {
- content: '\f39f';
-}
-.zmdi-fast-rewind:before {
- content: '\f3a0';
-}
-.zmdi-forward-10:before {
- content: '\f3a1';
-}
-.zmdi-forward-30:before {
- content: '\f3a2';
-}
-.zmdi-forward-5:before {
- content: '\f3a3';
-}
-.zmdi-hearing:before {
- content: '\f3a4';
-}
-.zmdi-pause-circle-outline:before {
- content: '\f3a5';
-}
-.zmdi-pause-circle:before {
- content: '\f3a6';
-}
-.zmdi-pause:before {
- content: '\f3a7';
-}
-.zmdi-play-circle-outline:before {
- content: '\f3a8';
-}
-.zmdi-play-circle:before {
- content: '\f3a9';
-}
-.zmdi-play:before {
- content: '\f3aa';
-}
-.zmdi-playlist-audio:before {
- content: '\f3ab';
-}
-.zmdi-playlist-plus:before {
- content: '\f3ac';
-}
-.zmdi-repeat-one:before {
- content: '\f3ad';
-}
-.zmdi-repeat:before {
- content: '\f3ae';
-}
-.zmdi-replay-10:before {
- content: '\f3af';
-}
-.zmdi-replay-30:before {
- content: '\f3b0';
-}
-.zmdi-replay-5:before {
- content: '\f3b1';
-}
-.zmdi-replay:before {
- content: '\f3b2';
-}
-.zmdi-shuffle:before {
- content: '\f3b3';
-}
-.zmdi-skip-next:before {
- content: '\f3b4';
-}
-.zmdi-skip-previous:before {
- content: '\f3b5';
-}
-.zmdi-stop:before {
- content: '\f3b6';
-}
-.zmdi-surround-sound:before {
- content: '\f3b7';
-}
-.zmdi-tune:before {
- content: '\f3b8';
-}
-.zmdi-volume-down:before {
- content: '\f3b9';
-}
-.zmdi-volume-mute:before {
- content: '\f3ba';
-}
-.zmdi-volume-off:before {
- content: '\f3bb';
-}
-.zmdi-volume-up:before {
- content: '\f3bc';
-}
-.zmdi-n-1-square:before {
- content: '\f3bd';
-}
-.zmdi-n-2-square:before {
- content: '\f3be';
-}
-.zmdi-n-3-square:before {
- content: '\f3bf';
-}
-.zmdi-n-4-square:before {
- content: '\f3c0';
-}
-.zmdi-n-5-square:before {
- content: '\f3c1';
-}
-.zmdi-n-6-square:before {
- content: '\f3c2';
-}
-.zmdi-neg-1:before {
- content: '\f3c3';
-}
-.zmdi-neg-2:before {
- content: '\f3c4';
-}
-.zmdi-plus-1:before {
- content: '\f3c5';
-}
-.zmdi-plus-2:before {
- content: '\f3c6';
-}
-.zmdi-sec-10:before {
- content: '\f3c7';
-}
-.zmdi-sec-3:before {
- content: '\f3c8';
-}
-.zmdi-zero:before {
- content: '\f3c9';
-}
-.zmdi-airline-seat-flat-angled:before {
- content: '\f3ca';
-}
-.zmdi-airline-seat-flat:before {
- content: '\f3cb';
-}
-.zmdi-airline-seat-individual-suite:before {
- content: '\f3cc';
-}
-.zmdi-airline-seat-legroom-extra:before {
- content: '\f3cd';
-}
-.zmdi-airline-seat-legroom-normal:before {
- content: '\f3ce';
-}
-.zmdi-airline-seat-legroom-reduced:before {
- content: '\f3cf';
-}
-.zmdi-airline-seat-recline-extra:before {
- content: '\f3d0';
-}
-.zmdi-airline-seat-recline-normal:before {
- content: '\f3d1';
-}
-.zmdi-airplay:before {
- content: '\f3d2';
-}
-.zmdi-closed-caption:before {
- content: '\f3d3';
-}
-.zmdi-confirmation-number:before {
- content: '\f3d4';
-}
-.zmdi-developer-board:before {
- content: '\f3d5';
-}
-.zmdi-disc-full:before {
- content: '\f3d6';
-}
-.zmdi-explicit:before {
- content: '\f3d7';
-}
-.zmdi-flight-land:before {
- content: '\f3d8';
-}
-.zmdi-flight-takeoff:before {
- content: '\f3d9';
-}
-.zmdi-flip-to-back:before {
- content: '\f3da';
-}
-.zmdi-flip-to-front:before {
- content: '\f3db';
-}
-.zmdi-group-work:before {
- content: '\f3dc';
-}
-.zmdi-hd:before {
- content: '\f3dd';
-}
-.zmdi-hq:before {
- content: '\f3de';
-}
-.zmdi-markunread-mailbox:before {
- content: '\f3df';
-}
-.zmdi-memory:before {
- content: '\f3e0';
-}
-.zmdi-nfc:before {
- content: '\f3e1';
-}
-.zmdi-play-for-work:before {
- content: '\f3e2';
-}
-.zmdi-power-input:before {
- content: '\f3e3';
-}
-.zmdi-present-to-all:before {
- content: '\f3e4';
-}
-.zmdi-satellite:before {
- content: '\f3e5';
-}
-.zmdi-tap-and-play:before {
- content: '\f3e6';
-}
-.zmdi-vibration:before {
- content: '\f3e7';
-}
-.zmdi-voicemail:before {
- content: '\f3e8';
-}
-.zmdi-group:before {
- content: '\f3e9';
-}
-.zmdi-rss:before {
- content: '\f3ea';
-}
-.zmdi-shape:before {
- content: '\f3eb';
-}
-.zmdi-spinner:before {
- content: '\f3ec';
-}
-.zmdi-ungroup:before {
- content: '\f3ed';
-}
-.zmdi-500px:before {
- content: '\f3ee';
-}
-.zmdi-8tracks:before {
- content: '\f3ef';
-}
-.zmdi-amazon:before {
- content: '\f3f0';
-}
-.zmdi-blogger:before {
- content: '\f3f1';
-}
-.zmdi-delicious:before {
- content: '\f3f2';
-}
-.zmdi-disqus:before {
- content: '\f3f3';
-}
-.zmdi-flattr:before {
- content: '\f3f4';
-}
-.zmdi-flickr:before {
- content: '\f3f5';
-}
-.zmdi-github-alt:before {
- content: '\f3f6';
-}
-.zmdi-google-old:before {
- content: '\f3f7';
-}
-.zmdi-linkedin:before {
- content: '\f3f8';
-}
-.zmdi-odnoklassniki:before {
- content: '\f3f9';
-}
-.zmdi-outlook:before {
- content: '\f3fa';
-}
-.zmdi-paypal-alt:before {
- content: '\f3fb';
-}
-.zmdi-pinterest:before {
- content: '\f3fc';
-}
-.zmdi-playstation:before {
- content: '\f3fd';
-}
-.zmdi-reddit:before {
- content: '\f3fe';
-}
-.zmdi-skype:before {
- content: '\f3ff';
-}
-.zmdi-slideshare:before {
- content: '\f400';
-}
-.zmdi-soundcloud:before {
- content: '\f401';
-}
-.zmdi-tumblr:before {
- content: '\f402';
-}
-.zmdi-twitch:before {
- content: '\f403';
-}
-.zmdi-vimeo:before {
- content: '\f404';
-}
-.zmdi-whatsapp:before {
- content: '\f405';
-}
-.zmdi-xbox:before {
- content: '\f406';
-}
-.zmdi-yahoo:before {
- content: '\f407';
-}
-.zmdi-youtube-play:before {
- content: '\f408';
-}
-.zmdi-youtube:before {
- content: '\f409';
-}
-.zmdi-import-export:before {
- content: '\f30c';
-}
-.zmdi-swap-vertical-:before {
- content: '\f30c';
-}
-.zmdi-airplanemode-inactive:before {
- content: '\f102';
-}
-.zmdi-airplanemode-active:before {
- content: '\f103';
-}
-.zmdi-rate-review:before {
- content: '\f103';
-}
-.zmdi-comment-sign:before {
- content: '\f25a';
-}
-.zmdi-network-warning:before {
- content: '\f2ad';
-}
-.zmdi-shopping-cart-add:before {
- content: '\f1ca';
-}
-.zmdi-file-add:before {
- content: '\f221';
-}
-.zmdi-network-wifi-scan:before {
- content: '\f2e4';
-}
-.zmdi-collection-add:before {
- content: '\f14e';
-}
-.zmdi-format-playlist-add:before {
- content: '\f3ac';
-}
-.zmdi-format-queue-music:before {
- content: '\f3ab';
-}
-.zmdi-plus-box:before {
- content: '\f277';
-}
-.zmdi-tag-backspace:before {
- content: '\f1d9';
-}
-.zmdi-alarm-add:before {
- content: '\f32b';
-}
-.zmdi-battery-charging:before {
- content: '\f114';
-}
-.zmdi-daydream-setting:before {
- content: '\f217';
-}
-.zmdi-more-horiz:before {
- content: '\f19c';
-}
-.zmdi-book-photo:before {
- content: '\f11b';
-}
-.zmdi-incandescent:before {
- content: '\f189';
-}
-.zmdi-wb-iridescent:before {
- content: '\f38c';
-}
-.zmdi-calendar-remove:before {
- content: '\f330';
-}
-.zmdi-refresh-sync-disabled:before {
- content: '\f1b7';
-}
-.zmdi-refresh-sync-problem:before {
- content: '\f1b6';
-}
-.zmdi-crop-original:before {
- content: '\f17e';
-}
-.zmdi-power-off:before {
- content: '\f1af';
-}
-.zmdi-power-off-setting:before {
- content: '\f1ae';
-}
-.zmdi-leak-remove:before {
- content: '\f38d';
-}
-.zmdi-star-border:before {
- content: '\f27c';
-}
-.zmdi-brightness-low:before {
- content: '\f36d';
-}
-.zmdi-brightness-medium:before {
- content: '\f36e';
-}
-.zmdi-brightness-high:before {
- content: '\f36f';
-}
-.zmdi-smartphone-portrait:before {
- content: '\f2d4';
-}
-.zmdi-live-tv:before {
- content: '\f2d9';
-}
-.zmdi-format-textdirection-l-to-r:before {
- content: '\f249';
-}
-.zmdi-format-textdirection-r-to-l:before {
- content: '\f24a';
-}
-.zmdi-arrow-back:before {
- content: '\f2ea';
-}
-.zmdi-arrow-forward:before {
- content: '\f2ee';
-}
-.zmdi-arrow-in:before {
- content: '\f2e9';
-}
-.zmdi-arrow-out:before {
- content: '\f2ed';
-}
-.zmdi-rotate-90-degrees-ccw:before {
- content: '\f304';
-}
-.zmdi-adb:before {
- content: '\f33a';
-}
-.zmdi-network-wifi:before {
- content: '\f2e8';
-}
-.zmdi-network-wifi-alt:before {
- content: '\f2e3';
-}
-.zmdi-network-wifi-lock:before {
- content: '\f2e5';
-}
-.zmdi-network-wifi-off:before {
- content: '\f2e6';
-}
-.zmdi-network-wifi-outline:before {
- content: '\f2e7';
-}
-.zmdi-network-wifi-info:before {
- content: '\f2e4';
-}
-.zmdi-layers-clear:before {
- content: '\f18b';
-}
-.zmdi-colorize:before {
- content: '\f15d';
-}
-.zmdi-format-paint:before {
- content: '\f1ba';
-}
-.zmdi-format-quote:before {
- content: '\f1b2';
-}
-.zmdi-camera-monochrome-photos:before {
- content: '\f285';
-}
-.zmdi-sort-by-alpha:before {
- content: '\f1cf';
-}
-.zmdi-folder-shared:before {
- content: '\f225';
-}
-.zmdi-folder-special:before {
- content: '\f226';
-}
-.zmdi-comment-dots:before {
- content: '\f260';
-}
-.zmdi-reorder:before {
- content: '\f31e';
-}
-.zmdi-dehaze:before {
- content: '\f197';
-}
-.zmdi-sort:before {
- content: '\f1ce';
-}
-.zmdi-pages:before {
- content: '\f34a';
-}
-.zmdi-stack-overflow:before {
- content: '\f35c';
-}
-.zmdi-calendar-account:before {
- content: '\f204';
-}
-.zmdi-paste:before {
- content: '\f109';
-}
-.zmdi-cut:before {
- content: '\f1bc';
-}
-.zmdi-save:before {
- content: '\f297';
-}
-.zmdi-smartphone-code:before {
- content: '\f139';
-}
-.zmdi-directions-bike:before {
- content: '\f117';
-}
-.zmdi-directions-boat:before {
- content: '\f11a';
-}
-.zmdi-directions-bus:before {
- content: '\f121';
-}
-.zmdi-directions-car:before {
- content: '\f125';
-}
-.zmdi-directions-railway:before {
- content: '\f1b3';
-}
-.zmdi-directions-run:before {
- content: '\f215';
-}
-.zmdi-directions-subway:before {
- content: '\f1d5';
-}
-.zmdi-directions-walk:before {
- content: '\f216';
-}
-.zmdi-local-hotel:before {
- content: '\f178';
-}
-.zmdi-local-activity:before {
- content: '\f1df';
-}
-.zmdi-local-play:before {
- content: '\f1df';
-}
-.zmdi-local-airport:before {
- content: '\f103';
-}
-.zmdi-local-atm:before {
- content: '\f198';
-}
-.zmdi-local-bar:before {
- content: '\f137';
-}
-.zmdi-local-cafe:before {
- content: '\f13b';
-}
-.zmdi-local-car-wash:before {
- content: '\f124';
-}
-.zmdi-local-convenience-store:before {
- content: '\f1d3';
-}
-.zmdi-local-dining:before {
- content: '\f153';
-}
-.zmdi-local-drink:before {
- content: '\f157';
-}
-.zmdi-local-florist:before {
- content: '\f168';
-}
-.zmdi-local-gas-station:before {
- content: '\f16f';
-}
-.zmdi-local-grocery-store:before {
- content: '\f1cb';
-}
-.zmdi-local-hospital:before {
- content: '\f177';
-}
-.zmdi-local-laundry-service:before {
- content: '\f1e9';
-}
-.zmdi-local-library:before {
- content: '\f18d';
-}
-.zmdi-local-mall:before {
- content: '\f195';
-}
-.zmdi-local-movies:before {
- content: '\f19d';
-}
-.zmdi-local-offer:before {
- content: '\f187';
-}
-.zmdi-local-parking:before {
- content: '\f1a5';
-}
-.zmdi-local-parking:before {
- content: '\f1a5';
-}
-.zmdi-local-pharmacy:before {
- content: '\f176';
-}
-.zmdi-local-phone:before {
- content: '\f2be';
-}
-.zmdi-local-pizza:before {
- content: '\f1ac';
-}
-.zmdi-local-post-office:before {
- content: '\f15a';
-}
-.zmdi-local-printshop:before {
- content: '\f1b0';
-}
-.zmdi-local-see:before {
- content: '\f28c';
-}
-.zmdi-local-shipping:before {
- content: '\f1e6';
-}
-.zmdi-local-store:before {
- content: '\f1d4';
-}
-.zmdi-local-taxi:before {
- content: '\f123';
-}
-.zmdi-local-wc:before {
- content: '\f211';
-}
-.zmdi-my-location:before {
- content: '\f299';
-}
-.zmdi-directions:before {
- content: '\f1e7';
-}
diff --git a/packages/website/public/css/roboto.css b/packages/website/public/css/roboto.css index 7af568a74..4c4a126b0 100644 --- a/packages/website/public/css/roboto.css +++ b/packages/website/public/css/roboto.css @@ -1,8 +1,14 @@ +/* +NOTE: This file includes several font faces that are commented out. They are +not currently used by this app but could be at a future point. For this reason, +we leave them commented out rather then removing them completely. +*/ + @font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Thin.ttf') format('truetype'); - font-weight: 100; - font-style: normal; + font-family: 'Roboto'; + src: url('../fonts/Roboto-Thin.ttf') format('truetype'); + font-weight: 100; + font-style: normal; } /*@font-face { @@ -13,10 +19,10 @@ }*/ @font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Light.ttf') format('truetype'); - font-weight: 300; - font-style: normal; + font-family: 'Roboto'; + src: url('../fonts/Roboto-Light.ttf') format('truetype'); + font-weight: 300; + font-style: normal; } /*@font-face { @@ -27,10 +33,10 @@ }*/ @font-face { - font-family: 'Roboto'; - src: url('../fonts/Roboto-Regular.ttf') format('truetype'); - font-weight: 400; - font-style: normal; + font-family: 'Roboto'; + src: url('../fonts/Roboto-Regular.ttf') format('truetype'); + font-weight: 400; + font-style: normal; } /*@font-face { diff --git a/packages/website/ts/blockchain.ts b/packages/website/ts/blockchain.ts index 156dc44e8..fca9504d7 100644 --- a/packages/website/ts/blockchain.ts +++ b/packages/website/ts/blockchain.ts @@ -15,6 +15,7 @@ import { TransactionReceiptWithDecodedLogs, ZeroEx, } from '0x.js'; +import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import { InjectedWeb3Subprovider, ledgerEthereumBrowserClientFactoryAsync, @@ -35,7 +36,6 @@ import { BlockchainCallErrs, BlockchainErrs, ContractInstance, - EtherscanLinkSuffixes, Order as PortalOrder, ProviderType, Side, @@ -271,7 +271,11 @@ export class Blockchain { }, ); await this._showEtherScanLinkAndAwaitTransactionMinedAsync(txHash); - const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx); + const etherScanLinkIfExists = sharedUtils.getEtherScanLinkIfExists( + txHash, + this.networkId, + EtherscanLinkSuffixes.Tx, + ); this._dispatcher.showFlashMessage( React.createElement(TokenSendCompleted, { etherScanLinkIfExists, @@ -542,7 +546,11 @@ export class Blockchain { private async _showEtherScanLinkAndAwaitTransactionMinedAsync( txHash: string, ): Promise<TransactionReceiptWithDecodedLogs> { - const etherScanLinkIfExists = utils.getEtherScanLinkIfExists(txHash, this.networkId, EtherscanLinkSuffixes.Tx); + const etherScanLinkIfExists = sharedUtils.getEtherScanLinkIfExists( + txHash, + this.networkId, + EtherscanLinkSuffixes.Tx, + ); this._dispatcher.showFlashMessage( React.createElement(TransactionSubmitted, { etherScanLinkIfExists, diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx index 278e2bbf5..e71a0f7d1 100644 --- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx +++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx @@ -1,10 +1,10 @@ +import { colors, Networks } from '@0xproject/react-shared'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; -import { BlockchainErrs, Networks } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { BlockchainErrs } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx index acd4a7110..5c61f0d57 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; @@ -6,7 +7,6 @@ import { Blockchain } from 'ts/blockchain'; import { EthAmountInput } from 'ts/components/inputs/eth_amount_input'; import { TokenAmountInput } from 'ts/components/inputs/token_amount_input'; import { Side, Token } from 'ts/types'; -import { colors } from 'ts/utils/colors'; interface EthWethConversionDialogProps { blockchain: Blockchain; diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx index bc5f05241..8a242cd33 100644 --- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx +++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx @@ -1,3 +1,4 @@ +import { colors, constants as sharedConstants } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; @@ -11,7 +12,6 @@ import { NetworkDropDown } from 'ts/components/dropdowns/network_drop_down'; import { LifeCycleRaisedButton } from 'ts/components/ui/lifecycle_raised_button'; import { Dispatcher } from 'ts/redux/dispatcher'; import { ProviderType } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; @@ -82,7 +82,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, ); } private _renderConnectStep() { - const networkIds = _.values(constants.NETWORK_ID_BY_NAME); + const networkIds = _.values(sharedConstants.NETWORK_ID_BY_NAME); return ( <div> <div className="h4 pt3">Follow these instructions before proceeding:</div> @@ -163,7 +163,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, const balance = this.state.addressBalances[i]; const addressTooltipId = `address-${userAddress}`; const balanceTooltipId = `balance-${userAddress}`; - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; // We specifically prefix kovan ETH. // TODO: We should probably add prefixes for all networks const isKovanNetwork = networkName === 'Kovan'; diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx index 3ecc454a0..b31667121 100644 --- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx +++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; interface PortalDisclaimerDialogProps { isOpen: boolean; diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx index 098e3e26d..6ac9cf917 100644 --- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx +++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; interface U2fNotSupportedDialogProps { diff --git a/packages/website/ts/components/dropdowns/network_drop_down.tsx b/packages/website/ts/components/dropdowns/network_drop_down.tsx index 28ec28ed5..b569807dd 100644 --- a/packages/website/ts/components/dropdowns/network_drop_down.tsx +++ b/packages/website/ts/components/dropdowns/network_drop_down.tsx @@ -1,8 +1,8 @@ +import { constants as sharedConstants } from '@0xproject/react-shared'; import * as _ from 'lodash'; import DropDownMenu from 'material-ui/DropDownMenu'; import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; -import { constants } from 'ts/utils/constants'; interface NetworkDropDownProps { updateSelectedNetwork: (e: any, index: number, value: number) => void; @@ -24,7 +24,7 @@ export class NetworkDropDown extends React.Component<NetworkDropDownProps, Netwo } private _renderDropDownItems() { const items = _.map(this.props.avialableNetworkIds, networkId => { - const networkName = constants.NETWORK_NAME_BY_ID[networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[networkId]; const primaryText = ( <div className="flex"> <div className="pr1" style={{ width: 14, paddingTop: 2 }}> diff --git a/packages/website/ts/components/eth_wrappers.tsx b/packages/website/ts/components/eth_wrappers.tsx index c2cdf6751..7ac5d5c9c 100644 --- a/packages/website/ts/components/eth_wrappers.tsx +++ b/packages/website/ts/components/eth_wrappers.tsx @@ -1,4 +1,5 @@ import { ZeroEx } from '0x.js'; +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import Divider from 'material-ui/Divider'; @@ -9,15 +10,7 @@ import ReactTooltip = require('react-tooltip'); import { Blockchain } from 'ts/blockchain'; import { EthWethConversionButton } from 'ts/components/eth_weth_conversion_button'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { - EtherscanLinkSuffixes, - OutdatedWrappedEtherByNetworkId, - Side, - Token, - TokenByAddress, - TokenState, -} from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { OutdatedWrappedEtherByNetworkId, Side, Token, TokenByAddress, TokenState } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; @@ -99,7 +92,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt const etherToken = this._getEthToken(); const wethBalance = ZeroEx.toUnitAmount(this.state.ethTokenState.balance, constants.DECIMAL_PLACES_ETH); const isBidirectional = true; - const etherscanUrl = utils.getEtherScanLinkIfExists( + const etherscanUrl = sharedUtils.getEtherScanLinkIfExists( etherToken.address, this.props.networkId, EtherscanLinkSuffixes.Address, @@ -281,7 +274,7 @@ export class EthWrappers extends React.Component<EthWrappersProps, EthWrappersSt this, outdatedWETHIfExists.address, ); - const etherscanUrl = utils.getEtherScanLinkIfExists( + const etherscanUrl = sharedUtils.getEtherScanLinkIfExists( outdatedWETHIfExists.address, this.props.networkId, EtherscanLinkSuffixes.Address, diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx index 51e44134c..e9127288d 100644 --- a/packages/website/ts/components/fill_order.tsx +++ b/packages/website/ts/components/fill_order.tsx @@ -1,4 +1,5 @@ import { Order as ZeroExOrder, ZeroEx } from '0x.js'; +import { colors, constants as sharedConstants } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as accounting from 'accounting'; import * as _ from 'lodash'; @@ -21,7 +22,6 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; import { validator } from 'ts/schemas/validator'; import { AlertTypes, BlockchainErrs, Order, Token, TokenByAddress, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; import { utils } from 'ts/utils/utils'; @@ -537,7 +537,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { }); return; } - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; const eventLabel = `${parsedOrder.metadata.takerToken.symbol}-${networkName}`; try { const orderFilledAmount: BigNumber = await this.props.blockchain.fillOrderAsync( @@ -623,7 +623,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { }); return; } - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; const eventLabel = `${parsedOrder.metadata.makerToken.symbol}-${networkName}`; try { await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount); diff --git a/packages/website/ts/components/fill_warning_dialog.tsx b/packages/website/ts/components/fill_warning_dialog.tsx index 165d21b34..d3215a6c1 100644 --- a/packages/website/ts/components/fill_warning_dialog.tsx +++ b/packages/website/ts/components/fill_warning_dialog.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; interface FillWarningDialogProps { isOpen: boolean; diff --git a/packages/website/ts/components/flash_messages/token_send_completed.tsx b/packages/website/ts/components/flash_messages/token_send_completed.tsx index 18f371624..a3b056758 100644 --- a/packages/website/ts/components/flash_messages/token_send_completed.tsx +++ b/packages/website/ts/components/flash_messages/token_send_completed.tsx @@ -1,9 +1,9 @@ import { ZeroEx } from '0x.js'; +import { colors } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import * as React from 'react'; import { Token } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; interface TokenSendCompletedProps { diff --git a/packages/website/ts/components/flash_messages/transaction_submitted.tsx b/packages/website/ts/components/flash_messages/transaction_submitted.tsx index 862e382dd..188f1f9a6 100644 --- a/packages/website/ts/components/flash_messages/transaction_submitted.tsx +++ b/packages/website/ts/components/flash_messages/transaction_submitted.tsx @@ -1,6 +1,6 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; interface TransactionSubmittedProps { etherScanLinkIfExists?: string; diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx index 810460cac..957ed2044 100644 --- a/packages/website/ts/components/footer.tsx +++ b/packages/website/ts/components/footer.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import DropDownMenu from 'material-ui/DropDownMenu'; import MenuItem from 'material-ui/MenuItem'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { Link } from 'react-router-dom'; import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, Language, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx index a3f222784..26fa904fe 100644 --- a/packages/website/ts/components/generate_order/generate_order_form.tsx +++ b/packages/website/ts/components/generate_order/generate_order_form.tsx @@ -1,4 +1,5 @@ import { ECSignature, Order, ZeroEx } from '0x.js'; +import { colors, constants as sharedConstants } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; @@ -20,7 +21,6 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; import { validator } from 'ts/schemas/validator'; import { AlertTypes, BlockchainErrs, HashData, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; import { utils } from 'ts/utils/utils'; @@ -253,7 +253,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G ) { const didSignSuccessfully = await this._signTransactionAsync(); if (didSignSuccessfully) { - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; const eventLabel = `${this.props.tokenByAddress[debitToken.address].symbol}-${networkName}`; ReactGA.event({ category: 'Portal', diff --git a/packages/website/ts/components/generate_order/new_token_form.tsx b/packages/website/ts/components/generate_order/new_token_form.tsx index f76830a49..e7f3b93c6 100644 --- a/packages/website/ts/components/generate_order/new_token_form.tsx +++ b/packages/website/ts/components/generate_order/new_token_form.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as React from 'react'; @@ -7,7 +8,6 @@ import { Alert } from 'ts/components/ui/alert'; import { LifeCycleRaisedButton } from 'ts/components/ui/lifecycle_raised_button'; import { RequiredLabel } from 'ts/components/ui/required_label'; import { AlertTypes, Token, TokenByAddress } from 'ts/types'; -import { colors } from 'ts/utils/colors'; interface NewTokenFormProps { blockchain: Blockchain; diff --git a/packages/website/ts/components/inputs/address_input.tsx b/packages/website/ts/components/inputs/address_input.tsx index dd4131140..7ca4af968 100644 --- a/packages/website/ts/components/inputs/address_input.tsx +++ b/packages/website/ts/components/inputs/address_input.tsx @@ -1,9 +1,9 @@ +import { colors } from '@0xproject/react-shared'; import { addressUtils } from '@0xproject/utils'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as React from 'react'; import { RequiredLabel } from 'ts/components/ui/required_label'; -import { colors } from 'ts/utils/colors'; interface AddressInputProps { disabled?: boolean; diff --git a/packages/website/ts/components/inputs/allowance_toggle.tsx b/packages/website/ts/components/inputs/allowance_toggle.tsx index a2e75dfed..7fe303cf4 100644 --- a/packages/website/ts/components/inputs/allowance_toggle.tsx +++ b/packages/website/ts/components/inputs/allowance_toggle.tsx @@ -1,3 +1,4 @@ +import { constants as sharedConstants } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import Toggle from 'material-ui/Toggle'; @@ -76,7 +77,7 @@ export class AllowanceToggle extends React.Component<AllowanceToggleProps, Allow if (!this._isAllowanceSet()) { newAllowanceAmountInBaseUnits = DEFAULT_ALLOWANCE_AMOUNT_IN_BASE_UNITS; } - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; const eventLabel = `${this.props.token.symbol}-${networkName}`; try { await this.props.blockchain.setProxyAllowanceAsync(this.props.token, newAllowanceAmountInBaseUnits); diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx index 3bbc7a5f6..253b01871 100644 --- a/packages/website/ts/components/inputs/balance_bounded_input.tsx +++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; @@ -5,7 +6,6 @@ import * as React from 'react'; import { Link } from 'react-router-dom'; import { RequiredLabel } from 'ts/components/ui/required_label'; import { InputErrMsg, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; interface BalanceBoundedInputProps { diff --git a/packages/website/ts/components/inputs/hash_input.tsx b/packages/website/ts/components/inputs/hash_input.tsx index 5a3d34fe6..28305637d 100644 --- a/packages/website/ts/components/inputs/hash_input.tsx +++ b/packages/website/ts/components/inputs/hash_input.tsx @@ -1,10 +1,11 @@ import { Order, ZeroEx } from '0x.js'; +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); import { Blockchain } from 'ts/blockchain'; import { FakeTextField } from 'ts/components/ui/fake_text_field'; -import { HashData, Styles } from 'ts/types'; +import { HashData } from 'ts/types'; import { constants } from 'ts/utils/constants'; const styles: Styles = { diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx index 2b167d875..53248c065 100644 --- a/packages/website/ts/components/inputs/token_amount_input.tsx +++ b/packages/website/ts/components/inputs/token_amount_input.tsx @@ -1,4 +1,5 @@ import { ZeroEx } from '0x.js'; +import { colors } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import * as React from 'react'; @@ -6,7 +7,6 @@ import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { BalanceBoundedInput } from 'ts/components/inputs/balance_bounded_input'; import { InputErrMsg, Token, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; interface TokenAmountInputProps { userAddress: string; diff --git a/packages/website/ts/components/inputs/token_input.tsx b/packages/website/ts/components/inputs/token_input.tsx index 5df19b28c..545e9a095 100644 --- a/packages/website/ts/components/inputs/token_input.tsx +++ b/packages/website/ts/components/inputs/token_input.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import Paper from 'material-ui/Paper'; import * as React from 'react'; @@ -7,7 +8,6 @@ import { InputLabel } from 'ts/components/ui/input_label'; import { TokenIcon } from 'ts/components/ui/token_icon'; import { Dispatcher } from 'ts/redux/dispatcher'; import { AssetToken, BlockchainErrs, Side, Token, TokenByAddress } from 'ts/types'; -import { colors } from 'ts/utils/colors'; const TOKEN_ICON_DIMENSION = 80; diff --git a/packages/website/ts/components/portal.tsx b/packages/website/ts/components/portal.tsx index 4871997ac..d71e821c6 100644 --- a/packages/website/ts/components/portal.tsx +++ b/packages/website/ts/components/portal.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; @@ -24,7 +25,6 @@ import { Dispatcher } from 'ts/redux/dispatcher'; import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; import { validator } from 'ts/schemas/validator'; import { BlockchainErrs, HashData, Order, ProviderType, ScreenWidths, TokenByAddress, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; diff --git a/packages/website/ts/components/sidebar_header.tsx b/packages/website/ts/components/sidebar_header.tsx new file mode 100644 index 000000000..519b23d80 --- /dev/null +++ b/packages/website/ts/components/sidebar_header.tsx @@ -0,0 +1,44 @@ +import { colors } from '@0xproject/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; + +const SHOW_DURATION_MS = 4000; + +const titleToIcon: { [title: string]: string } = { + '0x.js': 'zeroExJs.png', + '0x Connect': 'connect.png', + '0x Smart Contracts': 'contracts.png', + Wiki: 'wiki.png', +}; + +interface SidebarHeaderProps { + title: string; +} + +interface SidebarHeaderState {} + +export class SidebarHeader extends React.Component<SidebarHeaderProps, SidebarHeaderState> { + public render() { + return ( + <div className="pt2 md-px1 sm-px2" style={{ color: colors.black, paddingBottom: 18 }}> + <div className="flex" style={{ fontSize: 25 }}> + <div style={{ fontWeight: 'bold', fontFamily: 'Roboto Mono' }}>0x</div> + <div className="pl2" style={{ lineHeight: 1.4, fontWeight: 300 }}> + docs + </div> + </div> + <div className="pl1" style={{ color: colors.grey350, paddingBottom: 9, paddingLeft: 10, height: 17 }}> + | + </div> + <div className="flex"> + <div> + <img src={`/images/doc_icons/${titleToIcon[this.props.title]}`} width="22" /> + </div> + <div className="pl1" style={{ fontWeight: 600, fontSize: 20, lineHeight: 1.2 }}> + {this.props.title} + </div> + </div> + </div> + ); + } +} diff --git a/packages/website/ts/components/token_balances.tsx b/packages/website/ts/components/token_balances.tsx index 894edf0a8..7e7596fd7 100644 --- a/packages/website/ts/components/token_balances.tsx +++ b/packages/website/ts/components/token_balances.tsx @@ -1,4 +1,12 @@ import { ZeroEx } from '0x.js'; +import { + colors, + constants as sharedConstants, + EtherscanLinkSuffixes, + Networks, + Styles, + utils as sharedUtils, +} from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import DharmaLoanFrame from 'dharma-loan-frame'; import * as _ from 'lodash'; @@ -26,15 +34,11 @@ import { BalanceErrs, BlockchainCallErrs, BlockchainErrs, - EtherscanLinkSuffixes, - Networks, ScreenWidths, - Styles, Token, TokenByAddress, TokenVisibility, } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; @@ -118,7 +122,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala if (nextProps.userEtherBalance !== this.props.userEtherBalance) { if (this.state.isBalanceSpinnerVisible) { const receivedAmount = nextProps.userEtherBalance.minus(this.props.userEtherBalance); - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; this.props.dispatcher.showFlashMessage(`Received ${receivedAmount.toString(10)} ${networkName} Ether`); } this.setState({ @@ -358,17 +362,20 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala } private _renderTokenRow(tokenColSpan: number, actionPaddingX: number, token: Token) { const tokenState = this.state.trackedTokenStateByAddress[token.address]; - const tokenLink = utils.getEtherScanLinkIfExists( + const tokenLink = sharedUtils.getEtherScanLinkIfExists( token.address, this.props.networkId, EtherscanLinkSuffixes.Address, ); const isMintable = (_.includes(configs.SYMBOLS_OF_MINTABLE_KOVAN_TOKENS, token.symbol) && - this.props.networkId === constants.NETWORK_ID_BY_NAME[Networks.Kovan]) || + this.props.networkId === sharedConstants.NETWORK_ID_BY_NAME[Networks.Kovan]) || (_.includes(configs.SYMBOLS_OF_MINTABLE_RINKEBY_ROPSTEN_TOKENS, token.symbol) && _.includes( - [constants.NETWORK_ID_BY_NAME[Networks.Rinkeby], constants.NETWORK_ID_BY_NAME[Networks.Ropsten]], + [ + sharedConstants.NETWORK_ID_BY_NAME[Networks.Rinkeby], + sharedConstants.NETWORK_ID_BY_NAME[Networks.Ropsten], + ], this.props.networkId, )); return ( @@ -540,7 +547,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala } } private _renderDharmaLoanFrame() { - if (utils.isUserOnMobile()) { + if (sharedUtils.isUserOnMobile()) { return ( <h4 style={{ textAlign: 'center' }}> We apologize -- Dharma loan requests are not available on mobile yet. Please try again through your diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 39e7f2a8c..89c506d0e 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; @@ -7,7 +8,6 @@ import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; import { Dispatcher } from 'ts/redux/dispatcher'; import { ProviderType } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/components/top_bar/provider_picker.tsx b/packages/website/ts/components/top_bar/provider_picker.tsx index be7e57d6f..b986da873 100644 --- a/packages/website/ts/components/top_bar/provider_picker.tsx +++ b/packages/website/ts/components/top_bar/provider_picker.tsx @@ -1,10 +1,10 @@ +import { colors, constants as sharedConstants } from '@0xproject/react-shared'; import * as _ from 'lodash'; import { RadioButton, RadioButtonGroup } from 'material-ui/RadioButton'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; import { Dispatcher } from 'ts/redux/dispatcher'; import { ProviderType } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; interface ProviderPickerProps { @@ -56,7 +56,7 @@ export class ProviderPicker extends React.Component<ProviderPickerProps, Provide return label; } private _renderNetwork() { - const networkName = constants.NETWORK_NAME_BY_ID[this.props.networkId]; + const networkName = sharedConstants.NETWORK_NAME_BY_ID[this.props.networkId]; return ( <div className="flex" style={{ marginTop: 1 }}> <div className="relative" style={{ width: 14, paddingLeft: 14 }}> diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index b2b2d2ebd..29c68524c 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -1,3 +1,5 @@ +import { DocsInfo, DocsMenu } from '@0xproject/react-docs'; +import { colors, MenuSubsectionsBySection, NestedSidebarMenu, Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import Drawer from 'material-ui/Drawer'; import Menu from 'material-ui/Menu'; @@ -7,15 +9,13 @@ import { Link } from 'react-router-dom'; import ReactTooltip = require('react-tooltip'); import { Blockchain } from 'ts/blockchain'; import { PortalMenu } from 'ts/components/portal_menu'; +import { SidebarHeader } from 'ts/components/sidebar_header'; import { ProviderDisplay } from 'ts/components/top_bar/provider_display'; import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item'; import { DropDown } from 'ts/components/ui/drop_down'; import { Identicon } from 'ts/components/ui/identicon'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { Deco, DocsMenu, Key, MenuSubsectionsBySection, ProviderType, Styles, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { Deco, Key, ProviderType, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; @@ -38,6 +38,7 @@ interface TopBarProps { docsInfo?: DocsInfo; style?: React.CSSProperties; isNightVersion?: boolean; + onVersionSelected?: (semver: string) => void; } interface TopBarState { @@ -315,11 +316,12 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <NestedSidebarMenu topLevelMenu={this.props.menu} menuSubsectionsBySection={this.props.menuSubsectionsBySection} - title={this.props.docsInfo.displayName} + sidebarHeader={<SidebarHeader title={this.props.docsInfo.displayName} />} shouldDisplaySectionHeaders={false} onMenuItemClick={this._onMenuButtonClick.bind(this)} selectedVersion={this.props.docsVersion} versions={this.props.availableDocVersions} + onVersionSelected={this.props.onVersionSelected} /> </div> ); @@ -334,7 +336,7 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { <NestedSidebarMenu topLevelMenu={this.props.menuSubsectionsBySection} menuSubsectionsBySection={this.props.menuSubsectionsBySection} - title={this.props.translate.get(Key.Wiki, Deco.Cap)} + sidebarHeader={<SidebarHeader title="Wiki" />} shouldDisplaySectionHeaders={false} onMenuItemClick={this._onMenuButtonClick.bind(this)} /> diff --git a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx index e70381456..c0e674b17 100644 --- a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx +++ b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { Link } from 'react-router-dom'; -import { colors } from 'ts/utils/colors'; const DEFAULT_STYLE = { color: colors.darkestGrey, diff --git a/packages/website/ts/components/track_token_confirmation.tsx b/packages/website/ts/components/track_token_confirmation.tsx index 76971aefa..8c5ba7e6f 100644 --- a/packages/website/ts/components/track_token_confirmation.tsx +++ b/packages/website/ts/components/track_token_confirmation.tsx @@ -1,8 +1,8 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { Party } from 'ts/components/ui/party'; import { Token, TokenByAddress } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; interface TrackTokenConfirmationProps { diff --git a/packages/website/ts/components/trade_history/trade_history_item.tsx b/packages/website/ts/components/trade_history/trade_history_item.tsx index 7e42e64e6..6b8d7c7b5 100644 --- a/packages/website/ts/components/trade_history/trade_history_item.tsx +++ b/packages/website/ts/components/trade_history/trade_history_item.tsx @@ -1,4 +1,5 @@ import { ZeroEx } from '0x.js'; +import { colors, EtherscanLinkSuffixes } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import * as _ from 'lodash'; import Paper from 'material-ui/Paper'; @@ -7,8 +8,7 @@ import * as React from 'react'; import * as ReactTooltip from 'react-tooltip'; import { EtherScanIcon } from 'ts/components/ui/etherscan_icon'; import { Party } from 'ts/components/ui/party'; -import { EtherscanLinkSuffixes, Fill, Token, TokenByAddress } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { Fill, Token, TokenByAddress } from 'ts/types'; const PRECISION = 5; const IDENTICON_DIAMETER = 40; diff --git a/packages/website/ts/components/ui/alert.tsx b/packages/website/ts/components/ui/alert.tsx index 54881b499..f81939255 100644 --- a/packages/website/ts/components/ui/alert.tsx +++ b/packages/website/ts/components/ui/alert.tsx @@ -1,6 +1,6 @@ +import { colors } from '@0xproject/react-shared'; import * as React from 'react'; import { AlertTypes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; interface AlertProps { type: AlertTypes; diff --git a/packages/website/ts/components/ui/badge.tsx b/packages/website/ts/components/ui/badge.tsx deleted file mode 100644 index 056d741e0..000000000 --- a/packages/website/ts/components/ui/badge.tsx +++ /dev/null @@ -1,56 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { Styles } from 'ts/types'; - -const styles: Styles = { - badge: { - width: 50, - fontSize: 11, - height: 10, - borderRadius: 5, - lineHeight: 0.9, - fontFamily: 'Roboto Mono', - marginLeft: 3, - marginRight: 3, - }, -}; - -interface BadgeProps { - title: string; - backgroundColor: string; -} - -interface BadgeState { - isHovering: boolean; -} - -export class Badge extends React.Component<BadgeProps, BadgeState> { - constructor(props: BadgeProps) { - super(props); - this.state = { - isHovering: false, - }; - } - public render() { - const badgeStyle = { - ...styles.badge, - backgroundColor: this.props.backgroundColor, - opacity: this.state.isHovering ? 0.7 : 1, - }; - return ( - <div - className="p1 center" - style={badgeStyle} - onMouseOver={this._setHoverState.bind(this, true)} - onMouseOut={this._setHoverState.bind(this, false)} - > - {this.props.title} - </div> - ); - } - private _setHoverState(isHovering: boolean) { - this.setState({ - isHovering, - }); - } -} diff --git a/packages/website/ts/components/ui/copy_icon.tsx b/packages/website/ts/components/ui/copy_icon.tsx index df55e0922..d58e50815 100644 --- a/packages/website/ts/components/ui/copy_icon.tsx +++ b/packages/website/ts/components/ui/copy_icon.tsx @@ -1,9 +1,9 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import * as CopyToClipboard from 'react-copy-to-clipboard'; import * as ReactDOM from 'react-dom'; import ReactTooltip = require('react-tooltip'); -import { colors } from 'ts/utils/colors'; interface CopyIconProps { data: string; diff --git a/packages/website/ts/components/ui/ethereum_address.tsx b/packages/website/ts/components/ui/ethereum_address.tsx index b75d97e39..f449a8e75 100644 --- a/packages/website/ts/components/ui/ethereum_address.tsx +++ b/packages/website/ts/components/ui/ethereum_address.tsx @@ -1,7 +1,7 @@ +import { EtherscanLinkSuffixes } from '@0xproject/react-shared'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); import { EtherScanIcon } from 'ts/components/ui/etherscan_icon'; -import { EtherscanLinkSuffixes } from 'ts/types'; import { utils } from 'ts/utils/utils'; interface EthereumAddressProps { diff --git a/packages/website/ts/components/ui/etherscan_icon.tsx b/packages/website/ts/components/ui/etherscan_icon.tsx index 3b17bd0fa..040b84a0b 100644 --- a/packages/website/ts/components/ui/etherscan_icon.tsx +++ b/packages/website/ts/components/ui/etherscan_icon.tsx @@ -1,8 +1,7 @@ +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); -import { EtherscanLinkSuffixes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; interface EtherScanIconProps { @@ -12,7 +11,7 @@ interface EtherScanIconProps { } export const EtherScanIcon = (props: EtherScanIconProps) => { - const etherscanLinkIfExists = utils.getEtherScanLinkIfExists( + const etherscanLinkIfExists = sharedUtils.getEtherScanLinkIfExists( props.addressOrTxHash, props.networkId, EtherscanLinkSuffixes.Address, diff --git a/packages/website/ts/components/ui/fake_text_field.tsx b/packages/website/ts/components/ui/fake_text_field.tsx index f3d9410f6..646ae98f6 100644 --- a/packages/website/ts/components/ui/fake_text_field.tsx +++ b/packages/website/ts/components/ui/fake_text_field.tsx @@ -1,6 +1,6 @@ +import { Styles } from '@0xproject/react-shared'; import * as React from 'react'; import { InputLabel } from 'ts/components/ui/input_label'; -import { Styles } from 'ts/types'; const styles: Styles = { hr: { diff --git a/packages/website/ts/components/ui/input_label.tsx b/packages/website/ts/components/ui/input_label.tsx index e2009ad20..6a3f26155 100644 --- a/packages/website/ts/components/ui/input_label.tsx +++ b/packages/website/ts/components/ui/input_label.tsx @@ -1,5 +1,5 @@ +import { colors } from '@0xproject/react-shared'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; export interface InputLabelProps { text: string | Element | React.ReactNode; diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx index 8ff856a75..c85e11884 100644 --- a/packages/website/ts/components/ui/lifecycle_raised_button.tsx +++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; const COMPLETE_STATE_SHOW_LENGTH_MS = 2000; diff --git a/packages/website/ts/components/ui/party.tsx b/packages/website/ts/components/ui/party.tsx index ca2577b61..3d94903d1 100644 --- a/packages/website/ts/components/ui/party.tsx +++ b/packages/website/ts/components/ui/party.tsx @@ -1,10 +1,9 @@ +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); import { EthereumAddress } from 'ts/components/ui/ethereum_address'; import { Identicon } from 'ts/components/ui/identicon'; -import { EtherscanLinkSuffixes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { utils } from 'ts/utils/utils'; const IMAGE_DIMENSION = 100; @@ -43,7 +42,7 @@ export class Party extends React.Component<PartyProps, PartyState> { width: IMAGE_DIMENSION, height: IMAGE_DIMENSION, }; - const etherscanLinkIfExists = utils.getEtherScanLinkIfExists( + const etherscanLinkIfExists = sharedUtils.getEtherScanLinkIfExists( this.props.address, this.props.networkId, EtherscanLinkSuffixes.Address, diff --git a/packages/website/ts/components/ui/required_label.tsx b/packages/website/ts/components/ui/required_label.tsx index a5e7a22ce..0f96586ec 100644 --- a/packages/website/ts/components/ui/required_label.tsx +++ b/packages/website/ts/components/ui/required_label.tsx @@ -1,5 +1,5 @@ +import { colors } from '@0xproject/react-shared'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; export interface RequiredLabelProps { label: string | React.ReactNode; diff --git a/packages/website/ts/components/ui/swap_icon.tsx b/packages/website/ts/components/ui/swap_icon.tsx index c41592287..e465a8074 100644 --- a/packages/website/ts/components/ui/swap_icon.tsx +++ b/packages/website/ts/components/ui/swap_icon.tsx @@ -1,6 +1,6 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; interface SwapIconProps { swapTokensFn: () => void; diff --git a/packages/website/ts/containers/connect_documentation.ts b/packages/website/ts/containers/connect_documentation.ts index 6a5ba1f99..bd6821d19 100644 --- a/packages/website/ts/containers/connect_documentation.ts +++ b/packages/website/ts/containers/connect_documentation.ts @@ -1,12 +1,12 @@ +import { constants as docConstants, DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0xproject/react-docs'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; -import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types'; +import { DocPackages, Environments, WebsitePaths } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; @@ -21,7 +21,7 @@ const connectDocSections = { installation: 'installation', httpClient: 'httpClient', webSocketOrderbookChannel: 'webSocketOrderbookChannel', - types: constants.TYPES_SECTION_NAME, + types: docConstants.TYPES_SECTION_NAME, }; const docsInfoConfig: DocsInfoConfig = { @@ -40,29 +40,6 @@ const docsInfoConfig: DocsInfoConfig = { [connectDocSections.introduction]: IntroMarkdown, [connectDocSections.installation]: InstallationMarkdown, }, - // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is - // currently no way to extract the re-exported types from index.ts via TypeDoc :( - publicTypes: [ - 'Client', - 'FeesRequest', - 'FeesResponse', - 'OrderbookChannel', - 'OrderbookChannelHandler', - 'OrderbookChannelSubscriptionOpts', - 'OrderbookRequest', - 'OrderbookResponse', - 'OrdersRequest', - 'OrdersRequestOpts', - 'PagedRequestOpts', - 'TokenPairsItem', - 'TokenPairsRequest', - 'TokenPairsRequestOpts', - 'TokenTradeInfo', - 'WebSocketOrderbookChannelConfig', - 'Order', - 'SignedOrder', - 'ECSignature', - ], sectionNameToModulePath: { [connectDocSections.httpClient]: ['"src/http_client"'], [connectDocSections.webSocketOrderbookChannel]: ['"src/ws_orderbook_channel"'], @@ -71,6 +48,35 @@ const docsInfoConfig: DocsInfoConfig = { menuSubsectionToVersionWhenIntroduced: {}, sections: connectDocSections, visibleConstructors: [connectDocSections.httpClient, connectDocSections.webSocketOrderbookChannel], + typeConfigs: { + typeNameToExternalLink: { + Provider: constants.URL_WEB3_PROVIDER_DOCS, + BigNumber: constants.URL_BIGNUMBERJS_GITHUB, + }, + // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is + // currently no way to extract the re-exported types from index.ts via TypeDoc :( + publicTypes: [ + 'Client', + 'FeesRequest', + 'FeesResponse', + 'OrderbookChannel', + 'OrderbookChannelHandler', + 'OrderbookChannelSubscriptionOpts', + 'OrderbookRequest', + 'OrderbookResponse', + 'OrdersRequest', + 'OrdersRequestOpts', + 'PagedRequestOpts', + 'TokenPairsItem', + 'TokenPairsRequest', + 'TokenPairsRequestOpts', + 'TokenTradeInfo', + 'WebSocketOrderbookChannelConfig', + 'Order', + 'SignedOrder', + 'ECSignature', + ], + }, }; const docsInfo = new DocsInfo(docsInfoConfig); diff --git a/packages/website/ts/containers/smart_contracts_documentation.ts b/packages/website/ts/containers/smart_contracts_documentation.ts index a839529aa..b1b2ea922 100644 --- a/packages/website/ts/containers/smart_contracts_documentation.ts +++ b/packages/website/ts/containers/smart_contracts_documentation.ts @@ -1,19 +1,13 @@ +import { DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0xproject/react-docs'; +import { Networks } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; -import { - DocPackages, - DocsInfoConfig, - Networks, - SmartContractDocSections as Sections, - SupportedDocJson, - WebsitePaths, -} from 'ts/types'; +import { DocPackages, SmartContractDocSections as Sections, WebsitePaths } from 'ts/types'; import { Translate } from 'ts/utils/translate'; /* tslint:disable:no-var-requires */ diff --git a/packages/website/ts/containers/zero_ex_js_documentation.ts b/packages/website/ts/containers/zero_ex_js_documentation.ts index d0d697e70..21e2f780d 100644 --- a/packages/website/ts/containers/zero_ex_js_documentation.ts +++ b/packages/website/ts/containers/zero_ex_js_documentation.ts @@ -1,12 +1,12 @@ +import { constants as docConstants, DocsInfo, DocsInfoConfig, SupportedDocJson } from '@0xproject/react-docs'; import * as _ from 'lodash'; import * as React from 'react'; import { connect } from 'react-redux'; import { Dispatch } from 'redux'; import { DocPage as DocPageComponent, DocPageProps } from 'ts/pages/documentation/doc_page'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; import { Dispatcher } from 'ts/redux/dispatcher'; import { State } from 'ts/redux/reducer'; -import { DocPackages, DocsInfoConfig, Environments, SupportedDocJson, WebsitePaths } from 'ts/types'; +import { DocPackages, Environments, WebsitePaths } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; @@ -33,7 +33,7 @@ const zeroExJsDocSections = { etherToken: 'etherToken', proxy: 'proxy', orderWatcher: 'orderWatcher', - types: constants.TYPES_SECTION_NAME, + types: docConstants.TYPES_SECTION_NAME, }; const docsInfoConfig: DocsInfoConfig = { @@ -63,67 +63,6 @@ const docsInfoConfig: DocsInfoConfig = { [zeroExJsDocSections.errors]: ErrorsMarkdown, [zeroExJsDocSections.versioning]: versioningMarkdown, }, - // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is - // currently no way to extract the re-exported types from index.ts via TypeDoc :( Make sure to only - // ADD types here, DO NOT REMOVE types since they might still be needed for older supported versions - publicTypes: [ - 'Order', - 'SignedOrder', - 'ECSignature', - 'ZeroExError', - 'EventCallback', - 'EventCallbackAsync', - 'EventCallbackSync', - 'ExchangeContractErrs', - 'ContractEvent', - 'Token', - 'ExchangeEvents', - 'IndexedFilterValues', - 'SubscriptionOpts', - 'BlockRange', - 'BlockParam', - 'OrderFillOrKillRequest', - 'OrderCancellationRequest', - 'OrderFillRequest', - 'ContractEventEmitter', - 'Web3Provider', - 'ContractEventArgs', - 'LogCancelArgs', - 'LogFillArgs', - 'LogErrorContractEventArgs', - 'LogFillContractEventArgs', - 'LogCancelContractEventArgs', - 'EtherTokenContractEventArgs', - 'WithdrawalContractEventArgs', - 'DepositContractEventArgs', - 'TokenEvents', - 'ExchangeContractEventArgs', - 'TransferContractEventArgs', - 'ApprovalContractEventArgs', - 'TokenContractEventArgs', - 'ZeroExConfig', - 'TransactionReceipt', - 'TransactionReceiptWithDecodedLogs', - 'LogWithDecodedArgs', - 'EtherTokenEvents', - 'BlockParamLiteral', - 'DecodedLogArgs', - 'MethodOpts', - 'ValidateOrderFillableOpts', - 'OrderTransactionOpts', - 'TransactionOpts', - 'ContractEventArg', - 'LogEvent', - 'LogEntry', - 'DecodedLogEvent', - 'EventWatcherCallback', - 'OnOrderStateChangeCallback', - 'OrderStateValid', - 'OrderStateInvalid', - 'OrderState', - 'OrderStateWatcherConfig', - 'FilterObject', - ], sectionNameToModulePath: { [zeroExJsDocSections.zeroEx]: ['"0x.js/src/0x"', '"src/0x"'], [zeroExJsDocSections.exchange]: [ @@ -160,6 +99,91 @@ const docsInfoConfig: DocsInfoConfig = { }, sections: zeroExJsDocSections, visibleConstructors: [zeroExJsDocSections.zeroEx], + typeConfigs: { + // Note: This needs to be kept in sync with the types exported in index.ts. Unfortunately there is + // currently no way to extract the re-exported types from index.ts via TypeDoc :( Make sure to only + // ADD types here, DO NOT REMOVE types since they might still be needed for older supported versions + publicTypes: [ + 'Order', + 'SignedOrder', + 'ECSignature', + 'ZeroExError', + 'EventCallback', + 'EventCallbackAsync', + 'EventCallbackSync', + 'ExchangeContractErrs', + 'ContractEvent', + 'Token', + 'ExchangeEvents', + 'IndexedFilterValues', + 'SubscriptionOpts', + 'BlockRange', + 'BlockParam', + 'OrderFillOrKillRequest', + 'OrderCancellationRequest', + 'OrderFillRequest', + 'ContractEventEmitter', + 'Web3Provider', + 'ContractEventArgs', + 'LogCancelArgs', + 'LogFillArgs', + 'LogErrorContractEventArgs', + 'LogFillContractEventArgs', + 'LogCancelContractEventArgs', + 'EtherTokenContractEventArgs', + 'WithdrawalContractEventArgs', + 'DepositContractEventArgs', + 'TokenEvents', + 'ExchangeContractEventArgs', + 'TransferContractEventArgs', + 'ApprovalContractEventArgs', + 'TokenContractEventArgs', + 'ZeroExConfig', + 'TransactionReceipt', + 'TransactionReceiptWithDecodedLogs', + 'LogWithDecodedArgs', + 'EtherTokenEvents', + 'BlockParamLiteral', + 'DecodedLogArgs', + 'MethodOpts', + 'ValidateOrderFillableOpts', + 'OrderTransactionOpts', + 'TransactionOpts', + 'ContractEventArg', + 'LogEvent', + 'LogEntry', + 'DecodedLogEvent', + 'EventWatcherCallback', + 'OnOrderStateChangeCallback', + 'OrderStateValid', + 'OrderStateInvalid', + 'OrderState', + 'OrderStateWatcherConfig', + 'FilterObject', + ], + typeNameToPrefix: { + Provider: 'Web3', + DecodedLogEntryEvent: 'Web3', + LogEntryEvent: 'Web3', + CallData: 'Web3', + }, + typeNameToExternalLink: { + Web3: constants.URL_WEB3_DOCS, + Provider: constants.URL_WEB3_PROVIDER_DOCS, + BigNumber: constants.URL_BIGNUMBERJS_GITHUB, + DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT, + LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT, + }, + typeNameToDocSection: { + ExchangeWrapper: 'exchange', + TokenWrapper: 'token', + TokenRegistryWrapper: 'tokenRegistry', + EtherTokenWrapper: 'etherToken', + ProxyWrapper: 'proxy', + TokenTransferProxyWrapper: 'proxy', + OrderStateWatcher: 'orderWatcher', + }, + }, }; const docsInfo = new DocsInfo(docsInfoConfig); diff --git a/packages/website/ts/globals.d.ts b/packages/website/ts/globals.d.ts index 19237db14..ef276519c 100644 --- a/packages/website/ts/globals.d.ts +++ b/packages/website/ts/globals.d.ts @@ -7,7 +7,6 @@ declare module 'whatwg-fetch'; declare module 'react-html5video'; declare module 'web3-provider-engine/subproviders/filters'; declare module 'thenby'; -declare module 'react-highlight'; declare module 'react-recaptcha'; declare module 'react-document-title'; declare module 'ethereumjs-tx'; @@ -28,12 +27,6 @@ declare module 'find-versions' { export = findVersions; } -// compare-version declarations -declare function compareVersions(firstVersion: string, secondVersion: string): number; -declare module 'compare-versions' { - export = compareVersions; -} - // semver-sort declarations declare module 'semver-sort' { const desc: (versions: string[]) => string[]; @@ -116,12 +109,6 @@ declare module 'blockies' { export = blockies; } -// is-mobile declarations -declare function isMobile(): boolean; -declare module 'is-mobile' { - export = isMobile; -} - // web3-provider-engine declarations declare class Subprovider {} declare module 'web3-provider-engine/subproviders/subprovider' { diff --git a/packages/website/ts/pages/about/about.tsx b/packages/website/ts/pages/about/about.tsx index b99dc34ab..7f1e0bf80 100644 --- a/packages/website/ts/pages/about/about.tsx +++ b/packages/website/ts/pages/about/about.tsx @@ -1,3 +1,4 @@ +import { colors, Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import * as DocumentTitle from 'react-document-title'; @@ -5,8 +6,7 @@ import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Profile } from 'ts/pages/about/profile'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { ProfileInfo, Styles } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { ProfileInfo } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/pages/about/profile.tsx b/packages/website/ts/pages/about/profile.tsx index 18b4e0d5a..4361da103 100644 --- a/packages/website/ts/pages/about/profile.tsx +++ b/packages/website/ts/pages/about/profile.tsx @@ -1,7 +1,7 @@ +import { colors, Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { ProfileInfo, Styles } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { ProfileInfo } from 'ts/types'; const IMAGE_DIMENSION = 149; const styles: Styles = { diff --git a/packages/website/ts/pages/documentation/comment.tsx b/packages/website/ts/pages/documentation/comment.tsx deleted file mode 100644 index 5f177e97e..000000000 --- a/packages/website/ts/pages/documentation/comment.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import * as ReactMarkdown from 'react-markdown'; -import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block'; - -interface CommentProps { - comment: string; - className?: string; -} - -const defaultProps = { - className: '', -}; - -export const Comment: React.SFC<CommentProps> = (props: CommentProps) => { - return ( - <div className={`${props.className} comment`}> - <ReactMarkdown source={props.comment} renderers={{ code: MarkdownCodeBlock }} /> - </div> - ); -}; - -Comment.defaultProps = defaultProps; diff --git a/packages/website/ts/pages/documentation/custom_enum.tsx b/packages/website/ts/pages/documentation/custom_enum.tsx deleted file mode 100644 index 8d50a2f52..000000000 --- a/packages/website/ts/pages/documentation/custom_enum.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { CustomType } from 'ts/types'; -import { utils } from 'ts/utils/utils'; - -const STRING_ENUM_CODE_PREFIX = ' strEnum('; - -interface CustomEnumProps { - type: CustomType; -} - -// This component renders custom string enums that was a work-around for versions of -// TypeScript <2.4.0 that did not support them natively. We keep it around to support -// older versions of 0x.js <0.9.0 -export function CustomEnum(props: CustomEnumProps) { - const type = props.type; - if (!_.startsWith(type.defaultValue, STRING_ENUM_CODE_PREFIX)) { - utils.consoleLog('We do not yet support `Variable` types that are not strEnums'); - return null; - } - // Remove the prefix and postfix, leaving only the strEnum values without quotes. - const enumValues = type.defaultValue.slice(10, -3).replace(/'/g, ''); - return ( - <span> - {`{`} - {'\t'} - {enumValues} - <br /> - {`}`} - </span> - ); -} diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx index 2c8f1c103..1281219c6 100644 --- a/packages/website/ts/pages/documentation/doc_page.tsx +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -1,23 +1,27 @@ +import { DocAgnosticFormat, DocsInfo, Documentation, DoxityDocObj } from '@0xproject/react-docs'; +import { MenuSubsectionsBySection } from '@0xproject/react-shared'; import findVersions = require('find-versions'); import * as _ from 'lodash'; import * as React from 'react'; import DocumentTitle = require('react-document-title'); import semverSort = require('semver-sort'); +import { SidebarHeader } from 'ts/components/sidebar_header'; import { TopBar } from 'ts/components/top_bar/top_bar'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Documentation } from 'ts/pages/documentation/documentation'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { DocAgnosticFormat, DocPackages, DoxityDocObj, Environments, MenuSubsectionsBySection } from 'ts/types'; +import { DocPackages, Environments } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { docUtils } from 'ts/utils/doc_utils'; import { Translate } from 'ts/utils/translate'; +import { utils } from 'ts/utils/utils'; +const ZERO_EX_JS_VERSION_MISSING_TOPLEVEL_PATH = '0.32.4'; + +const isDevelopment = configs.ENVIRONMENT === Environments.DEVELOPMENT; const docIdToS3BucketName: { [id: string]: string } = { - [DocPackages.ZeroExJs]: '0xjs-docs-jsons', + [DocPackages.ZeroExJs]: isDevelopment ? 'staging-0xjs-docs-jsons' : '0xjs-docs-jsons', [DocPackages.SmartContracts]: 'smart-contracts-docs-json', - [DocPackages.Connect]: - configs.ENVIRONMENT === Environments.DEVELOPMENT ? 'staging-connect-docs-jsons' : 'connect-docs-jsons', + [DocPackages.Connect]: isDevelopment ? 'staging-connect-docs-jsons' : 'connect-docs-jsons', }; const docIdToSubpackageName: { [id: string]: string } = { @@ -77,15 +81,17 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> { menuSubsectionsBySection={menuSubsectionsBySection} docsInfo={this.props.docsInfo} translate={this.props.translate} + onVersionSelected={this._onVersionSelected.bind(this)} /> <Documentation - location={this.props.location} - docsVersion={this.props.docsVersion} - availableDocVersions={this.props.availableDocVersions} + selectedVersion={this.props.docsVersion} + availableVersions={this.props.availableDocVersions} docsInfo={this.props.docsInfo} docAgnosticFormat={this.state.docAgnosticFormat} - menuSubsectionsBySection={menuSubsectionsBySection} + sidebarHeader={<SidebarHeader title={this.props.docsInfo.displayName} />} sourceUrl={sourceUrl} + topBarHeight={60} + onVersionSelected={this._onVersionSelected.bind(this)} /> </div> ); @@ -110,7 +116,7 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> { const versionFileNameToFetch = versionToFileName[versionToFetch]; const versionDocObj = await docUtils.getJSONDocFileAsync(versionFileNameToFetch, docsJsonRoot); - const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj as DoxityDocObj); + const docAgnosticFormat = this.props.docsInfo.convertToDocAgnosticFormat(versionDocObj); if (!this._isUnmounted) { this.setState({ @@ -120,13 +126,33 @@ export class DocPage extends React.Component<DocPageProps, DocPageState> { } private _getSourceUrl() { const url = this.props.docsInfo.packageUrl; - const pkg = docIdToSubpackageName[this.props.docsInfo.id]; + let pkg = docIdToSubpackageName[this.props.docsInfo.id]; let tagPrefix = pkg; const packagesWithNamespace = ['connect']; if (_.includes(packagesWithNamespace, pkg)) { tagPrefix = `@0xproject/${pkg}`; } - const sourceUrl = `${url}/blob/${tagPrefix}%40${this.props.docsVersion}/packages/${pkg}`; + // HACK: The following three lines exist for backward compatibility reasons + // Before exporting types from other packages as part of the 0x.js interface, + // all TypeDoc generated paths omitted the topLevel `0x.js` segment. Now it + // adds it, and for that reason, we need to make sure we don't add it twice in + // the source links we generate. + const semvers = semverSort.desc([this.props.docsVersion, ZERO_EX_JS_VERSION_MISSING_TOPLEVEL_PATH]); + const isVersionAfterTopLevelPathChange = semvers[0] !== ZERO_EX_JS_VERSION_MISSING_TOPLEVEL_PATH; + pkg = this.props.docsInfo.id === DocPackages.ZeroExJs && isVersionAfterTopLevelPathChange ? '' : `/${pkg}`; + + const sourceUrl = `${url}/blob/${tagPrefix}%40${this.props.docsVersion}/packages${pkg}`; return sourceUrl; } + private _onVersionSelected(semver: string) { + let path = window.location.pathname; + const lastChar = path[path.length - 1]; + if (_.isFinite(_.parseInt(lastChar))) { + const pathSections = path.split('/'); + pathSections.pop(); + path = pathSections.join('/'); + } + const baseUrl = utils.getCurrentBaseUrl(); + window.location.href = `${baseUrl}${path}/${semver}${window.location.hash}`; + } } diff --git a/packages/website/ts/pages/documentation/docs_info.ts b/packages/website/ts/pages/documentation/docs_info.ts deleted file mode 100644 index 31e151fe8..000000000 --- a/packages/website/ts/pages/documentation/docs_info.ts +++ /dev/null @@ -1,119 +0,0 @@ -import compareVersions = require('compare-versions'); -import * as _ from 'lodash'; -import { - ContractsByVersionByNetworkId, - DocAgnosticFormat, - DocsInfoConfig, - DocsMenu, - DoxityDocObj, - MenuSubsectionsBySection, - SectionsMap, - SupportedDocJson, - TypeDocNode, -} from 'ts/types'; -import { doxityUtils } from 'ts/utils/doxity_utils'; -import { typeDocUtils } from 'ts/utils/typedoc_utils'; - -export class DocsInfo { - public id: string; - public type: SupportedDocJson; - public displayName: string; - public packageUrl: string; - public menu: DocsMenu; - public sections: SectionsMap; - public sectionNameToMarkdown: { [sectionName: string]: string }; - public contractsByVersionByNetworkId?: ContractsByVersionByNetworkId; - private _docsInfo: DocsInfoConfig; - constructor(config: DocsInfoConfig) { - this.id = config.id; - this.type = config.type; - this.displayName = config.displayName; - this.packageUrl = config.packageUrl; - this.sections = config.sections; - this.sectionNameToMarkdown = config.sectionNameToMarkdown; - this.contractsByVersionByNetworkId = config.contractsByVersionByNetworkId; - this._docsInfo = config; - } - public isPublicType(typeName: string): boolean { - if (_.isUndefined(this._docsInfo.publicTypes)) { - return false; - } - const isPublic = _.includes(this._docsInfo.publicTypes, typeName); - return isPublic; - } - public getModulePathsIfExists(sectionName: string): string[] { - const modulePathsIfExists = this._docsInfo.sectionNameToModulePath[sectionName]; - return modulePathsIfExists; - } - public getMenu(selectedVersion?: string): { [section: string]: string[] } { - if (_.isUndefined(selectedVersion) || _.isUndefined(this._docsInfo.menuSubsectionToVersionWhenIntroduced)) { - return this._docsInfo.menu; - } - - const finalMenu = _.cloneDeep(this._docsInfo.menu); - if (_.isUndefined(finalMenu.contracts)) { - return finalMenu; - } - - // TODO: refactor to include more sections then simply the `contracts` section - finalMenu.contracts = _.filter(finalMenu.contracts, (contractName: string) => { - const versionIntroducedIfExists = this._docsInfo.menuSubsectionToVersionWhenIntroduced[contractName]; - if (!_.isUndefined(versionIntroducedIfExists)) { - const existsInSelectedVersion = compareVersions(selectedVersion, versionIntroducedIfExists) >= 0; - return existsInSelectedVersion; - } else { - return true; - } - }); - return finalMenu; - } - public getMenuSubsectionsBySection(docAgnosticFormat?: DocAgnosticFormat): MenuSubsectionsBySection { - const menuSubsectionsBySection = {} as MenuSubsectionsBySection; - if (_.isUndefined(docAgnosticFormat)) { - return menuSubsectionsBySection; - } - - const docSections = _.keys(this.sections); - _.each(docSections, sectionName => { - const docSection = docAgnosticFormat[sectionName]; - if (_.isUndefined(docSection)) { - return; // no-op - } - - if (!_.isUndefined(this.sections.types) && sectionName === this.sections.types) { - const sortedTypesNames = _.sortBy(docSection.types, 'name'); - const typeNames = _.map(sortedTypesNames, t => t.name); - menuSubsectionsBySection[sectionName] = typeNames; - } else { - let eventNames: string[] = []; - if (!_.isUndefined(docSection.events)) { - const sortedEventNames = _.sortBy(docSection.events, 'name'); - eventNames = _.map(sortedEventNames, m => m.name); - } - const sortedMethodNames = _.sortBy(docSection.methods, 'name'); - const methodNames = _.map(sortedMethodNames, m => m.name); - menuSubsectionsBySection[sectionName] = [...methodNames, ...eventNames]; - } - }); - return menuSubsectionsBySection; - } - public getTypeDefinitionsByName(docAgnosticFormat: DocAgnosticFormat) { - if (_.isUndefined(this.sections.types)) { - return {}; - } - - const typeDocSection = docAgnosticFormat[this.sections.types]; - const typeDefinitionByName = _.keyBy(typeDocSection.types, 'name'); - return typeDefinitionByName; - } - public isVisibleConstructor(sectionName: string): boolean { - return _.includes(this._docsInfo.visibleConstructors, sectionName); - } - public convertToDocAgnosticFormat(docObj: DoxityDocObj | TypeDocNode): DocAgnosticFormat { - if (this.type === SupportedDocJson.Doxity) { - return doxityUtils.convertToDocAgnosticFormat(docObj as DoxityDocObj); - } else { - return typeDocUtils.convertToDocAgnosticFormat(docObj as TypeDocNode, this); - } - } -} diff --git a/packages/website/ts/pages/documentation/documentation.tsx b/packages/website/ts/pages/documentation/documentation.tsx deleted file mode 100644 index 699bef7a8..000000000 --- a/packages/website/ts/pages/documentation/documentation.tsx +++ /dev/null @@ -1,333 +0,0 @@ -import * as _ from 'lodash'; -import CircularProgress from 'material-ui/CircularProgress'; -import * as React from 'react'; -import { scroller } from 'react-scroll'; -import { Badge } from 'ts/components/ui/badge'; -import { Comment } from 'ts/pages/documentation/comment'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { EventDefinition } from 'ts/pages/documentation/event_definition'; -import { MethodBlock } from 'ts/pages/documentation/method_block'; -import { SourceLink } from 'ts/pages/documentation/source_link'; -import { Type } from 'ts/pages/documentation/type'; -import { TypeDefinition } from 'ts/pages/documentation/type_definition'; -import { MarkdownSection } from 'ts/pages/shared/markdown_section'; -import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu'; -import { SectionHeader } from 'ts/pages/shared/section_header'; -import { - AddressByContractName, - DocAgnosticFormat, - DoxityDocObj, - EtherscanLinkSuffixes, - Event, - MenuSubsectionsBySection, - Networks, - Property, - SolidityMethod, - Styles, - SupportedDocJson, - TypeDefinitionByName, - TypescriptMethod, -} from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { configs } from 'ts/utils/configs'; -import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; - -const TOP_BAR_HEIGHT = 60; - -const networkNameToColor: { [network: string]: string } = { - [Networks.Kovan]: colors.purple, - [Networks.Ropsten]: colors.red, - [Networks.Mainnet]: colors.turquois, - [Networks.Rinkeby]: colors.darkYellow, -}; - -export interface DocumentationProps { - location: Location; - docsVersion: string; - availableDocVersions: string[]; - docsInfo: DocsInfo; - docAgnosticFormat?: DocAgnosticFormat; - menuSubsectionsBySection: MenuSubsectionsBySection; - sourceUrl: string; -} - -interface DocumentationState {} - -const styles: Styles = { - mainContainers: { - position: 'absolute', - top: 1, - left: 0, - bottom: 0, - right: 0, - overflowZ: 'hidden', - overflowY: 'scroll', - minHeight: `calc(100vh - ${TOP_BAR_HEIGHT}px)`, - WebkitOverflowScrolling: 'touch', - }, - menuContainer: { - borderColor: colors.grey300, - maxWidth: 330, - marginLeft: 20, - }, -}; - -export class Documentation extends React.Component<DocumentationProps, DocumentationState> { - public componentDidUpdate(prevProps: DocumentationProps, prevState: DocumentationState) { - if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) { - const hash = this.props.location.hash.slice(1); - utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); - } - } - public render() { - return ( - <div> - {_.isUndefined(this.props.docAgnosticFormat) ? ( - this._renderLoading() - ) : ( - <div style={{ width: '100%', height: '100%', backgroundColor: colors.gray40 }}> - <div - className="mx-auto max-width-4 flex" - style={{ color: colors.grey800, height: `calc(100vh - ${TOP_BAR_HEIGHT}px)` }} - > - <div - className="relative sm-hide xs-hide" - style={{ width: '36%', height: `calc(100vh - ${TOP_BAR_HEIGHT}px)` }} - > - <div - className="border-right absolute" - style={{ - ...styles.menuContainer, - ...styles.mainContainers, - height: `calc(100vh - ${TOP_BAR_HEIGHT}px)`, - }} - > - <NestedSidebarMenu - selectedVersion={this.props.docsVersion} - versions={this.props.availableDocVersions} - title={this.props.docsInfo.displayName} - topLevelMenu={this.props.docsInfo.getMenu(this.props.docsVersion)} - menuSubsectionsBySection={this.props.menuSubsectionsBySection} - /> - </div> - </div> - <div - className="relative col lg-col-9 md-col-9 sm-col-12 col-12" - style={{ backgroundColor: colors.white }} - > - <div - id={configs.SCROLL_CONTAINER_ID} - style={styles.mainContainers} - className="absolute px1" - > - <div id={configs.SCROLL_TOP_ID} /> - {this._renderDocumentation()} - </div> - </div> - </div> - </div> - )} - </div> - ); - } - private _renderLoading() { - return ( - <div className="col col-12" style={styles.mainContainers}> - <div - className="relative sm-px2 sm-pt2 sm-m1" - style={{ height: 122, top: '50%', transform: 'translateY(-50%)' }} - > - <div className="center pb2"> - <CircularProgress size={40} thickness={5} /> - </div> - <div className="center pt2" style={{ paddingBottom: 11 }}> - Loading documentation... - </div> - </div> - </div> - ); - } - private _renderDocumentation(): React.ReactNode { - const subMenus = _.values(this.props.docsInfo.getMenu()); - const orderedSectionNames = _.flatten(subMenus); - - const typeDefinitionByName = this.props.docsInfo.getTypeDefinitionsByName(this.props.docAgnosticFormat); - const renderedSections = _.map(orderedSectionNames, this._renderSection.bind(this, typeDefinitionByName)); - - return renderedSections; - } - private _renderSection(typeDefinitionByName: TypeDefinitionByName, sectionName: string): React.ReactNode { - const markdownFileIfExists = this.props.docsInfo.sectionNameToMarkdown[sectionName]; - if (!_.isUndefined(markdownFileIfExists)) { - return ( - <MarkdownSection - key={`markdown-section-${sectionName}`} - sectionName={sectionName} - markdownContent={markdownFileIfExists} - /> - ); - } - - const docSection = this.props.docAgnosticFormat[sectionName]; - if (_.isUndefined(docSection)) { - return null; - } - - const sortedTypes = _.sortBy(docSection.types, 'name'); - const typeDefs = _.map(sortedTypes, customType => { - return ( - <TypeDefinition - sectionName={sectionName} - key={`type-${customType.name}`} - customType={customType} - docsInfo={this.props.docsInfo} - /> - ); - }); - - const sortedProperties = _.sortBy(docSection.properties, 'name'); - const propertyDefs = _.map(sortedProperties, this._renderProperty.bind(this, sectionName)); - - const sortedMethods = _.sortBy(docSection.methods, 'name'); - const methodDefs = _.map(sortedMethods, method => { - const isConstructor = false; - return this._renderMethodBlocks(method, sectionName, isConstructor, typeDefinitionByName); - }); - - const sortedEvents = _.sortBy(docSection.events, 'name'); - const eventDefs = _.map(sortedEvents, (event: Event, i: number) => { - return ( - <EventDefinition - key={`event-${event.name}-${i}`} - event={event} - sectionName={sectionName} - docsInfo={this.props.docsInfo} - /> - ); - }); - return ( - <div key={`section-${sectionName}`} className="py2 pr3 md-pl2 sm-pl3"> - <div className="flex pb2"> - <div style={{ marginRight: 7 }}> - <SectionHeader sectionName={sectionName} /> - </div> - {this._renderNetworkBadgesIfExists(sectionName)} - </div> - {docSection.comment && <Comment comment={docSection.comment} />} - {docSection.constructors.length > 0 && - this.props.docsInfo.isVisibleConstructor(sectionName) && ( - <div> - <h2 className="thin">Constructor</h2> - {this._renderConstructors(docSection.constructors, sectionName, typeDefinitionByName)} - </div> - )} - {docSection.properties.length > 0 && ( - <div> - <h2 className="thin">Properties</h2> - <div>{propertyDefs}</div> - </div> - )} - {docSection.methods.length > 0 && ( - <div> - <h2 className="thin">Methods</h2> - <div>{methodDefs}</div> - </div> - )} - {!_.isUndefined(docSection.events) && - docSection.events.length > 0 && ( - <div> - <h2 className="thin">Events</h2> - <div>{eventDefs}</div> - </div> - )} - {!_.isUndefined(typeDefs) && - typeDefs.length > 0 && ( - <div> - <div>{typeDefs}</div> - </div> - )} - </div> - ); - } - private _renderNetworkBadgesIfExists(sectionName: string) { - if (this.props.docsInfo.type !== SupportedDocJson.Doxity) { - return null; - } - - const networkToAddressByContractName = this.props.docsInfo.contractsByVersionByNetworkId[ - this.props.docsVersion - ]; - const badges = _.map( - networkToAddressByContractName, - (addressByContractName: AddressByContractName, networkName: string) => { - const contractAddress = addressByContractName[sectionName]; - if (_.isUndefined(contractAddress)) { - return null; - } - const linkIfExists = utils.getEtherScanLinkIfExists( - contractAddress, - constants.NETWORK_ID_BY_NAME[networkName], - EtherscanLinkSuffixes.Address, - ); - return ( - <a - key={`badge-${networkName}-${sectionName}`} - href={linkIfExists} - target="_blank" - style={{ color: colors.white, textDecoration: 'none' }} - > - <Badge title={networkName} backgroundColor={networkNameToColor[networkName]} /> - </a> - ); - }, - ); - return badges; - } - private _renderConstructors( - constructors: SolidityMethod[] | TypescriptMethod[], - sectionName: string, - typeDefinitionByName: TypeDefinitionByName, - ): React.ReactNode { - const constructorDefs = _.map(constructors, constructor => { - return this._renderMethodBlocks(constructor, sectionName, constructor.isConstructor, typeDefinitionByName); - }); - return <div>{constructorDefs}</div>; - } - private _renderProperty(sectionName: string, property: Property): React.ReactNode { - return ( - <div key={`property-${property.name}-${property.type.name}`} className="pb3"> - <code className="hljs"> - {property.name}: - <Type type={property.type} sectionName={sectionName} docsInfo={this.props.docsInfo} /> - </code> - {property.source && ( - <SourceLink - version={this.props.docsVersion} - source={property.source} - sourceUrl={this.props.sourceUrl} - /> - )} - {property.comment && <Comment comment={property.comment} className="py2" />} - </div> - ); - } - private _renderMethodBlocks( - method: SolidityMethod | TypescriptMethod, - sectionName: string, - isConstructor: boolean, - typeDefinitionByName: TypeDefinitionByName, - ): React.ReactNode { - return ( - <MethodBlock - key={`method-${method.name}-${sectionName}`} - sectionName={sectionName} - method={method} - typeDefinitionByName={typeDefinitionByName} - libraryVersion={this.props.docsVersion} - docsInfo={this.props.docsInfo} - sourceUrl={this.props.sourceUrl} - /> - ); - } -} diff --git a/packages/website/ts/pages/documentation/enum.tsx b/packages/website/ts/pages/documentation/enum.tsx deleted file mode 100644 index 7dfdee771..000000000 --- a/packages/website/ts/pages/documentation/enum.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { EnumValue } from 'ts/types'; - -interface EnumProps { - values: EnumValue[]; -} - -export function Enum(props: EnumProps) { - const values = _.map(props.values, (value, i) => { - const defaultValueIfAny = !_.isUndefined(value.defaultValue) ? ` = ${value.defaultValue}` : ''; - return `\n\t${value.name}${defaultValueIfAny},`; - }); - return ( - <span> - {`{`} - {values} - <br /> - {`}`} - </span> - ); -} diff --git a/packages/website/ts/pages/documentation/event_definition.tsx b/packages/website/ts/pages/documentation/event_definition.tsx deleted file mode 100644 index e62c9ecbd..000000000 --- a/packages/website/ts/pages/documentation/event_definition.tsx +++ /dev/null @@ -1,83 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Type } from 'ts/pages/documentation/type'; -import { AnchorTitle } from 'ts/pages/shared/anchor_title'; -import { Event, EventArg, HeaderSizes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; - -interface EventDefinitionProps { - event: Event; - sectionName: string; - docsInfo: DocsInfo; -} - -interface EventDefinitionState { - shouldShowAnchor: boolean; -} - -export class EventDefinition extends React.Component<EventDefinitionProps, EventDefinitionState> { - constructor(props: EventDefinitionProps) { - super(props); - this.state = { - shouldShowAnchor: false, - }; - } - public render() { - const event = this.props.event; - const id = `${this.props.sectionName}-${event.name}`; - return ( - <div - id={id} - className="pb2" - style={{ overflow: 'hidden', width: '100%' }} - onMouseOver={this._setAnchorVisibility.bind(this, true)} - onMouseOut={this._setAnchorVisibility.bind(this, false)} - > - <AnchorTitle - headerSize={HeaderSizes.H3} - title={`Event ${event.name}`} - id={id} - shouldShowAnchor={this.state.shouldShowAnchor} - /> - <div style={{ fontSize: 16 }}> - <pre> - <code className="hljs">{this._renderEventCode()}</code> - </pre> - </div> - </div> - ); - } - private _renderEventCode() { - const indexed = <span style={{ color: colors.green }}> indexed</span>; - const eventArgs = _.map(this.props.event.eventArgs, (eventArg: EventArg) => { - const type = ( - <Type type={eventArg.type} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} /> - ); - return ( - <span key={`eventArg-${eventArg.name}`}> - {eventArg.name} - {eventArg.isIndexed ? indexed : ''}: {type}, - </span> - ); - }); - const argList = _.reduce(eventArgs, (prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, '\n\t', curr]; - }); - return ( - <span> - {`{`} - <br /> - {'\t'} - {argList} - <br /> - {`}`} - </span> - ); - } - private _setAnchorVisibility(shouldShowAnchor: boolean) { - this.setState({ - shouldShowAnchor, - }); - } -} diff --git a/packages/website/ts/pages/documentation/interface.tsx b/packages/website/ts/pages/documentation/interface.tsx deleted file mode 100644 index 16a772125..000000000 --- a/packages/website/ts/pages/documentation/interface.tsx +++ /dev/null @@ -1,61 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { MethodSignature } from 'ts/pages/documentation/method_signature'; -import { Type } from 'ts/pages/documentation/type'; -import { CustomType, TypeDocTypes } from 'ts/types'; - -interface InterfaceProps { - type: CustomType; - sectionName: string; - docsInfo: DocsInfo; -} - -export function Interface(props: InterfaceProps) { - const type = props.type; - const properties = _.map(type.children, property => { - return ( - <span key={`property-${property.name}-${property.type}-${type.name}`}> - {property.name}:{' '} - {property.type.typeDocType !== TypeDocTypes.Reflection ? ( - <Type type={property.type} sectionName={props.sectionName} docsInfo={props.docsInfo} /> - ) : ( - <MethodSignature - method={property.type.method} - sectionName={props.sectionName} - shouldHideMethodName={true} - shouldUseArrowSyntax={true} - docsInfo={props.docsInfo} - /> - )}, - </span> - ); - }); - const hasIndexSignature = !_.isUndefined(type.indexSignature); - if (hasIndexSignature) { - const is = type.indexSignature; - const param = ( - <span key={`indexSigParams-${is.keyName}-${is.keyType}-${type.name}`}> - {is.keyName}: <Type type={is.keyType} sectionName={props.sectionName} docsInfo={props.docsInfo} /> - </span> - ); - properties.push( - <span key={`indexSignature-${type.name}-${is.keyType.name}`}> - [{param}]: {is.valueName}, - </span>, - ); - } - const propertyList = _.reduce(properties, (prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, '\n\t', curr]; - }); - return ( - <span> - {`{`} - <br /> - {'\t'} - {propertyList} - <br /> - {`}`} - </span> - ); -} diff --git a/packages/website/ts/pages/documentation/method_block.tsx b/packages/website/ts/pages/documentation/method_block.tsx deleted file mode 100644 index d2c96bf8c..000000000 --- a/packages/website/ts/pages/documentation/method_block.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { Comment } from 'ts/pages/documentation/comment'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { MethodSignature } from 'ts/pages/documentation/method_signature'; -import { SourceLink } from 'ts/pages/documentation/source_link'; -import { AnchorTitle } from 'ts/pages/shared/anchor_title'; -import { HeaderSizes, Parameter, SolidityMethod, Styles, TypeDefinitionByName, TypescriptMethod } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { typeDocUtils } from 'ts/utils/typedoc_utils'; - -interface MethodBlockProps { - method: SolidityMethod | TypescriptMethod; - sectionName: string; - libraryVersion: string; - typeDefinitionByName: TypeDefinitionByName; - docsInfo: DocsInfo; - sourceUrl: string; -} - -interface MethodBlockState { - shouldShowAnchor: boolean; -} - -const styles: Styles = { - chip: { - fontSize: 13, - backgroundColor: colors.lightBlueA700, - color: colors.white, - height: 11, - borderRadius: 14, - lineHeight: 0.9, - }, -}; - -export class MethodBlock extends React.Component<MethodBlockProps, MethodBlockState> { - constructor(props: MethodBlockProps) { - super(props); - this.state = { - shouldShowAnchor: false, - }; - } - public render() { - const method = this.props.method; - if (typeDocUtils.isPrivateOrProtectedProperty(method.name)) { - return null; - } - - return ( - <div - id={`${this.props.sectionName}-${method.name}`} - style={{ overflow: 'hidden', width: '100%' }} - className="pb4" - onMouseOver={this._setAnchorVisibility.bind(this, true)} - onMouseOut={this._setAnchorVisibility.bind(this, false)} - > - {!method.isConstructor && ( - <div className="flex pb2 pt2"> - {(method as TypescriptMethod).isStatic && this._renderChip('Static')} - {(method as SolidityMethod).isConstant && this._renderChip('Constant')} - {(method as SolidityMethod).isPayable && this._renderChip('Payable')} - <div style={{ lineHeight: 1.3 }}> - <AnchorTitle - headerSize={HeaderSizes.H3} - title={method.name} - id={`${this.props.sectionName}-${method.name}`} - shouldShowAnchor={this.state.shouldShowAnchor} - /> - </div> - </div> - )} - <code className="hljs"> - <MethodSignature - method={method} - sectionName={this.props.sectionName} - typeDefinitionByName={this.props.typeDefinitionByName} - docsInfo={this.props.docsInfo} - /> - </code> - {(method as TypescriptMethod).source && ( - <SourceLink - version={this.props.libraryVersion} - source={(method as TypescriptMethod).source} - sourceUrl={this.props.sourceUrl} - /> - )} - {method.comment && <Comment comment={method.comment} className="py2" />} - {method.parameters && - !_.isEmpty(method.parameters) && ( - <div> - <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}> - ARGUMENTS - </h4> - {this._renderParameterDescriptions(method.parameters)} - </div> - )} - {method.returnComment && ( - <div className="pt1 comment"> - <h4 className="pb1 thin" style={{ borderBottom: '1px solid #e1e8ed' }}> - RETURNS - </h4> - <Comment comment={method.returnComment} /> - </div> - )} - </div> - ); - } - private _renderChip(text: string) { - return ( - <div className="p1 mr1" style={styles.chip}> - {text} - </div> - ); - } - private _renderParameterDescriptions(parameters: Parameter[]) { - const descriptions = _.map(parameters, parameter => { - const isOptional = parameter.isOptional; - return ( - <div - key={`param-description-${parameter.name}`} - className="flex pb1 mb2" - style={{ borderBottom: '1px solid #f0f4f7' }} - > - <div className="pl2 col lg-col-4 md-col-4 sm-col-12 col-12"> - <div - className="bold" - style={{ overflow: 'hidden', whiteSpace: 'nowrap', textOverflow: 'ellipsis' }} - > - {parameter.name} - </div> - <div className="pt1" style={{ color: colors.grey, fontSize: 14 }}> - {isOptional && 'optional'} - </div> - </div> - <div className="col lg-col-8 md-col-8 sm-col-12 col-12" style={{ paddingLeft: 5 }}> - {parameter.comment && <Comment comment={parameter.comment} />} - </div> - </div> - ); - }); - return descriptions; - } - private _setAnchorVisibility(shouldShowAnchor: boolean) { - this.setState({ - shouldShowAnchor, - }); - } -} diff --git a/packages/website/ts/pages/documentation/method_signature.tsx b/packages/website/ts/pages/documentation/method_signature.tsx deleted file mode 100644 index 22294e428..000000000 --- a/packages/website/ts/pages/documentation/method_signature.tsx +++ /dev/null @@ -1,126 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import * as ReactDOM from 'react-dom'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Type } from 'ts/pages/documentation/type'; -import { Parameter, SolidityMethod, TypeDefinitionByName, TypescriptMethod } from 'ts/types'; -import { constants } from 'ts/utils/constants'; - -interface MethodSignatureProps { - method: TypescriptMethod | SolidityMethod; - sectionName: string; - shouldHideMethodName?: boolean; - shouldUseArrowSyntax?: boolean; - typeDefinitionByName?: TypeDefinitionByName; - docsInfo: DocsInfo; -} - -const defaultProps = { - shouldHideMethodName: false, - shouldUseArrowSyntax: false, -}; - -export const MethodSignature: React.SFC<MethodSignatureProps> = (props: MethodSignatureProps) => { - const sectionName = constants.TYPES_SECTION_NAME; - const parameters = renderParameters(props.method, props.docsInfo, sectionName, props.typeDefinitionByName); - const paramStringArray: any[] = []; - // HACK: For now we don't put params on newlines if there are less then 2 of them. - // Ideally we would check the character length of the resulting method signature and - // if it exceeds the available space, put params on their own lines. - const hasMoreThenTwoParams = parameters.length > 2; - _.each(parameters, (param: React.ReactNode, i: number) => { - const finalParam = hasMoreThenTwoParams ? ( - <span className="pl2" key={`param-${i}`}> - {param} - </span> - ) : ( - param - ); - paramStringArray.push(finalParam); - const comma = hasMoreThenTwoParams ? ( - <span key={`param-comma-${i}`}> - , <br /> - </span> - ) : ( - ', ' - ); - paramStringArray.push(comma); - }); - if (!hasMoreThenTwoParams) { - paramStringArray.pop(); - } - const methodName = props.shouldHideMethodName ? '' : props.method.name; - const typeParameterIfExists = _.isUndefined((props.method as TypescriptMethod).typeParameter) - ? undefined - : renderTypeParameter(props.method, props.docsInfo, sectionName, props.typeDefinitionByName); - return ( - <span style={{ fontSize: 15 }}> - {props.method.callPath} - {methodName} - {typeParameterIfExists}({hasMoreThenTwoParams && <br />} - {paramStringArray}) - {props.method.returnType && ( - <span> - {props.shouldUseArrowSyntax ? ' => ' : ': '}{' '} - <Type - type={props.method.returnType} - sectionName={sectionName} - typeDefinitionByName={props.typeDefinitionByName} - docsInfo={props.docsInfo} - /> - </span> - )} - </span> - ); -}; - -MethodSignature.defaultProps = defaultProps; - -function renderParameters( - method: TypescriptMethod | SolidityMethod, - docsInfo: DocsInfo, - sectionName: string, - typeDefinitionByName?: TypeDefinitionByName, -) { - const parameters = method.parameters; - const params = _.map(parameters, (p: Parameter) => { - const isOptional = p.isOptional; - const type = ( - <Type - type={p.type} - sectionName={sectionName} - typeDefinitionByName={typeDefinitionByName} - docsInfo={docsInfo} - /> - ); - return ( - <span key={`param-${p.type}-${p.name}`}> - {p.name} - {isOptional && '?'}: {type} - </span> - ); - }); - return params; -} - -function renderTypeParameter( - method: TypescriptMethod, - docsInfo: DocsInfo, - sectionName: string, - typeDefinitionByName?: TypeDefinitionByName, -) { - const typeParameter = method.typeParameter; - const typeParam = ( - <span> - {`<${typeParameter.name} extends `} - <Type - type={typeParameter.type} - sectionName={sectionName} - typeDefinitionByName={typeDefinitionByName} - docsInfo={docsInfo} - /> - {`>`} - </span> - ); - return typeParam; -} diff --git a/packages/website/ts/pages/documentation/source_link.tsx b/packages/website/ts/pages/documentation/source_link.tsx deleted file mode 100644 index 31f80aba3..000000000 --- a/packages/website/ts/pages/documentation/source_link.tsx +++ /dev/null @@ -1,22 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { Source } from 'ts/types'; -import { colors } from 'ts/utils/colors'; - -interface SourceLinkProps { - source: Source; - sourceUrl: string; - version: string; -} - -export function SourceLink(props: SourceLinkProps) { - const src = props.source; - const sourceCodeUrl = `${props.sourceUrl}/${src.fileName}#L${src.line}`; - return ( - <div className="pt2" style={{ fontSize: 14 }}> - <a href={sourceCodeUrl} target="_blank" className="underline" style={{ color: colors.grey }}> - Source - </a> - </div> - ); -} diff --git a/packages/website/ts/pages/documentation/type.tsx b/packages/website/ts/pages/documentation/type.tsx deleted file mode 100644 index b306fa053..000000000 --- a/packages/website/ts/pages/documentation/type.tsx +++ /dev/null @@ -1,229 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { Link as ScrollLink } from 'react-scroll'; -import * as ReactTooltip from 'react-tooltip'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { TypeDefinition } from 'ts/pages/documentation/type_definition'; -import { Type as TypeDef, TypeDefinitionByName, TypeDocTypes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; - -// Some types reference other libraries. For these types, we want to link the user to the relevant documentation. -const typeToUrl: { [typeName: string]: string } = { - Web3: constants.URL_WEB3_DOCS, - Provider: constants.URL_WEB3_PROVIDER_DOCS, - BigNumber: constants.URL_BIGNUMBERJS_GITHUB, - DecodedLogEntryEvent: constants.URL_WEB3_DECODED_LOG_ENTRY_EVENT, - LogEntryEvent: constants.URL_WEB3_LOG_ENTRY_EVENT, -}; - -const typePrefix: { [typeName: string]: string } = { - Provider: 'Web3', - DecodedLogEntryEvent: 'Web3', - LogEntryEvent: 'Web3', -}; - -const typeToSection: { [typeName: string]: string } = { - ExchangeWrapper: 'exchange', - TokenWrapper: 'token', - TokenRegistryWrapper: 'tokenRegistry', - EtherTokenWrapper: 'etherToken', - ProxyWrapper: 'proxy', - TokenTransferProxyWrapper: 'proxy', - OrderStateWatcher: 'orderWatcher', -}; - -interface TypeProps { - type: TypeDef; - docsInfo: DocsInfo; - sectionName: string; - typeDefinitionByName?: TypeDefinitionByName; -} - -// The return type needs to be `any` here so that we can recursively define <Type /> components within -// <Type /> components (e.g when rendering the union type). -export function Type(props: TypeProps): any { - const type = props.type; - const isReference = type.typeDocType === TypeDocTypes.Reference; - const isArray = type.typeDocType === TypeDocTypes.Array; - let typeNameColor = 'inherit'; - let typeName: string | React.ReactNode; - let typeArgs: React.ReactNode[] = []; - switch (type.typeDocType) { - case TypeDocTypes.Intrinsic: - case TypeDocTypes.Unknown: - typeName = type.name; - typeNameColor = colors.orange; - break; - - case TypeDocTypes.Reference: - typeName = type.name; - typeArgs = _.map(type.typeArguments, (arg: TypeDef) => { - if (arg.typeDocType === TypeDocTypes.Array) { - const key = `type-${arg.elementType.name}-${arg.elementType.typeDocType}`; - return ( - <span> - <Type - key={key} - type={arg.elementType} - sectionName={props.sectionName} - typeDefinitionByName={props.typeDefinitionByName} - docsInfo={props.docsInfo} - />[] - </span> - ); - } else { - const subType = ( - <Type - key={`type-${arg.name}-${arg.value}-${arg.typeDocType}`} - type={arg} - sectionName={props.sectionName} - typeDefinitionByName={props.typeDefinitionByName} - docsInfo={props.docsInfo} - /> - ); - return subType; - } - }); - break; - - case TypeDocTypes.StringLiteral: - typeName = `'${type.value}'`; - typeNameColor = colors.green; - break; - - case TypeDocTypes.Array: - typeName = type.elementType.name; - break; - - case TypeDocTypes.Union: - const unionTypes = _.map(type.types, t => { - return ( - <Type - key={`type-${t.name}-${t.value}-${t.typeDocType}`} - type={t} - sectionName={props.sectionName} - typeDefinitionByName={props.typeDefinitionByName} - docsInfo={props.docsInfo} - /> - ); - }); - typeName = _.reduce(unionTypes, (prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, '|', curr]; - }); - break; - - case TypeDocTypes.TypeParameter: - typeName = type.name; - break; - - case TypeDocTypes.Intersection: - const intersectionsTypes = _.map(type.types, t => { - return ( - <Type - key={`type-${t.name}-${t.value}-${t.typeDocType}`} - type={t} - sectionName={props.sectionName} - typeDefinitionByName={props.typeDefinitionByName} - docsInfo={props.docsInfo} - /> - ); - }); - typeName = _.reduce(intersectionsTypes, (prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, '&', curr]; - }); - break; - - default: - throw utils.spawnSwitchErr('type.typeDocType', type.typeDocType); - } - // HACK: Normalize BigNumber to simply BigNumber. For some reason the type - // name is unpredictably one or the other. - if (typeName === 'BigNumber') { - typeName = 'BigNumber'; - } - const commaSeparatedTypeArgs = _.reduce(typeArgs, (prev: React.ReactNode, curr: React.ReactNode) => { - return [prev, ', ', curr]; - }); - - const typeNameUrlIfExists = typeToUrl[typeName as string]; - const typePrefixIfExists = typePrefix[typeName as string]; - const sectionNameIfExists = typeToSection[typeName as string]; - if (!_.isUndefined(typeNameUrlIfExists)) { - typeName = ( - <a - href={typeNameUrlIfExists} - target="_blank" - className="text-decoration-none" - style={{ color: colors.lightBlueA700 }} - > - {!_.isUndefined(typePrefixIfExists) ? `${typePrefixIfExists}.` : ''} - {typeName} - </a> - ); - } else if ( - (isReference || isArray) && - (props.docsInfo.isPublicType(typeName as string) || !_.isUndefined(sectionNameIfExists)) - ) { - const id = Math.random().toString(); - const typeDefinitionAnchorId = _.isUndefined(sectionNameIfExists) - ? `${props.sectionName}-${typeName}` - : sectionNameIfExists; - let typeDefinition; - if (props.typeDefinitionByName) { - typeDefinition = props.typeDefinitionByName[typeName as string]; - } - typeName = ( - <ScrollLink - to={typeDefinitionAnchorId} - offset={0} - duration={constants.DOCS_SCROLL_DURATION_MS} - containerId={constants.DOCS_CONTAINER_ID} - > - {_.isUndefined(typeDefinition) || utils.isUserOnMobile() ? ( - <span - onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)} - style={{ color: colors.lightBlueA700, cursor: 'pointer' }} - > - {typeName} - </span> - ) : ( - <span - data-tip={true} - data-for={id} - onClick={utils.setUrlHash.bind(null, typeDefinitionAnchorId)} - style={{ - color: colors.lightBlueA700, - cursor: 'pointer', - display: 'inline-block', - }} - > - {typeName} - <ReactTooltip type="light" effect="solid" id={id} className="typeTooltip"> - <TypeDefinition - sectionName={props.sectionName} - customType={typeDefinition} - shouldAddId={false} - docsInfo={props.docsInfo} - /> - </ReactTooltip> - </span> - )} - </ScrollLink> - ); - } - return ( - <span> - <span style={{ color: typeNameColor }}>{typeName}</span> - {isArray && '[]'} - {!_.isEmpty(typeArgs) && ( - <span> - {'<'} - {commaSeparatedTypeArgs} - {'>'} - </span> - )} - </span> - ); -} diff --git a/packages/website/ts/pages/documentation/type_definition.tsx b/packages/website/ts/pages/documentation/type_definition.tsx deleted file mode 100644 index 02bf63258..000000000 --- a/packages/website/ts/pages/documentation/type_definition.tsx +++ /dev/null @@ -1,127 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { Comment } from 'ts/pages/documentation/comment'; -import { CustomEnum } from 'ts/pages/documentation/custom_enum'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { Enum } from 'ts/pages/documentation/enum'; -import { Interface } from 'ts/pages/documentation/interface'; -import { MethodSignature } from 'ts/pages/documentation/method_signature'; -import { Type } from 'ts/pages/documentation/type'; -import { AnchorTitle } from 'ts/pages/shared/anchor_title'; -import { CustomType, CustomTypeChild, HeaderSizes, KindString, TypeDocTypes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { utils } from 'ts/utils/utils'; - -interface TypeDefinitionProps { - sectionName: string; - customType: CustomType; - shouldAddId?: boolean; - docsInfo: DocsInfo; -} - -interface TypeDefinitionState { - shouldShowAnchor: boolean; -} - -export class TypeDefinition extends React.Component<TypeDefinitionProps, TypeDefinitionState> { - public static defaultProps: Partial<TypeDefinitionProps> = { - shouldAddId: true, - }; - constructor(props: TypeDefinitionProps) { - super(props); - this.state = { - shouldShowAnchor: false, - }; - } - public render() { - const customType = this.props.customType; - if (!this.props.docsInfo.isPublicType(customType.name)) { - return null; // no-op - } - - let typePrefix: string; - let codeSnippet: React.ReactNode; - switch (customType.kindString) { - case KindString.Interface: - typePrefix = 'Interface'; - codeSnippet = ( - <Interface type={customType} sectionName={this.props.sectionName} docsInfo={this.props.docsInfo} /> - ); - break; - - case KindString.Variable: - typePrefix = 'Enum'; - codeSnippet = <CustomEnum type={customType} />; - break; - - case KindString.Enumeration: - typePrefix = 'Enum'; - const enumValues = _.map(customType.children, (c: CustomTypeChild) => { - return { - name: c.name, - defaultValue: c.defaultValue, - }; - }); - codeSnippet = <Enum values={enumValues} />; - break; - - case KindString.TypeAlias: - typePrefix = 'Type Alias'; - codeSnippet = ( - <span> - <span style={{ color: colors.lightPurple }}>type</span> {customType.name} ={' '} - {customType.type.typeDocType !== TypeDocTypes.Reflection ? ( - <Type - type={customType.type} - sectionName={this.props.sectionName} - docsInfo={this.props.docsInfo} - /> - ) : ( - <MethodSignature - method={customType.type.method} - sectionName={this.props.sectionName} - shouldHideMethodName={true} - shouldUseArrowSyntax={true} - docsInfo={this.props.docsInfo} - /> - )} - </span> - ); - break; - - default: - throw utils.spawnSwitchErr('type.kindString', customType.kindString); - } - - const typeDefinitionAnchorId = `${this.props.sectionName}-${customType.name}`; - return ( - <div - id={this.props.shouldAddId ? typeDefinitionAnchorId : ''} - className="pb2" - style={{ overflow: 'hidden', width: '100%' }} - onMouseOver={this._setAnchorVisibility.bind(this, true)} - onMouseOut={this._setAnchorVisibility.bind(this, false)} - > - <AnchorTitle - headerSize={HeaderSizes.H3} - title={`${typePrefix} ${customType.name}`} - id={this.props.shouldAddId ? typeDefinitionAnchorId : ''} - shouldShowAnchor={this.state.shouldShowAnchor} - /> - <div style={{ fontSize: 16 }}> - <pre> - <code className="hljs">{codeSnippet}</code> - </pre> - </div> - <div style={{ maxWidth: 620 }}> - {customType.comment && <Comment comment={customType.comment} className="py2" />} - </div> - </div> - ); - } - private _setAnchorVisibility(shouldShowAnchor: boolean) { - this.setState({ - shouldShowAnchor, - }); - } -} diff --git a/packages/website/ts/pages/faq/faq.tsx b/packages/website/ts/pages/faq/faq.tsx index 34175abdc..1be3c3565 100644 --- a/packages/website/ts/pages/faq/faq.tsx +++ b/packages/website/ts/pages/faq/faq.tsx @@ -1,3 +1,4 @@ +import { colors, Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import * as DocumentTitle from 'react-document-title'; @@ -5,8 +6,7 @@ import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Question } from 'ts/pages/faq/question'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { FAQQuestion, FAQSection, Styles, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { FAQQuestion, FAQSection, WebsitePaths } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; diff --git a/packages/website/ts/pages/faq/question.tsx b/packages/website/ts/pages/faq/question.tsx index 988c04bc9..240dae910 100644 --- a/packages/website/ts/pages/faq/question.tsx +++ b/packages/website/ts/pages/faq/question.tsx @@ -1,7 +1,7 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import { Card, CardHeader, CardText } from 'material-ui/Card'; import * as React from 'react'; -import { colors } from 'ts/utils/colors'; export interface QuestionProps { prompt: string; diff --git a/packages/website/ts/pages/landing/landing.tsx b/packages/website/ts/pages/landing/landing.tsx index 044f0b41f..6699e4e6f 100644 --- a/packages/website/ts/pages/landing/landing.tsx +++ b/packages/website/ts/pages/landing/landing.tsx @@ -1,3 +1,4 @@ +import { colors } from '@0xproject/react-shared'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; @@ -7,7 +8,6 @@ import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, Language, ScreenWidths, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/pages/not_found.tsx b/packages/website/ts/pages/not_found.tsx index ad37f6242..ff25a35e9 100644 --- a/packages/website/ts/pages/not_found.tsx +++ b/packages/website/ts/pages/not_found.tsx @@ -1,9 +1,9 @@ +import { Styles } from '@0xproject/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { Footer } from 'ts/components/footer'; import { TopBar } from 'ts/components/top_bar/top_bar'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { Styles } from 'ts/types'; import { Translate } from 'ts/utils/translate'; export interface NotFoundProps { diff --git a/packages/website/ts/pages/shared/anchor_title.tsx b/packages/website/ts/pages/shared/anchor_title.tsx deleted file mode 100644 index 0270618a0..000000000 --- a/packages/website/ts/pages/shared/anchor_title.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import * as React from 'react'; -import { Link as ScrollLink } from 'react-scroll'; -import { HeaderSizes, Styles } from 'ts/types'; -import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; - -const headerSizeToScrollOffset: { [headerSize: string]: number } = { - h2: -20, - h3: 0, -}; - -interface AnchorTitleProps { - title: string | React.ReactNode; - id: string; - headerSize: HeaderSizes; - shouldShowAnchor: boolean; -} - -interface AnchorTitleState { - isHovering: boolean; -} - -const styles: Styles = { - anchor: { - fontSize: 20, - transform: 'rotate(45deg)', - cursor: 'pointer', - }, - headers: { - WebkitMarginStart: 0, - WebkitMarginEnd: 0, - fontWeight: 'bold', - display: 'block', - }, - h1: { - fontSize: '1.8em', - }, - h2: { - fontSize: '1.5em', - fontWeight: 400, - }, - h3: { - fontSize: '1.17em', - }, -}; - -export class AnchorTitle extends React.Component<AnchorTitleProps, AnchorTitleState> { - constructor(props: AnchorTitleProps) { - super(props); - this.state = { - isHovering: false, - }; - } - public render() { - let opacity = 0; - if (this.props.shouldShowAnchor) { - opacity = this.state.isHovering ? 0.6 : 1; - } - return ( - <div className="relative flex" style={{ ...styles[this.props.headerSize], ...styles.headers }}> - <div className="inline-block" style={{ paddingRight: 4 }}> - {this.props.title} - </div> - <ScrollLink - to={this.props.id} - offset={headerSizeToScrollOffset[this.props.headerSize]} - duration={constants.DOCS_SCROLL_DURATION_MS} - containerId={constants.DOCS_CONTAINER_ID} - > - <i - className="zmdi zmdi-link" - onClick={utils.setUrlHash.bind(utils, this.props.id)} - style={{ ...styles.anchor, opacity }} - onMouseOver={this._setHoverState.bind(this, true)} - onMouseOut={this._setHoverState.bind(this, false)} - /> - </ScrollLink> - </div> - ); - } - private _setHoverState(isHovering: boolean) { - this.setState({ - isHovering, - }); - } -} diff --git a/packages/website/ts/pages/shared/markdown_code_block.tsx b/packages/website/ts/pages/shared/markdown_code_block.tsx deleted file mode 100644 index 6dfb74554..000000000 --- a/packages/website/ts/pages/shared/markdown_code_block.tsx +++ /dev/null @@ -1,25 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import * as HighLight from 'react-highlight'; - -interface MarkdownCodeBlockProps { - value: string; - language: string; -} - -interface MarkdownCodeBlockState {} - -export class MarkdownCodeBlock extends React.Component<MarkdownCodeBlockProps, MarkdownCodeBlockState> { - // Re-rendering a codeblock causes any use selection to become de-selected. This is annoying when trying - // to copy-paste code examples. We therefore noop re-renders on this component if it's props haven't changed. - public shouldComponentUpdate(nextProps: MarkdownCodeBlockProps, nextState: MarkdownCodeBlockState) { - return nextProps.value !== this.props.value || nextProps.language !== this.props.language; - } - public render() { - return ( - <span style={{ fontSize: 14 }}> - <HighLight className={this.props.language || 'javascript'}>{this.props.value}</HighLight> - </span> - ); - } -} diff --git a/packages/website/ts/pages/shared/markdown_link_block.tsx b/packages/website/ts/pages/shared/markdown_link_block.tsx deleted file mode 100644 index e4553c87f..000000000 --- a/packages/website/ts/pages/shared/markdown_link_block.tsx +++ /dev/null @@ -1,46 +0,0 @@ -import * as _ from 'lodash'; -import * as React from 'react'; -import { configs } from 'ts/utils/configs'; -import { utils } from 'ts/utils/utils'; - -interface MarkdownLinkBlockProps { - href: string; -} - -interface MarkdownLinkBlockState {} - -export class MarkdownLinkBlock extends React.Component<MarkdownLinkBlockProps, MarkdownLinkBlockState> { - // Re-rendering a linkBlock causes it to remain unclickable. - // We therefore noop re-renders on this component if it's props haven't changed. - public shouldComponentUpdate(nextProps: MarkdownLinkBlockProps, nextState: MarkdownLinkBlockState) { - return nextProps.href !== this.props.href; - } - public render() { - const href = this.props.href; - const isLinkToSection = _.startsWith(href, '#'); - // If protocol is http or https, we can open in a new tab, otherwise don't for security reasons - if (_.startsWith(href, 'http') || _.startsWith(href, 'https')) { - return ( - <a href={href} target="_blank" rel="nofollow noreferrer noopener"> - {this.props.children} - </a> - ); - } else if (isLinkToSection) { - return ( - <a - style={{ cursor: 'pointer', textDecoration: 'underline' }} - onClick={this._onHashUrlClick.bind(this, href)} - > - {this.props.children} - </a> - ); - } else { - return <a href={href}>{this.props.children}</a>; - } - } - private _onHashUrlClick(href: string) { - const hash = href.split('#')[1]; - utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); - utils.setUrlHash(hash); - } -} diff --git a/packages/website/ts/pages/shared/markdown_section.tsx b/packages/website/ts/pages/shared/markdown_section.tsx deleted file mode 100644 index 7253072d9..000000000 --- a/packages/website/ts/pages/shared/markdown_section.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import * as _ from 'lodash'; -import RaisedButton from 'material-ui/RaisedButton'; -import * as React from 'react'; -import * as ReactMarkdown from 'react-markdown'; -import { Element as ScrollElement } from 'react-scroll'; -import { AnchorTitle } from 'ts/pages/shared/anchor_title'; -import { MarkdownCodeBlock } from 'ts/pages/shared/markdown_code_block'; -import { MarkdownLinkBlock } from 'ts/pages/shared/markdown_link_block'; -import { HeaderSizes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { utils } from 'ts/utils/utils'; - -interface MarkdownSectionProps { - sectionName: string; - markdownContent: string; - headerSize?: HeaderSizes; - githubLink?: string; -} - -interface MarkdownSectionState { - shouldShowAnchor: boolean; -} - -export class MarkdownSection extends React.Component<MarkdownSectionProps, MarkdownSectionState> { - public static defaultProps: Partial<MarkdownSectionProps> = { - headerSize: HeaderSizes.H3, - }; - constructor(props: MarkdownSectionProps) { - super(props); - this.state = { - shouldShowAnchor: false, - }; - } - public render() { - const sectionName = this.props.sectionName; - const id = utils.getIdFromName(sectionName); - return ( - <div - className="md-px1 sm-px2 overflow-hidden" - onMouseOver={this._setAnchorVisibility.bind(this, true)} - onMouseOut={this._setAnchorVisibility.bind(this, false)} - > - <ScrollElement name={id}> - <div className="clearfix pt3"> - <div className="col lg-col-8 md-col-8 sm-col-12"> - <span style={{ textTransform: 'capitalize', color: colors.grey700 }}> - <AnchorTitle - headerSize={this.props.headerSize} - title={sectionName} - id={id} - shouldShowAnchor={this.state.shouldShowAnchor} - /> - </span> - </div> - <div className="col col-4 sm-hide xs-hide right-align pr3" style={{ height: 28 }}> - {!_.isUndefined(this.props.githubLink) && ( - <a - href={this.props.githubLink} - target="_blank" - style={{ color: colors.linkBlue, textDecoration: 'none', lineHeight: 2.1 }} - > - Edit on Github - </a> - )} - </div> - </div> - <hr style={{ border: `1px solid ${colors.lightestGrey}` }} /> - <ReactMarkdown - source={this.props.markdownContent} - escapeHtml={false} - renderers={{ - code: MarkdownCodeBlock, - link: MarkdownLinkBlock, - }} - /> - </ScrollElement> - </div> - ); - } - private _setAnchorVisibility(shouldShowAnchor: boolean) { - this.setState({ - shouldShowAnchor, - }); - } -} diff --git a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx b/packages/website/ts/pages/shared/nested_sidebar_menu.tsx deleted file mode 100644 index 82a40eb7e..000000000 --- a/packages/website/ts/pages/shared/nested_sidebar_menu.tsx +++ /dev/null @@ -1,177 +0,0 @@ -import * as _ from 'lodash'; -import MenuItem from 'material-ui/MenuItem'; -import * as React from 'react'; -import { Link as ScrollLink } from 'react-scroll'; -import { VersionDropDown } from 'ts/pages/shared/version_drop_down'; -import { MenuSubsectionsBySection, Styles } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { constants } from 'ts/utils/constants'; -import { utils } from 'ts/utils/utils'; - -interface NestedSidebarMenuProps { - topLevelMenu: { [topLevel: string]: string[] }; - menuSubsectionsBySection: MenuSubsectionsBySection; - title: string; - shouldDisplaySectionHeaders?: boolean; - onMenuItemClick?: () => void; - selectedVersion?: string; - versions?: string[]; -} - -interface NestedSidebarMenuState {} - -const styles: Styles = { - menuItemWithHeaders: { - minHeight: 0, - }, - menuItemWithoutHeaders: { - minHeight: 48, - }, - menuItemInnerDivWithHeaders: { - color: colors.grey800, - fontSize: 14, - lineHeight: 2, - padding: 0, - }, -}; - -const titleToIcon: { [title: string]: string } = { - '0x.js': 'zeroExJs.png', - '0x Connect': 'connect.png', - '0x Smart Contracts': 'contracts.png', - Wiki: 'wiki.png', -}; - -export class NestedSidebarMenu extends React.Component<NestedSidebarMenuProps, NestedSidebarMenuState> { - public static defaultProps: Partial<NestedSidebarMenuProps> = { - shouldDisplaySectionHeaders: true, - onMenuItemClick: _.noop, - }; - public render() { - const navigation = _.map(this.props.topLevelMenu, (menuItems: string[], sectionName: string) => { - const finalSectionName = sectionName.replace(/-/g, ' '); - if (this.props.shouldDisplaySectionHeaders) { - const id = utils.getIdFromName(sectionName); - return ( - <div key={`section-${sectionName}`} className="py1" style={{ color: colors.grey800 }}> - <div style={{ fontWeight: 'bold', fontSize: 15 }} className="py1"> - {finalSectionName.toUpperCase()} - </div> - {this._renderMenuItems(menuItems)} - </div> - ); - } else { - return <div key={`section-${sectionName}`}>{this._renderMenuItems(menuItems)}</div>; - } - }); - return ( - <div> - {this._renderEmblem()} - {!_.isUndefined(this.props.versions) && - !_.isUndefined(this.props.selectedVersion) && ( - <VersionDropDown selectedVersion={this.props.selectedVersion} versions={this.props.versions} /> - )} - <div className="pl1">{navigation}</div> - </div> - ); - } - private _renderEmblem() { - return ( - <div className="pt2 md-px1 sm-px2" style={{ color: colors.black, paddingBottom: 18 }}> - <div className="flex" style={{ fontSize: 25 }}> - <div className="robotoMono" style={{ fontWeight: 'bold' }}> - 0x - </div> - <div className="pl2" style={{ lineHeight: 1.4, fontWeight: 300 }}> - docs - </div> - </div> - <div className="pl1" style={{ color: colors.grey350, paddingBottom: 9, paddingLeft: 10, height: 17 }}> - | - </div> - <div className="flex"> - <div> - <img src={`/images/doc_icons/${titleToIcon[this.props.title]}`} width="22" /> - </div> - <div className="pl1" style={{ fontWeight: 600, fontSize: 20, lineHeight: 1.2 }}> - {this.props.title} - </div> - </div> - </div> - ); - } - private _renderMenuItems(menuItemNames: string[]): React.ReactNode[] { - const menuItemStyles = this.props.shouldDisplaySectionHeaders - ? styles.menuItemWithHeaders - : styles.menuItemWithoutHeaders; - const menuItemInnerDivStyles = this.props.shouldDisplaySectionHeaders ? styles.menuItemInnerDivWithHeaders : {}; - const menuItems = _.map(menuItemNames, menuItemName => { - const id = utils.getIdFromName(menuItemName); - return ( - <div key={menuItemName}> - <ScrollLink - key={`menuItem-${menuItemName}`} - to={id} - offset={-10} - duration={constants.DOCS_SCROLL_DURATION_MS} - containerId={constants.DOCS_CONTAINER_ID} - > - <MenuItem - onTouchTap={this._onMenuItemClick.bind(this, menuItemName)} - style={menuItemStyles} - innerDivStyle={menuItemInnerDivStyles} - > - <span style={{ textTransform: 'capitalize' }}>{menuItemName}</span> - </MenuItem> - </ScrollLink> - {this._renderMenuItemSubsections(menuItemName)} - </div> - ); - }); - return menuItems; - } - private _renderMenuItemSubsections(menuItemName: string): React.ReactNode { - if (_.isUndefined(this.props.menuSubsectionsBySection[menuItemName])) { - return null; - } - return this._renderMenuSubsectionsBySection(menuItemName, this.props.menuSubsectionsBySection[menuItemName]); - } - private _renderMenuSubsectionsBySection(menuItemName: string, entityNames: string[]): React.ReactNode { - return ( - <ul style={{ margin: 0, listStyleType: 'none', paddingLeft: 0 }} key={menuItemName}> - {_.map(entityNames, entityName => { - const name = `${menuItemName}-${entityName}`; - const id = utils.getIdFromName(name); - return ( - <li key={`menuItem-${entityName}`}> - <ScrollLink - to={id} - offset={0} - duration={constants.DOCS_SCROLL_DURATION_MS} - containerId={constants.DOCS_CONTAINER_ID} - onTouchTap={this._onMenuItemClick.bind(this, name)} - > - <MenuItem - onTouchTap={this._onMenuItemClick.bind(this, name)} - style={{ minHeight: 35 }} - innerDivStyle={{ - paddingLeft: 16, - fontSize: 14, - lineHeight: '35px', - }} - > - {entityName} - </MenuItem> - </ScrollLink> - </li> - ); - })} - </ul> - ); - } - private _onMenuItemClick(name: string): void { - const id = utils.getIdFromName(name); - utils.setUrlHash(id); - this.props.onMenuItemClick(); - } -} diff --git a/packages/website/ts/pages/shared/section_header.tsx b/packages/website/ts/pages/shared/section_header.tsx deleted file mode 100644 index 52a1f30d9..000000000 --- a/packages/website/ts/pages/shared/section_header.tsx +++ /dev/null @@ -1,63 +0,0 @@ -import * as React from 'react'; -import { Element as ScrollElement } from 'react-scroll'; -import { AnchorTitle } from 'ts/pages/shared/anchor_title'; -import { HeaderSizes } from 'ts/types'; -import { colors } from 'ts/utils/colors'; -import { utils } from 'ts/utils/utils'; - -interface SectionHeaderProps { - sectionName: string; - headerSize?: HeaderSizes; -} - -interface SectionHeaderState { - shouldShowAnchor: boolean; -} - -export class SectionHeader extends React.Component<SectionHeaderProps, SectionHeaderState> { - public static defaultProps: Partial<SectionHeaderProps> = { - headerSize: HeaderSizes.H2, - }; - constructor(props: SectionHeaderProps) { - super(props); - this.state = { - shouldShowAnchor: false, - }; - } - public render() { - const sectionName = this.props.sectionName.replace(/-/g, ' '); - const id = utils.getIdFromName(sectionName); - return ( - <div - onMouseOver={this._setAnchorVisibility.bind(this, true)} - onMouseOut={this._setAnchorVisibility.bind(this, false)} - > - <ScrollElement name={id}> - <AnchorTitle - headerSize={this.props.headerSize} - title={ - <span - style={{ - textTransform: 'uppercase', - color: colors.grey, - fontFamily: 'Roboto Mono', - fontWeight: 300, - fontSize: 27, - }} - > - {sectionName} - </span> - } - id={id} - shouldShowAnchor={this.state.shouldShowAnchor} - /> - </ScrollElement> - </div> - ); - } - private _setAnchorVisibility(shouldShowAnchor: boolean) { - this.setState({ - shouldShowAnchor, - }); - } -} diff --git a/packages/website/ts/pages/shared/version_drop_down.tsx b/packages/website/ts/pages/shared/version_drop_down.tsx deleted file mode 100644 index 1b4dbb375..000000000 --- a/packages/website/ts/pages/shared/version_drop_down.tsx +++ /dev/null @@ -1,45 +0,0 @@ -import * as _ from 'lodash'; -import DropDownMenu from 'material-ui/DropDownMenu'; -import MenuItem from 'material-ui/MenuItem'; -import * as React from 'react'; -import { utils } from 'ts/utils/utils'; - -interface VersionDropDownProps { - selectedVersion: string; - versions: string[]; -} - -interface VersionDropDownState {} - -export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> { - public render() { - return ( - <div className="mx-auto" style={{ width: 120 }}> - <DropDownMenu - maxHeight={300} - value={this.props.selectedVersion} - onChange={this._updateSelectedVersion.bind(this)} - > - {this._renderDropDownItems()} - </DropDownMenu> - </div> - ); - } - private _renderDropDownItems() { - const items = _.map(this.props.versions, version => { - return <MenuItem key={version} value={version} primaryText={`v${version}`} />; - }); - return items; - } - private _updateSelectedVersion(e: any, index: number, semver: string) { - let path = window.location.pathname; - const lastChar = path[path.length - 1]; - if (_.isFinite(_.parseInt(lastChar))) { - const pathSections = path.split('/'); - pathSections.pop(); - path = pathSections.join('/'); - } - const baseUrl = utils.getCurrentBaseUrl(); - window.location.href = `${baseUrl}${path}/${semver}${window.location.hash}`; - } -} diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx index 4bb6052a2..f6cff51e4 100644 --- a/packages/website/ts/pages/wiki/wiki.tsx +++ b/packages/website/ts/pages/wiki/wiki.tsx @@ -1,16 +1,23 @@ +import { + colors, + constants as sharedConstants, + HeaderSizes, + MarkdownSection, + NestedSidebarMenu, + SectionHeader, + Styles, + utils as sharedUtils, +} from '@0xproject/react-shared'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; import DocumentTitle = require('react-document-title'); import { scroller } from 'react-scroll'; +import { SidebarHeader } from 'ts/components/sidebar_header'; import { TopBar } from 'ts/components/top_bar/top_bar'; -import { MarkdownSection } from 'ts/pages/shared/markdown_section'; -import { NestedSidebarMenu } from 'ts/pages/shared/nested_sidebar_menu'; -import { SectionHeader } from 'ts/pages/shared/section_header'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { Article, ArticlesBySection, HeaderSizes, Styles, WebsitePaths } from 'ts/types'; -import { colors } from 'ts/utils/colors'; +import { Article, ArticlesBySection, WebsitePaths } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; @@ -60,6 +67,9 @@ export class Wiki extends React.Component<WikiProps, WikiState> { isHoveringSidebar: false, }; } + public componentDidMount() { + window.addEventListener('hashchange', this._onHashChanged.bind(this), false); + } public componentWillMount() { // tslint:disable-next-line:no-floating-promises this._fetchArticlesBySectionAsync(); @@ -67,6 +77,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { public componentWillUnmount() { this._isUnmounted = true; clearTimeout(this._wikiBackoffTimeoutId); + window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); } public render() { const menuSubsectionsBySection = _.isUndefined(this.state.articlesBySection) @@ -122,7 +133,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { <NestedSidebarMenu topLevelMenu={menuSubsectionsBySection} menuSubsectionsBySection={menuSubsectionsBySection} - title="Wiki" + sidebarHeader={<SidebarHeader title="Wiki" />} /> </div> </div> @@ -135,11 +146,11 @@ export class Wiki extends React.Component<WikiProps, WikiState> { }} > <div - id={configs.SCROLL_CONTAINER_ID} + id={sharedConstants.SCROLL_CONTAINER_ID} style={{ ...mainContainersStyle, overflow: 'auto' }} className="absolute" > - <div id={configs.SCROLL_TOP_ID} /> + <div id={sharedConstants.SCROLL_TOP_ID} /> <div id="wiki" style={{ paddingRight: 2 }}> {this._renderWikiArticles()} </div> @@ -214,7 +225,7 @@ export class Wiki extends React.Component<WikiProps, WikiState> { async () => { await utils.onPageLoadAsync(); const hash = this.props.location.hash.slice(1); - utils.scrollToHash(hash, configs.SCROLL_CONTAINER_ID); + sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); }, ); } @@ -239,4 +250,8 @@ export class Wiki extends React.Component<WikiProps, WikiState> { isHoveringSidebar: false, }); } + private _onHashChanged(event: any) { + const hash = window.location.hash.slice(1); + sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); + } } diff --git a/packages/website/ts/types.ts b/packages/website/ts/types.ts index 28663270e..41fbc6a86 100644 --- a/packages/website/ts/types.ts +++ b/packages/website/ts/types.ts @@ -156,10 +156,6 @@ export interface TrackedTokensByUserAddress { [userAddress: string]: TrackedTokensByNetworkId; } -export interface Styles { - [name: string]: React.CSSProperties; -} - export interface ProfileInfo { name: string; title?: string; @@ -229,11 +225,6 @@ export enum AlertTypes { SUCCESS, } -export enum EtherscanLinkSuffixes { - Address = 'address', - Tx = 'tx', -} - export enum BlockchainErrs { AContractNotDeployedOnNetwork = 'A_CONTRACT_NOT_DEPLOYED_ON_NETWORK', DisconnectedFromEthereumNode = 'DISCONNECTED_FROM_ETHEREUM_NODE', @@ -247,24 +238,6 @@ export enum BlockchainCallErrs { TokenAddressIsInvalid = 'TOKEN_ADDRESS_IS_INVALID', } -// Exception: We don't make the values uppercase because these KindString's need to -// match up those returned by TypeDoc -export enum KindString { - Constructor = 'Constructor', - Property = 'Property', - Method = 'Method', - Interface = 'Interface', - TypeAlias = 'Type alias', - Variable = 'Variable', - Function = 'Function', - Enumeration = 'Enumeration', -} - -export interface EnumValue { - name: string; - defaultValue?: string; -} - export enum Environments { DEVELOPMENT, PRODUCTION, @@ -272,170 +245,6 @@ export enum Environments { export type ContractInstance = any; // TODO: add type definition for Contract -export interface TypeDocType { - type: TypeDocTypes; - value: string; - name: string; - types: TypeDocType[]; - typeArguments?: TypeDocType[]; - declaration: TypeDocNode; - elementType?: TypeDocType; -} - -export interface TypeDocFlags { - isStatic?: boolean; - isOptional?: boolean; - isPublic?: boolean; -} - -export interface TypeDocGroup { - title: string; - children: number[]; -} - -export interface TypeDocNode { - id?: number; - name?: string; - kind?: string; - defaultValue?: string; - kindString?: string; - type?: TypeDocType; - fileName?: string; - line?: number; - comment?: TypeDocNode; - text?: string; - shortText?: string; - returns?: string; - declaration: TypeDocNode; - flags?: TypeDocFlags; - indexSignature?: TypeDocNode | TypeDocNode[]; // TypeDocNode in TypeDoc <V0.9.0, TypeDocNode[] in >V0.9.0 - signatures?: TypeDocNode[]; - parameters?: TypeDocNode[]; - typeParameter?: TypeDocNode[]; - sources?: TypeDocNode[]; - children?: TypeDocNode[]; - groups?: TypeDocGroup[]; -} - -export enum TypeDocTypes { - Intrinsic = 'intrinsic', - Reference = 'reference', - Array = 'array', - StringLiteral = 'stringLiteral', - Reflection = 'reflection', - Union = 'union', - TypeParameter = 'typeParameter', - Intersection = 'intersection', - Unknown = 'unknown', -} - -export interface DocAgnosticFormat { - [sectionName: string]: DocSection; -} - -export interface DocSection { - comment: string; - constructors: Array<TypescriptMethod | SolidityMethod>; - methods: Array<TypescriptMethod | SolidityMethod>; - properties: Property[]; - types: CustomType[]; - events?: Event[]; -} - -export interface Event { - name: string; - eventArgs: EventArg[]; -} - -export interface EventArg { - isIndexed: boolean; - name: string; - type: Type; -} - -export interface Property { - name: string; - type: Type; - source?: Source; - comment?: string; -} - -export interface BaseMethod { - isConstructor: boolean; - name: string; - returnComment?: string | undefined; - callPath: string; - parameters: Parameter[]; - returnType: Type; - comment?: string; -} - -export interface TypescriptMethod extends BaseMethod { - source?: Source; - isStatic?: boolean; - typeParameter?: TypeParameter; -} - -export interface SolidityMethod extends BaseMethod { - isConstant?: boolean; - isPayable?: boolean; -} - -export interface Source { - fileName: string; - line: number; -} - -export interface Parameter { - name: string; - comment: string; - isOptional: boolean; - type: Type; -} - -export interface TypeParameter { - name: string; - type: Type; -} - -export interface Type { - name: string; - typeDocType: TypeDocTypes; - value?: string; - typeArguments?: Type[]; - elementType?: ElementType; - types?: Type[]; - method?: TypescriptMethod; -} - -export interface ElementType { - name: string; - typeDocType: TypeDocTypes; -} - -export interface IndexSignature { - keyName: string; - keyType: Type; - valueName: string; -} - -export interface CustomType { - name: string; - kindString: string; - type?: Type; - method?: TypescriptMethod; - indexSignature?: IndexSignature; - defaultValue?: string; - comment?: string; - children?: CustomTypeChild[]; -} - -export interface CustomTypeChild { - name: string; - type?: Type; - defaultValue?: string; -} - export interface FAQQuestion { prompt: string; answer: React.ReactNode; @@ -451,10 +260,6 @@ export interface S3FileObject { }; } -export interface MenuSubsectionsBySection { - [section: string]: string[]; -} - export enum ProviderType { Injected = 'INJECTED', Ledger = 'LEDGER', @@ -508,10 +313,6 @@ export interface BlogPost { url: string; } -export interface TypeDefinitionByName { - [typeName: string]: CustomType; -} - export interface Article { section: string; title: string; @@ -535,46 +336,6 @@ export enum TokenVisibility { TRACKED = 'TRACKED', } -export enum HeaderSizes { - H1 = 'h1', - H2 = 'h2', - H3 = 'h3', -} - -export interface DoxityDocObj { - [contractName: string]: DoxityContractObj; -} - -export interface DoxityContractObj { - title: string; - fileName: string; - name: string; - abiDocs: DoxityAbiDoc[]; -} - -export interface DoxityAbiDoc { - constant: boolean; - inputs: DoxityInput[]; - name: string; - outputs: DoxityOutput[]; - payable: boolean; - type: string; - details?: string; - return?: string; -} - -export interface DoxityOutput { - name: string; - type: string; -} - -export interface DoxityInput { - name: string; - type: string; - description: string; - indexed?: boolean; -} - export interface VersionToFileName { [version: string]: string; } @@ -584,29 +345,6 @@ export enum Docs { SmartContracts, } -export interface ContractAddresses { - [version: string]: { - [network: string]: AddressByContractName; - }; -} - -export interface AddressByContractName { - [contractName: string]: string; -} - -export enum Networks { - Mainnet = 'Mainnet', - Kovan = 'Kovan', - Ropsten = 'Ropsten', - Rinkeby = 'Rinkeby', -} - -export enum AbiTypes { - Constructor = 'constructor', - Function = 'function', - Event = 'event', -} - export enum WebsitePaths { Portal = '/portal', Wiki = '/wiki', @@ -619,49 +357,12 @@ export enum WebsitePaths { Connect = '/docs/connect', } -export interface DocsMenu { - [sectionName: string]: string[]; -} - -export interface SectionsMap { - [sectionName: string]: string; -} - export enum DocPackages { Connect = 'CONNECT', ZeroExJs = 'ZERO_EX_JS', SmartContracts = 'SMART_CONTRACTS', } -export enum SupportedDocJson { - Doxity = 'DOXITY', - TypeDoc = 'TYPEDOC', -} - -export interface ContractsByVersionByNetworkId { - [version: string]: { - [networkName: string]: { - [contractName: string]: string; - }; - }; -} - -export interface DocsInfoConfig { - id: string; - type: SupportedDocJson; - displayName: string; - packageUrl: string; - menu: DocsMenu; - sections: SectionsMap; - sectionNameToMarkdown: { [sectionName: string]: string }; - visibleConstructors: string[]; - subPackageName?: string; - publicTypes?: string[]; - sectionNameToModulePath?: { [sectionName: string]: string[] }; - menuSubsectionToVersionWhenIntroduced?: { [sectionName: string]: string }; - contractsByVersionByNetworkId?: ContractsByVersionByNetworkId; -} - export interface TimestampMsRange { startTimestampMs: number; endTimestampMs: number; diff --git a/packages/website/ts/utils/colors.ts b/packages/website/ts/utils/colors.ts deleted file mode 100644 index 2eead95c7..000000000 --- a/packages/website/ts/utils/colors.ts +++ /dev/null @@ -1,48 +0,0 @@ -import { colors as materialUiColors } from 'material-ui/styles'; - -export const colors = { - ...materialUiColors, - gray40: '#F8F8F8', - grey50: '#FAFAFA', - grey100: '#F5F5F5', - lightestGrey: '#F0F0F0', - greyishPink: '#E6E5E5', - grey300: '#E0E0E0', - beigeWhite: '#E4E4E4', - grey350: '#cacaca', - grey400: '#BDBDBD', - lightGrey: '#BBBBBB', - grey500: '#9E9E9E', - grey: '#A5A5A5', - darkGrey: '#818181', - landingLinkGrey: '#919191', - grey700: '#616161', - grey750: '#515151', - grey800: '#424242', - darkerGrey: '#393939', - heroGrey: '#404040', - projectsGrey: '#343333', - darkestGrey: '#272727', - dharmaDarkGrey: '#252525', - lightBlue: '#60A4F4', - lightBlueA700: '#0091EA', - linkBlue: '#1D5CDE', - darkBlue: '#4D5481', - turquois: '#058789', - lightPurple: '#A81CA6', - purple: '#690596', - red200: '#EF9A9A', - red: '#E91751', - red500: '#F44336', - red600: '#E53935', - limeGreen: '#66DE75', - lightGreen: '#4DC55C', - lightestGreen: '#89C774', - brightGreen: '#00C33E', - green400: '#66BB6A', - green: '#4DA24B', - amber600: '#FFB300', - orange: '#E69D00', - amber800: '#FF8F00', - darkYellow: '#caca03', -}; diff --git a/packages/website/ts/utils/configs.ts b/packages/website/ts/utils/configs.ts index 388fc8530..f33b06c0a 100644 --- a/packages/website/ts/utils/configs.ts +++ b/packages/website/ts/utils/configs.ts @@ -1,5 +1,5 @@ import * as _ from 'lodash'; -import { ContractAddresses, Environments, OutdatedWrappedEtherByNetworkId, PublicNodeUrlsByNetworkId } from 'ts/types'; +import { Environments, OutdatedWrappedEtherByNetworkId, PublicNodeUrlsByNetworkId } from 'ts/types'; const BASE_URL = window.location.origin; const isDevelopment = _.includes( @@ -94,8 +94,6 @@ export const configs = { [3]: [`https://ropsten.infura.io/${INFURA_API_KEY}`], [4]: [`https://rinkeby.infura.io/${INFURA_API_KEY}`], } as PublicNodeUrlsByNetworkId, - SCROLL_CONTAINER_ID: 'documentation', - SCROLL_TOP_ID: 'pageScrollTop', SHOULD_DEPRECATE_OLD_WETH_TOKEN: true, SYMBOLS_OF_MINTABLE_KOVAN_TOKENS: ['MKR', 'MLN', 'GNT', 'DGD', 'REP'], SYMBOLS_OF_MINTABLE_RINKEBY_ROPSTEN_TOKENS: [ diff --git a/packages/website/ts/utils/constants.ts b/packages/website/ts/utils/constants.ts index 3476b7375..71fe08abe 100644 --- a/packages/website/ts/utils/constants.ts +++ b/packages/website/ts/utils/constants.ts @@ -1,11 +1,9 @@ +import { Networks } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; -import { Networks } from 'ts/types'; export const constants = { DECIMAL_PLACES_ETH: 18, DECIMAL_PLACES_ZRX: 18, - DOCS_SCROLL_DURATION_MS: 0, - DOCS_CONTAINER_ID: 'documentation', GENESIS_ORDER_BLOCK_BY_NETWORK_ID: { 1: 4145578, 42: 3117574, @@ -23,18 +21,6 @@ export const constants = { NETWORK_ID_MAINNET: 1, NETWORK_ID_KOVAN: 42, NETWORK_ID_TESTRPC: 50, - NETWORK_NAME_BY_ID: { - 1: Networks.Mainnet, - 3: Networks.Ropsten, - 4: Networks.Rinkeby, - 42: Networks.Kovan, - } as { [symbol: number]: string }, - NETWORK_ID_BY_NAME: { - [Networks.Mainnet]: 1, - [Networks.Ropsten]: 3, - [Networks.Rinkeby]: 4, - [Networks.Kovan]: 42, - } as { [networkName: string]: number }, NULL_ADDRESS: '0x0000000000000000000000000000000000000000', PROVIDER_NAME_LEDGER: 'Ledger', PROVIDER_NAME_METAMASK: 'Metamask', @@ -47,7 +33,6 @@ export const constants = { UNAVAILABLE_STATUS: 503, TAKER_FEE: new BigNumber(0), TESTNET_NAME: 'Kovan', - TYPES_SECTION_NAME: 'types', PROJECT_URL_ETHFINEX: 'https://www.bitfinex.com/ethfinex', PROJECT_URL_AMADEUS: 'http://amadeusrelay.org', PROJECT_URL_DDEX: 'https://ddex.io', @@ -72,7 +57,6 @@ export const constants = { PROJECT_URL_OPEN_ANX: 'https://www.openanx.org', PROJECT_URL_IDT: 'https://kinalpha.com', URL_ANGELLIST: 'https://angel.co/0xproject/jobs', - URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js', URL_BITLY_API: 'https://api-ssl.bitly.com', URL_BLOG: 'https://blog.0xproject.com/latest', URL_DISCOURSE_FORUM: 'https://forum.0xproject.com', @@ -87,11 +71,12 @@ export const constants = { URL_REDDIT: 'https://reddit.com/r/0xproject', URL_STANDARD_RELAYER_API_GITHUB: 'https://github.com/0xProject/standard-relayer-api/blob/master/README.md', URL_TWITTER: 'https://twitter.com/0xproject', + URL_WETH_IO: 'https://weth.io/', + URL_ZEROEX_CHAT: 'https://chat.0xproject.com', URL_WEB3_DOCS: 'https://github.com/ethereum/wiki/wiki/JavaScript-API', URL_WEB3_DECODED_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L123', URL_WEB3_LOG_ENTRY_EVENT: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L127', URL_WEB3_PROVIDER_DOCS: 'https://github.com/0xProject/web3-typescript-typings/blob/f5bcb96/index.d.ts#L150', - URL_WETH_IO: 'https://weth.io/', - URL_ZEROEX_CHAT: 'https://chat.0xproject.com', + URL_BIGNUMBERJS_GITHUB: 'http://mikemcl.github.io/bignumber.js', }; diff --git a/packages/website/ts/utils/doc_utils.ts b/packages/website/ts/utils/doc_utils.ts index 1f5f75ee2..0686e3e7f 100644 --- a/packages/website/ts/utils/doc_utils.ts +++ b/packages/website/ts/utils/doc_utils.ts @@ -1,6 +1,7 @@ +import { DoxityDocObj, TypeDocNode } from '@0xproject/react-docs'; import findVersions = require('find-versions'); import * as _ from 'lodash'; -import { DoxityDocObj, S3FileObject, TypeDocNode, VersionToFileName } from 'ts/types'; +import { S3FileObject, VersionToFileName } from 'ts/types'; import { utils } from 'ts/utils/utils'; import convert = require('xml-js'); diff --git a/packages/website/ts/utils/doxity_utils.ts b/packages/website/ts/utils/doxity_utils.ts deleted file mode 100644 index 35ce05672..000000000 --- a/packages/website/ts/utils/doxity_utils.ts +++ /dev/null @@ -1,174 +0,0 @@ -import * as _ from 'lodash'; -import { - AbiTypes, - DocAgnosticFormat, - DocSection, - DoxityAbiDoc, - DoxityContractObj, - DoxityDocObj, - DoxityInput, - EventArg, - Parameter, - Property, - SolidityMethod, - Type, - TypeDocTypes, -} from 'ts/types'; - -export const doxityUtils = { - convertToDocAgnosticFormat(doxityDocObj: DoxityDocObj): DocAgnosticFormat { - const docAgnosticFormat: DocAgnosticFormat = {}; - _.each(doxityDocObj, (doxityContractObj: DoxityContractObj, contractName: string) => { - const doxityConstructor = _.find(doxityContractObj.abiDocs, (abiDoc: DoxityAbiDoc) => { - return abiDoc.type === AbiTypes.Constructor; - }); - const constructors = []; - if (!_.isUndefined(doxityConstructor)) { - const constructor = { - isConstructor: true, - name: doxityContractObj.name, - comment: doxityConstructor.details, - returnComment: doxityConstructor.return, - callPath: '', - parameters: this._convertParameters(doxityConstructor.inputs), - returnType: this._convertType(doxityContractObj.name), - }; - constructors.push(constructor); - } - - const doxityMethods: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>( - doxityContractObj.abiDocs, - (abiDoc: DoxityAbiDoc) => { - return this._isMethod(abiDoc); - }, - ); - const methods: SolidityMethod[] = _.map<DoxityAbiDoc, SolidityMethod>( - doxityMethods, - (doxityMethod: DoxityAbiDoc) => { - const outputs = !_.isUndefined(doxityMethod.outputs) ? doxityMethod.outputs : []; - let returnTypeIfExists: Type; - if (outputs.length === 0) { - // no-op. It's already undefined - } else if (outputs.length === 1) { - const outputsType = outputs[0].type; - returnTypeIfExists = this._convertType(outputsType); - } else { - const outputsType = `[${_.map(outputs, output => output.type).join(', ')}]`; - returnTypeIfExists = this._convertType(outputsType); - } - // For ZRXToken, we want to convert it to zrxToken, rather then simply zRXToken - const callPath = - contractName !== 'ZRXToken' - ? `${contractName[0].toLowerCase()}${contractName.slice(1)}.` - : `${contractName.slice(0, 3).toLowerCase()}${contractName.slice(3)}.`; - const method = { - isConstructor: false, - isConstant: doxityMethod.constant, - isPayable: doxityMethod.payable, - name: doxityMethod.name, - comment: doxityMethod.details, - returnComment: doxityMethod.return, - callPath, - parameters: this._convertParameters(doxityMethod.inputs), - returnType: returnTypeIfExists, - }; - return method; - }, - ); - - const doxityProperties: DoxityAbiDoc[] = _.filter<DoxityAbiDoc>( - doxityContractObj.abiDocs, - (abiDoc: DoxityAbiDoc) => { - return this._isProperty(abiDoc); - }, - ); - const properties = _.map<DoxityAbiDoc, Property>(doxityProperties, (doxityProperty: DoxityAbiDoc) => { - // We assume that none of our functions return more then a single return value - let typeName = doxityProperty.outputs[0].type; - if (!_.isEmpty(doxityProperty.inputs)) { - // Properties never have more then a single input - typeName = `(${doxityProperty.inputs[0].type} => ${typeName})`; - } - const property = { - name: doxityProperty.name, - type: this._convertType(typeName), - comment: doxityProperty.details, - }; - return property; - }); - - const doxityEvents = _.filter( - doxityContractObj.abiDocs, - (abiDoc: DoxityAbiDoc) => abiDoc.type === AbiTypes.Event, - ); - const events = _.map(doxityEvents, doxityEvent => { - const event = { - name: doxityEvent.name, - eventArgs: this._convertEventArgs(doxityEvent.inputs), - }; - return event; - }); - - const docSection: DocSection = { - comment: doxityContractObj.title, - constructors, - methods, - properties, - types: [], - events, - }; - docAgnosticFormat[contractName] = docSection; - }); - return docAgnosticFormat; - }, - _convertParameters(inputs: DoxityInput[]): Parameter[] { - const parameters = _.map(inputs, input => { - const parameter = { - name: input.name, - comment: input.description, - isOptional: false, - type: this._convertType(input.type), - }; - return parameter; - }); - return parameters; - }, - _convertType(typeName: string): Type { - const type = { - name: typeName, - typeDocType: TypeDocTypes.Intrinsic, - }; - return type; - }, - _isMethod(abiDoc: DoxityAbiDoc) { - if (abiDoc.type !== AbiTypes.Function) { - return false; - } - const hasInputs = !_.isEmpty(abiDoc.inputs); - const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name); - const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase(); - const isMethod = hasNamedOutputIfExists && !isNameAllCaps; - return isMethod; - }, - _isProperty(abiDoc: DoxityAbiDoc) { - if (abiDoc.type !== AbiTypes.Function) { - return false; - } - const hasInputs = !_.isEmpty(abiDoc.inputs); - const hasNamedOutputIfExists = !hasInputs || !_.isEmpty(abiDoc.inputs[0].name); - const isNameAllCaps = abiDoc.name === abiDoc.name.toUpperCase(); - const isProperty = !hasNamedOutputIfExists || isNameAllCaps; - return isProperty; - }, - _convertEventArgs(inputs: DoxityInput[]): EventArg[] { - const eventArgs = _.map(inputs, input => { - const eventArg = { - isIndexed: input.indexed, - name: input.name, - type: this._convertType(input.type), - }; - return eventArg; - }); - return eventArgs; - }, -}; diff --git a/packages/website/ts/utils/mui_theme.ts b/packages/website/ts/utils/mui_theme.ts index 32891baca..41bc2844b 100644 --- a/packages/website/ts/utils/mui_theme.ts +++ b/packages/website/ts/utils/mui_theme.ts @@ -1,5 +1,5 @@ +import { colors } from '@0xproject/react-shared'; import { getMuiTheme } from 'material-ui/styles'; -import { colors } from 'ts/utils/colors'; export const muiTheme = getMuiTheme({ appBar: { diff --git a/packages/website/ts/utils/typedoc_utils.ts b/packages/website/ts/utils/typedoc_utils.ts deleted file mode 100644 index ce7df4dbb..000000000 --- a/packages/website/ts/utils/typedoc_utils.ts +++ /dev/null @@ -1,369 +0,0 @@ -import * as _ from 'lodash'; -import { DocsInfo } from 'ts/pages/documentation/docs_info'; -import { - CustomType, - CustomTypeChild, - DocAgnosticFormat, - DocPackages, - DocSection, - IndexSignature, - KindString, - Parameter, - Property, - SectionsMap, - Type, - TypeDocNode, - TypeDocType, - TypeParameter, - TypescriptMethod, -} from 'ts/types'; -import { utils } from 'ts/utils/utils'; - -export const typeDocUtils = { - isType(entity: TypeDocNode): boolean { - return ( - entity.kindString === KindString.Interface || - entity.kindString === KindString.Function || - entity.kindString === KindString.TypeAlias || - entity.kindString === KindString.Variable || - entity.kindString === KindString.Enumeration - ); - }, - isMethod(entity: TypeDocNode): boolean { - return entity.kindString === KindString.Method; - }, - isConstructor(entity: TypeDocNode): boolean { - return entity.kindString === KindString.Constructor; - }, - isProperty(entity: TypeDocNode): boolean { - return entity.kindString === KindString.Property; - }, - isPrivateOrProtectedProperty(propertyName: string): boolean { - return _.startsWith(propertyName, '_'); - }, - getModuleDefinitionsBySectionName(versionDocObj: TypeDocNode, configModulePaths: string[]): TypeDocNode[] { - const moduleDefinitions: TypeDocNode[] = []; - const jsonModules = versionDocObj.children; - _.each(jsonModules, jsonMod => { - _.each(configModulePaths, configModulePath => { - if (_.includes(configModulePath, jsonMod.name)) { - moduleDefinitions.push(jsonMod); - } - }); - }); - return moduleDefinitions; - }, - convertToDocAgnosticFormat(typeDocJson: TypeDocNode, docsInfo: DocsInfo): DocAgnosticFormat { - const subMenus = _.values(docsInfo.getMenu()); - const orderedSectionNames = _.flatten(subMenus); - const docAgnosticFormat: DocAgnosticFormat = {}; - _.each(orderedSectionNames, sectionName => { - const modulePathsIfExists = docsInfo.getModulePathsIfExists(sectionName); - if (_.isUndefined(modulePathsIfExists)) { - return; // no-op - } - const packageDefinitions = typeDocUtils.getModuleDefinitionsBySectionName(typeDocJson, modulePathsIfExists); - let packageDefinitionWithMergedChildren; - if (_.isEmpty(packageDefinitions)) { - return; // no-op - } else if (packageDefinitions.length === 1) { - packageDefinitionWithMergedChildren = packageDefinitions[0]; - } else { - // HACK: For now, if there are two modules to display in a single section, - // we simply concat the children. This works for our limited use-case where - // we want to display types stored in two files under a single section - packageDefinitionWithMergedChildren = packageDefinitions[0]; - for (let i = 1; i < packageDefinitions.length; i++) { - packageDefinitionWithMergedChildren.children = [ - ...packageDefinitionWithMergedChildren.children, - ...packageDefinitions[i].children, - ]; - } - } - - // Since the `types.ts` file is the only file that does not export a module/class but - // instead has each type export itself, we do not need to go down two levels of nesting - // for it. - let entities; - let packageComment = ''; - if (sectionName === docsInfo.sections.types) { - entities = packageDefinitionWithMergedChildren.children; - } else { - entities = packageDefinitionWithMergedChildren.children[0].children; - const commentObj = packageDefinitionWithMergedChildren.children[0].comment; - packageComment = !_.isUndefined(commentObj) ? commentObj.shortText : packageComment; - } - - const docSection = typeDocUtils._convertEntitiesToDocSection(entities, docsInfo, sectionName); - docSection.comment = packageComment; - docAgnosticFormat[sectionName] = docSection; - }); - return docAgnosticFormat; - }, - _convertEntitiesToDocSection(entities: TypeDocNode[], docsInfo: DocsInfo, sectionName: string) { - const docSection: DocSection = { - comment: '', - constructors: [], - methods: [], - properties: [], - types: [], - }; - - let isConstructor; - _.each(entities, entity => { - switch (entity.kindString) { - case KindString.Constructor: - isConstructor = true; - const constructor = typeDocUtils._convertMethod( - entity, - isConstructor, - docsInfo.sections, - sectionName, - docsInfo.id, - ); - docSection.constructors.push(constructor); - break; - - case KindString.Method: - if (entity.flags.isPublic) { - isConstructor = false; - const method = typeDocUtils._convertMethod( - entity, - isConstructor, - docsInfo.sections, - sectionName, - docsInfo.id, - ); - docSection.methods.push(method); - } - break; - - case KindString.Property: - if (!typeDocUtils.isPrivateOrProtectedProperty(entity.name)) { - const property = typeDocUtils._convertProperty( - entity, - docsInfo.sections, - sectionName, - docsInfo.id, - ); - docSection.properties.push(property); - } - break; - - case KindString.Interface: - case KindString.Function: - case KindString.Variable: - case KindString.Enumeration: - case KindString.TypeAlias: - if (docsInfo.isPublicType(entity.name)) { - const customType = typeDocUtils._convertCustomType( - entity, - docsInfo.sections, - sectionName, - docsInfo.id, - ); - docSection.types.push(customType); - } - break; - - default: - throw utils.spawnSwitchErr('kindString', entity.kindString); - } - }); - return docSection; - }, - _convertCustomType(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): CustomType { - const typeIfExists = !_.isUndefined(entity.type) - ? typeDocUtils._convertType(entity.type, sections, sectionName, docId) - : undefined; - const isConstructor = false; - const methodIfExists = !_.isUndefined(entity.declaration) - ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId) - : undefined; - const doesIndexSignatureExist = !_.isUndefined(entity.indexSignature); - const isIndexSignatureArray = _.isArray(entity.indexSignature); - // HACK: TypeDoc Versions <0.9.0 indexSignature is of type TypeDocNode[] - // Versions >0.9.0 have it as type TypeDocNode - const indexSignature = - doesIndexSignatureExist && isIndexSignatureArray - ? (entity.indexSignature as TypeDocNode[])[0] - : (entity.indexSignature as TypeDocNode); - const indexSignatureIfExists = doesIndexSignatureExist - ? typeDocUtils._convertIndexSignature(indexSignature, sections, sectionName, docId) - : undefined; - const commentIfExists = - !_.isUndefined(entity.comment) && !_.isUndefined(entity.comment.shortText) - ? entity.comment.shortText - : undefined; - - const childrenIfExist = !_.isUndefined(entity.children) - ? _.map(entity.children, (child: TypeDocNode) => { - const childTypeIfExists = !_.isUndefined(child.type) - ? typeDocUtils._convertType(child.type, sections, sectionName, docId) - : undefined; - const c: CustomTypeChild = { - name: child.name, - type: childTypeIfExists, - defaultValue: child.defaultValue, - }; - return c; - }) - : undefined; - - const customType = { - name: entity.name, - kindString: entity.kindString, - type: typeIfExists, - method: methodIfExists, - indexSignature: indexSignatureIfExists, - defaultValue: entity.defaultValue, - comment: commentIfExists, - children: childrenIfExist, - }; - return customType; - }, - _convertIndexSignature( - entity: TypeDocNode, - sections: SectionsMap, - sectionName: string, - docId: string, - ): IndexSignature { - const key = entity.parameters[0]; - const indexSignature = { - keyName: key.name, - keyType: typeDocUtils._convertType(key.type, sections, sectionName, docId), - valueName: entity.type.name, - }; - return indexSignature; - }, - _convertProperty(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Property { - const source = entity.sources[0]; - const commentIfExists = !_.isUndefined(entity.comment) ? entity.comment.shortText : undefined; - const property = { - name: entity.name, - type: typeDocUtils._convertType(entity.type, sections, sectionName, docId), - source: { - fileName: source.fileName, - line: source.line, - }, - comment: commentIfExists, - }; - return property; - }, - _convertMethod( - entity: TypeDocNode, - isConstructor: boolean, - sections: SectionsMap, - sectionName: string, - docId: string, - ): TypescriptMethod { - const signature = entity.signatures[0]; - const source = entity.sources[0]; - const hasComment = !_.isUndefined(signature.comment); - const isStatic = _.isUndefined(entity.flags.isStatic) ? false : entity.flags.isStatic; - - // HACK: we use the fact that the sectionName is the same as the property name at the top-level - // of the public interface. In the future, we shouldn't use this hack but rather get it from the JSON. - let callPath; - if (isConstructor || entity.name === '__type') { - callPath = ''; - } else if (docId === DocPackages.ZeroExJs) { - const topLevelInterface = isStatic ? 'ZeroEx.' : 'zeroEx.'; - callPath = - !_.isUndefined(sections.zeroEx) && sectionName !== sections.zeroEx - ? `${topLevelInterface}${sectionName}.` - : topLevelInterface; - } else { - callPath = `${sectionName}.`; - } - - const parameters = _.map(signature.parameters, param => { - return typeDocUtils._convertParameter(param, sections, sectionName, docId); - }); - const returnType = typeDocUtils._convertType(signature.type, sections, sectionName, docId); - const typeParameter = _.isUndefined(signature.typeParameter) - ? undefined - : typeDocUtils._convertTypeParameter(signature.typeParameter[0], sections, sectionName, docId); - - const method = { - isConstructor, - isStatic, - name: signature.name, - comment: hasComment ? signature.comment.shortText : undefined, - returnComment: hasComment && signature.comment.returns ? signature.comment.returns : undefined, - source: { - fileName: source.fileName, - line: source.line, - }, - callPath, - parameters, - returnType, - typeParameter, - }; - return method; - }, - _convertTypeParameter( - entity: TypeDocNode, - sections: SectionsMap, - sectionName: string, - docId: string, - ): TypeParameter { - const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId); - const parameter = { - name: entity.name, - type, - }; - return parameter; - }, - _convertParameter(entity: TypeDocNode, sections: SectionsMap, sectionName: string, docId: string): Parameter { - let comment = '<No comment>'; - if (entity.comment && entity.comment.shortText) { - comment = entity.comment.shortText; - } else if (entity.comment && entity.comment.text) { - comment = entity.comment.text; - } - - const isOptional = !_.isUndefined(entity.flags.isOptional) ? entity.flags.isOptional : false; - - const type = typeDocUtils._convertType(entity.type, sections, sectionName, docId); - - const parameter = { - name: entity.name, - comment, - isOptional, - type, - }; - return parameter; - }, - _convertType(entity: TypeDocType, sections: SectionsMap, sectionName: string, docId: string): Type { - const typeArguments = _.map(entity.typeArguments, typeArgument => { - return typeDocUtils._convertType(typeArgument, sections, sectionName, docId); - }); - const types = _.map(entity.types, t => { - return typeDocUtils._convertType(t, sections, sectionName, docId); - }); - - const isConstructor = false; - const methodIfExists = !_.isUndefined(entity.declaration) - ? typeDocUtils._convertMethod(entity.declaration, isConstructor, sections, sectionName, docId) - : undefined; - - const elementTypeIfExists = !_.isUndefined(entity.elementType) - ? { - name: entity.elementType.name, - typeDocType: entity.elementType.type, - } - : undefined; - - const type = { - name: entity.name, - value: entity.value, - typeDocType: entity.type, - typeArguments, - elementType: elementTypeIfExists, - types, - method: methodIfExists, - }; - return type; - }, -}; diff --git a/packages/website/ts/utils/utils.ts b/packages/website/ts/utils/utils.ts index a1e045af7..308b4bb5c 100644 --- a/packages/website/ts/utils/utils.ts +++ b/packages/website/ts/utils/utils.ts @@ -1,20 +1,10 @@ import { ECSignature, ExchangeContractErrs, ZeroEx, ZeroExError } from '0x.js'; +import { constants as sharedConstants, EtherscanLinkSuffixes, Networks } from '@0xproject/react-shared'; import { BigNumber } from '@0xproject/utils'; import deepEqual = require('deep-equal'); -import isMobile = require('is-mobile'); import * as _ from 'lodash'; import * as moment from 'moment'; -import { scroller } from 'react-scroll'; -import { - EtherscanLinkSuffixes, - Networks, - Order, - ScreenWidths, - Side, - SideToAssetToken, - Token, - TokenByAddress, -} from 'ts/types'; +import { Order, ScreenWidths, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types'; import { configs } from 'ts/utils/configs'; import { constants } from 'ts/utils/constants'; import * as u2f from 'ts/vendor/u2f_api'; @@ -140,21 +130,6 @@ export const utils = { return ScreenWidths.Sm; } }, - isUserOnMobile(): boolean { - const isUserOnMobile = isMobile(); - return isUserOnMobile; - }, - getEtherScanLinkIfExists(addressOrTxHash: string, networkId: number, suffix: EtherscanLinkSuffixes): string { - const networkName = constants.NETWORK_NAME_BY_ID[networkId]; - if (_.isUndefined(networkName)) { - return undefined; - } - const etherScanPrefix = networkName === Networks.Mainnet ? '' : `${networkName.toLowerCase()}.`; - return `https://${etherScanPrefix}etherscan.io/${suffix}/${addressOrTxHash}`; - }, - setUrlHash(anchorId: string) { - window.location.hash = anchorId; - }, async isU2FSupportedAsync(): Promise<boolean> { const w = window as any; return new Promise((resolve: (isSupported: boolean) => void) => { @@ -202,10 +177,6 @@ export const utils = { return 'production'; } }, - getIdFromName(name: string) { - const id = name.replace(/ /g, '-'); - return id; - }, getAddressBeginAndEnd(address: string): string { const truncatedAddress = `${address.substring(0, 6)}...${address.substr(-4)}`; // 0x3d5a...b287 return truncatedAddress; @@ -283,32 +254,14 @@ export const utils = { isTestNetwork(networkId: number): boolean { const isTestNetwork = _.includes( [ - constants.NETWORK_ID_BY_NAME[Networks.Kovan], - constants.NETWORK_ID_BY_NAME[Networks.Rinkeby], - constants.NETWORK_ID_BY_NAME[Networks.Ropsten], + sharedConstants.NETWORK_ID_BY_NAME[Networks.Kovan], + sharedConstants.NETWORK_ID_BY_NAME[Networks.Rinkeby], + sharedConstants.NETWORK_ID_BY_NAME[Networks.Ropsten], ], networkId, ); return isTestNetwork; }, - getCurrentBaseUrl() { - const port = window.location.port; - const hasPort = !_.isUndefined(port); - const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`; - return baseUrl; - }, - scrollToHash(hash: string, containerId: string): void { - let finalHash = hash; - if (_.isEmpty(hash)) { - finalHash = configs.SCROLL_TOP_ID; // scroll to the top - } - - scroller.scrollTo(finalHash, { - duration: 0, - offset: 0, - containerId, - }); - }, async onPageLoadAsync(): Promise<void> { if (document.readyState === 'complete') { return; // Already loaded @@ -317,4 +270,10 @@ export const utils = { window.onload = () => resolve(); }); }, + getCurrentBaseUrl() { + const port = window.location.port; + const hasPort = !_.isUndefined(port); + const baseUrl = `https://${window.location.hostname}${hasPort ? `:${port}` : ''}`; + return baseUrl; + }, }; |