diff --git a/.babelrc b/.babelrc new file mode 100644 index 000000000..0be079203 --- /dev/null +++ b/.babelrc @@ -0,0 +1,10 @@ +{ + "presets": ["es2015"], + "plugins": [ + "add-module-exports", + "babel-root-import", + ["transform-react-jsx", { + "pragma": "JSX.createElement" + }] + ] +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..c9c6751f6 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,31 @@ +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Top-level config +root = true + +# All files +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..747746059 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,24 @@ +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Build files +/build +/material +/site diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..42e6738b4 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,199 @@ +{ + "extends": "eslint:recommended", + "ecmaFeatures": { + "arrowFunctions": true, + "binaryLiterals": true, + "blockBindings": true, + "classes": true, + "defaultParams": true, + "destructuring": true, + "forOf": true, + "generators": true, + "globalReturn": true, + "modules": true, + "objectLiteralComputedProperties": true, + "objectLiteralDuplicateProperties": true, + "objectLiteralShorthandMethods": true, + "objectLiteralShorthandProperties": true, + "octalLiterals": true, + "regexUFlag": true, + "regexYFlag": true, + "spread": true, + "superInFunctions": false, + "templateStrings": true, + "unicodeCodePointEscapes": true + }, + "env": { + "browser": true, + "es6": true, + "node": true + }, + "globals": { + "Modernizr": true, + "navigator": true + }, + "parser": "babel-eslint", + "parserOptions": { + "ecmaVersion": 6, + "impliedStrict": true, + "sourceType": "module" + }, + "plugins": [], + "rules": { + "array-callback-return": 2, + "array-bracket-spacing": 2, + "arrow-parens": [2, "as-needed"], + "arrow-spacing": 2, + "block-scoped-var": 2, + "block-spacing": 2, + "brace-style": 2, + "camelcase": [2, { + "properties": "always" + }], + "comma-dangle": [2, "never"], + "comma-style": [2, "last"], + "complexity": 2, + "computed-property-spacing": 2, + "consistent-this": 2, + "dot-notation": 2, + "eol-last": 2, + "eqeqeq": 2, + "func-call-spacing": 2, + "func-names": [2, "never"], + "func-style": 2, + "generator-star-spacing": 2, + "indent": [2, 2, { + "FunctionDeclaration": { + "body": 1, + "parameters": 2 + }, + "FunctionExpression": { + "body": 1, + "parameters": 2 + }, + "MemberExpression": 1, + "VariableDeclarator": { + "var": 2, + "let": 2, + "const": 3 + }, + "SwitchCase": 1 + }], + "init-declarations": 2, + "key-spacing": 2, + "keyword-spacing": 2, + "linebreak-style": 2, + "lines-around-comment": 2, + "lines-around-directive": 2, + "max-depth": 2, + "max-len": [1, { + "ignorePattern": "\/\/ TODO" + }], + "max-nested-callbacks": 2, + "max-params": 2, + "max-statements-per-line": 2, + "new-cap": 2, + "newline-per-chained-call": 2, + "no-array-constructor": 2, + "no-alert": 2, + "no-caller": 2, + "no-confusing-arrow": [2, { + "allowParens": false + }], + "no-console": 1, + "no-duplicate-imports": 2, + "no-eq-null": 2, + "no-eval": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-floating-decimal": 2, + "no-global-assign": 2, + "no-invalid-this": 2, + "no-labels": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multiple-empty-lines": [1, { + "max": 1 + }], + "no-nested-ternary": 2, + "no-new": 0, + "no-new-object": 2, + "no-param-reassign": 2, + "no-prototype-builtins": 2, + "no-shadow": 2, + "no-tabs": 2, + "no-template-curly-in-string": 2, + "no-throw-literal": 2, + "no-trailing-spaces": 2, + "no-undefined": 2, + "no-underscore-dangle": [2, { + "allowAfterThis": true, + "allowAfterSuper": true + }], + "no-unneeded-ternary": 2, + "no-unsafe-negation": 2, + "no-unused-expressions": 2, + "no-unused-vars": 1, + "no-use-before-define": 2, + "no-useless-call": 2, + "no-useless-computed-key": 2, + "no-useless-constructor": 2, + "no-useless-rename": 2, + "no-var": 2, + "no-whitespace-before-property": 2, + "no-with": 2, + "object-curly-spacing": [2, "always"], + "object-shorthand": 2, + "one-var-declaration-per-line": 2, + "operator-assignment": 2, + "prefer-arrow-callback": 2, + "prefer-const": 2, + "prefer-numeric-literals": 2, + "prefer-spread": 2, + "prefer-template": 2, + "quotes": [2, "double"], + "radix": 2, + "require-jsdoc": [1, { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": true, + "ClassDeclaration": false + } + }], + "rest-spread-spacing": 2, + "semi": [2, "never"], + "semi-spacing": 2, + "space-before-function-paren": [2, "never"], + "space-in-parens": 2, + "space-infix-ops": 2, + "space-unary-ops": 2, + "spaced-comment": [2, "always", { + "line": { + "markers": ["/"], + "exceptions": ["-", "+"] + }, + "block": { + "markers": ["!"], + "exceptions": ["*"], + "balanced": true + } + }], + "strict": 2, + "template-curly-spacing": 2, + "unicode-bom": 2, + "valid-jsdoc": [1, { + "prefer": { + "arg": "param", + "argument": "param", + "class": "constructor", + "returns": "return", + "virtual": "abstract" + }, + "requireParamDescription": true, + "requireReturn": false, + "requireReturnDescription": true + }], + "yield-star-spacing": 2 + }, + "root": true +} diff --git a/.githooks/post-merge/npm-update.sh b/.githooks/post-merge/npm-update.sh new file mode 100755 index 000000000..3d5a50b85 --- /dev/null +++ b/.githooks/post-merge/npm-update.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check, if all changes are added to the index +CHANGED="$(git diff-tree -r --name-only --no-commit-id ORIG_HEAD HEAD)" + +# Perform install and prune of NPM dependencies if package.json changed +if $(echo "$CHANGED" | grep --quiet package.json); then + echo "Hook[post-merge]: Updating dependencies..." + npm install && npm prune +fi diff --git a/.githooks/pre-commit/lint.sh b/.githooks/pre-commit/lint.sh new file mode 100755 index 000000000..eeb5688b7 --- /dev/null +++ b/.githooks/pre-commit/lint.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Patch file to store unindexed changes +PATCH_FILE=".working-tree.patch" + +# Revert changes that have been registered in the patch file +function cleanup { + EXIT_CODE=$? + if [ -f "$PATCH_FILE" ]; then + git apply "$PATCH_FILE" 2> /dev/null + rm "$PATCH_FILE" + fi + exit $EXIT_CODE +} + +# Register signal handlers +trap cleanup EXIT SIGINT SIGHUP + +# Cancel any changes to the working tree that are not going to be committed +git diff > "$PATCH_FILE" +git checkout -- . + +# Filter relevant files for linting +FILES=$(git diff --cached --name-only --diff-filter=ACMR | \ + grep "\.\(js\|jsx\|scss\)$") + +# Run the check and print indicator +if [ "$FILES" ]; then + echo "Hook[pre-commit]: Running linter..." + npm run lint --silent || exit 1 +fi diff --git a/.gitignore b/.gitignore index 9c5346675..c6cfbd09f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Martin Donath +# Copyright (c) 2016-2017 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -18,18 +18,19 @@ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -# Mac OS X internals +# macOS internals .DS_Store -# Bower and NPM libraries -bower_components -node_modules +# NPM-related +/node_modules +/npm-debug.log # Build files -build -MANIFEST -site +/build +/manifest.json +/MANIFEST +/site # Distribution files -dist -mkdocs_material.egg-info \ No newline at end of file +/dist +/mkdocs_material.egg-info diff --git a/.stylelintrc b/.stylelintrc new file mode 100644 index 000000000..93125f695 --- /dev/null +++ b/.stylelintrc @@ -0,0 +1,191 @@ +{ + "extends": "stylelint-config-standard", + "plugins": [ + "stylelint-order", + "stylelint-scss" + ], + "rules": { + "at-rule-empty-line-before": null, + "at-rule-no-vendor-prefix": true, + "block-opening-brace-space-before": null, + "block-closing-brace-newline-after": ["always", { + "ignoreAtRules": [ + "if", + "else", + "elseif" + ] + }], + "color-hex-case": "upper", + "color-hex-length": "long", + "color-named": "never", + "comment-empty-line-before": ["always", { + "ignore": ["stylelint-commands"] + }], + "font-family-name-quotes": "always-where-recommended", + "font-weight-notation": "numeric", + "function-url-quotes": "always", + "no-unknown-animations": true, + "order/declaration-block-order": [ + "custom-properties", + "declarations" + ], + "order/declaration-block-properties-specified-order": [ + "display", + "position", + "top", + "right", + "bottom", + "left", + + "flex", + "flex-basis", + "flex-direction", + "flex-flow", + "flex-grow", + "flex-shrink", + "flex-wrap", + "align-content", + "align-items", + "align-self", + "justify-content", + "order", + + "width", + "min-width", + "max-width", + + "height", + "min-height", + "max-height", + + "margin", + "margin-top", + "margin-right", + "margin-bottom", + "margin-left", + + "padding", + "padding-top", + "padding-right", + "padding-bottom", + "padding-left", + + "float", + "clear", + "clip", + + "columns", + "column-gap", + "column-fill", + "column-rule", + "column-span", + "column-count", + "column-width", + + "transform", + "transform-box", + "transform-origin", + "transform-style", + + "transition", + "transition-delay", + "transition-duration", + "transition-property", + "transition-timing-function", + + "border", + "border-top", + "border-right", + "border-bottom", + "border-left", + "border-width", + "border-top-width", + "border-right-width", + "border-bottom-width", + "border-left-width", + + "border-style", + "border-top-style", + "border-right-style", + "border-bottom-style", + "border-left-style", + + "border-radius", + "border-top-left-radius", + "border-top-right-radius", + "border-bottom-left-radius", + "border-bottom-right-radius", + + "border-color", + "border-top-color", + "border-right-color", + "border-bottom-color", + "border-left-color", + + "outline", + "outline-color", + "outline-offset", + "outline-style", + "outline-width", + + "background", + "background-attachment", + "background-clip", + "background-color", + "background-image", + "background-repeat", + "background-position", + "background-size", + + "color", + + "font", + "font-family", + "font-size", + "font-smoothing", + "font-style", + "font-variant", + "font-weight", + + "letter-spacing", + "line-height", + "list-style", + + "text-align", + "text-decoration", + "text-indent", + "text-overflow", + "text-rendering", + "text-shadow", + "text-transform", + "text-wrap", + + "white-space", + "word-spacing", + + "border-collapse", + "border-spacing", + "box-shadow", + "caption-side", + "content", + "cursor", + "empty-cells", + "opacity", + "overflow", + "quotes", + "speak", + "table-layout", + "vertical-align", + "visibility", + "z-index" + ], + "property-no-vendor-prefix": true, + "root-no-standard-properties": true, + "selector-class-pattern": "^[a-z0-9]+(-[a-z0-9]+)*(__[a-z]+)?(--[a-z]+)?$", + "selector-descendant-combinator-no-non-space": null, + "string-quotes": "double", + "unit-whitelist": ["rem", "em", "deg", "s", "%", "mm", "vh"], + "value-keyword-case": "lower", + "value-no-vendor-prefix": true + } +} diff --git a/.travis.yml b/.travis.yml index f68ba8fe1..b616c0470 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2013-2016 Martin Donath +# Copyright (c) 2016-2017 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -19,20 +19,23 @@ # IN THE SOFTWARE. language: node_js +sudo: false # Node.js versions node_js: - 4 + - 5 + - 6 + +# Cache dependencies +cache: + pip: true + directories: + - node_modules # Install dependencies before_script: - - # Install bower - - npm install -g bower - - # Install project dependencies - - npm install - - bower install + - pip install --user -r requirements.txt # Perform build and tests -script: gulp build --production +script: npm run build diff --git a/CHANGELOG b/CHANGELOG index bbcf6ac30..bc7774d1e 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,35 @@ +mkdocs-material-1.0.0 (2017-01-13) + + * Introduced Webpack for more sophisticated JavaScript bundling + * Introduced ESLint and Stylelint for code style checks + * Introduced more accurate Material Design colors and shadows + * Introduced modular scales for harmonic font sizing + * Introduced git-hooks for better development workflow + * Rewrite of CSS using the BEM methodology and SassDoc guidelines + * Rewrite of JavaScript using ES6 and Babel as a transpiler + * Rewrite of Admonition, Permalinks and CodeHilite integration + * Rewrite of the complete typographical system + * Rewrite of Gulp asset pipeline in ES6 and separation of tasks + * Removed Bower as a dependency in favor of NPM + * Removed custom icon build in favor of the Material Design iconset + * Removed _blank targets on links due to vulnerability: http://bit.ly/1Mk2Rtw + * Removed unversioned assets from build directory + * Restructured templates into base templates and partials + * Added build and watch scripts in package.json + * Added support for Metadata and Footnotes Markdown extensions + * Added support for pymdownx.* Markdown extensions + * Added support for collapsible sections in navigation + * Added support for separate table of contents + * Added support for better accessibility through REM-based layout + * Added icons for GitHub, GitLab and BitBucket integrations + * Added more detailed documentation on specimen, extensions etc. + * Added a 404.html error page for deployment on GitHub Pages + * Fixed live reload chain in watch mode when saving a template + * Fixed variable references to work with MkDocs 0.16 + mkdocs-material-0.2.4 (2016-06-26) - * Fixed improperly set set default favicon + * Fixed improperly set default favicon * Fixed #33: Protocol relative URL for webfonts doesn't work with file:// * Fixed #34: IE11 on Windows 7 doesn't honor max-width on main tag * Fixed #35: Add styling for blockquotes @@ -13,7 +42,7 @@ mkdocs-material-0.2.3 (2016-05-16) mkdocs-material-0.2.2 (2016-03-20) - * Fixed #15: Document pygments dependency for codehilite + * Fixed #15: Document Pygments dependency for CodeHilite * Fixed #16: Favicon could not be set through mkdocs.yml * Fixed #17: Put version into own container for styling * Fixed #20: Fix rounded borders for tables @@ -53,11 +82,11 @@ mkdocs-material-0.1.2 (2016-02-16) mkdocs-material-0.1.1 (2016-02-11) * Fixed #1: GitHub stars don't work if the repo_url ends with a '/' - * Updated npm and bower dependencies to most recent versions + * Updated NPM and Bower dependencies to most recent versions * Changed footer/copyright link to Material theme to GitHub pages * Made MkDocs building/serving in build process optional - * Set up continuous integration with travis-ci.org + * Set up continuous integration with Travis mkdocs-material-0.1.0 (2016-02-09) - * Initial release \ No newline at end of file + * Initial release diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 64b79ecd7..8c3bcf7fa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@ # Contributing -Interested in contributing to the Material theme? Before you do, please read -the following guidelines. +Interested in contributing to the Material theme? Want to report a bug? Before +you do, please read the following guidelines. ## Submission context @@ -15,8 +15,12 @@ For quick questions there's no need to open an issue as you can reach us on ### Found a bug? If you found a bug in the source code, you can help us by submitting an issue -to our GitHub Repository. Even better, you can submit a Pull Request with a -fix. However, before doing so, read the submission guidelines. +to the [issue tracker][2] in our GitHub repository. Even better, you can submit +a Pull Request with a fix. However, before doing so, please read the +[submission guidelines][3]. + + [2]: https://github.com/squidfunk/mkdocs-material/issues + [3]: #submission-guidelines ### Missing a feature? @@ -47,20 +51,31 @@ readily available. We want to fix all the issues as soon as possible, but before fixing a bug we need to reproduce and confirm it. In order to reproduce bugs we will systematically ask you to provide a minimal reproduction scenario using the -custom issue template. +custom issue template. Please stick to the issue template. Unfortunately we are not able to investigate / fix bugs without a minimal -reproduction, so if we don't hear back from you we are going to close issues -that don't have enough information to be reproduced. +reproduction scenario, so if we don't hear back from you we may close the issue. ### Submitting a Pull Request (PR) Search GitHub for an open or closed PR that relates to your submission. You -don't want to duplicate effort. Fork the project, make your changes in **a new -git branch** and commit your changes with a descriptive commit message. Then -push your branch to GitHub and send a PR to `mkdocs-material:master`. If we -suggest changes, make the required updates, rebase your branch and push -the changes to your GitHub repository, which will automatiaclly update your PR. +don't want to duplicate effort. If you do not find a related issue or PR, +go ahead. + +1. **Development**: Fork the project, set up the [development environment][4], + make your changes in a separate git branch and add descriptive messages to + your commits. + +2. **Build**: Before submitting a pull requests, build the theme. This is a + mandatory requirement for your PR to get accepted, as the theme should at + all times be installable through GitHub. + +3. **Pull Request**: After building the theme, commit the compiled output, push + your branch to GitHub and send a PR to `mkdocs-material:master`. If we + suggest changes, make the required updates, rebase your branch and push the + changes to your GitHub repository, which will automatically update your PR. After your PR is merged, you can safely delete your branch and pull the changes from the main (upstream) repository. + + [4]: http://localhost:8000/customization/#theme-development diff --git a/Gulpfile.babel.js b/Gulpfile.babel.js new file mode 100755 index 000000000..5fefcc60a --- /dev/null +++ b/Gulpfile.babel.js @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import gulp from "gulp" +import notifier from "node-notifier" +import plumber from "gulp-plumber" +import util from "gulp-util" +import yargs from "yargs" + +/* ---------------------------------------------------------------------------- + * Configuration and arguments + * ------------------------------------------------------------------------- */ + +const config = { + assets: { + src: "src/assets", /* Source directory for assets */ + build: "material/assets" /* Target directory for assets */ + }, + lib: "lib", /* Libraries */ + views: { + src: "src", /* Source directory for views */ + build: "material" /* Target directory for views */ + } +} + +const args = yargs + .default("clean", false) /* Clean before build */ + .default("karma", true) /* Karma watchdog */ + .default("lint", true) /* Lint sources */ + .default("mkdocs", true) /* MkDocs watchdog */ + .default("optimize", false) /* Optimize sources */ + .default("revision", false) /* Revision assets */ + .default("sourcemaps", false) /* Create sourcemaps */ + .argv + +/* ---------------------------------------------------------------------------- + * Overrides and helpers + * ------------------------------------------------------------------------- */ + +/* + * Override gulp.src() for nicer error handling. + */ +const src = gulp.src +gulp.src = (...glob) => { + return src.apply(gulp, glob) + .pipe( + plumber(function(error) { + util.log(util.colors.red( + `Error (${error.plugin}): ${error.message}` + )) + + /* Extract file where error happened, if existent */ + const file = error.relativePath + ? error.relativePath.split("/").pop() + : "" + + /* Dispatch system-level notification */ + notifier.notify({ + title: `Error (${error.plugin}): ${file}`, + message: error.messageOriginal + }) + + // eslint-disable-next-line no-invalid-this + this.emit("end") + + /* Throw error and abort, if not in watch mode */ + if (args._[0] !== "watch") + throw error + })) +} + +/* + * Helper function to load a task + */ +const load = task => { + return require(`./${config.lib}/tasks/${task}`)(gulp, config, args) +} + +/* ---------------------------------------------------------------------------- + * Images + * ------------------------------------------------------------------------- */ + +/* + * Copy favicon + */ +gulp.task("assets:images:build:ico", + load("assets/images/build/ico")) + +/* + * Copy and minify vector graphics + */ +gulp.task("assets:images:build:svg", + load("assets/images/build/svg")) + +/* + * Copy images + */ +gulp.task("assets:images:build", args.clean ? [ + "assets:images:clean" +] : [], () => { + return gulp.start([ + "assets:images:build:ico", + "assets:images:build:svg" + ]) +}) + +/* + * Clean images generated by build + */ +gulp.task("assets:images:clean", + load("assets/images/clean")) + +/* ---------------------------------------------------------------------------- + * JavaScript + * ------------------------------------------------------------------------- */ + +/* + * Build application logic + */ +gulp.task("assets:javascripts:build:application", + load("assets/javascripts/build/application")) + +/* + * Build custom modernizr + */ +gulp.task("assets:javascripts:build:modernizr", [ + "assets:stylesheets:build" +], load("assets/javascripts/build/modernizr")) + +/* + * Build application logic and modernizr + */ +gulp.task("assets:javascripts:build", (args.clean ? [ + "assets:javascripts:clean" +] : []).concat(args.lint ? [ + "assets:javascripts:lint" +] : []), () => { + return gulp.start([ + "assets:javascripts:build:application", + "assets:javascripts:build:modernizr" + ]) +}) + +/* + * Clean JavaScript generated by build + */ +gulp.task("assets:javascripts:clean", + load("assets/javascripts/clean")) + +/* + * Lint JavaScript + */ +gulp.task("assets:javascripts:lint", + load("assets/javascripts/lint")) + +/* ---------------------------------------------------------------------------- + * Stylesheets + * ------------------------------------------------------------------------- */ + +/* + * Build stylesheets from SASS source + */ +gulp.task("assets:stylesheets:build", (args.clean ? [ + "assets:stylesheets:clean" +] : []).concat(args.lint ? [ + "assets:stylesheets:lint" +] : []), + load("assets/stylesheets/build")) + +/* + * Clean stylesheets generated by build + */ +gulp.task("assets:stylesheets:clean", + load("assets/stylesheets/clean")) + +/* + * Lint SASS sources + */ +gulp.task("assets:stylesheets:lint", + load("assets/stylesheets/lint")) + +/* ---------------------------------------------------------------------------- + * Assets + * ------------------------------------------------------------------------- */ + +/* + * Build assets + */ +gulp.task("assets:build", [ + "assets:images:build", + "assets:javascripts:build", + "assets:stylesheets:build" +]) + +/* + * Clean files generated by build + */ +gulp.task("assets:clean", [ + "assets:images:clean", + "assets:javascripts:clean", + "assets:stylesheets:clean" +]) + +/* ---------------------------------------------------------------------------- + * Views + * ------------------------------------------------------------------------- */ + +/* + * Minify views + */ +gulp.task("views:build", (args.revision ? [ + "assets:images:build", + "assets:stylesheets:build", + "assets:javascripts:build" +] : []).concat(args.clean ? [ + "views:clean" +] : []), load("views/build")) + +/* + * Clean views + */ +gulp.task("views:clean", + load("views/clean")) + +/* ---------------------------------------------------------------------------- + * MkDocs + * ------------------------------------------------------------------------- */ + +/* + * Build documentation + */ +gulp.task("mkdocs:build", [ + "assets:build", + "views:build", + "mkdocs:clean" +], load("mkdocs/build")) + +/* + * Clean documentation build + */ +gulp.task("mkdocs:clean", + load("mkdocs/clean")) + +/* + * Restart MkDocs server + */ +gulp.task("mkdocs:serve", + load("mkdocs/serve")) + +/* ---------------------------------------------------------------------------- + * Tests + * ------------------------------------------------------------------------- */ + +/* + * Start karma test runner + */ +gulp.task("tests:unit:watch", + load("tests/unit/watch")) + +/* ---------------------------------------------------------------------------- + * Interface + * ------------------------------------------------------------------------- */ + +/* + * Build assets and documentation + */ +gulp.task("build", [ + "assets:build", + "views:build" +].concat(args.mkdocs + ? "mkdocs:build" + : [])) + +/* + * Clean assets and documentation + */ +gulp.task("clean", [ + "assets:clean", + "views:clean", + "mkdocs:clean" +]) + +/* + * Watch for changes and rebuild assets on the fly + */ +gulp.task("watch", [ + "assets:build", + "views:build" +], () => { + process.env.WATCH = true + + /* Start MkDocs server */ + if (args.mkdocs) + gulp.start("mkdocs:serve") + + /* Start karma test runner */ + // if (args.karma) + // gulp.start("tests:unit:watch") + + /* Rebuild stylesheets */ + gulp.watch([ + `${config.assets.src}/stylesheets/**/*.scss` + ], ["assets:stylesheets:build"]) + + /* Rebuild JavaScript */ + gulp.watch([ + `${config.assets.src}/javascripts/**/*.{js,jsx}` + ], ["assets:javascripts:build:application"]) + + /* Copy images */ + gulp.watch([ + `${config.assets.src}/images/**/*` + ], ["assets:images:build"]) + + /* Minify views */ + gulp.watch([ + `${config.views.src}/**/*.html` + ], ["views:build"]) +}) + +/* + * Build assets by default + */ +gulp.task("default", ["build"]) diff --git a/Gulpfile.js b/Gulpfile.js deleted file mode 100755 index e759bf410..000000000 --- a/Gulpfile.js +++ /dev/null @@ -1,332 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Imports - * ------------------------------------------------------------------------- */ - -var gulp = require('gulp'); -var addsrc = require('gulp-add-src'); -var args = require('yargs').argv; -var autoprefix = require('autoprefixer'); -var child = require('child_process'); -var clean = require('del'); -var collect = require('gulp-rev-collector'); -var compact = require('gulp-remove-empty-lines'); -var concat = require('gulp-concat'); -var ignore = require('gulp-ignore'); -var gulpif = require('gulp-if'); -var mincss = require('gulp-cssnano'); -var minhtml = require('gulp-htmlmin'); -var minimage = require('gulp-image-optimization'); -var modernizr = require('gulp-modernizr'); -var mqpacker = require('css-mqpacker'); -var notifier = require('node-notifier'); -var plumber = require('gulp-plumber'); -var postcss = require('gulp-postcss'); -var rev = require('gulp-rev'); -var sass = require('gulp-sass'); -var sourcemaps = require('gulp-sourcemaps'); -var uglify = require('gulp-uglify'); -var util = require('gulp-util'); -var vinyl = require('vinyl-paths'); - -/* ---------------------------------------------------------------------------- - * Locals - * ------------------------------------------------------------------------- */ - -/* MkDocs server */ -var server = null; - -/* ---------------------------------------------------------------------------- - * Overrides - * ------------------------------------------------------------------------- */ - -/* - * Override gulp.src() for nicer error handling. - */ -var src = gulp.src; -gulp.src = function() { - return src.apply(gulp, arguments) - .pipe( - plumber(function(error) { - util.log(util.colors.red( - 'Error (' + error.plugin + '): ' + error.message - )); - notifier.notify({ - title: 'Error (' + error.plugin + ')', - message: error.message.split('\n')[0] - }); - this.emit('end'); - })); -}; - -/* ---------------------------------------------------------------------------- - * Asset pipeline - * ------------------------------------------------------------------------- */ - -/* - * Build stylesheets from SASS source. - */ -gulp.task('assets:stylesheets', function() { - return gulp.src('src/assets/stylesheets/*.scss') - .pipe(gulpif(args.sourcemaps, sourcemaps.init())) - .pipe( - sass({ - includePaths: [ - 'bower_components/bourbon/app/assets/stylesheets/', - 'bower_components/quantum-colors/', - 'bower_components/quantum-shadows/' - ] - })) - .pipe( - postcss([ - autoprefix(), - mqpacker - ])) - .pipe(gulpif(args.sourcemaps, sourcemaps.write())) - .pipe(gulpif(args.production, mincss())) - .pipe(gulp.dest('material/assets/stylesheets/')); -}); - -/* - * Build javascripts from Bower components and source. - */ -gulp.task('assets:javascripts', function() { - return gulp.src([ - - /* Bower components */ - 'bower_components/classlist/classList.js', - 'bower_components/fastclick/lib/fastclick.js', - 'bower_components/pegasus/dist/pegasus.js', - 'bower_components/lunr.js/lunr.js', - - /* Application javascripts */ - 'src/assets/javascripts/application.js', - 'src/assets/javascripts/standalone.js' - ]).pipe(gulpif(args.sourcemaps, sourcemaps.init())) - .pipe(concat('application.js')) - .pipe(gulpif(args.sourcemaps, sourcemaps.write())) - .pipe(gulpif(args.production, uglify())) - .pipe(gulp.dest('material/assets/javascripts/')); -}); - -/* - * Create a customized modernizr build. - */ -gulp.task('assets:modernizr', [ - 'assets:stylesheets', - 'assets:javascripts' -], function() { - return gulp.src([ - 'material/assets/stylesheets/application.css', - 'material/assets/javascripts/application.js' - ]).pipe( - modernizr({ - options: [ - 'addTest', /* Add custom tests */ - 'fnBind', /* Use function.bind */ - 'html5printshiv', /* HTML5 support for IE */ - 'setClasses', /* Add CSS classes to root tag */ - 'testProp' /* Test for properties */ - ] - })) - .pipe(addsrc.append('bower_components/respond/dest/respond.src.js')) - .pipe(concat('modernizr.js')) - .pipe(gulpif(args.production, uglify())) - .pipe(gulp.dest('material/assets/javascripts')); -}); - -/* - * Copy static assets like images and webfonts. - */ -gulp.task('assets:static', function() { - return gulp.src('src/assets/{fonts,images}/*.{jpg,png,gif}') - .pipe(gulpif(args.production, - minimage({ - optimizationLevel: 5, - progressive: true, - interlaced: true - }))) - .pipe(addsrc.append('src/assets/{fonts,images}/*.{ico,eot,svg,ttf,woff}')) - .pipe(gulp.dest('material/assets/')); -}); - -/* - * Minify views. - */ -gulp.task('assets:views', args.production ? [ - 'assets:modernizr', - 'assets:revisions:clean', - 'assets:revisions' -] : [], function() { - return gulp.src([ - 'src/*.html' - ]).pipe( - minhtml({ - collapseBooleanAttributes: true, - removeComments: true, - removeScriptTypeAttributes: true, - removeStyleLinkTypeAttributes: true - })) - .pipe(compact()) - .pipe(gulpif(args.production, - addsrc.append([ - 'material/manifest.json', - 'material/**/*.css' - ]))) - .pipe(gulpif(args.production, collect())) - .pipe(ignore.exclude(/manifest\.json$/)) - .pipe(gulp.dest('material')); -}); - -/* - * Clean outdated revisions. - */ -gulp.task('assets:revisions:clean', function() { - return gulp.src(['material/**/*.{ico,css,js,png,jpg,gif}']) - .pipe(ignore.include(/-[a-f0-9]{8,}\.(ico|css|js|png|jpg|gif)$/)) - .pipe(vinyl(clean)); -}); - -/* - * Revision assets after build. - */ -gulp.task('assets:revisions', [ - 'assets:revisions:clean', - 'assets:stylesheets', - 'assets:javascripts', - 'assets:static' -], function() { - return gulp.src(['material/**/*.{ico,css,js,png,jpg,gif}']) - .pipe(ignore.exclude(/-[a-f0-9]{8,}\.(css|js|png|jpg|gif)$/)) - .pipe(rev()) - .pipe(gulp.dest('material')) - .pipe(rev.manifest('manifest.json')) - .pipe(gulp.dest('material')); -}); - -/* - * Build assets. - */ -gulp.task('assets:build', [ - 'assets:stylesheets', - 'assets:javascripts', - 'assets:modernizr', - 'assets:static', - 'assets:views' -]); - -/* - * Watch assets for changes and rebuild on the fly. - */ -gulp.task('assets:watch', function() { - - /* Rebuild stylesheets */ - gulp.watch([ - 'src/assets/stylesheets/**/*.scss' - ], ['assets:stylesheets']); - - /* Rebuild javascripts */ - gulp.watch([ - 'src/assets/javascripts/**/*.js', - 'bower.json' - ], ['assets:javascripts']); - - /* Copy static assets */ - gulp.watch([ - 'src/assets/{fonts,images}/*' - ], ['assets:static']); - - /* Minify views */ - gulp.watch([ - 'src/*.html' - ], ['assets:views']); -}); - -/* ---------------------------------------------------------------------------- - * Application server - * ------------------------------------------------------------------------- */ - -/* - * Build documentation. - */ -gulp.task('mkdocs:build', [ - 'assets:build' -], function() { - return child.spawnSync('mkdocs', ['build']); -}); - -/* - * Restart MkDocs server. - */ -gulp.task('mkdocs:serve', function() { - if (server) - server.kill(); - - /* Spawn MkDocs server */ - server = child.spawn('mkdocs', ['serve', '-a', '0.0.0.0:8000']); - - /* Pretty print server log output */ - server.stdout.on('data', function(data) { - var lines = data.toString().split('\n') - for (var l in lines) - if (lines[l].length) - util.log(lines[l]); - }); - - /* Print errors to stdout */ - server.stderr.on('data', function(data) { - process.stdout.write(data.toString()); - }); -}); - -/* ---------------------------------------------------------------------------- - * Interface - * ------------------------------------------------------------------------- */ - -/* - * Build assets and documentation. - */ -gulp.task('build', [ - 'assets:build' -].concat(args.mkdocs - ? 'mkdocs:build' - : [])); - -/* - * Start asset and MkDocs watchdogs. - */ -gulp.task('watch', [ - 'assets:build', -], function() { - return gulp.start([ - 'assets:watch' - ].concat(args.mkdocs - ? 'mkdocs:serve' - : [])); -}); - -/* - * Build assets by default. - */ -gulp.task('default', ['build']); \ No newline at end of file diff --git a/LICENSE b/LICENSE index a432e14c7..e28471522 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2016 Martin Donath +Copyright (c) 2016-2017 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to diff --git a/MANIFEST.in b/MANIFEST.in index 83ee74c85..c4fc1ece4 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,5 @@ -recursive-include material *.ico *.js *.css *.html *.eot *.svg *.ttf *.woff -recursive-exclude site * \ No newline at end of file +recursive-include material *.ico *.js *.css *.html *.svg +recursive-exclude site * +recursive-exclude * __pycache__ +recursive-exclude * *.py[co] +include LICENSE diff --git a/README.md b/README.md index a6af1af25..66d3c71e6 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ # Material -[![Travis CI][travis-image]][travis-link] -[![PyPI Version][pypi-v-image]][pypi-v-link] +[![Travis][travis-image]][travis-link] +[![Codacy][codacy-image]][codacy-link] +[![PyPI][pypi-image]][pypi-link] -A material design theme for [MkDocs](http://www.mkdocs.org). +A Material Design theme for [MkDocs](http://www.mkdocs.org). -**Note: the theme is currently undergoing a complete rewrite for 1.0.0 which should be -released shortly.** +TBD: [![_](docs/images/screen.png)](http://squidfunk.github.io/mkdocs-material/) -* To get a glimpse, checkout the -[rework](https://github.com/squidfunk/mkdocs-material/tree/rework) branch -* To give feedback on the rework version, please see issues [#46](https://github.com/squidfunk/mkdocs-material/issues/46) - -[![iOS](docs/images/screen.png)](http://squidfunk.github.io/mkdocs-material/) + [travis-image]: https://travis-ci.org/squidfunk/mkdocs-material.svg + [travis-link]: https://travis-ci.org/squidfunk/mkdocs-material + [codacy-image]: https://api.codacy.com/project/badge/Grade/fe07aa1fa91d453cb69711d3885c5d7e + [codacy-link]: https://www.codacy.com/app/squidfunk/mkdocs-material?utm_source=github.com&utm_medium=referral&utm_content=squidfunk/mkdocs-material&utm_campaign=Badge_Grade + [pypi-image]: https://img.shields.io/pypi/v/mkdocs-material.svg + [pypi-link]: https://pypi.python.org/pypi/mkdocs-material ## Quick start @@ -35,7 +36,7 @@ http://squidfunk.github.io/mkdocs-material/ **MIT License** -Copyright (c) 2016 Martin Donath +Copyright (c) 2016-2017 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -54,8 +55,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -[travis-image]: https://travis-ci.org/squidfunk/mkdocs-material.svg?branch=master -[travis-link]: https://travis-ci.org/squidfunk/mkdocs-material -[pypi-v-image]: https://img.shields.io/pypi/v/mkdocs-material.png -[pypi-v-link]: https://pypi.python.org/pypi/mkdocs-material diff --git a/bower.json b/bower.json deleted file mode 100644 index 65b77ce4d..000000000 --- a/bower.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "name": "mkdocs-material", - "version": "0.2.4", - "description": "A material design theme for MkDocs", - "homepage": "http://squidfunk.github.io/mkdocs-material/", - "authors": [ - "squidfunk " - ], - "license": "MIT", - "moduleType": [ - "globals" - ], - "ignore": [ - "**/.*", - "bower_components", - "node_modules" - ], - "private": true, - "dependencies": { - "classlist": "^2014.12.13", - "fastclick": "^1.0.6", - "lunr.js": "^0.6.0", - "pegasus": "0.3.3", - "respond": "^1.4.2" - }, - "devDependencies": { - "bourbon": "^4.2.6", - "quantum-colors": "^1.0.1", - "quantum-shadows": "^1.0.0" - } -} diff --git a/docs/contributing.md b/docs/contributing.md new file mode 100644 index 000000000..6cf8182db --- /dev/null +++ b/docs/contributing.md @@ -0,0 +1,81 @@ +# Contributing + +Interested in contributing to the Material theme? Want to report a bug? Before +you do, please read the following guidelines. + +## Submission context + +### Got a question or problem? + +For quick questions there's no need to open an issue as you can reach us on +[gitter.im][1]. + + [1]: https://gitter.im/mkdocs-material/general + +### Found a bug? + +If you found a bug in the source code, you can help us by submitting an issue +to the [issue tracker][2] in our GitHub repository. Even better, you can submit +a Pull Request with a fix. However, before doing so, please read the +[submission guidelines][3]. + + [2]: https://github.com/squidfunk/mkdocs-material/issues + [3]: #submission-guidelines + +### Missing a feature? + +You can request a new feature by submitting an issue to our GitHub Repository. +If you would like to implement a new feature, please submit an issue with a +proposal for your work first, to be sure that it is of use for everyone, as +the Material theme is highly opinionated. Please consider what kind of change +it is: + +* For a **major feature**, first open an issue and outline your proposal so + that it can be discussed. This will also allow us to better coordinate our + efforts, prevent duplication of work, and help you to craft the change so + that it is successfully accepted into the project. + +* **Small features and bugs** can be crafted and directly submitted as a Pull + Request. However, there is no guarantee that your feature will make it into + the master, as it's always a matter of opinion whether if benefits the + overall functionality of the theme. + +## Submission guidelines + +### Submitting an issue + +Before you submit an issue, please search the issue tracker, maybe an issue for +your problem already exists and the discussion might inform you of workarounds +readily available. + +We want to fix all the issues as soon as possible, but before fixing a bug we +need to reproduce and confirm it. In order to reproduce bugs we will +systematically ask you to provide a minimal reproduction scenario using the +custom issue template. Please stick to the issue template. + +Unfortunately we are not able to investigate / fix bugs without a minimal +reproduction scenario, so if we don't hear back from you we may close the issue. + +### Submitting a Pull Request (PR) + +Search GitHub for an open or closed PR that relates to your submission. You +don't want to duplicate effort. If you do not find a related issue or PR, +go ahead. + +1. **Development**: Fork the project, set up the [development environment][4], + make your changes in a separate git branch and add descriptive messages to + your commits. + +2. **Build**: Before submitting a pull requests, build the theme. This is a + mandatory requirement for your PR to get accepted, as the theme should at + all times be installable through GitHub. + +3. **Pull Request**: After building the theme, commit the compiled output, push + your branch to GitHub and send a PR to `mkdocs-material:master`. If we + suggest changes, make the required updates, rebase your branch and push the + changes to your GitHub repository, which will automatically update your PR. + +After your PR is merged, you can safely delete your branch and pull the changes +from the main (upstream) repository. + + [4]: http://localhost:8000/customization/#theme-development diff --git a/docs/customization.md b/docs/customization.md index 7814b6a8c..3b6311cf7 100644 --- a/docs/customization.md +++ b/docs/customization.md @@ -1,104 +1,240 @@ # Customization -## A good starting point +## A great starting point Project documentation is as diverse as the projects themselves and the Material -theme is a good starting point for making it look good. However, as you write +theme is a good starting point for making it look great. However, as you write your documentation, you may reach some point where some small adjustments are necessary to preserve the style. -## Small tweaks +## Adding assets -[MkDocs][] provides a simple way for making small adjustments, that is changing -some margins, centering text, etc. Simply put the CSS and Javascript files that -contain your adjustments in the `docs` directory (ideally in subdirectories of -their own) and include them via the `extra_css` and `extra_javascript` -variables in your `mkdocs.yml`: +[MkDocs][1] provides several ways to interfere with themes. In order to make a +few tweaks to an existing theme, you can just add your stylesheets and +JavaScript files to the `docs` directory. -``` yaml -extra_css: ['/stylesheets/extra.css'] -extra_javascript: ['/javascripts/extra.js'] -``` + [1]: http://www.mkdocs.org -Further assistance on including extra CSS and Javascript can be found in the -[MkDocs documentation][]. +### Additional stylesheets -## Fundamental changes - -If you want to make larger adjustments like changing the color palette or -typography, you should check out or download the repository of the project and -compile the SASS sources with your changes. The project design is very modular, -so most things can be tweaked by changing a few variables. - -### Setup - -In order to compile the project, you need `node` with a version greater than -`0.11` up and running. Then, make sure `bower` is installed or install it: +If you want to tweak some colors or change the spacing of certain elements, +you can do this in a separate stylesheet. The easiest way is by creating a +new stylesheet file in your `docs` directory: ``` sh -npm install -g bower +mkdir docs/stylesheets +touch docs/stylesheets/extra.css ``` -The project itself is hosted on GitHub, so the next -thing you should do is clone the project from GitHub: +Then, add the following line to your `mkdocs.yml`: + +``` yaml +extra_css: + - 'stylesheets/extra.css' +``` + +Spin up the development server with `mkdocs serve` and start typing your +changes in your additional stylesheet file – you can see them instantly after +saving, as the MkDocs development server implements live reloading. + +### Additional JavaScript + +The same is true for additional JavaScript. If you want to integrate another +syntax highlighter or add some custom logic to your theme, create a new +JavaScript file in your `docs` directory: + +``` sh +mkdir docs/javascripts +touch docs/javascripts/extra.js +``` + +Then, add the following line to your `mkdocs.yml`: + +``` yaml +extra_javascript: + - 'javascripts/extra.js' +``` + +Further assistance can be found in the [MkDocs documentation][2]. + + [2]: http://www.mkdocs.org/user-guide/styling-your-docs/#customizing-a-theme + +## Extending the theme + +If you want to alter the HTML source (e.g. add or remove some part), you can +extend the theme. From version 0.16 on MkDocs implements [theme extension][3], +an easy way to override parts of a theme without forking and changing the +main theme. + + [3]: http://www.mkdocs.org/user-guide/styling-your-docs/#using-the-theme_dir + +### Setup and theme structure + +Reference the Material theme as usual in your `mkdocs.yml`, and create a +new folder for overrides, e.g. `theme`, which you reference using `theme_dir`: + +``` yaml +theme: 'material' +theme_dir: 'theme' +``` + +!!! warning "Theme extension prerequisites" + + As the `theme_dir` variable is used for the theme extension process, the + Material theme needs to be installed via `pip` and referenced with the + `theme` parameter in your `mkdocs.yml`. + +The structure in the theme directory must mirror the directory structure of the +original theme, as any file in the theme directory will replace the file with +the same name which is part of the original theme. Besides, further assets +may also be put in the theme directory. + +The directory layout of the Material theme is as follows: + +``` sh +. +├─ assets/ +│ ├─ images/ # Images and icons +│ ├─ javascripts/ # JavaScript +│ └─ stylesheets/ # Stylesheets +├─ partials/ +│ ├─ fonts.html # Webfont definitions +│ ├─ footer.html # Footer bar +│ ├─ header.html # Header bar +│ ├─ i18n.html # Localized labels +│ ├─ nav-item.html # Main navigation item +│ ├─ nav.html # Main navigation +│ ├─ search.html # Search box +│ ├─ social.html # Social links +│ ├─ source.html # Repository information +│ ├─ svgs.html # Inline SVG definitions +│ ├─ toc-item.html # Table of contents item +│ └─ toc.html # Table of contents +├─ 404.html # 404 error page +├─ base.html # Base template +└─ main.html # Default page +``` + +### Overriding partials + +In order to override the footer, we can replace the `footer.html` partial with +our own partial. To do this, create the file `partials/footer.html` in the +theme directory. MkDocs will now use the new partial when rendering the theme. +This can be done with any file. + +### Overriding template blocks + +Besides overriding partials, one can also override so called template blocks, +which are defined inside the Material theme and wrap specific features. To +override a template block, create a `main.html` inside the theme directory and +define the block, e.g.: + +``` jinja +{% extends "base.html" %} + +{% block htmltitle %} + Lorem ipsum dolor sit amet +{% endblock %} +``` + +The Material theme provides the following template blocks: + +| Block name | Wrapped contents | +| ------------ | ----------------------------------------------- | +| `analytics` | Wraps the Google Analytics integration | +| `content` | Wraps the main content | +| `extrahead` | Empty block to define additional meta tags | +| `fonts` | Wraps the webfont definitions | +| `footer` | Wraps the footer with navigation and copyright | +| `header` | Wraps the fixed header bar | +| `htmltitle` | Wraps the `` tag | +| `libs` | Wraps the JavaScript libraries, e.g. Modernizr | +| `repo` | Wraps the repository link in the header bar | +| `scripts` | Wraps the JavaScript application logic | +| `search_box` | Wraps the search form in the header bar | +| `site_meta` | Wraps the meta tags in the document head | +| `site_name` | Wraps the site name in the header bar | +| `site_nav` | Wraps the site navigation and table of contents | +| `social` | Wraps the social links in the footer | +| `styles` | Wraps the stylesheets (also extra sources) | + +For more on this topic refer to the [MkDocs documentation][4] + + [4]: http://www.mkdocs.org/user-guide/styling-your-docs/#overriding-template-blocks + +## Theme development + +The Material theme is built on modern technologies like ES6, [Webpack][5], +[Babel][6] and [SASS][7]. If you want to make more fundamental changes, it may +be necessary to make the adjustments directly in the source of the Material +theme and recompile it. This is fairly easy. + + [5]: https://webpack.github.io/ + [6]: https://babeljs.io + [7]: http://sass-lang.com + +### Environment setup + +In order to start development on the Material theme, a [Node.js][8] version of +at least 4 is required. Clone the repository from GitHub: ``` sh git clone https://github.com/squidfunk/mkdocs-material ``` -Then you change the directory and install all dependencies specified in the -`package.json` and `bower.json` with the following command: +Next, all dependencies need to be installed, which is done with: ``` sh cd mkdocs-material -npm install && bower install +pip install -r requirements.txt +npm install ``` -### Development + [8]: https://nodejs.org -The asset pipeline is contained in `Gulpfile.js`, which you can start with -`gulp watch`. If you specify the `--mkdocs` flag, this will also run -`mkdocs serve`, to monitor changes to the documentation. Point your browser to [localhost:8000](http://localhost:8000) and you should see this very -documentation in front of your eyes. +### Development mode + +The Material theme uses a sophisticated asset pipeline using [Gulp][9] and +Webpack which can be started with the following command: ``` sh -gulp watch --mkdocs +npm run start ``` -For example, changing the color palette is as simple as changing the `$primary` -and `$accent` variables in `src/assets/stylesheets/_palette.scss`: +This will also start the MkDocs development server which will monitor changes +on assets, templates and documentation. Point your browser to +[localhost:8000][10] and you should see this documentation in front of you. + +For example, changing the color palette is as simple as changing the +`$md-color-primary` and `$md-color-accent` variables in +`src/assets/stylesheets/_config.scss`: ``` css -$primary: $red-400; -$accent: $teal-a700; +$md-color-primary: $clr-red-400; +$md-color-accent: $clr-teal-a700; ``` -The color variables are defined by the SASS library [quantum-colors][] and -resemble all the colors contained in the material design palette. -[This page][material-colors] offers a really good overview of the palette. +!!! warning "Automatically generated files" -### Building + Never make any changes in the `material` directory, as the contents of this + directory are automatically generated from the `src` directory and will be + overriden when the theme is built. + + [9]: http://gulpjs.com + [10]: http://localhost:8000 + +### Build process When you finished making your changes, you can build the theme by invoking: ``` sh -gulp build --production +npm run build ``` -The `--production` flag triggers the production-level compilation and -minification of all CSS and Javascript sources. When the command is ready, -the final theme is located in the `material` directory. Add the `theme_dir` -variable pointing to the aforementioned directory in your original -`mkdocs.yml`: - -``` yaml -theme_dir: 'mkdocs-material/material' -``` +This triggers the production-level compilation and minification of all +stylesheets and JavaScript sources. When the command is ready, the final +theme is located in the `material` directory. Add the `theme_dir` variable +pointing to the aforementioned directory in your original `mkdocs.yml`. Now you can run `mkdocs build` and you should see your documentation with your changes to the original Material theme. - -[MkDocs]: http://www.mkdocs.org -[MkDocs documentation]: http://www.mkdocs.org/user-guide/styling-your-docs/#customising-a-theme -[quantum-colors]: https://github.com/nkpfstr/quantum-colors -[material-colors]: http://www.materialui.co/colors \ No newline at end of file diff --git a/docs/extensions/admonition.md b/docs/extensions/admonition.md new file mode 100644 index 000000000..e43d2fa69 --- /dev/null +++ b/docs/extensions/admonition.md @@ -0,0 +1,333 @@ +# Admonition + +[Admonition][1] is an extension included in the standard Markdown library that +makes it possible to add block-styled side content to your documentation, for +example summaries, notes, hints or warnings. + + [1]: https://pythonhosted.org/Markdown/extensions/admonition.html + +## Installation + +Add the following lines to your `mkdocs.yml`: + +``` yaml +markdown_extensions: + - admonition +``` + +## Usage + +Admonition blocks follow a simple syntax: every block is started with `!!!`, +followed by a single keyword which is used as the [type qualifier][2] of the +block. The content of the block then follows on the next line, indented by +four spaces. + +Example: + +``` markdown +!!! note + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! note + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + + [2]: #types + +### Changing the title + +By default, the block title will equal the type qualifier in titlecase. However, +it can easily be changed by adding a quoted string after the type qualifier. + +Example: + +``` markdown +!!! note "Phasellus posuere in sem ut cursus" + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! note "Phasellus posuere in sem ut cursus" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +### Removing the title + +Similar to setting a [custom title][3], the icon and title can be omitted by +providing an empty string after the type qualifier: + +Example: + +``` markdown +!!! note "" + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! note "" + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + + [3]: #changing-the-title + +### Embedded code blocks + +Blocks can contain all kinds of text content, including headlines, lists, +paragraphs and other blocks – except code blocks, because the parser from the +standard Markdown library does not account for those. + +However, the [PyMdown Extensions][4] package adds an extension called +[SuperFences][5], which makes it possible to nest code blocks within other +blocks. + + [4]: https://facelessuser.github.io/pymdown-extensions + [5]: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/ + +Example: + +!!! note + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + + ``` mysql + SELECT + Employees.EmployeeID, + Employees.Name, + Employees.Salary, + Manager.Name AS Manager + FROM + Employees + LEFT JOIN + Employees AS Manager + ON + Employees.ManagerID = Manager.EmployeeID + WHERE + Employees.EmployeeID = '087652'; + ``` + + Nunc eu odio eleifend, blandit leo a, volutpat sapien. Phasellus posuere in + sem ut cursus. Nullam sit amet tincidunt ipsum, sit amet elementum turpis. + Etiam ipsum quam, mattis in purus vitae, lacinia fermentum enim. + +## Types + +Admonition supports user-defined type qualifiers which may influence the style +of the inserted block. Following is a list of type qualifiers supported by the +Material theme, whereas the default type, and thus fallback for unknown type +qualifiers, is [note][6]. + + [6]: #note + +### Note + +Example: + +``` markdown +!!! note + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! note + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `note` +* `seealso` + +### Summary + +Example: + +``` markdown +!!! summary + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! summary + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `summary` +* `tldr` + +### Tip + +Example: + +``` markdown +!!! tip + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! tip + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `tip` +* `hint` +* `important` + +### Success + +Example: + +``` markdown +!!! success + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! success + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `success` +* `check` +* `done` + +### Warning + +Example: + +``` markdown +!!! warning + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! warning + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `warning` +* `caution` +* `attention` + +### Failure + +Example: + +``` markdown +!!! failure + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! failure + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `failure` +* `fail` +* `missing` + +### Danger + +Example: + +``` markdown +!!! danger + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! danger + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `danger` +* `error` + +### Bug + +Example: + +``` markdown +!!! bug + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + +!!! bug + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. + +Qualifiers: + +* `bug` diff --git a/docs/extensions/codehilite.md b/docs/extensions/codehilite.md new file mode 100644 index 000000000..c5367aa5f --- /dev/null +++ b/docs/extensions/codehilite.md @@ -0,0 +1,855 @@ +# CodeHilite + +[CodeHilite][1] is an extension that adds syntax highlighting to code blocks +and is included in the standard Markdown library. The highlighting process is +executed during compilation of the Markdown file. + + [1]: https://pythonhosted.org/Markdown/extensions/code_hilite.html + +## Installation + +CodeHilite parses code blocks and wraps them in `<pre>` tags. If [Pygments][2] +is installed, which is a generic syntax highlighter with support for over +[300 languages][3], CodeHilite will also highlight the code block. Pygments can +be installed with the following command: + +``` sh +pip install pygments +``` + +To enable CodeHilite, add the following lines to your `mkdocs.yml`: + +``` yaml +markdown_extensions: + - codehilite +``` + +!!! warning "Migrating from Material 0.2.x" + + In 0.2.x the CodeHilite extension was included with + `codehilite(css_class=code)` which switched the CSS class from + `.codehilite` to `.code`. The current version of the theme doesn't require + that and defines styles for the default `.codehilite` class, so the part + `css_class=code` needs to be removed. + + [2]: http://pygments.org + [3]: http://pygments.org/languages + +## Usage + +### Specifying the language + +The CodeHilite extension uses the same syntax as regular Markdown code blocks, +but needs to know the language of the code block. This can be done in three +different ways. + +#### via Markdown syntax <small>recommended</small> + +In Markdown, code blocks can be opened and closed by writing three backticks on +separate lines. To add code highlighting to those blocks, the easiest way is +to specify the language directly after the opening block. + +Example: + +```` markdown +``` python +import tensorflow as tf +``` +```` + +Result: + +``` python +import tensorflow as tf +``` + +#### via Shebang + +Alternatively, if the first line of a code block contains a shebang, the +language is derived from the path referenced in the shebang. This will only +work for code blocks that are indented using four spaces, not for those +encapsulated in three backticks. + +Example: + +```` markdown + #!/usr/bin/python + import tensorflow as tf +```` + +Result: + +``` python +#!/usr/bin/python +import tensorflow as tf +``` + +#### via three colons + +If the first line starts with three colons followed by a language identifier, +the first line is stripped. This will only work for code blocks that are +indented using four spaces, not for those encapsulated in three backticks. + +Example: + +``` markdown + :::python + import tensorflow as tf +``` + +Result: + + :::python + import tensorflow as tf + +### Adding line numbers + +Line numbers can be added by enabling the `linenums` flag in your `mkdocs.yml`: + +``` yaml +markdown_extensions: + - codehilite(linenums=true) +``` + +Example: + +```` markdown +``` python +""" Bubble sort """ +def bubble_sort(items): + for i in range(len(items)): + for j in range(len(items) - 1 - i): + if items[j] > items[j + 1]: + items[j], items[j + 1] = items[j + 1], items[j] +``` +```` + +Result: + + #!python + """ Bubble sort """ + def bubble_sort(items): + for i in range(len(items)): + for j in range(len(items) - 1 - i): + if items[j] > items[j + 1]: + items[j], items[j + 1] = items[j + 1], items[j] + +### Highlighting specific lines + +Specific lines can be highlighted by passing the line numbers to the `hl_lines` +argument placed right after the language identifier. Line counts start at 1. + +Example: + +```` markdown +``` python hl_lines="3 4" +""" Bubble sort """ +def bubble_sort(items): + for i in range(len(items)): + for j in range(len(items) - 1 - i): + if items[j] > items[j + 1]: + items[j], items[j + 1] = items[j + 1], items[j] +``` +```` + +Result: + + #!python hl_lines="3 4" + """ Bubble sort """ + def bubble_sort(items): + for i in range(len(items)): + for j in range(len(items) - 1 - i): + if items[j] > items[j + 1]: + items[j], items[j + 1] = items[j + 1], items[j] + + +## Supported languages <small>excerpt</small> + +CodeHilite uses [Pygments][2], a generic syntax highlighter with support for +over [300 languages][3], so the following list of examples is just an excerpt. + +### Bash + +``` bash +#!/bin/bash + +for OPT in "$@" +do + case "$OPT" in + '-f' ) canonicalize=1 ;; + '-n' ) switchlf="-n" ;; + esac +done + +# readlink -f +function __readlink_f { + target="$1" + while test -n "$target"; do + filepath="$target" + cd `dirname "$filepath"` + target=`readlink "$filepath"` + done + /bin/echo $switchlf `pwd -P`/`basename "$filepath"` +} + +if [ ! "$canonicalize" ]; then + readlink $switchlf "$@" +else + for file in "$@" + do + case "$file" in + -* ) ;; + * ) __readlink_f "$file" ;; + esac + done +fi + +exit $? +``` + +### C + +``` c +extern size_t +pb_varint_scan(const uint8_t data[], size_t left) { + assert(data && left); + left = left > 10 ? 10 : left; + +#ifdef __SSE2__ + + /* Mapping: remaining bytes ==> bitmask */ + static const int mask_map[] = { + 0x0000, 0x0001, 0x0003, 0x0007, + 0x000F, 0x001F, 0x003F, 0x007F, + 0x00FF, 0x01FF, 0x03FF + }; + + /* Load buffer into 128-bit integer and create high-bit mask */ + __m128i temp = _mm_loadu_si128((const __m128i *)data); + __m128i high = _mm_set1_epi8(0x80); + + /* Intersect and extract mask with high-bits set */ + int mask = _mm_movemask_epi8(_mm_and_si128(temp, high)); + mask = (mask & mask_map[left]) ^ mask_map[left]; + + /* Count trailing zeroes */ + return mask ? __builtin_ctz(mask) + 1 : 0; + +#else + + /* Linear scan */ + size_t size = 0; + while (data[size++] & 0x80) + if (!--left) + return 0; + return size; + +#endif /* __SSE2__ */ + +} +``` + +### C++ + +``` cpp +Extension:: +Extension(const Descriptor *descriptor, const Descriptor *scope) : + descriptor_(descriptor), + scope_(scope) { + + /* Extract full name for signature */ + variables_["signature"] = descriptor_->full_name(); + + /* Prepare message symbol */ + variables_["message"] = StringReplace( + variables_["signature"], ".", "_", true); + LowerString(&(variables_["message"])); + + /* Suffix scope to identifiers, if given */ + string suffix (""); + if (scope_) { + suffix = scope_->full_name(); + + /* Check if the base and extension types are in the same package */ + if (!scope_->file()->package().compare(descriptor_->file()->package())) + suffix = StripPrefixString(suffix, + scope_->file()->package() + "."); + + /* Append to signature */ + variables_["signature"] += ".[" + suffix +"]"; + suffix = "_" + suffix; + } + + /* Prepare extension symbol */ + variables_["extension"] = StringReplace( + suffix, ".", "_", true); + LowerString(&(variables_["extension"])); +} +``` + +### C# + +``` csharp +public static void Send( + Socket socket, byte[] buffer, int offset, int size, int timeout) { + int startTickCount = Environment.TickCount; + int sent = 0; + do { + if (Environment.TickCount > startTickCount + timeout) + throw new Exception("Timeout."); + try { + sent += socket.Send(buffer, offset + sent, + size - sent, SocketFlags.None); + } catch (SocketException ex) { + if (ex.SocketErrorCode == SocketError.WouldBlock || + ex.SocketErrorCode == SocketError.IOPending || + ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable) { + /* Socket buffer is probably full, wait and try again */ + Thread.Sleep(30); + } else { + throw ex; + } + } + } while (sent < size); +} +``` + +### Clojure + +``` clojure +(clojure-version) + +(defn partition-when + [f] + (fn [rf] + (let [a (java.util.ArrayList.) + fval (volatile! false)] + (fn + ([] (rf)) + ([result] + (let [result (if (.isEmpty a) + result + (let [v (vec (.toArray a))] + ;; Clear first + (.clear a) + (unreduced (rf result v))))] + (rf result))) + ([result input] + (if-not (and (f input) @fval) + (do + (vreset! fval true) + (.add a input) + result) + (let [v (vec (.toArray a))] + (.clear a) + (let [ret (rf result v)] + (when-not (reduced? ret) + (.add a input)) + ret)))))))) + + +(into [] (partition-when + #(.startsWith % ">>")) + ["1d" "33" ">> 1" ">> 2" "22" ">> 3"]) +``` + +### Diff + +``` diff +Index: grunt.js +=================================================================== +--- grunt.js (revision 31200) ++++ grunt.js (working copy) +@@ -12,6 +12,7 @@ + + module.exports = function (grunt) { + ++ console.log('hello world'); + // Project configuration. + grunt.initConfig({ + lint: { +@@ -19,10 +20,6 @@ + 'packages/services.web/{!(test)/**/,}*.js', + 'packages/error/**/*.js' + ], +- scripts: [ +- 'grunt.js', +- 'db/**/*.js' +- ], + browser: [ + 'packages/web/server.js', + 'packages/web/server/**/*.js', +``` + +### Docker + +``` docker +FROM ubuntu + +# Install vnc, xvfb in order to create a 'fake' display and firefox +RUN apt-get update && apt-get install -y x11vnc xvfb firefox +RUN mkdir ~/.vnc + +# Setup a password +RUN x11vnc -storepasswd 1234 ~/.vnc/passwd + +# Autostart firefox (might not be the best way, but it does the trick) +RUN bash -c 'echo "firefox" >> /.bashrc' + +EXPOSE 5900 +CMD ["x11vnc", "-forever", "-usepw", "-create"] +``` + +### Elixir + +``` elixir +require Logger + +def accept(port) do + {:ok, socket} = :gen_tcp.listen(port, + [:binary, packet: :line, active: false, reuseaddr: true]) + Logger.info "Accepting connections on port #{port}" + loop_acceptor(socket) +end + +defp loop_acceptor(socket) do + {:ok, client} = :gen_tcp.accept(socket) + serve(client) + loop_acceptor(socket) +end + +defp serve(socket) do + socket + |> read_line() + |> write_line(socket) + + serve(socket) +end + +defp read_line(socket) do + {:ok, data} = :gen_tcp.recv(socket, 0) + data +end + +defp write_line(line, socket) do + :gen_tcp.send(socket, line) +end +``` + +### Erlang + +``` erlang +circular(Defs) -> + [ { { Type, Base }, Fields } || + { { Type, Base }, Fields } <- Defs, Type == msg, circular(Base, Defs) ]. + +circular(Base, Defs) -> + Fields = proplists:get_value({ msg, Base }, Defs), + circular(Defs, Fields, [Base]). + +circular(_Defs, [], _Path) -> + false; +circular(Defs, [Field | Fields], Path) -> + case Field#field.type of + { msg, Type } -> + case lists:member(Type, Path) of + false -> + Children = proplists:get_value({ msg, Type }, Defs), + case circular(Defs, Children, [Type | Path]) of + false -> circular(Defs, Fields, Path); + true -> true + end; + true -> + Type == lists:last(Path) andalso + (length(Path) == 1 orelse not is_tree(Path)) + end; + _ -> + circular(Defs, Fields, Path) + end. +``` + +### F# + +``` fsharp +/// Asynchronously download retangles from the server +/// and decode the JSON format to F# Rectangle record +let [<Js>] getRectangles () : Async<Rectangle[]> = async { + let req = XMLHttpRequest() + req.Open("POST", "/get", true) + let! resp = req.AsyncSend() + return JSON.parse(resp) } + +/// Repeatedly update rectangles after 0.5 sec +let [<Js>] updateLoop () = async { + while true do + do! Async.Sleep(500) + let! rects = getRectangles() + cleanRectangles() + rects |> Array.iter createRectangle } +``` + +### Go + +``` go +package main + +import "fmt" + +func counter(id int, channel chan int, closer bool) { + for i := 0; i < 10000000; i++ { + fmt.Println("process", id," send", i) + channel <- 1 + } + if closer { close(channel ) } +} + +func main() { + channel := make(chan int) + go counter(1, channel, false) + go counter(2, channel, true) + + x := 0 + + // receiving data from channel + for i := range channel { + fmt.Println("receiving") + x += i + } + + fmt.Println(x) +} +``` + +### HTML + +``` html +<!doctype html> +<html class="no-js" lang=""> + <head> + <meta charset="utf-8"> + <meta http-equiv="x-ua-compatible" content="ie=edge"> + <title>HTML5 Boilerplate + + + + + + + + + +

Hello world! This is HTML5 Boilerplate.

+ + +``` + +### Java + +``` java +import java.util.LinkedList; +import java.lang.reflect.Array; + +public class UnsortedHashSet { + + private static final double LOAD_FACTOR_LIMIT = 0.7; + + private int size; + private LinkedList[] con; + + public UnsortedHashSet() { + con = (LinkedList[])(new LinkedList[10]); + } + + public boolean add(E obj) { + int oldSize = size; + int index = Math.abs(obj.hashCode()) % con.length; + if (con[index] == null) + con[index] = new LinkedList(); + if (!con[index].contains(obj)) { + con[index].add(obj); + size++; + } + if (1.0 * size / con.length > LOAD_FACTOR_LIMIT) + resize(); + return oldSize != size; + } + + private void resize() { + UnsortedHashSet temp = new UnsortedHashSet(); + temp.con = (LinkedList[])(new LinkedList[con.length * 2 + 1]); + for (int i = 0; i < con.length; i++) { + if (con[i] != null) + for (E e : con[i]) + temp.add(e); + } + con = temp.con; + } + + public int size() { + return size; + } +} +``` + +### JavaScript + +``` javascript +var Math = require('lib/math'); + +var _extends = function (target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + target[key] = source[key]; + } + } + + return target; +}; + +var e = exports.e = 2.71828182846; +exports['default'] = function (x) { + return Math.exp(x); +}; + +module.exports = _extends(exports['default'], exports); +``` + +### JSON + +``` json +{ + "name": "mkdocs-material", + "version": "0.2.4", + "description": "A Material Design theme for MkDocs", + "homepage": "http://squidfunk.github.io/mkdocs-material/", + "authors": [ + "squidfunk " + ], + "license": "MIT", + "main": "Gulpfile.js", + "scripts": { + "start": "./node_modules/.bin/gulp watch --mkdocs", + "build": "./node_modules/.bin/gulp build --production" + } + ... +} +``` + +### Julia + +``` julia +using MXNet + +mlp = @mx.chain mx.Variable(:data) => + mx.FullyConnected(name=:fc1, num_hidden=128) => + mx.Activation(name=:relu1, act_type=:relu) => + mx.FullyConnected(name=:fc2, num_hidden=64) => + mx.Activation(name=:relu2, act_type=:relu) => + mx.FullyConnected(name=:fc3, num_hidden=10) => + mx.SoftmaxOutput(name=:softmax) + +# data provider +batch_size = 100 +include(Pkg.dir("MXNet", "examples", "mnist", "mnist-data.jl")) +train_provider, eval_provider = get_mnist_providers(batch_size) + +# setup model +model = mx.FeedForward(mlp, context=mx.cpu()) + +# optimization algorithm +optimizer = mx.SGD(lr=0.1, momentum=0.9) + +# fit parameters +mx.fit(model, optimizer, train_provider, n_epoch=20, eval_data=eval_provider) +``` + +### Lua + +``` lua +local ffi = require("ffi") + +ffi.cdef[[ + void Sleep(int ms); + int poll(struct pollfd *fds, unsigned long nfds, int timeout); +]] + +local sleep +if ffi.os == "Windows" then + function sleep(s) + ffi.C.Sleep(s*1000) + end +else + function sleep(s) + ffi.C.poll(nil, 0, s * 1000) + end +end + +for i = 1,160 do + io.write("."); io.flush() + sleep(0.01) +end +io.write("\n") +``` + +### MySQL + +``` mysql +SELECT + Employees.EmployeeID, + Employees.Name, + Employees.Salary, + Manager.Name AS Manager +FROM + Employees +LEFT JOIN + Employees AS Manager +ON + Employees.ManagerID = Manager.EmployeeID +WHERE + Employees.EmployeeID = '087652'; +``` + +### PHP + +``` php +Lucky number: '.$number.'' + ); + } +} +``` + +### Protocol Buffers + +``` proto +syntax = "proto2"; + +package caffe; + +// Specifies the shape (dimensions) of a Blob. +message BlobShape { + repeated int64 dim = 1 [packed = true]; +} + +message BlobProto { + optional BlobShape shape = 7; + repeated float data = 5 [packed = true]; + repeated float diff = 6 [packed = true]; + + // 4D dimensions -- deprecated. Use "shape" instead. + optional int32 num = 1 [default = 0]; + optional int32 channels = 2 [default = 0]; + optional int32 height = 3 [default = 0]; + optional int32 width = 4 [default = 0]; +} +``` + +### Python + +``` python + +""" + A very simple MNIST classifier. + See extensive documentation at + http://tensorflow.org/tutorials/mnist/beginners/index.md +""" +from __future__ import absolute_import +from __future__ import division +from __future__ import print_function + +# Import data +from tensorflow.examples.tutorials.mnist import input_data + +import tensorflow as tf + +flags = tf.app.flags +FLAGS = flags.FLAGS +flags.DEFINE_string('data_dir', '/tmp/data/', 'Directory for storing data') + +mnist = input_data.read_data_sets(FLAGS.data_dir, one_hot=True) + +sess = tf.InteractiveSession() + +# Create the model +x = tf.placeholder(tf.float32, [None, 784]) +W = tf.Variable(tf.zeros([784, 10])) +b = tf.Variable(tf.zeros([10])) +y = tf.nn.softmax(tf.matmul(x, W) + b) +``` + +### Ruby + +``` ruby +require 'finity/event' +require 'finity/machine' +require 'finity/state' +require 'finity/transition' +require 'finity/version' + +module Finity + class InvalidCallback < StandardError; end + class MissingCallback < StandardError; end + class InvalidState < StandardError; end + + # Class methods to be injected into the including class upon inclusion. + module ClassMethods + + # Instantiate a new state machine for the including class by accepting a + # block with state and event (and subsequent transition) definitions. + def finity options = {}, &block + @finity ||= Machine.new self, options, &block + end + + # Return the names of all registered states. + def states + @finity.states.map { |name, _| name } + end + + # Return the names of all registered events. + def events + @finity.events.map { |name, _| name } + end + end + + # Inject methods into the including class upon inclusion. + def self.included base + base.extend ClassMethods + end +end +``` + +### XML + +``` xml + + + + + + + Some text content + Some text content with <entities> and + mentioning uint8_t and int32_t + + + + +``` diff --git a/docs/extensions/footnotes.md b/docs/extensions/footnotes.md new file mode 100644 index 000000000..a33458bc7 --- /dev/null +++ b/docs/extensions/footnotes.md @@ -0,0 +1,84 @@ +# Footnotes + +[Footnotes][1] is another extension included in the standard Markdown library. +As the name says, it adds the ability to add footnotes to your documentation. + + [1]: https://pythonhosted.org/Markdown/extensions/footnotes.html + +## Installation + +Add the following lines to your `mkdocs.yml`: + +``` yaml +markdown_extensions: + - footnotes +``` + +## Usage + +The markup for footnotes is similar to the standard Markdown markup for links. +A reference is inserted in the text, which can then be defined at any point in +the document. + +### Inserting the reference + +The footnote reference is enclosed in square brackets and starts with a caret, +followed by an arbitrary label which may contain numeric identifiers [1, 2, 3, +...] or names [Granovetter et al. 1998]. The rendered references are always +consecutive superscripted numbers. + +Example: + +``` markdown +Lorem ipsum[^1] dolor sit amet, consectetur adipiscing elit.[^2] +``` + +Result: + +Lorem ipsum[^1] dolor sit amet, consectetur adipiscing elit.[^2] + +### Inserting the content + +The footnote content is also declared with a label, which must match the label +used for the footnote reference. It can be inserted at an arbitrary position in +the document and is always rendered at the bottom of the page. Furthermore, a +backlink is automatically added to the footnote reference. + +#### on a single line + +Short statements can be written on the same line. + +Example: + +``` markdown +[^1]: Lorem ipsum dolor sit amet, consectetur adipiscing elit. +``` + +Result: + +Jump to footnote at the bottom of the page + + [^1]: Lorem ipsum dolor sit amet, consectetur adipiscing elit. + +#### on multiple lines + +Paragraphs should be written on the next line. As with all Markdown blocks, the +content must be indented by four spaces. + +Example: + +``` markdown +[^2]: + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus auctor + massa, nec semper lorem quam in massa. +``` + +Result: + + [^2]: + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nulla et euismod + nulla. Curabitur feugiat, tortor non consequat finibus, justo purus + auctor massa, nec semper lorem quam in massa. + +Jump to footnote at the bottom of the page diff --git a/docs/extensions/permalinks.md b/docs/extensions/permalinks.md new file mode 100644 index 000000000..3269c834d --- /dev/null +++ b/docs/extensions/permalinks.md @@ -0,0 +1,31 @@ +# Permalinks + +Permalinks are a feature of the [Table of Contents][1] extension, which is part +of the standard Markdown library. The extension inserts an anchor at the end of +each headline, which makes it possible to directly link to a subpart of the +document. + + [1]: https://pythonhosted.org/Markdown/extensions/toc.html + +## Installation + +To enable permalinks, add the following to your `mkdocs.yml`: + +``` yaml +markdown_extensions: + - toc(permalink=true) +``` + +This will add a link containing the paragraph symbol `¶` at the end of each +headline (exactly like on the page you're currently viewing), which the +Material theme will make appear on hover. In order to change the text of the +permalink, a string can be passed, e.g.: + +``` markdown +markdown_extensions: + - toc(permalink=Link) +``` + +## Usage + +When enabled, permalinks are inserted automatically. diff --git a/docs/extensions/pymdown.md b/docs/extensions/pymdown.md new file mode 100644 index 000000000..e375db2aa --- /dev/null +++ b/docs/extensions/pymdown.md @@ -0,0 +1,284 @@ +# PyMdown Extensions + +[PyMdown Extensions][1] is a collection of Markdown extensions that add some +great features to the standard Markdown library. For this reason, the +**installation of this package is highly recommended** as it's well-integrated +with the Material theme. + + [1]: http://facelessuser.github.io/pymdown-extensions/ + +## Installation + +The PyMdown Extensions package can be installed with the following command: + +``` sh +pip install pymdown-extensions +``` + +The following list of extensions that are part of the PyMdown Extensions +package are recommended to be used together with the Material theme: + +``` yaml +markdown_extensions: + - pymdownx.arithmatex + - pymdownx.betterem(smart_enable=all) + - pymdownx.caret + - pymdownx.critic + - pymdownx.emoji: + emoji_generator: !!python/name:pymdownx.emoji.to_svg + - pymdownx.inlinehilite + - pymdownx.magiclink + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences + - pymdownx.tasklist(custom_checkbox=true) + - pymdownx.tilde +``` + +## Usage + +### GitHub Flavored Markdown + +Most of the extensions included in the PyMdown Extensions package try to bring +the Markdown experience closer to GitHub Flavored Markdown (GFM). + +The PyMdown Extensions package adds a shorthand to enable all of the included +extensions that provide the GFM experience. However, usage of the shorthand is +discouraged, because some extensions are not supported, as the Material theme +uses some incompatible extensions included in the standard Markdown library. + +#### BetterEm + +[BetterEm][2] improves the handling of emphasis markup (**bold** and *italic*) +within Markdown by providing a more sophisticated parser for better detecting +start and end tokens. Read the documentation for [usage notes][3]. + + [2]: https://facelessuser.github.io/pymdown-extensions/extensions/betterem/ + [3]: https://facelessuser.github.io/pymdown-extensions/usage_notes/ + +#### Emoji + +[Emoji][4] adds the ability to insert a :shit:-load of emojis that we use in +our daily lives. See the [EmojiOne demo][5] for a list of all available +emojis. Happy scrolling :tada: + +!!! warning "Legal disclaimer" + + Material has no affiliation with [EmojiOne][6] which is released under + [CC BY 4.0][7]. When including EmojiOne images or CSS, please read the + [EmojiOne license][8] to ensure proper usage and attribution. + + [4]: https://facelessuser.github.io/pymdown-extensions/extensions/emoji/ + [5]: http://emojione.com/demo/ + [6]: http://emojione.com + [7]: https://creativecommons.org/licenses/by/4.0/legalcode + [8]: http://emojione.com/licensing/ + +#### MagicLink + +[MagicLink][9] detects links in Markdown and auto-generates the necessary +markup, so no special syntax is required. It auto-links `http[s]://` and +`ftp://` links, as well as references to email addresses: + + [9]: https://facelessuser.github.io/pymdown-extensions/extensions/magiclink/ + +#### SuperFences + +[SuperFences][10] provides the ability to nest code blocks under blockquotes, +lists and other block elements, which the [Fenced Code Blocks][11] extension +from the standard Markdown library doesn't parse correctly. + + [10]: https://facelessuser.github.io/pymdown-extensions/extensions/superfences/ + [11]: https://pythonhosted.org/Markdown/extensions/fenced_code_blocks.html + +#### Tasklist + +[Tasklist][12] adds support for styled checkbox lists. This is useful for +keeping track of tasks and showing what has been done and has yet to be done. +Checkbox lists are like regular lists, but prefixed with `[ ]` for empty or +`[x]` for filled checkboxes. + +Example: + +``` markdown +* [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit +* [x] Nulla lobortis egestas semper +* [x] Curabitur elit nibh, euismod et ullamcorper at, iaculis feugiat est +* [ ] Vestibulum convallis sit amet nisi a tincidunt + * [x] In hac habitasse platea dictumst + * [x] In scelerisque nibh non dolor mollis congue sed et metus + * [x] Sed egestas felis quis elit dapibus, ac aliquet turpis mattis + * [ ] Praesent sed risus massa +* [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque +* [ ] Nulla vel eros venenatis, imperdiet enim id, faucibus nisi +``` + +Result: + +* [x] Lorem ipsum dolor sit amet, consectetur adipiscing elit +* [x] Nulla lobortis egestas semper +* [x] Curabitur elit nibh, euismod et ullamcorper at, iaculis feugiat est +* [ ] Vestibulum convallis sit amet nisi a tincidunt + * [x] In hac habitasse platea dictumst + * [x] In scelerisque nibh non dolor mollis congue sed et metus + * [x] Sed egestas felis quis elit dapibus, ac aliquet turpis mattis + * [ ] Praesent sed risus massa +* [ ] Aenean pretium efficitur erat, donec pharetra, ligula non scelerisque +* [ ] Nulla vel eros venenatis, imperdiet enim id, faucibus nisi + +[12]: https://facelessuser.github.io/pymdown-extensions/extensions/tasklist/ + +#### Tilde + +[Tilde][13] provides an easy way to ~~strike through~~ cross out text. +The portion of text that should be erased must be enclosed in two tildes +`~~...~~` and the extension will take care of the rest. + + [13]: https://facelessuser.github.io/pymdown-extensions/extensions/tilde/ + +### More syntactic sugar + +#### Caret + +[Caret][14] is the sister extension of [Tilde][15] and makes it possible to +highlight ^^inserted text^^. The portion of text that should be marked as added +must be enclosed in two carets `^^...^^`. + + [14]: https://facelessuser.github.io/pymdown-extensions/extensions/caret/ + [15]: #tilde + +#### Mark + +[Mark][16] adds the ability to ==highlight text== like it was marked with a +==yellow text marker==. The portion of text that should be highlighted must be +enclosed in two equal signs `==...==`. + + [16]: https://facelessuser.github.io/pymdown-extensions/extensions/mark/ + +#### SmartSymbols + +[SmartSymbols][17] converts markup for special characters into their +corresponding symbols, e.g. arrows (<--, -->, <-->), trademark and copyright +symbols ((c), (tm), (r)) and fractions (1/2, 1/4, ...). + + [17]: https://facelessuser.github.io/pymdown-extensions/extensions/smartsymbols/ + +#### Critic + +[Critic][18] implements [Critic Markup][19], a Markdown extension that enables +the tracking of changes (additions, deletions and comments) on documents. +During compilation of the Markdown document, changes can be rendered (default), +accepted or rejected. + +Text can be {--deleted--} and replacement text {++added++}. This can also be +combined into {~~one~>a single~~} operation. {==Highlighting==} is also +possible {>>and comments can be added inline<<}. + +{== + +Formatting can also be applied to blocks, by putting the opening and closing +tags on separate lines and adding new lines between the tags and the content. + +==} + + [18]: https://facelessuser.github.io/pymdown-extensions/extensions/critic/ + [19]: http://criticmarkup.com/ + +### Arithmatex MathJax + + + +[Arithmatex][20] integrates Material with [MathJax][21] which parses +block-style and inline equations written in TeX markup and outputs them in +mathematical notation. See [this thread][22] for a short introduction and quick +reference on how to write equations in TeX syntax. + +Besides activating the extension in the `mkdocs.yml`, the MathJax JavaScript +runtime needs to be included. This must be done with +[additional JavaScript][23]: + +``` yaml +extra_javascript: + - 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML' +``` + +If you want to override the default MathJax configuration, you can do this by +adding another JavaScript file **before** the MathJax runtime in +`extra_javascript` which contains your MathJax configuration, e.g.: + +``` js +window.MathJax = { + tex2jax: { + inlineMath: [ ["\\(","\\)"] ], + displayMath: [ ["\\[","\\]"] ] + }, + TeX: { + TagSide: "right", + TagIndent: ".8em", + MultLineWidth: "85%", + equationNumbers: { + autoNumber: "AMS", + }, + unicode: { + fonts: "STIXGeneral,'Arial Unicode MS'" + } + }, + displayAlign: "left", + showProcessingMessages: false, + messageStyle: "none" +}; +``` + +In your `mkdocs.yml`, include it with: + +``` yaml +extra_javascript: + - 'javascripts/extra.js' + - 'https://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-MML-AM_CHTML' +``` + + [20]: https://facelessuser.github.io/pymdown-extensions/extensions/arithmatex/ + [21]: https://www.mathjax.org/ + [22]: http://meta.math.stackexchange.com/questions/5020/ + [23]: ../customization.md#additional-javascript + +#### Blocks + +Blocks are enclosed in `:::tex $$...$$` which are placed on separate lines. + +Example: + +``` tex +$$ +\frac{n!}{k!(n-k)!} = \binom{n}{k} +$$ +``` + +Result: + +$$ +\frac{n!}{k!(n-k)!} = \binom{n}{k} +$$ + +#### Inline + +Inline equations need to be enclosed in `:::tex $...$`: + +Example: + +``` tex +Lorem ipsum dolor sit amet: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$ +``` + +Result: + +Lorem ipsum dolor sit amet: $p(x|y) = \frac{p(y|x)p(x)}{p(y)}$ + +### InlineHilite + +[InlineHilite][24] adds support for inline code highlighting. It's useful for +short snippets included within body copy, e.g. `#!js var test = 0;` and can be +achived by prefixing inline code with a shebang and language identifier, +e.g. `#!js`. + + [24]: https://facelessuser.github.io/pymdown-extensions/extensions/inlinehilite/ diff --git a/docs/getting-started.md b/docs/getting-started.md index f3f578e8a..1d770d6b9 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -4,130 +4,117 @@ ### Installing MkDocs -Before installing [MkDocs][], you need to make sure you have Python and `pip` -– the Python package manager – up and running. Assuming you are a developer and -have a basic understanding of how things work and what StackOverflow is, we -won't provide guidelines on setting those up. You can verify if you're already +Before installing [MkDocs][2], you need to make sure you have Python and `pip` +– the Python package manager – up and running. You can verify if you're already good to go with the following commands: ``` sh python --version -# Python 2.7.2 +# Python 2.7.13 pip --version -# pip 1.5.2 +# pip 9.0.1 ``` Installing and verifying MkDocs is as simple as: ``` sh pip install mkdocs && mkdocs --version -# mkdocs, version 0.15.2 +# mkdocs, version 0.16.0 ``` +!!! warning "MkDocs for Material requirements" + + Material requires MkDocs >= 0.16. + +Furthermore, it is highly recommended to install [Pygments][3] and the +[PyMdown Extensions][4] to get the most out of the Material theme: + +```sh +pip install pygments +pip install pymdown-extensions +``` + + [1]: https://hub.docker.com/r/squidfunk/mkdocs-material/ + [2]: http://www.mkdocs.org + [3]: http://pygments.org + [4]: http://facelessuser.github.io/pymdown-extensions/ + ### Installing Material -Next, assuming you have MkDocs up and running `mkdocs-material` can be -installed with `pip`: +#### by using pip + +Material can be installed with `pip`: ``` sh pip install mkdocs-material ``` -## Usage +!!! warning "Installation on macOS" -If you haven't already done it, creating a new documentation project is really -simple in MkDocs: + When you're running the pre-installed version of Python on macOS, `pip` + tries to install packages in a folder for which your user might not have + the adequate permissions. There are two possible solutions to this: + + 1. **Installing in user space** (recommended): Provide the `--user` flag + to the install command and `pip` will install the package in a user-site + location. This is the recommended way. + + 2. **Switching to a homebrewed Python**: Upgrade your Python installation + to a self-contained solution by installing Python with Homebrew. This + should eliminate a lot of problems you may be having with `pip`. + +#### by cloning from GitHub + +Material can also be used without a system-wide installation by cloning the +repository into a subfolder of your project's root directory: ``` sh -mkdocs new my-project -cd my-project +git clone https://github.com/squidfunk/mkdocs-material.git ``` -MkDocs will create the necessary files and base directory structure inside the -folder `my-project`. In order to enable the theme just add the following line -to the auto-generated `mkdocs.yml`: +This is especially useful if you want to extend the theme and override some +parts of the theme. The theme will reside in the folder +`mkdocs-material/material`. + +## Usage + +In order to enable the Material theme just add one of the following lines to +your `mkdocs.yml`. If you installed Material using pip: ``` yaml theme: 'material' ``` -If your project is hosted on GitHub, add the repository link to the -configuration. If the `repo_name` equals **GitHub**, the Material theme will -add a download and star button, and display the number of stars: +If you cloned Material from GitHub: ``` yaml -repo_name: 'GitHub' -repo_url: 'https://github.com/my-github-handle/my-project' +theme_dir: 'mkdocs-material/material' ``` -MkDocs includes a development server, so you can view your changes as you go - -very handy. Spin it up with the following command: +MkDocs includes a development server, so you can view your changes as you go. +The development server can be started with the following command: ``` sh mkdocs serve ``` -Now you can go to [localhost:8000](http://localhost:8000) and the Material -theme should be visible. You can now start writing your documentation, or read -on and customize the theme through some options. +Now you can point your browser to [localhost:8000][5] and the Material theme +should be visible. From here on, you can start writing your documentation, or +read on and customize the theme through some options. + + [5]: http://localhost:8000 ## Options The Material theme adds some extra variables for configuration via your project's `mkdocs.yml`. See the following section for all available options. -### Adding a version - -In order to add the current version next to the project banner inside the -drawer, you can set the variable `extra.version`: - -``` yaml -extra: - version: '0.1.0' -``` - -This will also change the link behind the download button to point to the -archive with the respective version on GitHub, assuming a release tagged with -this exact version identifier. - -### Adding a logo - -If your project has a logo, you can add it to the drawer/navigation by defining -the variable `extra.logo`. Ideally, the image of your logo should have -rectangular shape with a minimum resolution of 128x128 and leave some room -towards the edges. The logo will also be used as a web application icon on iOS. -Simply create the folder `docs/images`, add your image and reference it via: - -``` yaml -extra: - logo: 'images/logo.png' -``` - -### Link to GitHub releases page - -If your project has a GitHub url configured, the default behavior is that a -downlink button is displayed, linking to the source download of the given -`extra.version` or `master` branch. To link to the releases page instead, -set `extra.github.download_release` to `true`. It will link to the release of -the given `extra.version` or when no `extra.version` is given, the latest -release: - -``` yaml -repo_name: GitHub -repo_url: https://github.com/squidfunk/mkdocs-material - -extra: - github: - download_release: true -``` - - ### Changing the color palette Material defines a default hue for every primary and accent color on Google's -material design [color palette][]. This makes it very easy to change the -overall look of the theme. Just set the variables `extra.palette.primary` and -`extra.palette.accent` to one of the colors defined in the palette: +Material Design [color palette][6]. This makes it very easy to change the +overall look of the theme. Just set the primary and accent colors using the +following variables in your `mkdocs.yml`: ``` yaml extra: @@ -136,74 +123,154 @@ extra: accent: 'light blue' ``` -Color names can be written upper- or lowercase but must match the names of the -material design [color palette][]. Valid values are: _red_, _pink_, _purple_, -_deep purple_, _indigo_, _blue_, _light blue_, _cyan_, _teal_, _green_, _light -green_, _lime_, _yellow_, _amber_, _orange_, _deep orange_, _brown_, _grey_ and -_blue grey_. The last three colors can only be used as a primary color. +Color names are case-insensitive, but must match the names of the Material +Design color palette. Valid values are: `red`, `pink`, `purple`, `deep purple`, +`indigo`, `blue`, `light blue`, `cyan`, `teal`, `green`, `light green`, `lime`, +`yellow`, `amber`, `orange`, `deep orange`, `brown`, `grey` and `blue grey`. +The last three colors can only be used as a primary color. -![Material Screenshot](images/colors.png) +If the color is set via this configuration, an additional CSS file that +defines the color palette is included. If you want to keep things lean, clone +the repository and recompile the theme with your custom colors set. See the +guide on [customization][7] for more information. -If the color is set via this configuration, an additional CSS file called -`palettes.css` is included that defines the color palettes. If you want to -keep things lean, clone the repository and recompile the theme with your -custom colors set. See [this article](customization.md) for more information. + [6]: http://www.materialui.co/colors + [7]: customization.md + +#### Primary colors + +Click on a tile to change the primary color of the theme: + + + + + + + + + + + + + + + + + + + + + + + +#### Accent colors + +Click on a tile to change the accent color of the theme: + + + + + + + + + + + + + + + + + + + ### Changing the font family -Material uses the [Ubuntu font family][] by default, specifically the regular -sans-serif type for text and the monospaced type for code. Both fonts are -loaded from [Google Fonts][] and can be easily changed to other fonts, like for -example Google's own [Roboto font][]: +Material uses the [Roboto font family][8] by default, specifically the regular +sans-serif type for text and the `monospaced` type for code. Both fonts are +loaded from [Google Fonts][9] and can easily be changed to other fonts, like +for example the [Ubuntu font family][10]: ``` yaml extra: font: - text: 'Roboto' - code: 'Roboto Mono' + text: 'Ubuntu' + code: 'Ubuntu Mono' ``` -The text font will be loaded in font-weights 400 and **700**, the monospaced +The text font will be loaded in font-weights 400 and **700**, the `monospaced` font in regular weight. If you want to load fonts from other destinations or -don't want to use the Google Fonts loading magic, just set `extra.font` to -`'none'`: +don't want to use the Google Fonts loading magic, just set `font` to `'none'`: ``` yaml extra: font: 'none' ``` -### Localization + [8]: https://fonts.google.com/specimen/Roboto + [9]: https://fonts.google.com/ + [10]: https://fonts.google.com/specimen/Ubuntu -The following texts and labels can easily be changed by defining variables: +### Adding a logo + +Material makes it easy to add your logo. Your logo should have rectangular +shape with a minimum resolution of 128x128, leave some room towards the edges +and be composed of high contrast areas on a transparent ground, as it will be +placed on the colored header bar and drawer. Simply create the folder +`docs/images`, add your logo and embed it with: ``` yaml extra: - i18n: - prev: 'Previous' # "Previous" label in the footer - next: 'Next' # "Next" label in the footer - search: 'Search' # "Search" placeholder in the search bar + logo: 'images/logo.svg' ``` -### Adding a GitHub and Twitter account +### Adding social links -If you have a GitHub and/or Twitter account, you can add links to your -accounts to the drawer by setting the variables `extra.author.github` and -`extra.author.twitter` respectively: +If you want to link your social accounts, the Material theme provides an easy +way for doing this in the footer of the documentation using the automatically +included [FontAwesome][11] webfont. The syntax is simple – the `type` must +denote the name of the social service, e.g. `github`, `twitter` or `linkedin` +and the `link` must contain the URL you want to link to: ``` yaml extra: - author: - github: 'my-github-handle' - twitter: 'my-twitter-handle' + social: + - type: 'github' + link: 'https://github.com/squidfunk' + - type: 'twitter' + link: 'https://twitter.com/squidfunk' + - type: 'linkedin' + link: 'https://de.linkedin.com/in/martin-donath-20a95039' ``` +The links are generated in order and the `type` of the links must match the +name of the FontAwesome glyph. The `fa` is automatically added, so `github` +will result in `fa fa-github`. + + [11]: http://fontawesome.io/icons/ + ### Google Analytics integration -Material makes it easy to integrate site tracking with Google Analytics. -Besides basic tracking, clicks on all outgoing links can be tracked, clicks on -the download and star button, as well as how site search is used. Tracking can -be activated in your project's `mkdocs.yml`: +MkDocs makes it easy to integrate site tracking with Google Analytics. +Besides basic tracking, clicks on all outgoing links can be tracked as well as +how site search is used. Tracking can be activated in your project's +`mkdocs.yml`: ``` yaml google_analytics: @@ -211,86 +278,73 @@ google_analytics: - 'auto' ``` +### Localization L10N + +In order to localize the labels (e.g. *Previous* and *Next* in the footer), +you can override the file `partials/i18n.html` to provide your own translations +inside the macro `t`: + +``` jinja +{% macro t(key) %}{{ { + "edit.link.title": "Edit this page", + "footer.previous": "Previous", + "footer.next": "Next", + "search.placeholder": "Search", + "source.link.title": "Go to repository", + "toc.title": "Table of contents" +}[key] }}{% endmacro %} +``` + +Just copy the file from the original theme and make your adjustments. See the +section on [overriding partials][12] in the customization guide. + +!!! warning "Migrating from Material 0.2.x" + + In 0.2.x localization was done within the `extra` configuration of your + `mkdocs.yml`. With 1.0.0 this is no longer possible as the configuration + will be ignored. + + [12]: customization.md#overriding-partials + ### More advanced customization If you want to change the general appearance of the Material theme, see -[this article](customization.md) for more information on advanced customization. +[this article][13] for more information on advanced customization. + + [13]: customization.md ## Extensions -MkDocs supports several [Markdown extensions][]. The following extensions are -not enabled by default (see the link for which are enabled by default), so you -have to switch them on explicitly. - -### CodeHilite (recommended) - -This extensions uses [Pygments][] (install with `pip install pygments`) to add -code highlighting to fenced code blocks. It might not be the best code -highlighter, but it works without JavaScript and on the server: - -``` yaml -markdown_extensions: - - codehilite(css_class=code) -``` - -If you want more extensive highlighting, you can use a JavaScript library like -[highlight.js][], which is not included in Material. See [this link][extra] for -further instructions - -### Permalinks - -In order to add [permalinks][] to the headers of your article, set the -`markdown_extensions.toc.permalink` variable to a symbol, e.g. `#`: - -``` yaml -markdown_extensions: - - toc: - permalink: '#' -``` - -The symbol can be chosen freely, it can even be a WebFont icon. - -### Admonition - -[Admonition][] is a handy extension that adds block-styled side content to your -documentation, for example hints, notes or warnings. It can be enabled by -setting the variable `markdown_extensions.admonition`: +MkDocs supports several [Markdown extensions][14]. The following extensions +are not enabled by default (see the link for which are enabled by default) +but highly recommended, so they should be switched on at all times: ``` yaml markdown_extensions: - admonition + - codehilite(guess_lang=false) + - toc(permalink=true) ``` -In order to add a note, use the following syntax inside your article: +For more information, see the following list of extensions supported by the +Material theme including more information regarding installation and usage: -``` markdown -!!! note - Nothing to see here, move along. -``` +* [Admonition][15] +* [Codehilite][16] +* [Permalinks][17] +* [Footnotes][18] +* [PyMdown Extensions][19] -This will print the following block: - -!!! note - Nothing to see here, move along. - -The Material template adds a neutral color for the `note` class and a red color -for the `warning` class. You can also add a custom title: - -``` markdown -!!! warning "Don't try this at home" - If you do, you will regret it. -``` - -This will print: - -!!! warning "Don't try this at home" - If you do, you will regret it. - -More colors can be freely defined. + [14]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions + [15]: extensions/admonition.md + [16]: extensions/codehilite.md + [17]: extensions/permalinks.md + [18]: extensions/footnotes.md + [19]: extensions/pymdown.md ## Full example -Below is a full example configuration for a mkdocs.yml: +Below is a full example configuration for a `mkdocs.yml`: ``` yaml # Project information @@ -304,28 +358,27 @@ repo_name: 'GitHub' repo_url: 'https://github.com/my-github-handle/my-project' # Copyright -copyright: 'Copyright (c) 2016 John Doe' +copyright: 'Copyright © 2016 John Doe' # Documentation and theme -docs_dir: 'docs' theme: 'material' # Options extra: - version: '0.1.0' - logo: 'images/logo.png' + logo: 'images/logo.svg' palette: primary: 'indigo' - accent: 'light blue' + accent: 'indigo' font: text: 'Roboto' code: 'Roboto Mono' - i18n: - prev: 'Previous' - next: 'Next' - author: - github: 'my-github-handle' - twitter: 'my-twitter-handle' + social: + - type: 'github' + link: 'https://github.com/squidfunk' + - type: 'twitter' + link: 'https://twitter.com/squidfunk' + - type: 'linkedin' + link: 'https://de.linkedin.com/in/martin-donath-20a95039' # Google Analytics google_analytics: @@ -334,20 +387,9 @@ google_analytics: # Extensions markdown_extensions: - - codehilite(css_class=code) - admonition - - toc: - permalink: '#' + - codehilite(guess_lang=false) + - footnotes + - meta + - toc(permalink=true) ``` - -[MkDocs]: http://www.mkdocs.org -[color palette]: http://www.materialui.co/colors -[Ubuntu font family]: http://font.ubuntu.com -[Google Fonts]: https://www.google.com/fonts -[Roboto font]: https://www.google.com/fonts/specimen/Roboto -[Markdown extensions]: http://www.mkdocs.org/user-guide/writing-your-docs/#markdown-extensions -[Pygments]: http://pygments.org -[highlight.js]: https://highlightjs.org -[extra]: http://www.mkdocs.org/user-guide/styling-your-docs/#customising-a-theme -[permalinks]: https://en.wikipedia.org/wiki/Permalink -[Admonition]: https://pythonhosted.org/Markdown/extensions/admonition.html \ No newline at end of file diff --git a/docs/images/colors.png b/docs/images/colors.png deleted file mode 100644 index 45e4b6041..000000000 Binary files a/docs/images/colors.png and /dev/null differ diff --git a/docs/images/logo.png b/docs/images/logo.png deleted file mode 100644 index 573aca138..000000000 Binary files a/docs/images/logo.png and /dev/null differ diff --git a/docs/images/screen.png b/docs/images/screen.png deleted file mode 100644 index cb10504b4..000000000 Binary files a/docs/images/screen.png and /dev/null differ diff --git a/docs/index.md b/docs/index.md index 9fdad9c4f..d1cd26423 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,22 +1,17 @@ -# Material for MkDocs +# Material for MkDocs -## Beautiful documentation +## Beautiful project documentation -Material is a theme for [MkDocs][], an excellent static site generator geared -towards project documentation. It is built using Google's [material design][] -guidelines, full responsive, optimized for touch and pointer devices as well -as all sorts of screen sizes. +Material is a theme for [MkDocs][1], an excellent static site generator geared +towards project documentation. It is built using Google's [Material Design][2] +guidelines. -![Material Screenshot](images/screen.png) - -Material is very lightweight – it is built from scratch using Javascript and -CSS that weighs less than 30kb (minified, gzipped and excluding Google Fonts -and Analytics). Yet, it is highly customizable and degrades gracefully in older -browsers. + [1]: http://www.mkdocs.org + [2]: https://www.google.com/design/spec/material-design ## Quick start -Install with `pip`: +Install the latest version of Material with `pip`: ``` sh pip install mkdocs-material @@ -28,39 +23,6 @@ Add the following line to your `mkdocs.yml`: theme: 'material' ``` -## Features +For detailed instructions see the [getting started guide][3]. -- Beautiful, readable and very user-friendly design based on Google's material - design guidelines, packed in a full responsive template with a well-defined - and [easily customizable color palette][], great typography, as well as a - beautiful search interface and footer. - -- Well-tested and optimized Javascript and CSS including a cross-browser - fixed/sticky header, a drawer that even works without Javascript using - the [checkbox hack][] with fallbacks, responsive tables that scroll when - the screen is too small and well-defined print styles. - -- Extra configuration options like a [project logo][], links to the authors - [GitHub and Twitter accounts][], display of the amount of stars the - project has on GitHub and [Google Analytics integration][]. - -- Easily [extendable and customizable][] due to a well-designed asset pipeline - built on-top of [Gulp][] with `npm` and `bower` and modular and abstracted - style definitions built with [SASS][]. - -- Web application capability on iOS – when the page is saved to the homescreen, - it behaves and looks like a native application. - -See the [getting started guide](getting-started.md) for instructions how to get -it up and running. - -[MkDocs]: http://www.mkdocs.org -[material design]: https://www.google.com/design/spec/material-design -[checkbox hack]: http://tutorialzine.com/2015/08/quick-tip-css-only-dropdowns-with-the-checkbox-hack/ -[project logo]: getting-started.md#adding-a-logo -[easily customizable color palette]: getting-started.md#changing-the-color-palette -[GitHub and Twitter accounts]: getting-started.md#adding-a-github-and-twitter-account -[Google Analytics integration]: getting-started.md#google-analytics-integration -[extendable and customizable]: customization.md -[Gulp]: http://gulpjs.com -[SASS]: http://sass-lang.com \ No newline at end of file + [3]: getting-started.md diff --git a/docs/license.md b/docs/license.md index 27d4332be..569a9b93d 100644 --- a/docs/license.md +++ b/docs/license.md @@ -2,7 +2,7 @@ **MIT License** -Copyright (c) 2016 Martin Donath +Copyright © 2016 Martin Donath Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to @@ -20,4 +20,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -IN THE SOFTWARE. \ No newline at end of file +IN THE SOFTWARE. diff --git a/docs/release-notes.md b/docs/release-notes.md new file mode 100644 index 000000000..acd4e23db --- /dev/null +++ b/docs/release-notes.md @@ -0,0 +1,140 @@ +# Release Notes + +## Upgrading + +To upgrade Material to the latest version, use pip: + +``` sh +pip install --upgrade mkdocs-material +``` + +To determine the currently installed version, use the following command: + +``` sh +pip show mkdocs-material | grep -E ^Version +# Version 1.0.0 +``` + +## Changelog + +### 1.0.0 _ January 13, 2017 + +* Introduced Webpack for more sophisticated JavaScript bundling +* Introduced ESLint and Stylelint for code style checks +* Introduced more accurate Material Design colors and shadows +* Introduced modular scales for harmonic font sizing +* Introduced git-hooks for better development workflow +* Rewrite of CSS using the BEM methodology and SassDoc guidelines +* Rewrite of JavaScript using ES6 and Babel as a transpiler +* Rewrite of Admonition, Permalinks and CodeHilite integration +* Rewrite of the complete typographical system +* Rewrite of Gulp asset pipeline in ES6 and separation of tasks +* Removed Bower as a dependency in favor of NPM +* Removed custom icon build in favor of the Material Design iconset +* Removed `_blank` targets on links due to vulnerability: http://bit.ly/1Mk2Rtw +* Removed unversioned assets from build directory +* Restructured templates into base templates and partials +* Added build and watch scripts in `package.json` +* Added support for Metadata and Footnotes Markdown extensions +* Added support for PyMdown Extensions package +* Added support for collapsible sections in navigation +* Added support for separate table of contents +* Added support for better accessibility through REM-based layout +* Added icons for GitHub, GitLab and BitBucket integrations +* Added more detailed documentation on specimen, extensions etc. +* Added a `404.html` error page for deployment on GitHub Pages +* Fixed live reload chain in watch mode when saving a template +* Fixed variable references to work with MkDocs 0.16 + +### 0.2.4 _ June 26, 2016 + +* Fixed improperly set default favicon +* Fixed [#33][33]: Protocol relative URL for webfonts doesn't work with + `file://` +* Fixed [#34][34]: IE11 on Windows 7 doesn't honor `max-width` on `main` tag +* Fixed [#35][35]: Add styling for blockquotes + + [33]: https://github.com/squidfunk/mkdocs-material/issues/25 + [34]: https://github.com/squidfunk/mkdocs-material/issues/26 + [35]: https://github.com/squidfunk/mkdocs-material/issues/30 + +### 0.2.3 _ May 16, 2016 + +* Fixed [#25][25]: Highlight inline fenced blocks +* Fixed [#26][26]: Better highlighting for keystrokes +* Fixed [#30][30]: Suboptimal syntax highlighting for PHP + + [25]: https://github.com/squidfunk/mkdocs-material/issues/25 + [26]: https://github.com/squidfunk/mkdocs-material/issues/26 + [30]: https://github.com/squidfunk/mkdocs-material/issues/30 + +### 0.2.2 _ March 20, 2016 + +* Fixed [#15][15]: Document Pygments dependency for CodeHilite +* Fixed [#16][16]: Favicon could not be set through `mkdocs.yml` +* Fixed [#17][17]: Put version into own container for styling +* Fixed [#20][20]: Fix rounded borders for tables + + [15]: https://github.com/squidfunk/mkdocs-material/issues/15 + [16]: https://github.com/squidfunk/mkdocs-material/issues/16 + [17]: https://github.com/squidfunk/mkdocs-material/issues/17 + [20]: https://github.com/squidfunk/mkdocs-material/issues/20 + +### 0.2.1 _ March 12, 2016 + +* Fixed [#10][10]: Invisible header after closing search bar with + ESC key +* Fixed [#13][13]: Table cells don't wrap +* Fixed empty list in table of contents when no headline is defined +* Corrected wrong path for static asset monitoring in Gulpfile.js +* Set up tracking of site search for Google Analytics + + [10]: https://github.com/squidfunk/mkdocs-material/issues/10 + [13]: https://github.com/squidfunk/mkdocs-material/issues/13 + +### 0.2.0 _ February 24, 2016 + +* Fixed [#6][6]: Include multiple color palettes via `mkdocs.yml` +* Fixed [#7][7]: Better colors for links inside admonition notes and warnings +* Fixed [#9][9]: Text for prev/next footer navigation should be customizable +* Refactored templates (replaced `if`/`else` with modifiers where possible) + + [6]: https://github.com/squidfunk/mkdocs-material/issues/6 + [7]: https://github.com/squidfunk/mkdocs-material/issues/7 + [9]: https://github.com/squidfunk/mkdocs-material/issues/9 + +### 0.1.3 _ February 21, 2016 + +* Fixed [#3][3]: Ordered lists within an unordered list have `::before` content +* Fixed [#4][4]: Click on Logo/Title without Github-Repository: `"None"` +* Fixed [#5][5]: Page without headlines renders empty list in table of contents +* Moved Modernizr to top to ensure basic usability in IE8 + + [3]: https://github.com/squidfunk/mkdocs-material/issues/3 + [4]: https://github.com/squidfunk/mkdocs-material/issues/4 + [5]: https://github.com/squidfunk/mkdocs-material/issues/5 + +### 0.1.2 _ February 16, 2016 + +* Fixed styles for deep navigational hierarchies +* Fixed webfont delivery problem when hosted in subdirectories +* Fixed print styles in mobile/tablet configuration +* Added option to configure fonts in `mkdocs.yml` with fallbacks +* Changed styles for admonition notes and warnings +* Set download link to latest version if available +* Set up tracking of outgoing links and actions for Google Analytics + +### 0.1.1 _ February 11, 2016 + +* Fixed [#1][1]: GitHub stars don't work if the repo_url ends with a `/` +* Updated NPM and Bower dependencies to most recent versions +* Changed footer/copyright link to Material theme to GitHub pages +* Made MkDocs building/serving in build process optional +* Set up continuous integration with [Travis][2] + + [1]: https://github.com/squidfunk/mkdocs-material/issues/1 + [2]: https://travis-ci.org + +### 0.1.0 _ February 9, 2016 + +* Initial release diff --git a/docs/specimen.md b/docs/specimen.md new file mode 100644 index 000000000..fefccdea0 --- /dev/null +++ b/docs/specimen.md @@ -0,0 +1,228 @@ +# Specimen + +## Body copy + +Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras arcu libero, +mollis sed massa vel, *ornare viverra ex*. Mauris a ullamcorper lacus. Nullam +urna elit, malesuada eget finibus ut, ullamcorper ac tortor. Vestibulum sodales +pulvinar nisl, pharetra aliquet est. Quisque volutpat erat ac nisi accumsan +tempor. + +**Sed suscipit**, orci non pretium pretium, quam mi gravida metus, vel +venenatis justo est condimentum diam. Maecenas non ornare justo. Nam a ipsum +eros. [Nulla aliquam](/) orci sit amet nisl posuere malesuada. Proin aliquet +nulla velit, quis ultricies orci feugiat et. `Ut tincidunt sollicitudin` +tincidunt. Aenean ullamcorper sit amet nulla at interdum. + +## Headings + +### The 3rd level + +#### The 4th level + +##### The 5th level + +###### The 6th level + +## Headings with secondary text + +### The 3rd level with secondary text + +#### The 4th level with secondary text + +##### The 5th level with secondary text + +###### The 6th level with secondary text + +## Blockquotes + +> Morbi eget dapibus felis. Vivamus venenatis porttitor tortor sit amet rutrum. + Pellentesque aliquet quam enim, eu volutpat urna rutrum a. Nam vehicula nunc + mauris, a ultricies libero efficitur sed. *Class aptent* taciti sociosqu ad + litora torquent per conubia nostra, per inceptos himenaeos. Sed molestie + imperdiet consectetur. + +### Blockquote nesting + +> **Sed aliquet**, neque at rutrum mollis, neque nisi tincidunt nibh, vitae + faucibus lacus nunc at lacus. Nunc scelerisque, quam id cursus sodales, lorem + [libero fermentum](/) urna, ut efficitur elit ligula et nunc. + +> > Mauris dictum mi lacus, sit amet pellentesque urna vehicula fringilla. + Ut sit amet placerat ante. Proin sed elementum nulla. Nunc vitae sem odio. + Suspendisse ac eros arcu. Vivamus orci erat, volutpat a tempor et, rutrum. + eu odio. + +> > > `Suspendisse rutrum facilisis risus`, eu posuere neque commodo a. + Interdum et malesuada fames ac ante ipsum primis in faucibus. Sed nec leo + bibendum, sodales mauris ut, tincidunt massa. + +### Other content blocks + +> Vestibulum vitae orci quis ante viverra ultricies ut eget turpis. Sed eu + lectus dapibus, eleifend nulla varius, lobortis turpis. In ac hendrerit nisl, + sit amet laoreet nibh. + ``` js hl_lines="8" + var _extends = function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + target[key] = source[key]; + } + } + return target; + }; + ``` + + > > Praesent at `:::js return target`, sodales nibh vel, tempor felis. Fusce + vel lacinia lacus. Suspendisse rhoncus nunc non nisi iaculis ultrices. + Donec consectetur mauris non neque imperdiet, eget volutpat libero. + +## Lists + +### Unordered lists + +* Sed sagittis eleifend rutrum. Donec vitae suscipit est. Nullam tempus tellus + non sem sollicitudin, quis rutrum leo facilisis. Nulla tempor lobortis orci, + at elementum urna sodales vitae. In in vehicula nulla, quis ornare libero. + + * Duis mollis est eget nibh volutpat, fermentum aliquet dui mollis. + * Nam vulputate tincidunt fringilla. + * Nullam dignissim ultrices urna non auctor. + +* Aliquam metus eros, pretium sed nulla venenatis, faucibus auctor ex. Proin ut + eros sed sapien ullamcorper consequat. Nunc ligula ante, fringilla at aliquam + ac, aliquet sed mauris. + +* Nulla et rhoncus turpis. Mauris ultricies elementum leo. Duis efficitur + accumsan nibh eu mattis. Vivamus tempus velit eros, porttitor placerat nibh + lacinia sed. Aenean in finibus diam. + +### Ordered lists + +1. Integer vehicula feugiat magna, a mollis tellus. Nam mollis ex ante, quis + elementum eros tempor rutrum. Aenean efficitur lobortis lacinia. Nulla + consectetur feugiat sodales. + +2. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur + ridiculus mus. Aliquam ornare feugiat quam et egestas. Nunc id erat et quam + pellentesque lacinia eu vel odio. + + 1. Vivamus venenatis porttitor tortor sit amet rutrum. Pellentesque aliquet + quam enim, eu volutpat urna rutrum a. Nam vehicula nunc mauris, a + ultricies libero efficitur sed. + + 1. Mauris dictum mi lacus + 2. Ut sit amet placerat ante + 3. Suspendisse ac eros arcu + + 2. Morbi eget dapibus felis. Vivamus venenatis porttitor tortor sit amet + rutrum. Pellentesque aliquet quam enim, eu volutpat urna rutrum a. Sed + aliquet, neque at rutrum mollis, neque nisi tincidunt nibh. + + 3. Pellentesque eget `:::js var _extends` ornare tellus, ut gravida mi. + ``` js hl_lines="1" + var _extends = function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + target[key] = source[key]; + } + } + return target; + }; + ``` + +3. Vivamus id mi enim. Integer id turpis sapien. Ut condimentum lobortis + sagittis. Aliquam purus tellus, faucibus eget urna at, iaculis venenatis + nulla. Vivamus a pharetra leo. + +## Code blocks + +### Inline + +Morbi eget `dapibus felis`. Vivamus *`venenatis porttitor`* tortor sit amet +rutrum. Class aptent taciti sociosqu ad litora torquent per conubia nostra, +per inceptos himenaeos. [`Pellentesque aliquet quam enim`](/), eu volutpat urna +rutrum a. + +Nam vehicula nunc `:::js return target` mauris, a ultricies libero efficitur +sed. Sed molestie imperdiet consectetur. Vivamus a pharetra leo. Pellentesque +eget ornare tellus, ut gravida mi. Fusce vel lacinia lacus. + +### Listing + + #!js hl_lines="8" + var _extends = function(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i]; + for (var key in source) { + target[key] = source[key]; + } + } + return target; + }; + +## Horizontal rules + +Aenean in finibus diam. Duis mollis est eget nibh volutpat, fermentum aliquet +dui mollis. Nam vulputate tincidunt fringilla. Nullam dignissim ultrices urna +non auctor. + +*** + +Integer vehicula feugiat magna, a mollis tellus. Nam mollis ex ante, quis +elementum eros tempor rutrum. Aenean efficitur lobortis lacinia. Nulla +consectetur feugiat sodales. + +## Data tables + +| Sollicitudo / Pellentesi | consectetur | adipiscing | elit | arcu | sed | +| ------------------------ | ----------- | ---------- | ------- | ---- | --- | +| Vivamus a pharetra | yes | yes | yes | yes | yes | +| Ornare viverra ex | yes | yes | yes | yes | yes | +| Mauris a ullamcorper | yes | yes | partial | yes | yes | +| Nullam urna elit | yes | yes | yes | yes | yes | +| Malesuada eget finibus | yes | yes | yes | yes | yes | +| Ullamcorper | yes | yes | yes | yes | yes | +| Vestibulum sodales | yes | - | yes | - | yes | +| Pulvinar nisl | yes | yes | yes | - | - | +| Pharetra aliquet est | yes | yes | yes | yes | yes | +| Sed suscipit | yes | yes | yes | yes | yes | +| Orci non pretium | yes | partial | - | - | - | + +Sed sagittis eleifend rutrum. Donec vitae suscipit est. Nullam tempus tellus +non sem sollicitudin, quis rutrum leo facilisis. Nulla tempor lobortis orci, +at elementum urna sodales vitae. In in vehicula nulla, quis ornare libero. + +| Left | Center | Right | +| :--------- | :------: | ------: | +| Lorem | *dolor* | `amet` | +| [ipsum](/) | **sit** | | + +Vestibulum vitae orci quis ante viverra ultricies ut eget turpis. Sed eu +lectus dapibus, eleifend nulla varius, lobortis turpis. In ac hendrerit nisl, +sit amet laoreet nibh. + + + + + + + + + + + + + + + + + + + + + + +
Tablewith colgroups (Pandoc)
Loremipsum dolor sit amet.
Sed sagittiseleifend rutrum. Donec vitae suscipit est.
diff --git a/lib/providers/jsx.js b/lib/providers/jsx.js new file mode 100644 index 000000000..371f7c8fe --- /dev/null +++ b/lib/providers/jsx.js @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Definition + * ------------------------------------------------------------------------- */ + +export default /* JSX */ { + + /** + * Create a native DOM node from JSX's intermediate representation + * + * @param {string} tag - Tag name + * @param {object} properties - Properties + * @param {...(string|number|Array)} children - Child nodes + * @return {HTMLElement} Native DOM node + */ + createElement(tag, properties, ...children) { + const el = document.createElement(tag) + + /* Set all properties */ + if (properties) + Array.prototype.forEach.call(Object.keys(properties), attr => { + el.setAttribute(attr, properties[attr]) + }) + + /* Iterate child nodes */ + const iterateChildNodes = nodes => { + Array.prototype.forEach.call(nodes, node => { + + /* Directly append text content */ + if (typeof node === "string" || + typeof node === "number") { + el.textContent += node + + /* Recurse, if we got an array */ + } else if (Array.isArray(node)) { + iterateChildNodes(node) + + /* Append regular nodes */ + } else { + el.appendChild(node) + } + }) + } + + /* Iterate child nodes and return element */ + iterateChildNodes(children) + return el + } +} diff --git a/lib/tasks/.eslintrc b/lib/tasks/.eslintrc new file mode 100644 index 000000000..709b01107 --- /dev/null +++ b/lib/tasks/.eslintrc @@ -0,0 +1,5 @@ +{ + "rules": { + "no-invalid-this": 0 + } +} diff --git a/src/assets/stylesheets/modules/article/_typography.scss b/lib/tasks/assets/images/build/ico.js similarity index 73% rename from src/assets/stylesheets/modules/article/_typography.scss rename to lib/tasks/assets/images/build/ico.js index c657a7a29..dac4cd9b5 100644 --- a/src/assets/stylesheets/modules/article/_typography.scss +++ b/lib/tasks/assets/images/build/ico.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,39 +20,16 @@ * IN THE SOFTWARE. */ +import changed from "gulp-changed" + /* ---------------------------------------------------------------------------- - * Article typography + * Task: clean images generated by build * ------------------------------------------------------------------------- */ -/* - * Article - */ -.article { - - /* - * Third-level headlines should be bold - */ - h3 { - font-weight: 700; - } - - /* - * Fourth-level headlines should be italic - */ - h4 { - font-weight: 400; - font-style: italic; +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.src}/images/**/*.ico`) + .pipe(changed(`${config.assets.build}/images`)) + .pipe(gulp.dest(`${config.assets.build}/images`)) } } - -/* - * Permalink support - */ -.article { - h2, h3, h4, h5, h6 { - a { - font-weight: 400; - font-style: normal; - } - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/_highlight.scss b/lib/tasks/assets/images/build/svg.js similarity index 56% rename from src/assets/stylesheets/_highlight.scss rename to lib/tasks/assets/images/build/svg.js index 9882d794e..60cef28d8 100644 --- a/src/assets/stylesheets/_highlight.scss +++ b/lib/tasks/assets/images/build/svg.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,69 +20,35 @@ * IN THE SOFTWARE. */ +import changed from "gulp-changed" +import gulpif from "gulp-if" +import minsvg from "gulp-svgmin" +import rev from "gulp-rev" +import version from "gulp-rev-replace" + /* ---------------------------------------------------------------------------- - * Code highlighter + * Task: clean images generated by build * ------------------------------------------------------------------------- */ -/* - * Code block - */ -pre { - background: rgba($black, 0.05); - - /* - * Ensure correct color - */ - &, code { - color: $black; +export default (gulp, config, args) => { + return () => { + return gulp.src(`${config.assets.src}/images/**/*.svg`) + .pipe(changed(`${config.assets.build}/images`)) + .pipe(gulpif(args.optimize, + minsvg({ + plugins: [ + { cleanupIDs: false } + ] + }))) + .pipe(gulpif(args.revision, rev())) + .pipe(gulpif(args.revision, + version({ manifest: gulp.src("manifest.json") }))) + .pipe(gulp.dest(`${config.assets.build}/images`)) + .pipe(gulpif(args.revision, + rev.manifest("manifest.json", { + base: config.assets.build, + merge: true + }))) + .pipe(gulpif(args.revision, gulp.dest(config.assets.build))) } } - -/* - * Operators and comments - */ -.o, .c, .c1, .cm { - color: $black-light; -} - -/* - * Keywords - */ -.k, .kn { - color: #A71D5D; -} - -/* - * Types and functions - */ -.kt, .kd { - color: #0086B3; -} - -/* - * Function definition - */ -.nf, .n.f { - color: #795da3; -} - -/* - * Classes - */ -.nx { - color: #0086b3; -} - -/* - * Strings - */ -.s, .s1 { - color: #183691; -} - -/* - * Constants and numbers - */ -.mi, .bp { - color: #9575CD; -} \ No newline at end of file diff --git a/src/assets/stylesheets/_palette.scss b/lib/tasks/assets/images/clean.js similarity index 70% rename from src/assets/stylesheets/_palette.scss rename to lib/tasks/assets/images/clean.js index 3629d28af..3d9bb2ada 100644 --- a/src/assets/stylesheets/_palette.scss +++ b/lib/tasks/assets/images/clean.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,28 +20,16 @@ * IN THE SOFTWARE. */ +import clean from "del" +import vinyl from "vinyl-paths" + /* ---------------------------------------------------------------------------- - * Palette + * Task: clean images generated by build * ------------------------------------------------------------------------- */ -/* - * Primary and accent color - */ -$primary: $red-400 !default; -$accent: $teal-a700 !default; - -/* - * Black opacities - */ -$black: rgba(black, 0.87); -$black-light: rgba(black, 0.54); -$black-lighter: rgba(black, 0.26); -$black-lightest: rgba(black, 0.12); - -/* - * White opacities - */ -$white: rgba(white, 1.00); -$white-light: rgba(white, 0.70); -$white-lighter: rgba(white, 0.30); -$white-lightest: rgba(white, 0.12); \ No newline at end of file +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.build}/images/*`) + .pipe(vinyl(clean)) + } +} diff --git a/lib/tasks/assets/javascripts/build/application.js b/lib/tasks/assets/javascripts/build/application.js new file mode 100644 index 000000000..a697c83a1 --- /dev/null +++ b/lib/tasks/assets/javascripts/build/application.js @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import gulpif from "gulp-if" +import path from "path" +import rev from "gulp-rev" +import stream from "webpack-stream" +import version from "gulp-rev-replace" +import webpack from "webpack" + +/* ---------------------------------------------------------------------------- + * Task: build application logic + * ------------------------------------------------------------------------- */ + +export default (gulp, config, args) => { + return () => { + return gulp.src(`${config.assets.src}/javascripts/**/*.{js,jsx}`) + + /* Build with webpack */ + .pipe( + stream({ + entry: [ + + /* Polyfills */ + "core-js/fn/promise", + "custom-event-polyfill", + "whatwg-fetch", + + /* Main entry point */ + "application.js" + ], + output: { + filename: "application.js", + library: "Application" + }, + module: { + + /* Transpile ES6 to ES5 with Babel */ + loaders: [ + { + loader: "babel-loader", + test: /\.jsx?$/ + } + ] + }, + plugins: [ + + /* Don't emit assets that include errors */ + new webpack.NoErrorsPlugin(), + + /* Provide JSX helper */ + new webpack.ProvidePlugin({ + JSX: path.join(process.cwd(), `${config.lib}/providers/jsx.js`) + }) + ].concat( + + /* Minify sources */ + args.optimize ? [ + new webpack.optimize.UglifyJsPlugin({ + compress: { + warnings: false + } + }) + ] : []), + + /* Module resolver */ + resolve: { + modulesDirectories: [ + "src/assets/javascripts", + "node_modules" + ], + extensions: [ + "", + ".js", + ".jsx" + ] + }, + + /* Webpack commandline output */ + stats: { + colors: true + }, + + /* Sourcemap support */ + devtool: args.sourcemaps ? "source-map" : "" + })) + + /* Revisioning */ + .pipe(gulpif(args.revision, rev())) + .pipe(gulpif(args.revision, + version({ manifest: gulp.src("manifest.json") }))) + .pipe(gulp.dest(`${config.assets.build}/javascripts`)) + .pipe(gulpif(args.revision, + rev.manifest("manifest.json", { + base: config.assets.build, + merge: true + }))) + .pipe(gulpif(args.revision, gulp.dest(config.assets.build))) + } +} diff --git a/src/assets/stylesheets/modules/drawer/_animation.scss b/lib/tasks/assets/javascripts/build/modernizr.js similarity index 50% rename from src/assets/stylesheets/modules/drawer/_animation.scss rename to lib/tasks/assets/javascripts/build/modernizr.js index 16077f9b6..d87097672 100644 --- a/src/assets/stylesheets/modules/drawer/_animation.scss +++ b/lib/tasks/assets/javascripts/build/modernizr.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,62 +20,44 @@ * IN THE SOFTWARE. */ +import concat from "gulp-concat" +import gulpif from "gulp-if" +import modernizr from "gulp-modernizr" +import uglify from "gulp-uglify" +import rev from "gulp-rev" +import version from "gulp-rev-replace" + /* ---------------------------------------------------------------------------- - * Drawer animation + * Task: build custom modernizr * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { +export default (gulp, config, args) => { + return () => { + return gulp.src(`${config.assets.build}/stylesheets/*.css`) - /* [tablet landscape-]: Hide menu */ - @include break-to-device(tablet landscape) { - transform: translate3d(-262px, 0, 0); - transition: transform .25s cubic-bezier(.4, 0, .2, 1); + /* Build custom modernizr */ + .pipe( + modernizr({ + options: [ + "addTest", /* Add custom tests */ + "setClasses" /* Add CSS classes to root tag */ + ] + })) + .pipe(concat("modernizr.js")) - /* - * Just hide drawer, if browser doesn't support 3D transforms - */ - .no-csstransforms3d & { - display: none; - } - } + /* Minify sources */ + .pipe(gulpif(args.optimize, uglify())) - /* - * Expanded drawer - */ - #toggle-drawer:checked ~ .main &, - .toggle-drawer & { - transform: translate3d(0, 0, 0); - - /* - * Just show drawer, if browser doesn't support 3D transforms - */ - .no-csstransforms3d & { - display: block; - } + /* Revisioning */ + .pipe(gulpif(args.revision, rev())) + .pipe(gulpif(args.revision, + version({ manifest: gulp.src("manifest.json") }))) + .pipe(gulp.dest(`${config.assets.build}/javascripts`)) + .pipe(gulpif(args.revision, + rev.manifest("manifest.json", { + base: config.assets.build, + merge: true + }))) + .pipe(gulpif(args.revision, gulp.dest(config.assets.build))) } } - -/* - * No color transition for project link - */ -.project { - transition: none; -} - -/* - * Project logo image - */ -.project .logo img { - transition: box-shadow .4s; -} - -/* - * Repository buttons - */ -.repo a { - transition: box-shadow .4s, - opacity .4s; -} \ No newline at end of file diff --git a/lib/tasks/assets/javascripts/clean.js b/lib/tasks/assets/javascripts/clean.js new file mode 100644 index 000000000..0cbefbbfe --- /dev/null +++ b/lib/tasks/assets/javascripts/clean.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import clean from "del" +import vinyl from "vinyl-paths" + +/* ---------------------------------------------------------------------------- + * Task: clean JavaScript generated by build + * ------------------------------------------------------------------------- */ + +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.build}/javascripts/*`) + .pipe(vinyl(clean)) + } +} diff --git a/lib/tasks/assets/javascripts/lint.js b/lib/tasks/assets/javascripts/lint.js new file mode 100644 index 000000000..ffcd5a06b --- /dev/null +++ b/lib/tasks/assets/javascripts/lint.js @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import path from "path" +import through from "through2" +import util from "gulp-util" +import { CLIEngine } from "eslint" + +/* ---------------------------------------------------------------------------- + * Locals + * ------------------------------------------------------------------------- */ + +const eslint = new CLIEngine +const format = eslint.getFormatter() + +/* ---------------------------------------------------------------------------- + * Task: lint JavaScript + * ------------------------------------------------------------------------- */ + +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.src}/javascripts/**/*.js`) + + /* Linting */ + .pipe( + through.obj(function(file, enc, done) { + if (file.isNull() || file.isStream()) + return done() + + /* Lint file using .eslintrc */ + file.eslint = eslint.executeOnText( + file.contents.toString()) + + /* Correct file path */ + file.eslint.results[0].filePath = + path.relative(process.cwd(), file.path) + + /* Push file to next stage */ + this.push(file) + done() + })) + + /* Print errors */ + .pipe( + through.obj(function(file, enc, done) { + if (file.eslint.errorCount || file.eslint.warningCount) { + // eslint-disable-next-line no-console + console.log(format(file.eslint.results)) + } + + /* Push file to next stage */ + this.push(file) + done() + })) + + /* Terminate on error */ + .pipe( + (() => { + const errors = [] + + /* Gather errors */ + return through.obj(function(file, enc, done) { + const results = file.eslint + + /* Consider warnings as errors */ + if (results.errorCount || results.warningCount) + errors.push(file) + + /* Push file to next stage */ + this.push(file) + done() + + /* Format errors and terminate */ + }, function(done) { + if (errors.length > 0) { + const message = errors.map(file => { + return file.relative + }).join(", ") + + /* Emit error */ + this.emit("error", new util.PluginError("eslint", + `Terminated with errors in files: ${message}`)) + } + done() + }) + })()) + } +} diff --git a/lib/tasks/assets/stylesheets/build.js b/lib/tasks/assets/stylesheets/build.js new file mode 100644 index 000000000..2f78f1843 --- /dev/null +++ b/lib/tasks/assets/stylesheets/build.js @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import autoprefixer from "autoprefixer" +import gulpif from "gulp-if" +import mincss from "gulp-cssnano" +import mqpacker from "css-mqpacker" +import postcss from "gulp-postcss" +import rev from "gulp-rev" +import sass from "gulp-sass" +import sourcemaps from "gulp-sourcemaps" +import version from "gulp-rev-replace" + +/* ---------------------------------------------------------------------------- + * Task: build stylesheets from SASS source + * ------------------------------------------------------------------------- */ + +export default (gulp, config, args) => { + return () => { + return gulp.src(`${config.assets.src}/stylesheets/*.scss`) + .pipe(gulpif(args.sourcemaps, sourcemaps.init())) + + /* Compile SASS sources */ + .pipe( + sass({ + includePaths: [ + "node_modules/modularscale-sass/stylesheets", + "node_modules/material-design-color", + "node_modules/material-shadows" + ] + })) + + /* Apply PostCSS plugins */ + .pipe( + postcss([ + autoprefixer(), + mqpacker + ])) + + /* Minify sources */ + .pipe(gulpif(args.optimize, mincss())) + + /* Revisioning */ + .pipe(gulpif(args.revision, rev())) + .pipe(gulpif(args.revision, + version({ manifest: gulp.src("manifest.json") }))) + .pipe(gulpif(args.sourcemaps, sourcemaps.write("."))) + .pipe(gulp.dest(`${config.assets.build}/stylesheets`)) + .pipe(gulpif(args.revision, + rev.manifest("manifest.json", { + base: config.assets.build, + merge: true + }))) + .pipe(gulpif(args.revision, gulp.dest(config.assets.build))) + } +} diff --git a/lib/tasks/assets/stylesheets/clean.js b/lib/tasks/assets/stylesheets/clean.js new file mode 100644 index 000000000..e9f41bfbb --- /dev/null +++ b/lib/tasks/assets/stylesheets/clean.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import clean from "del" +import vinyl from "vinyl-paths" + +/* ---------------------------------------------------------------------------- + * Task: clean stylesheets generated by build + * ------------------------------------------------------------------------- */ + +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.build}/stylesheets/*`) + .pipe(vinyl(clean)) + } +} diff --git a/lib/tasks/assets/stylesheets/lint.js b/lib/tasks/assets/stylesheets/lint.js new file mode 100644 index 000000000..5cdad4927 --- /dev/null +++ b/lib/tasks/assets/stylesheets/lint.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import stylelint from "gulp-stylelint" + +/* ---------------------------------------------------------------------------- + * Task: lint SASS sources + * ------------------------------------------------------------------------- */ + +export default (gulp, config) => { + return () => { + return gulp.src(`${config.assets.src}/stylesheets/**/*.scss`) + .pipe( + stylelint({ + reporters: [ + { formatter: "string", console: true } + ] + })) + } +} diff --git a/lib/tasks/mkdocs/build.js b/lib/tasks/mkdocs/build.js new file mode 100644 index 000000000..534885050 --- /dev/null +++ b/lib/tasks/mkdocs/build.js @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import child from "child_process" + +/* ---------------------------------------------------------------------------- + * Task: build documentation + * ------------------------------------------------------------------------- */ + +export default () => { + return () => { + const proc = child.spawnSync("mkdocs", ["build"]) + if (proc.status) + throw new Error(`MkDocs error:\n${proc.stderr.toString()}`) + return proc + } +} diff --git a/src/assets/stylesheets/modules/article/_animation.scss b/lib/tasks/mkdocs/clean.js similarity index 80% rename from src/assets/stylesheets/modules/article/_animation.scss rename to lib/tasks/mkdocs/clean.js index 4a3cfb106..b8444b081 100644 --- a/src/assets/stylesheets/modules/article/_animation.scss +++ b/lib/tasks/mkdocs/clean.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,26 +20,16 @@ * IN THE SOFTWARE. */ +import clean from "del" +import vinyl from "vinyl-paths" + /* ---------------------------------------------------------------------------- - * Article animation + * Task: clean documentation build * ------------------------------------------------------------------------- */ -/* - * Fade color after highlighting - */ -pre span { - transition: color .25s; -} - -/* - * Copyright and theme information - */ -.copyright { - - /* - * Animate color on hover - */ - a { - transition: color .25s; +export default gulp => { + return () => { + return gulp.src("site") + .pipe(vinyl(clean)) } -} \ No newline at end of file +} diff --git a/src/assets/stylesheets/modules/drawer/_typography.scss b/lib/tasks/mkdocs/serve.js similarity index 69% rename from src/assets/stylesheets/modules/drawer/_typography.scss rename to lib/tasks/mkdocs/serve.js index 78ea4f242..102c2c8b9 100644 --- a/src/assets/stylesheets/modules/drawer/_typography.scss +++ b/lib/tasks/mkdocs/serve.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,49 +20,27 @@ * IN THE SOFTWARE. */ +import child from "child_process" + /* ---------------------------------------------------------------------------- - * Drawer typography + * Locals * ------------------------------------------------------------------------- */ -/* - * Drawer container - */ -.drawer { +/* MkDocs server */ +let server = null - /* - * Links to articles - */ - .toc li a { - font-weight: 700; - } +/* ---------------------------------------------------------------------------- + * Task: serve documentation + * ------------------------------------------------------------------------- */ - /* - * Links to chapters inside the current article - */ - .toc li.anchor a { - font-weight: 400; - } +export default () => { + return () => { + if (server) + server.kill() - /* - * Main sections - */ - .section { - font-weight: 700; + /* Spawn MkDocs server */ + server = child.spawn("mkdocs", ["serve", "-a", "0.0.0.0:8000"], { + stdio: "inherit" + }) } } - -/* - * Repository buttons - */ -.repo a { - text-transform: uppercase; - font-weight: 700; - - /* - * Stars - */ - .count { - text-transform: none; - font-weight: 700; - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/_print.scss b/lib/tasks/tests/regression/selenium.js similarity index 51% rename from src/assets/stylesheets/_print.scss rename to lib/tasks/tests/regression/selenium.js index 1b29b8b19..8c16f7df3 100644 --- a/src/assets/stylesheets/_print.scss +++ b/lib/tasks/tests/regression/selenium.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,58 +20,53 @@ * IN THE SOFTWARE. */ +import selenium from "selenium-standalone" + /* ---------------------------------------------------------------------------- - * Print overrides + * Locals * ------------------------------------------------------------------------- */ -/* - * Print styles - */ -@media print { +/* Selenium server */ +let server = null - /* - * Hide non-relevant elements - */ - .header, .drawer, .headerlink, .footer { - display: none; - } +/* ---------------------------------------------------------------------------- + * Definition + * ------------------------------------------------------------------------- */ - /* - * Article - */ - .article { +export const start = done => { + selenium.start({}, (err, proc) => { + if (err) { - /* - * Remove top spacing - */ - .wrapper { - padding-top: 0; - } + /* Install selenium, if not present */ + if (/^Missing(.*)chromedriver$/.test(err.message)) { + selenium.install(done) - /* - * Remove color in all code blocks - */ - pre, pre * { - color: $black !important; - } + /* Start selenium again */ + selenium.start({}, (err_, proc_) => { + server = proc_ + }) - pre { - border: 1px solid $black-lightest; - } - - /* - * Border-radius makes this table entirely black on paper, so scrap it - */ - table { - border-radius: none; - box-shadow: none; - - /* - * Color header - */ - th { - color: $primary; + /* Otherwise, throw error */ + } else { + throw err } } - } -} \ No newline at end of file + + /* Remember process handle */ + server = server || proc + done() + }) +} + +export const stop = () => { + if (server) + server.kill() +} + +/* ---------------------------------------------------------------------------- + * Signal handler + * ------------------------------------------------------------------------- */ + +/* Register signal handler for all relevant events */ +for (const signal of ["SIGTERM", "SIGINT", "exit"]) + process.on(signal, stop) diff --git a/lib/tasks/tests/unit/watch.js b/lib/tasks/tests/unit/watch.js new file mode 100644 index 000000000..842477e9d --- /dev/null +++ b/lib/tasks/tests/unit/watch.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import path from "path" +import { Server, stopper } from "karma" + +/* ---------------------------------------------------------------------------- + * Task: start karma test runner + * ------------------------------------------------------------------------- */ + +export default () => { + return done => { + new Server({ + configFile: path.join(process.cwd(), "tests/karma.conf.js") + }, done).start() + + /* Register signal handler for all relevant events */ + for (const signal of ["SIGTERM", "SIGINT", "exit"]) + process.on(signal, () => { + return stopper.stop({ + port: 9876, + logLevel: "OFF" + }) + }) + } +} diff --git a/lib/tasks/views/build.js b/lib/tasks/views/build.js new file mode 100644 index 000000000..645512081 --- /dev/null +++ b/lib/tasks/views/build.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import changed from "gulp-changed" +import compact from "gulp-remove-empty-lines" +import gulpif from "gulp-if" +import minhtml from "gulp-htmlmin" +import path from "path" +import replace from "gulp-replace" +import version from "gulp-rev-replace" + +/* ---------------------------------------------------------------------------- + * Task: minify views + * ------------------------------------------------------------------------- */ + +export default (gulp, config, args) => { + return () => { + const metadata = require(path.join(process.cwd(), "./package.json")) + return gulp.src(`${config.views.src}/**/*.{html,py}`) + .pipe(changed(config.views.build)) + .pipe( + minhtml({ + collapseBooleanAttributes: true, + customAttrCollapse: /(content)/, + includeAutoGeneratedTags: false, + minifyCSS: true, + minifyJS: true, + removeComments: true, + removeScriptTypeAttributes: true, + removeStyleLinkTypeAttributes: true + })) + .pipe(replace("$theme-name$", metadata.name)) + .pipe(replace("$theme-version$", metadata.version)) + .pipe(compact()) + .pipe(gulpif(args.revision, + version({ manifest: gulp.src("manifest.json") }))) + .pipe(gulp.dest(config.views.build)) + } +} diff --git a/lib/tasks/views/clean.js b/lib/tasks/views/clean.js new file mode 100644 index 000000000..95301e127 --- /dev/null +++ b/lib/tasks/views/clean.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import clean from "del" +import vinyl from "vinyl-paths" + +/* ---------------------------------------------------------------------------- + * Task: clean views + * ------------------------------------------------------------------------- */ + +export default (gulp, config) => { + return () => { + return gulp.src(`${config.views.build}/**/*.html`) + .pipe(vinyl(clean)) + } +} diff --git a/material/404.html b/material/404.html new file mode 100644 index 000000000..67cfc1126 --- /dev/null +++ b/material/404.html @@ -0,0 +1,4 @@ +{% extends "main.html" %} +{% block content %} +

404 - Not found

+{% endblock %} diff --git a/material/assets/fonts/icon.eot b/material/assets/fonts/icon.eot deleted file mode 100755 index 8f81638c2..000000000 Binary files a/material/assets/fonts/icon.eot and /dev/null differ diff --git a/material/assets/fonts/icon.svg b/material/assets/fonts/icon.svg deleted file mode 100755 index 86250e7b4..000000000 --- a/material/assets/fonts/icon.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/material/assets/fonts/icon.ttf b/material/assets/fonts/icon.ttf deleted file mode 100755 index b5ab5601b..000000000 Binary files a/material/assets/fonts/icon.ttf and /dev/null differ diff --git a/material/assets/fonts/icon.woff b/material/assets/fonts/icon.woff deleted file mode 100755 index ed0f20d5b..000000000 Binary files a/material/assets/fonts/icon.woff and /dev/null differ diff --git a/material/assets/images/favicon-e565ddfa3b.ico b/material/assets/images/favicon-e565ddfa3b.ico deleted file mode 100644 index e85006a3c..000000000 Binary files a/material/assets/images/favicon-e565ddfa3b.ico and /dev/null differ diff --git a/material/assets/images/icons/bitbucket-670608a71a.svg b/material/assets/images/icons/bitbucket-670608a71a.svg new file mode 100644 index 000000000..7d95cb22d --- /dev/null +++ b/material/assets/images/icons/bitbucket-670608a71a.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/material/assets/images/icons/github-1da075986e.svg b/material/assets/images/icons/github-1da075986e.svg new file mode 100644 index 000000000..3cacb2e0f --- /dev/null +++ b/material/assets/images/icons/github-1da075986e.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/material/assets/images/icons/gitlab-5ad3f9f9e5.svg b/material/assets/images/icons/gitlab-5ad3f9f9e5.svg new file mode 100644 index 000000000..b036a9b52 --- /dev/null +++ b/material/assets/images/icons/gitlab-5ad3f9f9e5.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/material/assets/javascripts/application-82b5011116.js b/material/assets/javascripts/application-82b5011116.js deleted file mode 100644 index d55575f79..000000000 --- a/material/assets/javascripts/application-82b5011116.js +++ /dev/null @@ -1 +0,0 @@ -function pegasus(t,e,n){return n=new XMLHttpRequest,n.open("GET",t),t=[],n.timeout=pegasus.timeout||1e4,n.ontimeout=function(t){e=t},n.onreadystatechange=n.then=function(e,o,i,r){if(e&&e.call&&(t=[,e,o]),s&&t[2]&&t[2](s,n),4==n.readyState&&(i=t[0|n.status/200])){try{r=JSON.parse(n.responseText)}catch(s){r=null}i(r,n)}},n.send(),n}if("document"in self&&("classList"in document.createElement("_")?!function(){"use strict";var t=document.createElement("_");if(t.classList.add("c1","c2"),!t.classList.contains("c2")){var e=function(t){var e=DOMTokenList.prototype[t];DOMTokenList.prototype[t]=function(t){var n,o=arguments.length;for(n=0;n=0,n=navigator.userAgent.indexOf("Android")>0&&!e,o=/iP(ad|hone|od)/.test(navigator.userAgent)&&!e,i=o&&/OS 4_\d(_\d)?/.test(navigator.userAgent),r=o&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0;t.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(o&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},t.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!n;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},t.prototype.sendClick=function(t,e){var n,o;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),o=e.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(t),!0,!0,window,1,o.screenX,o.screenY,o.clientX,o.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},t.prototype.determineEventType=function(t){return n&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},t.prototype.focus=function(t){var e;o&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},t.prototype.updateScrollParent=function(t){var e,n;if(e=t.fastClickScrollParent,!e||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},t.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},t.prototype.onTouchStart=function(t){var e,n,r;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],o){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!i){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTimen||Math.abs(e.pageY-this.touchStartY)>n},t.prototype.onTouchMove=function(t){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0)},t.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},t.prototype.onTouchEnd=function(t){var e,s,a,c,l,u=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,s=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,r&&(l=t.changedTouches[0],u=document.elementFromPoint(l.pageX-window.pageXOffset,l.pageY-window.pageYOffset)||u,u.fastClickScrollParent=this.targetElement.fastClickScrollParent),a=u.tagName.toLowerCase(),"label"===a){if(e=this.findControl(u)){if(this.focus(u),n)return!1;u=e}}else if(this.needsFocus(u))return t.timeStamp-s>100||o&&window.top!==window&&"input"===a?(this.targetElement=null,!1):(this.focus(u),this.sendClick(u,t),o&&"select"===a||(this.targetElement=null,t.preventDefault()),!1);return!(!o||i||(c=u.fastClickScrollParent,!c||c.fastClickLastScrollTop===c.scrollTop))||(this.needsClick(u)||(t.preventDefault(),this.sendClick(u,t)),!1)},t.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},t.prototype.onMouse=function(t){return!this.targetElement||(!!t.forwardedTouchEvent||(!t.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1))))},t.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail||(e=this.onMouse(t),e||(this.targetElement=null),e)},t.prototype.destroy=function(){var t=this.layer;n&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},t.notNeeded=function(t){var e,o,i,r;if("undefined"==typeof window.ontouchstart)return!0;if(o=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!n)return!0;if(e=document.querySelector("meta[name=viewport]")){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(o>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(i=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),i[1]>=10&&i[2]>=3&&(e=document.querySelector("meta[name=viewport]")))){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction||(r=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],!!(r>=27&&(e=document.querySelector("meta[name=viewport]"),e&&(e.content.indexOf("user-scalable=no")!==-1||document.documentElement.scrollWidth<=window.outerWidth)))||("none"===t.style.touchAction||"manipulation"===t.style.touchAction))},t.attach=function(e,n){return new t(e,n)},"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return t}):"undefined"!=typeof module&&module.exports?(module.exports=t.attach,module.exports.FastClick=t):window.FastClick=t}(),function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.6.0",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var o=t.Pipeline.registeredFunctions[e];if(!o)throw new Error("Cannot load un-registered function: "+e);n.add(o)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(o==-1)throw new Error("Cannot find existingFn");o+=1,this._stack.splice(o,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(o==-1)throw new Error("Cannot find existingFn");this._stack.splice(o,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);e!=-1&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,o=this._stack.length,i=0;in.idx?n=n.next:(o+=e.val*n.val,e=e.next,n=n.next);return o},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return i;rt&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i]}return r===t?i:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,o=n-e,i=e+Math.floor(o/2),r=this.elements[i];o>1;)rt&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i];return r>t?i:rr-1||i>s-1)break;a[o]!==c[i]?a[o]c[i]&&i++:(n.add(a[o]),o++,i++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,o;return this.length>=t.length?(e=this,n=t):(e=t,n=this),o=e.clone(),o.add.apply(o,n.toArray()),o},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var o={},i=new t.SortedSet,r=e[this._ref],n=void 0===n||n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));o[n.name]=r,t.SortedSet.prototype.add.apply(i,r)},this),this.documentStore.set(r,i),t.SortedSet.prototype.add.apply(this.corpusTokens,i.toArray());for(var s=0;s0&&(o=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=o},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),o=new t.Vector,i=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,c=this,l=this.tokenStore.expand(e).reduce(function(n,i){var r=c.corpusTokens.indexOf(i),s=c.idf(i),l=1,u=new t.SortedSet;if(i!==e){var d=Math.max(3,i.length-e.length);l=1/Math.log(d)}r>-1&&o.insert(r,a*s*l);for(var h=c.tokenStore.get(i),f=Object.keys(h),p=f.length,m=0;mt){for(;" "!=this[t]&&--t>0;);return this.substring(0,t)+"…"}return this},HTMLElement.prototype.wrap=function(t){t.length||(t=[t]);for(var e=t.length-1;e>=0;e--){var n=e>0?this.cloneNode(!0):this,o=t[e],i=o.parentNode,r=o.nextSibling;n.appendChild(o),r?i.insertBefore(n,r):i.appendChild(n)}},document.addEventListener("DOMContentLoaded",function(){"use strict";Modernizr.addTest("ios",function(){return!!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)}),Modernizr.addTest("standalone",function(){return!!navigator.standalone}),FastClick.attach(document.body);var t=document.getElementById("toggle-search"),e=(document.getElementById("reset-search"),document.querySelector(".drawer")),n=document.querySelectorAll(".anchor"),o=document.querySelector(".search .field"),i=document.querySelector(".query"),r=document.querySelector(".results .meta");Array.prototype.forEach.call(n,function(t){t.querySelector("a").addEventListener("click",function(){document.getElementById("toggle-drawer").checked=!1,document.body.classList.remove("toggle-drawer")})});var s=window.pageYOffset,a=function(){var t=window.pageYOffset+window.innerHeight,n=Math.max(0,window.innerHeight-e.offsetHeight);t>document.body.clientHeight-(96-n)?"absolute"!=e.style.position&&(e.style.position="absolute",e.style.top=null,e.style.bottom=0):e.offsetHeighte.offsetTop+e.offsetHeight?(e.style.position="fixed",e.style.top=null,e.style.bottom="-96px"):window.pageYOffsets?e.style.top&&(e.style.position="absolute",e.style.top=Math.max(0,s)+"px",e.style.bottom=null):e.style.bottom&&(e.style.position="absolute",e.style.top=t-e.offsetHeight+"px",e.style.bottom=null),s=Math.max(0,window.pageYOffset)},c=function(){var t=document.querySelector(".main");window.removeEventListener("scroll",a),matchMedia("only screen and (max-width: 959px)").matches?(e.style.position=null,e.style.top=null,e.style.bottom=null):e.offsetHeight+961e4?n=(n/1e3).toFixed(0)+"k":n>1e3&&(n=(n/1e3).toFixed(1)+"k");var o=document.querySelector(".repo-stars .count");o.innerHTML=n},function(t,e){console.error(t,e.status)})}),"standalone"in window.navigator&&window.navigator.standalone){var node,remotes=!1;document.addEventListener("click",function(t){for(node=t.target;"A"!==node.nodeName&&"HTML"!==node.nodeName;)node=node.parentNode;"href"in node&&node.href.indexOf("http")!==-1&&(node.href.indexOf(document.location.host)!==-1||remotes)&&(t.preventDefault(),document.location.href=node.href)},!1)} \ No newline at end of file diff --git a/material/assets/javascripts/application-ca9b3745c3.js b/material/assets/javascripts/application-ca9b3745c3.js new file mode 100644 index 000000000..c6ff05064 --- /dev/null +++ b/material/assets/javascripts/application-ca9b3745c3.js @@ -0,0 +1,58 @@ +var Application=function(t){function e(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return t[r].call(o.exports,o,o.exports,e),o.loaded=!0,o.exports}var n={};return e.m=t,e.c=n,e.p="",e(0)}([function(t,e,n){n(1),n(65),n(66),t.exports=n(67)},function(t,e,n){"use strict";n(2),n(22),n(48),n(52),t.exports=n(21).Promise},function(t,e,n){"use strict";var r=n(3),o={};o[n(5)("toStringTag")]="z",o+""!="[object z]"&&n(9)(Object.prototype,"toString",function(){return"[object "+r(this)+"]"},!0)},function(t,e,n){"use strict";var r=n(4),o=n(5)("toStringTag"),i="Arguments"==r(function(){return arguments}()),s=function(t,e){try{return t[e]}catch(n){}};t.exports=function(t){var e,n,a;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(n=s(e=Object(t),o))?n:i?r(e):"Object"==(a=r(e))&&"function"==typeof e.callee?"Arguments":a}},function(t,e){"use strict";var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){"use strict";var r=n(6)("wks"),o=n(8),i=n(7).Symbol,s="function"==typeof i,a=t.exports=function(t){return r[t]||(r[t]=s&&i[t]||(s?i:o)("Symbol."+t))};a.store=r},function(t,e,n){"use strict";var r=n(7),o="__core-js_shared__",i=r[o]||(r[o]={});t.exports=function(t){return i[t]||(i[t]={})}},function(t,e){"use strict";var n=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=n)},function(t,e){"use strict";var n=0,r=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++n+r).toString(36))}},function(t,e,n){"use strict";var r=n(7),o=n(10),i=n(20),s=n(8)("src"),a="toString",u=Function[a],c=(""+u).split(a);n(21).inspectSource=function(t){return u.call(t)},(t.exports=function(t,e,n,a){var u="function"==typeof n;u&&(i(n,"name")||o(n,"name",e)),t[e]!==n&&(u&&(i(n,s)||o(n,s,t[e]?""+t[e]:c.join(String(e)))),t===r?t[e]=n:a?t[e]?t[e]=n:o(t,e,n):(delete t[e],o(t,e,n)))})(Function.prototype,a,function(){return"function"==typeof this&&this[s]||u.call(this)})},function(t,e,n){"use strict";var r=n(11),o=n(19);t.exports=n(15)?function(t,e,n){return r.f(t,e,o(1,n))}:function(t,e,n){return t[e]=n,t}},function(t,e,n){"use strict";var r=n(12),o=n(14),i=n(18),s=Object.defineProperty;e.f=n(15)?Object.defineProperty:function(t,e,n){if(r(t),e=i(e,!0),r(n),o)try{return s(t,e,n)}catch(a){}if("get"in n||"set"in n)throw TypeError("Accessors not supported!");return"value"in n&&(t[e]=n.value),t}},function(t,e,n){"use strict";var r=n(13);t.exports=function(t){if(!r(t))throw TypeError(t+" is not an object!");return t}},function(t,e){"use strict";var n="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t};t.exports=function(t){return"object"===("undefined"==typeof t?"undefined":n(t))?null!==t:"function"==typeof t}},function(t,e,n){"use strict";t.exports=!n(15)&&!n(16)(function(){return 7!=Object.defineProperty(n(17)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";t.exports=!n(16)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e){"use strict";t.exports=function(t){try{return!!t()}catch(e){return!0}}},function(t,e,n){"use strict";var r=n(13),o=n(7).document,i=r(o)&&r(o.createElement);t.exports=function(t){return i?o.createElement(t):{}}},function(t,e,n){"use strict";var r=n(13);t.exports=function(t,e){if(!r(t))return t;var n,o;if(e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;if("function"==typeof(n=t.valueOf)&&!r(o=n.call(t)))return o;if(!e&&"function"==typeof(n=t.toString)&&!r(o=n.call(t)))return o;throw TypeError("Can't convert object to primitive value")}},function(t,e){"use strict";t.exports=function(t,e){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:e}}},function(t,e){"use strict";var n={}.hasOwnProperty;t.exports=function(t,e){return n.call(t,e)}},function(t,e){"use strict";var n=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=n)},function(t,e,n){"use strict";var r=n(23)(!0);n(26)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,e=this._t,n=this._i;return n>=e.length?{value:void 0,done:!0}:(t=r(e,n),this._i+=t.length,{value:t,done:!1})})},function(t,e,n){"use strict";var r=n(24),o=n(25);t.exports=function(t){return function(e,n){var i,s,a=String(o(e)),u=r(n),c=a.length;return u<0||u>=c?t?"":void 0:(i=a.charCodeAt(u),i<55296||i>56319||u+1===c||(s=a.charCodeAt(u+1))<56320||s>57343?t?a.charAt(u):i:t?a.slice(u,u+2):(i-55296<<10)+(s-56320)+65536)}}},function(t,e){"use strict";var n=Math.ceil,r=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?r:n)(t)}},function(t,e){"use strict";t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,e,n){"use strict";var r=n(27),o=n(28),i=n(9),s=n(10),a=n(20),u=n(31),c=n(32),l=n(45),f=n(46),d=n(5)("iterator"),h=!([].keys&&"next"in[].keys()),p="@@iterator",v="keys",m="values",y=function(){return this};t.exports=function(t,e,n,g,w,_,b){c(n,e,g);var S,x,E,k=function(t){if(!h&&t in C)return C[t];switch(t){case v:return function(){return new n(this,t)};case m:return function(){return new n(this,t)}}return function(){return new n(this,t)}},T=e+" Iterator",O=w==m,P=!1,C=t.prototype,M=C[d]||C[p]||w&&C[w],j=M||k(w),A=w?O?k("entries"):j:void 0,L="Array"==e?C.entries||M:M;if(L&&(E=f(L.call(new t)),E!==Object.prototype&&(l(E,T,!0),r||a(E,d)||s(E,d,y))),O&&M&&M.name!==m&&(P=!0,j=function(){return M.call(this)}),r&&!b||!h&&!P&&C[d]||s(C,d,j),u[e]=j,u[T]=y,w)if(S={values:O?j:k(m),keys:_?j:k(v),entries:A},b)for(x in S)x in C||i(C,x,S[x]);else o(o.P+o.F*(h||P),e,S);return S}},function(t,e){"use strict";t.exports=!1},function(t,e,n){"use strict";var r=n(7),o=n(21),i=n(10),s=n(9),a=n(29),u="prototype",c=function l(t,e,n){var c,f,d,h,p=t&l.F,v=t&l.G,m=t&l.S,y=t&l.P,g=t&l.B,w=v?r:m?r[e]||(r[e]={}):(r[e]||{})[u],_=v?o:o[e]||(o[e]={}),b=_[u]||(_[u]={});v&&(n=e);for(c in n)f=!p&&w&&void 0!==w[c],d=(f?w:n)[c],h=g&&f?a(d,r):y&&"function"==typeof d?a(Function.call,d):d,w&&s(w,c,d,t&l.U),_[c]!=d&&i(_,c,h),y&&b[c]!=d&&(b[c]=d)};r.core=o,c.F=1,c.G=2,c.S=4,c.P=8,c.B=16,c.W=32,c.U=64,c.R=128,t.exports=c},function(t,e,n){"use strict";var r=n(30);t.exports=function(t,e,n){if(r(t),void 0===e)return t;switch(n){case 1:return function(n){return t.call(e,n)};case 2:return function(n,r){return t.call(e,n,r)};case 3:return function(n,r,o){return t.call(e,n,r,o)}}return function(){return t.apply(e,arguments)}}},function(t,e){"use strict";t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,e){"use strict";t.exports={}},function(t,e,n){"use strict";var r=n(33),o=n(19),i=n(45),s={};n(10)(s,n(5)("iterator"),function(){return this}),t.exports=function(t,e,n){t.prototype=r(s,{next:o(1,n)}),i(t,e+" Iterator")}},function(t,e,n){"use strict";var r=n(12),o=n(34),i=n(43),s=n(42)("IE_PROTO"),a=function(){},u="prototype",c=function(){var t,e=n(17)("iframe"),r=i.length,o="<",s=">";for(e.style.display="none",n(44).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(o+"script"+s+"document.F=Object"+o+"/script"+s),t.close(),c=t.F;r--;)delete c[u][i[r]];return c()};t.exports=Object.create||function(t,e){var n;return null!==t?(a[u]=r(t),n=new a,a[u]=null,n[s]=t):n=c(),void 0===e?n:o(n,e)}},function(t,e,n){"use strict";var r=n(11),o=n(12),i=n(35);t.exports=n(15)?Object.defineProperties:function(t,e){o(t);for(var n,s=i(e),a=s.length,u=0;a>u;)r.f(t,n=s[u++],e[n]);return t}},function(t,e,n){"use strict";var r=n(36),o=n(43);t.exports=Object.keys||function(t){return r(t,o)}},function(t,e,n){"use strict";var r=n(20),o=n(37),i=n(39)(!1),s=n(42)("IE_PROTO");t.exports=function(t,e){var n,a=o(t),u=0,c=[];for(n in a)n!=s&&r(a,n)&&c.push(n);for(;e.length>u;)r(a,n=e[u++])&&(~i(c,n)||c.push(n));return c}},function(t,e,n){"use strict";var r=n(38),o=n(25);t.exports=function(t){return r(o(t))}},function(t,e,n){"use strict";var r=n(4);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==r(t)?t.split(""):Object(t)}},function(t,e,n){"use strict";var r=n(37),o=n(40),i=n(41);t.exports=function(t){return function(e,n,s){var a,u=r(e),c=o(u.length),l=i(s,c);if(t&&n!=n){for(;c>l;)if(a=u[l++],a!=a)return!0}else for(;c>l;l++)if((t||l in u)&&u[l]===n)return t||l||0;return!t&&-1}}},function(t,e,n){"use strict";var r=n(24),o=Math.min;t.exports=function(t){return t>0?o(r(t),9007199254740991):0}},function(t,e,n){"use strict";var r=n(24),o=Math.max,i=Math.min;t.exports=function(t,e){return t=r(t),t<0?o(t+e,0):i(t,e)}},function(t,e,n){"use strict";var r=n(6)("keys"),o=n(8);t.exports=function(t){return r[t]||(r[t]=o(t))}},function(t,e){"use strict";t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,e,n){"use strict";t.exports=n(7).document&&document.documentElement},function(t,e,n){"use strict";var r=n(11).f,o=n(20),i=n(5)("toStringTag");t.exports=function(t,e,n){t&&!o(t=n?t:t.prototype,i)&&r(t,i,{configurable:!0,value:e})}},function(t,e,n){"use strict";var r=n(20),o=n(47),i=n(42)("IE_PROTO"),s=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=o(t),r(t,i)?t[i]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?s:null}},function(t,e,n){"use strict";var r=n(25);t.exports=function(t){return Object(r(t))}},function(t,e,n){"use strict";for(var r=n(49),o=n(9),i=n(7),s=n(10),a=n(31),u=n(5),c=u("iterator"),l=u("toStringTag"),f=a.Array,d=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],h=0;h<5;h++){var p,v=d[h],m=i[v],y=m&&m.prototype;if(y){y[c]||s(y,c,f),y[l]||s(y,l,v),a[v]=f;for(p in r)y[p]||o(y,p,r[p],!0)}}},function(t,e,n){"use strict";var r=n(50),o=n(51),i=n(31),s=n(37);t.exports=n(26)(Array,"Array",function(t,e){this._t=s(t),this._i=0,this._k=e},function(){var t=this._t,e=this._k,n=this._i++;return!t||n>=t.length?(this._t=void 0,o(1)):"keys"==e?o(0,n):"values"==e?o(0,t[n]):o(0,[n,t[n]])},"values"),i.Arguments=i.Array,r("keys"),r("values"),r("entries")},function(t,e,n){"use strict";var r=n(5)("unscopables"),o=Array.prototype;void 0==o[r]&&n(10)(o,r,{}),t.exports=function(t){o[r][t]=!0}},function(t,e){"use strict";t.exports=function(t,e){return{value:e,done:!!t}}},function(t,e,n){"use strict";var r,o,i,s=n(27),a=n(7),u=n(29),c=n(3),l=n(28),f=n(13),d=n(30),h=n(53),p=n(54),v=n(58),m=n(59).set,y=n(61)(),g="Promise",w=a.TypeError,_=a.process,b=a[g],_=a.process,S="process"==c(_),x=function(){},E=!!function(){try{var t=b.resolve(1),e=(t.constructor={})[n(5)("species")]=function(t){t(x,x)};return(S||"function"==typeof PromiseRejectionEvent)&&t.then(x)instanceof e}catch(r){}}(),k=function(t,e){return t===e||t===b&&e===i},T=function(t){var e;return!(!f(t)||"function"!=typeof(e=t.then))&&e},O=function(t){return k(b,t)?new P(t):new o(t)},P=o=function(t){var e,n;this.promise=new t(function(t,r){if(void 0!==e||void 0!==n)throw w("Bad Promise constructor");e=t,n=r}),this.resolve=d(e),this.reject=d(n)},C=function(t){try{t()}catch(e){return{error:e}}},M=function(t,e){if(!t._n){t._n=!0;var n=t._c;y(function(){for(var r=t._v,o=1==t._s,i=0,s=function(e){var n,i,s=o?e.ok:e.fail,a=e.resolve,u=e.reject,c=e.domain;try{s?(o||(2==t._h&&L(t),t._h=1),s===!0?n=r:(c&&c.enter(),n=s(r),c&&c.exit()),n===e.promise?u(w("Promise-chain cycle")):(i=T(n))?i.call(n,a,u):a(n)):u(r)}catch(l){u(l)}};n.length>i;)s(n[i++]);t._c=[],t._n=!1,e&&!t._h&&j(t)})}},j=function(t){m.call(a,function(){var e,n,r,o=t._v;if(A(t)&&(e=C(function(){S?_.emit("unhandledRejection",o,t):(n=a.onunhandledrejection)?n({promise:t,reason:o}):(r=a.console)&&r.error&&r.error("Unhandled promise rejection",o)}),t._h=S||A(t)?2:1),t._a=void 0,e)throw e.error})},A=function R(t){if(1==t._h)return!1;for(var e,n=t._a||t._c,r=0;n.length>r;)if(e=n[r++],e.fail||!R(e.promise))return!1;return!0},L=function(t){m.call(a,function(){var e;S?_.emit("rejectionHandled",t):(e=a.onrejectionhandled)&&e({promise:t,reason:t._v})})},F=function(t){var e=this;e._d||(e._d=!0,e=e._w||e,e._v=t,e._s=2,e._a||(e._a=e._c.slice()),M(e,!0))},N=function I(t){var e,n=this;if(!n._d){n._d=!0,n=n._w||n;try{if(n===t)throw w("Promise can't be resolved itself");(e=T(t))?y(function(){var r={_w:n,_d:!1};try{e.call(t,u(I,r,1),u(F,r,1))}catch(o){F.call(r,o)}}):(n._v=t,n._s=1,M(n,!1))}catch(r){F.call({_w:n,_d:!1},r)}}};E||(b=function(t){h(this,b,g,"_h"),d(t),r.call(this);try{t(u(N,this,1),u(F,this,1))}catch(e){F.call(this,e)}},r=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},r.prototype=n(62)(b.prototype,{then:function(t,e){var n=O(v(this,b));return n.ok="function"!=typeof t||t,n.fail="function"==typeof e&&e,n.domain=S?_.domain:void 0,this._c.push(n),this._a&&this._a.push(n),this._s&&M(this,!1),n.promise},"catch":function(t){return this.then(void 0,t)}}),P=function(){var t=new r;this.promise=t,this.resolve=u(N,t,1),this.reject=u(F,t,1)}),l(l.G+l.W+l.F*!E,{Promise:b}),n(45)(b,g),n(63)(g),i=n(21)[g],l(l.S+l.F*!E,g,{reject:function(t){var e=O(this),n=e.reject;return n(t),e.promise}}),l(l.S+l.F*(s||!E),g,{resolve:function(t){if(t instanceof b&&k(t.constructor,this))return t;var e=O(this),n=e.resolve;return n(t),e.promise}}),l(l.S+l.F*!(E&&n(64)(function(t){b.all(t)["catch"](x)})),g,{all:function(t){var e=this,n=O(e),r=n.resolve,o=n.reject,i=C(function(){var n=[],i=0,s=1;p(t,!1,function(t){var a=i++,u=!1;n.push(void 0),s++,e.resolve(t).then(function(t){u||(u=!0,n[a]=t,--s||r(n))},o)}),--s||r(n)});return i&&o(i.error),n.promise},race:function(t){var e=this,n=O(e),r=n.reject,o=C(function(){p(t,!1,function(t){e.resolve(t).then(n.resolve,r)})});return o&&r(o.error),n.promise}})},function(t,e){"use strict";t.exports=function(t,e,n,r){if(!(t instanceof e)||void 0!==r&&r in t)throw TypeError(n+": incorrect invocation!");return t}},function(t,e,n){"use strict";var r=n(29),o=n(55),i=n(56),s=n(12),a=n(40),u=n(57),c={},l={},f=t.exports=function(t,e,n,f,d){var h,p,v,m,y=d?function(){return t}:u(t),g=r(n,f,e?2:1),w=0;if("function"!=typeof y)throw TypeError(t+" is not iterable!");if(i(y)){for(h=a(t.length);h>w;w++)if(m=e?g(s(p=t[w])[0],p[1]):g(t[w]),m===c||m===l)return m}else for(v=y.call(t);!(p=v.next()).done;)if(m=o(v,g,p.value,e),m===c||m===l)return m};f.BREAK=c,f.RETURN=l},function(t,e,n){"use strict";var r=n(12);t.exports=function(t,e,n,o){try{return o?e(r(n)[0],n[1]):e(n)}catch(i){var s=t["return"];throw void 0!==s&&r(s.call(t)),i}}},function(t,e,n){"use strict";var r=n(31),o=n(5)("iterator"),i=Array.prototype;t.exports=function(t){return void 0!==t&&(r.Array===t||i[o]===t)}},function(t,e,n){"use strict";var r=n(3),o=n(5)("iterator"),i=n(31);t.exports=n(21).getIteratorMethod=function(t){if(void 0!=t)return t[o]||t["@@iterator"]||i[r(t)]}},function(t,e,n){"use strict";var r=n(12),o=n(30),i=n(5)("species");t.exports=function(t,e){var n,s=r(t).constructor;return void 0===s||void 0==(n=r(s)[i])?e:o(n)}},function(t,e,n){"use strict";var r,o,i,s=n(29),a=n(60),u=n(44),c=n(17),l=n(7),f=l.process,d=l.setImmediate,h=l.clearImmediate,p=l.MessageChannel,v=0,m={},y="onreadystatechange",g=function(){var t=+this;if(m.hasOwnProperty(t)){var e=m[t];delete m[t],e()}},w=function(t){g.call(t.data)};d&&h||(d=function(t){for(var e=[],n=1;arguments.length>n;)e.push(arguments[n++]);return m[++v]=function(){a("function"==typeof t?t:Function(t),e)},r(v),v},h=function(t){delete m[t]},"process"==n(4)(f)?r=function(t){f.nextTick(s(g,t,1))}:p?(o=new p,i=o.port2,o.port1.onmessage=w,r=s(i.postMessage,i,1)):l.addEventListener&&"function"==typeof postMessage&&!l.importScripts?(r=function(t){l.postMessage(t+"","*")},l.addEventListener("message",w,!1)):r=y in c("script")?function(t){u.appendChild(c("script"))[y]=function(){u.removeChild(this),g.call(t)}}:function(t){setTimeout(s(g,t,1),0)}),t.exports={set:d,clear:h}},function(t,e){"use strict";t.exports=function(t,e,n){var r=void 0===n;switch(e.length){case 0:return r?t():t.call(n);case 1:return r?t(e[0]):t.call(n,e[0]);case 2:return r?t(e[0],e[1]):t.call(n,e[0],e[1]);case 3:return r?t(e[0],e[1],e[2]):t.call(n,e[0],e[1],e[2]);case 4:return r?t(e[0],e[1],e[2],e[3]):t.call(n,e[0],e[1],e[2],e[3])}return t.apply(n,e)}},function(t,e,n){"use strict";var r=n(7),o=n(59).set,i=r.MutationObserver||r.WebKitMutationObserver,s=r.process,a=r.Promise,u="process"==n(4)(s);t.exports=function(){var t,e,n,c=function(){var r,o;for(u&&(r=s.domain)&&r.exit();t;){o=t.fn,t=t.next;try{o()}catch(i){throw t?n():e=void 0,i}}e=void 0,r&&r.enter()};if(u)n=function(){s.nextTick(c)};else if(i){var l=!0,f=document.createTextNode("");new i(c).observe(f,{characterData:!0}),n=function(){f.data=l=!l}}else if(a&&a.resolve){var d=a.resolve();n=function(){d.then(c)}}else n=function(){o.call(r,c)};return function(r){var o={fn:r,next:void 0};e&&(e.next=o),t||(t=o,n()),e=o}}},function(t,e,n){"use strict";var r=n(9);t.exports=function(t,e,n){for(var o in e)r(t,o,e[o],n);return t}},function(t,e,n){"use strict";var r=n(7),o=n(11),i=n(15),s=n(5)("species");t.exports=function(t){var e=r[t];i&&e&&!e[s]&&o.f(e,s,{configurable:!0,get:function(){return this}})}},function(t,e,n){"use strict";var r=n(5)("iterator"),o=!1;try{var i=[7][r]();i["return"]=function(){o=!0},Array.from(i,function(){throw 2})}catch(s){}t.exports=function(t,e){if(!e&&!o)return!1;var n=!1;try{var i=[7],s=i[r]();s.next=function(){return{done:n=!0}},i[r]=function(){return s},t(i)}catch(a){}return n}},function(t,e){"use strict";try{var n=new window.CustomEvent("test");if(n.preventDefault(),n.defaultPrevented!==!0)throw new Error("Could not prevent default")}catch(r){var o=function(t,e){var n,r;return e=e||{bubbles:!1,cancelable:!1,detail:void 0},n=document.createEvent("CustomEvent"),n.initCustomEvent(t,e.bubbles,e.cancelable,e.detail),r=n.preventDefault,n.preventDefault=function(){r.call(this);try{Object.defineProperty(this,"defaultPrevented",{get:function(){return!0}})}catch(t){this.defaultPrevented=!0}},n};o.prototype=window.Event.prototype,window.CustomEvent=o}},function(t,e){"use strict";!function(t){function e(t){if("string"!=typeof t&&(t=String(t)),/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(t))throw new TypeError("Invalid character in header field name");return t.toLowerCase()}function n(t){return"string"!=typeof t&&(t=String(t)),t}function r(t){var e={next:function(){var e=t.shift();return{done:void 0===e,value:e}}};return v.iterable&&(e[Symbol.iterator]=function(){return e}),e}function o(t){this.map={},t instanceof o?t.forEach(function(t,e){this.append(e,t)},this):t&&Object.getOwnPropertyNames(t).forEach(function(e){this.append(e,t[e])},this)}function i(t){return t.bodyUsed?Promise.reject(new TypeError("Already read")):void(t.bodyUsed=!0)}function s(t){return new Promise(function(e,n){t.onload=function(){e(t.result)},t.onerror=function(){n(t.error)}})}function a(t){var e=new FileReader;return e.readAsArrayBuffer(t),s(e)}function u(t){var e=new FileReader;return e.readAsText(t),s(e)}function c(){return this.bodyUsed=!1,this._initBody=function(t){if(this._bodyInit=t,"string"==typeof t)this._bodyText=t;else if(v.blob&&Blob.prototype.isPrototypeOf(t))this._bodyBlob=t;else if(v.formData&&FormData.prototype.isPrototypeOf(t))this._bodyFormData=t;else if(v.searchParams&&URLSearchParams.prototype.isPrototypeOf(t))this._bodyText=t.toString();else if(t){if(!v.arrayBuffer||!ArrayBuffer.prototype.isPrototypeOf(t))throw new Error("unsupported BodyInit type")}else this._bodyText="";this.headers.get("content-type")||("string"==typeof t?this.headers.set("content-type","text/plain;charset=UTF-8"):this._bodyBlob&&this._bodyBlob.type?this.headers.set("content-type",this._bodyBlob.type):v.searchParams&&URLSearchParams.prototype.isPrototypeOf(t)&&this.headers.set("content-type","application/x-www-form-urlencoded;charset=UTF-8"))},v.blob?(this.blob=function(){var t=i(this);if(t)return t;if(this._bodyBlob)return Promise.resolve(this._bodyBlob);if(this._bodyFormData)throw new Error("could not read FormData body as blob");return Promise.resolve(new Blob([this._bodyText]))},this.arrayBuffer=function(){return this.blob().then(a)},this.text=function(){var t=i(this);if(t)return t;if(this._bodyBlob)return u(this._bodyBlob);if(this._bodyFormData)throw new Error("could not read FormData body as text");return Promise.resolve(this._bodyText)}):this.text=function(){var t=i(this);return t?t:Promise.resolve(this._bodyText)},v.formData&&(this.formData=function(){return this.text().then(d)}),this.json=function(){return this.text().then(JSON.parse)},this}function l(t){var e=t.toUpperCase();return m.indexOf(e)>-1?e:t}function f(t,e){e=e||{};var n=e.body;if(f.prototype.isPrototypeOf(t)){if(t.bodyUsed)throw new TypeError("Already read");this.url=t.url,this.credentials=t.credentials,e.headers||(this.headers=new o(t.headers)),this.method=t.method,this.mode=t.mode,n||(n=t._bodyInit,t.bodyUsed=!0)}else this.url=t;if(this.credentials=e.credentials||this.credentials||"omit",!e.headers&&this.headers||(this.headers=new o(e.headers)),this.method=l(e.method||this.method||"GET"),this.mode=e.mode||this.mode||null,this.referrer=null,("GET"===this.method||"HEAD"===this.method)&&n)throw new TypeError("Body not allowed for GET or HEAD requests");this._initBody(n)}function d(t){var e=new FormData;return t.trim().split("&").forEach(function(t){if(t){var n=t.split("="),r=n.shift().replace(/\+/g," "),o=n.join("=").replace(/\+/g," ");e.append(decodeURIComponent(r),decodeURIComponent(o))}}),e}function h(t){var e=new o,n=(t.getAllResponseHeaders()||"").trim().split("\n");return n.forEach(function(t){var n=t.trim().split(":"),r=n.shift().trim(),o=n.join(":").trim();e.append(r,o)}),e}function p(t,e){e||(e={}),this.type="default",this.status=e.status,this.ok=this.status>=200&&this.status<300,this.statusText=e.statusText,this.headers=e.headers instanceof o?e.headers:new o(e.headers),this.url=e.url||"",this._initBody(t)}if(!t.fetch){var v={searchParams:"URLSearchParams"in t,iterable:"Symbol"in t&&"iterator"in Symbol,blob:"FileReader"in t&&"Blob"in t&&function(){try{return new Blob,!0}catch(t){return!1}}(),formData:"FormData"in t,arrayBuffer:"ArrayBuffer"in t};o.prototype.append=function(t,r){t=e(t),r=n(r);var o=this.map[t];o||(o=[],this.map[t]=o),o.push(r)},o.prototype["delete"]=function(t){delete this.map[e(t)]},o.prototype.get=function(t){var n=this.map[e(t)];return n?n[0]:null},o.prototype.getAll=function(t){return this.map[e(t)]||[]},o.prototype.has=function(t){return this.map.hasOwnProperty(e(t))},o.prototype.set=function(t,r){this.map[e(t)]=[n(r)]},o.prototype.forEach=function(t,e){Object.getOwnPropertyNames(this.map).forEach(function(n){this.map[n].forEach(function(r){t.call(e,r,n,this)},this)},this)},o.prototype.keys=function(){var t=[];return this.forEach(function(e,n){t.push(n)}),r(t)},o.prototype.values=function(){var t=[];return this.forEach(function(e){t.push(e)}),r(t)},o.prototype.entries=function(){var t=[];return this.forEach(function(e,n){t.push([n,e])}),r(t)},v.iterable&&(o.prototype[Symbol.iterator]=o.prototype.entries);var m=["DELETE","GET","HEAD","OPTIONS","POST","PUT"];f.prototype.clone=function(){return new f(this)},c.call(f.prototype),c.call(p.prototype),p.prototype.clone=function(){return new p(this._bodyInit,{status:this.status,statusText:this.statusText,headers:new o(this.headers),url:this.url})},p.error=function(){var t=new p(null,{status:0,statusText:""});return t.type="error",t};var y=[301,302,303,307,308];p.redirect=function(t,e){if(y.indexOf(e)===-1)throw new RangeError("Invalid status code");return new p(null,{status:e,headers:{location:t}})},t.Headers=o,t.Request=f,t.Response=p,t.fetch=function(t,e){return new Promise(function(n,r){function o(){return"responseURL"in s?s.responseURL:/^X-Request-URL:/m.test(s.getAllResponseHeaders())?s.getResponseHeader("X-Request-URL"):void 0}var i;i=f.prototype.isPrototypeOf(t)&&!e?t:new f(t,e);var s=new XMLHttpRequest;s.onload=function(){var t={status:s.status,statusText:s.statusText,headers:h(s),url:o()},e="response"in s?s.response:s.responseText;n(new p(e,t))},s.onerror=function(){r(new TypeError("Network request failed"))},s.ontimeout=function(){r(new TypeError("Network request failed"))},s.open(i.method,i.url,!0),"include"===i.credentials&&(s.withCredentials=!0),"responseType"in s&&v.blob&&(s.responseType="blob"),i.headers.forEach(function(t,e){s.setRequestHeader(e,t)}),s.send("undefined"==typeof i._bodyInit?null:i._bodyInit)})},t.fetch.polyfill=!0}}("undefined"!=typeof self?self:void 0)},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var i=function(){function t(t,e){for(var n=0;n=0,a=navigator.userAgent.indexOf("Android")>0&&!s,u=/iP(ad|hone|od)/.test(navigator.userAgent)&&!s,c=u&&/OS 4_\d(_\d)?/.test(navigator.userAgent),l=u&&/OS [6-7]_\d/.test(navigator.userAgent),f=navigator.userAgent.indexOf("BB10")>0;i.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(u&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},i.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!a;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},i.prototype.sendClick=function(t,e){var n,r;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),r=e.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(t),!0,!0,window,1,r.screenX,r.screenY,r.clientX,r.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},i.prototype.determineEventType=function(t){return a&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},i.prototype.focus=function(t){var e;u&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},i.prototype.updateScrollParent=function(t){var e,n;if(e=t.fastClickScrollParent,!e||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},i.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},i.prototype.onTouchStart=function(t){var e,n,r;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],u){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!c){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTimen||Math.abs(e.pageY-this.touchStartY)>n},i.prototype.onTouchMove=function(t){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0)},i.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},i.prototype.onTouchEnd=function(t){var e,n,r,o,i,s=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,n=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,l&&(i=t.changedTouches[0],s=document.elementFromPoint(i.pageX-window.pageXOffset,i.pageY-window.pageYOffset)||s,s.fastClickScrollParent=this.targetElement.fastClickScrollParent),r=s.tagName.toLowerCase(),"label"===r){if(e=this.findControl(s)){if(this.focus(s),a)return!1;s=e}}else if(this.needsFocus(s))return t.timeStamp-n>100||u&&window.top!==window&&"input"===r?(this.targetElement=null,!1):(this.focus(s),this.sendClick(s,t),u&&"select"===r||(this.targetElement=null,t.preventDefault()),!1);return!(!u||c||(o=s.fastClickScrollParent,!o||o.fastClickLastScrollTop===o.scrollTop))||(this.needsClick(s)||(t.preventDefault(),this.sendClick(s,t)),!1)},i.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},i.prototype.onMouse=function(t){return!this.targetElement||(!!t.forwardedTouchEvent||(!t.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1))))},i.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail||(e=this.onMouse(t),e||(this.targetElement=null),e)},i.prototype.destroy=function(){var t=this.layer;a&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},i.notNeeded=function(t){var e,n,r,o;if("undefined"==typeof window.ontouchstart)return!0;if(n=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!a)return!0;if(e=document.querySelector("meta[name=viewport]")){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(n>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(f&&(r=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),r[1]>=10&&r[2]>=3&&(e=document.querySelector("meta[name=viewport]")))){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction||(o=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],!!(o>=27&&(e=document.querySelector("meta[name=viewport]"),e&&(e.content.indexOf("user-scalable=no")!==-1||document.documentElement.scrollWidth<=window.outerWidth)))||("none"===t.style.touchAction||"manipulation"===t.style.touchAction))},i.attach=function(t,e){return new i(t,e)},"object"===o(n(69))&&n(69)?(r=function(){return i}.call(e,n,e,t),!(void 0!==r&&(t.exports=r))):"undefined"!=typeof t&&t.exports?(t.exports=i.attach,t.exports.FastClick=i):window.FastClick=i}()},function(t,e){(function(e){t.exports=e}).call(e,{})},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var o=n(71),i=r(o),s=n(74),a=r(s),u=n(78),c=r(u),l=n(83),f=r(l),d=n(86),h=r(d);e["default"]={Event:i["default"],Nav:a["default"],Search:c["default"],Sidebar:f["default"],Source:h["default"]},t.exports=e["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var o=n(72),i=r(o),s=n(73),a=r(s);e["default"]={Listener:i["default"],MatchMedia:a["default"]},t.exports=e["default"]},function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;n0&&(this.els_[e-1].dataset.mdState="blur"),this.index_=e;else for(var n=this.index_;n>=0;n--){if(!(this.anchors_[n].offsetTop-80>t)){this.index_=n;break}n>0&&(this.els_[n-1].dataset.mdState="")}this.offset_=t}}},{key:"reset",value:function(){Array.prototype.forEach.call(this.els_,function(t){t.dataset.mdState=""}),this.index_=0,this.offset_=window.pageYOffset}}]),t}();e["default"]=o,t.exports=e["default"]},function(t,e){"use strict";function n(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(e,"__esModule",{value:!0});var r=function(){function t(t,e){for(var n=0;nn){for(;" "!==t[n]&&--n>0;);return t.substring(0,n)+"..."}return t}}return a(t,[{key:"update",value:function(t){var e=this;if("focus"!==t.type||this.index_){if("keyup"===t.type){for(;this.list_.firstChild;)this.list_.removeChild(this.list_.firstChild);var n=this.index_.search(t.target.value);n.forEach(function(t){var n=e.data_[t.ref],o=n.location.split("#"),i=s(o,1),a=i[0];a=a.replace(/^(\/?\.{2})+/g,""),e.list_.appendChild(r.createElement("li",{"class":"md-search-result__item"},r.createElement("a",{href:n.location,title:n.title,"class":"md-search-result__link","data-md-rel":a===document.location.pathname?"anchor":""},r.createElement("article",{"class":"md-search-result__article"},r.createElement("h1",{"class":"md-search-result__title"},n.title),r.createElement("p",{"class":"md-search-result__teaser"},e.truncate_(n.text,140))))))});var o=this.list_.querySelectorAll("[data-md-rel=anchor]");Array.prototype.forEach.call(o,function(t){t.addEventListener("click",function(e){var n=document.querySelector("[data-md-toggle=search]");n.checked&&(n.checked=!1,n.dispatchEvent(new CustomEvent("change"))),e.preventDefault(),setTimeout(function(){document.location.href=t.href},100)})}),this.meta_.textContent=n.length+" search result"+(1!==n.length?"s":"")}}else!function(){var t=function(t){e.index_=(0,c["default"])(function(){this.field("title",{boost:10}),this.field("text"),this.ref("location")}),e.data_=t.reduce(function(t,n){return e.index_.add(n),t[n.location]=n,t},{})};setTimeout(function(){return"function"==typeof e.data_?e.data_().then(t):t(e.data_)},250)}()}}]),t}();e["default"]=l,t.exports=e["default"]}).call(e,n(81))},function(t,e){"use strict";Object.defineProperty(e,"__esModule",{value:!0}),e["default"]={createElement:function(t,e){var n=document.createElement(t);e&&Array.prototype.forEach.call(Object.keys(e),function(t){n.setAttribute(t,e[t])});for(var r=function a(t){Array.prototype.forEach.call(t,function(t){"string"==typeof t||"number"==typeof t?n.textContent+=t:Array.isArray(t)?a(t):n.appendChild(t)})},o=arguments.length,i=Array(o>2?o-2:0),s=2;sn.idx?n=n.next:(r+=e.val*n.val,e=e.next,n=n.next);return r},i.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},/*! + * lunr.SortedSet + * Copyright (C) 2016 Oliver Nightingale + */ +i.SortedSet=function(){this.length=0,this.elements=[]},i.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},i.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(i===t)return o;it&&(n=o),r=n-e,o=e+Math.floor(r/2),i=this.elements[o]}return i===t?o:-1},i.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,r=n-e,o=e+Math.floor(r/2),i=this.elements[o];r>1;)it&&(n=o),r=n-e,o=e+Math.floor(r/2),i=this.elements[o];return i>t?o:io-1||r>s-1)break;a[n]!==u[r]?a[n]u[r]&&r++:(e.add(a[n]),n++,r++)}return e},i.SortedSet.prototype.clone=function(){var t=new i.SortedSet;return t.elements=this.toArray(),t.length=t.elements.length,t},i.SortedSet.prototype.union=function(t){var e,n,r;this.length>=t.length?(e=this,n=t):(e=t,n=this),r=e.clone();for(var o=0,i=n.toArray();o0&&(r=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=r},i.Index.prototype.search=function(t){var e=this.pipeline.run(this.tokenizerFn(t)),n=new i.Vector,r=[],o=this._fields.reduce(function(t,e){return t+e.boost},0),s=e.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];e.forEach(function(t,e,s){var a=1/s.length*this._fields.length*o,u=this,c=this.tokenStore.expand(t).reduce(function(e,r){var o=u.corpusTokens.indexOf(r),s=u.idf(r),c=1,l=new i.SortedSet;if(r!==t){var f=Math.max(3,r.length-t.length);c=1/Math.log(f)}o>-1&&n.insert(o,a*s*c);for(var d=u.tokenStore.get(r),h=Object.keys(d),p=h.length,v=0;v=this.offset_?"lock"!==this.el_.dataset.mdState&&(this.el_.dataset.mdState="lock"):"lock"===this.el_.dataset.mdState&&(this.el_.dataset.mdState="")}},{key:"reset",value:function(){this.el_.dataset.mdState="",this.el_.style.height="",this.height_=0}}]),t}();e["default"]=o,t.exports=e["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var o=n(87),i=r(o),s=n(91),a=r(s);e["default"]={Adapter:i["default"],Repository:a["default"]},t.exports=e["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}Object.defineProperty(e,"__esModule",{value:!0});var o=n(88),i=r(o);e["default"]={GitHub:i["default"]},t.exports=e["default"]},function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}function i(t,e){if(!t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!e||"object"!=typeof e&&"function"!=typeof e?t:e}function s(t,e){if("function"!=typeof e&&null!==e)throw new TypeError("Super expression must either be null or a function, not "+typeof e);t.prototype=Object.create(e&&e.prototype,{constructor:{value:t,enumerable:!1,writable:!0,configurable:!0}}),e&&(Object.setPrototypeOf?Object.setPrototypeOf(t,e):t.__proto__=e)}Object.defineProperty(e,"__esModule",{value:!0});var a=function(){function t(t,e){for(var n=0;n1e4?(t/1e3).toFixed(0)+"k":t>1e3?(t/1e3).toFixed(1)+"k":t}},{key:"hash_",value:function(t){var e=0;if(0===t.length)return e;for(var n=0,r=t.length;n1){if(i=t({path:"/"},r.defaults,i),"number"==typeof i.expires){var a=new Date;a.setMilliseconds(a.getMilliseconds()+864e5*i.expires),i.expires=a}try{s=JSON.stringify(o),/^[\{\[]/.test(s)&&(o=s)}catch(u){}return o=n.write?n.write(o,e):encodeURIComponent(String(o)).replace(/%(23|24|26|2B|3A|3C|3E|3D|2F|3F|40|5B|5D|5E|60|7B|7D|7C)/g,decodeURIComponent),e=encodeURIComponent(String(e)),e=e.replace(/%(23|24|26|2B|5E|60|7C)/g,decodeURIComponent),e=e.replace(/[\(\)]/g,escape),document.cookie=[e,"=",o,i.expires?"; expires="+i.expires.toUTCString():"",i.path?"; path="+i.path:"",i.domain?"; domain="+i.domain:"",i.secure?"; secure":""].join("")}e||(s={});for(var c=document.cookie?document.cookie.split("; "):[],l=/(%[0-9A-Z]{2})+/g,f=0;f=0,n=navigator.userAgent.indexOf("Android")>0&&!e,o=/iP(ad|hone|od)/.test(navigator.userAgent)&&!e,i=o&&/OS 4_\d(_\d)?/.test(navigator.userAgent),r=o&&/OS [6-7]_\d/.test(navigator.userAgent),s=navigator.userAgent.indexOf("BB10")>0;t.prototype.needsClick=function(t){switch(t.nodeName.toLowerCase()){case"button":case"select":case"textarea":if(t.disabled)return!0;break;case"input":if(o&&"file"===t.type||t.disabled)return!0;break;case"label":case"iframe":case"video":return!0}return/\bneedsclick\b/.test(t.className)},t.prototype.needsFocus=function(t){switch(t.nodeName.toLowerCase()){case"textarea":return!0;case"select":return!n;case"input":switch(t.type){case"button":case"checkbox":case"file":case"image":case"radio":case"submit":return!1}return!t.disabled&&!t.readOnly;default:return/\bneedsfocus\b/.test(t.className)}},t.prototype.sendClick=function(t,e){var n,o;document.activeElement&&document.activeElement!==t&&document.activeElement.blur(),o=e.changedTouches[0],n=document.createEvent("MouseEvents"),n.initMouseEvent(this.determineEventType(t),!0,!0,window,1,o.screenX,o.screenY,o.clientX,o.clientY,!1,!1,!1,!1,0,null),n.forwardedTouchEvent=!0,t.dispatchEvent(n)},t.prototype.determineEventType=function(t){return n&&"select"===t.tagName.toLowerCase()?"mousedown":"click"},t.prototype.focus=function(t){var e;o&&t.setSelectionRange&&0!==t.type.indexOf("date")&&"time"!==t.type&&"month"!==t.type?(e=t.value.length,t.setSelectionRange(e,e)):t.focus()},t.prototype.updateScrollParent=function(t){var e,n;if(e=t.fastClickScrollParent,!e||!e.contains(t)){n=t;do{if(n.scrollHeight>n.offsetHeight){e=n,t.fastClickScrollParent=n;break}n=n.parentElement}while(n)}e&&(e.fastClickLastScrollTop=e.scrollTop)},t.prototype.getTargetElementFromEventTarget=function(t){return t.nodeType===Node.TEXT_NODE?t.parentNode:t},t.prototype.onTouchStart=function(t){var e,n,r;if(t.targetTouches.length>1)return!0;if(e=this.getTargetElementFromEventTarget(t.target),n=t.targetTouches[0],o){if(r=window.getSelection(),r.rangeCount&&!r.isCollapsed)return!0;if(!i){if(n.identifier&&n.identifier===this.lastTouchIdentifier)return t.preventDefault(),!1;this.lastTouchIdentifier=n.identifier,this.updateScrollParent(e)}}return this.trackingClick=!0,this.trackingClickStart=t.timeStamp,this.targetElement=e,this.touchStartX=n.pageX,this.touchStartY=n.pageY,t.timeStamp-this.lastClickTimen||Math.abs(e.pageY-this.touchStartY)>n},t.prototype.onTouchMove=function(t){return!this.trackingClick||((this.targetElement!==this.getTargetElementFromEventTarget(t.target)||this.touchHasMoved(t))&&(this.trackingClick=!1,this.targetElement=null),!0)},t.prototype.findControl=function(t){return void 0!==t.control?t.control:t.htmlFor?document.getElementById(t.htmlFor):t.querySelector("button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea")},t.prototype.onTouchEnd=function(t){var e,s,a,c,l,u=this.targetElement;if(!this.trackingClick)return!0;if(t.timeStamp-this.lastClickTimethis.tapTimeout)return!0;if(this.cancelNextClick=!1,this.lastClickTime=t.timeStamp,s=this.trackingClickStart,this.trackingClick=!1,this.trackingClickStart=0,r&&(l=t.changedTouches[0],u=document.elementFromPoint(l.pageX-window.pageXOffset,l.pageY-window.pageYOffset)||u,u.fastClickScrollParent=this.targetElement.fastClickScrollParent),a=u.tagName.toLowerCase(),"label"===a){if(e=this.findControl(u)){if(this.focus(u),n)return!1;u=e}}else if(this.needsFocus(u))return t.timeStamp-s>100||o&&window.top!==window&&"input"===a?(this.targetElement=null,!1):(this.focus(u),this.sendClick(u,t),o&&"select"===a||(this.targetElement=null,t.preventDefault()),!1);return!(!o||i||(c=u.fastClickScrollParent,!c||c.fastClickLastScrollTop===c.scrollTop))||(this.needsClick(u)||(t.preventDefault(),this.sendClick(u,t)),!1)},t.prototype.onTouchCancel=function(){this.trackingClick=!1,this.targetElement=null},t.prototype.onMouse=function(t){return!this.targetElement||(!!t.forwardedTouchEvent||(!t.cancelable||(!(!this.needsClick(this.targetElement)||this.cancelNextClick)||(t.stopImmediatePropagation?t.stopImmediatePropagation():t.propagationStopped=!0,t.stopPropagation(),t.preventDefault(),!1))))},t.prototype.onClick=function(t){var e;return this.trackingClick?(this.targetElement=null,this.trackingClick=!1,!0):"submit"===t.target.type&&0===t.detail||(e=this.onMouse(t),e||(this.targetElement=null),e)},t.prototype.destroy=function(){var t=this.layer;n&&(t.removeEventListener("mouseover",this.onMouse,!0),t.removeEventListener("mousedown",this.onMouse,!0),t.removeEventListener("mouseup",this.onMouse,!0)),t.removeEventListener("click",this.onClick,!0),t.removeEventListener("touchstart",this.onTouchStart,!1),t.removeEventListener("touchmove",this.onTouchMove,!1),t.removeEventListener("touchend",this.onTouchEnd,!1),t.removeEventListener("touchcancel",this.onTouchCancel,!1)},t.notNeeded=function(t){var e,o,i,r;if("undefined"==typeof window.ontouchstart)return!0;if(o=+(/Chrome\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1]){if(!n)return!0;if(e=document.querySelector("meta[name=viewport]")){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(o>31&&document.documentElement.scrollWidth<=window.outerWidth)return!0}}if(s&&(i=navigator.userAgent.match(/Version\/([0-9]*)\.([0-9]*)/),i[1]>=10&&i[2]>=3&&(e=document.querySelector("meta[name=viewport]")))){if(e.content.indexOf("user-scalable=no")!==-1)return!0;if(document.documentElement.scrollWidth<=window.outerWidth)return!0}return"none"===t.style.msTouchAction||"manipulation"===t.style.touchAction||(r=+(/Firefox\/([0-9]+)/.exec(navigator.userAgent)||[,0])[1],!!(r>=27&&(e=document.querySelector("meta[name=viewport]"),e&&(e.content.indexOf("user-scalable=no")!==-1||document.documentElement.scrollWidth<=window.outerWidth)))||("none"===t.style.touchAction||"manipulation"===t.style.touchAction))},t.attach=function(e,n){return new t(e,n)},"function"==typeof define&&"object"==typeof define.amd&&define.amd?define(function(){return t}):"undefined"!=typeof module&&module.exports?(module.exports=t.attach,module.exports.FastClick=t):window.FastClick=t}(),function(){var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.6.0",t.utils={},t.utils.warn=function(t){return function(e){t.console&&console.warn&&console.warn(e)}}(this),t.utils.asString=function(t){return void 0===t||null===t?"":t.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=t;if("function"!=typeof e)throw new TypeError("last argument must be a function");n.forEach(function(t){this.hasHandler(t)||(this.events[t]=[]),this.events[t].push(e)},this)},t.EventEmitter.prototype.removeListener=function(t,e){if(this.hasHandler(t)){var n=this.events[t].indexOf(e);this.events[t].splice(n,1),this.events[t].length||delete this.events[t]}},t.EventEmitter.prototype.emit=function(t){if(this.hasHandler(t)){var e=Array.prototype.slice.call(arguments,1);this.events[t].forEach(function(t){t.apply(void 0,e)})}},t.EventEmitter.prototype.hasHandler=function(t){return t in this.events},t.tokenizer=function(e){return arguments.length&&null!=e&&void 0!=e?Array.isArray(e)?e.map(function(e){return t.utils.asString(e).toLowerCase()}):e.toString().trim().toLowerCase().split(t.tokenizer.seperator):[]},t.tokenizer.seperator=/[\s\-]+/,t.Pipeline=function(){this._stack=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in this.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[e.label]=e},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var o=t.Pipeline.registeredFunctions[e];if(!o)throw new Error("Cannot load un-registered function: "+e);n.add(o)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._stack.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(o==-1)throw new Error("Cannot find existingFn");o+=1,this._stack.splice(o,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var o=this._stack.indexOf(e);if(o==-1)throw new Error("Cannot find existingFn");this._stack.splice(o,0,n)},t.Pipeline.prototype.remove=function(t){var e=this._stack.indexOf(t);e!=-1&&this._stack.splice(e,1)},t.Pipeline.prototype.run=function(t){for(var e=[],n=t.length,o=this._stack.length,i=0;in.idx?n=n.next:(o+=e.val*n.val,e=e.next,n=n.next);return o},t.Vector.prototype.similarity=function(t){return this.dot(t)/(this.magnitude()*t.magnitude())},t.SortedSet=function(){this.length=0,this.elements=[]},t.SortedSet.load=function(t){var e=new this;return e.elements=t,e.length=t.length,e},t.SortedSet.prototype.add=function(){var t,e;for(t=0;t1;){if(r===t)return i;rt&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i]}return r===t?i:-1},t.SortedSet.prototype.locationFor=function(t){for(var e=0,n=this.elements.length,o=n-e,i=e+Math.floor(o/2),r=this.elements[i];o>1;)rt&&(n=i),o=n-e,i=e+Math.floor(o/2),r=this.elements[i];return r>t?i:rr-1||i>s-1)break;a[o]!==c[i]?a[o]c[i]&&i++:(n.add(a[o]),o++,i++)}return n},t.SortedSet.prototype.clone=function(){var e=new t.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},t.SortedSet.prototype.union=function(t){var e,n,o;return this.length>=t.length?(e=this,n=t):(e=t,n=this),o=e.clone(),o.add.apply(o,n.toArray()),o},t.SortedSet.prototype.toJSON=function(){return this.toArray()},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.Store,this.tokenStore=new t.TokenStore,this.corpusTokens=new t.SortedSet,this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var t=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,t)},t.Index.prototype.off=function(t,e){return this.eventEmitter.removeListener(t,e)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;return n._fields=e.fields,n._ref=e.ref,n.documentStore=t.Store.load(e.documentStore),n.tokenStore=t.TokenStore.load(e.tokenStore),n.corpusTokens=t.SortedSet.load(e.corpusTokens),n.pipeline=t.Pipeline.load(e.pipeline),n},t.Index.prototype.field=function(t,e){var e=e||{},n={name:t,boost:e.boost||1};return this._fields.push(n),this},t.Index.prototype.ref=function(t){return this._ref=t,this},t.Index.prototype.add=function(e,n){var o={},i=new t.SortedSet,r=e[this._ref],n=void 0===n||n;this._fields.forEach(function(n){var r=this.pipeline.run(t.tokenizer(e[n.name]));o[n.name]=r,t.SortedSet.prototype.add.apply(i,r)},this),this.documentStore.set(r,i),t.SortedSet.prototype.add.apply(this.corpusTokens,i.toArray());for(var s=0;s0&&(o=1+Math.log(this.documentStore.length/n)),this._idfCache[e]=o},t.Index.prototype.search=function(e){var n=this.pipeline.run(t.tokenizer(e)),o=new t.Vector,i=[],r=this._fields.reduce(function(t,e){return t+e.boost},0),s=n.some(function(t){return this.tokenStore.has(t)},this);if(!s)return[];n.forEach(function(e,n,s){var a=1/s.length*this._fields.length*r,c=this,l=this.tokenStore.expand(e).reduce(function(n,i){var r=c.corpusTokens.indexOf(i),s=c.idf(i),l=1,u=new t.SortedSet;if(i!==e){var d=Math.max(3,i.length-e.length);l=1/Math.log(d)}r>-1&&o.insert(r,a*s*l);for(var h=c.tokenStore.get(i),f=Object.keys(h),p=f.length,m=0;mt){for(;" "!=this[t]&&--t>0;);return this.substring(0,t)+"…"}return this},HTMLElement.prototype.wrap=function(t){t.length||(t=[t]);for(var e=t.length-1;e>=0;e--){var n=e>0?this.cloneNode(!0):this,o=t[e],i=o.parentNode,r=o.nextSibling;n.appendChild(o),r?i.insertBefore(n,r):i.appendChild(n)}},document.addEventListener("DOMContentLoaded",function(){"use strict";Modernizr.addTest("ios",function(){return!!navigator.userAgent.match(/(iPad|iPhone|iPod)/g)}),Modernizr.addTest("standalone",function(){return!!navigator.standalone}),FastClick.attach(document.body);var t=document.getElementById("toggle-search"),e=(document.getElementById("reset-search"),document.querySelector(".drawer")),n=document.querySelectorAll(".anchor"),o=document.querySelector(".search .field"),i=document.querySelector(".query"),r=document.querySelector(".results .meta");Array.prototype.forEach.call(n,function(t){t.querySelector("a").addEventListener("click",function(){document.getElementById("toggle-drawer").checked=!1,document.body.classList.remove("toggle-drawer")})});var s=window.pageYOffset,a=function(){var t=window.pageYOffset+window.innerHeight,n=Math.max(0,window.innerHeight-e.offsetHeight);t>document.body.clientHeight-(96-n)?"absolute"!=e.style.position&&(e.style.position="absolute",e.style.top=null,e.style.bottom=0):e.offsetHeighte.offsetTop+e.offsetHeight?(e.style.position="fixed",e.style.top=null,e.style.bottom="-96px"):window.pageYOffsets?e.style.top&&(e.style.position="absolute",e.style.top=Math.max(0,s)+"px",e.style.bottom=null):e.style.bottom&&(e.style.position="absolute",e.style.top=t-e.offsetHeight+"px",e.style.bottom=null),s=Math.max(0,window.pageYOffset)},c=function(){var t=document.querySelector(".main");window.removeEventListener("scroll",a),matchMedia("only screen and (max-width: 959px)").matches?(e.style.position=null,e.style.top=null,e.style.bottom=null):e.offsetHeight+961e4?n=(n/1e3).toFixed(0)+"k":n>1e3&&(n=(n/1e3).toFixed(1)+"k");var o=document.querySelector(".repo-stars .count");o.innerHTML=n},function(t,e){console.error(t,e.status)})}),"standalone"in window.navigator&&window.navigator.standalone){var node,remotes=!1;document.addEventListener("click",function(t){for(node=t.target;"A"!==node.nodeName&&"HTML"!==node.nodeName;)node=node.parentNode;"href"in node&&node.href.indexOf("http")!==-1&&(node.href.indexOf(document.location.host)!==-1||remotes)&&(t.preventDefault(),document.location.href=node.href)},!1)} \ No newline at end of file diff --git a/material/assets/javascripts/modernizr-2216498cab.js b/material/assets/javascripts/modernizr-2216498cab.js deleted file mode 100644 index 6fde6bf91..000000000 --- a/material/assets/javascripts/modernizr-2216498cab.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t,n){function r(e,t){return typeof e===t}function i(){var e,t,n,i,o,a,s;for(var l in x)if(x.hasOwnProperty(l)){if(e=[],t=x[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=C.elements;return"string"==typeof e?e.split(" "):e}function i(e,t){var n=C.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),C.elements=n+" "+e,u(t)}function o(e){var t=w[e[S]];return t||(t={},b++,e[S]=b,w[b]=t),t}function a(e,n,r){if(n||(n=t),g)return n.createElement(e);r||(r=o(n));var i;return i=r.cache[e]?r.cache[e].cloneNode():E.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!i.canHaveChildren||x.test(e)||i.tagUrn?i:r.frag.appendChild(i)}function s(e,n){if(e||(e=t),g)return e.createDocumentFragment();n=n||o(e);for(var i=n.frag.cloneNode(),a=0,s=r(),l=s.length;a+~])("+r().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),a="$1"+N+"\\:$2";i--;)t=n[i]=n[i].split("}"),t[t.length-1]=t[t.length-1].replace(o,a),n[i]=t.join("}");return n.join("{")}function p(e){for(var t=e.length;t--;)e[t].removeNode()}function m(e){function t(){clearTimeout(a._removeSheetTimer),r&&r.removeNode(!0),r=null}var r,i,a=o(e),s=e.namespaces,l=e.parentWindow;return!_||e.printShived?e:("undefined"==typeof s[N]&&s.add(N),l.attachEvent("onbeforeprint",function(){t();for(var o,a,s,l=e.styleSheets,u=[],f=l.length,p=Array(f);f--;)p[f]=l[f];for(;s=p.pop();)if(!s.disabled&&T.test(s.media)){try{o=s.imports,a=o.length}catch(m){a=0}for(f=0;f",h="hidden"in e,g=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){h=!0,g=!0}}();var C={elements:y.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:v,shivCSS:y.shivCSS!==!1,supportsUnknownElements:g,shivMethods:y.shivMethods!==!1,type:"default",shivDocument:u,createElement:a,createDocumentFragment:s,addElements:i};e.html5=C,u(t);var T=/^$|\b(?:all|print)\b/,N="html5shiv",_=!g&&function(){var n=t.documentElement;return!("undefined"==typeof t.namespaces||"undefined"==typeof t.parentWindow||"undefined"==typeof n.applyElement||"undefined"==typeof n.removeNode||"undefined"==typeof e.attachEvent)}();C.type+=" print",C.shivPrint=m,m(t),"object"==typeof module&&module.exports&&(module.exports=C)}("undefined"!=typeof e?e:this,t);var N={elem:u("modernizr")};S._q.push(function(){delete N.elem});var _={style:N.elem.style};S._q.unshift(function(){delete _.style});var z=(E.testProp=function(e,t,r){return h([e],n,t,r)},function(){function e(e,t){var i;return!!e&&(t&&"string"!=typeof t||(t=u(t||"div")),e="on"+e,i=e in t,!i&&r&&(t.setAttribute||(t=u("div")),t.setAttribute(e,""),i="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),i)}var r=!("onblur"in t.documentElement);return e}());E.hasEvent=z,S.addTest("inputsearchevent",z("search"));var k=E.testStyles=f,$=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,i=t<533&&e.match(/android/gi);return n||i||r}();$?S.addTest("fontface",!1):k('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),i=r.sheet||r.styleSheet,o=i?i.cssRules&&i.cssRules[0]?i.cssRules[0].cssText:i.cssText||"":"",a=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);S.addTest("fontface",a)});var j="Moz O ms Webkit",P=E._config.usePrefixes?j.split(" "):[];E._cssomPrefixes=P;var A=E._config.usePrefixes?j.toLowerCase().split(" "):[];E._domPrefixes=A,E.testAllProps=v,E.testAllProps=y;var R="CSS"in e&&"supports"in e.CSS,F="supportsCSS"in e;S.addTest("supports",R||F),S.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=S._config.usePrefixes;if(e&&(!t||"webkitPerspective"in C.style)){var n,r="#modernizr{width:0;height:0}";S.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",k(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),S.addTest("json","JSON"in e&&"parse"in JSON&&"stringify"in JSON),S.addTest("checked",function(){return k("#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}",function(e){var t=u("input");return t.setAttribute("type","checkbox"),t.setAttribute("checked","checked"),e.appendChild(t),20===t.offsetLeft})}),S.addTest("target",function(){var t=e.document;if(!("querySelectorAll"in t))return!1;try{return t.querySelectorAll(":target"),!0}catch(n){return!1}}),S.addTest("contains",r(String.prototype.contains,"function")),i(),o(w),delete E.addTest,delete E.addAsyncTest;for(var M=0;M #mq-test-1 { width: 42px; }',r.insertBefore(o,i),n=42===a.offsetWidth,r.removeChild(o),{matches:n,media:e}}}(e.document)}(this),function(e){"use strict";function t(){E(!0)}var n={};e.respond=n,n.update=function(){};var r=[],i=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}(),o=function(e,t){var n=i();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))};if(n.ajax=o,n.queue=r,n.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},n.mediaQueriesSupported=e.matchMedia&&null!==e.matchMedia("only all")&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,l,u=e.document,c=u.documentElement,f=[],d=[],p=[],m={},h=30,g=u.getElementsByTagName("head")[0]||c,v=u.getElementsByTagName("base")[0],y=g.getElementsByTagName("link"),x=function(){var e,t=u.createElement("div"),n=u.body,r=c.style.fontSize,i=n&&n.style.fontSize,o=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||(n=o=u.createElement("body"),n.style.background="none"),c.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),o&&c.insertBefore(n,c.firstChild),e=t.offsetWidth,o?c.removeChild(n):n.removeChild(t),c.style.fontSize=r,i&&(n.style.fontSize=i),e=l=parseFloat(e)},E=function(t){var n="clientWidth",r=c[n],i="CSS1Compat"===u.compatMode&&r||u.body[n]||r,o={},m=y[y.length-1],v=(new Date).getTime();if(t&&a&&v-a-1?l||x():1)),C&&(C=parseFloat(C)*(C.indexOf(_)>-1?l||x():1)),b.hasquery&&(T&&N||!(T||i>=w)||!(N||i<=C))||(o[b.media]||(o[b.media]=[]),o[b.media].push(d[b.rules]))}for(var z in p)p.hasOwnProperty(z)&&p[z]&&p[z].parentNode===g&&g.removeChild(p[z]);p.length=0;for(var k in o)if(o.hasOwnProperty(k)){var $=u.createElement("style"),j=o[k].join("\n");$.type="text/css",$.media=k,g.insertBefore($,m.nextSibling),$.styleSheet?$.styleSheet.cssText=j:$.appendChild(u.createTextNode(j)),p.push($)}},S=function(e,t,r){var i=e.replace(n.regex.keyframes,"").match(n.regex.media),o=i&&i.length||0;t=t.substring(0,t.lastIndexOf("/"));var a=function(e){return e.replace(n.regex.urls,"$1"+t+"$2$3")},s=!o&&r;t.length&&(t+="/"),s&&(o=1);for(var l=0;l-1,minw:c.match(n.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:c.match(n.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},b=function(){if(r.length){var t=r.shift();o(t.href,function(n){S(n,t.href,t.media),m[t.href]=!0,e.setTimeout(function(){b()},0)})}},w=function(){for(var t=0;t=9,r=t<533&&e.match(/android/gi);return n||r||s}();E?_.addTest("fontface",!1):z('@font-face {font-family:"font";src:url("https://")}',function(e,n){var s=t.getElementById("smodernizr"),r=s.sheet||s.styleSheet,o=r?r.cssRules&&r.cssRules[0]?r.cssRules[0].cssText:r.cssText||"":"",i=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);_.addTest("fontface",i)});var j="Moz O ms Webkit",k=x._config.usePrefixes?j.split(" "):[];x._cssomPrefixes=k;var N={elem:a("modernizr")};_._q.push(function(){delete N.elem});var A={style:N.elem.style};_._q.unshift(function(){delete A.style});var R=x._config.usePrefixes?j.toLowerCase().split(" "):[];x._domPrefixes=R,x.testAllProps=v,x.testAllProps=y;var q="CSS"in e&&"supports"in e.CSS,L="supportsCSS"in e;_.addTest("supports",q||L),_.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=_._config.usePrefixes;if(e&&(!t||"webkitPerspective"in b.style)){var n,s="#modernizr{width:0;height:0}";_.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",z(s+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),r(),o(S),delete x.addTest,delete x.addAsyncTest;for(var O=0;O<_._q.length;O++)_._q[O]();e.Modernizr=_}(window,document); \ No newline at end of file diff --git a/material/assets/javascripts/modernizr.js b/material/assets/javascripts/modernizr.js deleted file mode 100644 index 6fde6bf91..000000000 --- a/material/assets/javascripts/modernizr.js +++ /dev/null @@ -1 +0,0 @@ -!function(e,t,n){function r(e,t){return typeof e===t}function i(){var e,t,n,i,o,a,s;for(var l in x)if(x.hasOwnProperty(l)){if(e=[],t=x[l],t.name&&(e.push(t.name.toLowerCase()),t.options&&t.options.aliases&&t.options.aliases.length))for(n=0;n",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=C.elements;return"string"==typeof e?e.split(" "):e}function i(e,t){var n=C.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),C.elements=n+" "+e,u(t)}function o(e){var t=w[e[S]];return t||(t={},b++,e[S]=b,w[b]=t),t}function a(e,n,r){if(n||(n=t),g)return n.createElement(e);r||(r=o(n));var i;return i=r.cache[e]?r.cache[e].cloneNode():E.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!i.canHaveChildren||x.test(e)||i.tagUrn?i:r.frag.appendChild(i)}function s(e,n){if(e||(e=t),g)return e.createDocumentFragment();n=n||o(e);for(var i=n.frag.cloneNode(),a=0,s=r(),l=s.length;a+~])("+r().join("|")+")(?=[[\\s,>+~#.:]|$)","gi"),a="$1"+N+"\\:$2";i--;)t=n[i]=n[i].split("}"),t[t.length-1]=t[t.length-1].replace(o,a),n[i]=t.join("}");return n.join("{")}function p(e){for(var t=e.length;t--;)e[t].removeNode()}function m(e){function t(){clearTimeout(a._removeSheetTimer),r&&r.removeNode(!0),r=null}var r,i,a=o(e),s=e.namespaces,l=e.parentWindow;return!_||e.printShived?e:("undefined"==typeof s[N]&&s.add(N),l.attachEvent("onbeforeprint",function(){t();for(var o,a,s,l=e.styleSheets,u=[],f=l.length,p=Array(f);f--;)p[f]=l[f];for(;s=p.pop();)if(!s.disabled&&T.test(s.media)){try{o=s.imports,a=o.length}catch(m){a=0}for(f=0;f",h="hidden"in e,g=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){h=!0,g=!0}}();var C={elements:y.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:v,shivCSS:y.shivCSS!==!1,supportsUnknownElements:g,shivMethods:y.shivMethods!==!1,type:"default",shivDocument:u,createElement:a,createDocumentFragment:s,addElements:i};e.html5=C,u(t);var T=/^$|\b(?:all|print)\b/,N="html5shiv",_=!g&&function(){var n=t.documentElement;return!("undefined"==typeof t.namespaces||"undefined"==typeof t.parentWindow||"undefined"==typeof n.applyElement||"undefined"==typeof n.removeNode||"undefined"==typeof e.attachEvent)}();C.type+=" print",C.shivPrint=m,m(t),"object"==typeof module&&module.exports&&(module.exports=C)}("undefined"!=typeof e?e:this,t);var N={elem:u("modernizr")};S._q.push(function(){delete N.elem});var _={style:N.elem.style};S._q.unshift(function(){delete _.style});var z=(E.testProp=function(e,t,r){return h([e],n,t,r)},function(){function e(e,t){var i;return!!e&&(t&&"string"!=typeof t||(t=u(t||"div")),e="on"+e,i=e in t,!i&&r&&(t.setAttribute||(t=u("div")),t.setAttribute(e,""),i="function"==typeof t[e],t[e]!==n&&(t[e]=n),t.removeAttribute(e)),i)}var r=!("onblur"in t.documentElement);return e}());E.hasEvent=z,S.addTest("inputsearchevent",z("search"));var k=E.testStyles=f,$=function(){var e=navigator.userAgent,t=e.match(/applewebkit\/([0-9]+)/gi)&&parseFloat(RegExp.$1),n=e.match(/w(eb)?osbrowser/gi),r=e.match(/windows phone/gi)&&e.match(/iemobile\/([0-9])+/gi)&&parseFloat(RegExp.$1)>=9,i=t<533&&e.match(/android/gi);return n||i||r}();$?S.addTest("fontface",!1):k('@font-face {font-family:"font";src:url("https://")}',function(e,n){var r=t.getElementById("smodernizr"),i=r.sheet||r.styleSheet,o=i?i.cssRules&&i.cssRules[0]?i.cssRules[0].cssText:i.cssText||"":"",a=/src/i.test(o)&&0===o.indexOf(n.split(" ")[0]);S.addTest("fontface",a)});var j="Moz O ms Webkit",P=E._config.usePrefixes?j.split(" "):[];E._cssomPrefixes=P;var A=E._config.usePrefixes?j.toLowerCase().split(" "):[];E._domPrefixes=A,E.testAllProps=v,E.testAllProps=y;var R="CSS"in e&&"supports"in e.CSS,F="supportsCSS"in e;S.addTest("supports",R||F),S.addTest("csstransforms3d",function(){var e=!!y("perspective","1px",!0),t=S._config.usePrefixes;if(e&&(!t||"webkitPerspective"in C.style)){var n,r="#modernizr{width:0;height:0}";S.supports?n="@supports (perspective: 1px)":(n="@media (transform-3d)",t&&(n+=",(-webkit-transform-3d)")),n+="{#modernizr{width:7px;height:18px;margin:0;padding:0;border:0}}",k(r+n,function(t){e=7===t.offsetWidth&&18===t.offsetHeight})}return e}),S.addTest("json","JSON"in e&&"parse"in JSON&&"stringify"in JSON),S.addTest("checked",function(){return k("#modernizr {position:absolute} #modernizr input {margin-left:10px} #modernizr :checked {margin-left:20px;display:block}",function(e){var t=u("input");return t.setAttribute("type","checkbox"),t.setAttribute("checked","checked"),e.appendChild(t),20===t.offsetLeft})}),S.addTest("target",function(){var t=e.document;if(!("querySelectorAll"in t))return!1;try{return t.querySelectorAll(":target"),!0}catch(n){return!1}}),S.addTest("contains",r(String.prototype.contains,"function")),i(),o(w),delete E.addTest,delete E.addAsyncTest;for(var M=0;M #mq-test-1 { width: 42px; }',r.insertBefore(o,i),n=42===a.offsetWidth,r.removeChild(o),{matches:n,media:e}}}(e.document)}(this),function(e){"use strict";function t(){E(!0)}var n={};e.respond=n,n.update=function(){};var r=[],i=function(){var t=!1;try{t=new e.XMLHttpRequest}catch(n){t=new e.ActiveXObject("Microsoft.XMLHTTP")}return function(){return t}}(),o=function(e,t){var n=i();n&&(n.open("GET",e,!0),n.onreadystatechange=function(){4!==n.readyState||200!==n.status&&304!==n.status||t(n.responseText)},4!==n.readyState&&n.send(null))};if(n.ajax=o,n.queue=r,n.regex={media:/@media[^\{]+\{([^\{\}]*\{[^\}\{]*\})+/gi,keyframes:/@(?:\-(?:o|moz|webkit)\-)?keyframes[^\{]+\{(?:[^\{\}]*\{[^\}\{]*\})+[^\}]*\}/gi,urls:/(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g,findStyles:/@media *([^\{]+)\{([\S\s]+?)$/,only:/(only\s+)?([a-zA-Z]+)\s?/,minw:/\([\s]*min\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/,maxw:/\([\s]*max\-width\s*:[\s]*([\s]*[0-9\.]+)(px|em)[\s]*\)/},n.mediaQueriesSupported=e.matchMedia&&null!==e.matchMedia("only all")&&e.matchMedia("only all").matches,!n.mediaQueriesSupported){var a,s,l,u=e.document,c=u.documentElement,f=[],d=[],p=[],m={},h=30,g=u.getElementsByTagName("head")[0]||c,v=u.getElementsByTagName("base")[0],y=g.getElementsByTagName("link"),x=function(){var e,t=u.createElement("div"),n=u.body,r=c.style.fontSize,i=n&&n.style.fontSize,o=!1;return t.style.cssText="position:absolute;font-size:1em;width:1em",n||(n=o=u.createElement("body"),n.style.background="none"),c.style.fontSize="100%",n.style.fontSize="100%",n.appendChild(t),o&&c.insertBefore(n,c.firstChild),e=t.offsetWidth,o?c.removeChild(n):n.removeChild(t),c.style.fontSize=r,i&&(n.style.fontSize=i),e=l=parseFloat(e)},E=function(t){var n="clientWidth",r=c[n],i="CSS1Compat"===u.compatMode&&r||u.body[n]||r,o={},m=y[y.length-1],v=(new Date).getTime();if(t&&a&&v-a-1?l||x():1)),C&&(C=parseFloat(C)*(C.indexOf(_)>-1?l||x():1)),b.hasquery&&(T&&N||!(T||i>=w)||!(N||i<=C))||(o[b.media]||(o[b.media]=[]),o[b.media].push(d[b.rules]))}for(var z in p)p.hasOwnProperty(z)&&p[z]&&p[z].parentNode===g&&g.removeChild(p[z]);p.length=0;for(var k in o)if(o.hasOwnProperty(k)){var $=u.createElement("style"),j=o[k].join("\n");$.type="text/css",$.media=k,g.insertBefore($,m.nextSibling),$.styleSheet?$.styleSheet.cssText=j:$.appendChild(u.createTextNode(j)),p.push($)}},S=function(e,t,r){var i=e.replace(n.regex.keyframes,"").match(n.regex.media),o=i&&i.length||0;t=t.substring(0,t.lastIndexOf("/"));var a=function(e){return e.replace(n.regex.urls,"$1"+t+"$2$3")},s=!o&&r;t.length&&(t+="/"),s&&(o=1);for(var l=0;l-1,minw:c.match(n.regex.minw)&&parseFloat(RegExp.$1)+(RegExp.$2||""),maxw:c.match(n.regex.maxw)&&parseFloat(RegExp.$1)+(RegExp.$2||"")})}E()},b=function(){if(r.length){var t=r.shift();o(t.href,function(n){S(n,t.href,t.media),m[t.href]=!0,e.setTimeout(function(){b()},0)})}},w=function(){for(var t=0;tli:before{content:"\e602";display:block;float:left;font-family:Icon;font-size:16px;width:1.2em;margin-left:-1.2em;vertical-align:-.1em}.article p>code{white-space:nowrap;padding:2px 4px}.article kbd{display:inline-block;padding:3px 5px;line-height:10px}.article hr{margin-top:1.5em}.article img{max-width:100%}.article pre{padding:16px;margin:1.5em -16px 0;line-height:1.5em;overflow:auto;-webkit-overflow-scrolling:touch}.article table{margin:3em 0 1.5em;font-size:13px;overflow:hidden}.no-js .article table{display:inline-block;max-width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.article table th{min-width:100px;font-size:12px;text-align:left}.article table td,.article table th{padding:12px 16px;vertical-align:top}.article blockquote{padding-left:16px}.article .data{margin:1.5em -16px;padding:1.5em 0;overflow:auto;-webkit-overflow-scrolling:touch;text-align:center}.article .data table{display:inline-block;margin:0 16px;text-align:left}.footer{position:absolute;bottom:0;left:0;right:0;padding:0 4px}.copyright{margin:1.5em 0}.pagination{max-width:1184px;height:92px;padding:4px 0;margin-left:auto;margin-right:auto;overflow:hidden}.pagination a{display:block;height:100%}.pagination .next,.pagination .previous{position:relative;float:left;height:100%}.pagination .previous{width:25%}.pagination .previous .direction,.pagination .previous .stretch{display:none}.pagination .next{width:75%;text-align:right}.pagination .page{display:table;position:absolute;bottom:4px}.pagination .direction{display:block;position:absolute;bottom:40px;width:100%;font-size:15px;line-height:20px;padding:0 52px}.pagination .stretch{padding:0 4px}.pagination .stretch .title{font-size:18px;padding:11px 0 13px}.admonition{margin:20px -16px 0;padding:20px 16px}.admonition>:first-child{margin-top:0}.admonition .admonition-title{font-size:20px}.admonition .admonition-title:before{content:"\e611";display:block;float:left;font-family:Icon;font-size:24px;vertical-align:-.1em;margin-right:5px}.admonition.warning .admonition-title:before{content:"\e610"}.article h3{font-weight:700}.article h4{font-weight:400;font-style:italic}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{font-weight:400;font-style:normal}.bar{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1)}#toggle-search:checked~.header .bar,.toggle-search .bar{-webkit-transform:translate3d(0,-56px,0);transform:translate3d(0,-56px,0)}.bar.search .button-reset{-webkit-transform:scale(.5);transform:scale(.5);-webkit-transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);opacity:0}.bar.search.non-empty .button-reset{-webkit-transform:scale(1);transform:scale(1);opacity:1}.results{-webkit-transition:opacity .3s .1s,width 0s .4s,height 0s .4s;transition:opacity .3s .1s,width 0s .4s,height 0s .4s}#toggle-search:checked~.main .results,.toggle-search .results{-webkit-transition:opacity .4s,width 0s,height 0s;transition:opacity .4s,width 0s,height 0s}.results .list a{-webkit-transition:background .25s;transition:background .25s}.no-csstransforms3d .bar.default{display:table}.no-csstransforms3d .bar.search{display:none;margin-top:0}.no-csstransforms3d #toggle-search:checked~.header .bar.default,.no-csstransforms3d .toggle-search .bar.default{display:none}.no-csstransforms3d #toggle-search:checked~.header .bar.search,.no-csstransforms3d .toggle-search .bar.search{display:table}.bar.search{opacity:0}.bar.search .query{background:transparent;color:rgba(0,0,0,.87)}.bar.search .query::-webkit-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-moz-placeholder,.bar.search .query::-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-ms-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .button .icon:active{background:rgba(0,0,0,.12)}.results{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);background:#fff;color:rgba(0,0,0,.87);opacity:0}#toggle-search:checked~.main .results,.toggle-search .results{opacity:1}.results .meta{background:#e84e40;color:#fff}.results .list a{border-bottom:1px solid rgba(0,0,0,.12)}.results .list a:last-child{border-bottom:none}.results .list a:active{background:rgba(0,0,0,.12)}.result span{color:rgba(0,0,0,.54)}#toggle-search:checked~.header,.toggle-search .header{background:#fff;color:rgba(0,0,0,.54)}#toggle-search:checked~.header:before,.toggle-search .header:before{background:rgba(0,0,0,.54)}#toggle-search:checked~.header .bar.default,.toggle-search .header .bar.default{opacity:0}#toggle-search:checked~.header .bar.search,.toggle-search .header .bar.search{opacity:1}.bar.search{margin-top:8px}.bar.search .query{font-size:18px;padding:13px 0;margin:0;width:100%;height:48px}.bar.search .query::-ms-clear{display:none}.results{position:fixed;top:0;left:0;width:0;height:100%;z-index:2;overflow-y:scroll;-webkit-overflow-scrolling:touch}.results .scrollable{top:56px}#toggle-search:checked~.main .results,.toggle-search .results{width:100%;overflow-y:visible}.results .meta{font-weight:700}.results .meta strong{display:block;font-size:11px;max-width:1200px;margin-left:auto;margin-right:auto;padding:16px}.results .list a{display:block}.result{max-width:1200px;margin-left:auto;margin-right:auto;padding:12px 16px 16px}.result h1{line-height:24px}.result h1,.result span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.result span{font-size:12px}.no-csstransforms3d .results{display:none}.no-csstransforms3d #toggle-search:checked~.main .results,.no-csstransforms3d .toggle-search .results{display:block;overflow:auto}.meta{text-transform:uppercase;font-weight:700}@media only screen and (min-width:960px){.backdrop{background:#f2f2f2}.backdrop-paper:after{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.button-menu{display:none}.drawer{float:left;height:auto;margin-bottom:96px;padding-top:80px}.drawer,.drawer .scrollable{position:static}.article{margin-left:262px}.footer{z-index:5}.copyright{margin-bottom:64px}.results{height:auto;top:64px}.results .scrollable{position:static;max-height:413px}}@media only screen and (max-width:959px){#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{width:100%;height:100%}.drawer{-webkit-transform:translate3d(-262px,0,0);transform:translate3d(-262px,0,0);-webkit-transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),-webkit-transform .25s cubic-bezier(.4,0,.2,1)}.no-csstransforms3d .drawer{display:none}.drawer{background:#fff}.project{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}.drawer{position:fixed;z-index:5}#toggle-search:checked~.main .results,.drawer,.toggle-search .results{height:100%}}@media only screen and (min-width:720px){.header{height:64px;padding:8px}.header .stretch{padding:0 16px}.header .stretch .title{font-size:20px;padding:12px 0}.project .name{margin:26px 0 0 5px}.article .wrapper{padding:128px 24px 96px}.article .data{margin:1.5em -24px}.article .data table{margin:0 24px}.article h2{padding-top:100px;margin-top:-64px}.ios.standalone .article h2{padding-top:28px;margin-top:8px}.article h3,.article h4{padding-top:84px;margin-top:-64px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article pre{padding:1.5em 24px;margin:1.5em -24px 0}.footer{padding:0 8px}.pagination{height:96px;padding:8px 0}.pagination .direction{padding:0 56px;bottom:40px}.pagination .stretch{padding:0 8px}.admonition{margin:20px -24px 0;padding:20px 24px}.bar.search .query{font-size:20px;padding:12px 0}.results .scrollable{top:64px}.results .meta strong{padding:16px 24px}.result{padding:16px 24px 20px}}@media only screen and (min-width:1200px){.header{width:100%}.drawer .scrollable .wrapper hr{width:48px}}@media only screen and (orientation:portrait){.ios.standalone .header{height:76px;padding-top:24px}.ios.standalone .header:before{content:" ";position:absolute;top:0;left:0;z-index:4;width:100%;height:20px}.ios.standalone .drawer .scrollable{top:124px}.ios.standalone .project{padding-top:20px}.ios.standalone .project:before{content:" ";position:absolute;top:0;left:0;z-index:4;width:100%;height:20px}.ios.standalone .article{position:absolute;top:76px;right:0;bottom:0;left:0}.ios.standalone .results .scrollable{top:76px}}@media only screen and (orientation:portrait) and (min-width:720px){.ios.standalone .header{height:84px;padding-top:28px}.ios.standalone .results .scrollable{top:84px}}@media only screen and (max-width:719px){.bar .path{display:none}}@media only screen and (max-width:479px){.button-github,.button-twitter{display:none}}@media only screen and (min-width:720px) and (max-width:959px){.header .stretch{padding:0 24px}}@media only screen and (min-width:480px){.pagination .next,.pagination .previous{width:50%}.pagination .previous .direction{display:block}.pagination .previous .stretch{display:table}}@media print{.drawer,.footer,.header,.headerlink{display:none}.article .wrapper{padding-top:0}.article pre,.article pre *{color:rgba(0,0,0,.87)!important}.article pre{border:1px solid rgba(0,0,0,.12)}.article table{border-radius:none;box-shadow:none}.article table th{color:#e84e40}} \ No newline at end of file diff --git a/material/assets/stylesheets/application-ff220fd69d.css b/material/assets/stylesheets/application-ff220fd69d.css new file mode 100644 index 000000000..cfcc40e98 --- /dev/null +++ b/material/assets/stylesheets/application-ff220fd69d.css @@ -0,0 +1 @@ +html{box-sizing:border-box}*,:after,:before{box-sizing:inherit}html{-webkit-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none}body{margin:0}hr{overflow:visible;box-sizing:content-box}a{-webkit-text-decoration-skip:objects}a,button,input,label{-webkit-tap-highlight-color:transparent}a{color:inherit;text-decoration:none}a:active,a:hover{outline-width:0}small,sub,sup{font-size:80%}sub,sup{position:relative;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}table{border-collapse:collapse;border-spacing:0}td,th{font-weight:400;vertical-align:top}button{padding:0;background:transparent;font-size:inherit}button,input{border:0;outline:0}.admonition:before,.md-icon,.md-nav__icon,.md-nav__link:after,.md-nav__title:before,.md-typeset .critic.comment:before,.md-typeset .footnote-backref,.md-typeset .task-list-control .task-list-indicator:before{font-family:Material Icons;font-style:normal;font-variant:normal;font-weight:400;line-height:1;text-transform:none;white-space:nowrap;speak:none;word-wrap:normal;direction:ltr}.md-content__edit,.md-footer-nav__icon,.md-header-nav__icon,.md-nav__icon,.md-nav__title:before{display:inline-block;margin:.4rem;padding:.8rem;font-size:2.4rem;cursor:pointer}.md-icon--arrow-back:before{content:"arrow_back"}.md-icon--arrow-forward:before{content:"arrow_forward"}.md-icon--menu:before{content:"menu"}.md-icon--search:before{content:"search"}.md-icon--home:before{content:"school"}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}body,input{color:rgba(0,0,0,.87);-webkit-font-feature-settings:"kern","onum","liga";font-feature-settings:"kern","onum","liga";font-weight:400}.no-fontface body,.no-fontface input{font-family:Helvetica Neue,Helvetica,Arial,sans-serif}code,kbd,pre{color:rgba(0,0,0,.87);-webkit-font-feature-settings:"kern","onum","liga";font-feature-settings:"kern","onum","liga";font-weight:400}.no-fontface code,.no-fontface kbd,.no-fontface pre{font-family:Courier New,Courier,monospace}.md-typeset{font-size:1.6rem;line-height:1.6;-webkit-print-color-adjust:exact}.md-typeset blockquote,.md-typeset ol,.md-typeset p,.md-typeset ul{margin:1em 0}.md-typeset h1{margin:0 0 4rem;color:rgba(0,0,0,.54);font-size:3.125rem;line-height:1.3}.md-typeset h1,.md-typeset h2{font-weight:300;letter-spacing:-.01em}.md-typeset h2{margin:4rem 0 1.6rem;font-size:2.5rem;line-height:1.4}.md-typeset h3{margin:3.2rem 0 1.6rem;font-size:2rem;font-weight:400;letter-spacing:-.01em;line-height:1.5}.md-typeset h2+h3{margin-top:1.6rem}.md-typeset h4{font-size:1.6rem}.md-typeset h4,.md-typeset h5,.md-typeset h6{margin:1.6rem 0;font-weight:700;letter-spacing:-.01em}.md-typeset h5,.md-typeset h6{color:rgba(0,0,0,.54);font-size:1.28rem}.md-typeset h5{text-transform:uppercase}.md-typeset hr{margin:1.5em 0;border-bottom:.1rem dotted rgba(0,0,0,.26)}.md-typeset a{color:#3f51b5;word-break:break-word}.md-typeset a,.md-typeset a:before{-webkit-transition:color .125s;transition:color .125s}.md-typeset a:active,.md-typeset a:hover{color:#536dfe}.md-typeset code,.md-typeset pre{background-color:hsla(0,0%,93%,.5);color:#37474f;font-size:85%}.md-typeset code{margin:0 .29412em;padding:.07353em 0;border-radius:.2rem;box-shadow:.29412em 0 0 hsla(0,0%,93%,.5),-.29412em 0 0 hsla(0,0%,93%,.5);word-break:break-word;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset h1 code,.md-typeset h2 code,.md-typeset h3 code,.md-typeset h4 code,.md-typeset h5 code,.md-typeset h6 code{margin:0;background-color:transparent;box-shadow:none}.md-typeset a>code{margin:inherit;padding:inherit;border-radius:none;background-color:inherit;color:inherit;box-shadow:none}.md-typeset pre{margin:1em 0;padding:1rem 1.2rem;border-radius:.2rem;line-height:1.4;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset pre::-webkit-scrollbar{width:.4rem;height:.4rem}.md-typeset pre::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-typeset pre::-webkit-scrollbar-thumb:hover{background-color:#536dfe}.md-typeset pre>code{margin:0;background-color:transparent;font-size:inherit;box-shadow:none;-webkit-box-decoration-break:none;box-decoration-break:none}.md-typeset kbd{padding:0 .29412em;border:.1rem solid #c9c9c9;border-radius:.2rem;border-bottom-color:#bcbcbc;background-color:#fcfcfc;color:#555;font-size:85%;box-shadow:0 .1rem 0 #b0b0b0;word-break:break-word}.md-typeset mark{margin:0 .25em;padding:.0625em 0;border-radius:.2rem;background-color:rgba(255,235,59,.5);box-shadow:.25em 0 0 rgba(255,235,59,.5),-.25em 0 0 rgba(255,235,59,.5);word-break:break-word;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset abbr{border-bottom:.1rem dotted rgba(0,0,0,.54);cursor:help}.md-typeset small{opacity:.75}.md-typeset sub,.md-typeset sup{margin-left:.07812em}.md-typeset blockquote{padding-left:1.2rem;border-left:.4rem solid rgba(0,0,0,.26);color:rgba(0,0,0,.54)}.md-typeset ul{list-style-type:disc}.md-typeset ol,.md-typeset ul{margin-left:.625em;padding:0}.md-typeset ol ol,.md-typeset ul ol{list-style-type:lower-alpha}.md-typeset ol ol ol,.md-typeset ul ol ol{list-style-type:lower-roman}.md-typeset ol li,.md-typeset ul li{margin-bottom:.5em;margin-left:1.25em}.md-typeset ol li blockquote,.md-typeset ol li p,.md-typeset ul li blockquote,.md-typeset ul li p{margin:.5em 0}.md-typeset ol li:last-child,.md-typeset ul li:last-child{margin-bottom:0}.md-typeset ol li ol,.md-typeset ol li ul,.md-typeset ul li ol,.md-typeset ul li ul{margin:.5em 0 .5em .625em}.md-typeset iframe,.md-typeset img,.md-typeset svg{max-width:100%}.md-typeset table:not([class]){box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2);margin:2em 0;border-radius:.2rem;font-size:1.28rem;overflow:hidden}.no-js .md-typeset table:not([class]){display:inline-block;max-width:100%;margin:.8em 0;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset table:not([class]) td:not([align]),.md-typeset table:not([class]) th:not([align]){text-align:left}.md-typeset table:not([class]) th{min-width:10rem;padding:1.2rem 1.6rem;background-color:rgba(0,0,0,.54);color:#fff;vertical-align:top}.md-typeset table:not([class]) td{padding:1.2rem 1.6rem;border-top:.1rem solid rgba(0,0,0,.07);vertical-align:top}.md-typeset table:not([class]) tr:first-child td{border-top:0}.md-typeset table:not([class]) a{word-break:normal}.md-typeset .md-typeset__table{margin:1.6em -1.6rem;overflow-x:auto;-webkit-overflow-scrolling:touch}.md-typeset .md-typeset__table table{display:inline-block;margin:0 1.6rem}html{font-size:62.5%}body,html{height:100%}body{position:relative}hr{display:block;height:.1rem;padding:0;border:0}.md-svg{display:none}.md-grid{max-width:122rem;margin-right:auto;margin-left:auto}.md-container,.md-main{overflow:auto}.md-container{display:table;width:100%;height:100%;table-layout:fixed}.md-main{display:table-row;height:100%}.md-main__inner{margin-top:5.6rem;padding-top:3rem;overflow:auto}.csscalc .md-main__inner{min-height:calc(100% - 2.6rem)}@-moz-document url-prefix(){.csscalc .md-main__inner{min-height:calc(100% - 5.6rem)}}.md-toggle{display:none}.md-overlay{position:fixed;top:0;width:0;height:0;-webkit-transition:width 0s .25s,height 0s .25s,opacity .25s;transition:width 0s .25s,height 0s .25s,opacity .25s;background-color:rgba(0,0,0,.54);opacity:0;z-index:2}.md-flex{display:table}.md-flex__cell{display:table-cell;position:relative;vertical-align:top}.md-flex__cell--shrink{width:0}.md-flex__cell--stretch{display:table;width:100%;table-layout:fixed}.md-flex__ellipsis{display:table-cell;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}@page{margin:25mm}.md-content__inner{margin:2.4rem 1.6rem}.md-content__edit{float:right}.md-header{box-shadow:0 2px 2px 0 rgba(0,0,0,.14),0 1px 5px 0 rgba(0,0,0,.12),0 3px 1px -2px rgba(0,0,0,.2);position:fixed;top:0;right:0;left:0;height:5.6rem;-webkit-transition:background-color .25s;transition:background-color .25s;background-color:#3f51b5;color:#fff;z-index:1}.md-header-nav{padding:.4rem}.md-header-nav__icon{position:relative;-webkit-transition:opacity .25s;transition:opacity .25s;z-index:1}.md-header-nav__icon:hover{opacity:.7}.no-js .md-header-nav__icon .md-icon--search{display:none}.md-header-nav__title{padding:0 2rem;font-size:1.8rem;line-height:4.8rem}.md-header-nav__parent{color:hsla(0,0%,100%,.7)}.md-header-nav__parent:after{display:inline;color:hsla(0,0%,100%,.3);content:"/"}.md-header-nav__source{display:none}.md-footer-nav{background-color:rgba(0,0,0,.87);color:#fff}.md-footer-nav__inner{padding:.4rem;overflow:auto}.md-footer-nav__link{padding-top:2.8rem;padding-bottom:.8rem;-webkit-transition:opacity .25s;transition:opacity .25s}.md-footer-nav__link:hover{opacity:.7}.md-footer-nav__link--prev{width:25%;float:left}.md-footer-nav__link--next{width:75%;float:right;text-align:right}.md-footer-nav__icon{-webkit-transition:background .25s;transition:background .25s}.md-footer-nav__title{position:relative;padding:0 2rem;font-size:1.8rem;line-height:4.8rem}.md-footer-nav__direction{position:absolute;right:0;left:0;margin-top:-2rem;padding:0 2rem;color:hsla(0,0%,100%,.7);font-size:1.5rem}.md-footer-meta{background:rgba(0,0,0,.895)}.md-footer-meta__inner{padding:.4rem;overflow:auto}html .md-footer-meta.md-typeset a{color:hsla(0,0%,100%,.7)}.md-footer-copyright{margin:0 1.2rem;padding:.8rem 0;color:hsla(0,0%,100%,.3);font-size:1.28rem}.md-footer-copyright__highlight{color:hsla(0,0%,100%,.7)}.md-footer-social{margin:0 .8rem;padding:.4rem 0 1.2rem}.md-footer-social__link{display:inline-block;width:3.2rem;height:3.2rem;border:.1rem solid hsla(0,0%,100%,.12);border-radius:100%;color:hsla(0,0%,100%,.7);font-size:1.6rem;text-align:center}.md-footer-social__link:before{line-height:1.9}.md-nav{font-size:1.28rem;line-height:1.3}.md-nav--secondary{-webkit-transition:border-left .25s;transition:border-left .25s;border-left:.4rem solid #3f51b5}.md-nav__title{display:block;padding:1.2rem 1.2rem 0;font-weight:700;text-overflow:ellipsis;overflow:hidden}.md-nav__title:before{display:none;content:"arrow_back"}.md-nav__title .md-nav__icon{display:none}.md-nav__list{margin:0;padding:0;list-style:none}.md-nav__item{padding:.625em 1.2rem 0}.md-nav__item:last-child{padding-bottom:1.2rem}.md-nav__item .md-nav__item{padding-right:0}.md-nav__item .md-nav__item:last-child{padding-bottom:0}.md-nav__icon img{width:100%;height:auto}.md-nav__link{display:block;-webkit-transition:color .125s;transition:color .125s;text-overflow:ellipsis;cursor:pointer;overflow:hidden}.md-nav__item--nested>.md-nav__link:after{content:"keyboard_arrow_down"}html .md-nav__link[for=toc],html .md-nav__link[for=toc]+.md-nav__link:after,html .md-nav__link[for=toc]~.md-nav{display:none}.md-nav__link[data-md-state=blur]{color:rgba(0,0,0,.54)}.md-nav__link--active,.md-nav__link:active{color:#3f51b5}.md-nav__link:hover{color:#536dfe}.md-nav__source,.no-js .md-search{display:none}.md-search__overlay{display:none;pointer-events:none}.md-search__inner{width:100%}.md-search__form{position:relative}.md-search__input{position:relative;padding:0 1.6rem 0 7.2rem;text-overflow:ellipsis;z-index:1}.md-search__input+.md-search__icon,.md-search__input::-webkit-input-placeholder{color:rgba(0,0,0,.54)}.md-search__input+.md-search__icon,.md-search__input::-moz-placeholder{color:rgba(0,0,0,.54)}.md-search__input+.md-search__icon,.md-search__input:-ms-input-placeholder{color:rgba(0,0,0,.54)}.md-search__input+.md-search__icon,.md-search__input::placeholder{color:rgba(0,0,0,.54)}.md-search__input::-ms-clear{display:none}.md-search__icon{position:absolute;top:.8rem;left:1.2rem;-webkit-transition:color .25s;transition:color .25s;font-size:2.4rem;cursor:pointer;z-index:1}.md-search__icon:before{content:"search"}.md-search__output{position:absolute;width:100%;border-radius:0 0 .2rem .2rem;overflow:hidden}.md-search__scrollwrap{height:100%;background:-webkit-linear-gradient(top,#fff 10%,hsla(0,0%,100%,0)),-webkit-linear-gradient(top,rgba(0,0,0,.26),rgba(0,0,0,.07) 35%,transparent 60%);background:linear-gradient(180deg,#fff 10%,hsla(0,0%,100%,0)),linear-gradient(180deg,rgba(0,0,0,.26),rgba(0,0,0,.07) 35%,transparent 60%);background-attachment:local,scroll;background-color:#fff;background-repeat:no-repeat;background-size:100% 2rem,100% 1rem;box-shadow:inset 0 .1rem 0 rgba(0,0,0,.07);overflow-y:auto;-webkit-overflow-scrolling:touch}.md-search-result__meta{padding:0 1.6rem;background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.54);font-size:1.28rem;line-height:4rem}.md-search-result__list{margin:0;padding:0;border-top:.1rem solid rgba(0,0,0,.07);list-style:none}.md-search-result__item{box-shadow:0 -.1rem 0 rgba(0,0,0,.07)}.md-search-result__link{display:block;padding:0 1.6rem;-webkit-transition:background .25s;transition:background .25s;overflow:auto}.md-search-result__link:hover{background-color:rgba(83,109,254,.1)}.md-search-result__article{margin:1em 0}.md-search-result__title{margin-top:.5em;margin-bottom:0;color:rgba(0,0,0,.87);font-size:1.6rem;font-weight:400;line-height:1.4}.md-search-result__teaser{margin:.5em 0;color:rgba(0,0,0,.54);font-size:1.28rem;line-height:1.4;word-break:break-word}.md-sidebar{position:relative;width:24.2rem;float:left;overflow:visible}.md-sidebar[data-md-state=lock]{position:fixed;top:5.6rem}.md-sidebar--secondary{display:none}.md-sidebar__scrollwrap{margin:2.4rem .4rem;overflow-y:scroll}.js .md-sidebar__scrollwrap{position:absolute;top:0;right:0;bottom:0;left:0}.md-sidebar__scrollwrap::-webkit-scrollbar{width:.4rem;height:.4rem}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:#536dfe}@-webkit-keyframes a{0%{height:0}to{height:1.3rem}}@keyframes a{0%{height:0}to{height:1.3rem}}@-webkit-keyframes b{0%{-webkit-transform:translateY(100%);transform:translateY(100%);opacity:0}50%{opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}@keyframes b{0%{-webkit-transform:translateY(100%);transform:translateY(100%);opacity:0}50%{opacity:0}to{-webkit-transform:translateY(0);transform:translateY(0);opacity:1}}.md-source{display:block;-webkit-transition:opacity .25s;transition:opacity .25s;font-size:1.3rem;line-height:1.2;white-space:nowrap}.md-source:hover{opacity:.7}.md-source:after,.md-source__icon{display:inline-block;height:4.8rem;content:"";vertical-align:middle}.md-source__icon{width:4.8rem}.md-source__icon svg{margin-top:1.2rem;margin-left:1.2rem}.md-source__icon+.md-source__repository{margin-left:-4.4rem;padding-left:4rem}.md-source__repository{display:inline-block;max-width:100%;margin-left:1.2rem;font-weight:700;text-overflow:ellipsis;overflow:hidden;vertical-align:middle}.md-source__facts{margin:0;padding:0;font-size:1.1rem;font-weight:700;list-style-type:none;opacity:.75;overflow:auto}[data-md-state=done] .md-source__facts{-webkit-animation:a .25s ease-in;animation:a .25s ease-in}.md-source__fact{float:left}[data-md-state=done] .md-source__fact{-webkit-animation:b .4s ease-out;animation:b .4s ease-out}.md-source__fact:before{margin:0 .2rem;content:"\00B7"}.md-source__fact:first-child:before{display:none}.admonition{position:relative;margin:1.5625em 0;padding:.8rem 1.2rem;border-left:3.2rem solid rgba(68,138,255,.4);border-radius:.2rem;background-color:rgba(68,138,255,.15);font-size:1.28rem}.admonition:before{position:absolute;left:-2.6rem;color:#fff;font-size:2rem;content:"edit";vertical-align:-.25em}.admonition :first-child{margin-top:0}.admonition :last-child{margin-bottom:0}.admonition.summary,.admonition.tldr{border-color:rgba(0,176,255,.4);background-color:rgba(0,176,255,.15)}.admonition.summary:before,.admonition.tldr:before{content:"subject"}.admonition.hint,.admonition.important,.admonition.tip{border-color:rgba(0,191,165,.4);background-color:rgba(0,191,165,.15)}.admonition.hint:before,.admonition.important:before,.admonition.tip:before{content:"whatshot"}.admonition.check,.admonition.done,.admonition.success{border-color:rgba(0,230,118,.4);background-color:rgba(0,230,118,.15)}.admonition.check:before,.admonition.done:before,.admonition.success:before{content:"done"}.admonition.attention,.admonition.caution,.admonition.warning{border-color:rgba(255,145,0,.4);background-color:rgba(255,145,0,.15)}.admonition.attention:before,.admonition.caution:before,.admonition.warning:before{content:"warning"}.admonition.fail,.admonition.failure,.admonition.missing{border-color:rgba(255,82,82,.4);background-color:rgba(255,82,82,.15)}.admonition.fail:before,.admonition.failure:before,.admonition.missing:before{content:"clear"}.admonition.danger,.admonition.error{border-color:rgba(255,23,68,.4);background-color:rgba(255,23,68,.15)}.admonition.danger:before,.admonition.error:before{content:"flash_on"}.admonition.bug{border-color:rgba(245,0,87,.4);background-color:rgba(245,0,87,.15)}.admonition.bug:before{content:"bug_report"}.admonition-title{font-weight:700}html .admonition-title{margin-bottom:0}html .admonition-title+*{margin-top:0}.codehilite .o,.codehilite .ow{color:inherit}.codehilite .ge{color:#000}.codehilite .gr{color:#a00}.codehilite .gh{color:#999}.codehilite .go{color:#888}.codehilite .gp{color:#555}.codehilite .gs{color:inherit}.codehilite .gu{color:#aaa}.codehilite .gt{color:#a00}.codehilite .gd{background-color:#fdd}.codehilite .gi{background-color:#dfd}.codehilite .k{color:#3b78e7}.codehilite .kc{color:#a71d5d}.codehilite .kd,.codehilite .kn{color:#3b78e7}.codehilite .kp{color:#a71d5d}.codehilite .kr,.codehilite .kt{color:#3e61a2}.codehilite .c,.codehilite .cm{color:#999}.codehilite .cp{color:#666}.codehilite .c1,.codehilite .ch,.codehilite .cs{color:#999}.codehilite .na,.codehilite .nb{color:#c2185b}.codehilite .bp{color:#3e61a2}.codehilite .nc{color:#c2185b}.codehilite .no{color:#3e61a2}.codehilite .nd,.codehilite .ni{color:#666}.codehilite .ne,.codehilite .nf{color:#c2185b}.codehilite .nl{color:#3b5179}.codehilite .nn{color:#ec407a}.codehilite .nt{color:#3b78e7}.codehilite .nv,.codehilite .vc,.codehilite .vg,.codehilite .vi{color:#3e61a2}.codehilite .nx{color:#ec407a}.codehilite .il,.codehilite .m,.codehilite .mf,.codehilite .mh,.codehilite .mi,.codehilite .mo{color:#e74c3c}.codehilite .s,.codehilite .sb,.codehilite .sc{color:#0d904f}.codehilite .sd{color:#999}.codehilite .s2{color:#0d904f}.codehilite .se,.codehilite .sh,.codehilite .si,.codehilite .sx{color:#183691}.codehilite .sr{color:#009926}.codehilite .s1,.codehilite .ss{color:#0d904f}.codehilite .err{color:#a61717}.codehilite .w{color:transparent}.codehilite .hll{display:block;margin:0 -1.2rem;padding:0 1.2rem;background-color:rgba(255,235,59,.5)}.md-typeset .codehilite{margin:1em 0;padding:1rem 1.2rem .8rem;border-radius:.2rem;background-color:hsla(0,0%,93%,.5);color:#37474f;line-height:1.4;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset .codehilite::-webkit-scrollbar{width:.4rem;height:.4rem}.md-typeset .codehilite::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-typeset .codehilite::-webkit-scrollbar-thumb:hover{background-color:#536dfe}.md-typeset .codehilite pre{display:inline-block;min-width:100%;margin:0;padding:0;background-color:transparent;overflow:visible;vertical-align:top}.md-typeset .codehilitetable{display:block;margin:1em 0;border-radius:.2em;font-size:1.6rem;overflow:hidden}.md-typeset .codehilitetable tbody,.md-typeset .codehilitetable td{display:block;padding:0}.md-typeset .codehilitetable tr{display:-webkit-box;display:-ms-flexbox;display:flex}.md-typeset .codehilitetable .codehilite,.md-typeset .codehilitetable .linenodiv{margin:0;border-radius:0}.md-typeset .codehilitetable .linenodiv{padding:1rem 1.2rem .8rem}.md-typeset .codehilitetable .linenodiv,.md-typeset .codehilitetable .linenodiv>pre{height:100%}.md-typeset .codehilitetable .linenos{background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.26);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.md-typeset .codehilitetable .linenos pre{margin:0;padding:0;background-color:transparent;color:inherit;text-align:right}.md-typeset .codehilitetable .code{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow:hidden}.md-typeset>.codehilitetable{box-shadow:none}.md-typeset .footnote{color:rgba(0,0,0,.54);font-size:1.28rem}.md-typeset .footnote ol{margin-left:0}.md-typeset .footnote li{-webkit-transition:color .25s;transition:color .25s}.md-typeset .footnote li:before{display:block;height:0}.md-typeset .footnote li:target{color:rgba(0,0,0,.87)}.md-typeset .footnote li:target:before{margin-top:-9rem;padding-top:9rem;pointer-events:none}.md-typeset .footnote li :first-child{margin-top:0}.md-typeset .footnote li:hover .footnote-backref,.md-typeset .footnote li:target .footnote-backref{-webkit-transform:translateX(0);transform:translateX(0);opacity:1}.md-typeset .footnote li:hover .footnote-backref:hover,.md-typeset .footnote li:target .footnote-backref{color:#536dfe}.md-typeset .footnote-backref{position:absolute;-webkit-transform:translateX(.5rem);transform:translateX(.5rem);-webkit-transition:color .25s,opacity .125s .125s,-webkit-transform .25s .125s;transition:color .25s,opacity .125s .125s,-webkit-transform .25s .125s;transition:transform .25s .125s,color .25s,opacity .125s .125s;transition:transform .25s .125s,color .25s,opacity .125s .125s,-webkit-transform .25s .125s;color:rgba(0,0,0,.26);font-size:1.5625em;opacity:0;vertical-align:middle}.md-typeset .footnote-backref:first-letter{font-size:0}.md-typeset .footnote-backref:after{content:"keyboard_return"}.md-typeset .headerlink{display:inline-block;margin-left:1rem;-webkit-transform:translateY(.5rem);transform:translateY(.5rem);-webkit-transition:color .25s,opacity .125s .25s,-webkit-transform .25s .25s;transition:color .25s,opacity .125s .25s,-webkit-transform .25s .25s;transition:transform .25s .25s,color .25s,opacity .125s .25s;transition:transform .25s .25s,color .25s,opacity .125s .25s,-webkit-transform .25s .25s;opacity:0}html body .md-typeset .headerlink{color:rgba(0,0,0,.26)}.md-typeset [id]:before{display:inline-block;content:""}.md-typeset [id]:target:before{margin-top:-9.8rem;padding-top:9.8rem}.md-typeset [id] .headerlink:focus,.md-typeset [id]:hover .headerlink,.md-typeset [id]:target .headerlink{-webkit-transform:translate(0);transform:translate(0);opacity:1}.md-typeset [id] .headerlink:focus,.md-typeset [id]:hover .headerlink:hover,.md-typeset [id]:target .headerlink{color:#536dfe}.md-typeset h1[id] .headerlink{display:none}.md-typeset h2[id]:before{display:block;margin-top:-.2rem;padding-top:.2rem}.md-typeset h2[id]:target:before{margin-top:-8.2rem;padding-top:8.2rem}.md-typeset h3[id]:before{display:block;margin-top:-.4rem;padding-top:.4rem}.md-typeset h3[id]:target:before{margin-top:-8.4rem;padding-top:8.4rem}.md-typeset h4[id]:before{display:block;margin-top:-.6rem;padding-top:.6rem}.md-typeset h4[id]:target:before{margin-top:-8.6rem;padding-top:8.6rem}.md-typeset h5[id]:before{display:block;margin-top:-1rem;padding-top:1rem}.md-typeset h5[id]:target:before{margin-top:-9rem;padding-top:9rem}.md-typeset h6[id]:before{display:block;margin-top:-1rem;padding-top:1rem}.md-typeset h6[id]:target:before{margin-top:-9rem;padding-top:9rem}.md-typeset .MJXc-display{margin:.75em 0;padding:.25em 0;overflow:auto;-webkit-overflow-scrolling:touch}.md-typeset .MathJax_CHTML{outline:0}.md-typeset .comment.critic,.md-typeset del.critic,.md-typeset ins.critic{margin:0 .25em;padding:.0625em 0;border-radius:.2rem;-webkit-box-decoration-break:clone;box-decoration-break:clone}.md-typeset del.critic{background-color:#fdd;box-shadow:.25em 0 0 #fdd,-.25em 0 0 #fdd}.md-typeset ins.critic{background-color:#dfd;box-shadow:.25em 0 0 #dfd,-.25em 0 0 #dfd}.md-typeset .critic.comment{background-color:hsla(0,0%,93%,.5);color:#37474f;box-shadow:.25em 0 0 hsla(0,0%,93%,.5),-.25em 0 0 hsla(0,0%,93%,.5)}.md-typeset .critic.comment:before{padding-right:.125em;color:rgba(0,0,0,.26);content:"chat";vertical-align:-.125em}.md-typeset .critic.block{display:block;margin:1em 0;padding-right:1.6rem;padding-left:1.6rem;box-shadow:none}.md-typeset .critic.block :first-child{margin-top:.5em}.md-typeset .critic.block :last-child{margin-bottom:.5em}.md-typeset .emojione{width:2rem;vertical-align:text-top}.md-typeset code.codehilite{margin:0 .29412em;padding:.07353em 0}.md-typeset .task-list-item{position:relative;list-style-type:none}.md-typeset .task-list-item [type=checkbox]{position:absolute;top:.45em;left:-2em}.md-typeset .task-list-control .task-list-indicator:before{position:absolute;top:.05em;left:-1.25em;color:rgba(0,0,0,.26);font-size:1.5em;content:"check_box_outline_blank";vertical-align:-.25em}.md-typeset .task-list-control [type=checkbox]:checked+.task-list-indicator:before{content:"check_box"}.md-typeset .task-list-control [type=checkbox]{opacity:0;z-index:-1}@media print{.md-typeset a:after{color:rgba(0,0,0,.54);content:" [" attr(href) "]"}.md-typeset code{box-shadow:none;-webkit-box-decoration-break:initial;box-decoration-break:slice}.md-content__edit,.md-footer,.md-header,.md-sidebar,.md-typeset .headerlink{display:none}}@media only screen and (max-width:44.9375em){.md-typeset pre{margin:1em -1.6rem;padding:1rem 1.6rem;border-radius:0}.codehilite .hll{margin:0 -1.6rem;padding:0 1.6rem}.md-typeset>.codehilite{padding:1rem 1.6rem .8rem}.md-typeset>.codehilite,.md-typeset>.codehilitetable{margin:1em -1.6rem;border-radius:0}.md-typeset>.codehilitetable .codehilite,.md-typeset>.codehilitetable .linenodiv{padding:1rem 1.6rem}.md-typeset>p>.MJXc-display{margin:.75em -1.6rem;padding:.25em 1.6rem}}@media only screen and (min-width:100em){html{font-size:68.75%}}@media only screen and (min-width:125em){html{font-size:75%}}@media only screen and (max-width:59.9375em){body[data-md-state=lock]{overflow:hidden}.ios body[data-md-state=lock] .md-container{display:none}.md-content__edit{margin-right:-.8rem}.md-nav--secondary{border-left:0}html .md-nav__link[for=toc]{display:block;padding-right:4.8rem}html .md-nav__link[for=toc]:after{color:inherit;content:"toc"}html .md-nav__link[for=toc]+.md-nav__link{display:none}html .md-nav__link[for=toc]~.md-nav{display:-webkit-box;display:-ms-flexbox;display:flex}.md-nav__source{display:block;padding:.4rem;background-color:rgba(50,64,144,.9675);color:#fff}.md-search__overlay{display:block;position:absolute;top:.4rem;left:.4rem;width:4rem;height:4rem;-webkit-transform-origin:center;transform-origin:center;-webkit-transition:opacity .2s .2s,-webkit-transform .3s .1s;transition:opacity .2s .2s,-webkit-transform .3s .1s;transition:transform .3s .1s,opacity .2s .2s;transition:transform .3s .1s,opacity .2s .2s,-webkit-transform .3s .1s;border-radius:2rem;background-color:#fff;opacity:0;overflow:hidden;z-index:1}[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transition:opacity .1s,-webkit-transform .4s;transition:opacity .1s,-webkit-transform .4s;transition:transform .4s,opacity .1s;transition:transform .4s,opacity .1s,-webkit-transform .4s;opacity:1}.md-search__inner{position:fixed;top:0;left:100%;height:100%;-webkit-transform:translateX(5%);transform:translateX(5%);-webkit-transition:left 0s .3s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) .15s;transition:left 0s .3s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) .15s;transition:left 0s .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s;transition:left 0s .3s,transform .15s cubic-bezier(.4,0,.2,1) .15s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.4,0,.2,1) .15s;opacity:0;z-index:2}[data-md-toggle=search]:checked~.md-header .md-search__inner{left:0;-webkit-transform:translateX(0);transform:translateX(0);-webkit-transition:left 0s 0s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1) .15s;transition:left 0s 0s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1) .15s;transition:left 0s 0s,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s;transition:left 0s 0s,transform .15s cubic-bezier(.1,.7,.1,1) .15s,opacity .15s .15s,-webkit-transform .15s cubic-bezier(.1,.7,.1,1) .15s;opacity:1}.md-search__input{width:100%;height:5.6rem;font-size:1.8rem}.md-search__icon{top:1.6rem;left:1.6rem}.md-search__icon:before{content:"arrow_back"}.md-search__output{top:5.6rem;bottom:0}}@media only screen and (max-width:76.1875em){[data-md-toggle=drawer]:checked~.md-overlay{width:100%;height:100%;-webkit-transition:width 0s,height 0s,opacity .25s;transition:width 0s,height 0s,opacity .25s;opacity:1}.md-header-nav__icon.md-icon--home{display:none}.md-nav--primary,.md-nav--primary .md-nav{display:-webkit-box;display:-ms-flexbox;display:flex;position:absolute;top:0;right:0;left:0;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;height:100%;z-index:1}.md-nav--primary{background-color:#fff}.md-nav--primary .md-nav__toggle~.md-nav{box-shadow:0 4px 5px 0 rgba(0,0,0,.14),0 1px 10px 0 rgba(0,0,0,.12),0 2px 4px -1px rgba(0,0,0,.4);background-color:#fff}html .md-nav--primary .md-nav__title{position:relative;height:11.2rem;padding:6rem 1.6rem .4rem;background-color:rgba(0,0,0,.07);color:rgba(0,0,0,.54);font-weight:400;line-height:4.8rem;white-space:nowrap;cursor:pointer}html .md-nav--primary .md-nav__title:before{display:block;position:absolute;top:.4rem;left:.4rem;width:4rem;height:4rem;color:rgba(0,0,0,.54)}html .md-nav--primary .md-nav__title~.md-nav__list{background:-webkit-linear-gradient(top,#fff 10%,hsla(0,0%,100%,0)),-webkit-linear-gradient(top,rgba(0,0,0,.26),rgba(0,0,0,.07) 35%,transparent 60%);background:linear-gradient(180deg,#fff 10%,hsla(0,0%,100%,0)),linear-gradient(180deg,rgba(0,0,0,.26),rgba(0,0,0,.07) 35%,transparent 60%);background-attachment:local,scroll;background-color:#fff;background-repeat:no-repeat;background-size:100% 2rem,100% 1rem;box-shadow:inset 0 .1rem 0 rgba(0,0,0,.07)}html .md-nav--primary .md-nav__title~.md-nav__list>.md-nav__item:first-child{border-top:0}html .md-nav--primary .md-nav__title--site{position:relative;background-color:#3f51b5;color:#fff}html .md-nav--primary .md-nav__title--site .md-nav__icon{display:block;position:absolute;top:.4rem;left:.4rem;width:6.4rem;height:6.4rem;font-size:4.8rem}html .md-nav--primary .md-nav__title--site:before{display:none}.md-nav--primary .md-nav__list{-webkit-box-flex:1;-ms-flex:1;flex:1;overflow-y:scroll}.md-nav--primary .md-nav__item{padding:0;border-top:.1rem solid rgba(0,0,0,.07)}.md-nav--primary .md-nav__item--nested>.md-nav__link{padding-right:4.8rem}.md-nav--primary .md-nav__item--nested>.md-nav__link:after{content:"keyboard_arrow_right"}.md-nav--primary .md-nav__link{position:relative;padding:1.6rem}.md-nav--primary .md-nav__link:after{position:absolute;top:50%;right:1.2rem;margin-top:-1.2rem;color:rgba(0,0,0,.54);font-size:2.4rem}.md-nav--primary .md-nav__link:hover:after{color:inherit}.md-nav--primary .md-nav--secondary .md-nav{position:static}.md-nav--primary .md-nav--secondary .md-nav .md-nav__link{padding-left:2.8rem}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav__link{padding-left:4rem}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav__link{padding-left:5.2rem}.md-nav--primary .md-nav--secondary .md-nav .md-nav .md-nav .md-nav .md-nav__link{padding-left:6.4rem}.md-nav__toggle~.md-nav{display:none}.csstransforms3d .md-nav__toggle~.md-nav{-webkit-transform:translateX(100%);transform:translateX(100%);-webkit-transition:opacity .125s .05s,-webkit-transform .25s cubic-bezier(.8,0,.6,1);transition:opacity .125s .05s,-webkit-transform .25s cubic-bezier(.8,0,.6,1);transition:transform .25s cubic-bezier(.8,0,.6,1),opacity .125s .05s;transition:transform .25s cubic-bezier(.8,0,.6,1),opacity .125s .05s,-webkit-transform .25s cubic-bezier(.8,0,.6,1);opacity:0}.csstransforms3d .md-nav__toggle~.md-nav,.md-nav__toggle:checked~.md-nav{display:-webkit-box;display:-ms-flexbox;display:flex}.csstransforms3d .md-nav__toggle:checked~.md-nav{-webkit-transform:translateX(0);transform:translateX(0);-webkit-transition:opacity .125s .125s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:opacity .125s .125s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .125s .125s;transition:transform .25s cubic-bezier(.4,0,.2,1),opacity .125s .125s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);opacity:1}.md-nav .md-nav__item,.md-nav .md-nav__title{font-size:1.6rem;line-height:1.5}.md-sidebar--primary{position:fixed;top:0;left:-24.2rem;width:24.2rem;height:100%;-webkit-transform:translateX(0);transform:translateX(0);-webkit-transition:box-shadow .25s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:box-shadow .25s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s;transition:transform .25s cubic-bezier(.4,0,.2,1),box-shadow .25s,-webkit-transform .25s cubic-bezier(.4,0,.2,1);background-color:#fff;z-index:2}.no-csstransforms3d .md-sidebar--primary{display:none}[data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{box-shadow:0 8px 10px 1px rgba(0,0,0,.14),0 3px 14px 2px rgba(0,0,0,.12),0 5px 5px -3px rgba(0,0,0,.4);-webkit-transform:translateX(24.2rem);transform:translateX(24.2rem)}.no-csstransforms3d [data-md-toggle=drawer]:checked~.md-container .md-sidebar--primary{display:block}.md-sidebar--primary .md-sidebar__scrollwrap{overflow:hidden;margin:0}}@media only screen and (min-width:60em){.md-content{margin-right:24.2rem}.md-header-nav__icon.md-icon--search{display:none}.md-header-nav__source{display:block;width:23rem;max-width:23rem;padding-right:1.2rem}.md-search{margin-right:2.8rem;padding:.4rem}.md-search__inner{display:table;position:relative;clear:both}.md-search__form{width:23rem;float:right;-webkit-transition:width .25s cubic-bezier(.1,.7,.1,1);transition:width .25s cubic-bezier(.1,.7,.1,1);border-radius:.2rem}.md-search__input{width:100%;height:4rem;padding-left:4.8rem;-webkit-transition:background-color .25s,color .25s;transition:background-color .25s,color .25s;border-radius:.2rem;background-color:rgba(0,0,0,.26);color:#fff;font-size:1.6rem}.md-search__input+.md-search__icon,.md-search__input::-webkit-input-placeholder{-webkit-transition:color .25s;transition:color .25s;color:#fff}.md-search__input+.md-search__icon,.md-search__input::-moz-placeholder{-webkit-transition:color .25s;transition:color .25s;color:#fff}.md-search__input+.md-search__icon,.md-search__input:-ms-input-placeholder{-webkit-transition:color .25s;transition:color .25s;color:#fff}.md-search__input+.md-search__icon,.md-search__input::placeholder{-webkit-transition:color .25s;transition:color .25s;color:#fff}.md-search__input:hover{background-color:hsla(0,0%,100%,.12)}[data-md-toggle=search]:checked~.md-header .md-search__input{border-radius:.2rem .2rem 0 0;background-color:#fff;color:rgba(0,0,0,.87);text-overflow:none}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::-webkit-input-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::-moz-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input:-ms-input-placeholder{color:rgba(0,0,0,.54)}[data-md-toggle=search]:checked~.md-header .md-search__input+.md-search__icon,[data-md-toggle=search]:checked~.md-header .md-search__input::placeholder{color:rgba(0,0,0,.54)}.md-search__output{box-shadow:0 6px 10px 0 rgba(0,0,0,.14),0 1px 18px 0 rgba(0,0,0,.12),0 3px 5px -1px rgba(0,0,0,.4);top:4rem;-webkit-transition:opacity .4s;transition:opacity .4s;opacity:0}[data-md-toggle=search]:checked~.md-header .md-search__output{opacity:1}.md-search__scrollwrap{max-height:0}[data-md-toggle=search]:checked~.md-header .md-search__scrollwrap{max-height:75vh}.md-search__scrollwrap::-webkit-scrollbar{width:.4rem;height:.4rem}.md-search__scrollwrap::-webkit-scrollbar-thumb{background-color:rgba(0,0,0,.26)}.md-search__scrollwrap::-webkit-scrollbar-thumb:hover{background-color:#536dfe}.md-search-result__link,.md-search-result__meta{padding-left:4.8rem}.md-sidebar--secondary{display:block;float:right}.md-sidebar--secondary[data-md-state=lock]{margin-left:100%;-webkit-transform:translate(-100%);transform:translate(-100%)}}@media only screen and (min-width:76.25em){.md-content{margin-left:24.2rem}.md-content__inner{margin:2.4rem}.md-header-nav__icon.md-icon--menu{display:none}.md-nav[data-md-state=animate]{-webkit-transition:max-height .25s cubic-bezier(.86,0,.07,1);transition:max-height .25s cubic-bezier(.86,0,.07,1)}.md-nav__toggle~.md-nav{max-height:0;overflow:hidden}.md-nav[data-md-state=expand],.md-nav__toggle:checked~.md-nav{max-height:100%}.md-nav__item--nested>.md-nav>.md-nav__title{display:none}.md-nav__item--nested>.md-nav__link:after{display:inline-block;-webkit-transform-origin:.45em .45em;transform-origin:.45em .45em;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;vertical-align:-.125em}.js .md-nav__item--nested>.md-nav__link:after{-webkit-transition:-webkit-transform .4s;transition:-webkit-transform .4s;transition:transform .4s;transition:transform .4s,-webkit-transform .4s}.md-nav__item--nested .md-nav__toggle:checked~.md-nav__link:after{-webkit-transform:rotateX(180deg);transform:rotateX(180deg)}.md-search__scrollwrap,[data-md-toggle=search]:checked~.md-header .md-search__form{width:68.8rem}.md-sidebar__inner{border-right:.1rem solid rgba(0,0,0,.07)}}@media only screen and (max-width:29.9375em){.md-footer-nav__link--prev .md-footer-nav__title,.md-header-nav__parent{display:none}[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(45);transform:scale(45)}}@media only screen and (min-width:30em){.md-footer-nav__link{width:50%}}@media only screen and (min-width:45em){.md-footer-copyright{max-width:75%;float:left}.md-footer-social{padding:1.2rem 0;float:right}}@media only screen and (min-width:30em) and (max-width:44.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(60);transform:scale(60)}}@media only screen and (min-width:45em) and (max-width:59.9375em){[data-md-toggle=search]:checked~.md-header .md-search__overlay{-webkit-transform:scale(75);transform:scale(75)}}@media only screen and (min-width:60em) and (max-width:76.1875em){.md-search__scrollwrap,[data-md-toggle=search]:checked~.md-header .md-search__form{width:46.8rem}}@media only screen and (min-width:60em) and (min-width:76.25em){.md-sidebar--secondary[data-md-state=lock]{margin-left:122rem}} \ No newline at end of file diff --git a/material/assets/stylesheets/application.css b/material/assets/stylesheets/application.css deleted file mode 100644 index 7ff728ef6..000000000 --- a/material/assets/stylesheets/application.css +++ /dev/null @@ -1 +0,0 @@ -html{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}*,:after,:before{box-sizing:inherit;-moz-box-sizing:inherit;-webkit-box-sizing:inherit}html{font-size:62.5%;-webkit-text-size-adjust:none;-ms-text-size-adjust:none;text-size-adjust:none}a,abbr,acronym,address,applet,article,aside,audio,b,big,blockquote,body,canvas,caption,center,cite,code,dd,del,details,dfn,div,dl,dt,em,embed,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,html,i,iframe,img,ins,kbd,label,legend,li,main,mark,menu,nav,object,ol,output,p,pre,q,ruby,s,samp,section,small,span,strike,strong,sub,summary,sup,table,tbody,td,tfoot,th,thead,time,tr,tt,u,ul,var,video{margin:0;padding:0;border:0}main{display:block}ul{list-style:none}table{border-collapse:collapse;border-spacing:0}td{text-align:left;font-weight:400;vertical-align:middle}button{outline:0;padding:0;background:transparent;border:none;font-size:inherit}input{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;-o-appearance:none;appearance:none;outline:none;border:none}a{text-decoration:none;color:inherit}a,button,input,label{-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-tap-highlight-color:transparent}h1,h2,h3,h4,h5,h6{font-weight:inherit}pre{background:rgba(0,0,0,.05)}pre,pre code{color:rgba(0,0,0,.87)}.c,.c1,.cm,.o{color:rgba(0,0,0,.54)}.k,.kn{color:#a71d5d}.kd,.kt{color:#0086b3}.n.f,.nf{color:#795da3}.nx{color:#0086b3}.s,.s1{color:#183691}.bp,.mi{color:#9575cd}.icon{font-family:Icon;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.icon-search:before{content:"\e600"}.icon-back:before{content:"\e601"}.icon-link:before{content:"\e602"}.icon-close:before{content:"\e603"}.icon-menu:before{content:"\e604"}.icon-forward:before{content:"\e605"}.icon-twitter:before{content:"\e606"}.icon-github:before{content:"\e607"}.icon-download:before{content:"\e608"}.icon-star:before{content:"\e609"}.icon-warning:before{content:"\e610"}.icon-note:before{content:"\e611"}a{-webkit-transition:color .25s;transition:color .25s}.overlay{-webkit-transition:opacity .25s,width 0s .25s,height 0s .25s;transition:opacity .25s,width 0s .25s,height 0s .25s}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{-webkit-transition:opacity .25s,width 0s,height 0s;transition:opacity .25s,width 0s,height 0s}.js .header{-webkit-transition:background .6s,color .6s;transition:background .6s,color .6s}.js .header:before{-webkit-transition:background .6s;transition:background .6s}.button .icon{-webkit-transition:background .25s;transition:background .25s}body{color:rgba(0,0,0,.87)}@supports (-webkit-appearance:none){body{background:#e84e40}}.ios body{background:#fff}hr{border:0;border-top:1px solid rgba(0,0,0,.12)}.toggle-button{cursor:pointer;color:inherit}.backdrop,.backdrop-paper:after{background:#fff}.overlay{background:rgba(0,0,0,.54);opacity:0}#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{opacity:1}.header{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}.ios.standalone .header:before{background:rgba(0,0,0,.12)}.bar .path{color:hsla(0,0%,100%,.7)}.button .icon{border-radius:100%}.button .icon:active{background:hsla(0,0%,100%,.12)}html{height:100%}body{position:relative;min-height:100%}hr{display:block;height:1px;padding:0;margin:0}.locked{height:100%;overflow:hidden}.scrollable{position:absolute;top:0;right:0;bottom:0;left:0;overflow:auto;-webkit-overflow-scrolling:touch}.scrollable .wrapper{height:100%}.ios .scrollable .wrapper{margin-bottom:2px}.toggle{display:none}.toggle-button{display:block}.backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:-1}.backdrop-paper{max-width:1200px;height:100%;margin-left:auto;margin-right:auto}.backdrop-paper:after{content:" ";display:block;height:100%;margin-left:262px}.overlay{width:0;height:0;z-index:4}.header,.overlay{position:fixed;top:0}.header{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;left:0;z-index:3;height:56px;padding:4px;overflow:hidden}.ios.standalone .header{position:absolute}.bar{display:table;max-width:1184px;margin-left:auto;margin-right:auto}.bar a{display:block}.no-js .bar .button-search{display:none}.bar .path .icon:before{vertical-align:-1.5px}.button{display:table-cell;vertical-align:top;width:1%}.button button{margin:0;padding:0}.button button:active:before{position:relative;top:0;left:0}.button .icon{display:inline-block;font-size:24px;padding:8px;margin:4px}.stretch{display:table;table-layout:fixed;width:100%}.header .stretch{padding:0 20px}.stretch .title{display:table-cell;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}.header .stretch .title{font-size:18px;padding:13px 0}.main{max-width:1200px;margin-left:auto;margin-right:auto}body,input{font-weight:400;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.no-fontface body,.no-fontface input,body,input{font-family:Helvetica Neue,Helvetica,Arial,sans-serif}.no-fontface code,.no-fontface kbd,.no-fontface pre,code,kbd,pre{font-family:Courier New,Courier,monospace}#toggle-drawer:checked~.main .drawer,.toggle-drawer .drawer{-webkit-transform:translateZ(0);transform:translateZ(0)}.no-csstransforms3d #toggle-drawer:checked~.main .drawer,.no-csstransforms3d .toggle-drawer .drawer{display:block}.project{-webkit-transition:none;transition:none}.project .logo img{-webkit-transition:box-shadow .4s;transition:box-shadow .4s}.repo a{-webkit-transition:box-shadow .4s,opacity .4s;transition:box-shadow .4s,opacity .4s}.drawer .toc a.current,.drawer .toc a:focus,.drawer .toc a:hover{color:#e84e40}.drawer .anchor a{border-left:2px solid #e84e40}.drawer .section{color:rgba(0,0,0,.54)}.ios.standalone .project:before{background:rgba(0,0,0,.12)}.project .logo img{background:#fff;border-radius:100%}.project:focus .logo img,.project:hover .logo img{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05)}.repo a{background:#00bfa5;color:#fff;border-radius:3px}.repo a:focus,.repo a:hover{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);opacity:.8}.repo a .count{background:rgba(0,0,0,.26);color:#fff;border-radius:0 3px 3px 0}.repo a .count:before{border-width:15px 5px 15px 0;border-color:transparent rgba(0,0,0,.26);border-style:solid}.drawer{width:262px;font-size:13px;line-height:1em}.ios .drawer{overflow:scroll;-webkit-overflow-scrolling:touch}.drawer .toc li a{display:block;padding:14.5px 24px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.drawer .toc li.anchor a{margin-left:12px;padding:10px 24px 10px 12px}.drawer .toc li ul{margin-left:12px}.drawer .current+ul{margin-bottom:9px}.drawer .section{display:block;padding:14.5px 24px}.drawer .scrollable{top:104px;z-index:-1}.drawer .scrollable .wrapper{height:auto;min-height:100%}.drawer .scrollable .wrapper hr{margin:12px 0;margin-right:auto}.drawer .scrollable .wrapper .toc{margin:12px 0}.project{display:block}.project .banner{display:table;width:100%;height:104px;padding:20px}.project .logo{display:table-cell;width:64px;padding-right:12px}.project .logo img{display:block;width:64px;height:64px}.project .name{display:table-cell;padding-left:4px;font-size:14px;line-height:1.25em;vertical-align:middle}.project .logo+.name{font-size:12px}.repo{margin:24px 0;text-align:center}.repo li{display:inline-block;padding-right:12px;white-space:nowrap}.repo li:last-child{padding-right:0}.repo a{display:inline-block;padding:0 10px 0 6px;font-size:12px;line-height:30px;height:30px}.repo a .icon{font-size:18px;vertical-align:-3px}.repo a .count{display:inline-block;position:relative;padding:0 8px 0 4px;margin:0 -10px 0 8px;font-size:12px}.repo a .count:before{content:" ";display:block;position:absolute;top:0;left:-5px}.no-js .repo a .count{display:none}.drawer .toc li a{font-weight:700}.drawer .toc li.anchor a{font-weight:400}.drawer .section,.repo a{font-weight:700}.repo a{text-transform:uppercase}.repo a .count{text-transform:none;font-weight:700}pre span{-webkit-transition:color .25s;transition:color .25s}.copyright a{-webkit-transition:color .25s;transition:color .25s}.ios.standalone .article{background:-webkit-linear-gradient(top,#fff 50%,#e84e40 0);background:linear-gradient(180deg,#fff 50%,#e84e40 0)}.ios.standalone .article .wrapper{background:-webkit-linear-gradient(top,#fff 50%,#fff 0);background:linear-gradient(180deg,#fff 50%,#fff 0)}.article a,.article h1,.article h2{color:#e84e40}.article code{background:#eee}.article kbd{color:#555;background-color:#fcfcfc;border:1px solid #ccc;border-bottom-color:#bbb;border-radius:3px;box-shadow:inset 0 -1px 0 #bbb}.article h1{border-bottom:1px solid rgba(0,0,0,.12)}.article a{border-bottom:1px dotted}.article a:focus,.article a:hover{color:#00bfa5}.article .headerlink{color:rgba(0,0,0,.26);border:none}.article table{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);border-radius:3px}.article table th{background:#ee7a70;color:#fff}.article table td{border-top:1px solid rgba(0,0,0,.05)}.article blockquote{border-left:2px solid rgba(0,0,0,.54);color:rgba(0,0,0,.54)}.footer{background:#e84e40;color:#fff}.footer a{border:none}.copyright{color:rgba(0,0,0,.54)}.pagination a .button,.pagination a .title{color:#fff}.pagination .direction{color:hsla(0,0%,100%,.7)}.admonition{background:#29b6f6;color:#fff}.admonition pre{background:hsla(0,0%,100%,.3)}.admonition.warning{background:#e84e40}.admonition a,.admonition a:hover{color:#fff}.article{font-size:14px;line-height:1.7em}.article:after{content:" ";display:block;clear:both}.article .wrapper{padding:116px 16px 92px}.ios.standalone .article{position:absolute;top:56px;right:0;bottom:0;left:0;overflow:auto;-webkit-overflow-scrolling:touch}.ios.standalone .article .wrapper{position:relative;min-height:100%;padding-top:60px;margin-bottom:2px}.article h1{font-size:24px;line-height:1.333334em;padding:20px 0 42px}.article h2{font-size:20px;line-height:1.4em;padding-top:92px;margin-top:-56px}.ios.standalone .article h2{padding-top:36px;margin:0}.article h3,.article h4{font-size:14px;padding-top:76px;margin-top:-56px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article .headerlink{float:right;margin-left:20px;font-size:14px}h1 .article .headerlink{display:none}.article ol,.article p,.article ul{margin-top:1.5em}.article li,.article li ol,.article li ul{margin-top:.75em}.article li{margin-left:18px}.article li p{display:inline}.article ul>li:before{content:"\e602";display:block;float:left;font-family:Icon;font-size:16px;width:1.2em;margin-left:-1.2em;vertical-align:-.1em}.article p>code{white-space:nowrap;padding:2px 4px}.article kbd{display:inline-block;padding:3px 5px;line-height:10px}.article hr{margin-top:1.5em}.article img{max-width:100%}.article pre{padding:16px;margin:1.5em -16px 0;line-height:1.5em;overflow:auto;-webkit-overflow-scrolling:touch}.article table{margin:3em 0 1.5em;font-size:13px;overflow:hidden}.no-js .article table{display:inline-block;max-width:100%;overflow:auto;-webkit-overflow-scrolling:touch}.article table th{min-width:100px;font-size:12px;text-align:left}.article table td,.article table th{padding:12px 16px;vertical-align:top}.article blockquote{padding-left:16px}.article .data{margin:1.5em -16px;padding:1.5em 0;overflow:auto;-webkit-overflow-scrolling:touch;text-align:center}.article .data table{display:inline-block;margin:0 16px;text-align:left}.footer{position:absolute;bottom:0;left:0;right:0;padding:0 4px}.copyright{margin:1.5em 0}.pagination{max-width:1184px;height:92px;padding:4px 0;margin-left:auto;margin-right:auto;overflow:hidden}.pagination a{display:block;height:100%}.pagination .next,.pagination .previous{position:relative;float:left;height:100%}.pagination .previous{width:25%}.pagination .previous .direction,.pagination .previous .stretch{display:none}.pagination .next{width:75%;text-align:right}.pagination .page{display:table;position:absolute;bottom:4px}.pagination .direction{display:block;position:absolute;bottom:40px;width:100%;font-size:15px;line-height:20px;padding:0 52px}.pagination .stretch{padding:0 4px}.pagination .stretch .title{font-size:18px;padding:11px 0 13px}.admonition{margin:20px -16px 0;padding:20px 16px}.admonition>:first-child{margin-top:0}.admonition .admonition-title{font-size:20px}.admonition .admonition-title:before{content:"\e611";display:block;float:left;font-family:Icon;font-size:24px;vertical-align:-.1em;margin-right:5px}.admonition.warning .admonition-title:before{content:"\e610"}.article h3{font-weight:700}.article h4{font-weight:400;font-style:italic}.article h2 a,.article h3 a,.article h4 a,.article h5 a,.article h6 a{font-weight:400;font-style:normal}.bar{-webkit-transform:translateZ(0);transform:translateZ(0);-webkit-transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1);transition:opacity .2s cubic-bezier(.75,0,.25,1),transform .4s cubic-bezier(.75,0,.25,1),-webkit-transform .4s cubic-bezier(.75,0,.25,1)}#toggle-search:checked~.header .bar,.toggle-search .bar{-webkit-transform:translate3d(0,-56px,0);transform:translate3d(0,-56px,0)}.bar.search .button-reset{-webkit-transform:scale(.5);transform:scale(.5);-webkit-transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1);transition:opacity .4s cubic-bezier(.1,.7,.1,1),transform .4s cubic-bezier(.1,.7,.1,1),-webkit-transform .4s cubic-bezier(.1,.7,.1,1);opacity:0}.bar.search.non-empty .button-reset{-webkit-transform:scale(1);transform:scale(1);opacity:1}.results{-webkit-transition:opacity .3s .1s,width 0s .4s,height 0s .4s;transition:opacity .3s .1s,width 0s .4s,height 0s .4s}#toggle-search:checked~.main .results,.toggle-search .results{-webkit-transition:opacity .4s,width 0s,height 0s;transition:opacity .4s,width 0s,height 0s}.results .list a{-webkit-transition:background .25s;transition:background .25s}.no-csstransforms3d .bar.default{display:table}.no-csstransforms3d .bar.search{display:none;margin-top:0}.no-csstransforms3d #toggle-search:checked~.header .bar.default,.no-csstransforms3d .toggle-search .bar.default{display:none}.no-csstransforms3d #toggle-search:checked~.header .bar.search,.no-csstransforms3d .toggle-search .bar.search{display:table}.bar.search{opacity:0}.bar.search .query{background:transparent;color:rgba(0,0,0,.87)}.bar.search .query::-webkit-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-moz-placeholder,.bar.search .query::-moz-placeholder{color:rgba(0,0,0,.26)}.bar.search .query:-ms-input-placeholder{color:rgba(0,0,0,.26)}.bar.search .button .icon:active{background:rgba(0,0,0,.12)}.results{box-shadow:0 4px 7px rgba(0,0,0,.23),0 8px 25px rgba(0,0,0,.05);background:#fff;color:rgba(0,0,0,.87);opacity:0}#toggle-search:checked~.main .results,.toggle-search .results{opacity:1}.results .meta{background:#e84e40;color:#fff}.results .list a{border-bottom:1px solid rgba(0,0,0,.12)}.results .list a:last-child{border-bottom:none}.results .list a:active{background:rgba(0,0,0,.12)}.result span{color:rgba(0,0,0,.54)}#toggle-search:checked~.header,.toggle-search .header{background:#fff;color:rgba(0,0,0,.54)}#toggle-search:checked~.header:before,.toggle-search .header:before{background:rgba(0,0,0,.54)}#toggle-search:checked~.header .bar.default,.toggle-search .header .bar.default{opacity:0}#toggle-search:checked~.header .bar.search,.toggle-search .header .bar.search{opacity:1}.bar.search{margin-top:8px}.bar.search .query{font-size:18px;padding:13px 0;margin:0;width:100%;height:48px}.bar.search .query::-ms-clear{display:none}.results{position:fixed;top:0;left:0;width:0;height:100%;z-index:2;overflow-y:scroll;-webkit-overflow-scrolling:touch}.results .scrollable{top:56px}#toggle-search:checked~.main .results,.toggle-search .results{width:100%;overflow-y:visible}.results .meta{font-weight:700}.results .meta strong{display:block;font-size:11px;max-width:1200px;margin-left:auto;margin-right:auto;padding:16px}.results .list a{display:block}.result{max-width:1200px;margin-left:auto;margin-right:auto;padding:12px 16px 16px}.result h1{line-height:24px}.result h1,.result span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.result span{font-size:12px}.no-csstransforms3d .results{display:none}.no-csstransforms3d #toggle-search:checked~.main .results,.no-csstransforms3d .toggle-search .results{display:block;overflow:auto}.meta{text-transform:uppercase;font-weight:700}@media only screen and (min-width:960px){.backdrop{background:#f2f2f2}.backdrop-paper:after{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05)}.button-menu{display:none}.drawer{float:left;height:auto;margin-bottom:96px;padding-top:80px}.drawer,.drawer .scrollable{position:static}.article{margin-left:262px}.footer{z-index:5}.copyright{margin-bottom:64px}.results{height:auto;top:64px}.results .scrollable{position:static;max-height:413px}}@media only screen and (max-width:959px){#toggle-drawer:checked~.overlay,.toggle-drawer .overlay{width:100%;height:100%}.drawer{-webkit-transform:translate3d(-262px,0,0);transform:translate3d(-262px,0,0);-webkit-transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:-webkit-transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1);transition:transform .25s cubic-bezier(.4,0,.2,1),-webkit-transform .25s cubic-bezier(.4,0,.2,1)}.no-csstransforms3d .drawer{display:none}.drawer{background:#fff}.project{box-shadow:0 1.5px 3px rgba(0,0,0,.24),0 3px 8px rgba(0,0,0,.05);background:#e84e40;color:#fff}.drawer{position:fixed;z-index:5}#toggle-search:checked~.main .results,.drawer,.toggle-search .results{height:100%}}@media only screen and (min-width:720px){.header{height:64px;padding:8px}.header .stretch{padding:0 16px}.header .stretch .title{font-size:20px;padding:12px 0}.project .name{margin:26px 0 0 5px}.article .wrapper{padding:128px 24px 96px}.article .data{margin:1.5em -24px}.article .data table{margin:0 24px}.article h2{padding-top:100px;margin-top:-64px}.ios.standalone .article h2{padding-top:28px;margin-top:8px}.article h3,.article h4{padding-top:84px;margin-top:-64px}.ios.standalone .article h3,.ios.standalone .article h4{padding-top:20px;margin-top:0}.article pre{padding:1.5em 24px;margin:1.5em -24px 0}.footer{padding:0 8px}.pagination{height:96px;padding:8px 0}.pagination .direction{padding:0 56px;bottom:40px}.pagination .stretch{padding:0 8px}.admonition{margin:20px -24px 0;padding:20px 24px}.bar.search .query{font-size:20px;padding:12px 0}.results .scrollable{top:64px}.results .meta strong{padding:16px 24px}.result{padding:16px 24px 20px}}@media only screen and (min-width:1200px){.header{width:100%}.drawer .scrollable .wrapper hr{width:48px}}@media only screen and (orientation:portrait){.ios.standalone .header{height:76px;padding-top:24px}.ios.standalone .header:before{content:" ";position:absolute;top:0;left:0;z-index:4;width:100%;height:20px}.ios.standalone .drawer .scrollable{top:124px}.ios.standalone .project{padding-top:20px}.ios.standalone .project:before{content:" ";position:absolute;top:0;left:0;z-index:4;width:100%;height:20px}.ios.standalone .article{position:absolute;top:76px;right:0;bottom:0;left:0}.ios.standalone .results .scrollable{top:76px}}@media only screen and (orientation:portrait) and (min-width:720px){.ios.standalone .header{height:84px;padding-top:28px}.ios.standalone .results .scrollable{top:84px}}@media only screen and (max-width:719px){.bar .path{display:none}}@media only screen and (max-width:479px){.button-github,.button-twitter{display:none}}@media only screen and (min-width:720px) and (max-width:959px){.header .stretch{padding:0 24px}}@media only screen and (min-width:480px){.pagination .next,.pagination .previous{width:50%}.pagination .previous .direction{display:block}.pagination .previous .stretch{display:table}}@media print{.drawer,.footer,.header,.headerlink{display:none}.article .wrapper{padding-top:0}.article pre,.article pre *{color:rgba(0,0,0,.87)!important}.article pre{border:1px solid rgba(0,0,0,.12)}.article table{border-radius:none;box-shadow:none}.article table th{color:#e84e40}} \ No newline at end of file diff --git a/material/assets/stylesheets/palettes-2d6c5d2926.css b/material/assets/stylesheets/palettes-2d6c5d2926.css deleted file mode 100644 index 576fdb724..000000000 --- a/material/assets/stylesheets/palettes-2d6c5d2926.css +++ /dev/null @@ -1 +0,0 @@ -@supports (-webkit-appearance:none){.palette-primary-red{background:#e84e40}}.palette-primary-red .footer,.palette-primary-red .header{background:#e84e40}.palette-primary-red .drawer .toc a.current,.palette-primary-red .drawer .toc a:focus,.palette-primary-red .drawer .toc a:hover{color:#e84e40}.palette-primary-red .drawer .anchor a{border-left:2px solid #e84e40}.ios.standalone .palette-primary-red .article{background:-webkit-linear-gradient(top,#fff 50%,#e84e40 0);background:linear-gradient(180deg,#fff 50%,#e84e40 0)}.palette-primary-red .article a,.palette-primary-red .article code,.palette-primary-red .article h1,.palette-primary-red .article h2{color:#e84e40}.palette-primary-red .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-red .article table th{background:#ee7a70}.palette-primary-red .results .meta{background:#e84e40}@supports (-webkit-appearance:none){.palette-primary-pink{background:#e91e63}}.palette-primary-pink .footer,.palette-primary-pink .header{background:#e91e63}.palette-primary-pink .drawer .toc a.current,.palette-primary-pink .drawer .toc a:focus,.palette-primary-pink .drawer .toc a:hover{color:#e91e63}.palette-primary-pink .drawer .anchor a{border-left:2px solid #e91e63}.ios.standalone .palette-primary-pink .article{background:-webkit-linear-gradient(top,#fff 50%,#e91e63 0);background:linear-gradient(180deg,#fff 50%,#e91e63 0)}.palette-primary-pink .article a,.palette-primary-pink .article code,.palette-primary-pink .article h1,.palette-primary-pink .article h2{color:#e91e63}.palette-primary-pink .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-pink .article table th{background:#ef568a}.palette-primary-pink .results .meta{background:#e91e63}@supports (-webkit-appearance:none){.palette-primary-purple{background:#ab47bc}}.palette-primary-purple .footer,.palette-primary-purple .header{background:#ab47bc}.palette-primary-purple .drawer .toc a.current,.palette-primary-purple .drawer .toc a:focus,.palette-primary-purple .drawer .toc a:hover{color:#ab47bc}.palette-primary-purple .drawer .anchor a{border-left:2px solid #ab47bc}.ios.standalone .palette-primary-purple .article{background:-webkit-linear-gradient(top,#fff 50%,#ab47bc 0);background:linear-gradient(180deg,#fff 50%,#ab47bc 0)}.palette-primary-purple .article a,.palette-primary-purple .article code,.palette-primary-purple .article h1,.palette-primary-purple .article h2{color:#ab47bc}.palette-primary-purple .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-purple .article table th{background:#c075cd}.palette-primary-purple .results .meta{background:#ab47bc}@supports (-webkit-appearance:none){.palette-primary-deep-purple{background:#7e57c2}}.palette-primary-deep-purple .footer,.palette-primary-deep-purple .header{background:#7e57c2}.palette-primary-deep-purple .drawer .toc a.current,.palette-primary-deep-purple .drawer .toc a:focus,.palette-primary-deep-purple .drawer .toc a:hover{color:#7e57c2}.palette-primary-deep-purple .drawer .anchor a{border-left:2px solid #7e57c2}.ios.standalone .palette-primary-deep-purple .article{background:-webkit-linear-gradient(top,#fff 50%,#7e57c2 0);background:linear-gradient(180deg,#fff 50%,#7e57c2 0)}.palette-primary-deep-purple .article a,.palette-primary-deep-purple .article code,.palette-primary-deep-purple .article h1,.palette-primary-deep-purple .article h2{color:#7e57c2}.palette-primary-deep-purple .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-deep-purple .article table th{background:#9e81d1}.palette-primary-deep-purple .results .meta{background:#7e57c2}@supports (-webkit-appearance:none){.palette-primary-indigo{background:#3f51b5}}.palette-primary-indigo .footer,.palette-primary-indigo .header{background:#3f51b5}.palette-primary-indigo .drawer .toc a.current,.palette-primary-indigo .drawer .toc a:focus,.palette-primary-indigo .drawer .toc a:hover{color:#3f51b5}.palette-primary-indigo .drawer .anchor a{border-left:2px solid #3f51b5}.ios.standalone .palette-primary-indigo .article{background:-webkit-linear-gradient(top,#fff 50%,#3f51b5 0);background:linear-gradient(180deg,#fff 50%,#3f51b5 0)}.palette-primary-indigo .article a,.palette-primary-indigo .article code,.palette-primary-indigo .article h1,.palette-primary-indigo .article h2{color:#3f51b5}.palette-primary-indigo .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-indigo .article table th{background:#6f7dc8}.palette-primary-indigo .results .meta{background:#3f51b5}@supports (-webkit-appearance:none){.palette-primary-blue{background:#2196f3}}.palette-primary-blue .footer,.palette-primary-blue .header{background:#2196f3}.palette-primary-blue .drawer .toc a.current,.palette-primary-blue .drawer .toc a:focus,.palette-primary-blue .drawer .toc a:hover{color:#2196f3}.palette-primary-blue .drawer .anchor a{border-left:2px solid #2196f3}.ios.standalone .palette-primary-blue .article{background:-webkit-linear-gradient(top,#fff 50%,#2196f3 0);background:linear-gradient(180deg,#fff 50%,#2196f3 0)}.palette-primary-blue .article a,.palette-primary-blue .article code,.palette-primary-blue .article h1,.palette-primary-blue .article h2{color:#2196f3}.palette-primary-blue .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-blue .article table th{background:#59b0f6}.palette-primary-blue .results .meta{background:#2196f3}@supports (-webkit-appearance:none){.palette-primary-light-blue{background:#03a9f4}}.palette-primary-light-blue .footer,.palette-primary-light-blue .header{background:#03a9f4}.palette-primary-light-blue .drawer .toc a.current,.palette-primary-light-blue .drawer .toc a:focus,.palette-primary-light-blue .drawer .toc a:hover{color:#03a9f4}.palette-primary-light-blue .drawer .anchor a{border-left:2px solid #03a9f4}.ios.standalone .palette-primary-light-blue .article{background:-webkit-linear-gradient(top,#fff 50%,#03a9f4 0);background:linear-gradient(180deg,#fff 50%,#03a9f4 0)}.palette-primary-light-blue .article a,.palette-primary-light-blue .article code,.palette-primary-light-blue .article h1,.palette-primary-light-blue .article h2{color:#03a9f4}.palette-primary-light-blue .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-light-blue .article table th{background:#42bff7}.palette-primary-light-blue .results .meta{background:#03a9f4}@supports (-webkit-appearance:none){.palette-primary-cyan{background:#00bcd4}}.palette-primary-cyan .footer,.palette-primary-cyan .header{background:#00bcd4}.palette-primary-cyan .drawer .toc a.current,.palette-primary-cyan .drawer .toc a:focus,.palette-primary-cyan .drawer .toc a:hover{color:#00bcd4}.palette-primary-cyan .drawer .anchor a{border-left:2px solid #00bcd4}.ios.standalone .palette-primary-cyan .article{background:-webkit-linear-gradient(top,#fff 50%,#00bcd4 0);background:linear-gradient(180deg,#fff 50%,#00bcd4 0)}.palette-primary-cyan .article a,.palette-primary-cyan .article code,.palette-primary-cyan .article h1,.palette-primary-cyan .article h2{color:#00bcd4}.palette-primary-cyan .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-cyan .article table th{background:#40cddf}.palette-primary-cyan .results .meta{background:#00bcd4}@supports (-webkit-appearance:none){.palette-primary-teal{background:#009688}}.palette-primary-teal .footer,.palette-primary-teal .header{background:#009688}.palette-primary-teal .drawer .toc a.current,.palette-primary-teal .drawer .toc a:focus,.palette-primary-teal .drawer .toc a:hover{color:#009688}.palette-primary-teal .drawer .anchor a{border-left:2px solid #009688}.ios.standalone .palette-primary-teal .article{background:-webkit-linear-gradient(top,#fff 50%,#009688 0);background:linear-gradient(180deg,#fff 50%,#009688 0)}.palette-primary-teal .article a,.palette-primary-teal .article code,.palette-primary-teal .article h1,.palette-primary-teal .article h2{color:#009688}.palette-primary-teal .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-teal .article table th{background:#40b0a6}.palette-primary-teal .results .meta{background:#009688}@supports (-webkit-appearance:none){.palette-primary-green{background:#259b24}}.palette-primary-green .footer,.palette-primary-green .header{background:#259b24}.palette-primary-green .drawer .toc a.current,.palette-primary-green .drawer .toc a:focus,.palette-primary-green .drawer .toc a:hover{color:#259b24}.palette-primary-green .drawer .anchor a{border-left:2px solid #259b24}.ios.standalone .palette-primary-green .article{background:-webkit-linear-gradient(top,#fff 50%,#259b24 0);background:linear-gradient(180deg,#fff 50%,#259b24 0)}.palette-primary-green .article a,.palette-primary-green .article code,.palette-primary-green .article h1,.palette-primary-green .article h2{color:#259b24}.palette-primary-green .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-green .article table th{background:#5cb45b}.palette-primary-green .results .meta{background:#259b24}@supports (-webkit-appearance:none){.palette-primary-light-green{background:#7cb342}}.palette-primary-light-green .footer,.palette-primary-light-green .header{background:#7cb342}.palette-primary-light-green .drawer .toc a.current,.palette-primary-light-green .drawer .toc a:focus,.palette-primary-light-green .drawer .toc a:hover{color:#7cb342}.palette-primary-light-green .drawer .anchor a{border-left:2px solid #7cb342}.ios.standalone .palette-primary-light-green .article{background:-webkit-linear-gradient(top,#fff 50%,#7cb342 0);background:linear-gradient(180deg,#fff 50%,#7cb342 0)}.palette-primary-light-green .article a,.palette-primary-light-green .article code,.palette-primary-light-green .article h1,.palette-primary-light-green .article h2{color:#7cb342}.palette-primary-light-green .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-light-green .article table th{background:#9dc671}.palette-primary-light-green .results .meta{background:#7cb342}@supports (-webkit-appearance:none){.palette-primary-lime{background:#c0ca33}}.palette-primary-lime .footer,.palette-primary-lime .header{background:#c0ca33}.palette-primary-lime .drawer .toc a.current,.palette-primary-lime .drawer .toc a:focus,.palette-primary-lime .drawer .toc a:hover{color:#c0ca33}.palette-primary-lime .drawer .anchor a{border-left:2px solid #c0ca33}.ios.standalone .palette-primary-lime .article{background:-webkit-linear-gradient(top,#fff 50%,#c0ca33 0);background:linear-gradient(180deg,#fff 50%,#c0ca33 0)}.palette-primary-lime .article a,.palette-primary-lime .article code,.palette-primary-lime .article h1,.palette-primary-lime .article h2{color:#c0ca33}.palette-primary-lime .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-lime .article table th{background:#d0d766}.palette-primary-lime .results .meta{background:#c0ca33}@supports (-webkit-appearance:none){.palette-primary-yellow{background:#f9a825}}.palette-primary-yellow .footer,.palette-primary-yellow .header{background:#f9a825}.palette-primary-yellow .drawer .toc a.current,.palette-primary-yellow .drawer .toc a:focus,.palette-primary-yellow .drawer .toc a:hover{color:#f9a825}.palette-primary-yellow .drawer .anchor a{border-left:2px solid #f9a825}.ios.standalone .palette-primary-yellow .article{background:-webkit-linear-gradient(top,#fff 50%,#f9a825 0);background:linear-gradient(180deg,#fff 50%,#f9a825 0)}.palette-primary-yellow .article a,.palette-primary-yellow .article code,.palette-primary-yellow .article h1,.palette-primary-yellow .article h2{color:#f9a825}.palette-primary-yellow .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-yellow .article table th{background:#fbbe5c}.palette-primary-yellow .results .meta{background:#f9a825}@supports (-webkit-appearance:none){.palette-primary-amber{background:#ffb300}}.palette-primary-amber .footer,.palette-primary-amber .header{background:#ffb300}.palette-primary-amber .drawer .toc a.current,.palette-primary-amber .drawer .toc a:focus,.palette-primary-amber .drawer .toc a:hover{color:#ffb300}.palette-primary-amber .drawer .anchor a{border-left:2px solid #ffb300}.ios.standalone .palette-primary-amber .article{background:-webkit-linear-gradient(top,#fff 50%,#ffb300 0);background:linear-gradient(180deg,#fff 50%,#ffb300 0)}.palette-primary-amber .article a,.palette-primary-amber .article code,.palette-primary-amber .article h1,.palette-primary-amber .article h2{color:#ffb300}.palette-primary-amber .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-amber .article table th{background:#ffc640}.palette-primary-amber .results .meta{background:#ffb300}@supports (-webkit-appearance:none){.palette-primary-orange{background:#fb8c00}}.palette-primary-orange .footer,.palette-primary-orange .header{background:#fb8c00}.palette-primary-orange .drawer .toc a.current,.palette-primary-orange .drawer .toc a:focus,.palette-primary-orange .drawer .toc a:hover{color:#fb8c00}.palette-primary-orange .drawer .anchor a{border-left:2px solid #fb8c00}.ios.standalone .palette-primary-orange .article{background:-webkit-linear-gradient(top,#fff 50%,#fb8c00 0);background:linear-gradient(180deg,#fff 50%,#fb8c00 0)}.palette-primary-orange .article a,.palette-primary-orange .article code,.palette-primary-orange .article h1,.palette-primary-orange .article h2{color:#fb8c00}.palette-primary-orange .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-orange .article table th{background:#fca940}.palette-primary-orange .results .meta{background:#fb8c00}@supports (-webkit-appearance:none){.palette-primary-deep-orange{background:#ff7043}}.palette-primary-deep-orange .footer,.palette-primary-deep-orange .header{background:#ff7043}.palette-primary-deep-orange .drawer .toc a.current,.palette-primary-deep-orange .drawer .toc a:focus,.palette-primary-deep-orange .drawer .toc a:hover{color:#ff7043}.palette-primary-deep-orange .drawer .anchor a{border-left:2px solid #ff7043}.ios.standalone .palette-primary-deep-orange .article{background:-webkit-linear-gradient(top,#fff 50%,#ff7043 0);background:linear-gradient(180deg,#fff 50%,#ff7043 0)}.palette-primary-deep-orange .article a,.palette-primary-deep-orange .article code,.palette-primary-deep-orange .article h1,.palette-primary-deep-orange .article h2{color:#ff7043}.palette-primary-deep-orange .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-deep-orange .article table th{background:#ff9472}.palette-primary-deep-orange .results .meta{background:#ff7043}@supports (-webkit-appearance:none){.palette-primary-brown{background:#795548}}.palette-primary-brown .footer,.palette-primary-brown .header{background:#795548}.palette-primary-brown .drawer .toc a.current,.palette-primary-brown .drawer .toc a:focus,.palette-primary-brown .drawer .toc a:hover{color:#795548}.palette-primary-brown .drawer .anchor a{border-left:2px solid #795548}.ios.standalone .palette-primary-brown .article{background:-webkit-linear-gradient(top,#fff 50%,#795548 0);background:linear-gradient(180deg,#fff 50%,#795548 0)}.palette-primary-brown .article a,.palette-primary-brown .article code,.palette-primary-brown .article h1,.palette-primary-brown .article h2{color:#795548}.palette-primary-brown .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-brown .article table th{background:#9b8076}.palette-primary-brown .results .meta{background:#795548}@supports (-webkit-appearance:none){.palette-primary-grey{background:#757575}}.palette-primary-grey .footer,.palette-primary-grey .header{background:#757575}.palette-primary-grey .drawer .toc a.current,.palette-primary-grey .drawer .toc a:focus,.palette-primary-grey .drawer .toc a:hover{color:#757575}.palette-primary-grey .drawer .anchor a{border-left:2px solid #757575}.ios.standalone .palette-primary-grey .article{background:-webkit-linear-gradient(top,#fff 50%,#757575 0);background:linear-gradient(180deg,#fff 50%,#757575 0)}.palette-primary-grey .article a,.palette-primary-grey .article code,.palette-primary-grey .article h1,.palette-primary-grey .article h2{color:#757575}.palette-primary-grey .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-grey .article table th{background:#989898}.palette-primary-grey .results .meta{background:#757575}@supports (-webkit-appearance:none){.palette-primary-blue-grey{background:#546e7a}}.palette-primary-blue-grey .footer,.palette-primary-blue-grey .header{background:#546e7a}.palette-primary-blue-grey .drawer .toc a.current,.palette-primary-blue-grey .drawer .toc a:focus,.palette-primary-blue-grey .drawer .toc a:hover{color:#546e7a}.palette-primary-blue-grey .drawer .anchor a{border-left:2px solid #546e7a}.ios.standalone .palette-primary-blue-grey .article{background:-webkit-linear-gradient(top,#fff 50%,#546e7a 0);background:linear-gradient(180deg,#fff 50%,#546e7a 0)}.palette-primary-blue-grey .article a,.palette-primary-blue-grey .article code,.palette-primary-blue-grey .article h1,.palette-primary-blue-grey .article h2{color:#546e7a}.palette-primary-blue-grey .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-blue-grey .article table th{background:#7f929b}.palette-primary-blue-grey .results .meta{background:#546e7a}.palette-accent-red .article a:focus,.palette-accent-red .article a:hover{color:#ff2d6f}.palette-accent-red .repo a{background:#ff2d6f}.palette-accent-pink .article a:focus,.palette-accent-pink .article a:hover{color:#f50057}.palette-accent-pink .repo a{background:#f50057}.palette-accent-purple .article a:focus,.palette-accent-purple .article a:hover{color:#e040fb}.palette-accent-purple .repo a{background:#e040fb}.palette-accent-deep-purple .article a:focus,.palette-accent-deep-purple .article a:hover{color:#7c4dff}.palette-accent-deep-purple .repo a{background:#7c4dff}.palette-accent-indigo .article a:focus,.palette-accent-indigo .article a:hover{color:#536dfe}.palette-accent-indigo .repo a{background:#536dfe}.palette-accent-blue .article a:focus,.palette-accent-blue .article a:hover{color:#448aff}.palette-accent-blue .repo a{background:#448aff}.palette-accent-light-blue .article a:focus,.palette-accent-light-blue .article a:hover{color:#0091ea}.palette-accent-light-blue .repo a{background:#0091ea}.palette-accent-cyan .article a:focus,.palette-accent-cyan .article a:hover{color:#00b8d4}.palette-accent-cyan .repo a{background:#00b8d4}.palette-accent-teal .article a:focus,.palette-accent-teal .article a:hover{color:#00bfa5}.palette-accent-teal .repo a{background:#00bfa5}.palette-accent-green .article a:focus,.palette-accent-green .article a:hover{color:#12c700}.palette-accent-green .repo a{background:#12c700}.palette-accent-light-green .article a:focus,.palette-accent-light-green .article a:hover{color:#64dd17}.palette-accent-light-green .repo a{background:#64dd17}.palette-accent-lime .article a:focus,.palette-accent-lime .article a:hover{color:#aeea00}.palette-accent-lime .repo a{background:#aeea00}.palette-accent-yellow .article a:focus,.palette-accent-yellow .article a:hover{color:#ffd600}.palette-accent-yellow .repo a{background:#ffd600}.palette-accent-amber .article a:focus,.palette-accent-amber .article a:hover{color:#ffab00}.palette-accent-amber .repo a{background:#ffab00}.palette-accent-orange .article a:focus,.palette-accent-orange .article a:hover{color:#ff9100}.palette-accent-orange .repo a{background:#ff9100}.palette-accent-deep-orange .article a:focus,.palette-accent-deep-orange .article a:hover{color:#ff6e40}.palette-accent-deep-orange .repo a{background:#ff6e40}@media only screen and (max-width:959px){.palette-primary-red .project{background:#e84e40}.palette-primary-pink .project{background:#e91e63}.palette-primary-purple .project{background:#ab47bc}.palette-primary-deep-purple .project{background:#7e57c2}.palette-primary-indigo .project{background:#3f51b5}.palette-primary-blue .project{background:#2196f3}.palette-primary-light-blue .project{background:#03a9f4}.palette-primary-cyan .project{background:#00bcd4}.palette-primary-teal .project{background:#009688}.palette-primary-green .project{background:#259b24}.palette-primary-light-green .project{background:#7cb342}.palette-primary-lime .project{background:#c0ca33}.palette-primary-yellow .project{background:#f9a825}.palette-primary-amber .project{background:#ffb300}.palette-primary-orange .project{background:#fb8c00}.palette-primary-deep-orange .project{background:#ff7043}.palette-primary-brown .project{background:#795548}.palette-primary-grey .project{background:#757575}.palette-primary-blue-grey .project{background:#546e7a}} \ No newline at end of file diff --git a/material/assets/stylesheets/palettes.css b/material/assets/stylesheets/palettes.css deleted file mode 100644 index 576fdb724..000000000 --- a/material/assets/stylesheets/palettes.css +++ /dev/null @@ -1 +0,0 @@ -@supports (-webkit-appearance:none){.palette-primary-red{background:#e84e40}}.palette-primary-red .footer,.palette-primary-red .header{background:#e84e40}.palette-primary-red .drawer .toc a.current,.palette-primary-red .drawer .toc a:focus,.palette-primary-red .drawer .toc a:hover{color:#e84e40}.palette-primary-red .drawer .anchor a{border-left:2px solid #e84e40}.ios.standalone .palette-primary-red .article{background:-webkit-linear-gradient(top,#fff 50%,#e84e40 0);background:linear-gradient(180deg,#fff 50%,#e84e40 0)}.palette-primary-red .article a,.palette-primary-red .article code,.palette-primary-red .article h1,.palette-primary-red .article h2{color:#e84e40}.palette-primary-red .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-red .article table th{background:#ee7a70}.palette-primary-red .results .meta{background:#e84e40}@supports (-webkit-appearance:none){.palette-primary-pink{background:#e91e63}}.palette-primary-pink .footer,.palette-primary-pink .header{background:#e91e63}.palette-primary-pink .drawer .toc a.current,.palette-primary-pink .drawer .toc a:focus,.palette-primary-pink .drawer .toc a:hover{color:#e91e63}.palette-primary-pink .drawer .anchor a{border-left:2px solid #e91e63}.ios.standalone .palette-primary-pink .article{background:-webkit-linear-gradient(top,#fff 50%,#e91e63 0);background:linear-gradient(180deg,#fff 50%,#e91e63 0)}.palette-primary-pink .article a,.palette-primary-pink .article code,.palette-primary-pink .article h1,.palette-primary-pink .article h2{color:#e91e63}.palette-primary-pink .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-pink .article table th{background:#ef568a}.palette-primary-pink .results .meta{background:#e91e63}@supports (-webkit-appearance:none){.palette-primary-purple{background:#ab47bc}}.palette-primary-purple .footer,.palette-primary-purple .header{background:#ab47bc}.palette-primary-purple .drawer .toc a.current,.palette-primary-purple .drawer .toc a:focus,.palette-primary-purple .drawer .toc a:hover{color:#ab47bc}.palette-primary-purple .drawer .anchor a{border-left:2px solid #ab47bc}.ios.standalone .palette-primary-purple .article{background:-webkit-linear-gradient(top,#fff 50%,#ab47bc 0);background:linear-gradient(180deg,#fff 50%,#ab47bc 0)}.palette-primary-purple .article a,.palette-primary-purple .article code,.palette-primary-purple .article h1,.palette-primary-purple .article h2{color:#ab47bc}.palette-primary-purple .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-purple .article table th{background:#c075cd}.palette-primary-purple .results .meta{background:#ab47bc}@supports (-webkit-appearance:none){.palette-primary-deep-purple{background:#7e57c2}}.palette-primary-deep-purple .footer,.palette-primary-deep-purple .header{background:#7e57c2}.palette-primary-deep-purple .drawer .toc a.current,.palette-primary-deep-purple .drawer .toc a:focus,.palette-primary-deep-purple .drawer .toc a:hover{color:#7e57c2}.palette-primary-deep-purple .drawer .anchor a{border-left:2px solid #7e57c2}.ios.standalone .palette-primary-deep-purple .article{background:-webkit-linear-gradient(top,#fff 50%,#7e57c2 0);background:linear-gradient(180deg,#fff 50%,#7e57c2 0)}.palette-primary-deep-purple .article a,.palette-primary-deep-purple .article code,.palette-primary-deep-purple .article h1,.palette-primary-deep-purple .article h2{color:#7e57c2}.palette-primary-deep-purple .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-deep-purple .article table th{background:#9e81d1}.palette-primary-deep-purple .results .meta{background:#7e57c2}@supports (-webkit-appearance:none){.palette-primary-indigo{background:#3f51b5}}.palette-primary-indigo .footer,.palette-primary-indigo .header{background:#3f51b5}.palette-primary-indigo .drawer .toc a.current,.palette-primary-indigo .drawer .toc a:focus,.palette-primary-indigo .drawer .toc a:hover{color:#3f51b5}.palette-primary-indigo .drawer .anchor a{border-left:2px solid #3f51b5}.ios.standalone .palette-primary-indigo .article{background:-webkit-linear-gradient(top,#fff 50%,#3f51b5 0);background:linear-gradient(180deg,#fff 50%,#3f51b5 0)}.palette-primary-indigo .article a,.palette-primary-indigo .article code,.palette-primary-indigo .article h1,.palette-primary-indigo .article h2{color:#3f51b5}.palette-primary-indigo .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-indigo .article table th{background:#6f7dc8}.palette-primary-indigo .results .meta{background:#3f51b5}@supports (-webkit-appearance:none){.palette-primary-blue{background:#2196f3}}.palette-primary-blue .footer,.palette-primary-blue .header{background:#2196f3}.palette-primary-blue .drawer .toc a.current,.palette-primary-blue .drawer .toc a:focus,.palette-primary-blue .drawer .toc a:hover{color:#2196f3}.palette-primary-blue .drawer .anchor a{border-left:2px solid #2196f3}.ios.standalone .palette-primary-blue .article{background:-webkit-linear-gradient(top,#fff 50%,#2196f3 0);background:linear-gradient(180deg,#fff 50%,#2196f3 0)}.palette-primary-blue .article a,.palette-primary-blue .article code,.palette-primary-blue .article h1,.palette-primary-blue .article h2{color:#2196f3}.palette-primary-blue .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-blue .article table th{background:#59b0f6}.palette-primary-blue .results .meta{background:#2196f3}@supports (-webkit-appearance:none){.palette-primary-light-blue{background:#03a9f4}}.palette-primary-light-blue .footer,.palette-primary-light-blue .header{background:#03a9f4}.palette-primary-light-blue .drawer .toc a.current,.palette-primary-light-blue .drawer .toc a:focus,.palette-primary-light-blue .drawer .toc a:hover{color:#03a9f4}.palette-primary-light-blue .drawer .anchor a{border-left:2px solid #03a9f4}.ios.standalone .palette-primary-light-blue .article{background:-webkit-linear-gradient(top,#fff 50%,#03a9f4 0);background:linear-gradient(180deg,#fff 50%,#03a9f4 0)}.palette-primary-light-blue .article a,.palette-primary-light-blue .article code,.palette-primary-light-blue .article h1,.palette-primary-light-blue .article h2{color:#03a9f4}.palette-primary-light-blue .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-light-blue .article table th{background:#42bff7}.palette-primary-light-blue .results .meta{background:#03a9f4}@supports (-webkit-appearance:none){.palette-primary-cyan{background:#00bcd4}}.palette-primary-cyan .footer,.palette-primary-cyan .header{background:#00bcd4}.palette-primary-cyan .drawer .toc a.current,.palette-primary-cyan .drawer .toc a:focus,.palette-primary-cyan .drawer .toc a:hover{color:#00bcd4}.palette-primary-cyan .drawer .anchor a{border-left:2px solid #00bcd4}.ios.standalone .palette-primary-cyan .article{background:-webkit-linear-gradient(top,#fff 50%,#00bcd4 0);background:linear-gradient(180deg,#fff 50%,#00bcd4 0)}.palette-primary-cyan .article a,.palette-primary-cyan .article code,.palette-primary-cyan .article h1,.palette-primary-cyan .article h2{color:#00bcd4}.palette-primary-cyan .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-cyan .article table th{background:#40cddf}.palette-primary-cyan .results .meta{background:#00bcd4}@supports (-webkit-appearance:none){.palette-primary-teal{background:#009688}}.palette-primary-teal .footer,.palette-primary-teal .header{background:#009688}.palette-primary-teal .drawer .toc a.current,.palette-primary-teal .drawer .toc a:focus,.palette-primary-teal .drawer .toc a:hover{color:#009688}.palette-primary-teal .drawer .anchor a{border-left:2px solid #009688}.ios.standalone .palette-primary-teal .article{background:-webkit-linear-gradient(top,#fff 50%,#009688 0);background:linear-gradient(180deg,#fff 50%,#009688 0)}.palette-primary-teal .article a,.palette-primary-teal .article code,.palette-primary-teal .article h1,.palette-primary-teal .article h2{color:#009688}.palette-primary-teal .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-teal .article table th{background:#40b0a6}.palette-primary-teal .results .meta{background:#009688}@supports (-webkit-appearance:none){.palette-primary-green{background:#259b24}}.palette-primary-green .footer,.palette-primary-green .header{background:#259b24}.palette-primary-green .drawer .toc a.current,.palette-primary-green .drawer .toc a:focus,.palette-primary-green .drawer .toc a:hover{color:#259b24}.palette-primary-green .drawer .anchor a{border-left:2px solid #259b24}.ios.standalone .palette-primary-green .article{background:-webkit-linear-gradient(top,#fff 50%,#259b24 0);background:linear-gradient(180deg,#fff 50%,#259b24 0)}.palette-primary-green .article a,.palette-primary-green .article code,.palette-primary-green .article h1,.palette-primary-green .article h2{color:#259b24}.palette-primary-green .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-green .article table th{background:#5cb45b}.palette-primary-green .results .meta{background:#259b24}@supports (-webkit-appearance:none){.palette-primary-light-green{background:#7cb342}}.palette-primary-light-green .footer,.palette-primary-light-green .header{background:#7cb342}.palette-primary-light-green .drawer .toc a.current,.palette-primary-light-green .drawer .toc a:focus,.palette-primary-light-green .drawer .toc a:hover{color:#7cb342}.palette-primary-light-green .drawer .anchor a{border-left:2px solid #7cb342}.ios.standalone .palette-primary-light-green .article{background:-webkit-linear-gradient(top,#fff 50%,#7cb342 0);background:linear-gradient(180deg,#fff 50%,#7cb342 0)}.palette-primary-light-green .article a,.palette-primary-light-green .article code,.palette-primary-light-green .article h1,.palette-primary-light-green .article h2{color:#7cb342}.palette-primary-light-green .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-light-green .article table th{background:#9dc671}.palette-primary-light-green .results .meta{background:#7cb342}@supports (-webkit-appearance:none){.palette-primary-lime{background:#c0ca33}}.palette-primary-lime .footer,.palette-primary-lime .header{background:#c0ca33}.palette-primary-lime .drawer .toc a.current,.palette-primary-lime .drawer .toc a:focus,.palette-primary-lime .drawer .toc a:hover{color:#c0ca33}.palette-primary-lime .drawer .anchor a{border-left:2px solid #c0ca33}.ios.standalone .palette-primary-lime .article{background:-webkit-linear-gradient(top,#fff 50%,#c0ca33 0);background:linear-gradient(180deg,#fff 50%,#c0ca33 0)}.palette-primary-lime .article a,.palette-primary-lime .article code,.palette-primary-lime .article h1,.palette-primary-lime .article h2{color:#c0ca33}.palette-primary-lime .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-lime .article table th{background:#d0d766}.palette-primary-lime .results .meta{background:#c0ca33}@supports (-webkit-appearance:none){.palette-primary-yellow{background:#f9a825}}.palette-primary-yellow .footer,.palette-primary-yellow .header{background:#f9a825}.palette-primary-yellow .drawer .toc a.current,.palette-primary-yellow .drawer .toc a:focus,.palette-primary-yellow .drawer .toc a:hover{color:#f9a825}.palette-primary-yellow .drawer .anchor a{border-left:2px solid #f9a825}.ios.standalone .palette-primary-yellow .article{background:-webkit-linear-gradient(top,#fff 50%,#f9a825 0);background:linear-gradient(180deg,#fff 50%,#f9a825 0)}.palette-primary-yellow .article a,.palette-primary-yellow .article code,.palette-primary-yellow .article h1,.palette-primary-yellow .article h2{color:#f9a825}.palette-primary-yellow .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-yellow .article table th{background:#fbbe5c}.palette-primary-yellow .results .meta{background:#f9a825}@supports (-webkit-appearance:none){.palette-primary-amber{background:#ffb300}}.palette-primary-amber .footer,.palette-primary-amber .header{background:#ffb300}.palette-primary-amber .drawer .toc a.current,.palette-primary-amber .drawer .toc a:focus,.palette-primary-amber .drawer .toc a:hover{color:#ffb300}.palette-primary-amber .drawer .anchor a{border-left:2px solid #ffb300}.ios.standalone .palette-primary-amber .article{background:-webkit-linear-gradient(top,#fff 50%,#ffb300 0);background:linear-gradient(180deg,#fff 50%,#ffb300 0)}.palette-primary-amber .article a,.palette-primary-amber .article code,.palette-primary-amber .article h1,.palette-primary-amber .article h2{color:#ffb300}.palette-primary-amber .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-amber .article table th{background:#ffc640}.palette-primary-amber .results .meta{background:#ffb300}@supports (-webkit-appearance:none){.palette-primary-orange{background:#fb8c00}}.palette-primary-orange .footer,.palette-primary-orange .header{background:#fb8c00}.palette-primary-orange .drawer .toc a.current,.palette-primary-orange .drawer .toc a:focus,.palette-primary-orange .drawer .toc a:hover{color:#fb8c00}.palette-primary-orange .drawer .anchor a{border-left:2px solid #fb8c00}.ios.standalone .palette-primary-orange .article{background:-webkit-linear-gradient(top,#fff 50%,#fb8c00 0);background:linear-gradient(180deg,#fff 50%,#fb8c00 0)}.palette-primary-orange .article a,.palette-primary-orange .article code,.palette-primary-orange .article h1,.palette-primary-orange .article h2{color:#fb8c00}.palette-primary-orange .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-orange .article table th{background:#fca940}.palette-primary-orange .results .meta{background:#fb8c00}@supports (-webkit-appearance:none){.palette-primary-deep-orange{background:#ff7043}}.palette-primary-deep-orange .footer,.palette-primary-deep-orange .header{background:#ff7043}.palette-primary-deep-orange .drawer .toc a.current,.palette-primary-deep-orange .drawer .toc a:focus,.palette-primary-deep-orange .drawer .toc a:hover{color:#ff7043}.palette-primary-deep-orange .drawer .anchor a{border-left:2px solid #ff7043}.ios.standalone .palette-primary-deep-orange .article{background:-webkit-linear-gradient(top,#fff 50%,#ff7043 0);background:linear-gradient(180deg,#fff 50%,#ff7043 0)}.palette-primary-deep-orange .article a,.palette-primary-deep-orange .article code,.palette-primary-deep-orange .article h1,.palette-primary-deep-orange .article h2{color:#ff7043}.palette-primary-deep-orange .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-deep-orange .article table th{background:#ff9472}.palette-primary-deep-orange .results .meta{background:#ff7043}@supports (-webkit-appearance:none){.palette-primary-brown{background:#795548}}.palette-primary-brown .footer,.palette-primary-brown .header{background:#795548}.palette-primary-brown .drawer .toc a.current,.palette-primary-brown .drawer .toc a:focus,.palette-primary-brown .drawer .toc a:hover{color:#795548}.palette-primary-brown .drawer .anchor a{border-left:2px solid #795548}.ios.standalone .palette-primary-brown .article{background:-webkit-linear-gradient(top,#fff 50%,#795548 0);background:linear-gradient(180deg,#fff 50%,#795548 0)}.palette-primary-brown .article a,.palette-primary-brown .article code,.palette-primary-brown .article h1,.palette-primary-brown .article h2{color:#795548}.palette-primary-brown .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-brown .article table th{background:#9b8076}.palette-primary-brown .results .meta{background:#795548}@supports (-webkit-appearance:none){.palette-primary-grey{background:#757575}}.palette-primary-grey .footer,.palette-primary-grey .header{background:#757575}.palette-primary-grey .drawer .toc a.current,.palette-primary-grey .drawer .toc a:focus,.palette-primary-grey .drawer .toc a:hover{color:#757575}.palette-primary-grey .drawer .anchor a{border-left:2px solid #757575}.ios.standalone .palette-primary-grey .article{background:-webkit-linear-gradient(top,#fff 50%,#757575 0);background:linear-gradient(180deg,#fff 50%,#757575 0)}.palette-primary-grey .article a,.palette-primary-grey .article code,.palette-primary-grey .article h1,.palette-primary-grey .article h2{color:#757575}.palette-primary-grey .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-grey .article table th{background:#989898}.palette-primary-grey .results .meta{background:#757575}@supports (-webkit-appearance:none){.palette-primary-blue-grey{background:#546e7a}}.palette-primary-blue-grey .footer,.palette-primary-blue-grey .header{background:#546e7a}.palette-primary-blue-grey .drawer .toc a.current,.palette-primary-blue-grey .drawer .toc a:focus,.palette-primary-blue-grey .drawer .toc a:hover{color:#546e7a}.palette-primary-blue-grey .drawer .anchor a{border-left:2px solid #546e7a}.ios.standalone .palette-primary-blue-grey .article{background:-webkit-linear-gradient(top,#fff 50%,#546e7a 0);background:linear-gradient(180deg,#fff 50%,#546e7a 0)}.palette-primary-blue-grey .article a,.palette-primary-blue-grey .article code,.palette-primary-blue-grey .article h1,.palette-primary-blue-grey .article h2{color:#546e7a}.palette-primary-blue-grey .article .headerlink{color:rgba(0,0,0,.26)}.palette-primary-blue-grey .article table th{background:#7f929b}.palette-primary-blue-grey .results .meta{background:#546e7a}.palette-accent-red .article a:focus,.palette-accent-red .article a:hover{color:#ff2d6f}.palette-accent-red .repo a{background:#ff2d6f}.palette-accent-pink .article a:focus,.palette-accent-pink .article a:hover{color:#f50057}.palette-accent-pink .repo a{background:#f50057}.palette-accent-purple .article a:focus,.palette-accent-purple .article a:hover{color:#e040fb}.palette-accent-purple .repo a{background:#e040fb}.palette-accent-deep-purple .article a:focus,.palette-accent-deep-purple .article a:hover{color:#7c4dff}.palette-accent-deep-purple .repo a{background:#7c4dff}.palette-accent-indigo .article a:focus,.palette-accent-indigo .article a:hover{color:#536dfe}.palette-accent-indigo .repo a{background:#536dfe}.palette-accent-blue .article a:focus,.palette-accent-blue .article a:hover{color:#448aff}.palette-accent-blue .repo a{background:#448aff}.palette-accent-light-blue .article a:focus,.palette-accent-light-blue .article a:hover{color:#0091ea}.palette-accent-light-blue .repo a{background:#0091ea}.palette-accent-cyan .article a:focus,.palette-accent-cyan .article a:hover{color:#00b8d4}.palette-accent-cyan .repo a{background:#00b8d4}.palette-accent-teal .article a:focus,.palette-accent-teal .article a:hover{color:#00bfa5}.palette-accent-teal .repo a{background:#00bfa5}.palette-accent-green .article a:focus,.palette-accent-green .article a:hover{color:#12c700}.palette-accent-green .repo a{background:#12c700}.palette-accent-light-green .article a:focus,.palette-accent-light-green .article a:hover{color:#64dd17}.palette-accent-light-green .repo a{background:#64dd17}.palette-accent-lime .article a:focus,.palette-accent-lime .article a:hover{color:#aeea00}.palette-accent-lime .repo a{background:#aeea00}.palette-accent-yellow .article a:focus,.palette-accent-yellow .article a:hover{color:#ffd600}.palette-accent-yellow .repo a{background:#ffd600}.palette-accent-amber .article a:focus,.palette-accent-amber .article a:hover{color:#ffab00}.palette-accent-amber .repo a{background:#ffab00}.palette-accent-orange .article a:focus,.palette-accent-orange .article a:hover{color:#ff9100}.palette-accent-orange .repo a{background:#ff9100}.palette-accent-deep-orange .article a:focus,.palette-accent-deep-orange .article a:hover{color:#ff6e40}.palette-accent-deep-orange .repo a{background:#ff6e40}@media only screen and (max-width:959px){.palette-primary-red .project{background:#e84e40}.palette-primary-pink .project{background:#e91e63}.palette-primary-purple .project{background:#ab47bc}.palette-primary-deep-purple .project{background:#7e57c2}.palette-primary-indigo .project{background:#3f51b5}.palette-primary-blue .project{background:#2196f3}.palette-primary-light-blue .project{background:#03a9f4}.palette-primary-cyan .project{background:#00bcd4}.palette-primary-teal .project{background:#009688}.palette-primary-green .project{background:#259b24}.palette-primary-light-green .project{background:#7cb342}.palette-primary-lime .project{background:#c0ca33}.palette-primary-yellow .project{background:#f9a825}.palette-primary-amber .project{background:#ffb300}.palette-primary-orange .project{background:#fb8c00}.palette-primary-deep-orange .project{background:#ff7043}.palette-primary-brown .project{background:#795548}.palette-primary-grey .project{background:#757575}.palette-primary-blue-grey .project{background:#546e7a}} \ No newline at end of file diff --git a/material/base.html b/material/base.html index 097b92805..ad183eb14 100644 --- a/material/base.html +++ b/material/base.html @@ -1,180 +1,120 @@ +{% import "partials/i18n.html" as i18n %} - - - - - + - - - {% block htmltitle %} - {% if page_title %} - {{ page_title }} - {{ site_name }} - {% elif page_description %} - {{ site_name }} - {{ page_description }} + {% block site_meta %} + + + {% if config.site_description %} + + {% endif %} + {% if page.canonical_url %} + + {% endif %} + {% if config.site_author %} + + {% endif %} + {% if config.site_favicon %} + {% else %} - {{ site_name }} + {% endif %} - {% if page_description %} - - {% endif %} - {% if canonical_url %} - - {% endif %} - {% if site_author %} - + + {% endblock %} + {% block htmltitle %} + {% if page.title %} + {{ page.title }} - {{ config.site_name }} + {% elif config.site_description %} + {{ config.site_name }} - {{ config.site_description }} + {% else %} + {{ config.site_name }} {% endif %} {% endblock %} - - - - - - - {% if config.extra.logo %} - - {% endif %} - {% set favicon = favicon | default("assets/images/favicon-e565ddfa3b.ico", true) %} - - - - - {% if config.extra.palette %} - - {% endif %} - {% if config.extra.font != "none" %} - {% set text = config.extra.get("font", {}).text | default("Ubuntu") %} - {% set code = config.extra.get("font", {}).code | default("Ubuntu Mono") %} - {% set font = text + ':400,700|' + code | replace(' ', '+') %} - - - {% endif %} - {% for path in extra_css %} - - {% endfor %} - + {% block libs %} + + {% endblock %} + {% block fonts %} + {% include "partials/fonts.html" %} + {% endblock %} + {% block styles %} + + {% if config.extra.palette %} + + {% endif %} + {% for path in extra_css %} + + {% endfor %} + {% endblock %} {% block extrahead %}{% endblock %} {% set palette = config.extra.get("palette", {}) %} - {% set primary = palette.primary | replace(' ', '-') | lower %} - {% set accent = palette.accent | replace(' ', '-') | lower %} - - {% if repo_name == "GitHub" and repo_url %} - {% set repo_id = repo_url | replace("https://github.com/", "") %} - {% if repo_id[-1:] == "/" %} - {% set repo_id = repo_id[:-1] %} - {% endif %} - {% endif %} -
-
-
- - - -
- {% include "header.html" %} -
-
- {% set h1 = "\x3ch1 id=" in content %} -
- {% include "drawer.html" %} -
-
-
- {% if not h1 %} -

{{ page_title | default(site_name, true)}}

- {% endif %} - {{ content }} - - {% block footer %} -
- {% include "footer.html" %} -
{% endblock %} -
-
-
-
-
-
-
+
+
+ {% if config.edit_uri %} + edit + {% endif %} + {% block content %} + {% if not "\x3ch1 id=" in page.content %} +

{{ page.title | default(config.site_name, true)}}

+ {% endif %} + {{ page.content }} + {% endblock %} +
-
-
- - - {% for path in extra_javascript %} - - {% endfor %} - {% if google_analytics %} - - {% endif %} + + {% block footer %} + {% include "partials/footer.html" %} + {% endblock %} + + {% block scripts %} + + + {% for path in extra_javascript %} + + {% endfor %} + {% endblock %} + {% block analytics %} + {% if config.google_analytics %} + + {% endif %} + {% endblock %} - \ No newline at end of file + diff --git a/material/drawer.html b/material/drawer.html deleted file mode 100644 index af72b35d0..000000000 --- a/material/drawer.html +++ /dev/null @@ -1,81 +0,0 @@ - \ No newline at end of file diff --git a/material/footer.html b/material/footer.html deleted file mode 100644 index 660b28f67..000000000 --- a/material/footer.html +++ /dev/null @@ -1,42 +0,0 @@ -{% if include_next_prev %} - -{% endif %} \ No newline at end of file diff --git a/material/header.html b/material/header.html deleted file mode 100644 index f2ea2340e..000000000 --- a/material/header.html +++ /dev/null @@ -1,54 +0,0 @@ - \ No newline at end of file diff --git a/material/main.html b/material/main.html new file mode 100644 index 000000000..94d9808cc --- /dev/null +++ b/material/main.html @@ -0,0 +1 @@ +{% extends "base.html" %} diff --git a/material/manifest.json b/material/manifest.json deleted file mode 100644 index 0b1a84b7c..000000000 --- a/material/manifest.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "assets/images/favicon.ico": "assets/images/favicon-e565ddfa3b.ico", - "assets/javascripts/application.js": "assets/javascripts/application-82b5011116.js", - "assets/javascripts/modernizr.js": "assets/javascripts/modernizr-2216498cab.js", - "assets/stylesheets/application.css": "assets/stylesheets/application-e576885f03.css", - "assets/stylesheets/palettes.css": "assets/stylesheets/palettes-2d6c5d2926.css" -} \ No newline at end of file diff --git a/material/nav.html b/material/nav.html deleted file mode 100644 index c926c085b..000000000 --- a/material/nav.html +++ /dev/null @@ -1,32 +0,0 @@ -{% if nav_item.children %} -
  • - {{ nav_item.title }} -
      - {% for nav_item in nav_item.children %} - {% include "nav.html" %} - {% endfor %} -
    -
  • -{% else %} -
  • - - {{ nav_item.title }} - - {% if nav_item == current_page %} - {% if h1 %} - {% set toc = (toc | first).children %} - {% endif %} - {% if toc and (toc | first) %} - - {% endif %} - {% endif %} -
  • -{% endif %} \ No newline at end of file diff --git a/material/partials/fonts.html b/material/partials/fonts.html new file mode 100644 index 000000000..39f7aea82 --- /dev/null +++ b/material/partials/fonts.html @@ -0,0 +1,8 @@ +{% if config.extra.font != "none" %} + {% set text = config.extra.get("font", {}).text | default("Roboto") %} + {% set code = config.extra.get("font", {}).code | default("Roboto Mono") %} + {% set font = text + ':300,400,400i,700|' + code | replace(' ', '+') %} + + +{% endif %} + diff --git a/material/partials/footer.html b/material/partials/footer.html new file mode 100644 index 000000000..5a063b2e2 --- /dev/null +++ b/material/partials/footer.html @@ -0,0 +1,58 @@ +{% import "partials/i18n.html" as i18n %} + diff --git a/material/partials/header.html b/material/partials/header.html new file mode 100644 index 000000000..6c99deafb --- /dev/null +++ b/material/partials/header.html @@ -0,0 +1,43 @@ +
    + +
    diff --git a/material/partials/i18n.html b/material/partials/i18n.html new file mode 100644 index 000000000..bf43cf588 --- /dev/null +++ b/material/partials/i18n.html @@ -0,0 +1,8 @@ +{% macro t(key) %}{{ { + "edit.link.title": "Edit this page", + "footer.previous": "Previous", + "footer.next": "Next", + "search.placeholder": "Search", + "source.link.title": "Go to repository", + "toc.title": "Table of contents" +}[key] }}{% endmacro %} diff --git a/material/partials/nav-item.html b/material/partials/nav-item.html new file mode 100644 index 000000000..651c60120 --- /dev/null +++ b/material/partials/nav-item.html @@ -0,0 +1,55 @@ +{% if nav_item.children %} +
  • + {% if nav_item.active %} + + {% else %} + + {% endif %} + + +
  • +{% elif nav_item == page %} +
  • + {% set toc_ = page.toc %} + + {% if "\x3ch1 id=" in page.content %} + {% set toc_ = (toc_ | first).children %} + {% endif %} + {% if toc_ and (toc_ | first) %} + + {% endif %} + + {{ nav_item.title }} + + {% if page.toc %} + {% include "partials/toc.html" %} + {% endif %} +
  • +{% else %} +
  • + {% if nav_item.active %} + + {{ nav_item.title }} + + {% else %} + + {{ nav_item.title }} + + {% endif %} +
  • +{% endif %} diff --git a/material/partials/nav.html b/material/partials/nav.html new file mode 100644 index 000000000..3961da55e --- /dev/null +++ b/material/partials/nav.html @@ -0,0 +1,21 @@ + diff --git a/material/partials/search.html b/material/partials/search.html new file mode 100644 index 000000000..875d22d02 --- /dev/null +++ b/material/partials/search.html @@ -0,0 +1,15 @@ +{% import "partials/i18n.html" as i18n %} + diff --git a/material/partials/social.html b/material/partials/social.html new file mode 100644 index 000000000..cb68735ad --- /dev/null +++ b/material/partials/social.html @@ -0,0 +1,9 @@ +{% if config.extra.social %} + +{% endif %} diff --git a/material/partials/source.html b/material/partials/source.html new file mode 100644 index 000000000..5dbaee2e6 --- /dev/null +++ b/material/partials/source.html @@ -0,0 +1,25 @@ +{% import "partials/i18n.html" as i18n %} +{% set platform = config.extra.repo_icon or config.repo_url %} +{% if "github" in platform %} + {% set repo_type = "github" %} +{% elif "gitlab" in platform %} + {% set repo_type = "gitlab" %} +{% elif "bitbucket" in platform %} + {% set repo_type = "bitbucket" %} +{% else %} + {% set repo_type = "" %} +{% endif %} +{% block repo %} + + {% if repo_type %} +
    + + + +
    + {% endif %} +
    + {{ config.repo_name }} +
    +
    +{% endblock %} diff --git a/material/partials/svgs.html b/material/partials/svgs.html new file mode 100644 index 000000000..82385c7d4 --- /dev/null +++ b/material/partials/svgs.html @@ -0,0 +1,10 @@ +
    + {% set platform = config.extra.repo_icon or config.repo_url %} + {% if "github" in platform %} + {% include "assets/images/icons/github-1da075986e.svg" %} + {% elif "gitlab" in platform %} + {% include "assets/images/icons/gitlab-5ad3f9f9e5.svg" %} + {% elif "bitbucket" in platform %} + {% include "assets/images/icons/bitbucket-670608a71a.svg" %} + {% endif %} +
    diff --git a/material/partials/toc-item.html b/material/partials/toc-item.html new file mode 100644 index 000000000..3b4f4d76c --- /dev/null +++ b/material/partials/toc-item.html @@ -0,0 +1,14 @@ +
  • + + {{ toc_item.title }} + + {% if toc_item.children %} + + {% endif %} +
  • diff --git a/material/partials/toc.html b/material/partials/toc.html new file mode 100644 index 000000000..d17dc7074 --- /dev/null +++ b/material/partials/toc.html @@ -0,0 +1,15 @@ +{% import "partials/i18n.html" as i18n %} + diff --git a/mkdocs.yml b/mkdocs.yml index 718d73c9e..e60f188ad 100755 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Martin Donath +# Copyright (c) 2016-2017 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -19,41 +19,67 @@ # IN THE SOFTWARE. # Project information -site_name: Material -site_description: A material design theme for MkDocs +site_name: Material for MkDocs +site_description: A Material Design theme for MkDocs site_author: Martin Donath site_url: http://squidfunk.github.io/mkdocs-material/ # Repository -repo_name: GitHub +repo_name: squidfunk/mkdocs-material repo_url: https://github.com/squidfunk/mkdocs-material # Copyright -copyright: Copyright (c) 2016 Martin Donath +copyright: 'Copyright © 2016 Martin Donath' # Documentation and theme theme_dir: material # Options extra: - version: 0.2.4 - logo: images/logo.png - github: - download_release: true - author: - github: squidfunk - twitter: squidfunk + palette: + primary: indigo + accent: indigo + social: + - type: github-alt + link: https://github.com/squidfunk + - type: twitter + link: https://twitter.com/squidfunk + - type: linkedin + link: https://de.linkedin.com/in/martin-donath-20a95039 # Extensions markdown_extensions: - - codehilite(css_class=code) - - admonition - - toc: - permalink: '#' + - markdown.extensions.admonition + - markdown.extensions.codehilite(guess_lang=false) + - markdown.extensions.footnotes + - markdown.extensions.meta + - markdown.extensions.toc(permalink=true) + - pymdownx.arithmatex + - pymdownx.betterem(smart_enable=all) + - pymdownx.caret + - pymdownx.critic + - pymdownx.emoji: + emoji_generator: !!python/name:pymdownx.emoji.to_svg + - pymdownx.inlinehilite + - pymdownx.magiclink + - pymdownx.mark + - pymdownx.smartsymbols + - pymdownx.superfences + - pymdownx.tasklist(custom_checkbox=true) + - pymdownx.tilde # Page tree pages: - Material: index.md - Getting started: getting-started.md + - Extensions: + - Admonition: extensions/admonition.md + - CodeHilite: extensions/codehilite.md + - Footnotes: extensions/footnotes.md + - Permalinks: extensions/permalinks.md + - PyMdown: extensions/pymdown.md + - Specimen: specimen.md - Customization: customization.md - - License: license.md \ No newline at end of file + - Release notes: release-notes.md + - Contributing: contributing.md + - License: license.md diff --git a/package.json b/package.json index cd8955a44..817628d8a 100644 --- a/package.json +++ b/package.json @@ -1,45 +1,103 @@ { "name": "mkdocs-material", - "version": "0.2.4", - "description": "A material design theme for MkDocs", - "homepage": "http://squidfunk.github.io/mkdocs-material/", - "authors": [ - "squidfunk " + "version": "1.0.0", + "description": "A Material Design theme for MkDocs", + "keywords": [ + "mkdocs", + "documentation", + "theme" ], - "license": "MIT", - "main": "Gulpfile.js", - "scripts": { - "start": "gulp watch" + "homepage": "http://squidfunk.github.io/mkdocs-material/", + "bugs": { + "url": "https://github.com/squidfunk/mkdocs-material/issues", + "email": "martin.donath@squidfunk.com" }, + "license": "MIT", + "author": { + "name": "Martin Donath", + "email": "martin.donath@squidfunk.com" + }, + "contributors": [], "repository": { "type": "git", "url": "https://github.com/squidfunk/mkdocs-material.git" }, - "private": true, + "scripts": { + "build": "scripts/build", + "clean": "scripts/clean", + "lint": "scripts/lint", + "start": "scripts/start", + "test": "scripts/test" + }, + "dependencies": {}, "devDependencies": { "autoprefixer": "^6.3.2", + "babel-eslint": "^6.1.2", + "babel-loader": "^6.2.4", + "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-transform-react-jsx": "^6.8.0", + "babel-polyfill": "^6.20.0", + "babel-preset-es2015": "^6.13.2", + "babel-register": "^6.16.3", + "babel-root-import": "^4.1.3", + "chai": "^3.5.0", + "core-js": "^2.4.1", "css-mqpacker": "^5.0.1", + "custom-event-polyfill": "^0.3.0", "del": "^2.2.0", + "eslint": "^3.6.1", + "eslint-plugin-mocha": "^4.6.0", + "fastclick": "^1.0.6", + "git-hooks": "^1.1.6", "gulp": "^3.9.1", - "gulp-add-src": "^0.2.0", + "gulp-changed": "^1.3.2", "gulp-concat": "^2.6.0", "gulp-cssnano": "^2.1.1", "gulp-htmlmin": "^3.0.0", "gulp-if": "^2.0.0", "gulp-ignore": "^2.0.1", - "gulp-image-optimization": "^0.1.3", "gulp-modernizr": "0.0.0", "gulp-plumber": "^1.1.0", "gulp-postcss": "^6.1.0", "gulp-remove-empty-lines": "0.0.8", + "gulp-replace": "^0.5.4", "gulp-rev": "^7.0.0", - "gulp-rev-collector": "^1.0.2", + "gulp-rev-replace": "^0.4.3", "gulp-sass": "^3.0.0", "gulp-sourcemaps": "^2.2.2", + "gulp-stylelint": "^3.7.0", + "gulp-svgmin": "^1.2.2", "gulp-uglify": "^2.0.0", "gulp-util": "^3.0.7", + "js-cookie": "^2.1.3", + "karma": "^1.3.0", + "karma-chrome-launcher": "^2.0.0", + "karma-coverage": "^1.1.1", + "karma-mocha": "^1.2.0", + "karma-notify-reporter": "^1.0.1", + "karma-sourcemap-loader": "^0.3.7", + "karma-spec-reporter": "0.0.26", + "karma-webpack": "^1.8.0", + "lunr": "^0.7.1", + "material-design-color": "^2.3.1", + "material-shadows": "^3.0.0", + "mocha": "^3.1.0", + "modularscale-sass": "^2.1.1", "node-notifier": "^4.5.0", + "selenium-standalone": "^5.7.2", + "stylelint": "^7.7.1", + "stylelint-config-standard": "^15.0.1", + "stylelint-order": "^0.2.2", + "stylelint-scss": "^1.4.1", + "through2": "^2.0.1", "vinyl-paths": "^2.1.0", + "webpack": "^1.13.1", + "webpack-stream": "^3.2.0", + "whatwg-fetch": "^1.0.0", "yargs": "^6.6.0" - } + }, + "engines": { + "node": ">= 4.5.0" + }, + "private": true } diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..b1b14a966 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,23 @@ +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +mkdocs>=0.16 +pygments +pymdown-extensions diff --git a/scripts/build b/scripts/build new file mode 100755 index 000000000..f3fff3648 --- /dev/null +++ b/scripts/build @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check if "npm install" was executed +if [[ ! -d `npm bin` ]]; then + echo "\"node_modules\" not found:" + echo "npm install" + exit 1 +fi + +# Run command +`npm bin`/gulp build --clean --optimize --revision diff --git a/scripts/clean b/scripts/clean new file mode 100755 index 000000000..1b3cb6417 --- /dev/null +++ b/scripts/clean @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check if "npm install" was executed +if [[ ! -d `npm bin` ]]; then + echo "\"node_modules\" not found:" + echo "npm install" + exit 1 +fi + +# Run command +`npm bin`/gulp clean diff --git a/scripts/lint b/scripts/lint new file mode 100755 index 000000000..51c64adc0 --- /dev/null +++ b/scripts/lint @@ -0,0 +1,44 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check if "npm install" was executed +if [[ ! -d `npm bin` ]]; then + echo "\"node_modules\" not found:" + echo "npm install" + exit 1 +fi + +# Run ESLint +`npm bin`/eslint . +ESLINT=$? + +# Run Stylelint +`npm bin`/stylelint `find src/assets -name *.scss` +STYLELINT=$? + +# If one command failed, exit with error +if [ $ESLINT -gt 0 ] || [ $STYLELINT -gt 0 ]; then + exit 1 +fi; + +# Otherwise return with success +exit 0 diff --git a/scripts/start b/scripts/start new file mode 100755 index 000000000..d3e0db297 --- /dev/null +++ b/scripts/start @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check if "npm install" was executed +if [[ ! -d `npm bin` ]]; then + echo "\"node_modules\" not found:" + echo "npm install" + exit 1 +fi + +# Run command +`npm bin`/gulp watch --no-lint diff --git a/scripts/test b/scripts/test new file mode 100755 index 000000000..e6f32df17 --- /dev/null +++ b/scripts/test @@ -0,0 +1,31 @@ +#!/bin/bash + +# Copyright (c) 2016-2017 Martin Donath + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +# Check if "npm install" was executed +if [[ ! -d `npm bin` ]]; then + echo "\"node_modules\" not found:" + echo "npm install" + exit 1 +fi + +# Run command +`npm bin`/gulp test diff --git a/setup.py b/setup.py index 546258c3a..ca6a66f58 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright (c) 2016 Martin Donath +# Copyright (c) 2016-2017 Martin Donath # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to @@ -22,20 +22,20 @@ from setuptools import setup, find_packages # Package description setup( - name = 'mkdocs-material', - version = '0.2.4', - url = 'http://squidfunk.github.io/mkdocs-material/', - license = 'MIT', - description = 'A material design theme for MkDocs', - author = 'Martin Donath', - author_email = 'martin.donath@squidfunk.com', - keywords = ['mkdocs', 'documentation', 'theme'], + name = "mkdocs-material", + version = "1.0.0", + url = "http://squidfunk.github.io/mkdocs-material/", + license = "MIT", + description = "A Material Design theme for MkDocs", + author = "Martin Donath", + author_email = "martin.donath@squidfunk.com", + keywords = ["mkdocs", "documentation", "theme"], packages = find_packages(), include_package_data = True, entry_points = { - 'mkdocs.themes': [ - 'material = material', + "mkdocs.themes": [ + "material = material", ] }, zip_safe = False -) \ No newline at end of file +) diff --git a/src/404.html b/src/404.html new file mode 100644 index 000000000..70bc698f7 --- /dev/null +++ b/src/404.html @@ -0,0 +1,28 @@ + + +{% extends "main.html" %} + + +{% block content %} +

    404 - Not found

    +{% endblock %} diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/assets/fonts/icon.eot b/src/assets/fonts/icon.eot deleted file mode 100755 index 8f81638c2..000000000 Binary files a/src/assets/fonts/icon.eot and /dev/null differ diff --git a/src/assets/fonts/icon.json b/src/assets/fonts/icon.json deleted file mode 100644 index fc26e5702..000000000 --- a/src/assets/fonts/icon.json +++ /dev/null @@ -1,348 +0,0 @@ -{ -  "IcoMoonType": "selection", -  "icons": [ -    { -      "icon": { -        "paths": [ -          "M661.333 597.333h-33.92l-11.733-11.733c41.813-48.427 66.987-111.36 66.987-180.267 0-153.173-124.16-277.333-277.333-277.333s-277.333 124.16-277.333 277.333 124.16 277.333 277.333 277.333c68.907 0 131.84-25.173 180.267-66.773l11.733 11.733v33.707l213.333 212.907 63.573-63.573-212.907-213.333zM405.333 597.333c-106.027 0-192-85.973-192-192s85.973-192 192-192 192 85.973 192 192-85.973 192-192 192z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "search" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 0, -        "order": 7, -        "prevSize": 24, -        "code": 58880, -        "name": "search" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 0 -    }, -    { -      "icon": { -        "paths": [ -          "M853.333 469.333h-519.253l238.293-238.293-60.373-60.373-341.333 341.333 341.333 341.333 60.373-60.373-238.293-238.293h519.253v-85.333z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "arrow-back" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 1, -        "order": 4, -        "prevSize": 24, -        "code": 58881, -        "name": "arrow-back" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 1 -    }, -    { -      "icon": { -        "paths": [ -          "M426.667 256l-60.373 60.373 195.627 195.627-195.627 195.627 60.373 60.373 256-256z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "chevron-right" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 2, -        "order": 9, -        "prevSize": 24, -        "code": 58882, -        "name": "chevron-right" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 2 -    }, -    { -      "icon": { -        "paths": [ -          "M810.667 273.707l-60.373-60.373-238.293 238.293-238.293-238.293-60.373 60.373 238.293 238.293-238.293 238.293 60.373 60.373 238.293-238.293 238.293 238.293 60.373-60.373-238.293-238.293z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "close" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 3, -        "order": 8, -        "prevSize": 24, -        "code": 58883, -        "name": "close" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 3 -    }, -    { -      "icon": { -        "paths": [ -          "M128 768h768v-85.333h-768v85.333zM128 554.667h768v-85.333h-768v85.333zM128 256v85.333h768v-85.333h-768z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "menu" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 4, -        "order": 10, -        "prevSize": 24, -        "code": 58884, -        "name": "menu" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 4 -    }, -    { -      "icon": { -        "paths": [ -          "M512 170.667l-60.373 60.373 238.293 238.293h-519.253v85.333h519.253l-238.293 238.293 60.373 60.373 341.333-341.333z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "arrow-forward" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 5, -        "order": 15, -        "prevSize": 24, -        "code": 58885, -        "name": "arrow-forward" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 5 -    }, -    { -      "icon": { -        "paths": [ -          "M1024 194.418c-37.676 16.708-78.164 28.002-120.66 33.080 43.372-26 76.686-67.17 92.372-116.23-40.596 24.078-85.556 41.56-133.41 50.98-38.32-40.83-92.922-66.34-153.346-66.34-116.022 0-210.088 94.058-210.088 210.078 0 16.466 1.858 32.5 5.44 47.878-174.6-8.764-329.402-92.4-433.018-219.506-18.084 31.028-28.446 67.116-28.446 105.618 0 72.888 37.088 137.192 93.46 174.866-34.438-1.092-66.832-10.542-95.154-26.278-0.020 0.876-0.020 1.756-0.020 2.642 0 101.788 72.418 186.696 168.522 206-17.626 4.8-36.188 7.372-55.348 7.372-13.538 0-26.698-1.32-39.528-3.772 26.736 83.46 104.32 144.206 196.252 145.896-71.9 56.35-162.486 89.934-260.916 89.934-16.958 0-33.68-0.994-50.116-2.94 92.972 59.61 203.402 94.394 322.042 94.394 386.422 0 597.736-320.124 597.736-597.744 0-9.108-0.206-18.168-0.61-27.18 41.056-29.62 76.672-66.62 104.836-108.748z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "twitter", -          "brand", -          "tweet", -          "social" -        ], -        "defaultCode": 58525, -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 6, -        "order": 9, -        "prevSize": 24, -        "code": 58886, -        "ligatures": "twitter, brand11", -        "name": "twitter" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 6 -    }, -    { -      "icon": { -        "paths": [ -          "M810.667 384h-170.667v-256h-256v256h-170.667l298.667 298.667 298.667-298.667zM213.333 768v85.333h597.333v-85.333h-597.333z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "file-download" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 7, -        "order": 10, -        "prevSize": 24, -        "code": 58888, -        "name": "download" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 7 -    }, -    { -      "icon": { -        "paths": [ -          "M512 736.853l263.68 159.147-69.973-299.947 232.96-201.813-306.773-26.027-119.893-282.88-119.893 282.88-306.773 26.027 232.96 201.813-69.973 299.947z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "star" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "id": 8, -        "order": 9, -        "prevSize": 24, -        "code": 58889, -        "name": "star" -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 8 -    }, -    { -      "icon": { -        "paths": [ -          "M512.008 12.642c-282.738 0-512.008 229.218-512.008 511.998 0 226.214 146.704 418.132 350.136 485.836 25.586 4.738 34.992-11.11 34.992-24.632 0-12.204-0.48-52.542-0.696-95.324-142.448 30.976-172.504-60.41-172.504-60.41-23.282-59.176-56.848-74.916-56.848-74.916-46.452-31.778 3.51-31.124 3.51-31.124 51.4 3.61 78.476 52.766 78.476 52.766 45.672 78.27 119.776 55.64 149.004 42.558 4.588-33.086 17.852-55.68 32.506-68.464-113.73-12.942-233.276-56.85-233.276-253.032 0-55.898 20.004-101.574 52.76-137.428-5.316-12.9-22.854-64.972 4.952-135.5 0 0 43.006-13.752 140.84 52.49 40.836-11.348 84.636-17.036 128.154-17.234 43.502 0.198 87.336 5.886 128.256 17.234 97.734-66.244 140.656-52.49 140.656-52.49 27.872 70.528 10.35 122.6 5.036 135.5 32.82 35.856 52.694 81.532 52.694 137.428 0 196.654-119.778 239.95-233.79 252.624 18.364 15.89 34.724 47.046 34.724 94.812 0 68.508-0.596 123.644-0.596 140.508 0 13.628 9.222 29.594 35.172 24.566 203.322-67.776 349.842-259.626 349.842-485.768 0-282.78-229.234-511.998-511.992-511.998z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "github", -          "brand", -          "octacat", -          "social" -        ], -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "order": 27, -        "prevSize": 24, -        "ligatures": "github, brand40", -        "name": "github", -        "id": 9, -        "code": 58887 -      }, -      "setIdx": 0, -      "setId": 3, -      "iconIdx": 9 -    }, -    { -      "icon": { -        "paths": [ -          "M554 598v-172h-84v172h84zM554 768v-86h-84v86h84zM42 896l470-810 470 810h-940z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "warning" -        ], -        "defaultCode": 57346, -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "order": 11, -        "prevSize": 24, -        "name": "warning", -        "ligatures": "warning", -        "id": 2, -        "code": 58896 -      }, -      "setIdx": 1, -      "setId": 2, -      "iconIdx": 2 -    }, -    { -      "icon": { -        "paths": [ -          "M614 256h240v426h-300l-16-84h-240v298h-84v-726h384z" -        ], -        "attrs": [], -        "isMulticolor": false, -        "tags": [ -          "flag" -        ], -        "defaultCode": 57683, -        "grid": 24 -      }, -      "attrs": [], -      "properties": { -        "order": 13, -        "prevSize": 24, -        "name": "note", -        "ligatures": "flag", -        "id": 140, -        "code": 58897 -      }, -      "setIdx": 1, -      "setId": 2, -      "iconIdx": 140 -    } -  ], -  "height": 1024, -  "metadata": { -    "name": "icon" -  }, -  "preferences": { -    "showGlyphs": true, -    "showQuickUse": true, -    "showQuickUse2": true, -    "showSVGs": true, -    "fontPref": { -      "prefix": "icon-", -      "metadata": { -        "fontFamily": "icon", -        "majorVersion": 1, -        "minorVersion": 0 -      }, -      "metrics": { -        "emSize": 1024, -        "baseline": 6.25, -        "whitespace": 50 -      }, -      "ie7": true, -      "showSelector": true, -      "selector": "class", -      "classSelector": ".icon", -      "showMetrics": true, -      "showMetadata": true, -      "cssVars": true, -      "embed": false, -      "noie8": false -    }, -    "imagePref": { -      "prefix": "icon-", -      "png": true, -      "useClassSelector": true, -      "color": 4473924, -      "bgColor": 16777215 -    }, -    "historySize": 100, -    "showCodes": true, -    "gridSize": 16 -  } -} \ No newline at end of file diff --git a/src/assets/fonts/icon.svg b/src/assets/fonts/icon.svg deleted file mode 100755 index 86250e7b4..000000000 --- a/src/assets/fonts/icon.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - -Generated by IcoMoon - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/assets/fonts/icon.ttf b/src/assets/fonts/icon.ttf deleted file mode 100755 index b5ab5601b..000000000 Binary files a/src/assets/fonts/icon.ttf and /dev/null differ diff --git a/src/assets/fonts/icon.woff b/src/assets/fonts/icon.woff deleted file mode 100755 index ed0f20d5b..000000000 Binary files a/src/assets/fonts/icon.woff and /dev/null differ diff --git a/src/assets/images/icons/bitbucket.svg b/src/assets/images/icons/bitbucket.svg new file mode 100644 index 000000000..ffc79b1ec --- /dev/null +++ b/src/assets/images/icons/bitbucket.svg @@ -0,0 +1,20 @@ + + + diff --git a/src/assets/images/icons/github.svg b/src/assets/images/icons/github.svg new file mode 100644 index 000000000..f8944b015 --- /dev/null +++ b/src/assets/images/icons/github.svg @@ -0,0 +1,18 @@ + + + diff --git a/src/assets/images/icons/gitlab.svg b/src/assets/images/icons/gitlab.svg new file mode 100644 index 000000000..cda66137a --- /dev/null +++ b/src/assets/images/icons/gitlab.svg @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/javascripts/application.js b/src/assets/javascripts/application.js index d1ffbec30..39187f8e3 100644 --- a/src/assets/javascripts/application.js +++ b/src/assets/javascripts/application.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,511 +20,222 @@ * IN THE SOFTWARE. */ -/* Hey, there's your missing semicolon, lunr.js! */ -; - -/* Truncate a string after the given number of characters */ -String.prototype.truncate = function(n) { - if (this.length > n) { - while (this[n] != ' ' && --n > 0); - return this.substring(0, n) + '…'; - } - return this; -} - -/* Wrap an HTMLElement around each element in an HTMLElement array */ -HTMLElement.prototype.wrap = function (elms) { - if (!elms.length) elms = [elms]; - for (var i = elms.length - 1; i >= 0; i--) { - var child = (i > 0) ? this.cloneNode(true) : this; - var el = elms[i]; - - /* Cache current parent and sibling */ - var parent = el.parentNode, - sibling = el.nextSibling; - - /* Wrap the element and remove it from its current parent */ - child.appendChild(el); - if (sibling) { - parent.insertBefore(child, sibling); - } else { - parent.appendChild(child); - } - } -} +import FastClick from "fastclick" +import Material from "./components/Material" /* ---------------------------------------------------------------------------- - * Application logic + * Application * ------------------------------------------------------------------------- */ -/* Initialize application upon DOM ready */ -document.addEventListener('DOMContentLoaded', function() { - 'use strict'; +export default class Application { - /* Test for iOS */ - Modernizr.addTest('ios', function() { - return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g); - }); + /** + * Create the application + * + * @constructor + * @param {object} config Configuration object + */ + constructor(config) { + this.config_ = config + } - /* Test for web application context */ - Modernizr.addTest('standalone', function() { - return !!navigator.standalone; - }); + /** + * Initialize all components and listeners + */ + initialize() { - /* Attack FastClick to mitigate 300ms delay on touch devices */ - FastClick.attach(document.body); + /* Initialize Modernizr and FastClick */ + new Material.Event.Listener(document, "DOMContentLoaded", () => { - /* Grab relevant elements from the DOM */ - var toggle = document.getElementById('toggle-search'), - reset = document.getElementById('reset-search'), - drawer = document.querySelector('.drawer'), - anchors = document.querySelectorAll('.anchor'), - search = document.querySelector('.search .field'), - query = document.querySelector('.query'), - meta = document.querySelector('.results .meta'); + /* Test for iOS */ + Modernizr.addTest("ios", () => { + return !!navigator.userAgent.match(/(iPad|iPhone|iPod)/g) + }) -/* ---------------------------------------------------------------------------- - * Initialize drawer - * ------------------------------------------------------------------------- */ + /* Test for web application context */ + Modernizr.addTest("standalone", () => { + return !!navigator.standalone + }) - /* Automatically close drawer when anchors are clicked */ - Array.prototype.forEach.call(anchors, function(item) { - item.querySelector('a').addEventListener('click', function() { - document.getElementById('toggle-drawer').checked = false; - document.body.classList.remove('toggle-drawer'); - }); - }); + /* Attack FastClick to mitigate 300ms delay on touch devices */ + FastClick.attach(document.body) - /* Align drawer to window offset */ - var pageYOffsetLast = window.pageYOffset; - var align = function() { - var boundary = window.pageYOffset + window.innerHeight; - var clipping = Math.max(0, window.innerHeight - drawer.offsetHeight); - - /* Ensure alignment with footer if at end of document */ - if (boundary > document.body.clientHeight - (96 - clipping)) { - if (drawer.style.position != 'absolute') { - drawer.style.position = 'absolute'; - drawer.style.top = null; - drawer.style.bottom = 0; - } - - /* Pin drawer to top, if window is higher than drawer */ - } else if (drawer.offsetHeight < window.innerHeight) { - if (drawer.style.position != 'fixed') { - drawer.style.position = 'fixed'; - drawer.style.top = 0; - drawer.style.bottom = null; - } - - /* If the drawer is not pinned, check if we need to pin it */ - } else if (drawer.style.position != 'fixed') { - - /* Pin drawer to bottom of window */ - if (boundary > drawer.offsetTop + drawer.offsetHeight) { - drawer.style.position = 'fixed'; - drawer.style.top = null; - drawer.style.bottom = -96 + 'px'; - - /* Pin drawer to top of window */ - } else if (window.pageYOffset < drawer.offsetTop) { - drawer.style.position = 'fixed'; - drawer.style.top = 0; - drawer.style.bottom = null; - } - - /* If the drawer is pinned, check if we have to unpin it */ - } else { - if (window.pageYOffset > pageYOffsetLast) { - if (drawer.style.top) { - drawer.style.position = 'absolute'; - drawer.style.top = Math.max(0, pageYOffsetLast) + 'px'; - drawer.style.bottom = null; + /* Wrap all data tables for better overflow scrolling */ + const tables = document.querySelectorAll("table:not([class])") + Array.prototype.forEach.call(tables, table => { + const wrap = document.createElement("div") + wrap.classList.add("md-typeset__table") + if (table.nextSibling) { + table.parentNode.insertBefore(wrap, table.nextSibling) + } else { + table.parentNode.appendChild(wrap) } - } else if (drawer.style.bottom) { - drawer.style.position = 'absolute'; - drawer.style.top = (boundary - drawer.offsetHeight) + 'px'; - drawer.style.bottom = null; - } - } + wrap.appendChild(table) + }) - /* Update last offset (mitigiate negative offsets in Safari) */ - pageYOffsetLast = Math.max(0, window.pageYOffset); - } + /* Force 1px scroll offset to trigger overflow scrolling */ + if (Modernizr.ios) { + const scrollable = document.querySelectorAll("[data-md-scrollfix]") + Array.prototype.forEach.call(scrollable, item => { + item.addEventListener("touchstart", () => { + const top = item.scrollTop - /* Check for media query events */ - var check = function() { - var main = document.querySelector('.main'); - window.removeEventListener('scroll', align); + /* We're at the top of the container */ + if (top === 0) { + item.scrollTop = 1 - /* Reset drawer position when entering collapsed mode */ - if (matchMedia("only screen and (max-width: 959px)").matches) { - drawer.style.position = null; - drawer.style.top = null; - drawer.style.bottom = null; - - /* Check if the scroll handler needs to be registered */ - } else if (drawer.offsetHeight + 96 < main.offsetHeight) { - window.addEventListener('scroll', align); - align(); - } - } - - /* Register resize handler and fire once */ - if (!Modernizr.ios) { - window.addEventListener('resize', check); - check(); - } - -/* ---------------------------------------------------------------------------- - * Initialize search index - * ------------------------------------------------------------------------- */ - - /* Initialize index */ - var initialize = function() { - pegasus(base_url + '/mkdocs/search_index.json').then( - - /* Request successful, we got the index */ - function(data, xhr) { - - /* Create index */ - var index = lunr(function() { - this.field('title', { boost: 10 }); - this.field('text'); - this.ref('location'); - }); - - /* Index articles */ - var articles = {}; - data.docs.map(function(article) { - article.location = base_url + article.location; - articles[article.location] = article; - index.add(article); - }); - - /* Register keyhandler to execute search on key up */ - query.addEventListener('keyup', function() { - var container = document.querySelector('.results .list'); - while (container.firstChild) - container.removeChild(container.firstChild); - - /* Abort, if the query is empty */ - var bar = document.querySelector('.bar.search'); - if (!query.value.length) { - while (meta.firstChild) - meta.removeChild(meta.firstChild); - - /* Restore state */ - bar.classList.remove('non-empty'); - return; - } - - /* Show reset button */ - bar.classList.add('non-empty'); - - /* Execute search */ - var results = index.search(query.value); - results.map(function(result) { - var article = articles[result.ref]; - - /* Create article container */ - var teaser = document.createElement('article'); - teaser.classList.add('result'); - - /* Create title element */ - var title = document.createElement('h1'); - title.innerHTML = article.title; - teaser.appendChild(title); - - // /* Create text element */ - // var text = document.createElement('p'); - // text.innerHTML = article.text.truncate(140); - // teaser.appendChild(text); - - /* Create a link referring to the article */ - var link = document.createElement('a'); - link.href = article.location; - link.appendChild(teaser); - - /* Create url element */ - var url = document.createElement('span'); - url.innerHTML = link.href.split('#')[0]; - teaser.appendChild(url); - - /* Close search and jump to anchor when on same page */ - var parts = link.href.split('#'); - if (parts[0] == document.location.href.split('#')[0]) { - link.addEventListener('click', function(e) { - document.body.classList.remove('toggle-search'); - document.body.classList.remove('locked'); - toggle.checked = false; - - /* Don't catch anchors if the search doesn't cover the page */ - if (matchMedia('only screen and (min-width: 960px)').matches) - return; - - /* Prevent default to intercept scroll-to behaviour and - stop propagation, as this interferes with the link-lock in - the web application context, which opens all internal links - inside the same context */ - e.preventDefault(); - e.stopPropagation(); - - /* Scroll to chapter, if given */ - if (parts.length != 1) { - var chapter = document.getElementById(parts[1]); - if (chapter) { - - /* Scroll to chapter, but wait for 100ms to prevent flashes - on iOS. A short timeout seems to do the trick */ - setTimeout(function() { - chapter.scrollIntoView && chapter.scrollIntoView() || - window.scrollTo(0, chapter.offsetTop); - }, 100); - } - } - }); + /* We're at the bottom of the container */ + } else if (top + item.offsetHeight === item.scrollHeight) { + item.scrollTop = top - 1 } - - /* Add article to search results */ - container.appendChild(link); - }); - - /* Show number of search results */ - var number = document.createElement('strong'); - number.innerHTML = results.length + ' search result' - + (results.length != 1 ? 's' : ''); - - /* Update number */ - while (meta.firstChild) - meta.removeChild(meta.firstChild); - meta.appendChild(number); - }); - }, - - /* Handle error */ - function(data, xhr) { - console.error(data, xhr.status); + }) + }) } - ); + }).listen() - /* Remove listener, as we only have to initialize once */ - toggle.removeEventListener('click', initialize); - }; + /* Component: sidebar container */ + if (!Modernizr.csscalc) + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener(window, [ + "resize", "orientationchange" + ], new Material.Sidebar.Container("[data-md-component=container]"))) - /* Initialize on first click */ - toggle.addEventListener('click', initialize); + /* Component: sidebar with navigation */ + new Material.Event.MatchMedia("(min-width: 1220px)", + new Material.Event.Listener(window, [ + "scroll", "resize", "orientationchange" + ], new Material.Sidebar.Position("[data-md-component=navigation]"))) -/* ---------------------------------------------------------------------------- - * Initialize search modal - * ------------------------------------------------------------------------- */ + /* Component: sidebar with table of contents */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener(window, [ + "scroll", "resize", "orientationchange" + ], new Material.Sidebar.Position("[data-md-component=toc]"))) - /* Intercept click on search mode toggle */ - var offset = 0; - toggle.addEventListener('click', function(e) { - var list = document.body.classList; - var lock = !matchMedia('only screen and (min-width: 960px)').matches; + /* Component: link blurring for table of contents */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener(window, "scroll", + new Material.Nav.Blur("[data-md-component=toc] .md-nav__link"))) - /* Exiting search mode */ - if (list.contains('locked')) { - list.remove('locked'); + /* Component: collapsible elements for navigation */ + const collapsibles = + document.querySelectorAll("[data-md-component=collapsible]") + Array.prototype.forEach.call(collapsibles, collapse => { + new Material.Event.MatchMedia("(min-width: 1220px)", + new Material.Event.Listener(collapse.previousElementSibling, "click", + new Material.Nav.Collapse(collapse))) + }) - /* Scroll to former position, but wait for 100ms to prevent flashes - on iOS. A short timeout seems to do the trick */ - if (lock) - setTimeout(function() { - window.scrollTo(0, offset); - }, 100); + /* Component: active pane monitor for iOS scrolling fixes */ + new Material.Event.MatchMedia("(max-width: 1219px)", + new Material.Event.Listener( + "[data-md-component=navigation] [data-md-toggle]", "change", + new Material.Nav.Scrolling("[data-md-component=navigation] nav"))) - /* Entering search mode */ - } else { - offset = window.scrollY; + /* Component: search body lock for mobile */ + new Material.Event.MatchMedia("(max-width: 959px)", + new Material.Event.Listener("[data-md-toggle=search]", "change", + new Material.Search.Lock("[data-md-toggle=search]"))) - /* First timeout: scroll to top after transition, to omit flickering */ - if (lock) - setTimeout(function(){ - window.scrollTo(0, 0); - }, 400); + /* Component: search results */ + new Material.Event.Listener(document.forms.search.query, [ + "focus", "keyup" + ], new Material.Search.Result("[data-md-component=result]", () => { + return fetch(`${this.config_.url.base}/mkdocs/search_index.json`, { + credentials: "same-origin" + }).then(response => response.json()) + .then(data => { + return data.docs.map(doc => { + doc.location = this.config_.url.base + doc.location + return doc + }) + }) + })).listen() - /* Second timeout: Lock body after finishing transition and scrolling to - top and focus input field. Sadly, the focus event is not dispatched - on iOS Safari and there's nothing we can do about it. */ - setTimeout(function() { + /* Listener: prevent touches on overlay if navigation is active */ + new Material.Event.MatchMedia("(max-width: 1219px)", + new Material.Event.Listener("[data-md-component=overlay]", "touchstart", + ev => ev.preventDefault())) - /* This additional check is necessary to handle fast subsequent clicks - on the toggle and the timeout to lock the body must be cancelled */ - if (this.checked) { - if (lock) - list.add('locked'); - setTimeout(function() { - query.focus(); - }, 200); + /* Listener: close drawer when anchor links are clicked */ + new Material.Event.MatchMedia("(max-width: 959px)", + new Material.Event.Listener("[data-md-component=navigation] [href^='#']", + "click", () => { + const toggle = document.querySelector("[data-md-toggle=drawer]") + if (toggle.checked) { + toggle.checked = false + toggle.dispatchEvent(new CustomEvent("change")) + } + })) + + /* Listener: focus input after opening search */ + new Material.Event.Listener("[data-md-toggle=search]", "change", ev => { + setTimeout(toggle => { + const query = document.forms.search.query + if (toggle.checked) + query.focus() + }, 400, ev.target) + }).listen() + + /* Listener: open search on focus */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener(document.forms.search.query, "focus", () => { + const toggle = document.querySelector("[data-md-toggle=search]") + if (!toggle.checked) { + toggle.checked = true + toggle.dispatchEvent(new CustomEvent("change")) } - }.bind(this), 450); - } - }); + })) - /* Dispatch input focus on touch of search section */ - search.addEventListener('touchstart', function() { - query.focus(); - }); - - /* Exit search mode when pressing ESC */ - window.addEventListener('keyup', function(e) { - var code = e.keyCode || e.which; - if (code == 27) { - query.blur(); - - /* Exit locked state */ - document.body.classList.remove('toggle-search'); - document.body.classList.remove('locked'); - toggle.checked = false; - } - }); - - /* Delete search results upon click on "x" */ - var empty = document.getElementById('reset-search'); - empty.addEventListener('click', function() { - var container = document.querySelector('.results .list'); - while (container.firstChild) - container.removeChild(container.firstChild); - - /* Hide search button */ - var bar = document.querySelector('.bar.search'); - bar.classList.remove('non-empty'); - - /* Reset number of search results */ - meta.innerHTML = ''; - - /* Empty search input */ - query.value = ''; - query.focus(); - }); - -/* ---------------------------------------------------------------------------- - * Initialize scroll spy - * ------------------------------------------------------------------------- */ - - /* Retrieve vertical offset of article chapters */ - var chapters = document.querySelectorAll('h2'); - chapters = Array.prototype.map.call(chapters, function(item) { - return item.offsetTop; - }); - - /* Update currently active chapter, if the new chapter is two thirds - into the viewport - account for iOS web application context */ - var visible = null; - document.addEventListener('scroll', function() { - var offset = window.scrollY + (window.innerHeight / 3), - active = chapters.length - 1; - for (var c = 0; c < active; c++) - if (offset < chapters[c + 1]) - active = c; - - /* Update anchors, if a new chapter became visible */ - if (active != visible) { - visible = active; - Array.prototype.forEach.call(anchors, function(item, index) { - var link = item.querySelector('a'); - if (index != visible || link.classList.add('current')) - link.classList.remove('current'); - }); - } - }); - -/* ---------------------------------------------------------------------------- - * Fix syntax highlighting - * ------------------------------------------------------------------------- */ - - /* Fix highlighting for function calls */ - var functions = document.querySelectorAll('.n + .p'); - Array.prototype.forEach.call(functions, function(item) { - var text = item.innerText || item.textContent; - if (text && text[0] == '(') - item.previousSibling.classList.add('f'); - }); - -/* ---------------------------------------------------------------------------- - * Progressive structure enhancement - * ------------------------------------------------------------------------- */ - - /* Wrap all data tables */ - var tables = document.querySelectorAll('table'); - Array.prototype.forEach.call(tables, function(item) { - var wrapper = document.createElement('div'); - wrapper.classList.add('data'); - wrapper.wrap(item); - }); - -/* ---------------------------------------------------------------------------- - * Fix overflow scrolling on iOS - * ------------------------------------------------------------------------- */ - - /* Force 1px scroll offset to trigger overflow scrolling */ - if (Modernizr.ios) { - var scrollable = document.querySelectorAll( - '.scrollable, .standalone .article'); - Array.prototype.forEach.call(scrollable, function(item) { - item.addEventListener('touchstart', function() { - var top = this.scrollTop; - - /* We're at the top of the container */ - if (top == 0) { - this.scrollTop = 1; - - /* We're at the bottom of the container */ - } else if (top + this.offsetHeight == this.scrollHeight) { - this.scrollTop = top - 1; + /* Listener: close search when clicking outside */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener(document.body, "click", () => { + const toggle = document.querySelector("[data-md-toggle=search]") + if (toggle.checked) { + toggle.checked = false + toggle.dispatchEvent(new CustomEvent("change")) } - }); - }); - } + })) - /* Prevent scrolling on project, overlay and header */ - var prevented = document.querySelectorAll('.project, .overlay, .header'); - Array.prototype.forEach.call(prevented, function(item) { - item.addEventListener('touchmove', function(e) { - e.preventDefault(); - }); - }); - -/* ---------------------------------------------------------------------------- - * Fallback for browsers that don't support :checked - * ------------------------------------------------------------------------- */ - - /* Set representative class on body for active toggle */ - var toggles = document.querySelectorAll('.toggle'); - Array.prototype.forEach.call(toggles, function(item) { - item.addEventListener('click', function() { - document.body.classList.toggle(this.id); - }); - }); - -/* ---------------------------------------------------------------------------- - * Initialize GitHub star button - * ------------------------------------------------------------------------- */ - - /* Get Stars for current repository */ - if (repo_id) { - pegasus('https://api.github.com/repos/' + repo_id).then( - - /* Request successful, we got the stars */ - function(data, xhr) { - var count = data.stargazers_count; - if (count > 10000) - count = (count / 1000).toFixed(0) + 'k'; - else if (count > 1000) - count = (count / 1000).toFixed(1) + 'k'; - - /* Set number of stars */ - var stars = document.querySelector('.repo-stars .count'); - stars.innerHTML = count; - }, - - /* Handle error */ - function(data, xhr) { - console.error(data, xhr.status); + /* Listener: disable search when ESC key is pressed */ + new Material.Event.Listener(window, "keyup", ev => { + const code = ev.keyCode || ev.which + if (code === 27) { + const toggle = document.querySelector("[data-md-toggle=search]") + if (toggle.checked) { + toggle.checked = false + toggle.dispatchEvent(new CustomEvent("change")) + document.forms.search.query.blur() + } } - ); + }).listen() + + /* Listener: fix unclickable toggle due to blur handler */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener("[data-md-toggle=search]", "click", + ev => ev.stopPropagation())) + + /* Listener: prevent search from closing when clicking */ + new Material.Event.MatchMedia("(min-width: 960px)", + new Material.Event.Listener("[data-md-component=search]", "click", + ev => ev.stopPropagation())) + + /* Retrieve facts for the given repository type */ + ;(() => { + const el = document.querySelector("[data-md-source]") + if (!el) return Promise.resolve([]) + switch (el.dataset.mdSource) { + case "github": return new Material.Source.Adapter.GitHub(el).fetch() + default: return Promise.resolve([]) + } + + /* Render repository source information */ + })().then(facts => { + const sources = document.querySelectorAll("[data-md-source]") + Array.prototype.forEach.call(sources, source => { + new Material.Source.Repository(source) + .initialize(facts) + }) + }) } -}); \ No newline at end of file +} diff --git a/src/assets/javascripts/components/Material.js b/src/assets/javascripts/components/Material.js new file mode 100644 index 000000000..bf271bd22 --- /dev/null +++ b/src/assets/javascripts/components/Material.js @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Event from "./Material/Event" +import Nav from "./Material/Nav" +import Search from "./Material/Search" +import Sidebar from "./Material/Sidebar" +import Source from "./Material/Source" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Event, + Nav, + Search, + Sidebar, + Source +} diff --git a/src/assets/javascripts/components/Material/Event.js b/src/assets/javascripts/components/Material/Event.js new file mode 100644 index 000000000..7a088c6ad --- /dev/null +++ b/src/assets/javascripts/components/Material/Event.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Listener from "./Event/Listener" +import MatchMedia from "./Event/MatchMedia" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Listener, + MatchMedia +} diff --git a/src/assets/javascripts/components/Material/Event/Listener.js b/src/assets/javascripts/components/Material/Event/Listener.js new file mode 100644 index 000000000..5b5776698 --- /dev/null +++ b/src/assets/javascripts/components/Material/Event/Listener.js @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Listener { + + /** + * Generic event listener + * + * @constructor + * @param {(string|NodeList)} els - Selector or HTML elements + * @param {Array.} events - Event names + * @param {(object|function)} handler - Handler to be invoked + */ + constructor(els, events, handler) { + this.els_ = (typeof els === "string") + ? document.querySelectorAll(els) + : [].concat(els) + + /* Set handler as function or directly as object */ + this.handler_ = typeof handler === "function" + ? { update: handler } + : handler + + /* Initialize event names and update handler */ + this.events_ = [].concat(events) + this.update_ = ev => this.handler_.update(ev) + } + + /** + * Register listener for all relevant events + */ + listen() { + Array.prototype.forEach.call(this.els_, el => { + this.events_.forEach(event => { + el.addEventListener(event, this.update_, false) + }) + }) + + /* Execute setup handler, if implemented */ + if (typeof this.handler_.setup === "function") + this.handler_.setup() + } + + /** + * Unregister listener for all relevant events + */ + unlisten() { + Array.prototype.forEach.call(this.els_, el => { + this.events_.forEach(event => { + el.removeEventListener(event, this.update_) + }) + }) + + /* Execute reset handler, if implemented */ + if (typeof this.handler_.reset === "function") + this.handler_.reset() + } +} diff --git a/src/assets/stylesheets/modules/base/_typography.scss b/src/assets/javascripts/components/Material/Event/MatchMedia.js similarity index 63% rename from src/assets/stylesheets/modules/base/_typography.scss rename to src/assets/javascripts/components/Material/Event/MatchMedia.js index 037e46a5b..2d792e2c2 100644 --- a/src/assets/stylesheets/modules/base/_typography.scss +++ b/src/assets/javascripts/components/Material/Event/MatchMedia.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -21,38 +21,34 @@ */ /* ---------------------------------------------------------------------------- - * Base typography + * Class * ------------------------------------------------------------------------- */ -/* - * Default font styles - */ -body, input { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; - font-weight: 400; +export default class MatchMedia { - /* Enable font-smoothing in Webkit and FF */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - - /* - * Use system fonts, if browser doesn't support webfonts + /** + * Media query listener + * + * This class listens for state changes of media queries and automatically + * switches the given listeners on or off. + * + * @constructor + * @param {string} query - Media query to test for + * @param {Listener} listener - Event listener */ - .no-fontface & { - font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; + constructor(query, listener) { + this.handler_ = mq => { + if (mq.matches) + listener.listen() + else + listener.unlisten() + } + + /* Initialize media query listener */ + const media = window.matchMedia(query) + media.addListener(this.handler_) + + /* Always check at initialization */ + this.handler_(media) } } - -/* - * Proportional fonts - */ -pre, code, kbd { - font-family: 'Courier New', 'Courier', monospace; - - /* - * Use system fonts, if browser doesn't support webfonts - */ - .no-fontface & { - font-family: 'Courier New', 'Courier', monospace; - } -} \ No newline at end of file diff --git a/src/assets/javascripts/components/Material/Nav.js b/src/assets/javascripts/components/Material/Nav.js new file mode 100644 index 000000000..2bad97d8e --- /dev/null +++ b/src/assets/javascripts/components/Material/Nav.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Blur from "./Nav/Blur" +import Collapse from "./Nav/Collapse" +import Scrolling from "./Nav/Scrolling" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Blur, + Collapse, + Scrolling +} diff --git a/src/assets/javascripts/components/Material/Nav/Blur.js b/src/assets/javascripts/components/Material/Nav/Blur.js new file mode 100644 index 000000000..0f5065c65 --- /dev/null +++ b/src/assets/javascripts/components/Material/Nav/Blur.js @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Blur { + + /** + * Blur anchors within the navigation above current page y-offset + * + * @constructor + * @param {(string|NodeList)} els - Selector or HTML elements + */ + constructor(els) { + this.els_ = (typeof els === "string") + ? document.querySelectorAll(els) + : els + + /* Initialize index and page y-offset */ + this.index_ = 0 + this.offset_ = window.pageYOffset + + /* Index anchor node offsets for fast lookup */ + this.anchors_ = [].map.call(this.els_, el => { + return document.getElementById(el.hash.substring(1)) + }) + } + + /** + * Initialize anchor states + */ + setup() { + this.update() + } + + /** + * Update anchor states + * + * Deduct the static offset of the header (56px) and sidebar offset (24px), + * see _permalinks.scss for more information. + */ + update() { + const offset = window.pageYOffset + + /* Exit when there are no anchors */ + if (this.anchors_.length === 0) + return + + /* Scroll direction is down */ + if (this.offset_ <= offset) { + for (let i = this.index_ + 1; i < this.els_.length; i++) { + if (this.anchors_[i].offsetTop - (56 + 24) <= offset) { + if (i > 0) + this.els_[i - 1].dataset.mdState = "blur" + this.index_ = i + } else { + break + } + } + + /* Scroll direction is up */ + } else { + for (let i = this.index_; i >= 0; i--) { + if (this.anchors_[i].offsetTop - (56 + 24) > offset) { + if (i > 0) + this.els_[i - 1].dataset.mdState = "" + } else { + this.index_ = i + break + } + } + } + + /* Remember current offset for next iteration */ + this.offset_ = offset + } + + /** + * Reset anchor states + */ + reset() { + Array.prototype.forEach.call(this.els_, el => { + el.dataset.mdState = "" + }) + + /* Reset index and page y-offset */ + this.index_ = 0 + this.offset_ = window.pageYOffset + } +} diff --git a/src/assets/javascripts/components/Material/Nav/Collapse.js b/src/assets/javascripts/components/Material/Nav/Collapse.js new file mode 100644 index 000000000..07fb23264 --- /dev/null +++ b/src/assets/javascripts/components/Material/Nav/Collapse.js @@ -0,0 +1,90 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Collapse { + + /** + * Expand or collapse navigation on toggle + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + } + + /** + * Animate expand and collapse smoothly + */ + update() { + const current = this.el_.getBoundingClientRect().height + + /* Expanded, so collapse */ + if (current) { + this.el_.style.maxHeight = `${current}px` + requestAnimationFrame(() => { + this.el_.dataset.mdState = "animate" + this.el_.style.maxHeight = "0px" + }) + + /* Collapsed, so expand */ + } else { + this.el_.dataset.mdState = "expand" + this.el_.style.maxHeight = "" + + /* Read height and unset pseudo-toggled state */ + const height = this.el_.getBoundingClientRect().height + this.el_.dataset.mdState = "" + + /* Set initial state and animate */ + this.el_.style.maxHeight = "0px" + requestAnimationFrame(() => { + this.el_.dataset.mdState = "animate" + this.el_.style.maxHeight = `${height}px` + }) + } + + /* Remove state on end of transition */ + const end = ev => { + ev.target.dataset.mdState = "" + ev.target.style.maxHeight = "" + + /* Only fire once, so directly remove event listener */ + ev.target.removeEventListener("transitionend", end, false) + } + this.el_.addEventListener("transitionend", end, false) + } + + /** + * Reset height and pseudo-toggled state + */ + reset() { + this.el_.dataset.mdState = "" + this.el_.style.maxHeight = "" + } +} diff --git a/src/assets/javascripts/components/Material/Nav/Scrolling.js b/src/assets/javascripts/components/Material/Nav/Scrolling.js new file mode 100644 index 000000000..b1fd58bae --- /dev/null +++ b/src/assets/javascripts/components/Material/Nav/Scrolling.js @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Scrolling { + + /** + * Set overflow scrolling on the current active pane (for iOS) + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + } + + /** + * Setup panes + */ + setup() { + + /* Initially set overflow scrolling on main pane */ + this.el_.children[1].style.webkitOverflowScrolling = "touch" + + /* Find all toggles and check which one is active */ + const toggles = this.el_.querySelectorAll("[data-md-toggle]") + Array.prototype.forEach.call(toggles, toggle => { + if (toggle.checked) { + + /* Find corresponding navigational pane */ + let pane = toggle.nextElementSibling + while (pane.tagName !== "NAV") + pane = pane.nextElementSibling + + /* Find current and parent list elements */ + const parent = toggle.parentNode.parentNode + const target = pane.children[pane.children.length - 1] + + /* Always reset all lists when transitioning */ + parent.style.webkitOverflowScrolling = "" + target.style.webkitOverflowScrolling = "touch" + } + }) + } + + /** + * Update active panes + * + * @param {Event} ev - Change event + */ + update(ev) { + + /* Find corresponding navigational pane */ + let pane = ev.target.nextElementSibling + while (pane.tagName !== "NAV") + pane = pane.nextElementSibling + + /* Find current and parent list elements */ + const parent = ev.target.parentNode.parentNode + const target = pane.children[pane.children.length - 1] + + /* Always reset all lists when transitioning */ + parent.style.webkitOverflowScrolling = "" + target.style.webkitOverflowScrolling = "" + + /* Set overflow scrolling on parent */ + if (!ev.target.checked) { + const end = () => { + parent.style.webkitOverflowScrolling = "touch" + pane.removeEventListener("transitionend", end) + } + pane.addEventListener("transitionend", end, false) + } + + /* Set overflow scrolling on target */ + if (ev.target.checked) { + const end = () => { + target.style.webkitOverflowScrolling = "touch" + pane.removeEventListener("transitionend", end, false) + } + pane.addEventListener("transitionend", end, false) + } + } + + /** + * Reset panes + */ + reset() { + + /* Reset overflow scrolling on main pane */ + this.el_.children[1].style.webkitOverflowScrolling = "" + + /* Find all toggles and check which one is active */ + const toggles = this.el_.querySelectorAll("[data-md-toggle]") + Array.prototype.forEach.call(toggles, toggle => { + if (toggle.checked) { + + /* Find corresponding navigational pane */ + let pane = toggle.nextElementSibling + while (pane.tagName !== "NAV") + pane = pane.nextElementSibling + + /* Find current and parent list elements */ + const parent = toggle.parentNode.parentNode + const target = pane.children[pane.children.length - 1] + + /* Always reset all lists when transitioning */ + parent.style.webkitOverflowScrolling = "" + target.style.webkitOverflowScrolling = "" + } + }) + } +} diff --git a/src/assets/stylesheets/modules/_drawer.scss b/src/assets/javascripts/components/Material/Search.js similarity index 75% rename from src/assets/stylesheets/modules/_drawer.scss rename to src/assets/javascripts/components/Material/Search.js index afefecffd..57cd44691 100644 --- a/src/assets/stylesheets/modules/_drawer.scss +++ b/src/assets/javascripts/components/Material/Search.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,7 +20,14 @@ * IN THE SOFTWARE. */ -@import "drawer/animation"; -@import "drawer/appearance"; -@import "drawer/layout"; -@import "drawer/typography"; \ No newline at end of file +import Lock from "./Search/Lock" +import Result from "./Search/Result" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Lock, + Result +} diff --git a/src/assets/javascripts/components/Material/Search/Lock.js b/src/assets/javascripts/components/Material/Search/Lock.js new file mode 100644 index 000000000..2726515ba --- /dev/null +++ b/src/assets/javascripts/components/Material/Search/Lock.js @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Lock { + + /** + * Lock body for full-screen search modal + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + } + + /** + * Setup locked state + */ + setup() { + this.update() + } + + /** + * Update locked state + */ + update() { + + /* Entering search mode */ + if (this.el_.checked) { + this.offset_ = window.pageYOffset + + /* Scroll to top after transition, to omit flickering */ + setTimeout(() => { + window.scrollTo(0, 0) + + /* Lock body after finishing transition */ + if (this.el_.checked) { + document.body.dataset.mdState = "lock" + } + }, 400) + + /* Exiting search mode */ + } else { + document.body.dataset.mdState = "" + + /* Scroll to former position, but wait for 100ms to prevent flashes on + iOS. A short timeout seems to do the trick */ + setTimeout(() => { + if (typeof this.offset_ !== "undefined") + window.scrollTo(0, this.offset_) + }, 100) + } + } + + /** + * Reset locked state and page y-offset + */ + reset() { + if (document.body.dataset.mdState === "lock") + window.scrollTo(0, this.offset_) + document.body.dataset.mdState = "" + } +} diff --git a/src/assets/javascripts/components/Material/Search/Result.jsx b/src/assets/javascripts/components/Material/Search/Result.jsx new file mode 100644 index 000000000..c4bfbe7ca --- /dev/null +++ b/src/assets/javascripts/components/Material/Search/Result.jsx @@ -0,0 +1,165 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import lunr from "lunr" + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Result { + + /** + * Perform search and update results on keyboard events + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + * @param {(Array.|Function)} data - Promise or array providing data + */ + constructor(el, data) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + + /* Set data and create metadata and list elements */ + this.data_ = data + this.meta_ = ( +
    + Type to start searching +
    + ) + this.list_ = ( +
      + ) + + /* Inject created elements */ + this.el_.appendChild(this.meta_) + this.el_.appendChild(this.list_) + + /* Truncate a string after the given number of characters - this is not + a reasonable approach, since the summaries kind of suck. It would be + better to create something more intelligent, highlighting the search + occurrences and making a better summary out of it */ + this.truncate_ = function(string, n) { + let i = n + if (string.length > i) { + while (string[i] !== " " && --i > 0); + return `${string.substring(0, i)}...` + } + return string + } + } + + /** + * Update search results + * + * @param {Event} ev - Input or focus event + */ + update(ev) { + + /* Initialize index, if this has not be done yet */ + if (ev.type === "focus" && !this.index_) { + + /* Initialize index */ + const init = data => { + this.index_ = lunr(function() { + /* eslint-disable no-invalid-this, lines-around-comment */ + this.field("title", { boost: 10 }) + this.field("text") + this.ref("location") + /* eslint-enable no-invalid-this, lines-around-comment */ + }) + + /* Index documents */ + this.data_ = data.reduce((docs, doc) => { + this.index_.add(doc) + docs[doc.location] = doc + return docs + }, {}) + } + + /* Initialize index after short timeout to account for transition */ + setTimeout(() => { + return typeof this.data_ === "function" + ? this.data_().then(init) + : init(this.data_) + }, 250) + + /* Execute search on new input event after clearing current list */ + } else if (ev.type === "keyup") { + while (this.list_.firstChild) + this.list_.removeChild(this.list_.firstChild) + + /* Perform search on index and render documents */ + const result = this.index_.search(ev.target.value) + result.forEach(item => { + const doc = this.data_[item.ref] + + /* Check if it's a anchor link on the current page */ + let [pathname] = doc.location.split("#") + pathname = pathname.replace(/^(\/?\.{2})+/g, "") + + /* Append search result */ + this.list_.appendChild( +
    1. + +
      +

      + {doc.title} +

      +

      + {this.truncate_(doc.text, 140)} +

      +
      +
      +
    2. + ) + }) + + /* Bind click handlers for anchors */ + const anchors = this.list_.querySelectorAll("[data-md-rel=anchor]") + Array.prototype.forEach.call(anchors, anchor => { + anchor.addEventListener("click", ev2 => { + const toggle = document.querySelector("[data-md-toggle=search]") + if (toggle.checked) { + toggle.checked = false + toggle.dispatchEvent(new CustomEvent("change")) + } + + /* Hack: prevent default, as the navigation needs to be delayed due + to the search body lock on mobile */ + ev2.preventDefault() + setTimeout(() => { + document.location.href = anchor.href + }, 100) + }) + }) + + /* Update search metadata */ + this.meta_.textContent = + `${result.length} search result${result.length !== 1 ? "s" : ""}` + } + } +} diff --git a/src/assets/javascripts/components/Material/Sidebar.js b/src/assets/javascripts/components/Material/Sidebar.js new file mode 100644 index 000000000..3ce1435b3 --- /dev/null +++ b/src/assets/javascripts/components/Material/Sidebar.js @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Container from "./Sidebar/Container" +import Position from "./Sidebar/Position" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Container, + Position +} diff --git a/src/assets/stylesheets/modules/base/_animation.scss b/src/assets/javascripts/components/Material/Sidebar/Container.js similarity index 62% rename from src/assets/stylesheets/modules/base/_animation.scss rename to src/assets/javascripts/components/Material/Sidebar/Container.js index 720621f68..b4a6bc038 100644 --- a/src/assets/stylesheets/modules/base/_animation.scss +++ b/src/assets/javascripts/components/Material/Sidebar/Container.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -21,53 +21,45 @@ */ /* ---------------------------------------------------------------------------- - * Base animation + * Class * ------------------------------------------------------------------------- */ -/* - * Animate color on hover - */ -a { - transition: color .25s; -} +export default class Container { -/* - * Overlay - */ -.overlay { - transition: opacity .25s, - width .0s .25s, - height .0s .25s; - - /* - * Expanded drawer + /** + * Monitor window height to stretch sidebar container to viewport + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element */ - #toggle-drawer:checked ~ &, - .toggle-drawer & { - transition: opacity .25s, - width .0s, - height .0s; + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + + /* Retrieve parent node */ + this.parent_ = this.el_.parentNode + } + + /** + * Initialize container state + */ + setup() { + this.update() + } + + /** + * Update minimum height + */ + update() { + const height = this.parent_.offsetHeight - this.el_.offsetTop + this.el_.style.minHeight = `${height}px` + } + + /** + * Reset minimum height + */ + reset() { + this.el_.style.minHeight = "" } } - -/* - * Application header - check for javascript to omit flashing - */ -.js .header { - transition: background .6s, - color .6s; - - /* - * Status bar - */ - &:before { - transition: background .6s; - } -} - -/* - * Extended visible touch area on icon - */ -.button .icon { - transition: background .25s; -} \ No newline at end of file diff --git a/src/assets/javascripts/components/Material/Sidebar/Position.js b/src/assets/javascripts/components/Material/Sidebar/Position.js new file mode 100644 index 000000000..27edad313 --- /dev/null +++ b/src/assets/javascripts/components/Material/Sidebar/Position.js @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Position { + + /** + * Set sidebars to locked state and limit height to parent node + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + + /* Initialize parent container and current height */ + this.parent_ = this.el_.parentNode + this.height_ = 0 + } + + /** + * Initialize sidebar state + */ + setup() { + this.offset_ = this.el_.offsetTop - this.parent_.offsetTop + this.update() + } + + /** + * Update locked state and height + * + * The inner height of the window (= the visible area) is the maximum + * possible height for the stretching sidebar. This height must be deducted + * by the top offset of the parent container, which accounts for the fixed + * header, setting the baseline. Depending on the page y-offset, the top + * offset of the sidebar must be taken into account, as well as the case + * where the window is scrolled beyond the sidebar container. + */ + update() { + const offset = window.pageYOffset + const visible = window.innerHeight + + /* Calculate bounds of sidebar container */ + this.bounds_ = { + top: this.parent_.offsetTop, + bottom: this.parent_.offsetTop + this.parent_.offsetHeight + } + + /* Calculate new offset and height */ + const height = visible - this.bounds_.top + - Math.max(0, this.offset_ - offset) + - Math.max(0, offset + visible - this.bounds_.bottom) + + /* If height changed, update element */ + if (height !== this.height_) + this.el_.style.height = `${this.height_ = height}px` + + /* Sidebar should be locked, as we're below parent offset */ + if (offset >= this.offset_) { + if (this.el_.dataset.mdState !== "lock") + this.el_.dataset.mdState = "lock" + + /* Sidebar should be unlocked, if locked */ + } else if (this.el_.dataset.mdState === "lock") { + this.el_.dataset.mdState = "" + } + } + + /** + * Reset locked state and height + */ + reset() { + this.el_.dataset.mdState = "" + this.el_.style.height = "" + this.height_ = 0 + } +} diff --git a/src/assets/stylesheets/modules/_search.scss b/src/assets/javascripts/components/Material/Source.js similarity index 74% rename from src/assets/stylesheets/modules/_search.scss rename to src/assets/javascripts/components/Material/Source.js index 77914e3b1..f26e7ad83 100644 --- a/src/assets/stylesheets/modules/_search.scss +++ b/src/assets/javascripts/components/Material/Source.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,7 +20,14 @@ * IN THE SOFTWARE. */ -@import "search/animation"; -@import "search/appearance"; -@import "search/layout"; -@import "search/typography"; \ No newline at end of file +import Adapter from "./Source/Adapter" +import Repository from "./Source/Repository" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + Adapter, + Repository +} diff --git a/src/assets/stylesheets/modules/_article.scss b/src/assets/javascripts/components/Material/Source/Adapter.js similarity index 77% rename from src/assets/stylesheets/modules/_article.scss rename to src/assets/javascripts/components/Material/Source/Adapter.js index 0529e777a..45bd8efcc 100644 --- a/src/assets/stylesheets/modules/_article.scss +++ b/src/assets/javascripts/components/Material/Source/Adapter.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016 Martin Donath + * Copyright (c) 2016-2017 Martin Donath * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to @@ -20,7 +20,12 @@ * IN THE SOFTWARE. */ -@import "article/animation"; -@import "article/appearance"; -@import "article/layout"; -@import "article/typography"; \ No newline at end of file +import GitHub from "./Adapter/GitHub" + +/* ---------------------------------------------------------------------------- + * Module + * ------------------------------------------------------------------------- */ + +export default { + GitHub +} diff --git a/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js b/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js new file mode 100644 index 000000000..024722009 --- /dev/null +++ b/src/assets/javascripts/components/Material/Source/Adapter/Abstract.js @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Cookies from "js-cookie" + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Abstract { + + /** + * Retrieve source information + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + + /* Retrieve base URL */ + this.base_ = this.el_.href + this.salt_ = this.hash_(this.base_) + } + + /** + * Retrieve data from Cookie or fetch from respective API + * + * @return {Promise} Promise that returns an array of facts + */ + fetch() { + return new Promise(resolve => { + const cached = Cookies.getJSON(`${this.salt_}.cache-source`) + if (typeof cached !== "undefined") { + resolve(cached) + + /* If the data is not cached in a cookie, invoke fetch and set + a cookie that automatically expires in 15 minutes */ + } else { + this.fetch_().then(data => { + Cookies.set(`${this.salt_}.cache-source`, data, { expires: 1 / 96 }) + resolve(data) + }) + } + }) + } + + /** + * Abstract private function that fetches relevant repository information + * + * @abstract + * @return {Promise} Promise that provides the facts in an array + */ + fetch_() { + throw new Error("fetch_(): Not implemented") + } + + /** + * Format a number with suffix + * + * @param {Number} number - Number to format + * @return {Number} Formatted number + */ + format_(number) { + if (number > 10000) + return `${(number / 1000).toFixed(0)}k` + else if (number > 1000) + return `${(number / 1000).toFixed(1)}k` + return number + } + + /** + * Simple hash function + * + * Taken from http://stackoverflow.com/a/7616484/1065584 + * + * @param {string} str - Input string + * @return {string} Hashed string + */ + hash_(str) { + let hash = 0 + if (str.length === 0) return hash + for (let i = 0, len = str.length; i < len; i++) { + hash = ((hash << 5) - hash) + str.charCodeAt(i) + hash |= 0 // Convert to 32bit integer + } + return hash + } +} diff --git a/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js b/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js new file mode 100644 index 000000000..243ef1d11 --- /dev/null +++ b/src/assets/javascripts/components/Material/Source/Adapter/GitHub.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +import Abstract from "./Abstract" + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class GitHub extends Abstract { + + /** + * Retrieve source information from GitHub + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + super(el) + + /* Adjust base URL to reach API endpoints */ + this.base_ = this.base_.replace("github.com/", "api.github.com/repos/") + } + + /** + * Fetch relevant source information from GitHub + * + * @return {function} Promise returning an array of facts + */ + fetch_() { + return fetch(this.base_) + .then(response => response.json()) + .then(data => { + return [ + `${this.format_(data.stargazers_count)} Stars`, + `${this.format_(data.forks_count)} Forks` + ] + }) + } +} diff --git a/src/assets/javascripts/components/Material/Source/Repository.jsx b/src/assets/javascripts/components/Material/Source/Repository.jsx new file mode 100644 index 000000000..917e5f762 --- /dev/null +++ b/src/assets/javascripts/components/Material/Source/Repository.jsx @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016-2017 Martin Donath + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +/* ---------------------------------------------------------------------------- + * Class + * ------------------------------------------------------------------------- */ + +export default class Repository { + + /** + * Render repository information + * + * @constructor + * @param {(string|HTMLElement)} el - Selector or HTML element + */ + constructor(el) { + this.el_ = (typeof el === "string") + ? document.querySelector(el) + : el + } + + /** + * Initialize the source repository + * + * @param {Array.} facts - Facts to be rendered + */ + initialize(facts) { + if (facts.length) + this.el_.children[this.el_.children.length - 1].appendChild( +
        + {facts.map(fact =>
      • {fact}
      • )} +
      + ) + + /* Finish rendering with animation */ + this.el_.dataset.mdState = "done" + } +} diff --git a/src/assets/javascripts/standalone.js b/src/assets/javascripts/standalone.js deleted file mode 100644 index 0ed044874..000000000 --- a/src/assets/javascripts/standalone.js +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Taken and adapted from https://gist.github.com/kylebarrow/1042026 - * ------------------------------------------------------------------------- */ - -/* Detect standalone mode */ -if (('standalone' in window.navigator) && window.navigator.standalone) { - - /* If you want to prevent remote links in standalone web apps opening - Mobile Safari, change 'remotes' to true */ - var node, remotes = false; - - /* Bind to document */ - document.addEventListener('click', function(event) { - node = event.target; - - /* Bubble up until we hit link or top HTML element. Warning: BODY element - is not compulsory so better to stop on HTML */ - while (node.nodeName !== 'A' && node.nodeName !== 'HTML') { - node = node.parentNode; - } - if ('href' in node && node.href.indexOf('http') !== -1 && ( - node.href.indexOf(document.location.host) !== -1 || remotes)) { - event.preventDefault(); - document.location.href = node.href; - } - }, false); -} \ No newline at end of file diff --git a/src/assets/stylesheets/_config.scss b/src/assets/stylesheets/_config.scss new file mode 100644 index 000000000..f841e9338 --- /dev/null +++ b/src/assets/stylesheets/_config.scss @@ -0,0 +1,93 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables: typography +// ---------------------------------------------------------------------------- + +// Modular typographic scale +$ms-base: 1.6rem; +$ms-ratio: $major-third; + +// ---------------------------------------------------------------------------- +// Variables: breakpoints +// ---------------------------------------------------------------------------- + +// stylelint-disable unit-whitelist + +// Device-specific breakpoints +$break-devices: ( + mobile: ( + portrait: px2em(220px) px2em(479px), + landscape: px2em(480px) px2em(719px) + ), + tablet: ( + portrait: px2em(720px) px2em(959px), + landscape: px2em(960px) px2em(1219px) + ), + screen: ( + small: px2em(1220px) px2em(1599px), + medium: px2em(1600px) px2em(1999px), + large: px2em(2000px) + ) +); + +// stylelint-enable unit-whitelist + +// ---------------------------------------------------------------------------- +// Variables: base colors +// ---------------------------------------------------------------------------- + +// Primary and accent colors +$md-color-primary: $clr-indigo-500; +$md-color-accent: $clr-indigo-a200; + +// Shades of black +$md-color-black: hsla(0, 0%, 0%, 0.87); +$md-color-black--light: hsla(0, 0%, 0%, 0.54); +$md-color-black--lighter: hsla(0, 0%, 0%, 0.26); +$md-color-black--lightest: hsla(0, 0%, 0%, 0.07); +$md-color-black--transparent: hsla(0, 0%, 0%, 0); + +// Shades of white +$md-color-white: hsla(0, 0%, 100%, 1); +$md-color-white--light: hsla(0, 0%, 100%, 0.7); +$md-color-white--lighter: hsla(0, 0%, 100%, 0.3); +$md-color-white--lightest: hsla(0, 0%, 100%, 0.12); +$md-color-white--transparent: hsla(0, 0%, 100%, 0); + +// ---------------------------------------------------------------------------- +// Variables: sizing and spacing +// ---------------------------------------------------------------------------- + +// Icons +$md-icon-size: $ms-base * 1.5; +$md-icon-padding: $ms-base * 0.5; +$md-icon-margin: $ms-base * 0.25; + +// Code blocks +$md-code-background: hsla(0, 0%, 92.5%, 0.5); +$md-code-color: #37474F; + +// Keystrokes +$md-keyboard-background: #FCFCFC; +$md-keyboard-color: #555555; diff --git a/src/assets/stylesheets/_reset.scss b/src/assets/stylesheets/_reset.scss deleted file mode 100644 index 57bfb1a67..000000000 --- a/src/assets/stylesheets/_reset.scss +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Resets - * ------------------------------------------------------------------------- */ - -/* - * Enfore correct box model - the prefixed versions are necessary for older - * browsers, i.e. Chrome < 10, Firefox < 29, Safari < 6 and Android < 4 - */ -html { - box-sizing: border-box; - -moz-box-sizing: border-box; - -webkit-box-sizing: border-box; -} - -/* - * All elements shall inherit the document default - */ -*, *:before, *:after { - box-sizing: inherit; - -moz-box-sizing: inherit; - -webkit-box-sizing: inherit; -} - -/* - * 16px --> 10px, browser default - */ -html { - font-size: 62.5%; - text-size-adjust: none; -} - -/* - * Reset spacing and borders for all tags - */ -html, body, div, span, applet, object, iframe, -h1, h2, h3, h4, h5, h6, p, blockquote, pre, -a, abbr, acronym, address, big, cite, code, -del, dfn, em, img, ins, kbd, q, s, samp, -small, strike, strong, sub, sup, tt, var, -b, u, i, center, -dl, dt, dd, ol, ul, li, -fieldset, form, label, legend, -table, caption, tbody, tfoot, thead, tr, th, td, -article, aside, canvas, details, embed, -figure, figcaption, footer, header, hgroup, main, -menu, nav, output, ruby, section, summary, -time, mark, audio, video { - margin: 0; - padding: 0; - border: 0; -} - -/* - * Enforce correct rendering of main element - missing in user agent stylesheet - * of IE11 on Windows 7. - */ -main { - display: block; -} - -/* - * Reset list styles - */ -ul { - list-style: none; -} - -/* - * Reset table styles - */ -table { - border-collapse: collapse; - border-spacing: 0; -} - -/* - * Reset table cell styles - */ -td { - text-align: left; - font-weight: normal; - vertical-align: middle; -} - -/* - * Reset (native) button styles - */ -button { - outline: 0; - padding: 0; - - background: transparent; - border: none; - - font-size: inherit; -} - -/* - * Reset (native) input styles - */ -input { - @include appearance(none); - - outline: none; - border: none; -} - -/* - * Reset link styles - */ -a { - text-decoration: none; - color: inherit; -} - -/* - * Reset tap outlines on iOS and Android - */ -a, button, label, input { - -webkit-tap-highlight-color: rgba(white, 0); - -webkit-tap-highlight-color: transparent; -} - -/* - * Reset headlines - */ -h1, h2, h3, h4, h5, h6 { - font-weight: inherit; -} \ No newline at end of file diff --git a/src/assets/stylesheets/_shame.scss b/src/assets/stylesheets/_shame.scss index cd2b15733..0add3bad0 100644 --- a/src/assets/stylesheets/_shame.scss +++ b/src/assets/stylesheets/_shame.scss @@ -1,25 +1,25 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// -/* ---------------------------------------------------------------------------- - * Nothing to see here, move along - * ------------------------------------------------------------------------- */ \ No newline at end of file +// ---------------------------------------------------------------------------- +// Nothing to see here, move along +// ---------------------------------------------------------------------------- diff --git a/src/assets/stylesheets/application.palette.scss b/src/assets/stylesheets/application.palette.scss new file mode 100644 index 000000000..8cfe0f302 --- /dev/null +++ b/src/assets/stylesheets/application.palette.scss @@ -0,0 +1,218 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- + +@import "modular-scale"; +@import "material-color"; +@import "material-shadows"; + +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- + +@import "helpers/break"; +@import "helpers/px2em"; + +@import "config"; + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Color tile for presentation in theme documentation +button[data-md-color-primary], +button[data-md-color-accent] { + width: 13rem; + margin-bottom: 0.4rem; + padding: 2.4rem 0.8rem 0.4rem; + transition: + background-color 0.25s, + opacity 0.25s; + border-radius: 0.2rem; + color: $md-color-white; + font-size: ms(-1); + text-align: left; + cursor: pointer; + + // Hovered color tile + &:hover { + opacity: 0.75; + } +} + +// Build primary colors +@each $name, $color in ( + "red": $clr-red-400, + "pink": $clr-pink-500, + "purple": $clr-purple-400, + "deep-purple": $clr-deep-purple-400, + "indigo": $clr-indigo-500, + "blue": $clr-blue-500, + "light-blue": $clr-light-blue-500, + "cyan": $clr-cyan-500, + "teal": $clr-teal-500, + "green": $clr-green-500, + "light-green": $clr-light-green-600, + "lime": $clr-lime-600, + "yellow": $clr-yellow-800, + "amber": $clr-amber-600, + "orange": $clr-orange-600, + "deep-orange": $clr-deep-orange-400, + "brown": $clr-brown-500, + "grey": $clr-grey-600, + "blue-grey": $clr-blue-grey-600 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-primary="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-primary="#{$name}"] { + + // Links in typesetted content + .md-typeset a { + color: $color; + } + + // Application header (stays always on top) + .md-header { + background-color: $color; + } + + // Current or hovered link + .md-nav__link:active, + .md-nav__link--active { + color: $color; + } + + // [tablet portrait -]: Layered navigation + @include break-to-device(tablet portrait) { + + // Repository containing source + .md-nav__source { + background-color: mix($color, $md-color-black, 75%); + } + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Site title in main navigation + html & .md-nav--primary .md-nav__title--site { + background-color: $color; + } + } + + // [tablet landscape +]: Add border to table of contents + @include break-from-device(tablet landscape) { + + // Table of contents + .md-nav--secondary { + border-left: 0.4rem solid $color; + } + } + } +} + +// Build accent colors +@each $name, $color in ( + "red": $clr-red-a400, + "pink": $clr-pink-a400, + "purple": $clr-purple-a200, + "deep-purple": $clr-deep-purple-a200, + "indigo": $clr-indigo-a200, + "blue": $clr-blue-a200, + "light-blue": $clr-light-blue-a700, + "cyan": $clr-cyan-a700, + "teal": $clr-teal-a700, + "green": $clr-green-a700, + "light-green": $clr-light-green-a700, + "lime": $clr-lime-a700, + "yellow": $clr-yellow-a700, + "amber": $clr-amber-a700, + "orange": $clr-orange-a400, + "deep-orange": $clr-deep-orange-a200 +) { + + // Color tile for presentation in theme documentation + button[data-md-color-accent="#{$name}"] { + background-color: $color; + } + + // Color palette + [data-md-color-accent="#{$name}"] { + + // Typesetted content + .md-typeset { + + // Hovered and active links + a:hover, + a:active { + color: $color; + } + + // Hovered scrollbar thumb + pre::-webkit-scrollbar-thumb:hover, + .codehilite::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Active or targeted back reference + .footnote li:hover .footnote-backref:hover, + .footnote li:target .footnote-backref { + color: $color; + } + + // Active or targeted permalink + [id]:hover .headerlink:hover, + [id]:target .headerlink, + [id] .headerlink:focus { + color: $color; + } + } + + // Current or hovered link + .md-nav__link:hover { + color: $color; + } + + // Search container scrollbar thumb + .md-search__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + + // Hovered search result link + .md-search-result__link:hover { + background-color: transparentize($color, 0.9); + } + + // Wrapper for scrolling on overflow + .md-sidebar__scrollwrap::-webkit-scrollbar-thumb:hover { + background-color: $color; + } + } +} diff --git a/src/assets/stylesheets/application.scss b/src/assets/stylesheets/application.scss index dc02b3c01..6ff9ff338 100644 --- a/src/assets/stylesheets/application.scss +++ b/src/assets/stylesheets/application.scss @@ -1,49 +1,64 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// -/* ---------------------------------------------------------------------------- - * Dependencies - * ------------------------------------------------------------------------- */ +// ---------------------------------------------------------------------------- +// Dependencies +// ---------------------------------------------------------------------------- -@import "bourbon"; -@import "quantum-colors"; -@import "quantum-shadows"; +@import "modular-scale"; +@import "material-color"; +@import "material-shadows"; -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ +// ---------------------------------------------------------------------------- +// Local imports +// ---------------------------------------------------------------------------- -@import "reset"; -@import "palette"; -@import "highlight"; +@import "helpers/break"; +@import "helpers/px2em"; -@import "fonts/icon"; +@import "config"; -@import "mixins/break"; +@import "base/reset"; +@import "base/icons"; +@import "base/typeset"; -@import "modules/base"; -@import "modules/drawer"; -@import "modules/article"; -@import "modules/search"; +@import "layout/base"; +@import "layout/content"; +@import "layout/header"; +@import "layout/footer"; +@import "layout/nav"; +@import "layout/search"; +@import "layout/sidebar"; +@import "layout/source"; -@import "print"; -@import "shame"; \ No newline at end of file +@import "extensions/admonition"; +@import "extensions/codehilite"; +@import "extensions/footnotes"; +@import "extensions/permalinks"; + +@import "extensions/pymdown/arithmatex"; +@import "extensions/pymdown/critic"; +@import "extensions/pymdown/emoji"; +@import "extensions/pymdown/inlinehilite"; +@import "extensions/pymdown/tasklist"; + +@import "shame"; diff --git a/src/assets/stylesheets/base/.stylelintrc b/src/assets/stylesheets/base/.stylelintrc new file mode 100644 index 000000000..422ff2c6f --- /dev/null +++ b/src/assets/stylesheets/base/.stylelintrc @@ -0,0 +1,7 @@ +{ + "extends": "../../../../.stylelintrc", + "rules": { + "font-weight-notation": null, + "property-no-vendor-prefix": null + } +} diff --git a/src/assets/stylesheets/base/_icons.scss b/src/assets/stylesheets/base/_icons.scss new file mode 100644 index 000000000..06c43b016 --- /dev/null +++ b/src/assets/stylesheets/base/_icons.scss @@ -0,0 +1,66 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Icon placeholders +%md-icon { + font-family: "Material Icons"; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1; + text-transform: none; + white-space: nowrap; + speak: none; + word-wrap: normal; + direction: ltr; + + // Icon rendered as button + &__button { + display: inline-block; + margin: $md-icon-margin; + padding: $md-icon-padding; + font-size: $md-icon-size; + cursor: pointer; + } +} + +// Representational classes +.md-icon { + @extend %md-icon; + + // Build representational classes + @each $ligature, $name in ( + "arrow_back": "arrow-back", + "arrow_forward": "arrow-forward", + "menu": "menu", + "search": "search", + "school": "home" + ) { + &--#{$name}::before { + content: $ligature; + } + } +} diff --git a/src/assets/stylesheets/base/_reset.scss b/src/assets/stylesheets/base/_reset.scss new file mode 100644 index 000000000..7a91b4ce1 --- /dev/null +++ b/src/assets/stylesheets/base/_reset.scss @@ -0,0 +1,135 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Enforce correct box model +html { + box-sizing: border-box; +} + +// All elements shall inherit the document default +*, +*::before, +*::after { + box-sizing: inherit; +} + +// Prevent adjustments of font size after orientation changes in IE and iOS +html { + text-size-adjust: none; +} + +// Remove margin in all browsers +body { + margin: 0; +} + +// Reset horizontal rules in FF +hr { + overflow: visible; + box-sizing: content-box; +} + +// Remove gaps in underlined links in iOS >= 8 and Safari >= 8 +a { + -webkit-text-decoration-skip: objects; +} + +// Reset tap outlines on iOS and Android +a, +button, +label, +input { + -webkit-tap-highlight-color: transparent; +} + +// Reset link styles +a { + color: inherit; + text-decoration: none; + + // Remove outline on focused or active links + &:active, + &:hover { + outline-width: 0; + } +} + +// Normalize font-size in all browsers +small { + font-size: 80%; +} + +// Prevent subscript and superscript from affecting line-height +sub, +sup { + position: relative; + font-size: 80%; + line-height: 0; + vertical-align: baseline; +} + +// Correct subscript offset +sub { + bottom: -0.25em; +} + +// Correct superscript offset +sup { + top: -0.5em; +} + +// Remove borders on images +img { + border-style: none; +} + +// Reset table styles +table { + border-collapse: collapse; + border-spacing: 0; +} + +// Reset table cell styles +td, +th { + font-weight: normal; + vertical-align: top; +} + +// Reset (native) button styles +button { + padding: 0; + border: 0; + outline: 0; + background: transparent; + font-size: inherit; +} + +// Reset (native) input styles +input { + border: 0; + outline: 0; +} diff --git a/src/assets/stylesheets/base/_typeset.scss b/src/assets/stylesheets/base/_typeset.scss new file mode 100644 index 000000000..2eced7319 --- /dev/null +++ b/src/assets/stylesheets/base/_typeset.scss @@ -0,0 +1,434 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules: font definitions +// ---------------------------------------------------------------------------- + +// Enable font-smoothing in Webkit and FF +body { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +// Default fonts +body, +input { + color: $md-color-black; + // font-family: "Roboto", "Helvetica Neue", Helvetica, Arial, sans-serif; + font-feature-settings: "kern", "onum", "liga"; + font-weight: 400; + + // Use system fonts, if browser doesn't support webfonts + .no-fontface & { + font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; + } +} + +// Proportionally spaced fonts +pre, +code, +kbd { + color: $md-color-black; + // font-family: "Roboto Mono", "Courier New", Courier, monospace; + font-feature-settings: "kern", "onum", "liga"; + font-weight: 400; + + // Use system fonts, if browser doesn't support webfonts + .no-fontface & { + font-family: "Courier New", Courier, monospace; + } +} + +// ---------------------------------------------------------------------------- +// Rules: typesetted content +// ---------------------------------------------------------------------------- + +// Content that is typeset - if possible, all margins, paddings and font sizes +// should be set in ems, so nested blocks (e.g. Admonition) render correctly, +// except headlines that should only appear on the top level and need to have +// consistent spacing due to layout constraints. +.md-typeset { + font-size: ms(0); + line-height: 1.6; + + // Colors should be kept when printing + -webkit-print-color-adjust: exact; + + // Default spacing + p, + ul, + ol, + blockquote { + margin: 1em 0; + } + + // 1st level headline + h1 { + margin: 0 0 4rem; + color: $md-color-black--light; + font-size: ms(3); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.3; + } + + // 2nd level headline + h2 { + margin: 4rem 0 1.6rem; + font-size: ms(2); + font-weight: 300; + letter-spacing: -0.01em; + line-height: 1.4; + } + + // 3rd level headline + h3 { + margin: 3.2rem 0 1.6rem; + font-size: ms(1); + font-weight: 400; + letter-spacing: -0.01em; + line-height: 1.5; + } + + // 3rd level headline following an 2nd level headline + h2 + h3 { + margin-top: 1.6rem; + } + + // 4th level headline + h4 { + margin: 1.6rem 0; + font-size: ms(0); + font-weight: 700; + letter-spacing: -0.01em; + } + + // 5th and 6th level headline + h5, + h6 { + margin: 1.6rem 0; + color: $md-color-black--light; + font-size: ms(-1); + font-weight: 700; + letter-spacing: -0.01em; + } + + // Overrides for 5th level headline + h5 { + text-transform: uppercase; + } + + // Horizontal separators + hr { + margin: 1.5em 0; + border-bottom: 0.1rem dotted $md-color-black--lighter; + } + + // Links + a { + color: $md-color-primary; + word-break: break-word; + + // Also enable color transition on pseudo elements + &, + &::before { + transition: color 0.125s; + } + + // Hovered and active links + &:hover, + &:active { + color: $md-color-accent; + } + + // Add URLs for print + @media print { + + // Show link URL + &::after { + color: $md-color-black--light; + content: " [" attr(href) "]"; + } + } + } + + // Code blocks + code, + pre { + background-color: $md-code-background; + color: $md-code-color; + font-size: 85%; + } + + // Inline code blocks, correct relative ems for smaller font size + code { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + border-radius: 0.2rem; + box-shadow: + +0.25em * $correct 0 0 $md-code-background, + -0.25em * $correct 0 0 $md-code-background; + word-break: break-word; + box-decoration-break: clone; + + // Remove box-shadows for print + @media print { + box-shadow: none; + box-decoration-break: initial; + } + } + + // Disable containing block inside headlines + h1 code, + h2 code, + h3 code, + h4 code, + h5 code, + h6 code { + margin: 0; + background-color: transparent; + box-shadow: none; + } + + // Reset code if it's inside a link + a > code { + margin: inherit; + padding: inherit; + border-radius: none; + background-color: inherit; + color: inherit; + box-shadow: none; + } + + // Unformatted code blocks + pre { + margin: 1em 0; + padding: 1rem 1.2rem; + border-radius: 0.2rem; + line-height: 1.4; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + padding: 1rem 1.6rem; + border-radius: 0; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + + // Reset, if code is wrapped inside pre tag + > code { + margin: 0; + background-color: transparent; + font-size: inherit; + box-shadow: none; + box-decoration-break: none; + } + } + + // Keystrokes + kbd { + $correct: 1 / 0.85; + + padding: 0 0.25em * $correct; + border: 0.1rem solid darken($md-keyboard-background, 20%); + border-radius: 0.2rem; + border-bottom-color: darken($md-keyboard-background, 25%); + background-color: $md-keyboard-background; + color: $md-keyboard-color; + font-size: 85%; + box-shadow: 0 0.1rem 0 darken($md-keyboard-background, 30%); + word-break: break-word; + } + + // Text highlighting marker + mark { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + box-shadow: + +0.25em 0 0 transparentize($clr-yellow-500, 0.5), + -0.25em 0 0 transparentize($clr-yellow-500, 0.5); + word-break: break-word; + box-decoration-break: clone; + } + + // Abbreviations + abbr { + border-bottom: 0.1rem dotted $md-color-black--light; + cursor: help; + } + + // Small text + small { + opacity: 0.75; + } + + // Superscript and subscript + sup, + sub { + margin-left: 0.0625em * 1 / 0.8; + } + + // Blockquotes, possibly nested + blockquote { + padding-left: 1.2rem; + border-left: 0.4rem solid $md-color-black--lighter; + color: $md-color-black--light; + } + + // Unordered lists + ul { + list-style-type: disc; + } + + // Unordered and ordered lists + ul, + ol { + margin-left: 0.625em; + padding: 0; + + // Nested ordered lists + ol { + list-style-type: lower-alpha; + + // Triply nested ordered list + ol { + list-style-type: lower-roman; + } + } + + // List elements + li { + margin-bottom: 0.5em; + margin-left: 1.25em; + + // Decrease vertical spacing + p, + blockquote { + margin: 0.5em 0; + } + + // Remove margin on last element + &:last-child { + margin-bottom: 0; + } + + // Nested lists + ul, + ol { + margin: 0.5em 0 0.5em 0.625em; + } + } + } + + // Limit width to container + iframe, + img, + svg { + max-width: 100%; + } + + // Data tables + table:not([class]) { + @include z-depth(2); + + margin: 2em 0; + border-radius: 0.2rem; + font-size: ms(-1); + overflow: hidden; + + // Semi-cool overflow solution, in case JavaScript is not available + .no-js & { + display: inline-block; + max-width: 100%; + margin: 0.8em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + // Table headings and cells + th:not([align]), + td:not([align]) { + text-align: left; + } + + // Table headings + th { + min-width: 10rem; + padding: 1.2rem 1.6rem; + background-color: $md-color-black--light; + color: $md-color-white; + vertical-align: top; + } + + // Table cells + td { + padding: 1.2rem 1.6rem; + border-top: 0.1rem solid $md-color-black--lightest; + vertical-align: top; + } + + // Remove top border on first row + tr:first-child td { + border-top: 0; + } + + // Do not wrap links in tables + a { + word-break: normal; + } + } + + // Data table wrapper, in case JavaScript is available + .md-typeset__table { + margin: 1.6em -1.6rem; + overflow-x: auto; + -webkit-overflow-scrolling: touch; + + // Data tables + table { + display: inline-block; + margin: 0 1.6rem; + } + } +} diff --git a/src/assets/stylesheets/extensions/_admonition.scss b/src/assets/stylesheets/extensions/_admonition.scss new file mode 100644 index 000000000..b382e19d1 --- /dev/null +++ b/src/assets/stylesheets/extensions/_admonition.scss @@ -0,0 +1,108 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Admonition extension +.admonition { + position: relative; + margin: 1.5625em 0; + padding: 0.8rem 1.2rem; + border-left: 3.2rem solid transparentize($clr-blue-a200, 0.6); + border-radius: 0.2rem; + background-color: transparentize($clr-blue-a200, 0.85); + font-size: ms(-1); + + // Icon + &::before { + @extend %md-icon; + + position: absolute; + left: -2.6rem; + color: $md-color-white; + font-size: 2rem; + content: "edit"; + vertical-align: -0.25em; + } + + // Remove spacing on first element + :first-child { + margin-top: 0; + } + + // Remove spacing on last element + :last-child { + margin-bottom: 0; + } + + // Build representational classes + @each $names, $appearance in ( + summary tldr: $clr-light-blue-a400 "subject", + tip hint important : $clr-teal-a700 "whatshot", + success check done: $clr-green-a400 "done", + warning caution attention: $clr-orange-a400 "warning", + failure fail missing: $clr-red-a200 "clear", + danger error: $clr-red-a400 "flash_on", + bug: $clr-pink-a400 "bug_report" + ) { + $tint: nth($appearance, 1); + $icon: nth($appearance, 2); + + // Define base class + &%#{nth($names, 1)}, + &.#{nth($names, 1)} { + border-color: transparentize($tint, 0.6); + background-color: transparentize($tint, 0.85); + + // Icon + &::before { + content: $icon; + } + } + + // Define synonyms for base class + @if length($names) > 1 { + @for $n from 2 through length($names) { + &.#{nth($names, $n)} { + @extend .admonition%#{nth($names, 1)}; + } + } + } + } +} + +// Title +.admonition-title { + font-weight: 700; + + // Remove bottom spacing for title + html & { + margin-bottom: 0; + } + + // Remove top spacing for first element following title + html & + * { + margin-top: 0; + } +} diff --git a/src/assets/stylesheets/extensions/_codehilite.scss b/src/assets/stylesheets/extensions/_codehilite.scss new file mode 100644 index 000000000..c2c97bc75 --- /dev/null +++ b/src/assets/stylesheets/extensions/_codehilite.scss @@ -0,0 +1,351 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +// Operators +$codehilite-operator: inherit; +$codehilite-operator-word: inherit; + +// Generics +$codehilite-generic-emph: #000000; +$codehilite-generic-error: #AA0000; +$codehilite-generic-heading: #999999; +$codehilite-generic-output: #888888; +$codehilite-generic-prompt: #555555; +$codehilite-generic-strong: inherit; +$codehilite-generic-subheading: #AAAAAA; +$codehilite-generic-traceback: #AA0000; + +// Diffs +$codehilite-diff-deleted: #FFDDDD; +$codehilite-diff-inserted: #DDFFDD; + +// Keywords +$codehilite-keyword: #3B78E7; +$codehilite-keyword-constant: #A71D5D; +$codehilite-keyword-declaration: #3B78E7; +$codehilite-keyword-namespace: #3B78E7; +$codehilite-keyword-pseudo: #A71D5D; +$codehilite-keyword-reserved: #3E61A2; +$codehilite-keyword-type: #3E61A2; + +// Comments +$codehilite-comment: #999999; +$codehilite-comment-multiline: #999999; +$codehilite-comment-preproc: #666666; +$codehilite-comment-single: #999999; +$codehilite-comment-shebang: #999999; +$codehilite-comment-special: #999999; + +// Names +$codehilite-name-attribute: #C2185B; +$codehilite-name-builtin: #C2185B; +$codehilite-name-builtin-pseudo: #3E61A2; +$codehilite-name-class: #C2185B; +$codehilite-name-constant: #3E61A2; +$codehilite-name-decorator: #666666; +$codehilite-name-entity: #666666; +$codehilite-name-exception: #C2185B; +$codehilite-name-function: #C2185B; +$codehilite-name-label: #3B5179; +$codehilite-name-namespace: #EC407A; +$codehilite-name-tag: #3B78E7; +$codehilite-name-variable: #3E61A2; +$codehilite-name-variable-class: #3E61A2; +$codehilite-name-variable-instance: #3E61A2; +$codehilite-name-variable-global: #3E61A2; +$codehilite-name-extension: #EC407A; + +// Numbers +$codehilite-literal-number: #E74C3C; +$codehilite-literal-number-float: #E74C3C; +$codehilite-literal-number-hex: #E74C3C; +$codehilite-literal-number-integer: #E74C3C; +$codehilite-literal-number-integer-long: #E74C3C; +$codehilite-literal-number-oct: #E74C3C; + +// Strings +$codehilite-literal-string: #0D904F; +$codehilite-literal-string-backticks: #0D904F; +$codehilite-literal-string-char: #0D904F; +$codehilite-literal-string-doc: #999999; +$codehilite-literal-string-double: #0D904F; +$codehilite-literal-string-escape: #183691; +$codehilite-literal-string-heredoc: #183691; +$codehilite-literal-string-interpol: #183691; +$codehilite-literal-string-other: #183691; +$codehilite-literal-string-regex: #009926; +$codehilite-literal-string-single: #0D904F; +$codehilite-literal-string-symbol: #0D904F; + +// Miscellaneous +$codehilite-error: #A61717; +$codehilite-whitespace: transparent; + +// ---------------------------------------------------------------------------- +// Rules: syntax highlighting +// ---------------------------------------------------------------------------- + +// Codehilite extension +.codehilite { + + // Operators + .o { color: $codehilite-operator; } + .ow { color: $codehilite-operator-word; } + + // Generics + .ge { color: $codehilite-generic-emph; } + .gr { color: $codehilite-generic-error; } + .gh { color: $codehilite-generic-heading; } + .go { color: $codehilite-generic-output; } + .gp { color: $codehilite-generic-prompt; } + .gs { color: $codehilite-generic-strong; } + .gu { color: $codehilite-generic-subheading; } + .gt { color: $codehilite-generic-traceback; } + + // Diffs + .gd { background-color: $codehilite-diff-deleted; } + .gi { background-color: $codehilite-diff-inserted; } + + // Keywords + .k { color: $codehilite-keyword; } + .kc { color: $codehilite-keyword-constant; } + .kd { color: $codehilite-keyword-declaration; } + .kn { color: $codehilite-keyword-namespace; } + .kp { color: $codehilite-keyword-pseudo; } + .kr { color: $codehilite-keyword-reserved; } + .kt { color: $codehilite-keyword-type; } + + // Comments + .c { color: $codehilite-comment; } + .cm { color: $codehilite-comment-multiline; } + .cp { color: $codehilite-comment-preproc; } + .c1 { color: $codehilite-comment-single; } + .ch { color: $codehilite-comment-shebang; } + .cs { color: $codehilite-comment-special; } + + // Names + .na { color: $codehilite-name-attribute; } + .nb { color: $codehilite-name-builtin; } + .bp { color: $codehilite-name-builtin-pseudo; } + .nc { color: $codehilite-name-class; } + .no { color: $codehilite-name-constant; } + .nd { color: $codehilite-name-entity; } + .ni { color: $codehilite-name-entity; } + .ne { color: $codehilite-name-exception; } + .nf { color: $codehilite-name-function; } + .nl { color: $codehilite-name-label; } + .nn { color: $codehilite-name-namespace; } + .nt { color: $codehilite-name-tag; } + .nv { color: $codehilite-name-variable; } + .vc { color: $codehilite-name-variable-class; } + .vg { color: $codehilite-name-variable-global; } + .vi { color: $codehilite-name-variable-instance; } + .nx { color: $codehilite-name-extension; } + + // Numbers + .m { color: $codehilite-literal-number; } + .mf { color: $codehilite-literal-number-float; } + .mh { color: $codehilite-literal-number-hex; } + .mi { color: $codehilite-literal-number-integer; } + .il { color: $codehilite-literal-number-integer-long; } + .mo { color: $codehilite-literal-number-oct; } + + // Strings + .s { color: $codehilite-literal-string; } + .sb { color: $codehilite-literal-string-backticks; } + .sc { color: $codehilite-literal-string-char; } + .sd { color: $codehilite-literal-string-doc; } + .s2 { color: $codehilite-literal-string-double; } + .se { color: $codehilite-literal-string-escape; } + .sh { color: $codehilite-literal-string-heredoc; } + .si { color: $codehilite-literal-string-interpol; } + .sx { color: $codehilite-literal-string-other; } + .sr { color: $codehilite-literal-string-regex; } + .s1 { color: $codehilite-literal-string-single; } + .ss { color: $codehilite-literal-string-symbol; } + + // Miscellaneous + .err { color: $codehilite-error; } + .w { color: $codehilite-whitespace; } + + // Highlighted lines + .hll { + display: block; + margin: 0 -1.2rem; + padding: 0 1.2rem; + background-color: transparentize($clr-yellow-500, 0.5); + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0 -1.6rem; + padding: 0 1.6rem; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: layout +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // If code blocks are wrapped with codehilite, the styles must be adjusted + // so the marker stretches to the whole width and the padding is respected + .codehilite { + margin: 1em 0; + padding: 1rem 1.2rem 0.8rem; + border-radius: 0.2rem; + background-color: $md-code-background; + color: $md-code-color; + line-height: 1.4; + overflow: auto; + -webkit-overflow-scrolling: touch; + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + + // Hack: set pre-tag to inline-block, in order to stetch the content on + // overflow correctly to the whole width + pre { + display: inline-block; + min-width: 100%; + margin: 0; + padding: 0; + background-color: transparent; + overflow: visible; + vertical-align: top; + } + } + + // Block with line numbers + .codehilitetable { + display: block; + margin: 1em 0; + border-radius: 0.2em; + font-size: ms(0); + overflow: hidden; + + // Set table elements to block layout, because otherwise the whole flexbox + // hacking won't work correctly + tbody, + td { + display: block; + padding: 0; + } + + // We need to use flexbox layout, because otherwise it's not possible to + // make the code container scroll while keeping the line numbers static + tr { + display: flex; + } + + // The pre tags are nested inside a table, so we need to remove the + // margin because it collapses below all the overflows + .codehilite, + .linenodiv { + margin: 0; + border-radius: 0; + } + + // Add spacing to line number container + .linenodiv { + padding: 1rem 1.2rem 0.8rem; + + // Stretch the line number container vertically, so it always aligns with + // the code container, even when there's a scrollbar. + &, + & > pre { + height: 100%; + } + } + + // Disable user selection, so code can be easily copied without + // accidentally also copying the line numbers + .linenos { + background-color: $md-color-black--lightest; + color: $md-color-black--lighter; + user-select: none; + + // Reset spacings + pre { + margin: 0; + padding: 0; + background-color: transparent; + color: inherit; + text-align: right; + } + } + + // The table cell containing the code container wrapper and code should + // stretch horizontally to the remaining space + .code { + flex: 1; + overflow: hidden; + } + } + + // Full-width container + > .codehilite { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + padding: 1rem 1.6rem 0.8rem; + border-radius: 0; + } + } + + // Full-width container + > .codehilitetable { + box-shadow: none; + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 1em -1.6rem; + border-radius: 0; + + // Increase spacing + .codehilite, + .linenodiv { + padding: 1rem 1.6rem; + } + } + } +} diff --git a/src/assets/stylesheets/extensions/_footnotes.scss b/src/assets/stylesheets/extensions/_footnotes.scss new file mode 100644 index 000000000..df4bb778e --- /dev/null +++ b/src/assets/stylesheets/extensions/_footnotes.scss @@ -0,0 +1,107 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Footnotes extension + .footnote { + color: $md-color-black--light; + font-size: ms(-1); + + // Remove additional spacing on footnotes + ol { + margin-left: 0; + } + + // Footnote + li { + transition: color 0.25s; + + // Un-targeted footnote + &::before { + display: block; + height: 0; + } + + // Darken color for targeted footnote + &:target { + color: $md-color-black; + } + + // Targeted footnote + &:target::before { + margin-top: -(5.6rem + 2.4rem + 1rem); + padding-top: (5.6rem + 2.4rem + 1rem); + pointer-events: none; + } + + // Remove spacing on first element + :first-child { + margin-top: 0; + } + + // Make back references visible on hover + &:hover .footnote-backref, + &:target .footnote-backref { + transform: translateX(0); + opacity: 1; + } + + // Active or targeted back reference + &:hover .footnote-backref:hover, + &:target .footnote-backref { + color: $md-color-accent; + } + } + } + + // Footnote back-reference + .footnote-backref { + @extend %md-icon; + + position: absolute; + transform: translateX(0.5rem); + transition: + transform 0.25s 0.125s, + color 0.25s, + opacity 0.125s 0.125s; + color: $md-color-black--lighter; + font-size: 1.5625em; + opacity: 0; + vertical-align: middle; + + // Hack: remove Unicode arrow for icon + &::first-letter { + font-size: 0; + } + + // Back reference icon + &::after { + content: "keyboard_return"; + } + } +} diff --git a/src/assets/stylesheets/extensions/_permalinks.scss b/src/assets/stylesheets/extensions/_permalinks.scss new file mode 100644 index 000000000..8c910fa9e --- /dev/null +++ b/src/assets/stylesheets/extensions/_permalinks.scss @@ -0,0 +1,110 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Permalinks extension + .headerlink { + display: inline-block; + margin-left: 1rem; + transform: translate(0, 0.5rem); + transition: + transform 0.25s 0.25s, + color 0.25s, + opacity 0.125s 0.25s; + opacity: 0; + + // Higher specificity for color due to palettes integration + html body & { + color: $md-color-black--lighter; + } + + // Hide for print + @media print { + display: none; + } + } + + // All headers with permalinks have ids + [id] { + + // Add spacing to anchor for offset + &::before { + display: inline-block; + content: ""; + } + + // Targeted anchor + &:target::before { + margin-top: -(5.6rem + 2.4rem + 1.8rem); + padding-top: (5.6rem + 2.4rem + 1.8rem); + } + + // Make permalink visible on hover + &:hover .headerlink, + &:target .headerlink, + & .headerlink:focus { + transform: translate(0, 0); + opacity: 1; + } + + // Active or targeted permalink + &:hover .headerlink:hover, + &:target .headerlink, + & .headerlink:focus { + color: $md-color-accent; + } + } + + // Hide anchor for top-level heading, as it makes no sense + h1[id] .headerlink { + display: none; + } + + // Correct anchor offset for link blurring + @each $level, $delta in ( + h2: 0.2rem, + h3: 0.4rem, + h4: 0.6rem, + h5: 1rem, + h6: 1rem + ) { + + // Un-targeted anchor + #{$level}[id]::before { + display: block; + margin-top: -$delta; + padding-top: $delta; + } + + // Targeted anchor (56px from header, 24px from sidebar offset) + #{$level}[id]:target::before { + margin-top: -(5.6rem + 2.4rem + $delta); + padding-top: (5.6rem + 2.4rem + $delta); + } + } +} diff --git a/src/assets/stylesheets/extensions/pymdown/_arithmatex.scss b/src/assets/stylesheets/extensions/pymdown/_arithmatex.scss new file mode 100644 index 000000000..5a5cd30f6 --- /dev/null +++ b/src/assets/stylesheets/extensions/pymdown/_arithmatex.scss @@ -0,0 +1,54 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// stylelint-disable selector-class-pattern + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // MathJax integration - add padding to omit vertical scrollbar + .MJXc-display { + margin: 0.75em 0; + padding: 0.25em 0; + overflow: auto; + -webkit-overflow-scrolling: touch; + } + + // Stretch top-level containers + > p > .MJXc-display { + + // [mobile -]: Stretch to whole width + @include break-to-device(mobile) { + margin: 0.75em -1.6rem; + padding: 0.25em 1.6rem; + } + } + + // Remove outline on tab index + .MathJax_CHTML { + outline: 0; + } +} diff --git a/src/assets/stylesheets/extensions/pymdown/_critic.scss b/src/assets/stylesheets/extensions/pymdown/_critic.scss new file mode 100644 index 000000000..f9f0df06d --- /dev/null +++ b/src/assets/stylesheets/extensions/pymdown/_critic.scss @@ -0,0 +1,93 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Deletions, additions and comments + del.critic, + ins.critic, + .comment.critic { + margin: 0 0.25em; + padding: 0.0625em 0; + border-radius: 0.2rem; + box-decoration-break: clone; + } + + // Deletion + del.critic { + background-color: $codehilite-diff-deleted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-deleted, + -0.25em 0 0 $codehilite-diff-deleted; + } + + // Addition + ins.critic { + background-color: $codehilite-diff-inserted; // TODO: dependent on order of inclusion + box-shadow: + +0.25em 0 0 $codehilite-diff-inserted, + -0.25em 0 0 $codehilite-diff-inserted; + } + + // Comment + .critic.comment { + background-color: $md-code-background; // TODO: rename, centralize somehow + color: $md-code-color; + box-shadow: + +0.25em 0 0 $md-code-background, + -0.25em 0 0 $md-code-background; + + // Icon + &::before { + @extend %md-icon; + + padding-right: 0.125em; + color: $md-color-black--lighter; + content: "chat"; + vertical-align: -0.125em; + } + } + + // Block + .critic.block { + display: block; + margin: 1em 0; + padding-right: 1.6rem; + padding-left: 1.6rem; + box-shadow: none; + + // Decrease spacing on first element + :first-child { + margin-top: 0.5em; + } + + // Decrease spacing on last element + :last-child { + margin-bottom: 0.5em; + } + } +} diff --git a/src/assets/stylesheets/extensions/pymdown/_emoji.scss b/src/assets/stylesheets/extensions/pymdown/_emoji.scss new file mode 100644 index 000000000..85ec8c6ef --- /dev/null +++ b/src/assets/stylesheets/extensions/pymdown/_emoji.scss @@ -0,0 +1,35 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Correct alignment of emojis + .emojione { + width: 2rem; + vertical-align: text-top; + } +} diff --git a/src/assets/stylesheets/extensions/pymdown/_inlinehilite.scss b/src/assets/stylesheets/extensions/pymdown/_inlinehilite.scss new file mode 100644 index 000000000..adda8f0e1 --- /dev/null +++ b/src/assets/stylesheets/extensions/pymdown/_inlinehilite.scss @@ -0,0 +1,37 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Qualified class selector to distinguish inline code from code blocks + code.codehilite { + $correct: 1 / 0.85; + + margin: 0 0.25em * $correct; + padding: 0.0625em * $correct 0; + } +} diff --git a/src/assets/stylesheets/extensions/pymdown/_tasklist.scss b/src/assets/stylesheets/extensions/pymdown/_tasklist.scss new file mode 100644 index 000000000..821970247 --- /dev/null +++ b/src/assets/stylesheets/extensions/pymdown/_tasklist.scss @@ -0,0 +1,71 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Scoped in typesetted content to match specificity of regular content +.md-typeset { + + // Remove list icon on task items + .task-list-item { + position: relative; + list-style-type: none; + + // Make checkbox items align with normal list items, but position + // everything in ems for correct layout at smaller font sizes + [type="checkbox"] { + position: absolute; + top: 0.45em; + left: -2em; + } + } + + // Wrapper for list controls, in case custom checkboxes are enabled + .task-list-control { + + // Checkbox icon in unchecked state + .task-list-indicator::before { + @extend %md-icon; + + position: absolute; + top: 0.05em; + left: -1.25em; + color: $md-color-black--lighter; + font-size: 1.5em; + content: "check_box_outline_blank"; + vertical-align: -0.25em; + } + + // Checkbox icon in checked state + [type="checkbox"]:checked + .task-list-indicator::before { + content: "check_box"; + } + + // Hide original checkbox behind icon + [type="checkbox"] { + opacity: 0; + z-index: -1; + } + } +} diff --git a/src/assets/stylesheets/fonts/_icon.scss b/src/assets/stylesheets/fonts/_icon.scss deleted file mode 100644 index e66951d91..000000000 --- a/src/assets/stylesheets/fonts/_icon.scss +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Font faces - defined in base.html for correct path resolution - * ------------------------------------------------------------------------- */ - -// /* -// * Icon font -// */ -// @font-face { -// font-family: 'Icon'; -// src: url('/assets/fonts/icon.eot?52m981'); -// src: url('/assets/fonts/icon.eot?#iefix52m981') format('embedded-opentype'), -// url('/assets/fonts/icon.woff?52m981') format('woff'), -// url('/assets/fonts/icon.ttf?52m981') format('truetype'), -// url('/assets/fonts/icon.svg?52m981#icon') format('svg'); -// font-weight: normal; -// font-style: normal; -// } - -/* ---------------------------------------------------------------------------- - * Representational classes - * ------------------------------------------------------------------------- */ - -/* - * Base icon class - */ -.icon { - font-family: 'Icon'; - speak: none; - font-style: normal; - font-weight: normal; - font-variant: normal; - text-transform: none; - line-height: 1; - - /* Better Font Rendering */ - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} - -/* - * Magnifying glass - */ -.icon-search:before { - content: "\e600"; -} - -/* - * Back arrow - */ -.icon-back:before { - content: "\e601"; -} - -/* - * Link indicator - */ -.icon-link:before { - content: "\e602"; -} - -/* - * Close button - */ -.icon-close:before { - content: "\e603"; -} - -/* - * Hamburger icon - */ -.icon-menu:before { - content: "\e604"; -} - -/* - * Forward arrow - */ -.icon-forward:before { - content: "\e605"; -} - -/* - * Twitter icon - */ -.icon-twitter:before { - content: "\e606"; -} - -/* - * GitHub icon - */ -.icon-github:before { - content: "\e607"; -} - -/* - * Download icon - */ -.icon-download:before { - content: "\e608"; -} - -/* - * Star icon - */ -.icon-star:before { - content: "\e609"; -} - -/* - * Warning icon - */ -.icon-warning:before { - content: "\e610"; -} - -/* - * Star icon - */ -.icon-note:before { - content: "\e611"; -} \ No newline at end of file diff --git a/src/assets/stylesheets/helpers/_break.scss b/src/assets/stylesheets/helpers/_break.scss new file mode 100644 index 000000000..1de8b9677 --- /dev/null +++ b/src/assets/stylesheets/helpers/_break.scss @@ -0,0 +1,250 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Variables +// ---------------------------------------------------------------------------- + +/// +/// Device-specific breakpoints +/// +/// @example +/// $break-devices: ( +/// mobile: ( +/// portrait: 220px 479px, +/// landscape: 480px 719px +/// ), +/// tablet: ( +/// portrait: 720px 959px, +/// landscape: 960px 1219px +/// ), +/// screen: ( +/// small: 1220px 1599px, +/// medium: 1600px 1999px, +/// large: 2000px +/// ) +/// ); +/// +/// @group helpers +/// @access private +/// @type Map +/// +$break-devices: () !default; + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Choose minimum and maximum device widths +/// +/// @group helpers +/// @access private +/// @param {Map} $devices Map of devices +/// @return {List} Minimum and maximum width +/// +@function break-select-min-max($devices) { + $min: 1000000; + $max: 0; + @each $key, $value in $devices { + @while type-of($value) == map { + $value: break-select-min-max($value); + } + @if type-of($value) == list { + @each $number in $value { + @if type-of($number) == number { + $min: min($number, $min); + @if $max != null { + $max: max($number, $max); + } + } @else { + @error "Invalid number: #{$number}"; + } + } + } @elseif type-of($value) == number { + $min: min($value, $min); + $max: null; + } @else { + @error "Invalid value: #{$value}"; + } + } + @return $min, $max; +} + +/// +/// Select minimum and maximum widths for a device breakpoint +/// +/// @group helpers +/// @access private +/// @param {String} $device Device +/// @return {List} Minimum and maximum width +/// +@function break-select-device($device) { + $current: $break-devices; + @for $n from 1 through length($device) { + @if type-of($current) == map { + $current: map-get($current, nth($device, $n)); + } @else { + @error "Invalid device map: #{$devices}"; + } + } + @if type-of($current) == list or type-of($current) == number { + $current: (default: $current); + } + @return break-select-min-max($current); +} + +// ---------------------------------------------------------------------------- +// Mixins +// ---------------------------------------------------------------------------- + +/// +/// A minimum-maximum media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number|List} $breakpoint Number or number pair +/// +@mixin break-at($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (min-width: $breakpoint) { + @content; + } + } @elseif type-of($breakpoint) == list { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @if type-of($min) == number and type-of($max) == number { + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// An orientation media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {String} $breakpoint Orientation +/// +@mixin break-at-orientation($breakpoint) { + @if type-of($breakpoint) == string { + @media only screen and (orientation: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A maximum-aspect-ratio media query breakpoint +/// +/// @group helpers +/// @access public +/// @param {Number} $breakpoint Ratio +/// +@mixin break-at-ratio($breakpoint) { + @if type-of($breakpoint) == number { + @media only screen and (max-aspect-ratio: $breakpoint) { + @content; + } + } @else { + @error "Invalid breakpoint: #{$breakpoint}"; + } +} + +/// +/// A minimum-maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-at-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + @if nth($breakpoint, 2) != null { + $min: nth($breakpoint, 1); + $max: nth($breakpoint, 2); + @media only screen and (min-width: $min) and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A minimum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-from-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $min: nth($breakpoint, 1); + @media only screen and (min-width: $min) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} + +/// +/// A maximum media query device breakpoint +/// +/// @group helpers +/// @access public +/// @param {String|List} $breakpoint Device +/// +@mixin break-to-device($device) { + @if type-of($device) == string { + $device: $device,; + } + @if type-of($device) == list { + $breakpoint: break-select-device($device); + $max: nth($breakpoint, 2); + @media only screen and (max-width: $max) { + @content; + } + } @else { + @error "Invalid device: #{$device}"; + } +} diff --git a/src/assets/stylesheets/helpers/_px2em.scss b/src/assets/stylesheets/helpers/_px2em.scss new file mode 100644 index 000000000..a131caa4d --- /dev/null +++ b/src/assets/stylesheets/helpers/_px2em.scss @@ -0,0 +1,46 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Helpers +// ---------------------------------------------------------------------------- + +/// +/// Convert font size in px to em. +/// +/// @group helpers +/// @access public +/// @param {Number} $size Font size in px +/// @param {Number} $base Base font size +/// @return {Number} Font size in em +/// +@function px2em($size, $base: 16px) { + @if unit($size) == px { + @if unit($base) == px { + @return ($size / $base) * 1em; + } @else { + @error "Invalid base: #{$base} - unit must be 'px'"; + } + } @else { + @error "Invalid size: #{$size} - unit must be 'px'"; + } +} diff --git a/src/assets/stylesheets/layout/_base.scss b/src/assets/stylesheets/layout/_base.scss new file mode 100644 index 000000000..5ac95cb0c --- /dev/null +++ b/src/assets/stylesheets/layout/_base.scss @@ -0,0 +1,211 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules: base grid and containers +// ---------------------------------------------------------------------------- + +// Stretch container to viewport and set base font-size to 10px for simple +// calculations base on relative ems (rems). +html { + height: 100%; + font-size: 62.5%; + + // [screen medium +]: Set base font-size to 11px + @include break-from-device(screen medium) { + font-size: 68.75%; + } + + // [screen large +]: Set base font-size to 12px + @include break-from-device(screen large) { + font-size: 75%; + } +} + +// Stretch body to container and leave room for footer. +body { + position: relative; + height: 100%; + + // [tablet portrait -]: Lock body to disable scroll bubbling + @include break-to-device(tablet portrait) { + + // Lock body to viewport height (e.g. in search mode) + &[data-md-state="lock"] { + overflow: hidden; + + // Hide container on iOS, or the body will not be locked correctly + .ios & .md-container { + display: none; + } + } + } +} + +// Horizontal separators +hr { + display: block; + height: 0.1rem; + padding: 0; + border: 0; +} + +// Inline SVG container +.md-svg { + display: none; +} + +// Template-wide grid +.md-grid { + max-width: 122rem; + margin-right: auto; + margin-left: auto; +} + +// Prevent collapse of margin when setting margin on child element +.md-container, +.md-main { + overflow: auto; +} + +// Content wrapper - use display: table to make variable-height sticky footers +// work and fixed table-layout for IE, taken from http://bit.ly/2hZohXL +.md-container { + display: table; + width: 100%; + height: 100%; + table-layout: fixed; +} + +// The main content should stretch to maximum height in the table +.md-main { + display: table-row; + height: 100%; + + // Top-spacing to account for header and some additional padding + &__inner { + margin-top: 5.6rem; + padding-top: 2.4rem + 0.6rem; + overflow: auto; + + // If the browser supports calc(), no JavaScript is necessary + .csscalc & { + min-height: calc(100% - #{5.6rem - 3rem}); + + // Hack: Firefox doesn't correctly calculate min-height, as it takes the + // top margin into account which leads to the container overflowing its + // parent. For this reason we use this hack here to target only Firefox + // and see if we can find a better solution later. + + // stylelint-disable-next-line function-url-quotes + @-moz-document url-prefix() { + & { + min-height: calc(100% - 5.6rem); + } + } + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: navigational elements +// ---------------------------------------------------------------------------- + +// Toggle checkbox +.md-toggle { + display: none; +} + +// Overlay below expanded drawer +.md-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + transition: + width 0s 0.25s, + height 0s 0.25s, + opacity 0.25s; + background-color: $md-color-black--light; + opacity: 0; + z-index: 2; + + // [tablet -]: Trigger overlay + @include break-to-device(tablet) { + + // Expanded drawer + [data-md-toggle="drawer"]:checked ~ & { + width: 100%; + height: 100%; + transition: + width 0s, + height 0s, + opacity 0.25s; + opacity: 1; + } + } +} + +// ---------------------------------------------------------------------------- +// Rules: flexible elements, implemented with table layout +// ---------------------------------------------------------------------------- + +// Flexible layout container +.md-flex { + display: table; + + // Flexible layout container cell/element + &__cell { + display: table-cell; + position: relative; + vertical-align: top; + + // Shrink to minimum width + &--shrink { + width: 0%; + } + + // Stretch to maximum width + &--stretch { + display: table; + width: 100%; + table-layout: fixed; + } + } + + // Apply ellipsis in case of overflowing text + &__ellipsis { + display: table-cell; + text-overflow: ellipsis; + white-space: nowrap; + overflow: hidden; + } +} + +// ---------------------------------------------------------------------------- +// Rules: print styles +// ---------------------------------------------------------------------------- + +// Add margins to page +@page { + margin: 25mm; +} diff --git a/src/assets/stylesheets/layout/_content.scss b/src/assets/stylesheets/layout/_content.scss new file mode 100644 index 000000000..6273ffee8 --- /dev/null +++ b/src/assets/stylesheets/layout/_content.scss @@ -0,0 +1,66 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Content container +.md-content { + + // [tablet landscape +]: Add space for table of contents + @include break-from-device(tablet landscape) { + margin-right: 24.2rem; + } + + // [screen +]: Add space for table of contents + @include break-from-device(screen) { + margin-left: 24.2rem; + } + + // Define spacing + &__inner { + margin: 2.4rem 1.6rem; + + // [screen +]: Increase spacing + @include break-from-device(screen) { + margin: 2.4rem; + } + } + + // Icons (edit button) + &__edit { + @extend %md-icon__button; + + float: right; + + // [tablet portrait -]: Align edit link with search icon + @include break-to-device(tablet portrait) { + margin-right: -0.8rem; + } + + // Hide for print + @media print { + display: none; + } + } +} diff --git a/src/assets/stylesheets/layout/_footer.scss b/src/assets/stylesheets/layout/_footer.scss new file mode 100644 index 000000000..f30f2aeb3 --- /dev/null +++ b/src/assets/stylesheets/layout/_footer.scss @@ -0,0 +1,175 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application footer +.md-footer { + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within footer +.md-footer-nav { + background-color: $md-color-black; + color: $md-color-white; + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Links to previous and next page + &__link { + padding-top: 2.8rem; + padding-bottom: 0.8rem; + transition: opacity 0.25s; + + // [mobile landscape +]: Set proportional width + @include break-from-device(mobile landscape) { + width: 50%; + } + + // Hovered link + &:hover { + opacity: 0.7; + } + + // Link to previous page + &--prev { + width: 25%; + float: left; + + // Title + .md-footer-nav__title { + + // [mobile portrait -]: Hide title for previous page + @include break-to-device(mobile portrait) { + display: none; + } + } + } + + // Link to next page + &--next { + width: 75%; + float: right; + text-align: right; + } + } + + // Icons + &__icon { + @extend %md-icon__button; + + transition: background 0.25s; + } + + // Link title - set line height to match icon for correct alignment + &__title { + position: relative; + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + } + + // Link direction + &__direction { + position: absolute; + right: 0; + left: 0; + margin-top: -2rem; + padding: 0 2rem; + color: $md-color-white--light; + font-size: 1.5rem; + } +} + +// Non-navigational information +.md-footer-meta { + background: opacify($md-color-black, 0.025); + + // Set spacing + &__inner { + padding: 0.4rem; + overflow: auto; + } + + // Use a decent color for non-hovered links and ensure specificity + html &.md-typeset a { + color: $md-color-white--light; + } +} + +// Copyright and theme information +.md-footer-copyright { + margin: 0 1.2rem; + padding: 0.8rem 0; + color: $md-color-white--lighter; + font-size: ms(-1); + + // [tablet portrait +]: Show next to social media links + @include break-from-device(tablet portrait) { + max-width: 75%; + float: left; + } + + // Highlight copyright information + &__highlight { + color: $md-color-white--light; + } +} + +// Social media links +.md-footer-social { + margin: 0 0.8rem; + padding: 0.4rem 0 1.2rem; + + // [tablet portrait +]: Show next to copyright information + @include break-from-device(tablet portrait) { + padding: 1.2rem 0; + float: right; + } + + // Link with icon + &__link { + display: inline-block; + width: 3.2rem; + height: 3.2rem; + border: 0.1rem solid $md-color-white--lightest; + border-radius: 100%; + color: $md-color-white--light; + font-size: 1.6rem; + text-align: center; + + // Adjust line-height to match height for correct alignment + &::before { + line-height: 1.9; + } + } +} diff --git a/src/assets/stylesheets/layout/_header.scss b/src/assets/stylesheets/layout/_header.scss new file mode 100644 index 000000000..e4f2c3092 --- /dev/null +++ b/src/assets/stylesheets/layout/_header.scss @@ -0,0 +1,133 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Application header (stays always on top) +.md-header { + @include z-depth(2); + + position: fixed; + top: 0; + right: 0; + left: 0; + height: 5.6rem; + transition: background-color 0.25s; + background-color: $md-color-primary; + color: $md-color-white; + z-index: 1; + + // Hide for print + @media print { + display: none; + } +} + +// Navigation within header +.md-header-nav { + padding: 0.4rem; + + // Icons + &__icon { + @extend %md-icon__button; + + position: relative; + transition: opacity 0.25s; + z-index: 1; + + // Hovered icon + &:hover { + opacity: 0.7; + } + + // Hide search icon, if JavaScript is not available. + .no-js & .md-icon--search { + display: none; + } + + // [tablet landscape +]: Hide the search icon + @include break-from-device(tablet landscape) { + + // Search icon + &.md-icon--search { + display: none; + } + } + + // [tablet -]: Hide the home icon + @include break-to-device(tablet) { + + // Home icon + &.md-icon--home { + display: none; + } + } + + // [screen +]: Hide the menu icon + @include break-from-device(screen) { + + // Menu icon + &.md-icon--menu { + display: none; + } + } + } + + // Header title - set line height to match icon for correct alignment + &__title { + padding: 0 2rem; + font-size: 1.8rem; + line-height: 4.8rem; + } + + // Parent page title + &__parent { + color: $md-color-white--light; + + // Ancestor separator + &::after { + display: inline; + color: $md-color-white--lighter; + content: "/"; + } + + // [mobile portrait -]: Hide on very small screens + @include break-to-device(mobile portrait) { + display: none; + } + } + + // Repository containing source + &__source { + display: none; + + // [tablet landscape +]: Show the reposistory from tablet + @include break-from-device(tablet landscape) { + display: block; + width: 23rem; + max-width: 23rem; + padding-right: 1.2rem; + } + } +} diff --git a/src/assets/stylesheets/layout/_nav.scss b/src/assets/stylesheets/layout/_nav.scss new file mode 100644 index 000000000..59400e37f --- /dev/null +++ b/src/assets/stylesheets/layout/_nav.scss @@ -0,0 +1,455 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Navigation container +.md-nav { + font-size: ms(-1); + line-height: 1.3; + + // Table of contents + &--secondary { + transition: border-left 0.25s; + border-left: 0.4rem solid $md-color-primary; + } + + // List title + &__title { + display: block; + padding: 1.2rem 1.2rem 0; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + + // Icon, hidden by default + &::before { + @extend %md-icon, %md-icon__button; + + display: none; + content: "arrow_back"; + } + + // Hide icon by default + .md-nav__icon { + display: none; + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + list-style: none; + } + + // List item + &__item { + padding: 0.625em 1.2rem 0; + + // Add bottom spacing to last item + &:last-child { + padding-bottom: 1.2rem; + } + + // 2nd+ level items + & & { + padding-right: 0; + + // Remove bottom spacing for nested items + &:last-child { + padding-bottom: 0; + } + } + } + + // Icon + &__icon { + @extend %md-icon, %md-icon__button; + + // Stretch image + img { + width: 100%; + height: auto; + } + } + + // Link inside item + &__link { + display: block; + transition: color 0.125s; + text-overflow: ellipsis; + cursor: pointer; + overflow: hidden; + + // Icon + &::after { + @extend %md-icon; + + // Item contains a nested list + .md-nav__item--nested > & { + content: "keyboard_arrow_down"; + } + } + + // Hide link to table of contents by default - this will only match the + // table of contents inside the drawer below and including tablet portrait + html &[for="toc"] { + display: none; + + // Hide table of contents by default + & ~ .md-nav { + display: none; + } + + // Hide icon for current item + + .md-nav__link::after { + display: none; + } + } + + // Blurred item + &[data-md-state="blur"] { + color: $md-color-black--light; + } + + // Active item + &:active, + &--active { + color: $md-color-primary; + } + + // Hovered item + &:hover { + color: $md-color-accent; + } + } + + // Repository containing source + &__source { + display: none; + } + + // [tablet -]: Layered navigation + @include break-to-device(tablet) { + + // Stretch primary navigation to drawer + &--primary, + &--primary .md-nav { + display: flex; + position: absolute; + top: 0; + right: 0; + left: 0; + flex-direction: column; + height: 100%; + z-index: 1; + } + + // Adjust styles for primary navigation + &--primary { + background-color: $md-color-white; + + // Move subsequent navigations off + .md-nav__toggle ~ .md-nav { + @include z-depth(4); + + background-color: $md-color-white; + } + + // List title - higher specificity is necessary to ensure that the title + // inside the drawer is always styled accordingly + html & .md-nav__title { + position: relative; + height: 11.2rem; + padding: 6rem 1.6rem 0.4rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-weight: 400; + line-height: 4.8rem; + white-space: nowrap; + cursor: pointer; + + // Icon + &::before { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + color: $md-color-black--light; + } + + // Main lists + ~ .md-nav__list { + + // Pure CSS scrolling shadows, taken from + // http://lea.verou.me/2012/04/background-attachment-local/ + background: + linear-gradient( + to bottom, + $md-color-white 10%, + $md-color-white--transparent + ), + linear-gradient( + to bottom, + $md-color-black--lighter, + $md-color-black--lightest 35%, + $md-color-black--transparent 60% + ); + background-attachment: local, scroll; + background-color: $md-color-white; + background-repeat: no-repeat; + background-size: 100% 2rem, 100% 1rem; + + // End of scrolling shadow definition + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + + // Remove border for first list item + & > .md-nav__item:first-child { + border-top: 0; + } + } + + // Site title in main navigation + &--site { + position: relative; + background-color: $md-color-primary; + color: $md-color-white; + + // Site logo + .md-nav__icon { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 6.4rem; + height: 6.4rem; + font-size: 4.8rem; + } + + // Hide back arrow icon + &::before { + display: none; + } + } + } + + // List of items + .md-nav__list { + flex: 1; + overflow-y: scroll; + } + + // List item + .md-nav__item { + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + + // Increase spacing to account for icon + &--nested > .md-nav__link { + padding-right: 4.8rem; + + // Replace icon with right arrow + &::after { + content: "keyboard_arrow_right"; + } + } + } + + // Link inside item + .md-nav__link { + position: relative; + padding: 1.6rem; + + // Rotate icon + &::after { + position: absolute; + top: 50%; + right: 1.2rem; + margin-top: -1.2rem; + color: $md-color-black--light; + font-size: 2.4rem; + } + + // Color of icon should inherit link color on hover + &:hover::after { + color: inherit; + } + } + + // Set nested navigation for table of contents to static + .md-nav--secondary .md-nav { + position: static; + + // 3rd level link + .md-nav__link { + padding-left: 2.8rem; + } + + // 4th level link + .md-nav .md-nav__link { + padding-left: 4rem; + } + + // 5th level link + .md-nav .md-nav .md-nav__link { + padding-left: 5.2rem; + } + + // 6th level link + .md-nav .md-nav .md-nav .md-nav__link { + padding-left: 6.4rem; + } + } + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + display: none; + + // Animate appearance, if browser supports 3D transforms + .csstransforms3d & { + display: flex; + transform: translateX(100%); + transition: + transform 0.25s cubic-bezier(0.8, 0, 0.6, 1), + opacity 0.125s 0.05s; + opacity: 0; + } + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ & { + display: flex; + + // Animate appearance, if browser supports 3D transforms + .csstransforms3d & { + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.125s 0.125s; + opacity: 1; + } + } + + // List item + .md-nav__title, + .md-nav__item { + font-size: 1.6rem; + line-height: 1.5; + } + } + + // [tablet portrait -]: Show table of contents in drawer + @include break-to-device(tablet portrait) { + + // Remove border on secondary navigation + &--secondary { + border-left: 0; + } + + // Show link to table of contents - higher specificity is necessary to + // display the table of contents inside the drawer + html &__link[for="toc"] { + display: block; + padding-right: 4.8rem; + + // Unrotate icon for table of contents + &::after { + color: inherit; + content: "toc"; + } + + // Hide link to current item + + .md-nav__link { + display: none; + } + + // Show table of contents + & ~ .md-nav { + display: flex; + } + } + + // Repository containing source + &__source { + display: block; + padding: 0.4rem; + background-color: mix($md-color-primary, $md-color-black, 75%); + color: $md-color-white; + } + } + + // [screen +]: Tree-like navigation + @include break-from-device(screen) { + + // Animation is only possible if JavaScript is available, as the max-height + // property must be calculated before transitioning + &[data-md-state="animate"] { + transition: max-height 0.25s cubic-bezier(0.86, 0, 0.07, 1); + } + + // Hide nested navigation by default + .md-nav__toggle ~ & { + max-height: 0; + overflow: hidden; + } + + // Expand nested navigation, if toggle is checked + .md-nav__toggle:checked ~ &, + &[data-md-state="expand"] { + max-height: 100%; + } + + // Hide titles for nested navigation + &__item--nested > .md-nav > &__title { + display: none; + } + + // Link inside item + &__link { + + // Item contains a nested list + .md-nav__item--nested > &::after { + display: inline-block; + transform-origin: 0.45em 0.45em; + transform-style: preserve-3d; + vertical-align: -0.125em; + + // Only animate icon when JavaScript is available, as the height can + // not be animated anyway, and better no fun than half the fun + .js & { + transition: transform 0.4s; + } + } + + // Rotate icon for expanded lists + .md-nav__item--nested .md-nav__toggle:checked ~ &::after { + transform: rotateX(180deg); + } + } + } +} diff --git a/src/assets/stylesheets/layout/_search.scss b/src/assets/stylesheets/layout/_search.scss new file mode 100644 index 000000000..568aa0dda --- /dev/null +++ b/src/assets/stylesheets/layout/_search.scss @@ -0,0 +1,418 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Search container +.md-search { + + // Hide search, if JavaScript is not available. + .no-js & { + display: none; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + margin-right: 2.8rem; + padding: 0.4rem; + } + + // Search modal overlay + &__overlay { + display: none; + pointer-events: none; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + display: block; + position: absolute; + top: 0.4rem; + left: 0.4rem; + width: 4rem; + height: 4rem; + transform-origin: center; + transition: + transform 0.3s 0.1s, + opacity 0.2s 0.2s; + border-radius: 2rem; + background-color: $md-color-white; + opacity: 0; + overflow: hidden; + z-index: 1; + + // Expanded overlay + [data-md-toggle="search"]:checked ~ .md-header & { + transition: + transform 0.4s, + opacity 0.1s; + opacity: 1; + } + } + + // Set scale factors + [data-md-toggle="search"]:checked ~ .md-header & { + + // [mobile portrait -]: Scale up 45 times + @include break-to-device(mobile portrait) { + transform: scale(45); + } + + // [mobile landscape]: Scale up 60 times + @include break-at-device(mobile landscape) { + transform: scale(60); + } + + // [tablet portrait]: Scale up 75 times + @include break-at-device(tablet portrait) { + transform: scale(75); + } + } + } + + // Search modal wrapper + &__inner { + width: 100%; + + // [tablet portrait -]: Put search modal off-canvas by default + @include break-to-device(tablet portrait) { + position: fixed; + top: 0; + left: 100%; + height: 100%; + transform: translateX(5%); + transition: + left 0s 0.3s, + transform 0.15s 0.15s cubic-bezier(0.4, 0, 0.2, 1), + opacity 0.15s 0.15s; + opacity: 0; + z-index: 2; + + // Active search modal + [data-md-toggle="search"]:checked ~ .md-header & { + left: 0; + transform: translateX(0); + transition: + left 0s 0s, + transform 0.15s 0.15s cubic-bezier(0.1, 0.7, 0.1, 1), + opacity 0.15s 0.15s; + opacity: 1; + } + } + + // [tablet landscape +]: Make relative for inner layout + @include break-from-device(tablet landscape) { + display: table; + position: relative; + clear: both; + } + } + + // Search form + &__form { + position: relative; + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + width: 23rem; + // Hack: omit jitter when form is resized + float: right; + transition: width 0.25s cubic-bezier(0.1, 0.7, 0.1, 1); + border-radius: 0.2rem; + } + + // Set maximum width + [data-md-toggle="search"]:checked ~ .md-header & { + + // [tablet landscape]: Do not overlay title + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Match content width + @include break-from-device(screen) { + width: 68.8rem; + } + } + } + + // Search input + &__input { + position: relative; + padding: 0 1.6rem 0 7.2rem; + text-overflow: ellipsis; + z-index: 1; + + // Placeholder and icon color in active state + + .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + + // Remove the "x" rendered by Internet Explorer + &::-ms-clear { + display: none; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + width: 100%; + height: 5.6rem; + font-size: 1.8rem; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + width: 100%; + height: 4rem; + padding-left: 4.8rem; + transition: + background-color 0.25s, + color 0.25s; + border-radius: 0.2rem; + background-color: $md-color-black--lighter; + color: $md-color-white; + font-size: ms(0); + + // Placeholder color + + .md-search__icon, + &::placeholder { + transition: color 0.25s; + color: $md-color-white; + } + + // Hovered search field + &:hover { + background-color: $md-color-white--lightest; + } + + // Set light background on active search field + [data-md-toggle="search"]:checked ~ .md-header & { + border-radius: 0.2rem 0.2rem 0 0; + background-color: $md-color-white; + color: $md-color-black; + text-overflow: none; + + // Placeholder and icon color in active state + + .md-search__icon, + &::placeholder { + color: $md-color-black--light; + } + } + } + } + + // Icons + &__icon { + position: absolute; + top: $md-icon-padding; + left: $md-icon-padding + $md-icon-margin; + transition: color 0.25s; + font-size: $md-icon-size; + cursor: pointer; + z-index: 1; + + // Set search icon on pseudo class, so it can be overridden for mobile + // and tablet when the search is rendered in an overlay + &::before { + content: "search"; + } + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 1.6rem; + left: 1.6rem; + + // Show back arrow instead of search icon + &::before { + content: "arrow_back"; + } + } + } + + // Search output container + &__output { + position: absolute; + width: 100%; + border-radius: 0 0 0.2rem 0.2rem; + overflow: hidden; + + // [tablet portrait -]: Full-screen search bar + @include break-to-device(tablet portrait) { + top: 5.6rem; + bottom: 0; + } + + // [tablet landscape +]: Header-embedded search + @include break-from-device(tablet landscape) { + @include z-depth(6); + + top: 4rem; + transition: opacity 0.4s; + opacity: 0; + + // Show search output in active state + [data-md-toggle="search"]:checked ~ .md-header & { + opacity: 1; + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + height: 100%; + + // Pure CSS scrolling shadows, taken from + // http://lea.verou.me/2012/04/background-attachment-local/ + background: + linear-gradient( + to bottom, + $md-color-white 10%, + $md-color-white--transparent + ), + linear-gradient( + to bottom, + $md-color-black--lighter, + $md-color-black--lightest 35%, + $md-color-black--transparent 60% + ); + background-attachment: local, scroll; + background-color: $md-color-white; + background-repeat: no-repeat; + background-size: 100% 2rem, 100% 1rem; + + // End of scrolling shadow definition + box-shadow: 0 0.1rem 0 $md-color-black--lightest inset; + overflow-y: auto; + -webkit-overflow-scrolling: touch; + + // [tablet landscape]: Set absolute width to omit unnecessary reflow + @include break-at-device(tablet landscape) { + width: 46.8rem; + } + + // [screen +]: Set absolute width to omit unnecessary reflow + @include break-from-device(screen) { + width: 68.8rem; + } + + // [tablet landscape +]: Limit height to viewport + @include break-from-device(tablet landscape) { + max-height: 0; + + // Expand in active state + [data-md-toggle="search"]:checked ~ .md-header & { + max-height: 75vh; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + } +} + +// Search result +.md-search-result { + + // Search metadata + &__meta { + padding: 0 1.6rem; + background-color: $md-color-black--lightest; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 4rem; + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.8rem; + } + } + + // List of items + &__list { + margin: 0; + padding: 0; + border-top: 0.1rem solid $md-color-black--lightest; + list-style: none; + } + + // List item + &__item { + box-shadow: 0 -0.1rem 0 $md-color-black--lightest; + } + + // Link inside item + &__link { + display: block; + padding: 0 1.6rem; + transition: background 0.25s; + overflow: auto; + + // Hovered link + &:hover { + background-color: transparentize($md-color-accent, 0.9); + } + + // [tablet landscape +]: Increase left indent + @include break-from-device(tablet landscape) { + padding-left: 4.8rem; + } + } + + // Search result content + &__article { + margin: 1em 0; + } + + // Search result title + &__title { + margin-top: 0.5em; + margin-bottom: 0; + color: $md-color-black; + font-size: ms(0); + font-weight: 400; + line-height: 1.4; + } + + // Search result teaser + &__teaser { + margin: 0.5em 0; + color: $md-color-black--light; + font-size: ms(-1); + line-height: 1.4; + word-break: break-word; + } +} diff --git a/src/assets/stylesheets/layout/_sidebar.scss b/src/assets/stylesheets/layout/_sidebar.scss new file mode 100644 index 000000000..d751d0150 --- /dev/null +++ b/src/assets/stylesheets/layout/_sidebar.scss @@ -0,0 +1,156 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Sidebar container +.md-sidebar { + position: relative; + width: 24.2rem; + float: left; + overflow: visible; + + // Hide for print + @media print { + display: none; + } + + // Lock sidebar to container height (account for fixed header) + &[data-md-state="lock"] { + position: fixed; + top: 5.6rem; + } + + // [tablet -]: Convert navigation to drawer + @include break-to-device(tablet) { + + // Render primary sidebar as a slideout container + &--primary { + position: fixed; + top: 0; + left: -24.2rem; + width: 24.2rem; + height: 100%; + transform: translateX(0); + transition: + transform 0.25s cubic-bezier(0.4, 0, 0.2, 1), + box-shadow 0.25s; + background-color: $md-color-white; + z-index: 2; + + // Just hide drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: none; + } + + // Expanded drawer + [data-md-toggle="drawer"]:checked ~ .md-container & { + @include z-depth(8); + + transform: translateX(24.2rem); + + // Just show drawer, if browser doesn't support 3D transforms + .no-csstransforms3d & { + display: block; + } + } + + // Hide overflow for nested navigation + .md-sidebar__scrollwrap { + overflow: hidden; + } + } + } + + // Secondary sidebar with table of contents + &--secondary { + display: none; + + // [tablet landscape +]: Show table of contents next to body copy + @include break-from-device(tablet landscape) { + display: block; + float: right; + + // Hack: align right in case of locked sidebar + &[data-md-state="lock"] { + margin-left: 100%; + transform: translate(-100%, 0); + + // [screen +]: Limit to grid + @include break-from-device(screen) { + margin-left: 122rem; + } + } + } + } + + // Wrapper for scrolling on overflow + &__scrollwrap { + margin: 2.4rem 0.4rem; + overflow-y: scroll; + + // [tablet -]: Adjust margins + @include break-to-device(tablet) { + + // Adjust margins for primary scrollbar + .md-sidebar--primary & { + margin: 0; + } + } + + // Limit height to window, if JavaScript is available + .js & { + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 0; + } + + // Override native scrollbar styles + &::-webkit-scrollbar { + width: 0.4rem; + height: 0.4rem; + } + + // Style scrollbar thumb + &::-webkit-scrollbar-thumb { + background-color: $md-color-black--lighter; + + // Hovered scrollbar thumb + &:hover { + background-color: $md-color-accent; + } + } + } + + // Sidebar content + &__inner { + + // [screen +]: Add line for reference + @include break-from-device(screen) { + border-right: 0.1rem solid $md-color-black--lightest; + } + } +} diff --git a/src/assets/stylesheets/layout/_source.scss b/src/assets/stylesheets/layout/_source.scss new file mode 100644 index 000000000..2f29bfb14 --- /dev/null +++ b/src/assets/stylesheets/layout/_source.scss @@ -0,0 +1,149 @@ +//// +/// Copyright (c) 2016-2017 Martin Donath +/// +/// Permission is hereby granted, free of charge, to any person obtaining a +/// copy of this software and associated documentation files (the "Software"), +/// to deal in the Software without restriction, including without limitation +/// the rights to use, copy, modify, merge, publish, distribute, sublicense, +/// and/or sell copies of the Software, and to permit persons to whom the +/// Software is furnished to do so, subject to the following conditions: +/// +/// The above copyright notice and this permission notice shall be included in +/// all copies or substantial portions of the Software. +/// +/// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +/// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +/// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +/// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +/// DEALINGS +//// + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Show source facts +@keyframes md-source__facts--done { + 0% { + height: 0; + } + + 100% { + height: 1.3rem; + } +} + +// Show source fact +@keyframes md-source__fact--done { + 0% { + transform: translateY(100%); + opacity: 0; + } + + 50% { + opacity: 0; + } + + 100% { + transform: translateY(0%); + opacity: 1; + } +} + +// ---------------------------------------------------------------------------- +// Rules +// ---------------------------------------------------------------------------- + +// Source container +.md-source { + display: block; + transition: opacity 0.25s; + font-size: 1.3rem; + line-height: 1.2; + white-space: nowrap; + + // Hovered source information + &:hover { + opacity: 0.7; + } + + // Necessary for vertical alignment + &::after { + display: inline-block; + height: 4.8rem; + content: ""; + vertical-align: middle; + } + + // Repository platform icon + &__icon { + display: inline-block; + width: 4.8rem; + height: 4.8rem; + content: ""; + vertical-align: middle; + + // Align SVG, do not scale, as this will incur strange formatting bugs + // in Internet Explorer and Edge + svg { + margin-top: 1.2rem; + margin-left: 1.2rem; + } + + // Correct alignment, if icon is present + + .md-source__repository { + margin-left: -4.4rem; + padding-left: 4rem; + } + } + + // Repository name + &__repository { + display: inline-block; + max-width: 100%; + margin-left: 1.2rem; + font-weight: 700; + text-overflow: ellipsis; + overflow: hidden; + vertical-align: middle; + } + + // Source facts (statistics etc.) + &__facts { + margin: 0; + padding: 0; + font-size: 1.1rem; + font-weight: 700; + list-style-type: none; + opacity: 0.75; + overflow: auto; + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__facts--done 0.25s ease-in; + } + } + + // Fact + &__fact { + float: left; + + // Show after the data was loaded + [data-md-state="done"] & { + animation: md-source__fact--done 0.4s ease-out; + } + + // Middle dot before fact + &::before { + margin: 0 0.2rem; + content: "\00B7"; + } + + // Remove middle dot on first fact + &:first-child::before { + display: none; + } + } +} diff --git a/src/assets/stylesheets/mixins/_break.scss b/src/assets/stylesheets/mixins/_break.scss deleted file mode 100644 index 468fa2ec7..000000000 --- a/src/assets/stylesheets/mixins/_break.scss +++ /dev/null @@ -1,206 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Defaults - * ------------------------------------------------------------------------- */ - -$break: ( - devices: ( - mobile: ( - portrait: 220px 479px, - landscape: 480px 719px - ), - tablet: ( - portrait: 720px 959px, - landscape: 960px 1199px - ), - screen: 1200px - ) -) !default; - -/* ---------------------------------------------------------------------------- - * Helper functions - * ------------------------------------------------------------------------- */ - -/* - * Choose minimum and maximum device widths. - */ -@function break-select-min-max($devices) { - $min: 1000000; $max: 0; - @each $key, $value in $devices { - @while type-of($value) == map { - $value: break-select-min-max($value); - } - @if type-of($value) == list { - @each $number in $value { - @if type-of($number) == number { - $min: min($number, $min); - @if $max != null { - $max: max($number, $max); - } - } @else { - @warn "Invalid number: #{$number}"; - } - } - } @elseif type-of($value) == number { - $min: min($value, $min); - $max: null; - } @else { - @warn "Invalid tuple: #{$value}"; - } - } - @return $min, $max; -} - -/* - * Select minimum and maximum widths for a device breakpoint. - */ -@function break-select-device($device) { - $devices: map-get($break, devices); - @for $n from 1 through length($device) { - @if type-of($devices) == map { - $devices: map-get($devices, nth($device, $n)); - } @else { - @warn "Invalid device map: #{$devices}"; - } - } - @if type-of($devices) == list or - type-of($devices) == number { - $devices: (default: $devices); - } - @return break-select-min-max($devices); -} - -/* ---------------------------------------------------------------------------- - * Mixins for numeric breakpoints - * ------------------------------------------------------------------------- */ - -/* - * A minimum-maximum media query breakpoint. - */ -@mixin break-at($breakpoint) { - @if type-of($breakpoint) == number { - @media only screen and (min-width: $breakpoint) { - @content; - } - } @elseif type-of($breakpoint) == list { - $min: nth($breakpoint, 1); $max: nth($breakpoint, 2); - @if type-of($min) == number and type-of($max) == number { - @media only screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @warn "Invalid breakpoint: #{$breakpoint}"; - } - } @else { - @warn "Invalid breakpoint: #{$breakpoint}"; - } -} - -/* - * An orientation media query breakpoint. - */ -@mixin break-at-orientation($breakpoint) { - @if type-of($breakpoint) == string { - @media only screen and (orientation: $breakpoint) { - @content; - } - } @else { - @warn "Invalid breakpoint: #{$breakpoint}"; - } -} - -/* - * A maximum-aspect-ratio media query breakpoint. - */ -@mixin break-at-ratio($breakpoint) { - @if type-of($breakpoint) == number { - @media only screen and (max-aspect-ratio: $breakpoint) { - @content; - } - } @else { - @warn "Invalid breakpoint: #{$breakpoint}"; - } -} - -/* ---------------------------------------------------------------------------- - * Mixins for device breakpoints - * ------------------------------------------------------------------------- */ - -/* - * A minimum-maximum media query device breakpoint. - */ -@mixin break-at-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - @if nth($breakpoint, 2) != null { - $min: nth($breakpoint, 1); $max: nth($breakpoint, 2); - @media only screen and (min-width: $min) and (max-width: $max) { - @content; - } - } @else { - @warn "Invalid device: #{$device}"; - } - } @else { - @warn "Invalid device: #{$device}"; - } -} - -/* - * A minimum media query device breakpoint. - */ -@mixin break-from-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $min: nth($breakpoint, 1); - @media only screen and (min-width: $min) { - @content; - } - } @else { - @warn "Invalid device: #{$device}"; - } -} - -/* - * A maximum media query device breakpoint. - */ -@mixin break-to-device($device) { - @if type-of($device) == string { - $device: $device,; - } - @if type-of($device) == list { - $breakpoint: break-select-device($device); - $max: nth($breakpoint, 1) - 1; - @media only screen and (max-width: $max) { - @content; - } - } @else { - @warn "Invalid device: #{$device}"; - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/_base.scss b/src/assets/stylesheets/modules/_base.scss deleted file mode 100644 index 140d308fb..000000000 --- a/src/assets/stylesheets/modules/_base.scss +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -@import "base/animation"; -@import "base/appearance"; -@import "base/layout"; -@import "base/typography"; \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_appearance.scss b/src/assets/stylesheets/modules/article/_appearance.scss deleted file mode 100644 index f02f84e44..000000000 --- a/src/assets/stylesheets/modules/article/_appearance.scss +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Article appearance - * ------------------------------------------------------------------------- */ - -/* - * Article - */ -.article { - - /* - * Differing top and bottom rubberband backgrounds in iOS web application - */ - .ios.standalone & { - background: linear-gradient( - to bottom, $white 50%, $primary 50%); - - /* Hack [iOS]: Mitigate black bounding box with linear gradient */ - .wrapper { - background: linear-gradient( - to bottom, $white 50%, $white 50%); - } - } - - /* - * Headlines, chapters, links and inline code - */ - h1, h2, a { - color: $primary; - } - - /* - * Inline code - */ - code { - background: #eee; - } - - /* - * Keyboard tags - */ - kbd { - color: #555; - background-color: #fcfcfc; - border: solid 1px #ccc; - border-bottom-color: #bbb; - border-radius: 3px; - box-shadow: inset 0 -1px 0 #bbb; - } - - /* - * Lower border for main headline - */ - h1 { - border-bottom: 1px solid $black-lightest; - } - - /* - * Underline links - */ - a { - border-bottom: 1px dotted; - } - - /* - * Hovered and focused links - */ - a:hover, a:focus { - color: $accent; - } - - /* - * Light permalinks - */ - .headerlink { - color: $black-lighter; - border: none; - } - - /* - * Data tables - */ - table { - @include drop-shadow(1); - - border-radius: 3px; - - /* - * Table heading - */ - th { - background: mix($primary, $white, 75%); - color: $white; - } - - /* - * Table cell - */ - td { - border-top: 1px solid rgba($black, 0.05); - } - } - - /* - * Blockquote styles - */ - blockquote { - border-left: 2px solid $black-light; - color: $black-light; - } -} - -/* - * Article footer - */ -.footer { - background: $primary; - color: $white; - - /* - * Remove bottom border on links - */ - a { - border: none; - } -} - -/* - * Copyright and theme information - */ -.copyright { - color: $black-light; -} - -/* - * Pagination - */ -.pagination { - - /* - * Inherit color for links - */ - a .title, a .button { - color: $white; - } - - /* - * Smaller font size for direction - */ - .direction { - color: $white-light; - } -} - -/* - * Admonition support - */ -.admonition { - background: $light-blue-400; - color: $white; - - /* - * Embedded code blocks - */ - pre { - background: $white-lighter; - } - - /* - * A warning hint - */ - &.warning { - background: $red-400; - } - - /* - * Headlines, chapters, links and inline code - */ - a, a:hover { - color: $white; - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/article/_layout.scss b/src/assets/stylesheets/modules/article/_layout.scss deleted file mode 100644 index c5605160c..000000000 --- a/src/assets/stylesheets/modules/article/_layout.scss +++ /dev/null @@ -1,585 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Article layout - * ------------------------------------------------------------------------- */ - -/* - * Article - */ -.article { - font-size: 14px; - line-height: 1.7em; - - /* [tablet landscape+]: Indent to account for drawer */ - @include break-from-device(tablet landscape) { - margin-left: 262px; - } - - /* - * Clearfix - */ - &:after { - content: " "; - display: block; - clear: both; - } - - /* - * Article wrapper - */ - .wrapper { - padding: 116px 16px 92px; - - /* [tablet portait+]: Increase top spacing */ - @include break-from-device(tablet portrait) { - padding: 128px 24px 96px; - } - } - - /* - * Enable overflow scrolling in iOS web application - */ - .ios.standalone & { - @include position(absolute, 56px 0 0 0); - - overflow: auto; - -webkit-overflow-scrolling: touch; - - /* [orientation: portrait]: Account for status bar in portrait mode */ - @include break-at-orientation(portrait) { - @include position(absolute, (56px + 20px) 0 0 0); - } - - /* - * Article wrapper - */ - .wrapper { - position: relative; - min-height: 100%; - padding-top: 60px; - margin-bottom: 2px; - } - } - - /* - * Article headline - */ - h1 { - font-size: 24px; - line-height: 1.333334em; - padding: 20px 0 42px; - } - - /* - * Article chapters - */ - h2 { - font-size: 20px; - line-height: 1.4em; - padding-top: (36px + 56px); - margin-top: (0px - 56px); - - /* - * No offset correction in iOS web application - */ - .ios.standalone & { - padding-top: 36px; - margin: 0; - } - } - - /* - * Sub headlines - */ - h3, h4 { - font-size: 14px; - padding-top: (20px + 56px); - margin-top: (0 - 56px); - - /* - * No offset correction in iOS web application - */ - .ios.standalone & { - padding-top: 20px; - margin-top: 0; - } - } - - /* - * Align permalinks on the right - */ - .headerlink { - float: right; - margin-left: 20px; - font-size: 14px; - - /* - * Hide permalink to main headline - */ - h1 & { - display: none; - } - } - - /* - * Paragraphs and section titles - */ - p, ul, ol { - margin-top: 1.5em; - } - - /* - * Smaler top spacing for nested lists - */ - li ul, li ol { - margin-top: 0.75em; - } - - /* - * List elements - */ - li { - margin-top: 0.75em; - margin-left: 18px; - - /* - * Inline paragraphs in list elements - */ - p { - display: inline; - } - } - - /* - * Add icon for elements of an unordered list - */ - ul > li:before { - content: "\e602"; - display: block; - float: left; - font-family: 'Icon'; - font-size: 16px; - width: 1.2em; - margin-left: -1.2em; - vertical-align: -0.1em; - } - - /* - * Inline code snippets must not wrap - */ - p > code { - white-space: nowrap; - padding: 2px 4px; - } - - /* - * Keyboard tags - */ - kbd { - display: inline-block; - padding: 3px 5px; - line-height: 10px; - } - - /* - * Add spacing at top of separator - */ - hr { - margin-top: 1.5em; - } - - /* - * Limit images to article container - */ - img { - max-width: 100%; - } - - /* - * Code listing container - */ - pre { - padding: 16px; - margin: 1.5em -16px 0; - line-height: 1.5em; - overflow: auto; - -webkit-overflow-scrolling: touch; - } - - /* - * Data tables - */ - table { - margin: 3.0em 0 1.5em; - font-size: 13px; - overflow: hidden; - - /* - * The semi-cool solution, in case javascript is not available - */ - .no-js & { - display: inline-block; - max-width: 100%; - overflow: auto; - -webkit-overflow-scrolling: touch; - } - - /* - * Table heading - */ - th { - min-width: 100px; - padding: 12px 16px; - font-size: 12px; - text-align: left; - vertical-align: top; - } - - /* - * Table cell - */ - td { - padding: 12px 16px; - vertical-align: top; - } - } - - /* - * Blockquote styles - */ - blockquote { - padding-left: 16px; - } - - /* - * Data table wrapper, in case javascript is available - */ - .data { - margin: 1.5em -16px; - padding: 1.5em 0; - overflow: auto; - -webkit-overflow-scrolling: touch; - text-align: center; - - /* - * Data table - */ - table { - display: inline-block; - margin: 0 16px; - text-align: left; - } - - /* [tablet portait+]: Increase spacing */ - @include break-from-device(tablet portrait) { - margin: 1.5em -24px; - - /* - * Data table - */ - table { - margin: 0 24px; - } - } - } - - /* [tablet portait+]: Increase spacing */ - @include break-from-device(tablet portrait) { - - /* - * Account for larged header bar and anchors - */ - h2 { - padding-top: (28px + 72px); - margin-top: (8px - 72px); - - /* - * No offset correction in iOS web application - */ - .ios.standalone & { - padding-top: 28px; - margin-top: 8px; - } - } - - /* - * Sub headlines - */ - h3, h4 { - padding-top: (20px + 64px); - margin-top: (0 - 64px); - - /* - * No offset correction in iOS web application - */ - .ios.standalone & { - padding-top: 20px; - margin-top: 0; - } - } - - /* - * Increase spacing for code blocks - */ - pre { - padding: 1.5em 24px; - margin: 1.5em -24px 0; - } - } -} - -/* - * Article footer - */ -.footer { - position: absolute; - bottom: 0; - left: 0; - right: 0; - padding: 0 4px; - - /* [tablet portait+]: Larger spacing */ - @include break-from-device(tablet portrait) { - padding: 0 8px; - } - - /* [tablet landscape+]: Stretch footer to viewport */ - @include break-from-device(tablet landscape) { - z-index: 5; - } -} - -/* - * Copyright and theme information - */ -.copyright { - margin: 1.5em 0; - - /* [tablet landscape+]: Add bottom spacing */ - @include break-from-device(tablet landscape) { - margin-bottom: 64px; - } -} - -/* - * Pagination - */ -.pagination { - max-width: 1184px; - height: 92px; - padding: 4px 0; - margin-left: auto; - margin-right: auto; - overflow: hidden; - - /* [tablet portait+]: Larger pagination and spacing */ - @include break-from-device(tablet portrait) { - height: 96px; - padding: 8px 0; - } - - /* - * Links should span icons entirely - */ - a { - display: block; - height: 100%; - } - - /* - * Previous and next page - */ - .previous, - .next { - position: relative; - float: left; - height: 100%; - } - - /* - * Previous page - */ - .previous { - width: 25%; - - /* - * Hide direction - */ - .direction { - display: none; - } - - /* - * Hide title - */ - .stretch { - display: none; - } - } - - /* - * Next page - */ - .next { - width: 75%; - text-align: right; - } - - /* - * Link to page - */ - .page { - display: table; - position: absolute; - bottom: 4px; - } - - /* - * Put direction over page title - */ - .direction { - display: block; - position: absolute; - bottom: 40px; - width: 100%; - font-size: 15px; - line-height: 20px; - padding: 0 52px; - } - - /* - * Decrease indent for stretching content - */ - .stretch { - padding: 0 4px; - - /* - * Correct vertical spacing - */ - .title { - font-size: 18px; - padding: 11px 0 13px; - } - } - - /* [mobile landscape+]: Proportional width for pagination */ - @include break-from-device(mobile landscape) { - - /* - * Previous and next page - */ - .previous, - .next { - width: 50%; - } - - /* - * Previous page - */ - .previous { - width: 50%; - - /* - * Show direction - */ - .direction { - display: block; - } - - /* - * Show title - */ - .stretch { - display: table; - } - } - } - - /* [tablet portrait+]: Increase vertical spacing */ - @include break-from-device(tablet portrait) { - - /* - * Increase vertical spacing - */ - .direction { - padding: 0 56px; - bottom: 40px; - } - - /* - * Increase vertical spacing - */ - .stretch { - padding: 0 8px; - } - } -} - -/* - * Admonition support - */ -.admonition { - margin: 20px -16px 0; - padding: 20px 16px; - - /* - * Remove redundant margin of first child - */ - > :first-child { - margin-top: 0; - } - - /* [tablet portait+]: Increase horizontal spacing */ - @include break-from-device(tablet portrait) { - margin: 20px -24px 0; - padding: 20px 24px; - } - - /* - * Admonition title, if given - */ - .admonition-title { - font-size: 20px; - - /* - * Default icon - */ - &:before { - content: "\e611"; - display: block; - float: left; - font-family: 'Icon'; - font-size: 24px; - vertical-align: -0.1em; - margin-right: 5px; - } - } - - /* - * Warning icon - */ - &.warning .admonition-title:before { - content: "\e610"; - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_appearance.scss b/src/assets/stylesheets/modules/base/_appearance.scss deleted file mode 100644 index 5f0870c1b..000000000 --- a/src/assets/stylesheets/modules/base/_appearance.scss +++ /dev/null @@ -1,138 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Base appearance - * ------------------------------------------------------------------------- */ - -/* - * Device specific background hacks related to rubberband - */ -body { - color: $black; - - /* Hack [Chrome, Opera]: Set background color in Chrome and Opera */ - @supports (-webkit-appearance: none) { - background: $primary; - } - - /* - * Don't tint menu bar on iOS - */ - .ios & { - background: $white; - } -} - -/* - * Horizontal separators - */ -hr { - border: 0; - border-top: 1px solid $black-lightest; -} - -/* - * Toggle button - */ -.toggle-button { - cursor: pointer; - color: inherit; -} - -/* - * Backdrop - */ -.backdrop { - background: $white; - - /* [tablet landscape+]: Introduce paper with shadow */ - @include break-from-device(tablet landscape) { - background: darken($white, 5%); - } -} - -/* - * Backdrop paper with shadow - */ -.backdrop-paper:after { - background: $white; - - /* [tablet landscape+]: Add drop shadow */ - @include break-from-device(tablet landscape) { - @include drop-shadow(1); - } -} - -/* - * Overlay - */ -.overlay { - background: $black-light; - opacity: 0; - - /* - * Expanded drawer - */ - #toggle-drawer:checked ~ &, - .toggle-drawer & { - opacity: 1; - } -} - -/* - * Application header - */ -.header { - @include drop-shadow(1); - - background: $primary; - color: $white; - - /* - * Add status bar overlay for iOS web application - */ - .ios.standalone &:before { - background: $black-lightest; - } -} - -/* - * Navigation path within header bar - */ -.bar .path { - color: $white-light; -} - -/* - * Draw round area around icon on touch - */ -.button .icon { - border-radius: 100%; -} - -/* - * Pushed/clicked icon - */ -.button .icon:active { - background: $white-lightest; -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/base/_layout.scss b/src/assets/stylesheets/modules/base/_layout.scss deleted file mode 100644 index 2a4569153..000000000 --- a/src/assets/stylesheets/modules/base/_layout.scss +++ /dev/null @@ -1,363 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Base layout - * ------------------------------------------------------------------------- */ - -/* - * Stretch container to viewport - */ -html { - height: 100%; -} - -/* - * Stretch body to container and leave room for sticky footer. - */ -body { - position: relative; - min-height: 100%; -} - -/* - * Horizontal separators - */ -hr { - display: block; - height: 1px; - padding: 0; - margin: 0; -} - -/* - * Lock body (e.g. in search mode) - */ -.locked { - height: 100%; - overflow: hidden; -} - -/* - * Scrollable container - */ -.scrollable { - @include position(absolute, 0 0 0 0); - - overflow: auto; - -webkit-overflow-scrolling: touch; - - /* - * Content wrapper - */ - .wrapper { - height: 100%; - - /* Hack [iOS]: Force overflow scrolling */ - .ios & { - margin-bottom: 2px; - } - } -} - -/* - * Toggle states and button - */ -.toggle { - display: none; - - /* - * Toggle button - */ - &-button { - display: block; - } -} - -/* - * Backdrop - */ -.backdrop { - @include position(absolute, 0 0 0 0); - - z-index: -1; -} - -/* - * Backdrop paper container - */ -.backdrop-paper { - max-width: 1200px; - height: 100%; - margin-left: auto; - margin-right: auto; - - /* - * Actual paper - */ - &:after { - content: " "; - display: block; - height: 100%; - margin-left: 262px; - } -} - -/* - * Overlay - */ -.overlay { - position: fixed; - top: 0; - width: 0; - height: 0; - z-index: 4; - - /* [tablet landscape-]: Trigger overlay */ - @include break-to-device(tablet landscape) { - - /* - * Expanded drawer - */ - #toggle-drawer:checked ~ &, - .toggle-drawer & { - width: 100%; - height: 100%; - } - } -} - -/* - * Application header stays always on top - */ -.header { - @include user-select(none); - - position: fixed; - top: 0; - left: 0; - z-index: 3; - height: 56px; - padding: 4px; - overflow: hidden; - - /* [tablet portait+]: Larger header bar */ - @include break-from-device(tablet portrait) { - height: 64px; - padding: 8px; - } - - /* [screen+]: Stretch to screen */ - @include break-from-device(screen) { - width: 100%; - } - - /* - * Absolute positioning in iOS web application - */ - .ios.standalone & { - position: absolute; - - /* [orientation: portrait]: Account for status bar in portrait mode */ - @include break-at-orientation(portrait) { - height: (56px + 20px); - padding-top: (4px + 20px); - - /* [tablet portait+]: Larger header bar */ - @include break-from-device(tablet portrait) { - height: (64px + 20px); - padding-top: (8px + 20px); - } - - /* - * Add status bar overlay - */ - &:before { - content: " "; - position: absolute; - top: 0; - left: 0; - z-index: 4; - width: 100%; - height: 20px; - } - } - } -} - -/* - * Header bar - */ -.bar { - display: table; - max-width: 1184px; - margin-left: auto; - margin-right: auto; - - /* - * Links should span icons entirely - */ - a { - display: block; - } - - /* - * Hide search button, in case javascript is not available. - */ - .no-js & .button-search { - display: none; - } - - /* - * Navigation path - */ - .path { - - /* - * Correct icon alignment - */ - .icon:before { - vertical-align: -1.5px; - } - - /* [tablet portait-]: Hide path */ - @include break-to-device(tablet portrait) { - display: none; - } - } -} - -/* - * Buttons - */ -.button { - display: table-cell; - vertical-align: top; - width: 1%; - - /* - * Remove native spacing on button - */ - button { - margin: 0; - padding: 0; - - /* Hack [IE]: Remove button offset in active state */ - &:active:before { - position: relative; - top: 0; - left: 0; - } - } - - /* - * Button icons - */ - .icon { - display: inline-block; - font-size: 24px; - padding: 8px; - margin: 4px; - } -} - -/* - * Hide source and twitter button - */ -.button-github, -.button-twitter { - - /* [mobile landscape-]: Hide button */ - @include break-to-device(mobile landscape) { - display: none; - } -} - -/* - * Hide menu button - */ -.button-menu { - - /* [tablet landscape+]: Hide button */ - @include break-from-device(tablet landscape) { - display: none; - } -} - -/* - * Stretch content to remaining space - */ -.stretch { - display: table; - table-layout: fixed; - width: 100%; - - /* - * Set vertical spacing for header - */ - .header & { - padding: 0 20px; - - /* [tablet portait]: Increase vertical spacing */ - @include break-at-device(tablet portrait) { - padding: 0 24px; - } - - /* [tablet portait+]: Account for missing menu icon */ - @include break-from-device(tablet portrait) { - padding: 0 (24px - 8px) 0 16px; - } - } - - /* - * Title with ellipsis on overflow - */ - .title { - display: table-cell; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - - /* - * Increase header font size - */ - .header & { - font-size: 18px; - padding: 13px 0; - - /* [tablet portait+]: Slightly larger typography in header */ - @include break-from-device(tablet portrait) { - font-size: 20px; - padding: 12px 0; - } - } - } -} - -/* - * Main content - */ -.main { - max-width: 1200px; - margin-left: auto; - margin-right: auto; -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_appearance.scss b/src/assets/stylesheets/modules/drawer/_appearance.scss deleted file mode 100644 index b4f9926a5..000000000 --- a/src/assets/stylesheets/modules/drawer/_appearance.scss +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Drawer appearance - * ------------------------------------------------------------------------- */ - -/* - * Drawer container - */ -.drawer { - - /* [tablet landscape-]: Light gray background */ - @include break-to-device(tablet landscape) { - background: $white; - } - - /* - * Color links - */ - .toc a { - - /* - * Current active element - */ - &.current { - color: $primary; - } - - /* - * Hovered link - */ - &:hover, &:focus { - color: $primary; - } - } - - /* - * Color anchors menu - */ - .anchor a { - border-left: 2px solid $primary; - } - - /* - * Main sections - */ - .section { - color: $black-light; - } -} - -/* - * Project information - */ -.project { - - /* [tablet landscape-]: Add drop shadow */ - @include break-to-device(tablet landscape) { - @include drop-shadow(1); - - background: $primary; - color: $white; - } - - /* - * Add status bar overlay for iOS web application - */ - .ios.standalone &:before { - background: $black-lightest; - } - - /* - * Project logo - */ - .logo img { - background: $white; - border-radius: 100%; - } - - /* - * Scale logo on hover - */ - &:hover .logo img, - &:focus .logo img { - @include drop-shadow(2); - } -} - -/* - * Repository buttons - */ -.repo a { - background: $accent; - color: $white; - border-radius: 3px; - - /* - * Hovered button - */ - &:hover, &:focus { - @include drop-shadow(2); - - opacity: 0.8; - } - - /* - * Stars - */ - .count { - background: $black-lighter; - color: $white; - border-radius: 0px 3px 3px 0px; - - /* - * Star bubble - */ - &:before { - border-width: 15px 5px 15px 0; - border-color: transparent $black-lighter; - border-style: solid; - } - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/drawer/_layout.scss b/src/assets/stylesheets/modules/drawer/_layout.scss deleted file mode 100644 index d6e1df280..000000000 --- a/src/assets/stylesheets/modules/drawer/_layout.scss +++ /dev/null @@ -1,305 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Drawer layout - * ------------------------------------------------------------------------- */ - -/* - * Drawer container - */ -.drawer { - width: 262px; - font-size: 13px; - line-height: 1.0em; - - /* [tablet landscape-]: Fixed positioning */ - @include break-to-device(tablet landscape) { - position: fixed; - z-index: 5; - height: 100%; - } - - /* [tablet landscape+]: Inline with content */ - @include break-from-device(tablet landscape) { - position: static; - float: left; - height: auto; - margin-bottom: 96px; - padding-top: 80px; - } - - /* Hack [iOS]: Mitigate scrolling of parent container on boundaries */ - .ios & { - overflow: scroll; - -webkit-overflow-scrolling: touch; - } - - /* - * Links to articles - */ - .toc li a { - display: block; - padding: 14.5px 24px; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } - - /* - * Links to anchors - */ - .toc li.anchor a { - margin-left: 12px; - padding: 10px 24px 10px 12px; - } - - /* - * Nested links and anchors - */ - .toc li ul { - margin-left: 12px; - } - - /* - * Nested anchors - */ - .current + ul { - margin-bottom: 9px; - } - - /* - * Main sections - */ - .section { - display: block; - padding: 14.5px 24px; - } - - /* - * Scrollable container - */ - .scrollable { - top: 104px; - z-index: -1; - - /* [tablet landscape+]: Revert fixed positioning */ - @include break-from-device(tablet landscape) { - position: static; - } - - /* - * Leave room for status bar in iOS web application - */ - .ios.standalone & { - - /* [orientation: portrait]: Account for status bar in portrait mode */ - @include break-at-orientation(portrait) { - top: (104px + 20px); - } - } - - /* - * Content wrapper - */ - .wrapper { - height: auto; - min-height: 100%; - - /* - * Add spacing at top and bottom of separator - */ - hr { - margin: 12px 0; - - /* [screen+]: Shorten separator */ - @include break-from-device(screen) { - width: 48px; - } - - /* Hack [IE]: Left-align horizontal rule */ - margin-right: auto; - } - - /* - * Add spacing at top and bottom of top level navigation - */ - .toc { - margin: 12px 0; - } - } - } -} - -/* - * Project information - */ -.project { - display: block; - - /* - * Leave room for status bar in iOS web application - */ - .ios.standalone & { - - /* [orientation: portrait]: Account for status bar in portrait mode */ - @include break-at-orientation(portrait) { - padding-top: 20px; - - /* - * Add status bar overlay - */ - &:before { - content: " "; - position: absolute; - top: 0; - left: 0; - z-index: 4; - width: 100%; - height: 20px; - } - } - } - - /* - * Project banner - */ - .banner { - display: table; - width: 100%; - height: 104px; - padding: 20px; - } - - /* - * Project logo - */ - .logo { - display: table-cell; - width: 64px; - padding-right: 12px; - - /* - * Project logo image - */ - img { - display: block; - width: 64px; - height: 64px; - } - } - - /* - * Project name - */ - .name { - display: table-cell; - padding-left: 4px; - font-size: 14px; - line-height: 1.25em; - vertical-align: middle; - - /* [tablet portait+]: Slightly larger project name */ - @include break-from-device(tablet portrait) { - margin: 26px 0 0 5px; - } - } - - /* - * Shrink font, if a logo is given. - */ - .logo + .name { - font-size: 12px; - } -} - -/* - * Repository - */ -.repo { - margin: 24px 0; - text-align: center; - - /* - * Inline buttons - */ - li { - display: inline-block; - padding-right: 12px; - white-space: nowrap; - - /* - * No padding on last button - */ - &:last-child { - padding-right: 0; - } - } - - /* - * Buttons - */ - a { - display: inline-block; - padding: 0px 10px 0px 6px; - font-size: 12px; - line-height: 30px; - height: 30px; - - /* - * Slightly larger icons - */ - .icon { - font-size: 18px; - vertical-align: -3px; - } - - /* - * Stars - */ - .count { - display: inline-block; - position: relative; - padding: 0px 8px 0 4px; - margin: 0 -10px 0 8px; - font-size: 12px; - - /* - * Star bubble - */ - &:before { - content: " "; - display: block; - position: absolute; - top: 0px; - left: -5px; - } - - /* - * Hide count, in case javascript is not available. - */ - .no-js & { - display: none; - } - } - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_animation.scss b/src/assets/stylesheets/modules/search/_animation.scss deleted file mode 100644 index 37df48f32..000000000 --- a/src/assets/stylesheets/modules/search/_animation.scss +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Search animation - * ------------------------------------------------------------------------- */ - -/* - * Animate header bar in offset and opacity - */ -.bar { - transform: translate3d(0, 0, 0); - transition: opacity .2s cubic-bezier(.75, 0, .25, 1), - transform .4s cubic-bezier(.75, 0, .25, 1); - - /* - * Active search mode - */ - #toggle-search:checked ~ .header &, - .toggle-search & { - transform: translate3d(0, -56px, 0); - } - - /* - * Search animations - */ - &.search { - - /* - * Hide reset button by default - */ - .button-reset { - transform: scale(0.5, 0.5); - transition: opacity .4s cubic-bezier(.1, .7, .1, 1), - transform .4s cubic-bezier(.1, .7, .1, 1); - opacity: 0; - } - - /* - * Show reset button if search is not empty - */ - &.non-empty .button-reset { - transform: scale(1.0, 1.0); - opacity: 1; - } - } -} - -/* - * Search results - */ -.results { - transition: opacity .3s .1s, - width .0s .4s, - height .0s .4s; - - /* - * Active search mode - */ - #toggle-search:checked ~ .main &, - .toggle-search & { - transition: opacity .4s, - width .0s, - height .0s; - } - - /* - * Search result item link - */ - .list a { - transition: background .25s; - } -} - -/* - * Just hide and show bars, if browser doesn't support 3D transforms - */ -.no-csstransforms3d { - - /* - * Show default bar - */ - .bar.default { - display: table; - } - - /* - * Hide search bar - */ - .bar.search { - display: none; - margin-top: 0; - } - - /* - * Active search mode - */ - #toggle-search:checked ~ .header, - .toggle-search { - - /* - * Hide default bar - */ - .bar.default { - display: none; - } - - /* - * Show search bar - */ - .bar.search { - display: table; - } - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_appearance.scss b/src/assets/stylesheets/modules/search/_appearance.scss deleted file mode 100644 index 045cd7613..000000000 --- a/src/assets/stylesheets/modules/search/_appearance.scss +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Search appearance - * ------------------------------------------------------------------------- */ - -/* - * Search bar - */ -.bar.search { - opacity: 0; - - /* - * Search input - */ - .query { - background: transparent; - color: $black; - - /* - * Search input placeholder - */ - @include placeholder { - color: $black-lighter; - } - } - - /* - * Pushed/clicked icon - */ - .button .icon:active { - background: $black-lightest; - } -} - -/* - * Search results - */ -.results { - @include drop-shadow(2); - - background: $white; - color: $black; - opacity: 0; - - /* - * Active search mode - */ - #toggle-search:checked ~ .main &, - .toggle-search & { - opacity: 1; - } - - /* - * Search meta data - */ - .meta { - background: $primary; - color: $white; - } - - /* - * Search result item link - */ - .list a { - border-bottom: 1px solid $black-lightest; - - /* - * Remove border on last element - */ - &:last-child { - border-bottom: none; - } - - /* - * Active item link - */ - &:active { - background: $black-lightest; - } - } -} - -/* - * Article link - */ -.result span { - color: $black-light; -} - -/* - * Active search bar - */ -#toggle-search:checked ~ .header, -.toggle-search .header { - background: $white; - color: $black-light; - - /* - * Add darker status bar overlay in search mode - */ - &:before { - background: $black-light; - } - - /* - * Fade out default header bar - */ - .bar.default { - opacity: 0; - } - - /* - * Fade in search header bar - */ - .bar.search { - opacity: 1; - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_layout.scss b/src/assets/stylesheets/modules/search/_layout.scss deleted file mode 100644 index 33c89be98..000000000 --- a/src/assets/stylesheets/modules/search/_layout.scss +++ /dev/null @@ -1,218 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Search layout - * ------------------------------------------------------------------------- */ - -/* - * Search bar - */ -.bar.search { - margin-top: 8px; - - /* - * Search input - */ - .query { - font-size: 18px; - padding: 13px 0; - margin: 0; - width: 100%; - height: 48px; - - /* [tablet portait+]: Slightly larger typo */ - @include break-from-device(tablet portrait) { - font-size: 20px; - padding: 12px 0; - } - - /* Hack [IE]: Hide redundant clear button */ - &::-ms-clear { - display: none; - } - } -} - -/* - * Search results - */ -.results { - position: fixed; - top: 0; - left: 0; - width: 0; - height: 100%; - z-index: 2; - overflow-y: scroll; - -webkit-overflow-scrolling: touch; - - /* [tablet landscape+]: Limit results to five entries */ - @include break-from-device(tablet landscape) { - height: auto; - top: 64px; - } - - /* - * Scrollable container - */ - .scrollable { - top: 56px; - - /* [tablet portait+]: Increase vertical spacing */ - @include break-from-device(tablet portrait) { - top: 64px; - } - - /* [tablet landscape+]: Limit results to five entries */ - @include break-from-device(tablet landscape) { - position: static; - max-height: 413px; - } - - /* - * Leave room for status bar in iOS web application - */ - .ios.standalone & { - - /* [orientation: portrait]: Account for status bar in portrait mode */ - @include break-at-orientation(portrait) { - top: (56px + 20px); - - /* [tablet portait+]: Increase vertical spacing */ - @include break-from-device(tablet portrait) { - top: (64px + 20px); - } - } - } - } - - /* - * Active search mode - */ - #toggle-search:checked ~ .main &, - .toggle-search & { - width: 100%; - - /* Hack [Firefox]: div doesn't collapse, unless this is applied */ - overflow-y: visible; - - /* [tablet portait+]: Stretch to viewport */ - @include break-to-device(tablet landscape) { - height: 100%; - } - } - - /* - * Search meta data - */ - .meta { - font-weight: 700; - - /* - * Number of results - */ - strong { - display: block; - font-size: 11px; - max-width: 1200px; - margin-left: auto; - margin-right: auto; - padding: 16px; - - /* [tablet portait+]: Increase vertical spacing */ - @include break-from-device(tablet portrait) { - padding: 16px 24px; - } - } - } - - /* - * Search result item link - */ - .list a { - display: block; - } -} - -/* - * Search result item - */ -.result { - max-width: 1200px; - margin-left: auto; - margin-right: auto; - padding: 12px 16px 16px; - - /* [tablet portait+]: Increase vertical spacing */ - @include break-from-device(tablet portrait) { - padding: 16px 24px 20px; - } - - /* - * Article title - */ - h1 { - line-height: 24px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } - - /* - * Article link - */ - span { - font-size: 12px; - text-overflow: ellipsis; - white-space: nowrap; - overflow: hidden; - } -} - -/* - * Switch visibility, if browser doesn't support 3D transforms - */ -.no-csstransforms3d { - - /* - * Hide search results - */ - .results { - display: none; - } - - /* - * Active search mode - */ - #toggle-search:checked ~ .main, - .toggle-search { - - /* - * Show search results - */ - .results { - display: block; - overflow: auto; - } - } -} \ No newline at end of file diff --git a/src/assets/stylesheets/modules/search/_typography.scss b/src/assets/stylesheets/modules/search/_typography.scss deleted file mode 100644 index 465f20ede..000000000 --- a/src/assets/stylesheets/modules/search/_typography.scss +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* - * Search meta data - */ -.meta { - text-transform: uppercase; - font-weight: 700; -} \ No newline at end of file diff --git a/src/assets/stylesheets/palettes.scss b/src/assets/stylesheets/palettes.scss deleted file mode 100644 index fe2fc69e4..000000000 --- a/src/assets/stylesheets/palettes.scss +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright (c) 2016 Martin Donath - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -/* ---------------------------------------------------------------------------- - * Dependencies - * ------------------------------------------------------------------------- */ - -@import "bourbon"; -@import "quantum-colors"; -@import "quantum-shadows"; - -/* ---------------------------------------------------------------------------- - * Application - * ------------------------------------------------------------------------- */ - -@import "palette"; - -@import "mixins/break"; - -/* ---------------------------------------------------------------------------- - * Palette - * ------------------------------------------------------------------------- */ - -/* - * Build primary palette - */ -@each $name, $color in ( - 'red': $red-400, - 'pink': $pink-500, - 'purple': $purple-400, - 'deep-purple': $deep-purple-400, - 'indigo': $indigo-500, - 'blue': $blue-500, - 'light-blue': $light-blue-500, - 'cyan': $cyan-500, - 'teal': $teal-500, - 'green': $green-500, - 'light-green': $light-green-600, - 'lime': $lime-600, - 'yellow': $yellow-800, - 'amber': $amber-600, - 'orange': $orange-600, - 'deep-orange': $deep-orange-400, - 'brown': $brown-500, - 'grey': $grey-600, - 'blue-grey': $blue-grey-600 -) { - - /* - * Device specific background hacks related to rubberband - */ - .palette-primary-#{$name} { - - /* Hack [Chrome, Opera]: Set background color in Chrome and Opera */ - @supports (-webkit-appearance: none) { - background: $color; - } - - /* - * Application header and footer - */ - .header, .footer { - background: $color; - } - - /* - * Drawer container - */ - .drawer { - - /* - * Color links - */ - .toc a { - - /* - * Current active element - */ - &.current { - color: $color; - } - - /* - * Hovered link - */ - &:hover, &:focus { - color: $color; - } - } - - /* - * Color anchors menu - */ - .anchor a { - border-left: 2px solid $color; - } - } - - /* - * Project information - */ - .project { - - /* [tablet landscape-]: Set background color */ - @include break-to-device(tablet landscape) { - background: $color; - } - } - - /* - * Article - */ - .article { - - /* - * Differing top and bottom rubberband backgrounds in iOS web application - */ - .ios.standalone & { - background: linear-gradient( - to bottom, $white 50%, $color 50%); - } - - /* - * Headlines, chapters, links and inline code - */ - h1, h2, a, code { - color: $color; - } - - /* - * Light permalinks - */ - .headerlink { - color: $black-lighter; - } - - /* - * Data table headings - */ - table th { - background: mix($color, $white, 75%); - } - } - - /* - * Search meta data - */ - .results .meta { - background: $color; - } - } -} - -/* - * Build accent palette - */ -@each $name, $color in ( - 'red': $red-a400, - 'pink': $pink-a400, - 'purple': $purple-a200, - 'deep-purple': $deep-purple-a200, - 'indigo': $indigo-a200, - 'blue': $blue-a200, - 'light-blue': $light-blue-a700, - 'cyan': $cyan-a700, - 'teal': $teal-a700, - 'green': $green-a700, - 'light-green': $light-green-a700, - 'lime': $lime-a700, - 'yellow': $yellow-a700, - 'amber': $amber-a700, - 'orange': $orange-a400, - 'deep-orange': $deep-orange-a200 -) { - - /* - * Device specific background hacks related to rubberband - */ - .palette-accent-#{$name} { - - /* - * Article - */ - .article { - - /* - * Hovered and focused links - */ - a:hover, - a:focus { - color: $color; - } - } - - /* - * Repository buttons - */ - .repo a { - background: $color; - } - } -} \ No newline at end of file diff --git a/src/base.html b/src/base.html index 5238fd148..06de751a7 100644 --- a/src/base.html +++ b/src/base.html @@ -1,273 +1,269 @@ + + +{% import "partials/i18n.html" as i18n %} + - - - - - + - - - - - - {% block htmltitle %} - - - {% if page_title %} - {{ page_title }} - {{ site_name }} - {% elif page_description %} - {{ site_name }} - {{ page_description }} - {% else %} - {{ site_name }} - {% endif %} + + {% block site_meta %} + + - {% if page_description %} - + {% if config.site_description %} + {% endif %} - {% if canonical_url %} - + {% if page.canonical_url %} + {% endif %} - {% if site_author %} - + {% if config.site_author %} + + {% endif %} + + + {% if config.site_favicon %} + + {% else %} + + {% endif %} + + + + {% endblock %} + + + {% block htmltitle %} + {% if page.title %} + {{ page.title }} - {{ config.site_name }} + {% elif config.site_description %} + {{ config.site_name }} - {{ config.site_description }} + {% else %} + {{ config.site_name }} {% endif %} {% endblock %} - - - - + + {% block libs %} + + {% endblock %} - - - - + + {% block fonts %} + {% include "partials/fonts.html" %} + {% endblock %} - - {% if config.extra.logo %} - - {% endif %} + + {% block styles %} - - {% set favicon = favicon | default("assets/images/favicon.ico", true) %} - - - - - - - - - - - {% if config.extra.palette %} + - {% endif %} + href="{{ base_url }}/assets/stylesheets/application.css" /> - - {% if config.extra.font != "none" %} - {% set text = config.extra.get("font", {}).text | default("Ubuntu") %} - {% set code = config.extra.get("font", {}).code | default("Ubuntu Mono") %} - {% set font = text + ':400,700|' + code | replace(' ', '+') %} - - - {% endif %} + + {% if config.extra.palette %} + + {% endif %} - - {% for path in extra_css %} - - {% endfor %} + + {% for path in extra_css %} + + {% endfor %} + {% endblock %} - - - - + {% block extrahead %}{% endblock %} - + {% set palette = config.extra.get("palette", {}) %} - {% set primary = palette.primary | replace(' ', '-') | lower %} - {% set accent = palette.accent | replace(' ', '-') | lower %} - + {% set primary = palette.primary | replace(" ", "-") | lower %} + {% set accent = palette.accent | replace(" ", "-") | lower %} + {% if primary or accent %} + + {% else %} + + {% endif %} - - {% if repo_name == "GitHub" and repo_url %} - {% set repo_id = repo_url | replace("https://github.com/", "") %} - {% if repo_id[-1:] == "/" %} - {% set repo_id = repo_id[:-1] %} - {% endif %} - {% endif %} - - -
      -
      -
      + + {% include "partials/svgs.html" %} - - + + - + - -
      - {% include "header.html" %} -
      + + {% block header %} + {% include "partials/header.html" %} + {% endblock %} - -
      + +
      - - {% set h1 = "\x3ch1 id=" in content %} + +
      +
      - -
      - {% include "drawer.html" %} -
      + + {% block site_nav %} - -
      -
      - - - {% if not h1 %} -

      {{ page_title | default(site_name, true)}}

      - {% endif %} - - - {{ content }} - - - - - {% block footer %} -
      - {% include "footer.html" %} -
      + + {% if page.toc %} +
      +
      +
      + {% include "partials/toc.html" %} +
      +
      +
      + {% endif %} {% endblock %} -
      -
      - -
      -
      -
      -
      -
      + +
      +
      + + + {% if config.edit_uri %} + edit + {% endif %} + + + {% block content %} + + + {% if not "\x3ch1 id=" in page.content %} +

      {{ page.title | default(config.site_name, true)}}

      + {% endif %} + + + {{ page.content }} + {% endblock %} +
      -
      -
      +
      - - - - {% for path in extra_javascript %} - - {% endfor %} + + {% block footer %} + {% include "partials/footer.html" %} + {% endblock %} + - - {% if google_analytics %} + + {% block scripts %} + + + {% for path in extra_javascript %} + + {% endfor %} + {% endblock %} + + + {% block analytics %} + {% if config.google_analytics %} - {% endif %} + {% endif %} + {% endblock %} - \ No newline at end of file + diff --git a/src/drawer.html b/src/drawer.html deleted file mode 100644 index ac7f7933a..000000000 --- a/src/drawer.html +++ /dev/null @@ -1,109 +0,0 @@ - - \ No newline at end of file diff --git a/src/footer.html b/src/footer.html deleted file mode 100644 index 012515541..000000000 --- a/src/footer.html +++ /dev/null @@ -1,48 +0,0 @@ - -{% if include_next_prev %} - -{% endif %} \ No newline at end of file diff --git a/src/header.html b/src/header.html deleted file mode 100644 index 43910b49a..000000000 --- a/src/header.html +++ /dev/null @@ -1,84 +0,0 @@ - - \ No newline at end of file diff --git a/src/main.html b/src/main.html new file mode 100644 index 000000000..7312ae073 --- /dev/null +++ b/src/main.html @@ -0,0 +1,23 @@ + + +{% extends "base.html" %} diff --git a/src/nav.html b/src/nav.html deleted file mode 100644 index 1d70b9fc1..000000000 --- a/src/nav.html +++ /dev/null @@ -1,51 +0,0 @@ - -{% if nav_item.children %} -
    3. - {{ nav_item.title }} -
        - - - {% for nav_item in nav_item.children %} - {% include "nav.html" %} - {% endfor %} -
      -
    4. - - -{% else %} -
    5. - - {{ nav_item.title }} - - - - {% if nav_item == current_page %} - - - {% if h1 %} - {% set toc = (toc | first).children %} - {% endif %} - - - {% if toc and (toc | first) %} - - {% endif %} - {% endif %} -
    6. -{% endif %} \ No newline at end of file diff --git a/src/partials/fonts.html b/src/partials/fonts.html new file mode 100644 index 000000000..038c61473 --- /dev/null +++ b/src/partials/fonts.html @@ -0,0 +1,42 @@ + + + +{% if config.extra.font != "none" %} + {% set text = config.extra.get("font", {}).text | default("Roboto") %} + {% set code = config.extra.get("font", {}).code | default("Roboto Mono") %} + {% set font = text + ':300,400,400i,700|' + code | replace(' ', '+') %} + + +{% endif %} + + + diff --git a/src/partials/footer.html b/src/partials/footer.html new file mode 100644 index 000000000..27d79ccd7 --- /dev/null +++ b/src/partials/footer.html @@ -0,0 +1,104 @@ + + +{% import "partials/i18n.html" as i18n %} + + + diff --git a/src/partials/header.html b/src/partials/header.html new file mode 100644 index 000000000..4cb0b05d9 --- /dev/null +++ b/src/partials/header.html @@ -0,0 +1,87 @@ + + + +
      + + + +
      diff --git a/src/partials/i18n.html b/src/partials/i18n.html new file mode 100644 index 000000000..bf8702f6d --- /dev/null +++ b/src/partials/i18n.html @@ -0,0 +1,31 @@ + + + +{% macro t(key) %}{{ { + "edit.link.title": "Edit this page", + "footer.previous": "Previous", + "footer.next": "Next", + "search.placeholder": "Search", + "source.link.title": "Go to repository", + "toc.title": "Table of contents" +}[key] }}{% endmacro %} diff --git a/src/partials/nav-item.html b/src/partials/nav-item.html new file mode 100644 index 000000000..eb20e8773 --- /dev/null +++ b/src/partials/nav-item.html @@ -0,0 +1,102 @@ + + + +{% if nav_item.children %} +
    7. + + + {% if nav_item.active %} + + {% else %} + + {% endif %} + + + + +
    8. + + +{% elif nav_item == page %} +
    9. + {% set toc_ = page.toc %} + + + + + + {% if "\x3ch1 id=" in page.content %} + {% set toc_ = (toc_ | first).children %} + {% endif %} + + + {% if toc_ and (toc_ | first) %} + + {% endif %} + + {{ nav_item.title }} + + + + {% if page.toc %} + {% include "partials/toc.html" %} + {% endif %} +
    10. + + +{% else %} +
    11. + {% if nav_item.active %} + + {{ nav_item.title }} + + {% else %} + + {{ nav_item.title }} + + {% endif %} +
    12. +{% endif %} diff --git a/src/partials/nav.html b/src/partials/nav.html new file mode 100644 index 000000000..bef7c8095 --- /dev/null +++ b/src/partials/nav.html @@ -0,0 +1,48 @@ + + + + diff --git a/src/partials/search.html b/src/partials/search.html new file mode 100644 index 000000000..d1514a4ed --- /dev/null +++ b/src/partials/search.html @@ -0,0 +1,42 @@ + + +{% import "partials/i18n.html" as i18n %} + + + diff --git a/src/partials/social.html b/src/partials/social.html new file mode 100644 index 000000000..c572289a3 --- /dev/null +++ b/src/partials/social.html @@ -0,0 +1,34 @@ + + + +{% if config.extra.social %} + +{% endif %} diff --git a/src/partials/source.html b/src/partials/source.html new file mode 100644 index 000000000..9d8e90935 --- /dev/null +++ b/src/partials/source.html @@ -0,0 +1,55 @@ + + +{% import "partials/i18n.html" as i18n %} + + +{% set platform = config.extra.repo_icon or config.repo_url %} +{% if "github" in platform %} + {% set repo_type = "github" %} +{% elif "gitlab" in platform %} + {% set repo_type = "gitlab" %} +{% elif "bitbucket" in platform %} + {% set repo_type = "bitbucket" %} +{% else %} + {% set repo_type = "" %} +{% endif %} + + +{% block repo %} + + {% if repo_type %} +
      + + + +
      + {% endif %} +
      + {{ config.repo_name }} +
      +
      +{% endblock %} diff --git a/src/partials/svgs.html b/src/partials/svgs.html new file mode 100644 index 000000000..8b88039be --- /dev/null +++ b/src/partials/svgs.html @@ -0,0 +1,38 @@ + + + +
      + + + {% set platform = config.extra.repo_icon or config.repo_url %} + {% if "github" in platform %} + {% include "assets/images/icons/github.svg" %} + {% elif "gitlab" in platform %} + {% include "assets/images/icons/gitlab.svg" %} + {% elif "bitbucket" in platform %} + {% include "assets/images/icons/bitbucket.svg" %} + {% endif %} +
      diff --git a/src/partials/toc-item.html b/src/partials/toc-item.html new file mode 100644 index 000000000..76c5ab7fc --- /dev/null +++ b/src/partials/toc-item.html @@ -0,0 +1,40 @@ + + + +
    13. + + {{ toc_item.title }} + + + + {% if toc_item.children %} + + {% endif %} +
    14. diff --git a/src/partials/toc.html b/src/partials/toc.html new file mode 100644 index 000000000..999bb2450 --- /dev/null +++ b/src/partials/toc.html @@ -0,0 +1,48 @@ + + +{% import "partials/i18n.html" as i18n %} + + +