Commit e2d68a6f authored by hyeryung's avatar hyeryung

init

parents
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
{
"extends": "standard",
"rules": {
"arrow-parens": ["error", "always"],
"comma-dangle": ["error", {
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline"
}],
"no-restricted-properties": ["error", {
"property": "substr",
"message": "Use String#slice instead."
}],
"max-len": [1, 120, 2],
"spaced-comment": "off",
"radix": ["error", "always"]
}
}
/build/
/node_modules/
/public/
image: node:10.14.2-stretch
stages: [setup, verify, deploy]
install:
stage: setup
cache:
paths:
- .cache/npm
script:
- &npm_install npm install --quiet --no-progress --cache=.cache/npm
lint:
stage: verify
cache: &pull_cache
policy: pull
paths:
- .cache/npm
script:
- *npm_install
- node_modules/.bin/gulp lint
bundle-stable:
stage: deploy
only:
- master@swd/swlab-ui
cache: *pull_cache
script:
- *npm_install
- node_modules/.bin/gulp bundle
artifacts:
paths:
- build/ui-bundle.zip
bundle-dev:
stage: deploy
except:
- master
cache: *pull_cache
script:
- *npm_install
- node_modules/.bin/gulp bundle
artifacts:
expire_in: 1 day # unless marked as keep from job page
paths:
- build/ui-bundle.zip
pages:
stage: deploy
only:
- master@swd/swlab-ui
cache: *pull_cache
script:
- *npm_install
- node_modules/.bin/gulp preview:build
# FIXME figure out a way to avoid copying these files to preview site
- rm -rf public/_/{helpers,layouts,partials}
artifacts:
paths:
- public
{
"description": "Build tasks for the SWLab UI project",
"flags.tasksDepth": 1
}
{
"extends": "stylelint-config-standard",
"rules": {
"comment-empty-line-before": null,
"no-descending-specificity": null,
}
}
Mozilla Public License Version 2.0
==================================
1. Definitions
--------------
1.1. "Contributor"
means each individual or legal entity that creates, contributes to
the creation of, or owns Covered Software.
1.2. "Contributor Version"
means the combination of the Contributions of others (if any) used
by a Contributor and that particular Contributor's Contribution.
1.3. "Contribution"
means Covered Software of a particular Contributor.
1.4. "Covered Software"
means Source Code Form to which the initial Contributor has attached
the notice in Exhibit A, the Executable Form of such Source Code
Form, and Modifications of such Source Code Form, in each case
including portions thereof.
1.5. "Incompatible With Secondary Licenses"
means
(a) that the initial Contributor has attached the notice described
in Exhibit B to the Covered Software; or
(b) that the Covered Software was made available under the terms of
version 1.1 or earlier of the License, but not also under the
terms of a Secondary License.
1.6. "Executable Form"
means any form of the work other than Source Code Form.
1.7. "Larger Work"
means a work that combines Covered Software with other material, in
a separate file or files, that is not Covered Software.
1.8. "License"
means this document.
1.9. "Licensable"
means having the right to grant, to the maximum extent possible,
whether at the time of the initial grant or subsequently, any and
all of the rights conveyed by this License.
1.10. "Modifications"
means any of the following:
(a) any file in Source Code Form that results from an addition to,
deletion from, or modification of the contents of Covered
Software; or
(b) any new file in Source Code Form that contains any Covered
Software.
1.11. "Patent Claims" of a Contributor
means any patent claim(s), including without limitation, method,
process, and apparatus claims, in any patent Licensable by such
Contributor that would be infringed, but for the grant of the
License, by the making, using, selling, offering for sale, having
made, import, or transfer of either its Contributions or its
Contributor Version.
1.12. "Secondary License"
means either the GNU General Public License, Version 2.0, the GNU
Lesser General Public License, Version 2.1, the GNU Affero General
Public License, Version 3.0, or any later versions of those
licenses.
1.13. "Source Code Form"
means the form of the work preferred for making modifications.
1.14. "You" (or "Your")
means an individual or a legal entity exercising rights under this
License. For legal entities, "You" includes any entity that
controls, is controlled by, or is under common control with You. For
purposes of this definition, "control" means (a) the power, direct
or indirect, to cause the direction or management of such entity,
whether by contract or otherwise, or (b) ownership of more than
fifty percent (50%) of the outstanding shares or beneficial
ownership of such entity.
2. License Grants and Conditions
--------------------------------
2.1. Grants
Each Contributor hereby grants You a world-wide, royalty-free,
non-exclusive license:
(a) under intellectual property rights (other than patent or trademark)
Licensable by such Contributor to use, reproduce, make available,
modify, display, perform, distribute, and otherwise exploit its
Contributions, either on an unmodified basis, with Modifications, or
as part of a Larger Work; and
(b) under Patent Claims of such Contributor to make, use, sell, offer
for sale, have made, import, and otherwise transfer either its
Contributions or its Contributor Version.
2.2. Effective Date
The licenses granted in Section 2.1 with respect to any Contribution
become effective for each Contribution on the date the Contributor first
distributes such Contribution.
2.3. Limitations on Grant Scope
The licenses granted in this Section 2 are the only rights granted under
this License. No additional rights or licenses will be implied from the
distribution or licensing of Covered Software under this License.
Notwithstanding Section 2.1(b) above, no patent license is granted by a
Contributor:
(a) for any code that a Contributor has removed from Covered Software;
or
(b) for infringements caused by: (i) Your and any other third party's
modifications of Covered Software, or (ii) the combination of its
Contributions with other software (except as part of its Contributor
Version); or
(c) under Patent Claims infringed by Covered Software in the absence of
its Contributions.
This License does not grant any rights in the trademarks, service marks,
or logos of any Contributor (except as may be necessary to comply with
the notice requirements in Section 3.4).
2.4. Subsequent Licenses
No Contributor makes additional grants as a result of Your choice to
distribute the Covered Software under a subsequent version of this
License (see Section 10.2) or under the terms of a Secondary License (if
permitted under the terms of Section 3.3).
2.5. Representation
Each Contributor represents that the Contributor believes its
Contributions are its original creation(s) or it has sufficient rights
to grant the rights to its Contributions conveyed by this License.
2.6. Fair Use
This License is not intended to limit any rights You have under
applicable copyright doctrines of fair use, fair dealing, or other
equivalents.
2.7. Conditions
Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
in Section 2.1.
3. Responsibilities
-------------------
3.1. Distribution of Source Form
All distribution of Covered Software in Source Code Form, including any
Modifications that You create or to which You contribute, must be under
the terms of this License. You must inform recipients that the Source
Code Form of the Covered Software is governed by the terms of this
License, and how they can obtain a copy of this License. You may not
attempt to alter or restrict the recipients' rights in the Source Code
Form.
3.2. Distribution of Executable Form
If You distribute Covered Software in Executable Form then:
(a) such Covered Software must also be made available in Source Code
Form, as described in Section 3.1, and You must inform recipients of
the Executable Form how they can obtain a copy of such Source Code
Form by reasonable means in a timely manner, at a charge no more
than the cost of distribution to the recipient; and
(b) You may distribute such Executable Form under the terms of this
License, or sublicense it under different terms, provided that the
license for the Executable Form does not attempt to limit or alter
the recipients' rights in the Source Code Form under this License.
3.3. Distribution of a Larger Work
You may create and distribute a Larger Work under terms of Your choice,
provided that You also comply with the requirements of this License for
the Covered Software. If the Larger Work is a combination of Covered
Software with a work governed by one or more Secondary Licenses, and the
Covered Software is not Incompatible With Secondary Licenses, this
License permits You to additionally distribute such Covered Software
under the terms of such Secondary License(s), so that the recipient of
the Larger Work may, at their option, further distribute the Covered
Software under the terms of either this License or such Secondary
License(s).
3.4. Notices
You may not remove or alter the substance of any license notices
(including copyright notices, patent notices, disclaimers of warranty,
or limitations of liability) contained within the Source Code Form of
the Covered Software, except that You may alter any license notices to
the extent required to remedy known factual inaccuracies.
3.5. Application of Additional Terms
You may choose to offer, and to charge a fee for, warranty, support,
indemnity or liability obligations to one or more recipients of Covered
Software. However, You may do so only on Your own behalf, and not on
behalf of any Contributor. You must make it absolutely clear that any
such warranty, support, indemnity, or liability obligation is offered by
You alone, and You hereby agree to indemnify every Contributor for any
liability incurred by such Contributor as a result of warranty, support,
indemnity or liability terms You offer. You may include additional
disclaimers of warranty and limitations of liability specific to any
jurisdiction.
4. Inability to Comply Due to Statute or Regulation
---------------------------------------------------
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Software due to
statute, judicial order, or regulation then You must: (a) comply with
the terms of this License to the maximum extent possible; and (b)
describe the limitations and the code they affect. Such description must
be placed in a text file included with all distributions of the Covered
Software under this License. Except to the extent prohibited by statute
or regulation, such description must be sufficiently detailed for a
recipient of ordinary skill to be able to understand it.
5. Termination
--------------
5.1. The rights granted under this License will terminate automatically
if You fail to comply with any of its terms. However, if You become
compliant, then the rights granted under this License from a particular
Contributor are reinstated (a) provisionally, unless and until such
Contributor explicitly and finally terminates Your grants, and (b) on an
ongoing basis, if such Contributor fails to notify You of the
non-compliance by some reasonable means prior to 60 days after You have
come back into compliance. Moreover, Your grants from a particular
Contributor are reinstated on an ongoing basis if such Contributor
notifies You of the non-compliance by some reasonable means, this is the
first time You have received notice of non-compliance with this License
from such Contributor, and You become compliant prior to 30 days after
Your receipt of the notice.
5.2. If You initiate litigation against any entity by asserting a patent
infringement claim (excluding declaratory judgment actions,
counter-claims, and cross-claims) alleging that a Contributor Version
directly or indirectly infringes any patent, then the rights granted to
You by any and all Contributors for the Covered Software under Section
2.1 of this License shall terminate.
5.3. In the event of termination under Sections 5.1 or 5.2 above, all
end user license agreements (excluding distributors and resellers) which
have been validly granted by You or Your distributors under this License
prior to termination shall survive termination.
************************************************************************
* *
* 6. Disclaimer of Warranty *
* ------------------------- *
* *
* Covered Software is provided under this License on an "as is" *
* basis, without warranty of any kind, either expressed, implied, or *
* statutory, including, without limitation, warranties that the *
* Covered Software is free of defects, merchantable, fit for a *
* particular purpose or non-infringing. The entire risk as to the *
* quality and performance of the Covered Software is with You. *
* Should any Covered Software prove defective in any respect, You *
* (not any Contributor) assume the cost of any necessary servicing, *
* repair, or correction. This disclaimer of warranty constitutes an *
* essential part of this License. No use of any Covered Software is *
* authorized under this License except under this disclaimer. *
* *
************************************************************************
************************************************************************
* *
* 7. Limitation of Liability *
* -------------------------- *
* *
* Under no circumstances and under no legal theory, whether tort *
* (including negligence), contract, or otherwise, shall any *
* Contributor, or anyone who distributes Covered Software as *
* permitted above, be liable to You for any direct, indirect, *
* special, incidental, or consequential damages of any character *
* including, without limitation, damages for lost profits, loss of *
* goodwill, work stoppage, computer failure or malfunction, or any *
* and all other commercial damages or losses, even if such party *
* shall have been informed of the possibility of such damages. This *
* limitation of liability shall not apply to liability for death or *
* personal injury resulting from such party's negligence to the *
* extent applicable law prohibits such limitation. Some *
* jurisdictions do not allow the exclusion or limitation of *
* incidental or consequential damages, so this exclusion and *
* limitation may not apply to You. *
* *
************************************************************************
8. Litigation
-------------
Any litigation relating to this License may be brought only in the
courts of a jurisdiction where the defendant maintains its principal
place of business and such litigation shall be governed by laws of that
jurisdiction, without reference to its conflict-of-law provisions.
Nothing in this Section shall prevent a party's ability to bring
cross-claims or counter-claims.
9. Miscellaneous
----------------
This License represents the complete agreement concerning the subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. Any law or regulation which provides
that the language of a contract shall be construed against the drafter
shall not be used to construe this License against a Contributor.
10. Versions of the License
---------------------------
10.1. New Versions
Mozilla Foundation is the license steward. Except as provided in Section
10.3, no one other than the license steward has the right to modify or
publish new versions of this License. Each version will be given a
distinguishing version number.
10.2. Effect of New Versions
You may distribute the Covered Software under the terms of the version
of the License under which You originally received the Covered Software,
or under the terms of any subsequent version published by the license
steward.
10.3. Modified Versions
If you create software not governed by this License, and you want to
create a new license for such software, you may create and use a
modified version of this License if you rename the license and remove
any references to the name of the license steward (except to note that
such modified license differs from this License).
10.4. Distributing Source Code Form that is Incompatible With Secondary
Licenses
If You choose to distribute Source Code Form that is Incompatible With
Secondary Licenses under the terms of this version of the License, the
notice described in Exhibit B of this License must be attached.
Exhibit A - Source Code Form License Notice
-------------------------------------------
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at http://mozilla.org/MPL/2.0/.
If it is not possible or desirable to put the notice in a particular
file, then You may include the notice in a location (such as a LICENSE
file in a relevant directory) where a recipient would be likely to look
for such a notice.
You may add additional accurate notices of copyright ownership.
Exhibit B - "Incompatible With Secondary Licenses" Notice
---------------------------------------------------------
This Source Code Form is "Incompatible With Secondary Licenses", as
defined by the Mozilla Public License, v. 2.0.
# SWLab UI
'use strict'
const metadata = require('undertaker/lib/helpers/metadata')
const { watch } = require('gulp')
module.exports = ({ name, desc, opts, call: fn, loop }) => {
if (name) {
const displayName = fn.displayName
if (displayName === '<series>' || displayName === '<parallel>') {
metadata.get(fn).tree.label = `${displayName} ${name}`
}
fn.displayName = name
}
if (loop) {
const delegate = fn
name = delegate.displayName
delegate.displayName = `${name}:loop`
fn = () => watch(loop, { ignoreInitial: false }, delegate)
fn.displayName = name
}
if (desc) fn.description = desc
if (opts) fn.flags = opts
return fn
}
'use strict'
module.exports = (...tasks) => {
const seed = {}
if (tasks.length) {
if (tasks.lastIndexOf(tasks[0]) > 0) {
const task1 = tasks.shift()
seed.default = Object.assign(task1.bind(null), { description: `=> ${task1.displayName}`, displayName: 'default' })
}
return tasks.reduce((acc, it) => (acc[it.displayName || it.name] = it) && acc, seed)
} else {
return seed
}
}
'use strict'
const log = require('fancy-log')
const PluginError = require('plugin-error')
const prettierEslint = require('prettier-eslint')
const { Transform } = require('stream')
const map = (transform) => new Transform({ objectMode: true, transform })
module.exports = () => {
const report = { changed: 0, unchanged: 0 }
return map(format).on('finish', () => {
if (report.changed > 0) {
const changed = 'formatted '
.concat(report.changed)
.concat(' file')
.concat(report.changed === 1 ? '' : 's')
const unchanged = 'left '
.concat(report.unchanged)
.concat(' file')
.concat(report.unchanged === 1 ? '' : 's')
.concat(' unchanged')
log(`prettier-eslint: ${changed}; ${unchanged}`)
} else {
log(`prettier-eslint: left ${report.unchanged} file${report.unchanged === 1 ? '' : 's'} unchanged`)
}
})
function format (file, enc, next) {
if (file.isNull()) return next()
if (file.isStream()) return next(new PluginError('gulp-prettier-eslint', 'Streaming not supported'))
const input = file.contents.toString()
const output = prettierEslint({ text: input, filePath: file.path })
if (input === output) {
report.unchanged += 1
} else {
report.changed += 1
file.contents = Buffer.from(output)
}
next(null, file)
}
}
'use strict'
const Asciidoctor = require('@asciidoctor/core')()
const fs = require('fs-extra')
const handlebars = require('handlebars')
const merge = require('merge-stream')
const ospath = require('path')
const path = ospath.posix
const requireFromString = require('require-from-string')
const { Transform } = require('stream')
const map = (transform = () => {}, flush = undefined) => new Transform({ objectMode: true, transform, flush })
const vfs = require('vinyl-fs')
const yaml = require('js-yaml')
const ASCIIDOC_ATTRIBUTES = { experimental: '', icons: 'font', sectanchors: '', 'source-highlighter': 'highlight.js' }
module.exports = (src, previewSrc, previewDest, sink = () => map()) => (done) =>
Promise.all([
loadSampleUiModel(previewSrc),
toPromise(
merge(compileLayouts(src), registerPartials(src), registerHelpers(src), copyImages(previewSrc, previewDest))
),
])
.then(([baseUiModel, { layouts }]) => {
const extensions = ((baseUiModel.asciidoc || {}).extensions || []).map((request) => {
ASCIIDOC_ATTRIBUTES[request.replace(/^@|\.js$/, '').replace(/[/]/g, '-') + '-loaded'] = ''
const extension = require(request)
extension.register.call(Asciidoctor.Extensions)
return extension
})
const asciidoc = { extensions }
for (const component of baseUiModel.site.components) {
for (const version of component.versions || []) version.asciidoc = asciidoc
}
baseUiModel = { ...baseUiModel, env: process.env }
delete baseUiModel.asciidoc
return [baseUiModel, layouts]
})
.then(([baseUiModel, layouts]) =>
vfs
.src('**/*.adoc', { base: previewSrc, cwd: previewSrc })
.pipe(
map((file, enc, next) => {
const siteRootPath = path.relative(ospath.dirname(file.path), ospath.resolve(previewSrc))
const uiModel = { ...baseUiModel }
uiModel.page = { ...uiModel.page }
uiModel.siteRootPath = siteRootPath
uiModel.uiRootPath = path.join(siteRootPath, '_')
if (file.stem === '404') {
uiModel.page = { layout: '404', title: 'Page Not Found' }
} else {
const doc = Asciidoctor.load(file.contents, { safe: 'safe', attributes: ASCIIDOC_ATTRIBUTES })
uiModel.page.attributes = Object.entries(doc.getAttributes())
.filter(([name, val]) => name.startsWith('page-'))
.reduce((accum, [name, val]) => {
accum[name.slice(5)] = val
return accum
}, {})
uiModel.page.layout = doc.getAttribute('page-layout', 'default')
uiModel.page.title = doc.getDocumentTitle()
uiModel.page.contents = Buffer.from(doc.convert())
}
file.extname = '.html'
try {
file.contents = Buffer.from(layouts.get(uiModel.page.layout)(uiModel))
next(null, file)
} catch (e) {
next(transformHandlebarsError(e, uiModel.page.layout))
}
})
)
.pipe(vfs.dest(previewDest))
.on('error', done)
.pipe(sink())
)
function loadSampleUiModel (src) {
return fs.readFile(ospath.join(src, 'ui-model.yml'), 'utf8').then((contents) => yaml.safeLoad(contents))
}
function registerPartials (src) {
return vfs.src('partials/*.hbs', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerPartial(file.stem, file.contents.toString())
next()
})
)
}
function registerHelpers (src) {
handlebars.registerHelper('resolvePage', resolvePage)
handlebars.registerHelper('resolvePageURL', resolvePageURL)
return vfs.src('helpers/*.js', { base: src, cwd: src }).pipe(
map((file, enc, next) => {
handlebars.registerHelper(file.stem, requireFromString(file.contents.toString()))
next()
})
)
}
function compileLayouts (src) {
const layouts = new Map()
return vfs.src('layouts/*.hbs', { base: src, cwd: src }).pipe(
map(
(file, enc, next) => {
const srcName = path.join(src, file.relative)
layouts.set(file.stem, handlebars.compile(file.contents.toString(), { preventIndent: true, srcName }))
next()
},
function (done) {
this.push({ layouts })
done()
}
)
)
}
function copyImages (src, dest) {
return vfs
.src('**/*.{png,svg}', { base: src, cwd: src })
.pipe(vfs.dest(dest))
.pipe(map((file, enc, next) => next()))
}
function resolvePage (spec, context = {}) {
if (spec) return { pub: { url: resolvePageURL(spec) } }
}
function resolvePageURL (spec, context = {}) {
if (spec) return '/' + (spec = spec.split(':').pop()).slice(0, spec.lastIndexOf('.')) + '.html'
}
function transformHandlebarsError ({ message, stack }, layout) {
const m = stack.match(/^ *at Object\.ret \[as (.+?)\]/m)
const templatePath = `src/${m ? 'partials/' + m[1] : 'layouts/' + layout}.hbs`
const err = new Error(`${message}${~message.indexOf('\n') ? '\n^ ' : ' '}in UI template ${templatePath}`)
err.stack = [err.toString()].concat(stack.slice(message.length + 8)).join('\n')
return err
}
function toPromise (stream) {
return new Promise((resolve, reject, data = {}) =>
stream
.on('error', reject)
.on('data', (chunk) => chunk.constructor === Object && Object.assign(data, chunk))
.on('finish', () => resolve(data))
)
}
'use strict'
const autoprefixer = require('autoprefixer')
const browserify = require('browserify')
const concat = require('gulp-concat')
const cssnano = require('cssnano')
const fs = require('fs-extra')
const imagemin = require('gulp-imagemin')
const merge = require('merge-stream')
const ospath = require('path')
const path = ospath.posix
const postcss = require('gulp-postcss')
const postcssCalc = require('postcss-calc')
const postcssImport = require('postcss-import')
const postcssUrl = require('postcss-url')
const postcssVar = require('postcss-custom-properties')
const { Transform } = require('stream')
const map = (transform) => new Transform({ objectMode: true, transform })
const through = () => map((file, enc, next) => next(null, file))
const uglify = require('gulp-uglify')
const vfs = require('vinyl-fs')
module.exports = (src, dest, preview) => () => {
const opts = { base: src, cwd: src }
const sourcemaps = preview || process.env.SOURCEMAPS === 'true'
const postcssPlugins = [
postcssImport,
(css, { messages, opts: { file } }) =>
Promise.all(
messages
.reduce((accum, { file: depPath, type }) => (type === 'dependency' ? accum.concat(depPath) : accum), [])
.map((importedPath) => fs.stat(importedPath).then(({ mtime }) => mtime))
).then((mtimes) => {
const newestMtime = mtimes.reduce((max, curr) => (!max || curr > max ? curr : max), file.stat.mtime)
if (newestMtime > file.stat.mtime) file.stat.mtimeMs = +(file.stat.mtime = newestMtime)
}),
postcssUrl([
{
filter: (asset) => new RegExp('^[~][^/]*(?:font|typeface)[^/]*/.*/files/.+[.](?:ttf|woff2?)$').test(asset.url),
url: (asset) => {
const relpath = asset.pathname.slice(1)
const abspath = require.resolve(relpath)
const basename = ospath.basename(abspath)
const destpath = ospath.join(dest, 'font', basename)
if (!fs.pathExistsSync(destpath)) fs.copySync(abspath, destpath)
return path.join('..', 'font', basename)
},
},
]),
postcssVar({ preserve: preview }),
// NOTE to make vars.css available to all top-level stylesheets, use the next line in place of the previous one
//postcssVar({ importFrom: path.join(src, 'css', 'vars.css'), preserve: preview }),
preview ? postcssCalc : () => {}, // cssnano already applies postcssCalc
autoprefixer,
preview
? () => {}
: (css, result) => cssnano({ preset: 'default' })(css, result).then(() => postcssPseudoElementFixer(css, result)),
]
return merge(
vfs.src('ui.yml', { ...opts, allowEmpty: true }),
vfs
.src('js/+([0-9])-*.js', { ...opts, read: false, sourcemaps })
.pipe(bundle(opts))
.pipe(uglify({ output: { comments: /^! / } }))
// NOTE concat already uses stat from newest combined file
.pipe(concat('js/site.js')),
vfs
.src('js/vendor/*([^.])?(.bundle).js', { ...opts, read: false })
.pipe(bundle(opts))
.pipe(uglify({ output: { comments: /^! / } })),
vfs
.src('js/vendor/*.min.js', opts)
.pipe(map((file, enc, next) => next(null, Object.assign(file, { extname: '' }, { extname: '.js' })))),
// NOTE use the next line to bundle a JavaScript library that cannot be browserified, like jQuery
//vfs.src(require.resolve('<package-name-or-require-path>'), opts).pipe(concat('js/vendor/<library-name>.js')),
vfs
.src(['css/site.css', 'css/vendor/*.css'], { ...opts, sourcemaps })
.pipe(postcss((file) => ({ plugins: postcssPlugins, options: { file } }))),
vfs.src('font/*.{ttf,woff*(2)}', opts),
vfs.src('img/**/*.{gif,ico,jpg,png,svg}', opts).pipe(
preview
? through()
: imagemin(
[
imagemin.gifsicle(),
imagemin.jpegtran(),
imagemin.optipng(),
imagemin.svgo({
plugins: [
{ cleanupIDs: { preservePrefixes: ['icon-', 'view-'] } },
{ removeViewBox: false },
{ removeDesc: false },
],
}),
].reduce((accum, it) => (it ? accum.concat(it) : accum), [])
)
),
vfs.src('helpers/*.js', opts),
vfs.src('layouts/*.hbs', opts),
vfs.src('partials/*.hbs', opts),
vfs.src('static/**/*[!~]', { ...opts, base: ospath.join(src, 'static'), dot: true })
).pipe(vfs.dest(dest, { sourcemaps: sourcemaps && '.' }))
}
function bundle ({ base: basedir, ext: bundleExt = '.bundle.js' }) {
return map((file, enc, next) => {
if (bundleExt && file.relative.endsWith(bundleExt)) {
const mtimePromises = []
const bundlePath = file.path
browserify(file.relative, { basedir, detectGlobals: false })
.plugin('browser-pack-flat/plugin')
.on('file', (bundledPath) => {
if (bundledPath !== bundlePath) mtimePromises.push(fs.stat(bundledPath).then(({ mtime }) => mtime))
})
.bundle((bundleError, bundleBuffer) =>
Promise.all(mtimePromises).then((mtimes) => {
const newestMtime = mtimes.reduce((max, curr) => (curr > max ? curr : max), file.stat.mtime)
if (newestMtime > file.stat.mtime) file.stat.mtimeMs = +(file.stat.mtime = newestMtime)
if (bundleBuffer !== undefined) file.contents = bundleBuffer
next(bundleError, Object.assign(file, { path: file.path.slice(0, file.path.length - 10) + '.js' }))
})
)
return
}
fs.readFile(file.path, 'UTF-8').then((contents) => {
next(null, Object.assign(file, { contents: Buffer.from(contents) }))
})
})
}
function postcssPseudoElementFixer (css, result) {
css.walkRules(/(?:^|[^:]):(?:before|after)/, (rule) => {
rule.selector = rule.selectors.map((it) => it.replace(/(^|[^:]):(before|after)$/, '$1::$2')).join(',')
})
}
'use strict'
const prettier = require('../lib/gulp-prettier-eslint')
const vfs = require('vinyl-fs')
module.exports = (files) => () =>
vfs
.src(files)
.pipe(prettier())
.pipe(vfs.dest((file) => file.base))
'use strict'
const camelCase = (name) => name.replace(/[-]./g, (m) => m.slice(1).toUpperCase())
module.exports = require('require-directory')(module, __dirname, { recurse: false, rename: camelCase })
'use strict'
const stylelint = require('gulp-stylelint')
const vfs = require('vinyl-fs')
module.exports = (files) => (done) =>
vfs
.src(files)
.pipe(stylelint({ reporters: [{ formatter: 'string', console: true }], failAfterError: true }))
.on('error', done)
'use strict'
const eslint = require('gulp-eslint')
const vfs = require('vinyl-fs')
module.exports = (files) => (done) =>
vfs
.src(files)
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError())
.on('error', done)
'use strict'
const ospath = require('path')
const vfs = require('vinyl-fs')
const zip = (() => {
try {
return require('@vscode/gulp-vinyl-zip')
} catch {
return require('gulp-vinyl-zip')
}
})()
module.exports = (src, dest, bundleName, onFinish) => () =>
vfs
.src('**/*', { base: src, cwd: src, dot: true })
.pipe(zip.dest(ospath.join(dest, `${bundleName}-bundle.zip`)))
.on('finish', () => onFinish && onFinish(ospath.resolve(dest, `${bundleName}-bundle.zip`)))
'use strict'
const fs = require('fs-extra')
const { Transform } = require('stream')
const map = (transform) => new Transform({ objectMode: true, transform })
const vfs = require('vinyl-fs')
module.exports = (files) => () =>
vfs.src(files, { allowEmpty: true }).pipe(map((file, enc, next) => fs.remove(file.path, next)))
'use strict'
const connect = require('gulp-connect')
const os = require('os')
const ANY_HOST = '0.0.0.0'
const URL_RX = /(https?):\/\/(?:[^/: ]+)(:\d+)?/
module.exports = (root, opts = {}, watch = undefined) => (done) => {
connect.server({ ...opts, middleware: opts.host === ANY_HOST ? decorateLog : undefined, root }, function () {
this.server.on('close', done)
if (watch) watch()
})
}
function decorateLog (_, app) {
const _log = app.log
app.log = (msg) => {
if (msg.startsWith('Server started ')) {
const localIp = getLocalIp()
const replacement = '$1://localhost$2' + (localIp ? ` and $1://${localIp}$2` : '')
msg = msg.replace(URL_RX, replacement)
}
_log(msg)
}
return []
}
function getLocalIp () {
for (const records of Object.values(os.networkInterfaces())) {
for (const record of records) {
if (!record.internal && record.family === 'IPv4') return record.address
}
}
return 'localhost'
}
'use strict'
const { parallel, series, watch } = require('gulp')
const createTask = require('./gulp.d/lib/create-task')
const exportTasks = require('./gulp.d/lib/export-tasks')
const log = require('fancy-log')
const bundleName = 'ui'
const buildDir = 'build'
const previewSrcDir = 'preview-src'
const previewDestDir = 'public'
const srcDir = 'src'
const destDir = `${previewDestDir}/_`
const { reload: livereload } = process.env.LIVERELOAD === 'true' ? require('gulp-connect') : {}
const serverConfig = { host: '0.0.0.0', port: 5252, livereload }
const task = require('./gulp.d/tasks')
const glob = {
all: [srcDir, previewSrcDir],
css: `${srcDir}/css/**/*.css`,
js: ['gulpfile.js', 'gulp.d/**/*.js', `${srcDir}/helpers/*.js`, `${srcDir}/js/**/+([^.])?(.bundle).js`],
}
const cleanTask = createTask({
name: 'clean',
desc: 'Clean files and folders generated by build',
call: task.remove(['build', 'public']),
})
const lintCssTask = createTask({
name: 'lint:css',
desc: 'Lint the CSS source files using stylelint (standard config)',
call: task.lintCss(glob.css),
})
const lintJsTask = createTask({
name: 'lint:js',
desc: 'Lint the JavaScript source files using eslint (JavaScript Standard Style)',
call: task.lintJs(glob.js),
})
const lintTask = createTask({
name: 'lint',
desc: 'Lint the CSS and JavaScript source files',
call: parallel(lintCssTask, lintJsTask),
})
const formatTask = createTask({
name: 'format',
desc: 'Format the JavaScript source files using prettify (JavaScript Standard Style)',
call: task.format(glob.js),
})
const buildTask = createTask({
name: 'build',
desc: 'Build and stage the UI assets for bundling',
call: task.build(
srcDir,
destDir,
process.argv.slice(2).some((name) => name.startsWith('preview'))
),
})
const bundleBuildTask = createTask({
name: 'bundle:build',
call: series(cleanTask, lintTask, buildTask),
})
const bundlePackTask = createTask({
name: 'bundle:pack',
desc: 'Create a bundle of the staged UI assets for publishing',
call: task.pack(
destDir,
buildDir,
bundleName,
(bundlePath) => !process.env.CI && log(`Antora option: --ui-bundle-url=${bundlePath}`)
),
})
const bundleTask = createTask({
name: 'bundle',
desc: 'Clean, lint, build, and bundle the UI for publishing',
call: series(bundleBuildTask, bundlePackTask),
})
const packTask = createTask({
name: 'pack',
desc: '(deprecated; use bundle instead)',
call: series(bundleTask),
})
const buildPreviewPagesTask = createTask({
name: 'preview:build-pages',
call: task.buildPreviewPages(srcDir, previewSrcDir, previewDestDir, livereload),
})
const previewBuildTask = createTask({
name: 'preview:build',
desc: 'Process and stage the UI assets and generate pages for the preview',
call: parallel(buildTask, buildPreviewPagesTask),
})
const previewServeTask = createTask({
name: 'preview:serve',
call: task.serve(previewDestDir, serverConfig, () => watch(glob.all, previewBuildTask)),
})
const previewTask = createTask({
name: 'preview',
desc: 'Generate a preview site and launch a server to view it',
call: series(previewBuildTask, previewServeTask),
})
module.exports = exportTasks(
bundleTask,
cleanTask,
lintTask,
formatTask,
buildTask,
bundleTask,
bundlePackTask,
previewTask,
previewBuildTask,
packTask
)
'use strict'
// This placeholder script allows this package to be discovered using require.resolve.
// It may be used in the future to export information about the files in this UI.
This source diff could not be displayed because it is too large. You can view the blob instead.
{
"name": "swlab-ui",
"description": "swlab-ui",
"homepage": "https://gitlab.bwg.co.kr/swd/swlab-ui.git",
"license": "MPL-2.0",
"repository": {
"type": "git",
"url": "https://gitlab.bwg.co.kr/swd/swlab-ui.git"
},
"engines": {
"node": ">= 8.0.0"
},
"browserslist": [
"last 2 versions"
],
"devDependencies": {
"@asciidoctor/core": "~2.2",
"@fontsource/roboto": "~4.5",
"@fontsource/roboto-mono": "~4.5",
"@vscode/gulp-vinyl-zip": "~2.5",
"autoprefixer": "~9.7",
"browser-pack-flat": "~3.4",
"browserify": "~16.5",
"cssnano": "~4.1",
"eslint": "~6.8",
"eslint-config-standard": "~14.1",
"eslint-plugin-import": "~2.20",
"eslint-plugin-node": "~11.1",
"eslint-plugin-promise": "~4.2",
"eslint-plugin-standard": "~4.0",
"fancy-log": "~1.3",
"fs-extra": "~8.1",
"gulp": "~4.0",
"gulp-concat": "~2.6",
"gulp-connect": "~5.7",
"gulp-eslint": "~6.0",
"gulp-imagemin": "~6.2",
"gulp-postcss": "~8.0",
"gulp-stylelint": "~13.0",
"gulp-uglify": "~3.0",
"handlebars": "~4.7",
"highlight.js": "9.18.3",
"js-yaml": "~3.13",
"merge-stream": "~2.0",
"postcss-calc": "~7.0",
"postcss-custom-properties": "~9.1",
"postcss-import": "~12.0",
"postcss-url": "~8.0",
"prettier-eslint": "~9.0",
"require-directory": "~2.1",
"require-from-string": "~2.0",
"stylelint": "~13.3",
"stylelint-config-standard": "~20.0",
"vinyl-fs": "~3.0"
}
}
*,
*::before,
*::after {
box-sizing: inherit;
}
html {
box-sizing: border-box;
font-size: var(--body-font-size);
height: 100%;
scroll-behavior: smooth;
}
@media screen and (min-width: 1024px) {
html {
font-size: var(--body-font-size--desktop);
}
}
body {
background: var(--body-background);
color: var(--body-font-color);
font-family: var(--body-font-family);
line-height: var(--body-line-height);
margin: 0;
tab-size: 4;
word-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:active {
background-color: none;
}
code,
kbd,
pre {
font-family: var(--monospace-font-family);
}
b,
dt,
strong,
th {
font-weight: var(--body-font-weight-bold);
}
sub,
sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub {
bottom: -0.25em;
}
sup {
top: -0.5em;
}
em em { /* stylelint-disable-line */
font-style: normal;
}
strong strong { /* stylelint-disable-line */
font-weight: normal;
}
button {
cursor: pointer;
font-family: inherit;
font-size: 1em;
line-height: var(--body-line-height);
margin: 0;
}
button::-moz-focus-inner {
border: none;
padding: 0;
}
summary {
cursor: pointer;
-webkit-tap-highlight-color: transparent;
outline: none;
}
table {
border-collapse: collapse;
word-wrap: normal; /* table widths aren't computed as expected when word-wrap is enabled */
}
object[type="image/svg+xml"]:not([width]) {
width: fit-content;
}
::placeholder {
opacity: 0.5;
}
@media (pointer: fine) {
@supports (scrollbar-width: thin) {
html {
scrollbar-color: var(--scrollbar-thumb-color) var(--scrollbar-track-color);
}
body * {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb-color) transparent;
}
}
html::-webkit-scrollbar {
background-color: var(--scrollbar-track-color);
height: 12px;
width: 12px;
}
body ::-webkit-scrollbar {
height: 6px;
width: 6px;
}
::-webkit-scrollbar-thumb {
background-clip: padding-box;
background-color: var(--scrollbar-thumb-color);
border: 3px solid transparent;
border-radius: 12px;
}
body ::-webkit-scrollbar-thumb {
border-width: 1.75px;
border-radius: 6px;
}
::-webkit-scrollbar-thumb:hover {
background-color: var(--scrollbar_hover-thumb-color);
}
}
@media screen and (min-width: 1024px) {
.body {
display: flex;
}
}
.breadcrumbs {
display: none;
flex: 1 1;
padding: 0 0.5rem 0 0.75rem;
line-height: var(--nav-line-height);
}
@media screen and (min-width: 1024px) {
.breadcrumbs {
display: block;
}
}
a + .breadcrumbs {
padding-left: 0.05rem;
}
.breadcrumbs ul {
display: flex;
flex-wrap: wrap;
margin: 0;
padding: 0;
list-style: none;
}
.breadcrumbs li {
display: inline;
margin: 0;
}
.breadcrumbs li::after {
content: "/";
padding: 0 0.5rem;
}
.breadcrumbs li:last-of-type::after {
content: none;
}
.doc {
color: var(--doc-font-color);
font-size: var(--doc-font-size);
hyphens: auto;
line-height: var(--doc-line-height);
margin: var(--doc-margin);
max-width: var(--doc-max-width);
padding: 0 1rem 4rem;
}
@media screen and (min-width: 1024px) {
.doc {
flex: auto;
font-size: var(--doc-font-size--desktop);
margin: var(--doc-margin--desktop);
max-width: var(--doc-max-width--desktop);
min-width: 0;
}
}
.doc h1,
.doc h2,
.doc h3,
.doc h4,
.doc h5,
.doc h6 {
color: var(--heading-font-color);
font-weight: var(--heading-font-weight);
hyphens: none;
line-height: 1.3;
margin: 1rem 0 0;
}
.doc > h1.page:first-child {
font-size: calc(36 / var(--rem-base) * 1rem);
margin: 1.5rem 0;
}
@media screen and (min-width: 769px) {
.doc > h1.page:first-child {
margin-top: 2.5rem;
}
}
.doc > h1.page:first-child + aside.toc.embedded {
margin-top: -0.5rem;
}
.doc > h2#name + .sectionbody {
margin-top: 1rem;
}
#preamble + .sect1,
.doc .sect1 + .sect1 {
margin-top: 2rem;
}
.doc h1.sect0 {
background: var(--abstract-background);
font-size: 1.8em;
margin: 1.5rem -1rem 0;
padding: 0.5rem 1rem;
}
.doc h2:not(.discrete) {
border-bottom: 1px solid var(--section-divider-color);
margin-left: -1rem;
margin-right: -1rem;
padding: 0.4rem 1rem 0.1rem;
}
.doc h3:not(.discrete),
.doc h4:not(.discrete) {
font-weight: var(--alt-heading-font-weight);
}
.doc h1 .anchor,
.doc h2 .anchor,
.doc h3 .anchor,
.doc h4 .anchor,
.doc h5 .anchor,
.doc h6 .anchor {
position: absolute;
text-decoration: none;
width: 1.75ex;
margin-left: -1.5ex;
visibility: hidden;
font-size: 0.8em;
font-weight: normal;
padding-top: 0.05em;
}
.doc h1 .anchor::before,
.doc h2 .anchor::before,
.doc h3 .anchor::before,
.doc h4 .anchor::before,
.doc h5 .anchor::before,
.doc h6 .anchor::before {
content: "\00a7";
}
.doc h1:hover .anchor,
.doc h2:hover .anchor,
.doc h3:hover .anchor,
.doc h4:hover .anchor,
.doc h5:hover .anchor,
.doc h6:hover .anchor {
visibility: visible;
}
.doc p,
.doc dl {
margin: 0;
}
.doc a {
color: var(--link-font-color);
}
.doc a:hover {
color: var(--link_hover-font-color);
}
.doc a.bare {
hyphens: none;
}
.doc a.unresolved {
color: var(--link_unresolved-font-color);
}
.doc i.fa {
hyphens: none;
font-style: normal;
}
.doc p code,
.doc thead code,
.doc .colist > table code {
color: var(--code-font-color);
background: var(--code-background);
border-radius: 0.25em;
font-size: 0.95em;
padding: 0.125em 0.25em;
}
.doc code,
.doc pre {
hyphens: none;
}
.doc pre {
font-size: calc(16 / var(--rem-base) * 1rem);
line-height: 1.5;
margin: 0;
}
.doc blockquote {
margin: 0;
}
.doc .paragraph.lead > p {
font-size: calc(18 / var(--rem-base) * 1rem);
}
.doc .right {
float: right;
}
.doc .left {
float: left;
}
.doc .float-gap.right {
margin: 0 1rem 1rem 0;
}
.doc .float-gap.left {
margin: 0 0 1rem 1rem;
}
.doc .float-group::after {
content: "";
display: table;
clear: both;
}
.doc .text-left {
text-align: left;
}
.doc .text-center {
text-align: center;
}
.doc .text-right {
text-align: right;
}
.doc .text-justify {
text-align: justify;
}
.doc .stretch {
width: 100%;
}
.doc .big {
font-size: larger;
}
.doc .small {
font-size: smaller;
}
.doc .underline {
text-decoration: underline;
}
.doc .line-through {
text-decoration: line-through;
}
.doc .paragraph,
.doc .dlist,
.doc .hdlist,
.doc .olist,
.doc .ulist,
.doc .exampleblock,
.doc .imageblock,
.doc .listingblock,
.doc .literalblock,
.doc .tabs,
.doc .sidebarblock,
.doc .verseblock,
.doc .videoblock,
.doc .quoteblock,
.doc .partintro,
.doc details,
.doc hr {
margin: 1rem 0 0;
}
.doc > table.tableblock,
.doc > table.tableblock + *,
.doc .tablecontainer,
.doc .tablecontainer + *,
.doc :not(.tablecontainer) > table.tableblock,
.doc :not(.tablecontainer) > table.tableblock + * {
margin-top: 1.5rem;
}
.doc table.tableblock {
font-size: calc(15 / var(--rem-base) * 1rem);
}
.doc p.tableblock + p.tableblock {
margin-top: 0.5rem;
}
.doc table.tableblock pre {
font-size: inherit;
}
.doc td.tableblock > .content {
word-wrap: anywhere; /* aka overflow-wrap; used when hyphens are disabled or aren't sufficient */
}
.doc td.tableblock > .content > :first-child {
margin-top: 0;
}
.doc table.tableblock th,
.doc table.tableblock td {
padding: 0.5rem;
}
.doc table.tableblock,
.doc table.tableblock > * > tr > * {
border: 0 solid var(--table-border-color);
}
.doc table.grid-all > * > tr > * {
border-width: 1px;
}
.doc table.grid-cols > * > tr > * {
border-width: 0 1px;
}
.doc table.grid-rows > * > tr > * {
border-width: 1px 0;
}
.doc table.grid-all > thead th,
.doc table.grid-rows > thead th {
border-bottom-width: 2.5px;
}
.doc table.frame-all {
border-width: 1px;
}
.doc table.frame-ends {
border-width: 1px 0;
}
.doc table.frame-sides {
border-width: 0 1px;
}
.doc table.frame-none > colgroup + * > :first-child > *,
.doc table.frame-sides > colgroup + * > :first-child > * {
border-top-width: 0;
}
/* NOTE let the grid win in case of frame-none */
.doc table.frame-sides > :last-child > :last-child > * {
border-bottom-width: 0;
}
.doc table.frame-none > * > tr > :first-child,
.doc table.frame-ends > * > tr > :first-child {
border-left-width: 0;
}
.doc table.frame-none > * > tr > :last-child,
.doc table.frame-ends > * > tr > :last-child {
border-right-width: 0;
}
.doc table.stripes-all > tbody > tr,
.doc table.stripes-odd > tbody > tr:nth-of-type(odd),
.doc table.stripes-even > tbody > tr:nth-of-type(even),
.doc table.stripes-hover > tbody > tr:hover {
background: var(--table-stripe-background);
}
.doc table.tableblock > tfoot {
background: var(--table-footer-background);
}
.doc .halign-left {
text-align: left;
}
.doc .halign-right {
text-align: right;
}
.doc .halign-center {
text-align: center;
}
.doc .valign-top {
vertical-align: top;
}
.doc .valign-bottom {
vertical-align: bottom;
}
.doc .valign-middle {
vertical-align: middle;
}
.doc .admonitionblock {
margin: 1.4rem 0 0;
}
.doc .admonitionblock p,
.doc .admonitionblock td.content {
font-size: calc(16 / var(--rem-base) * 1rem);
}
.doc .admonitionblock td.content > :not(.title):first-child,
.doc .admonitionblock td.content > .title + * {
margin-top: 0;
}
.doc .admonitionblock td.content pre {
font-size: calc(15 / var(--rem-base) * 1rem);
}
.doc .admonitionblock > table {
table-layout: fixed;
position: relative;
width: 100%;
}
.doc .admonitionblock td.content {
padding: 1rem 1rem 0.75rem;
background: var(--admonition-background);
width: 100%;
word-wrap: anywhere;
}
.doc .admonitionblock td.icon {
font-size: calc(15 / var(--rem-base) * 1rem);
left: 0;
line-height: 1;
padding: 0;
position: absolute;
top: 0;
transform: translate(-0.5rem, -50%);
}
.doc .admonitionblock td.icon i {
align-items: center;
border-radius: 0.45rem;
display: inline-flex;
filter: initial;
height: 1.25rem;
padding: 0 0.5rem;
vertical-align: initial;
width: fit-content;
}
.doc .admonitionblock td.icon i::after {
content: attr(title);
font-weight: var(--admonition-label-font-weight);
font-style: normal;
text-transform: uppercase;
}
.doc .admonitionblock td.icon i.icon-caution {
background-color: var(--caution-color);
color: var(--caution-on-color);
}
.doc .admonitionblock td.icon i.icon-important {
background-color: var(--important-color);
color: var(--important-on-color);
}
.doc .admonitionblock td.icon i.icon-note {
background-color: var(--note-color);
color: var(--note-on-color);
}
.doc .admonitionblock td.icon i.icon-tip {
background-color: var(--tip-color);
color: var(--tip-on-color);
}
.doc .admonitionblock td.icon i.icon-warning {
background-color: var(--warning-color);
color: var(--warning-on-color);
}
.doc .imageblock,
.doc .videoblock {
display: flex;
flex-direction: column;
align-items: center;
}
.doc .imageblock .content {
align-self: stretch;
text-align: center;
}
.doc .imageblock.text-left,
.doc .videoblock.text-left {
align-items: flex-start;
}
.doc .imageblock.text-left .content {
text-align: left;
}
.doc .imageblock.text-right,
.doc .videoblock.text-right {
align-items: flex-end;
}
.doc .imageblock.text-right .content {
text-align: right;
}
.doc .imageblock img,
.doc .imageblock object,
.doc .imageblock svg,
.doc .image > img,
.doc .image > object,
.doc .image > svg {
display: inline-block;
height: auto;
max-width: 100%;
vertical-align: middle;
}
.doc .image:not(.left):not(.right) > img {
margin-top: -0.2em;
}
.doc .videoblock iframe,
.doc .videoblock video {
max-width: 100%;
vertical-align: middle;
}
#preamble .abstract blockquote {
background: var(--abstract-background);
border-left: 5px solid var(--abstract-border-color);
color: var(--abstract-font-color);
font-size: calc(16 / var(--rem-base) * 1rem);
padding: 0.75em 1em;
}
.doc .quoteblock,
.doc .verseblock {
background: var(--quote-background);
border-left: 5px solid var(--quote-border-color);
color: var(--quote-font-color);
}
.doc .quoteblock {
padding: 0.25rem 2rem 1.25rem;
}
.doc .quoteblock .attribution {
color: var(--quote-attribution-font-color);
font-size: calc(15 / var(--rem-base) * 1rem);
margin-top: 0.75rem;
}
.doc .quoteblock blockquote {
margin-top: 1rem;
}
.doc .quoteblock .paragraph {
font-style: italic;
}
.doc .quoteblock cite {
padding-left: 1em;
}
.doc .verseblock {
font-size: 1.15em;
padding: 1rem 2rem;
}
.doc .verseblock pre {
font-family: inherit;
font-size: inherit;
}
.doc ol,
.doc ul {
margin: 0;
padding: 0 0 0 2rem;
}
.doc ul.checklist,
.doc ul.none,
.doc ol.none,
.doc ul.no-bullet,
.doc ol.unnumbered,
.doc ul.unstyled,
.doc ol.unstyled {
list-style-type: none;
}
.doc ul.no-bullet,
.doc ol.unnumbered {
padding-left: 1.25rem;
}
.doc ul.unstyled,
.doc ol.unstyled {
padding-left: 0;
}
.doc ul.circle {
list-style-type: circle;
}
.doc ul.disc {
list-style-type: disc;
}
.doc ul.square {
list-style-type: square;
}
.doc ul.circle ul:not([class]),
.doc ul.disc ul:not([class]),
.doc ul.square ul:not([class]) {
list-style: inherit;
}
.doc ol.arabic {
list-style-type: decimal;
}
.doc ol.decimal {
list-style-type: decimal-leading-zero;
}
.doc ol.loweralpha {
list-style-type: lower-alpha;
}
.doc ol.upperalpha {
list-style-type: upper-alpha;
}
.doc ol.lowerroman {
list-style-type: lower-roman;
}
.doc ol.upperroman {
list-style-type: upper-roman;
}
.doc ol.lowergreek {
list-style-type: lower-greek;
}
.doc ul.checklist {
padding-left: 1.75rem;
}
.doc ul.checklist p > i.fa-check-square-o:first-child,
.doc ul.checklist p > i.fa-square-o:first-child {
display: inline-flex;
justify-content: center;
width: 1.25rem;
margin-left: -1.25rem;
}
.doc ul.checklist i.fa-check-square-o::before {
content: "\2713";
}
.doc ul.checklist i.fa-square-o::before {
content: "\274f";
}
.doc .dlist .dlist,
.doc .dlist .olist,
.doc .dlist .ulist,
.doc .olist .dlist,
.doc .olist .olist,
.doc .olist .ulist,
.doc .ulist .dlist,
.doc .ulist .olist,
.doc .ulist .ulist {
margin-top: 0.5rem;
}
.doc .olist li + li,
.doc .ulist li + li {
margin-top: 0.5rem;
}
.doc .ulist .listingblock,
.doc .olist .listingblock,
.doc .admonitionblock .listingblock {
padding: 0;
}
.doc .admonitionblock .title,
.doc .exampleblock .title,
.doc .imageblock .title,
.doc .literalblock .title,
.doc .listingblock .title,
.doc .openblock .title,
.doc .videoblock .title,
.doc table.tableblock caption {
color: var(--caption-font-color);
font-size: calc(16 / var(--rem-base) * 1rem);
font-style: var(--caption-font-style);
font-weight: var(--caption-font-weight);
hyphens: none;
letter-spacing: 0.01em;
padding-bottom: 0.075rem;
}
.doc table.tableblock caption {
text-align: left;
}
.doc .olist .title,
.doc .ulist .title {
font-style: var(--caption-font-style);
font-weight: var(--caption-font-weight);
margin-bottom: 0.25rem;
}
.doc .imageblock .title,
.doc .videoblock .title {
margin-top: 0.5rem;
padding-bottom: 0;
}
.doc details {
margin-left: 1rem;
}
.doc details > summary {
display: block;
position: relative;
line-height: var(--doc-line-height);
margin-bottom: 0.5rem;
}
.doc details > summary::-webkit-details-marker {
display: none;
}
.doc details > summary::before {
content: "";
border: solid transparent;
border-left-color: currentColor;
border-width: 0.3em 0 0.3em 0.5em;
position: absolute;
top: calc((var(--doc-line-height) * 0.5 - 0.3) * 1em);
left: -1rem;
transform: translateX(15%);
}
.doc details[open] > summary::before {
border-color: currentColor transparent transparent;
border-width: 0.5rem 0.3rem 0;
transform: translateY(15%);
}
.doc details > summary::after {
content: "";
width: 1rem;
height: 1em;
position: absolute;
top: calc((var(--doc-line-height) * 0.5 - 0.5) * 1em);
left: -1rem;
}
.doc details.result {
margin-top: 0.25rem;
}
.doc details.result > summary {
color: var(--caption-font-color);
font-style: italic;
margin-bottom: 0;
}
.doc details.result > .content {
margin-left: -1rem;
}
.doc .exampleblock > .content,
.doc details.result > .content {
background: var(--example-background);
border: 0.25rem solid var(--example-border-color);
border-radius: 0.5rem;
padding: 0.75rem;
}
.doc .exampleblock > .content::after,
.doc details.result > .content::after {
content: "";
display: table;
clear: both;
}
.doc .exampleblock > .content > :first-child,
.doc details > .content > :first-child {
margin-top: 0;
}
.doc .sidebarblock {
background: var(--sidebar-background);
border-radius: 0.75rem;
padding: 0.75rem 1.5rem;
}
.doc .sidebarblock > .content > .title {
font-size: calc(22.5 / var(--rem-base) * 1rem);
font-weight: var(--alt-heading-font-weight);
line-height: 1.3;
margin-bottom: 0.5rem;
text-align: center;
}
.doc .sidebarblock > .content > .title + *,
.doc .sidebarblock > .content > :not(.title):first-child {
margin-top: 0;
}
/* NEEDS REVIEW prevent pre in table from causing article to exceed bounds */
.doc table.tableblock pre,
.doc .listingblock.wrap pre {
white-space: pre-wrap;
}
.doc pre.highlight > code,
.doc .listingblock pre:not(.highlight),
.doc .literalblock pre {
background: var(--pre-background);
box-shadow: inset 0 0 1.75px var(--pre-border-color);
display: block;
overflow-x: auto;
padding: 0.875em;
}
.doc .listingblock > .content {
position: relative;
}
.doc .source-toolbox {
display: flex;
visibility: hidden;
position: absolute;
top: 0.25rem;
right: 0.5rem;
color: var(--pre-annotation-font-color);
font-family: var(--body-font-family);
font-size: calc(13 / var(--rem-base) * 1rem);
line-height: 1;
user-select: none;
white-space: nowrap;
z-index: 1;
}
.doc .listingblock:hover .source-toolbox {
visibility: visible;
}
.doc .source-toolbox .source-lang {
text-transform: uppercase;
letter-spacing: 0.075em;
}
.doc .source-toolbox > :not(:last-child)::after {
content: "|";
letter-spacing: 0;
padding: 0 1ch;
}
.doc .source-toolbox .copy-button {
display: flex;
flex-direction: column;
align-items: center;
background: none;
border: none;
color: inherit;
outline: none;
padding: 0;
font-size: inherit;
line-height: inherit;
width: 1em;
height: 1em;
}
.doc .source-toolbox .copy-icon {
flex: none;
width: inherit;
height: inherit;
}
.doc .source-toolbox img.copy-icon {
filter: invert(50.2%);
}
.doc .source-toolbox svg.copy-icon {
fill: currentColor;
}
.doc .source-toolbox .copy-toast {
flex: none;
position: relative;
display: inline-flex;
justify-content: center;
margin-top: 1em;
background-color: var(--doc-font-color);
border-radius: 0.25em;
padding: 0.5em;
color: var(--color-white);
cursor: auto;
opacity: 0;
transition: opacity 0.5s ease 0.5s;
}
.doc .source-toolbox .copy-toast::after {
content: "";
position: absolute;
top: 0;
width: 1em;
height: 1em;
border: 0.55em solid transparent;
border-left-color: var(--doc-font-color);
transform: rotate(-90deg) translateX(50%) translateY(50%);
transform-origin: left;
}
.doc .source-toolbox .copy-button.clicked .copy-toast {
opacity: 1;
transition: none;
}
.doc .language-console .hljs-meta {
user-select: none;
}
.doc .dlist dt {
font-style: italic;
}
.doc .dlist dd {
margin: 0 0 0 1.5rem;
}
.doc .dlist dd + dt,
.doc .dlist dd > p:first-child {
margin-top: 0.5rem;
}
.doc td.hdlist1,
.doc td.hdlist2 {
padding: 0.5rem 0 0;
vertical-align: top;
}
.doc tr:first-child > .hdlist1,
.doc tr:first-child > .hdlist2 {
padding-top: 0;
}
.doc td.hdlist1 {
font-weight: var(--body-font-weight-bold);
padding-right: 0.25rem;
}
.doc td.hdlist2 {
padding-left: 0.25rem;
}
.doc .colist {
font-size: calc(16 / var(--rem-base) * 1rem);
margin: 0.25rem 0 -0.25rem;
}
.doc .colist > table > tr > :first-child,
.doc .colist > table > tbody > tr > :first-child {
padding: 0.25em 0.5rem 0;
vertical-align: top;
}
.doc .colist > table > tr > :last-child,
.doc .colist > table > tbody > tr > :last-child {
padding: 0.25rem 0;
}
.doc .conum[data-value] {
border: 1px solid currentColor;
border-radius: 100%;
display: inline-block;
font-family: var(--body-font-family);
font-size: calc(13.5 / var(--rem-base) * 1rem);
font-style: normal;
line-height: 1.2;
text-align: center;
width: 1.25em;
height: 1.25em;
letter-spacing: -0.25ex;
text-indent: -0.25ex;
}
.doc .conum[data-value]::after {
content: attr(data-value);
}
.doc .conum[data-value] + b {
display: none;
}
.doc hr {
border: solid var(--section-divider-color);
border-width: 2px 0 0;
height: 0;
}
.doc b.button {
white-space: nowrap; /* effectively ignores hyphens setting */
}
.doc b.button::before {
content: "[";
padding-right: 0.25em;
}
.doc b.button::after {
content: "]";
padding-left: 0.25em;
}
.doc kbd {
display: inline-block;
font-size: calc(12 / var(--rem-base) * 1rem);
background: var(--kbd-background);
border: 1px solid var(--kbd-border-color);
border-radius: 0.25em;
box-shadow: 0 1px 0 var(--kbd-border-color), 0 0 0 0.1em var(--body-background) inset;
padding: 0.25em 0.5em;
vertical-align: text-bottom;
white-space: nowrap; /* effectively ignores hyphens setting */
}
.doc kbd,
.doc .keyseq {
line-height: 1;
}
.doc .keyseq {
font-size: calc(16 / var(--rem-base) * 1rem);
}
.doc .keyseq kbd {
margin: 0 0.125em;
}
.doc .keyseq kbd:first-child {
margin-left: 0;
}
.doc .keyseq kbd:last-child {
margin-right: 0;
}
.doc .menuseq,
.doc .path {
hyphens: none;
}
.doc .menuseq i.caret::before {
content: "\203a";
font-size: 1.1em;
font-weight: var(--body-font-weight-bold);
line-height: calc(1 / 1.1);
}
.doc :not(pre).nowrap {
white-space: nowrap;
}
.doc .nobreak {
hyphens: none;
word-wrap: normal;
}
.doc :not(pre).pre-wrap {
white-space: pre-wrap;
}
#footnotes {
font-size: 0.85em;
line-height: 1.5;
margin: 2rem -0.5rem 0;
}
.doc td.tableblock > .content #footnotes {
margin: 2rem 0 0;
}
#footnotes hr {
border-top-width: 1px;
margin-top: 0;
width: 20%;
}
#footnotes .footnote {
margin: 0.5em 0 0 1em;
}
#footnotes .footnote + .footnote {
margin-top: 0.25em;
}
#footnotes .footnote > a:first-of-type {
display: inline-block;
margin-left: -2em;
text-align: right;
width: 1.5em;
}
.doc .userinput {
color: red;
}
footer.footer {
background-color: var(--footer-background);
color: var(--footer-font-color);
font-size: calc(15 / var(--rem-base) * 1rem);
line-height: var(--footer-line-height);
padding: 1.5rem;
}
.footer p {
margin: 0.5rem 0;
}
.footer a {
color: var(--footer-link-font-color);
}
@media screen and (max-width: 1023.5px) {
html.is-clipped--navbar {
overflow-y: hidden;
}
}
body {
padding-top: var(--navbar-height);
}
.navbar {
background: var(--navbar-background);
color: var(--navbar-font-color);
font-size: calc(16 / var(--rem-base) * 1rem);
height: var(--navbar-height);
position: fixed;
top: 0;
width: 100%;
z-index: var(--z-index-navbar);
}
.navbar a {
text-decoration: none;
}
.navbar-brand {
display: flex;
flex: auto;
padding-left: 1rem;
}
.navbar-brand .navbar-item {
color: var(--navbar-font-color);
}
.navbar-brand .navbar-item:first-child {
align-self: center;
padding: 0;
font-size: calc(22 / var(--rem-base) * 1rem);
flex-wrap: wrap;
line-height: 1;
}
.navbar-brand .navbar-item:first-child a {
color: inherit;
word-wrap: normal;
}
.navbar-brand .navbar-item:first-child :not(:last-child) {
padding-right: 0.375rem;
}
.navbar-brand .navbar-item.search {
flex: auto;
justify-content: flex-end;
}
#search-input {
color: #333;
font-family: inherit;
font-size: 0.95rem;
width: 150px;
border: 1px solid #dbdbdb;
border-radius: 0.1em;
line-height: 1.5;
padding: 0 0.25em;
}
#search-input:disabled {
background-color: #dbdbdb;
/* disable cursor */
cursor: not-allowed;
pointer-events: all !important;
}
#search-input:disabled::placeholder {
color: #4c4c4c;
}
#search-input:focus {
outline: none;
}
.navbar-burger {
background: none;
border: none;
outline: none;
line-height: 1;
position: relative;
width: 3rem;
padding: 0;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
margin-left: auto;
min-width: 0;
}
.navbar-burger span {
background-color: var(--navbar-font-color);
height: 1.5px;
width: 1rem;
}
.navbar-burger:not(.is-active) span {
transition: transform ease-out 0.25s, opacity 0s 0.25s, margin-top ease-out 0.25s 0.25s;
}
.navbar-burger span + span {
margin-top: 0.25rem;
}
.navbar-burger.is-active span + span {
margin-top: -1.5px;
}
.navbar-burger.is-active span:nth-child(1) {
transform: rotate(45deg);
}
.navbar-burger.is-active span:nth-child(2) {
opacity: 0;
}
.navbar-burger.is-active span:nth-child(3) {
transform: rotate(-45deg);
}
.navbar-item,
.navbar-link {
color: var(--navbar-menu-font-color);
display: block;
line-height: var(--doc-line-height);
padding: 0.5rem 1rem;
}
.navbar-item.has-dropdown {
padding: 0;
}
.navbar-item .icon {
width: 1.25rem;
height: 1.25rem;
display: block;
}
.navbar-item .icon img,
.navbar-item .icon svg {
fill: currentColor;
width: inherit;
height: inherit;
}
.navbar-link {
padding-right: 2.5em;
}
.navbar-dropdown .navbar-item {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.navbar-dropdown .navbar-item.has-label {
display: flex;
justify-content: space-between;
}
.navbar-dropdown .navbar-item small {
color: var(--toolbar-muted-color);
font-size: calc(12 / var(--rem-base) * 1rem);
}
.navbar-divider {
background-color: var(--navbar-menu-border-color);
border: none;
height: 1px;
margin: 0.25rem 0;
}
.navbar .button {
display: inline-flex;
align-items: center;
background: var(--navbar-button-background);
border: 1px solid var(--navbar-button-border-color);
border-radius: 0.15rem;
height: 1.75rem;
color: var(--navbar-button-font-color);
padding: 0 0.75em;
white-space: nowrap;
}
@media screen and (max-width: 768.5px) {
.navbar-brand .navbar-item.search {
padding-left: 0;
padding-right: 0;
}
}
@media screen and (min-width: 769px) {
#search-input {
width: 200px;
}
}
@media screen and (max-width: 1023.5px) {
.navbar-brand {
height: inherit;
}
.navbar-brand .navbar-item {
align-items: center;
display: flex;
}
.navbar-menu {
background: var(--navbar-menu-background);
box-shadow: 0 8px 16px rgba(10, 10, 10, 0.1);
max-height: var(--body-min-height);
overflow-y: auto;
overscroll-behavior: none;
padding: 0.5rem 0;
}
.navbar-menu:not(.is-active) {
display: none;
}
.navbar-menu a.navbar-item:hover,
.navbar-menu .navbar-link:hover {
background: var(--navbar-menu_hover-background);
}
}
@media screen and (min-width: 1024px) {
.navbar-burger {
display: none;
}
.navbar,
.navbar-menu,
.navbar-end {
display: flex;
}
.navbar-item,
.navbar-link {
display: flex;
position: relative;
flex: none;
}
.navbar-item:not(.has-dropdown),
.navbar-link {
align-items: center;
}
.navbar-item.is-hoverable:hover .navbar-dropdown {
display: block;
}
.navbar-link::after {
border-width: 0 0 1px 1px;
border-style: solid;
content: "";
display: block;
height: 0.5em;
pointer-events: none;
position: absolute;
transform: rotate(-45deg);
width: 0.5em;
margin-top: -0.375em;
right: 1.125em;
top: 50%;
}
.navbar-end > .navbar-item,
.navbar-end .navbar-link {
color: var(--navbar-font-color);
}
.navbar-end > a.navbar-item:hover,
.navbar-end .navbar-link:hover,
.navbar-end .navbar-item.has-dropdown:hover .navbar-link {
background: var(--navbar_hover-background);
color: var(--navbar-font-color);
}
.navbar-end .navbar-link::after {
border-color: currentColor;
}
.navbar-dropdown {
background: var(--navbar-menu-background);
border: 1px solid var(--navbar-menu-border-color);
border-top: none;
border-radius: 0 0 0.25rem 0.25rem;
display: none;
top: 100%;
left: 0;
min-width: 100%;
position: absolute;
}
.navbar-dropdown .navbar-item {
padding: 0.5rem 3rem 0.5rem 1rem;
white-space: nowrap;
}
.navbar-dropdown .navbar-item small {
position: relative;
right: -2rem;
}
.navbar-dropdown .navbar-item:last-child {
border-radius: inherit;
}
.navbar-dropdown.is-right {
left: auto;
right: 0;
}
.navbar-dropdown a.navbar-item:hover {
background: var(--navbar-menu_hover-background);
}
}
/*! Adapted from the GitHub style by Vasily Polovnyov <vast@whiteants.net> */
.hljs-comment,
.hljs-quote {
color: #998;
font-style: italic;
}
.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
color: #333;
font-weight: var(--monospace-font-weight-bold);
}
.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
color: #008080;
}
.hljs-string,
.hljs-doctag {
color: #d14;
}
.hljs-title,
.hljs-section,
.hljs-selector-id {
color: #900;
font-weight: var(--monospace-font-weight-bold);
}
.hljs-subst {
font-weight: normal;
}
.hljs-type,
.hljs-class .hljs-title {
color: #458;
font-weight: var(--monospace-font-weight-bold);
}
.hljs-tag,
.hljs-name,
.hljs-attribute {
color: #000080;
font-weight: normal;
}
.hljs-regexp,
.hljs-link {
color: #009926;
}
.hljs-symbol,
.hljs-bullet {
color: #990073;
}
.hljs-built_in,
.hljs-builtin-name {
color: #0086b3;
}
.hljs-meta {
color: #999;
font-weight: var(--monospace-font-weight-bold);
}
.hljs-deletion {
background: #fdd;
}
.hljs-addition {
background: #dfd;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: var(--monospace-font-weight-bold);
}
body.-toc aside.toc.sidebar {
display: none;
}
@media screen and (max-width: 1023.5px) {
aside.toc.sidebar {
display: none;
}
main > .content {
overflow-x: auto;
}
}
@media screen and (min-width: 1024px) {
main {
flex: auto;
min-width: 0; /* min-width: 0 required for flexbox to constrain overflowing elements */
}
main > .content {
display: flex;
}
aside.toc.embedded {
display: none;
}
aside.toc.sidebar {
flex: 0 0 var(--toc-width);
order: 1;
}
}
@media screen and (min-width: 1216px) {
aside.toc.sidebar {
flex-basis: var(--toc-width--widescreen);
}
}
@media screen and (max-width: 1023.5px) {
html.is-clipped--nav {
overflow-y: hidden;
}
}
.nav-container {
position: fixed;
top: var(--navbar-height);
left: 0;
width: 100%;
font-size: calc(17 / var(--rem-base) * 1rem);
z-index: var(--z-index-nav);
visibility: hidden;
}
@media screen and (min-width: 769px) {
.nav-container {
width: var(--nav-width);
}
}
@media screen and (min-width: 1024px) {
.nav-container {
font-size: calc(15.5 / var(--rem-base) * 1rem);
flex: none;
position: static;
top: 0;
visibility: visible;
}
}
.nav-container.is-active {
visibility: visible;
}
.nav {
background: var(--nav-background);
position: relative;
top: var(--toolbar-height);
height: var(--nav-height);
}
@media screen and (min-width: 769px) {
.nav {
box-shadow: 0.5px 0 3px var(--nav-border-color);
}
}
@media screen and (min-width: 1024px) {
.nav {
top: var(--navbar-height);
box-shadow: none;
position: sticky;
height: var(--nav-height--desktop);
}
}
.nav a {
color: inherit;
}
.nav .panels {
display: flex;
flex-direction: column;
height: inherit;
}
.nav-panel-menu {
overflow-y: scroll;
overscroll-behavior: none;
height: var(--nav-panel-menu-height);
}
.nav-panel-menu:not(.is-active) .nav-menu {
opacity: 0.75;
}
.nav-panel-menu:not(.is-active)::after {
content: "";
background: rgba(0, 0, 0, 0.5);
display: block;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.nav-menu {
min-height: 100%;
padding: 0.5rem 0.75rem;
line-height: var(--nav-line-height);
position: relative;
}
.nav-menu-toggle {
background: transparent url(../img/octicons-16.svg#view-unfold) no-repeat center / 100% 100%;
border: none;
float: right;
height: 1em;
margin-right: -0.5rem;
opacity: 0.75;
outline: none;
padding: 0;
position: sticky;
top: calc((var(--nav-line-height) - 1 + 0.5) * 1rem);
visibility: hidden;
width: 1em;
}
.nav-menu-toggle.is-active {
background-image: url(../img/octicons-16.svg#view-fold);
}
.nav-panel-menu.is-active:hover .nav-menu-toggle {
visibility: visible;
}
.nav-menu h3.title {
color: var(--nav-heading-font-color);
font-size: inherit;
font-weight: var(--body-font-weight-bold);
margin: 0;
padding: 0.25em 0 0.125em;
}
.nav-list {
list-style: none;
margin: 0 0 0 0.75rem;
padding: 0;
}
.nav-menu > .nav-list + .nav-list {
margin-top: 0.5rem;
}
.nav-item {
margin-top: 0.5em;
}
/* adds some breathing room below a nested list */
.nav-item-toggle ~ .nav-list {
padding-bottom: 0.125rem;
}
/* matches list without a title */
.nav-item[data-depth="0"] > .nav-list:first-child {
display: block;
margin: 0;
}
.nav-item:not(.is-active) > .nav-list {
display: none;
}
.nav-item-toggle {
background: transparent url(../img/caret.svg) no-repeat center / 50%;
border: none;
outline: none;
line-height: inherit;
padding: 0;
position: absolute;
height: calc(var(--nav-line-height) * 1em);
width: calc(var(--nav-line-height) * 1em);
margin-top: -0.05em;
margin-left: calc(var(--nav-line-height) * -1em);
}
.nav-item.is-active > .nav-item-toggle {
transform: rotate(90deg);
}
.is-current-page > .nav-link,
.is-current-page > .nav-text {
font-weight: var(--body-font-weight-bold);
}
.nav-panel-explore {
background: var(--nav-background);
display: flex;
flex-direction: column;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.nav-panel-explore:not(:first-child) {
top: auto;
max-height: var(--nav-panel-explore-height);
}
.nav-panel-explore .context {
font-size: calc(15 / var(--rem-base) * 1rem);
flex-shrink: 0;
color: var(--nav-muted-color);
box-shadow: 0 -1px 0 var(--nav-panel-divider-color);
padding: 0 0.5rem;
display: flex;
align-items: center;
justify-content: space-between;
line-height: 1;
height: var(--drawer-height);
}
.nav-panel-explore:not(:first-child) .context {
cursor: pointer;
}
.nav-panel-explore .context .version {
display: flex;
align-items: inherit;
}
.nav-panel-explore .context .version::after {
content: "";
background: url(../img/chevron.svg) no-repeat center right / auto 100%;
width: 1.25em;
height: 0.75em;
}
.nav-panel-explore .components {
line-height: var(--nav-line-height);
flex-grow: 1;
box-shadow: inset 0 1px 5px var(--nav-panel-divider-color);
background: var(--nav-secondary-background);
padding: 0.75rem 0.75rem 0 0.75rem;
margin: 0;
overflow-y: scroll;
overscroll-behavior: none;
max-height: 100%;
display: block;
}
.nav-panel-explore:not(.is-active) .components {
display: none;
}
.nav-panel-explore .component {
display: block;
}
.nav-panel-explore .component + .component {
margin-top: 0.75rem;
}
.nav-panel-explore .component:last-child {
margin-bottom: 0.75rem;
}
.nav-panel-explore .component .title {
font-weight: var(--body-font-weight-bold);
text-indent: 0.375rem hanging;
}
.nav-panel-explore .versions {
display: flex;
flex-wrap: wrap;
padding-left: 0;
margin: -0.125rem -0.375rem 0 0.375rem;
line-height: 1;
list-style: none;
}
.nav-panel-explore .component .version {
margin: 0.375rem 0.375rem 0 0;
}
.nav-panel-explore .component .version a {
background: var(--nav-border-color);
border-radius: 0.25rem;
white-space: nowrap;
padding: 0.25em 0.5em;
display: inherit;
opacity: 0.75;
}
.nav-panel-explore .component .is-current a {
background: var(--nav-heading-font-color);
color: var(--nav-secondary-background);
font-weight: var(--body-font-weight-bold);
opacity: 1;
}
.page-versions {
margin: 0 0.2rem 0 auto;
position: relative;
line-height: 1;
}
@media screen and (min-width: 1024px) {
.page-versions {
margin-right: 0.7rem;
}
}
.page-versions .version-menu-toggle {
color: inherit;
background: url(../img/chevron.svg) no-repeat;
background-position: right 0.5rem top 50%;
background-size: auto 0.75em;
border: none;
outline: none;
line-height: inherit;
padding: 0.5rem 1.5rem 0.5rem 0.5rem;
position: relative;
z-index: var(--z-index-page-version-menu);
}
.page-versions .version-menu {
display: flex;
min-width: 100%;
flex-direction: column;
align-items: flex-end;
background: linear-gradient(to bottom, var(--page-version-menu-background) 0%, var(--page-version-menu-background) 100%) no-repeat;
padding: 1.375rem 1.5rem 0.5rem 0.5rem;
position: absolute;
top: 0;
right: 0;
white-space: nowrap;
}
.page-versions:not(.is-active) .version-menu {
display: none;
}
.page-versions .version {
display: block;
padding-top: 0.5rem;
}
.page-versions .version.is-current {
display: none;
}
.page-versions .version.is-missing {
color: var(--page-version-missing-font-color);
font-style: italic;
text-decoration: none;
}
nav.pagination {
display: flex;
border-top: 1px solid var(--toolbar-border-color);
line-height: 1;
margin: 2rem -1rem -1rem;
padding: 0.75rem 1rem 0;
}
nav.pagination span {
display: flex;
flex: 50%;
flex-direction: column;
}
nav.pagination .prev {
padding-right: 0.5rem;
}
nav.pagination .next {
margin-left: auto;
padding-left: 0.5rem;
text-align: right;
}
nav.pagination span::before {
color: var(--toolbar-muted-color);
font-size: 0.75em;
padding-bottom: 0.1em;
}
nav.pagination .prev::before {
content: "Prev";
}
nav.pagination .next::before {
content: "Next";
}
nav.pagination a {
font-weight: var(--body-font-weight-bold);
line-height: 1.3;
position: relative;
}
nav.pagination a::before,
nav.pagination a::after {
color: var(--toolbar-muted-color);
font-weight: normal;
font-size: 1.5em;
line-height: 0.75;
position: absolute;
top: 0;
width: 1rem;
}
nav.pagination .prev a::before {
content: "\2039";
transform: translateX(-100%);
}
nav.pagination .next a::after {
content: "\203a";
}
@page {
margin: 0.5in;
}
@media print {
.hide-for-print {
display: none !important;
}
html {
font-size: var(--body-font-size--print);
}
a {
color: inherit !important;
text-decoration: underline;
}
a.bare,
a[href^="#"],
a[href^="mailto:"] {
text-decoration: none;
}
tr,
img,
object,
svg {
page-break-inside: avoid;
}
thead {
display: table-header-group;
}
pre {
hyphens: none;
white-space: pre-wrap;
}
body {
padding-top: 2rem;
}
.navbar {
background: none;
color: inherit;
position: absolute;
}
.navbar * {
color: inherit !important;
}
.navbar > :not(.navbar-brand),
.nav-container,
.toolbar,
aside.toc,
nav.pagination {
display: none;
}
.doc {
color: inherit;
margin: auto;
max-width: none;
padding-bottom: 2rem;
}
.doc .admonitionblock td.icon {
color-adjust: exact;
}
.doc .listingblock code[data-lang]::before {
display: block;
}
footer.footer {
background: none;
border-top: 1px solid var(--panel-border-color);
color: var(--quote-attribution-font-color);
padding: 0.25rem 0.5rem 0;
}
.footer * {
color: inherit;
}
}
@import "typeface-roboto.css";
@import "typeface-roboto-mono.css";
@import "vars.css";
@import "base.css";
@import "body.css";
@import "nav.css";
@import "main.css";
@import "toolbar.css";
@import "breadcrumbs.css";
@import "page-versions.css";
@import "toc.css";
@import "doc.css";
@import "pagination.css";
@import "header.css";
@import "footer.css";
@import "highlight.css";
@import "print.css";
.toc-menu {
color: var(--toc-font-color);
}
.toc.sidebar .toc-menu {
margin-right: 0.75rem;
position: sticky;
top: var(--toc-top);
}
.toc .toc-menu h3 {
color: var(--toc-heading-font-color);
font-size: calc(16 / var(--rem-base) * 1rem);
font-weight: var(--body-font-weight-bold);
line-height: 1.3;
margin: 0 -0.5px;
padding-bottom: 0.25rem;
}
.toc.sidebar .toc-menu h3 {
display: flex;
flex-direction: column;
height: 2.5rem;
justify-content: flex-end;
}
.toc .toc-menu ul {
font-size: calc(15 / var(--rem-base) * 1rem);
line-height: var(--toc-line-height);
list-style: none;
margin: 0;
padding: 0;
}
.toc.sidebar .toc-menu ul {
max-height: var(--toc-height);
overflow-y: auto;
overscroll-behavior: none;
}
@supports (scrollbar-width: none) {
.toc.sidebar .toc-menu ul {
scrollbar-width: none;
}
}
.toc .toc-menu ul::-webkit-scrollbar {
width: 0;
height: 0;
}
@media screen and (min-width: 1024px) {
.toc .toc-menu h3 {
font-size: calc(15 / var(--rem-base) * 1rem);
}
.toc .toc-menu ul {
font-size: calc(13.5 / var(--rem-base) * 1rem);
}
}
.toc .toc-menu li {
margin: 0;
}
.toc .toc-menu li[data-level="2"] a {
padding-left: 1.25rem;
}
.toc .toc-menu li[data-level="3"] a {
padding-left: 2rem;
}
.toc .toc-menu a {
color: inherit;
border-left: 2px solid var(--toc-border-color);
display: inline-block;
padding: 0.25rem 0 0.25rem 0.5rem;
text-decoration: none;
}
.sidebar.toc .toc-menu a {
display: block;
outline: none;
}
.toc .toc-menu a:hover {
color: var(--link-font-color);
}
.toc .toc-menu a.is-active {
border-left-color: var(--link-font-color);
color: var(--doc-font-color);
}
.sidebar.toc .toc-menu a:focus {
background: var(--panel-background);
}
.toolbar {
color: var(--toolbar-font-color);
align-items: center;
background-color: var(--toolbar-background);
box-shadow: 0 1px 0 var(--toolbar-border-color);
display: flex;
font-size: calc(15 / var(--rem-base) * 1rem);
height: var(--toolbar-height);
justify-content: flex-start;
position: sticky;
top: var(--navbar-height);
z-index: var(--z-index-toolbar);
}
.toolbar a {
color: inherit;
}
.nav-toggle {
background: url(../img/menu.svg) no-repeat 50% 47.5%;
background-size: 49%;
border: none;
outline: none;
line-height: inherit;
padding: 0;
height: var(--toolbar-height);
width: var(--toolbar-height);
margin-right: -0.25rem;
}
@media screen and (min-width: 1024px) {
.nav-toggle {
display: none;
}
}
.nav-toggle.is-active {
background-image: url(../img/back.svg);
background-size: 41.5%;
}
.home-link {
display: block;
background: url(../img/home-o.svg) no-repeat center;
height: calc(var(--toolbar-height) / 2);
width: calc(var(--toolbar-height) / 2);
margin: calc(var(--toolbar-height) / 4);
}
.home-link:hover,
.home-link.is-current {
background-image: url(../img/home.svg);
}
.edit-this-page {
display: none;
padding-right: 0.5rem;
}
@media screen and (min-width: 1024px) {
.edit-this-page {
display: block;
}
}
.toolbar .edit-this-page a {
color: var(--toolbar-muted-color);
}
@font-face {
font-family: "Roboto Mono";
font-style: normal;
font-weight: 400;
src:
url(~@fontsource/roboto-mono/files/roboto-mono-latin-400-normal.woff2) format("woff2"),
url(~@fontsource/roboto-mono/files/roboto-mono-latin-400-normal.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/*
@font-face {
font-family: "Roboto Mono";
font-style: normal;
font-weight: 400;
src: url(~@fontsource/roboto-mono/files/roboto-mono-cyrillic-400-normal.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
*/
@font-face {
font-family: "Roboto Mono";
font-style: normal;
font-weight: 600;
src:
url(~@fontsource/roboto-mono/files/roboto-mono-latin-500-normal.woff2) format("woff2"),
url(~@fontsource/roboto-mono/files/roboto-mono-latin-500-normal.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/*
@font-face {
font-family: "Roboto Mono";
font-style: normal;
font-weight: 600;
src: url(~@fontsource/roboto-mono/files/roboto-mono-cyrillic-500-normal.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
*/
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
src:
url(~@fontsource/roboto/files/roboto-latin-400-normal.woff2) format("woff2"),
url(~@fontsource/roboto/files/roboto-latin-400-normal.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 400;
src: url(~@fontsource/roboto/files/roboto-cyrillic-400-normal.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: "Roboto";
font-style: italic;
font-weight: 400;
src:
url(~@fontsource/roboto/files/roboto-latin-400-italic.woff2) format("woff2"),
url(~@fontsource/roboto/files/roboto-latin-400-italic.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Roboto";
font-style: italic;
font-weight: 400;
src: url(~@fontsource/roboto/files/roboto-cyrillic-400-italic.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 600;
src:
url(~@fontsource/roboto/files/roboto-latin-500-normal.woff2) format("woff2"),
url(~@fontsource/roboto/files/roboto-latin-500-normal.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Roboto";
font-style: normal;
font-weight: 600;
src: url(~@fontsource/roboto/files/roboto-cyrillic-500-normal.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
font-family: "Roboto";
font-style: italic;
font-weight: 600;
src:
url(~@fontsource/roboto/files/roboto-latin-500-italic.woff2) format("woff2"),
url(~@fontsource/roboto/files/roboto-latin-500-italic.woff) format("woff");
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
font-family: "Roboto";
font-style: italic;
font-weight: 600;
src: url(~@fontsource/roboto/files/roboto-cyrillic-500-italic.woff2) format("woff2");
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
:root {
/* colors */
--color-white: #fff;
--color-smoke-10: #fefefe;
--color-smoke-30: #fafafa;
--color-smoke-50: #f5f5f5;
--color-smoke-70: #f0f0f0;
--color-smoke-90: #e1e1e1;
--color-gray-10: #c1c1c1;
--color-gray-30: #9c9c9c;
--color-gray-40: #8e8e8e;
--color-gray-50: #808080;
--color-gray-70: #5d5d5d;
--color-jet-20: #4a4a4a;
--color-jet-30: #424242;
--color-jet-50: #333;
--color-jet-70: #222;
--color-jet-80: #191919;
--color-black: #000;
/* fonts */
--rem-base: 18; /* used to compute rem value from desired pixel value (e.g., calc(18 / var(--rem-base) * 1rem) = 18px) */
--body-font-size: 1.0625em; /* 17px */
--body-font-size--desktop: 1.125em; /* 18px */
--body-font-size--print: 0.9375em; /* 15px */
--body-line-height: 1.15;
--body-font-color: var(--color-jet-70);
--body-font-family: "Roboto", sans-serif;
--body-font-weight-bold: 600;
--monospace-font-family: "Roboto Mono", monospace;
--monospace-font-weight-bold: 600;
/* base */
--body-background: var(--color-white);
--panel-background: var(--color-smoke-30);
--panel-border-color: var(--color-smoke-90);
--scrollbar-track-color: var(--color-smoke-30);
--scrollbar-thumb-color: var(--color-gray-10);
--scrollbar_hover-thumb-color: var(--color-gray-30);
/* navbar */
--navbar-background: var(--color-jet-80);
--navbar-font-color: var(--color-white);
--navbar_hover-background: var(--color-black);
--navbar-button-background: var(--color-white);
--navbar-button-border-color: var(--panel-border-color);
--navbar-button-font-color: var(--body-font-color);
--navbar-menu-border-color: var(--panel-border-color);
--navbar-menu-background: var(--color-white);
--navbar-menu-font-color: var(--body-font-color);
--navbar-menu_hover-background: var(--color-smoke-50);
/* nav */
--nav-background: var(--panel-background);
--nav-border-color: var(--color-gray-10);
--nav-line-height: 1.35;
--nav-heading-font-color: var(--color-jet-30);
--nav-muted-color: var(--color-gray-70);
--nav-panel-divider-color: var(--color-smoke-90);
--nav-secondary-background: var(--color-smoke-70);
/* toolbar */
--toolbar-background: var(--panel-background);
--toolbar-border-color: var(--panel-border-color);
--toolbar-font-color: var(--color-gray-70);
--toolbar-muted-color: var(--color-gray-40);
--page-version-menu-background: var(--color-smoke-70);
--page-version-missing-font-color: var(--color-gray-40);
/* admonitions */
--caution-color: #a0439c;
--caution-on-color: var(--color-white);
--important-color: #d32f2f;
--important-on-color: var(--color-white);
--note-color: #217ee7;
--note-on-color: var(--color-white);
--tip-color: #41af46;
--tip-on-color: var(--color-white);
--warning-color: #e18114;
--warning-on-color: var(--color-white);
/* doc */
--doc-font-color: var(--color-jet-50);
--doc-font-size: inherit;
--doc-font-size--desktop: calc(17 / var(--rem-base) * 1rem);
--doc-line-height: 1.6;
--doc-margin: 0 auto;
--doc-margin--desktop: 0 2rem;
--heading-font-color: var(--color-jet-80);
--heading-font-weight: normal;
--alt-heading-font-weight: var(--body-font-weight-bold);
--section-divider-color: var(--panel-border-color);
--link-font-color: #1565c0;
--link_hover-font-color: #104d92;
--link_unresolved-font-color: var(--important-color);
--abstract-background: var(--color-smoke-70);
--abstract-font-color: var(--color-jet-20);
--abstract-border-color: var(--panel-border-color);
--admonition-background: var(--panel-background);
--admonition-label-font-weight: var(--body-font-weight-bold);
--caption-font-color: var(--color-gray-70);
--caption-font-style: italic;
--caption-font-weight: var(--body-font-weight-bold);
--code-background: var(--panel-background);
--code-font-color: var(--body-font-color);
--example-background: var(--color-white);
--example-border-color: var(--color-gray-70);
--kbd-background: var(--panel-background);
--kbd-border-color: var(--color-gray-10);
--pre-background: var(--panel-background);
--pre-border-color: var(--panel-border-color);
--pre-annotation-font-color: var(--color-gray-50);
--quote-background: var(--panel-background);
--quote-border-color: var(--color-gray-70);
--quote-font-color: var(--color-gray-70);
--quote-attribution-font-color: var(--color-gray-40);
--sidebar-background: var(--color-smoke-90);
--table-border-color: var(--panel-border-color);
--table-stripe-background: var(--panel-background);
--table-footer-background: linear-gradient(to bottom, var(--color-smoke-70) 0%, var(--color-white) 100%);
/* toc */
--toc-font-color: var(--nav-muted-color);
--toc-heading-font-color: var(--doc-font-color);
--toc-border-color: var(--panel-border-color);
--toc-line-height: 1.2;
/* footer */
--footer-line-height: var(--doc-line-height);
--footer-background: var(--color-smoke-90);
--footer-font-color: var(--color-gray-70);
--footer-link-font-color: var(--color-jet-80);
/* dimensions and positioning */
--navbar-height: calc(63 / var(--rem-base) * 1rem);
--toolbar-height: calc(45 / var(--rem-base) * 1rem);
--drawer-height: var(--toolbar-height);
--body-top: var(--navbar-height);
--body-min-height: calc(100vh - var(--body-top));
--nav-height: calc(var(--body-min-height) - var(--toolbar-height));
--nav-height--desktop: var(--body-min-height);
--nav-panel-menu-height: calc(100% - var(--drawer-height));
--nav-panel-explore-height: calc(50% + var(--drawer-height));
--nav-width: calc(270 / var(--rem-base) * 1rem);
--toc-top: calc(var(--body-top) + var(--toolbar-height));
--toc-height: calc(100vh - var(--toc-top) - 2.5rem);
--toc-width: calc(162 / var(--rem-base) * 1rem);
--toc-width--widescreen: calc(216 / var(--rem-base) * 1rem);
--doc-max-width: calc(720 / var(--rem-base) * 1rem);
--doc-max-width--desktop: calc(828 / var(--rem-base) * 1rem);
/* stacking */
--z-index-nav: 1;
--z-index-toolbar: 2;
--z-index-page-version-menu: 3;
--z-index-navbar: 4;
}
'use strict'
module.exports = (...args) => {
const numArgs = args.length
if (numArgs === 3) return args[0] && args[1]
if (numArgs < 3) throw new Error('{{and}} helper expects at least 2 arguments')
args.pop()
return args.every((it) => it)
}
'use strict'
const TAG_ALL_RX = /<[^>]+>/g
module.exports = (html) => html && html.replace(TAG_ALL_RX, '')
'use strict'
module.exports = (a, b) => a === b
'use strict'
module.exports = (value) => (value || 0) + 1
'use strict'
module.exports = (a, b) => a !== b
'use strict'
module.exports = (val) => !val
'use strict'
module.exports = (...args) => {
const numArgs = args.length
if (numArgs === 3) return args[0] || args[1]
if (numArgs < 3) throw new Error('{{or}} helper expects at least 2 arguments')
args.pop()
return args.some((it) => it)
}
'use strict'
const { posix: path } = require('path')
module.exports = (to, from, ctx) => {
if (!to) return '#'
if (to.charAt() !== '/') return to
// NOTE only legacy invocation provides both to and from
if (!ctx) from = (ctx = from).data.root.page.url
if (!from) return (ctx.data.root.site.path || '') + to
let hash = ''
const hashIdx = to.indexOf('#')
if (~hashIdx) {
hash = to.slice(hashIdx)
to = to.slice(0, hashIdx)
}
if (to === from) return hash || (isDir(to) ? './' : path.basename(to))
const rel = path.relative(path.dirname(from + '.'), to)
return rel ? (isDir(to) ? rel + '/' : rel) + hash : (isDir(to) ? './' : '../' + path.basename(to)) + hash
}
function isDir (str) {
return str.charAt(str.length - 1) === '/'
}
'use strict'
module.exports = () => new Date().getFullYear().toString()
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="100"
height="100"
viewBox="0 0 100 100"
version="1.1"
inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
sodipodi:docname="back.svg"
enable-background="new">
<title>Left arrow</title>
<sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="6.108138"
inkscape:cx="21.142679"
inkscape:cy="42.629076"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
inkscape:window-width="1920"
inkscape:window-height="1001"
inkscape:window-x="0"
inkscape:window-y="41"
inkscape:window-maximized="1"
scale-x="1" />
<metadata>
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Left arrow</dc:title>
<dc:creator>
<cc:Agent>
<dc:title>Sarah White</dc:title>
</cc:Agent>
</dc:creator>
<dc:publisher>
<cc:Agent>
<dc:title>OpenDevise Inc.</dc:title>
</cc:Agent>
</dc:publisher>
<cc:license
rdf:resource="http://creativecommons.org/licenses/by-sa/4.0/" />
</cc:Work>
<cc:License
rdf:about="http://creativecommons.org/licenses/by-sa/4.0/">
<cc:permits
rdf:resource="http://creativecommons.org/ns#Reproduction" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#Distribution" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Notice" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#Attribution" />
<cc:permits
rdf:resource="http://creativecommons.org/ns#DerivativeWorks" />
<cc:requires
rdf:resource="http://creativecommons.org/ns#ShareAlike" />
</cc:License>
</rdf:RDF>
</metadata>
<g
transform="translate(-3.926492e-7,-270.54187)">
<path
d="m 50.000978,280.44162 -40.1010516,40.10025 40.1010516,40.10025 5.6556,-5.65551 -30.434757,-30.44194 h 64.878253 v -8.0056 H 25.221821 l 30.434757,-30.44001 z" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30"
height="30"
viewBox="0 0 30 30"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="caret.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="16"
inkscape:cx="31.65919"
inkscape:cy="23.730414"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="2688"
inkscape:window-height="1478"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1022.3622)">
<path
style="opacity:1;fill:#c1c1c1;fill-opacity:1;stroke:#c1c1c1;stroke-width:1.99999976;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="m 10.18745,1025.362 14.0001,12.0002 -14.0001,12.0001 z"
id="rect3338"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccc"
inkscape:transform-center-x="-2.1875" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="30"
height="30"
viewBox="0 0 30 30"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="chevron.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.627417"
inkscape:cx="10.05311"
inkscape:cy="10.530062"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
units="px"
inkscape:window-width="2560"
inkscape:window-height="1406"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Calque 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1022.3622)">
<path
style="opacity:1;fill:#5d5d5d;fill-opacity:1;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
d="M 3.6699219,6.5898438 1.4550781,8.6152344 15,23.374272 28.544922,8.6152344 26.330078,6.5898438 15,18.759498 Z"
transform="translate(0,1022.3622)"
id="rect4136"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="home.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<inkscape:path-effect
is_visible="true"
id="path-effect4225"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4221"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4213"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4209"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4204"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4191"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4187"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4183"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4179"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4173"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4169"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4165"
is_visible="true" />
</defs>
<sodipodi:namedview
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1406"
id="namedview8"
showgrid="false"
inkscape:zoom="8.1458701"
inkscape:cx="33.343764"
inkscape:cy="44.907032"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4" />
<g
transform="translate(0,-952.36218)"
id="g4">
<path
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
d="M 50.019531 13.576172 L 21.439453 39.115234 L 21.419922 86.460938 L 42.925781 86.460938 L 42.951172 61.294922 L 57.048828 61.294922 L 57.074219 86.460938 L 78.619141 86.460938 L 78.638672 39.150391 L 50.019531 13.576172 z "
id="path4175"
transform="translate(0,952.36218)" />
<path
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 63.815035,25.903568 0,-9.217018 8.656932,0 -2e-6,16.95383 z"
id="path4193"
transform="translate(0,952.36218)"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 21.43888,991.47783 -9.98234,8.92037"
id="path4177" />
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 88.58189,1000.3982 -9.94315,-8.88535"
id="path4170" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="home-hovered.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<inkscape:path-effect
is_visible="true"
id="path-effect4225"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4221"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4213"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4209"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4204"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4191"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4187"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4183"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4179"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4173"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4169"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4165"
is_visible="true" />
</defs>
<sodipodi:namedview
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1406"
id="namedview8"
showgrid="false"
inkscape:zoom="8.1458701"
inkscape:cx="-15.147065"
inkscape:cy="42.942846"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="g4" />
<g
transform="translate(0,-952.36218)"
id="g4">
<path
style="fill:#222;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
d="M 50.019531 13.576172 L 21.439453 39.115234 L 21.419922 86.460938 L 42.925781 86.460938 L 42.951172 61.294922 L 57.048828 61.294922 L 57.074219 86.460938 L 78.619141 86.460938 L 78.638672 39.150391 L 50.019531 13.576172 z "
id="path4175"
transform="translate(0,952.36218)" />
<path
style="fill:#222;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;fill-opacity:1"
d="m 63.815035,25.903568 0,-9.217018 8.656932,0 -2e-6,16.95383 z"
id="path4193"
transform="translate(0,952.36218)"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccc" />
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 21.43888,991.47783 -9.98234,8.92037"
id="path4177" />
<path
inkscape:connector-curvature="0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:4;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 88.58189,1000.3982 -9.94315,-8.88535"
id="path4170" />
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
id="svg2"
inkscape:version="0.91 r13725"
sodipodi:docname="menu.svg">
<metadata
id="metadata12">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<defs
id="defs10">
<inkscape:path-effect
is_visible="true"
id="path-effect4225"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4221"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4213"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4209"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4204"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4191"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4187"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4183"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4179"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4173"
is_visible="true" />
<inkscape:path-effect
is_visible="true"
id="path-effect4169"
effect="spiro" />
<inkscape:path-effect
effect="spiro"
id="path-effect4165"
is_visible="true" />
</defs>
<sodipodi:namedview
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="2560"
inkscape:window-height="1406"
id="namedview8"
showgrid="false"
inkscape:zoom="5.76"
inkscape:cx="14.532031"
inkscape:cy="43.425849"
inkscape:window-x="0"
inkscape:window-y="1440"
inkscape:window-maximized="1"
inkscape:current-layer="g4" />
<g
transform="translate(0,-952.36218)"
id="g4">
<g
id="g4238"
transform="translate(-1.5e-6,-0.2053541)">
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4149"
d="m 35,972.34003 55.000003,0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:8;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647" />
<rect
y="964.84003"
x="10"
height="15"
width="15"
id="rect4184"
style="opacity:1;fill:#222;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647"
d="m 42.999999,1016.2452 44.999999,0"
id="path4180"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<rect
style="opacity:1;fill:#222;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect4186"
width="10"
height="10"
x="23"
y="1011.2452" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4182"
d="m 42.999999,1035.295 44.999999,0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647" />
<rect
y="1030.295"
x="23"
height="10"
width="10"
id="rect4188"
style="opacity:1;fill:#222;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4210"
d="m 42.999999,997.1955 44.999999,0"
style="fill:none;fill-rule:evenodd;stroke:#222;stroke-width:5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.94117647" />
<rect
y="992.1955"
x="23"
height="10"
width="10"
id="rect4212"
style="opacity:1;fill:#222;fill-opacity:1;stroke:none;stroke-width:10;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
</g>
</g>
</svg>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16">
<title>Octicons (16px subset)</title>
<desc>Octicons v11.2.0 by GitHub - https://primer.style/octicons/ - License: MIT</desc>
<metadata
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<rdf:RDF>
<cc:Work rdf:about="">
<dc:title>@primer/octicons</dc:title>
<dc:identifier>11.2.0</dc:identifier>
<dc:description>A scalable set of icons handcrafted with &lt;3 by GitHub</dc:description>
<dc:format>image/svg+xml</dc:format>
<dc:creator>
<cc:Agent>
<dc:title>GitHub</dc:title>
</cc:Agent>
</dc:creator>
<dc:rights>
<cc:Agent>
<dc:title>Copyright (c) 2020 GitHub Inc.</dc:title>
</cc:Agent>
</dc:rights>
<cc:license rdf:resource="https://opensource.org/licenses/MIT" />
<dc:relation>https://primer.style/octicons/</dc:relation>
</cc:Work>
</rdf:RDF>
</metadata>
<symbol id="icon-clippy" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
d="M5.75 1a.75.75 0 00-.75.75v3c0 .414.336.75.75.75h4.5a.75.75 0 00.75-.75v-3a.75.75 0 00-.75-.75h-4.5zm.75 3V2.5h3V4h-3zm-2.874-.467a.75.75 0 00-.752-1.298A1.75 1.75 0 002 3.75v9.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0014 13.25v-9.5a1.75 1.75 0 00-.874-1.515.75.75 0 10-.752 1.298.25.25 0 01.126.217v9.5a.25.25 0 01-.25.25h-8.5a.25.25 0 01-.25-.25v-9.5a.25.25 0 01.126-.217z" />
</symbol>
<symbol id="icon-fold" viewBox="0 0 16 16">
<path d="M10.896 2H8.75V.75a.75.75 0 0 0-1.5 0V2H5.104a.25.25 0 0 0-.177.427l2.896 2.896a.25.25 0 0 0 .354 0l2.896-2.896A.25.25 0 0 0 10.896 2ZM8.75 15.25a.75.75 0 0 1-1.5 0V14H5.104a.25.25 0 0 1-.177-.427l2.896-2.896a.25.25 0 0 1 .354 0l2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25Zm-6.5-6.5a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" />
</symbol>
<symbol id="icon-unfold" viewBox="0 0 16 16">
<path d="m8.177.677 2.896 2.896a.25.25 0 0 1-.177.427H8.75v1.25a.75.75 0 0 1-1.5 0V4H5.104a.25.25 0 0 1-.177-.427L7.823.677a.25.25 0 0 1 .354 0ZM7.25 10.75a.75.75 0 0 1 1.5 0V12h2.146a.25.25 0 0 1 .177.427l-2.896 2.896a.25.25 0 0 1-.354 0l-2.896-2.896A.25.25 0 0 1 5.104 12H7.25v-1.25Zm-5-2a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM6 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 6 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5ZM12 8a.75.75 0 0 1-.75.75h-.5a.75.75 0 0 1 0-1.5h.5A.75.75 0 0 1 12 8Zm2.25.75a.75.75 0 0 0 0-1.5h-.5a.75.75 0 0 0 0 1.5h.5Z" />
</symbol>
<use href="#icon-clippy" width="16" height="16" x="0" y="0" />
<view id="view-clippy" viewBox="0 0 16 16" />
<use href="#icon-fold" width="16" height="16" x="0" y="16" />
<view id="view-fold" viewBox="0 16 16 16" />
<use href="#icon-unfold" width="16" height="16" x="0" y="32" />
<view id="view-unfold" viewBox="0 32 16 16" />
</svg>
;(function () {
'use strict'
var SECT_CLASS_RX = /^sect(\d)$/
var navContainer = document.querySelector('.nav-container')
if (!navContainer) return
var navToggle = document.querySelector('.nav-toggle')
var nav = navContainer.querySelector('.nav')
var navMenuToggle = navContainer.querySelector('.nav-menu-toggle')
navToggle.addEventListener('click', showNav)
navContainer.addEventListener('click', trapEvent)
var menuPanel = navContainer.querySelector('[data-panel=menu]')
if (!menuPanel) return
var explorePanel = navContainer.querySelector('[data-panel=explore]')
var currentPageItem = menuPanel.querySelector('.is-current-page')
var originalPageItem = currentPageItem
if (currentPageItem) {
activateCurrentPath(currentPageItem)
scrollItemToMidpoint(menuPanel, currentPageItem.querySelector('.nav-link'))
} else {
menuPanel.scrollTop = 0
}
find(menuPanel, '.nav-item-toggle').forEach(function (btn) {
var li = btn.parentElement
btn.addEventListener('click', toggleActive.bind(li))
var navItemSpan = findNextElement(btn, '.nav-text')
if (navItemSpan) {
navItemSpan.style.cursor = 'pointer'
navItemSpan.addEventListener('click', toggleActive.bind(li))
}
})
if (navMenuToggle && menuPanel.querySelector('.nav-item-toggle')) {
navMenuToggle.style.display = ''
navMenuToggle.addEventListener('click', function () {
var collapse = !this.classList.toggle('is-active')
find(menuPanel, '.nav-item > .nav-item-toggle').forEach(function (btn) {
collapse ? btn.parentElement.classList.remove('is-active') : btn.parentElement.classList.add('is-active')
})
if (currentPageItem) {
if (collapse) activateCurrentPath(currentPageItem)
scrollItemToMidpoint(menuPanel, currentPageItem.querySelector('.nav-link'))
} else {
menuPanel.scrollTop = 0
}
})
}
if (explorePanel) {
explorePanel.querySelector('.context').addEventListener('click', function () {
// NOTE logic assumes there are only two panels
find(nav, '[data-panel]').forEach(function (panel) {
panel.classList.toggle('is-active')
})
})
}
// NOTE prevent text from being selected by double click
menuPanel.addEventListener('mousedown', function (e) {
if (e.detail > 1) e.preventDefault()
})
function onHashChange () {
var navLink
var hash = window.location.hash
if (hash) {
if (hash.indexOf('%')) hash = decodeURIComponent(hash)
navLink = menuPanel.querySelector('.nav-link[href="' + hash + '"]')
if (!navLink) {
var targetNode = document.getElementById(hash.slice(1))
if (targetNode) {
var current = targetNode
var ceiling = document.querySelector('article.doc')
while ((current = current.parentNode) && current !== ceiling) {
var id = current.id
// NOTE: look for section heading
if (!id && (id = SECT_CLASS_RX.test(current.className))) id = (current.firstElementChild || {}).id
if (id && (navLink = menuPanel.querySelector('.nav-link[href="#' + id + '"]'))) break
}
}
}
}
var navItem
if (navLink) {
navItem = navLink.parentNode
} else if (originalPageItem) {
navLink = (navItem = originalPageItem).querySelector('.nav-link')
} else {
return
}
if (navItem === currentPageItem) return
find(menuPanel, '.nav-item.is-active').forEach(function (el) {
el.classList.remove('is-active', 'is-current-path', 'is-current-page')
})
navItem.classList.add('is-current-page')
currentPageItem = navItem
activateCurrentPath(navItem)
scrollItemToMidpoint(menuPanel, navLink)
}
if (menuPanel.querySelector('.nav-link[href^="#"]')) {
if (window.location.hash) onHashChange()
window.addEventListener('hashchange', onHashChange)
}
function activateCurrentPath (navItem) {
var ancestorClasses
var ancestor = navItem.parentNode
while (!(ancestorClasses = ancestor.classList).contains('nav-menu')) {
if (ancestor.tagName === 'LI' && ancestorClasses.contains('nav-item')) {
ancestorClasses.add('is-active', 'is-current-path')
}
ancestor = ancestor.parentNode
}
navItem.classList.add('is-active')
}
function toggleActive () {
if (this.classList.toggle('is-active')) {
var padding = parseFloat(window.getComputedStyle(this).marginTop)
var rect = this.getBoundingClientRect()
var menuPanelRect = menuPanel.getBoundingClientRect()
var overflowY = (rect.bottom - menuPanelRect.top - menuPanelRect.height + padding).toFixed()
if (overflowY > 0) menuPanel.scrollTop += Math.min((rect.top - menuPanelRect.top - padding).toFixed(), overflowY)
}
}
function showNav (e) {
if (navToggle.classList.contains('is-active')) return hideNav(e)
trapEvent(e)
var html = document.documentElement
html.classList.add('is-clipped--nav')
navToggle.classList.add('is-active')
navContainer.classList.add('is-active')
var bounds = nav.getBoundingClientRect()
var expectedHeight = window.innerHeight - Math.round(bounds.top)
if (Math.round(bounds.height) !== expectedHeight) nav.style.height = expectedHeight + 'px'
html.addEventListener('click', hideNav)
}
function hideNav (e) {
trapEvent(e)
var html = document.documentElement
html.classList.remove('is-clipped--nav')
navToggle.classList.remove('is-active')
navContainer.classList.remove('is-active')
html.removeEventListener('click', hideNav)
}
function trapEvent (e) {
e.stopPropagation()
}
function scrollItemToMidpoint (panel, el) {
var rect = panel.getBoundingClientRect()
var effectiveHeight = rect.height
var navStyle = window.getComputedStyle(nav)
if (navStyle.position === 'sticky') effectiveHeight -= rect.top - parseFloat(navStyle.top)
panel.scrollTop = Math.max(0, (el.getBoundingClientRect().height - effectiveHeight) * 0.5 + el.offsetTop)
}
function find (from, selector) {
return [].slice.call(from.querySelectorAll(selector))
}
function findNextElement (from, selector) {
var el = from.nextElementSibling
return el && selector ? el[el.matches ? 'matches' : 'msMatchesSelector'](selector) && el : el
}
})()
;(function () {
'use strict'
var sidebar = document.querySelector('aside.toc.sidebar')
if (!sidebar) return
if (document.querySelector('body.-toc')) return sidebar.parentNode.removeChild(sidebar)
var levels = parseInt(sidebar.dataset.levels || 2, 10)
if (levels < 0) return
var articleSelector = 'article.doc'
var article = document.querySelector(articleSelector)
if (!article) return
var headingsSelector = []
for (var level = 0; level <= levels; level++) {
var headingSelector = [articleSelector]
if (level) {
for (var l = 1; l <= level; l++) headingSelector.push((l === 2 ? '.sectionbody>' : '') + '.sect' + l)
headingSelector.push('h' + (level + 1) + '[id]' + (level > 1 ? ':not(.discrete)' : ''))
} else {
headingSelector.push('h1[id].sect0')
}
headingsSelector.push(headingSelector.join('>'))
}
var headings = find(headingsSelector.join(','), article.parentNode)
if (!headings.length) return sidebar.parentNode.removeChild(sidebar)
var lastActiveFragment
var links = {}
var list = headings.reduce(function (accum, heading) {
var link = document.createElement('a')
link.textContent = heading.textContent
links[(link.href = '#' + heading.id)] = link
var listItem = document.createElement('li')
listItem.dataset.level = parseInt(heading.nodeName.slice(1), 10) - 1
listItem.appendChild(link)
accum.appendChild(listItem)
return accum
}, document.createElement('ul'))
var menu = sidebar.querySelector('.toc-menu')
if (!menu) (menu = document.createElement('div')).className = 'toc-menu'
var title = document.createElement('h3')
title.textContent = sidebar.dataset.title || 'Contents'
menu.appendChild(title)
menu.appendChild(list)
var startOfContent = !document.getElementById('toc') && article.querySelector('h1.page ~ :not(.is-before-toc)')
if (startOfContent) {
var embeddedToc = document.createElement('aside')
embeddedToc.className = 'toc embedded'
embeddedToc.appendChild(menu.cloneNode(true))
startOfContent.parentNode.insertBefore(embeddedToc, startOfContent)
}
window.addEventListener('load', function () {
onScroll()
window.addEventListener('scroll', onScroll)
})
function onScroll () {
var scrolledBy = window.pageYOffset
var buffer = getNumericStyleVal(document.documentElement, 'fontSize') * 1.15
var ceil = article.offsetTop
if (scrolledBy && window.innerHeight + scrolledBy + 2 >= document.documentElement.scrollHeight) {
lastActiveFragment = Array.isArray(lastActiveFragment) ? lastActiveFragment : Array(lastActiveFragment || 0)
var activeFragments = []
var lastIdx = headings.length - 1
headings.forEach(function (heading, idx) {
var fragment = '#' + heading.id
if (idx === lastIdx || heading.getBoundingClientRect().top + getNumericStyleVal(heading, 'paddingTop') > ceil) {
activeFragments.push(fragment)
if (lastActiveFragment.indexOf(fragment) < 0) links[fragment].classList.add('is-active')
} else if (~lastActiveFragment.indexOf(fragment)) {
links[lastActiveFragment.shift()].classList.remove('is-active')
}
})
list.scrollTop = list.scrollHeight - list.offsetHeight
lastActiveFragment = activeFragments.length > 1 ? activeFragments : activeFragments[0]
return
}
if (Array.isArray(lastActiveFragment)) {
lastActiveFragment.forEach(function (fragment) {
links[fragment].classList.remove('is-active')
})
lastActiveFragment = undefined
}
var activeFragment
headings.some(function (heading) {
if (heading.getBoundingClientRect().top + getNumericStyleVal(heading, 'paddingTop') - buffer > ceil) return true
activeFragment = '#' + heading.id
})
if (activeFragment) {
if (activeFragment === lastActiveFragment) return
if (lastActiveFragment) links[lastActiveFragment].classList.remove('is-active')
var activeLink = links[activeFragment]
activeLink.classList.add('is-active')
if (list.scrollHeight > list.offsetHeight) {
list.scrollTop = Math.max(0, activeLink.offsetTop + activeLink.offsetHeight - list.offsetHeight)
}
lastActiveFragment = activeFragment
} else if (lastActiveFragment) {
links[lastActiveFragment].classList.remove('is-active')
lastActiveFragment = undefined
}
}
function find (selector, from) {
return [].slice.call((from || document).querySelectorAll(selector))
}
function getNumericStyleVal (el, prop) {
return parseFloat(window.getComputedStyle(el)[prop])
}
})()
;(function () {
'use strict'
var article = document.querySelector('article.doc')
if (!article) return
var toolbar = document.querySelector('.toolbar')
var supportsScrollToOptions = 'scrollTo' in document.documentElement
function decodeFragment (hash) {
return hash && (~hash.indexOf('%') ? decodeURIComponent(hash) : hash).slice(1)
}
function computePosition (el, sum) {
return article.contains(el) ? computePosition(el.offsetParent, el.offsetTop + sum) : sum
}
function jumpToAnchor (e) {
if (e) {
if (e.altKey || e.ctrlKey) return
window.location.hash = '#' + this.id
e.preventDefault()
}
var y = computePosition(this, 0) - toolbar.getBoundingClientRect().bottom
var instant = e === false && supportsScrollToOptions
instant ? window.scrollTo({ left: 0, top: y, behavior: 'instant' }) : window.scrollTo(0, y)
}
window.addEventListener('load', function jumpOnLoad (e) {
var fragment, target
if ((fragment = decodeFragment(window.location.hash)) && (target = document.getElementById(fragment))) {
jumpToAnchor.call(target, false)
setTimeout(jumpToAnchor.bind(target, false), 250)
}
window.removeEventListener('load', jumpOnLoad)
})
Array.prototype.slice.call(document.querySelectorAll('a[href^="#"]')).forEach(function (el) {
var fragment, target
if ((fragment = decodeFragment(el.hash)) && (target = document.getElementById(fragment))) {
el.addEventListener('click', jumpToAnchor.bind(target))
}
})
})()
;(function () {
'use strict'
var toggle = document.querySelector('.page-versions .version-menu-toggle')
if (!toggle) return
var selector = document.querySelector('.page-versions')
toggle.addEventListener('click', function (e) {
selector.classList.toggle('is-active')
e.stopPropagation() // trap event
})
document.documentElement.addEventListener('click', function () {
selector.classList.remove('is-active')
})
})()
;(function () {
'use strict'
var navbarBurger = document.querySelector('.navbar-burger')
if (!navbarBurger) return
navbarBurger.addEventListener('click', toggleNavbarMenu.bind(navbarBurger))
function toggleNavbarMenu (e) {
e.stopPropagation() // trap event
document.documentElement.classList.toggle('is-clipped--navbar')
navbarBurger.setAttribute('aria-expanded', this.classList.toggle('is-active'))
var menu = document.getElementById(this.getAttribute('aria-controls') || this.dataset.target)
if (menu.classList.toggle('is-active')) {
menu.style.maxHeight = ''
var expectedMaxHeight = window.innerHeight - Math.round(menu.getBoundingClientRect().top)
var actualMaxHeight = parseInt(window.getComputedStyle(menu).maxHeight, 10)
if (actualMaxHeight !== expectedMaxHeight) menu.style.maxHeight = expectedMaxHeight + 'px'
}
}
})()
;(function () {
'use strict'
var CMD_RX = /^\$ (\S[^\\\n]*(\\\n(?!\$ )[^\\\n]*)*)(?=\n|$)/gm
var LINE_CONTINUATION_RX = /( ) *\\\n *|\\\n( ?) */g
var TRAILING_SPACE_RX = / +$/gm
var config = (document.getElementById('site-script') || { dataset: {} }).dataset
var supportsCopy = window.navigator.clipboard
var svgAs = config.svgAs
var uiRootPath = (config.uiRootPath == null ? window.uiRootPath : config.uiRootPath) || '.'
;[].slice.call(document.querySelectorAll('.doc pre.highlight, .doc .literalblock pre')).forEach(function (pre) {
var code, language, lang, copy, toast, toolbox
if (pre.classList.contains('highlight')) {
code = pre.querySelector('code')
if ((language = code.dataset.lang) && language !== 'console') {
;(lang = document.createElement('span')).className = 'source-lang'
lang.appendChild(document.createTextNode(language))
}
} else if (pre.innerText.startsWith('$ ')) {
var block = pre.parentNode.parentNode
block.classList.remove('literalblock')
block.classList.add('listingblock')
pre.classList.add('highlightjs', 'highlight')
;(code = document.createElement('code')).className = 'language-console hljs'
code.dataset.lang = 'console'
code.appendChild(pre.firstChild)
pre.appendChild(code)
} else {
return
}
;(toolbox = document.createElement('div')).className = 'source-toolbox'
if (lang) toolbox.appendChild(lang)
if (supportsCopy) {
;(copy = document.createElement('button')).className = 'copy-button'
copy.setAttribute('title', 'Copy to clipboard')
if (svgAs === 'svg') {
var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg')
svg.setAttribute('class', 'copy-icon')
var use = document.createElementNS('http://www.w3.org/2000/svg', 'use')
use.setAttribute('href', uiRootPath + '/img/octicons-16.svg#icon-clippy')
svg.appendChild(use)
copy.appendChild(svg)
} else {
var img = document.createElement('img')
img.src = uiRootPath + '/img/octicons-16.svg#view-clippy'
img.alt = 'copy icon'
img.className = 'copy-icon'
copy.appendChild(img)
}
;(toast = document.createElement('span')).className = 'copy-toast'
toast.appendChild(document.createTextNode('Copied!'))
copy.appendChild(toast)
toolbox.appendChild(copy)
}
pre.parentNode.appendChild(toolbox)
if (copy) copy.addEventListener('click', writeToClipboard.bind(copy, code))
})
function extractCommands (text) {
var cmds = []
var m
while ((m = CMD_RX.exec(text))) cmds.push(m[1].replace(LINE_CONTINUATION_RX, '$1$2'))
return cmds.join(' && ')
}
function writeToClipboard (code) {
var text = code.innerText.replace(TRAILING_SPACE_RX, '')
if (code.dataset.lang === 'console' && text.startsWith('$ ')) text = extractCommands(text)
window.navigator.clipboard.writeText(text).then(
function () {
this.classList.add('clicked')
this.offsetHeight // eslint-disable-line no-unused-expressions
this.classList.remove('clicked')
}.bind(this),
function () {}
)
}
})()
;(function () {
'use strict'
var hljs = require('highlight.js/lib/highlight')
hljs.registerLanguage('asciidoc', require('highlight.js/lib/languages/asciidoc'))
hljs.registerLanguage('bash', require('highlight.js/lib/languages/bash'))
hljs.registerLanguage('clojure', require('highlight.js/lib/languages/clojure'))
hljs.registerLanguage('cpp', require('highlight.js/lib/languages/cpp'))
hljs.registerLanguage('cs', require('highlight.js/lib/languages/cs'))
hljs.registerLanguage('css', require('highlight.js/lib/languages/css'))
hljs.registerLanguage('diff', require('highlight.js/lib/languages/diff'))
hljs.registerLanguage('dockerfile', require('highlight.js/lib/languages/dockerfile'))
hljs.registerLanguage('elixir', require('highlight.js/lib/languages/elixir'))
hljs.registerLanguage('go', require('highlight.js/lib/languages/go'))
hljs.registerLanguage('groovy', require('highlight.js/lib/languages/groovy'))
hljs.registerLanguage('haskell', require('highlight.js/lib/languages/haskell'))
hljs.registerLanguage('java', require('highlight.js/lib/languages/java'))
hljs.registerLanguage('javascript', require('highlight.js/lib/languages/javascript'))
hljs.registerLanguage('json', require('highlight.js/lib/languages/json'))
hljs.registerLanguage('julia', require('highlight.js/lib/languages/julia'))
hljs.registerLanguage('kotlin', require('highlight.js/lib/languages/kotlin'))
hljs.registerLanguage('lua', require('highlight.js/lib/languages/lua'))
hljs.registerLanguage('markdown', require('highlight.js/lib/languages/markdown'))
hljs.registerLanguage('nix', require('highlight.js/lib/languages/nix'))
hljs.registerLanguage('none', require('highlight.js/lib/languages/plaintext'))
hljs.registerLanguage('objectivec', require('highlight.js/lib/languages/objectivec'))
hljs.registerLanguage('perl', require('highlight.js/lib/languages/perl'))
hljs.registerLanguage('php', require('highlight.js/lib/languages/php'))
hljs.registerLanguage('properties', require('highlight.js/lib/languages/properties'))
hljs.registerLanguage('puppet', require('highlight.js/lib/languages/puppet'))
hljs.registerLanguage('python', require('highlight.js/lib/languages/python'))
hljs.registerLanguage('ruby', require('highlight.js/lib/languages/ruby'))
hljs.registerLanguage('rust', require('highlight.js/lib/languages/rust'))
hljs.registerLanguage('scala', require('highlight.js/lib/languages/scala'))
hljs.registerLanguage('shell', require('highlight.js/lib/languages/shell'))
hljs.registerLanguage('sql', require('highlight.js/lib/languages/sql'))
hljs.registerLanguage('swift', require('highlight.js/lib/languages/swift'))
hljs.registerLanguage('xml', require('highlight.js/lib/languages/xml'))
hljs.registerLanguage('yaml', require('highlight.js/lib/languages/yaml'))
;[].slice.call(document.querySelectorAll('pre code.hljs[data-lang]')).forEach(function (node) {
hljs.highlightBlock(node)
})
})()
<!DOCTYPE html>
<html lang="en">
<head>
{{> head defaultPageTitle='Page Not Found'}}
</head>
<body class="status-404">
{{> header}}
{{> body}}
{{> footer}}
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
{{> head defaultPageTitle='Untitled'}}
</head>
<body class="article{{#with (or page.attributes.role page.role)}} {{{this}}}{{/with}}">
{{> header}}
{{> body}}
{{> footer}}
</body>
</html>
<article class="doc">
<h1 class="page">{{{or page.title 'Page Not Found'}}}</h1>
<div class="paragraph">
<p>The page you&#8217;re looking for does not exist. It may have been moved. You can{{#with site.homeUrl}} return to the <a href="{{{this}}}">start page</a>, or{{/with}} follow one of the links in the navigation to the left.</p>
</div>
<div class="paragraph">
<p>If you arrived on this page by clicking on a link, please notify the owner of the site that the link is broken.
If you typed the URL of this page manually, please double check that you entered the address correctly.</p>
</div>
</article>
<article class="doc">
{{#with page.title}}
<h1 class="page">{{{this}}}</h1>
{{/with}}
{{{page.contents}}}
{{> pagination}}
</article>
<div class="body">
{{> nav}}
{{> main}}
</div>
<nav class="breadcrumbs" aria-label="breadcrumbs">
{{#if page.breadcrumbs}}
<ul>
{{#with page.componentVersion}}
{{#if (and ./title (ne ./title @root.page.breadcrumbs.0.content))}}
<li><a href="{{{relativize ./url}}}">{{{./title}}}</a></li>
{{/if}}
{{/with}}
{{#each page.breadcrumbs}}
<li>
{{~#if (and ./url (eq ./urlType 'internal'))~}}
<a href="{{{relativize ./url}}}">{{{./content}}}</a>
{{~else~}}
{{{./content}}}
{{~/if~}}
</li>
{{/each}}
</ul>
{{/if}}
</nav>
{{#if (and page.fileUri (not env.CI))}}
<div class="edit-this-page"><a href="{{page.fileUri}}">Edit this Page</a></div>
{{else if (and page.editUrl (or env.FORCE_SHOW_EDIT_PAGE_LINK (not page.origin.private)))}}
<div class="edit-this-page"><a href="{{page.editUrl}}">Edit this Page</a></div>
{{/if}}
<footer class="footer">
<p>This page was built using the Antora default UI.</p>
<p>The source code for this UI is licensed under the terms of the MPL-2.0 license.</p>
</footer>
<script id="site-script" src="{{{uiRootPath}}}/js/site.js" data-ui-root-path="{{{uiRootPath}}}"></script>
<script async src="{{{uiRootPath}}}/js/vendor/highlight.js"></script>
{{#if env.SITE_SEARCH_PROVIDER}}
{{> search-scripts}}
{{/if}}
{{> footer-content}}
{{> footer-scripts}}
{{!-- <link rel="icon" href="{{{uiRootPath}}}/img/favicon.ico" type="image/x-icon"> --}}
{{#with page.canonicalUrl}}
<link rel="canonical" href="{{{this}}}">
{{/with}}
{{#unless (eq page.attributes.pagination undefined)}}
{{#with page.previous}}
<link rel="prev" href="{{{relativize ./url}}}">
{{/with}}
{{#with page.next}}
<link rel="next" href="{{{relativize ./url}}}">
{{/with}}
{{/unless}}
{{#with page.description}}
<meta name="description" content="{{{detag this}}}">
{{/with}}
{{#with page.keywords}}
<meta name="keywords" content="{{{this}}}">
{{/with}}
{{#with (or antoraVersion site.antoraVersion)}}
<meta name="generator" content="Antora {{{this}}}">
{{/with}}
{{!-- Add additional meta tags here --}}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
{{#with site.keys.googleAnalytics}}
<script async src="https://www.googletagmanager.com/gtag/js?id={{this}}"></script>
<script>function gtag(){dataLayer.push(arguments)};window.dataLayer=window.dataLayer||[];gtag('js',new Date());gtag('config','{{this}}')</script>
{{/with}}
{{!--
<script>var uiRootPath = '{{{uiRootPath}}}'</script>
--}}
<link rel="stylesheet" href="{{{uiRootPath}}}/css/site.css">
<title>{{{detag (or page.title defaultPageTitle)}}}{{#with site.title}} :: {{this}}{{/with}}</title>
{{> head-prelude}}
{{> head-title}}
{{> head-info}}
{{> head-styles}}
{{> head-meta}}
{{> head-scripts}}
{{> head-icons}}
<header class="header">
<nav class="navbar">
<div class="navbar-brand">
<a class="navbar-item" href="{{{or site.url siteRootPath}}}">{{site.title}}</a>
{{#if env.SITE_SEARCH_PROVIDER}}
<div class="navbar-item search hide-for-print">
<div id="search-field" class="field">
<input id="search-input" type="text" placeholder="Search the docs"{{#if page.home}} autofocus{{/if}}>
</div>
</div>
{{/if}}
<button class="navbar-burger" aria-controls="topbar-nav" aria-expanded="false" aria-label="Toggle main menu">
<span></span>
<span></span>
<span></span>
</button>
</div>
<div id="topbar-nav" class="navbar-menu">
<div class="navbar-end">
<a class="navbar-item" href="#">Home</a>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Products</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="#">Product A</a>
<a class="navbar-item" href="#">Product B</a>
<a class="navbar-item" href="#">Product C</a>
</div>
</div>
<div class="navbar-item has-dropdown is-hoverable">
<a class="navbar-link" href="#">Services</a>
<div class="navbar-dropdown">
<a class="navbar-item" href="#">Service A</a>
<a class="navbar-item" href="#">Service B</a>
<a class="navbar-item" href="#">Service C</a>
</div>
</div>
<div class="navbar-item">
<span class="control">
<a class="button is-primary" href="#">Download</a>
</span>
</div>
</div>
</div>
</nav>
</header>
{{!-- Add header scripts here --}}
{{> header-scripts}}
{{> header-content}}
<main class="article">
{{> toolbar}}
<div class="content">
{{#if (eq page.layout '404')}}
{{> article-404}}
{{else}}
{{> toc}}
{{> article}}
{{/if}}
</div>
</main>
<div class="nav-panel-explore{{#unless page.navigation}} is-active{{/unless}}" data-panel="explore">
{{#if page.component}}
<div class="context">
<span class="title">{{page.component.title}}</span>
<span class="version">{{#if (or page.componentVersion.version (ne page.componentVersion.displayVersion 'default'))}}{{page.componentVersion.displayVersion}}{{/if}}</span>
</div>
{{/if}}
<ul class="components">
{{#each site.components}}
<li class="component{{#if (eq this @root.page.component)}} is-current{{/if}}">
<div class="title"><a href="{{{relativize ./url}}}">{{{./title}}}</a></div>
{{#if (or ./versions.[1] ./versions.[0].version (ne ./versions.[0].displayVersion 'default'))}}
<ul class="versions">
{{#each ./versions}}
<li class="version
{{~#if (and (eq .. @root.page.component) (eq this @root.page.componentVersion))}} is-current{{/if~}}
{{~#if (eq this ../latest)}} is-latest{{/if}}">
<a href="{{{relativize ./url}}}">{{./displayVersion}}</a>
</li>
{{/each}}
</ul>
{{/if}}
</li>
{{/each}}
</ul>
</div>
{{#with page.navigation}}
<div class="nav-panel-menu is-active" data-panel="menu">
<nav class="nav-menu">
<button class="nav-menu-toggle" aria-label="Toggle expand/collapse all" style="display: none"></button>
{{#with @root.page.componentVersion}}
<h3 class="title"><a href="{{{relativize ./url}}}">{{./title}}</a></h3>
{{/with}}
{{> nav-tree navigation=this}}
</nav>
</div>
{{/with}}
<button class="nav-toggle"></button>
{{#if navigation.length}}
<ul class="nav-list">
{{#each navigation}}
<li class="nav-item{{#if (eq ./url @root.page.url)}} is-current-page{{/if}}" data-depth="{{or ../level 0}}">
{{#if ./content}}
{{#if ./items.length}}
<button class="nav-item-toggle"></button>
{{/if}}
{{#if ./url}}
<a class="nav-link" href="
{{~#if (eq ./urlType 'internal')}}{{{relativize ./url}}}
{{~else}}{{{./url}}}{{~/if}}">{{{./content}}}</a>
{{else}}
<span class="nav-text">{{{./content}}}</span>
{{/if}}
{{/if}}
{{> nav-tree navigation=./items level=(increment ../level)}}
</li>
{{/each}}
</ul>
{{/if}}
<div class="nav-container"{{#if page.component}} data-component="{{page.component.name}}" data-version="{{page.version}}"{{/if}}>
<aside class="nav">
<div class="panels">
{{> nav-menu}}
{{> nav-explore}}
</div>
</aside>
</div>
{{#with page.versions}}
<div class="page-versions">
<button class="version-menu-toggle" title="Show other versions of page">{{@root.page.componentVersion.displayVersion}}</button>
<div class="version-menu">
{{#each this}}
<a class="version
{{~#if (eq ./version @root.page.version)}} is-current{{/if~}}
{{~#if ./missing}} is-missing{{/if}}" href="{{{relativize ./url}}}">{{./displayVersion}}</a>
{{/each}}
</div>
</div>
{{/with}}
{{#unless (eq page.attributes.pagination undefined)}}
{{#if (or page.previous page.next)}}
<nav class="pagination">
{{#if (ne page.attributes.pagination 'next')}}
{{#with page.previous}}
<span class="prev"><a href="{{{relativize ./url}}}">{{{./content}}}</a></span>
{{/with}}
{{/if}}
{{#if (ne page.attributes.pagination 'prev')}}
{{#with page.next}}
<span class="next"><a href="{{{relativize ./url}}}">{{{./content}}}</a></span>
{{/with}}
{{/if}}
</nav>
{{/if}}
{{/unless}}
<aside class="toc sidebar" data-title="{{{or page.attributes.toctitle 'Contents'}}}" data-levels="{{{or page.attributes.toclevels 2}}}">
<div class="toc-menu"></div>
</aside>
<div class="toolbar" role="navigation">
{{> nav-toggle}}
{{#with site.homeUrl}}
<a href="{{{relativize this}}}" class="home-link{{#if @root.page.home}} is-current{{/if}}"></a>
{{/with}}
{{> breadcrumbs}}
{{> page-versions}}
{{> edit-this-page}}
</div>
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment