From 371de8a42d035bf0f6fdfc394aaf01e28a075ce0 Mon Sep 17 00:00:00 2001 From: Carl Kittelberger Date: Fri, 24 Aug 2018 16:49:50 +0200 Subject: [PATCH] Prepare for production deployment. --- .browserslistrc | 3 +- .gitattributes | 2 +- Caddyfile | 1 + Dockerfile | 29 +-- Jenkinsfile | 157 +++++++++++++ deployment/.gitignore | 1 + deployment/docker-compose.yml | 41 ++++ deployment/frontend.env | 1 + package.json | 5 + src/player.styl | 2 +- webpack.config.babel.js | 27 ++- yarn.lock | 429 +++++++++++++++++++++++++++++++++- 12 files changed, 673 insertions(+), 25 deletions(-) create mode 100644 Caddyfile create mode 100644 Jenkinsfile create mode 100644 deployment/.gitignore create mode 100644 deployment/docker-compose.yml create mode 100644 deployment/frontend.env diff --git a/.browserslistrc b/.browserslistrc index 1c965af..3c314c9 100644 --- a/.browserslistrc +++ b/.browserslistrc @@ -1,4 +1,5 @@ last 2 major versions last 2 years ->= 1% not dead +IE >= 9 +>= 1% diff --git a/.gitattributes b/.gitattributes index f8ff2b5..3fd51a7 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1 +1 @@ -*.mp4 filter=lfs diff=lfs merge=lfs -text +*.mp4 filter=lfs diff=lfs merge=lfs -text \ No newline at end of file diff --git a/Caddyfile b/Caddyfile new file mode 100644 index 0000000..9fab2cf --- /dev/null +++ b/Caddyfile @@ -0,0 +1 @@ +http://:80 diff --git a/Dockerfile b/Dockerfile index 3f8e273..21346e7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,22 +1,23 @@ -FROM alpine:3.7 AS video +FROM node:8-alpine AS builder -RUN apk add --no-cache ffmpeg +WORKDIR /src -COPY video/big.mp4 big.mp4 +COPY ./video/ ./video/ +COPY ./package.json ./ +COPY ./development/node/ ./development/node/ +COPY ./.*rc ./ +RUN NODE_ENV=development yarn +RUN yarn video:production -RUN mkdir /out -RUN ffmpeg \ - -i big.mp4 \ - -c copy \ - -use_timeline 1 \ - -use_template 1 \ - -single_file 1 \ - -hls_playlist 1 \ - -f dash \ - /out/clock.mpd +COPY ./webpack* ./ +COPY ./src/ ./src/ +RUN yarn build:production ### FROM icedream/caddy -COPY --from=video /out /htdocs/video +COPY Caddyfile . +COPY --from=builder /src/dist/ . + +EXPOSE 80 diff --git a/Jenkinsfile b/Jenkinsfile new file mode 100644 index 0000000..ac3309d --- /dev/null +++ b/Jenkinsfile @@ -0,0 +1,157 @@ +def gitBranchSlugUnderscore = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "_") +def gitBranchSlugDash = env.BRANCH_NAME.replaceAll(/[^A-Za-z0-9]/, "-") + +// Stack name under which to deploy the stack, must not conflict with other +// projects! +def dockerStackName = "dashwoodenclock_${gitBranchSlugUnderscore}" + +// Hostnames +/* +| Component | master | develop | other branches | +| --- | --- | --- | --- | +| Frontend | https://dash-wooden-clock.icedream.tech | https://develop.review.dash-wooden-clock.icedream.tech | https://${gitBranchSlugDash}.review.dash-wooden-clock.icedream.tech | +| Backend | https://api.dash-wooden-clock.icedream.tech | https://develop-api.review.dash-wooden-clock.icedream.tech | https://${gitBranchSlugDash}-api.review.dash-wooden-clock.icedream.tech | +| Backend SQL admin | https://mysql.admin.dash-wooden-clock.icedream.tech | https://develop-mysql.admin.dash-wooden-clock.icedream.tech | https://${gitBranchSlugDash}-mysql.admin.dash-wooden-clock.icedream.tech | + */ +def projectDomainBase = 'clock.icedream.tech' +def projectReviewDomainBase = projectDomainBase + +def projectTag = "latest" +def projectFrontendHostname = projectDomainBase +if (env.BRANCH_NAME != "master") { + projectTag = gitBranchSlugDash + projectFrontendHostname = "${gitBranchSlugDash}.${projectReviewDomainBase}" +} + +// How to access the swarm manager of the deployment infrastructure +def dockerSwarmManagerUrl = 'tcp://prod-docker-mgr.dmz.dreamnetwork.oss:2375' +def dockerSwarmManagerCredentials = 'docker_socket_project_gitea_secretkeys' + +// Docker image version tags +def dockerVersion = '18.03' +def dockerComposeVersion = '1.22.0' + +// Fully qualified docker images to pull +def dockerImage = "docker:${dockerVersion}" +def dockerComposeImage = "docker/compose:${dockerComposeVersion}" +def nodeImage = "node:8" +def composerImage = "composer:1.6.5" + +// Fully qualified names for our project images +def dockerProjectImageNamespace = "docker.dreamnetwork.oss:5000/dash-wooden-clock" +def dockerProjectBackendImageName = "${dockerProjectImageNamespace}/dash-wooden-clock-backend" +def dockerProjectFrontendImageName = "${dockerProjectImageNamespace}/dash-wooden-clock-frontend" + +// Abort build under some conditions +@NonCPS +def shouldSkip() { + if (currentBuild.changeSets != null) { + def skipMarkerFound = false; + for (changeSet in currentBuild.changeSets) { + for (entry in changeSet) { + // Check for [ci skip] + skipMarkerFound = !!(entry.comment =~ /\[ci\s+skip\]/) + } + } + + if (skipMarkerFound) { + echo "Skipping CI as last commit contains [ci skip]." + return true + } + } + return false +} + +node { + checkout scm +} +if (shouldSkip()) { + manager.buildNotBuilt() + return +} + +pipeline { + agent none + environment { + DASHWOODENCLOCK_FRONTEND_HOSTNAME = "${projectFrontendHostname}" + } + options { + ansiColor('xterm') + } + stages { + stage('build') { + agent { + docker { + label 'docker' + image dockerImage + // pass through to host Docker instance + args '-v /var/run/docker.sock:/var/run/docker.sock' + } + } + environment { + DASHWOODENCLOCK_FRONTEND_IMAGE = "${dockerProjectFrontendImageName}:${projectTag}" + } + steps { + sh """ + apk add --no-cache python3 py3-pip + pip3 install docker-compose==${dockerComposeVersion} + """ + sh """ + export PATH="$PATH:/var/tmp/deps/docker-compose" + cd deployment + docker-compose build \"frontend\" + docker-compose push \"frontend\" + """ + sh "docker inspect -f \"DASHWOODENCLOCK_FRONTEND_IMAGE={{index .RepoDigests 0}}\" \"${dockerProjectFrontendImageName}:${projectTag}\" > deployment/frontend.env" + stash includes: 'deployment/frontend.env', name: 'deploymentFrontendEnv' + } + } + + stage('predeploy') { + agent { + docker { + label 'docker' + image dockerImage + } + } + steps { + sh """ + apk add --no-cache python3 py3-pip + pip3 install docker-compose==${dockerComposeVersion} + """ + unstash "deploymentFrontendEnv" + sh """ + export PATH="$PATH:/var/tmp/deps/docker-compose" + cd deployment + for envfile in ./*.env; do + source \"\${envfile}\" + done + export DASHWOODENCLOCK_BACKEND_IMAGE + export DASHWOODENCLOCK_FRONTEND_IMAGE + docker-compose config > .docker-compose.yml + """ + archive "deployment/.docker-compose.yml" + stash includes: 'deployment/.docker-compose.yml', name: 'finalStackConfig' + } + } + + stage('deploy') { + agent { + label 'docker' + } + steps { + unstash "finalStackConfig" + script { + docker.withServer(dockerSwarmManagerUrl, dockerSwarmManagerCredentials) { + sh "docker stack rm ${dockerStackName}" + sleep 10 + sh "cd deployment && docker stack deploy -c .docker-compose.yml ${dockerStackName}" + } + currentBuild.description = """ +- Frontend web server:\thttps://${env.DASHWOODENCLOCK_FRONTEND_HOSTNAME} +""" + } + } + } + } +} diff --git a/deployment/.gitignore b/deployment/.gitignore new file mode 100644 index 0000000..03bd412 --- /dev/null +++ b/deployment/.gitignore @@ -0,0 +1 @@ +*.env diff --git a/deployment/docker-compose.yml b/deployment/docker-compose.yml new file mode 100644 index 0000000..59c0bbe --- /dev/null +++ b/deployment/docker-compose.yml @@ -0,0 +1,41 @@ +# Docker Compose project stack +# This will be used by Jenkins to fire up the project on the server. + +version: "3.6" + +networks: + # Private network with all containers that will be published via HTTP/HTTPS + overlay_web_front: + external: true + +x-security-headers: &security_headers + traefik.frontend.headers.SSLRedirect: "true" + traefik.frontend.headers.ForceSTSHeader: "true" + traefik.frontend.headers.STSSeconds: "315360000" + traefik.frontend.headers.referrerPolicy: "same-origin" + traefik.frontend.headers.contentTypeNosniff: "true" + traefik.frontend.headers.browserXSSFilter: "true" + traefik.frontend.headers.frameDeny: "true" + # traefik.frontend.headers.contentSecurityPolicy: "default-src 'none'; base-uri 'none'; form-action 'self'; script-src 'self'; object-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self'; media-src 'none'; frame-src 'none'; frame-ancestors 'none'; font-src 'self'; connect-src 'self'" + +services: + # Single page frontend application + frontend: + image: ${DASHWOODENCLOCK_FRONTEND_IMAGE:-docker.dreamnetwork.oss:5000/icedream/dash-wooden-clock} + build: ../frontend + env_file: + - frontend.env + deploy: + mode: global + placement: + constraints: + - node.labels.deployment.production == 1 + - node.platform.os == linux + - node.platform.arch == x86_64 + labels: + <<: *security_headers + traefik.port: "80" + traefik.frontend.rule: "Host:${SECRETKEYS_FRONTEND_HOSTNAME:-clock.icedream.tech}" + traefik.docker.network: overlay_web_front + networks: + overlay_web_front: diff --git a/deployment/frontend.env b/deployment/frontend.env new file mode 100644 index 0000000..dcf2c80 --- /dev/null +++ b/deployment/frontend.env @@ -0,0 +1 @@ +# Placeholder diff --git a/package.json b/package.json index 64ae5b3..f2802ee 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,10 @@ "@babel/node": "^7.0.0-rc.2", "@babel/preset-env": "^7.0.0-rc.2", "@ffmpeg-installer/ffmpeg": "^1.0.15", + "autoprefixer": "^9.1.3", "babel-core": "7.0.0-bridge.0", "babel-loader": "^8.0.0-beta.6", + "browserslist": "^4.1.0", "csp-html-webpack-plugin": "^2.3.0", "css-loader": "^1.0.0", "eslint": "^5.4.0", @@ -21,6 +23,9 @@ "mini-css-extract-plugin": "^0.4.2", "mkdirp": "^0.5.1", "npm-run-all": "^4.1.3", + "postcss-font-family-system-ui": "^3.0.0", + "postcss-loader": "^3.0.0", + "postcss-preset-env": "^5.3.0", "resolve-url-loader": "^2.3.0", "script-ext-html-webpack-plugin": "^2.0.1", "style-loader": "^0.22.1", diff --git a/src/player.styl b/src/player.styl index 350f224..2073b17 100644 --- a/src/player.styl +++ b/src/player.styl @@ -11,7 +11,7 @@ html body background: transparent - font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif + font-family: system-ui html, body padding: 0 diff --git a/webpack.config.babel.js b/webpack.config.babel.js index a1abb48..f3325d1 100644 --- a/webpack.config.babel.js +++ b/webpack.config.babel.js @@ -3,6 +3,10 @@ import CspHtmlWebpackPlugin from 'csp-html-webpack-plugin'; import ScriptExtHtmlWebpackPlugin from 'script-ext-html-webpack-plugin'; import MiniCssExtractPlugin from 'mini-css-extract-plugin'; +import AutoprefixerPostCSSPlugin from 'autoprefixer'; +import SystemUIFontFamilyPostCSSPlugin from 'postcss-font-family-system-ui'; +import PostCSSEnvPreset from 'postcss-preset-env'; + import path from 'path'; const sourceDirectory = path.resolve(__dirname, 'src'); @@ -74,6 +78,17 @@ export default (env, { mode }) => { options: { modules: true, camelCase: true, + importLoaders: 1, + }, + }, + { + loader: 'postcss-loader', + options: { + plugins: [ + PostCSSEnvPreset(), + SystemUIFontFamilyPostCSSPlugin(), + AutoprefixerPostCSSPlugin(), + ], }, }, ], @@ -89,7 +104,17 @@ export default (env, { mode }) => { options: { modules: true, camelCase: true, - importLoaders: 2, + importLoaders: 3, + }, + }, + { + loader: 'postcss-loader', + options: { + plugins: [ + PostCSSEnvPreset(), + SystemUIFontFamilyPostCSSPlugin(), + AutoprefixerPostCSSPlugin(), + ], }, }, 'resolve-url-loader', diff --git a/yarn.lock b/yarn.lock index 38c1639..9e445fb 100644 --- a/yarn.lock +++ b/yarn.lock @@ -549,6 +549,10 @@ lodash "^4.17.10" to-fast-properties "^2.0.0" +"@csstools/convert-colors@^1.4.0": + version "1.4.0" + resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" + "@ffmpeg-installer/darwin-x64@4.0.6": version "4.0.6" resolved "https://registry.yarnpkg.com/@ffmpeg-installer/darwin-x64/-/darwin-x64-4.0.6.tgz#366c0ee40160e0e6b6e4748f97a2bd9dd45d9e68" @@ -920,6 +924,28 @@ atob@^2.1.1: version "2.1.2" resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" +autoprefixer@^8.6.5: + version "8.6.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-8.6.5.tgz#343f3d193ed568b3208e00117a1b96eb691d4ee9" + dependencies: + browserslist "^3.2.8" + caniuse-lite "^1.0.30000864" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^6.0.23" + postcss-value-parser "^3.2.3" + +autoprefixer@^9.1.3: + version "9.1.3" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.1.3.tgz#bd5940ccb9d1bfa3508308659915f0a14394c8d5" + dependencies: + browserslist "^4.0.2" + caniuse-lite "^1.0.30000878" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + postcss "^7.0.2" + postcss-value-parser "^3.2.3" + babel-code-frame@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" @@ -941,6 +967,10 @@ babel-loader@^8.0.0-beta.6: mkdirp "^0.5.1" util.promisify "^1.0.0" +balanced-match@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + balanced-match@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" @@ -1090,13 +1120,21 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^3.0.0: +browserslist@^3.0.0, browserslist@^3.2.8: version "3.2.8" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" dependencies: caniuse-lite "^1.0.30000844" electron-to-chromium "^1.3.47" +browserslist@^4.0.2, browserslist@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.1.0.tgz#81cbb8e52dfa09918f93c6e051d779cb7360785d" + dependencies: + caniuse-lite "^1.0.30000878" + electron-to-chromium "^1.3.61" + node-releases "^1.0.0-alpha.11" + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -1197,7 +1235,7 @@ camelcase@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" -caniuse-lite@^1.0.30000844: +caniuse-lite@^1.0.30000844, caniuse-lite@^1.0.30000864, caniuse-lite@^1.0.30000865, caniuse-lite@^1.0.30000878: version "1.0.30000878" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000878.tgz#c644c39588dd42d3498e952234c372e5a40a4123" @@ -1326,7 +1364,7 @@ collection-visit@^1.0.0: map-visit "^1.0.0" object-visit "^1.0.0" -color-convert@^1.9.0: +color-convert@^1.8.2, color-convert@^1.9.0: version "1.9.2" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" dependencies: @@ -1336,6 +1374,24 @@ color-name@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" +color-name@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + +color-string@^1.4.0: + version "1.5.3" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.5.3.tgz#c9bbc5f01b58b5492f3d6857459cb6590ce204cc" + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + +color@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/color/-/color-1.0.3.tgz#e48e832d85f14ef694fb468811c2d5cfe729b55d" + dependencies: + color-convert "^1.8.2" + color-string "^1.4.0" + commander@2.17.x, commander@^2.8.1: version "2.17.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" @@ -1456,6 +1512,15 @@ core-util-is@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" +cosmiconfig@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-4.0.0.tgz#760391549580bbd2df1e562bc177b13c290972dc" + dependencies: + is-directory "^0.3.1" + js-yaml "^3.9.0" + parse-json "^4.0.0" + require-from-string "^2.0.1" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -1576,10 +1641,18 @@ css@^2.0.0: source-map-resolve "^0.5.1" urix "^0.1.0" +cssdb@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-3.1.0.tgz#e1efa0d8831e9e655cadd499a89266d3565d9697" + cssesc@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-0.1.0.tgz#c814903e45623371a0477b40109aaafbeeaddbb4" +cssesc@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-1.0.1.tgz#ef7bd8d0229ed6a3a7051ff7771265fe7330e0a8" + currently-unhandled@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" @@ -1837,7 +1910,7 @@ ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" -electron-to-chromium@^1.3.47: +electron-to-chromium@^1.3.47, electron-to-chromium@^1.3.61: version "1.3.61" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.61.tgz#a8ac295b28d0f03d85e37326fd16b6b6b17a1795" @@ -2317,6 +2390,10 @@ flat-cache@^1.2.1: graceful-fs "^4.1.2" write "^0.2.1" +flatten@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.2.tgz#dae46a9d78fbe25292258cc1e780a41d95c03782" + flush-write-stream@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" @@ -2725,6 +2802,18 @@ ignore@^4.0.2: version "4.0.6" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" +import-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9" + dependencies: + import-from "^2.1.0" + +import-from@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/import-from/-/import-from-2.1.0.tgz#335db7f2a7affd53aaa471d4b8021dee36b7f3b1" + dependencies: + resolve-from "^3.0.0" + import-local@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" @@ -2748,6 +2837,10 @@ indent-string@^2.1.0: dependencies: repeating "^2.0.0" +indexes-of@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" + indexof@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" @@ -2851,6 +2944,10 @@ is-arrayish@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" +is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" @@ -2903,6 +3000,10 @@ is-descriptor@^1.0.0, is-descriptor@^1.0.2: is-data-descriptor "^1.0.0" kind-of "^6.0.2" +is-directory@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/is-directory/-/is-directory-0.3.1.tgz#61339b6f2475fc772fd9c9d83f5c8575dc154ae1" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" @@ -3045,7 +3146,7 @@ js-tokens@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" -js-yaml@^3.11.0: +js-yaml@^3.11.0, js-yaml@^3.9.0: version "3.12.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" dependencies: @@ -3215,6 +3316,10 @@ lodash._isiterateecall@^3.0.0: version "3.0.9" resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c" +lodash._reinterpolate@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d" + lodash.assign@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/lodash.assign/-/lodash.assign-3.2.0.tgz#3ce9f0234b4b2223e296b8fa0ac1fee8ebca64fa" @@ -3270,6 +3375,19 @@ lodash.restparam@^3.0.0: version "3.6.1" resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805" +lodash.template@^4.2.4: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash.templatesettings "^4.0.0" + +lodash.templatesettings@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz#2b4d4e95ba440d915ff08bc899e4553666713316" + dependencies: + lodash._reinterpolate "~3.0.0" + lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.3, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -3659,6 +3777,12 @@ node-pre-gyp@^0.10.0: semver "^5.3.0" tar "^4" +node-releases@^1.0.0-alpha.11: + version "1.0.0-alpha.11" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.0.0-alpha.11.tgz#73c810acc2e5b741a17ddfbb39dfca9ab9359d8a" + dependencies: + semver "^5.3.0" + nopt@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" @@ -3681,6 +3805,10 @@ normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" +normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + npm-bundled@^1.0.1: version "1.0.5" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.5.tgz#3c1732b7ba936b3a10325aef616467c0ccbcc979" @@ -3727,6 +3855,10 @@ nth-check@~1.0.1: dependencies: boolbase "~1.0.0" +num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" @@ -4097,6 +4229,161 @@ posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" +postcss-attribute-case-insensitive@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-3.0.1.tgz#efd2c40b5d3d27dfab5678073bf652f76eaf4352" + dependencies: + postcss "^6.0.23" + postcss-selector-parser "^4.0.0" + +postcss-color-functional-notation@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-1.0.2.tgz#836fbc5e88a4ebd958ba6a3f9e2dad7792166c9f" + dependencies: + postcss "^6.0.23" + postcss-values-parser "^1.5.0" + +postcss-color-hex-alpha@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-3.0.0.tgz#1e53e6c8acb237955e8fd08b7ecdb1b8b8309f95" + dependencies: + color "^1.0.3" + postcss "^6.0.1" + postcss-message-helpers "^2.0.0" + +postcss-color-mod-function@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-2.4.3.tgz#14a97f5b17a5f19396e9dea7ffcb5be732592baf" + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^6.0.23" + postcss-values-parser "^1.5.0" + +postcss-color-rebeccapurple@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-3.1.0.tgz#ce1269ecc2d0d8bf92aab44bd884e633124c33ec" + dependencies: + postcss "^6.0.22" + postcss-values-parser "^1.5.0" + +postcss-custom-media@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-6.0.0.tgz#be532784110ecb295044fb5395a18006eb21a737" + dependencies: + postcss "^6.0.1" + +postcss-custom-properties@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-7.0.0.tgz#24dc4fbe6d6ed550ea4fd3b11204660e9ffa3b33" + dependencies: + balanced-match "^1.0.0" + postcss "^6.0.18" + +postcss-custom-selectors@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-4.0.1.tgz#781382f94c52e727ef5ca4776ea2adf49a611382" + dependencies: + postcss "^6.0.1" + postcss-selector-matches "^3.0.0" + +postcss-dir-pseudo-class@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-4.0.0.tgz#007dba154a0750cb3095eeae01077088a61dcef5" + dependencies: + postcss "^6.0.22" + postcss-selector-parser "^4.0.0" + +postcss-env-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-1.0.0.tgz#0d81b53b3d789d55d1cac8125ec64f89e916a2f7" + dependencies: + postcss "^6.0.22" + postcss-values-parser "^1.5.0" + +postcss-focus-visible@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-3.0.0.tgz#c105b9d97e83c6a60cf3af34245ae451b326fb54" + dependencies: + postcss "^6.0" + +postcss-focus-within@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-2.0.0.tgz#7ff76ad8b5e9a000c0123d9690a76752c36c0c52" + dependencies: + postcss "^6.0.21" + +postcss-font-family-system-ui@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-family-system-ui/-/postcss-font-family-system-ui-3.0.0.tgz#675fe7a9e029669f05f8dba2e44c2225ede80623" + dependencies: + postcss "^6.0" + +postcss-font-variant@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-3.0.0.tgz#08ccc88f6050ba82ed8ef2cc76c0c6a6b41f183e" + dependencies: + postcss "^6.0.1" + +postcss-gap-properties@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-1.0.0.tgz#2a43bed20d73fc9744e3b869610711ee72db58af" + dependencies: + postcss "^6.0.22" + +postcss-image-set-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-2.0.0.tgz#3f43f25bc242ec1319c4bd879ccfd62ee5256feb" + dependencies: + postcss "^6.0.22" + postcss-values-parser "^1.5.0" + +postcss-initial@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-2.0.0.tgz#72715f7336e0bb79351d99ee65c4a253a8441ba4" + dependencies: + lodash.template "^4.2.4" + postcss "^6.0.1" + +postcss-lab-function@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-1.1.0.tgz#1965cd4cfb380601129f29c59797a0df13463f48" + dependencies: + "@csstools/convert-colors" "^1.4.0" + postcss "^6.0.23" + postcss-values-parser "^1.5.0" + +postcss-load-config@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-load-config/-/postcss-load-config-2.0.0.tgz#f1312ddbf5912cd747177083c5ef7a19d62ee484" + dependencies: + cosmiconfig "^4.0.0" + import-cwd "^2.0.0" + +postcss-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-3.0.0.tgz#6b97943e47c72d845fa9e03f273773d4e8dd6c2d" + dependencies: + loader-utils "^1.1.0" + postcss "^7.0.0" + postcss-load-config "^2.0.0" + schema-utils "^1.0.0" + +postcss-logical@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-1.1.1.tgz#bcabf0638d8aa747743b32bc52f9d90d4a3313d2" + dependencies: + postcss "^6.0.20" + +postcss-media-minmax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-3.0.0.tgz#675256037a43ef40bc4f0760bfd06d4dc69d48d2" + dependencies: + postcss "^6.0.1" + +postcss-message-helpers@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz#a4f2f4fab6e4fe002f0aed000478cdf52f9ba60e" + postcss-modules-extract-imports@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz#66140ecece38ef06bf0d3e355d69bf59d141ea85" @@ -4124,11 +4411,117 @@ postcss-modules-values@^1.3.0: icss-replace-symbols "^1.1.0" postcss "^6.0.1" -postcss-value-parser@^3.3.0: +postcss-nesting@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-6.0.0.tgz#4c45276a065765ec063efe1e4daf75c131518991" + dependencies: + postcss "^6.0.22" + +postcss-overflow-shorthand@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-1.0.1.tgz#f72cc216f770f1ab712863dcce9bc32f774b2b74" + dependencies: + postcss "^6.0.22" + +postcss-page-break@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-1.0.0.tgz#09a63b6e03db092d38569b33dcba42a343ace60b" + dependencies: + postcss "^6.0.16" + +postcss-place@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-3.0.1.tgz#95b0aeedd1302fe898c77ef6392cd1cfa7b23dd8" + dependencies: + postcss "^6.0.22" + postcss-values-parser "^1.5.0" + +postcss-preset-env@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-5.3.0.tgz#568939a1c03e950ced2bdfe32822c316ac7d0b7f" + dependencies: + autoprefixer "^8.6.5" + browserslist "^3.2.8" + caniuse-lite "^1.0.30000865" + cssdb "^3.1.0" + postcss "^6.0.23" + postcss-attribute-case-insensitive "^3.0.1" + postcss-color-functional-notation "^1.0.2" + postcss-color-hex-alpha "^3.0.0" + postcss-color-mod-function "^2.4.3" + postcss-color-rebeccapurple "^3.1.0" + postcss-custom-media "^6.0.0" + postcss-custom-properties "^7.0.0" + postcss-custom-selectors "^4.0.1" + postcss-dir-pseudo-class "^4.0.0" + postcss-env-function "^1.0.0" + postcss-focus-visible "^3.0.0" + postcss-focus-within "^2.0.0" + postcss-font-family-system-ui "^3.0.0" + postcss-font-variant "^3.0.0" + postcss-gap-properties "^1.0.0" + postcss-image-set-function "^2.0.0" + postcss-initial "^2.0.0" + postcss-lab-function "^1.1.0" + postcss-logical "^1.1.1" + postcss-media-minmax "^3.0.0" + postcss-nesting "^6.0.0" + postcss-overflow-shorthand "^1.0.1" + postcss-page-break "^1.0.0" + postcss-place "^3.0.1" + postcss-pseudo-class-any-link "^5.0.0" + postcss-replace-overflow-wrap "^2.0.0" + postcss-selector-matches "^3.0.1" + postcss-selector-not "^3.0.1" + +postcss-pseudo-class-any-link@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-5.0.0.tgz#9979a55a75956c402c5d270a667632cf8ee8eccb" + dependencies: + postcss "^6.0.22" + postcss-selector-parser "^4.0.0" + +postcss-replace-overflow-wrap@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-2.0.0.tgz#794db6faa54f8db100854392a93af45768b4e25b" + dependencies: + postcss "^6.0.1" + +postcss-selector-matches@^3.0.0, postcss-selector-matches@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-3.0.1.tgz#e5634011e13950881861bbdd58c2d0111ffc96ab" + dependencies: + balanced-match "^0.4.2" + postcss "^6.0.1" + +postcss-selector-not@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-3.0.1.tgz#2e4db2f0965336c01e7cec7db6c60dff767335d9" + dependencies: + balanced-match "^0.4.2" + postcss "^6.0.1" + +postcss-selector-parser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-4.0.0.tgz#50c6570f40579036d8e63f23e6c0626fe5743527" + dependencies: + cssesc "^1.0.1" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss-value-parser@^3.2.3, postcss-value-parser@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz#87f38f9f18f774a4ab4c8a232f5c5ce8872a9d15" -postcss@^6.0.1, postcss@^6.0.23: +postcss-values-parser@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-1.5.0.tgz#5d9fa63e2bcb0179ce48f3235303765eb89f3047" + dependencies: + flatten "^1.0.2" + indexes-of "^1.0.1" + uniq "^1.0.1" + +postcss@^6.0, postcss@^6.0.1, postcss@^6.0.16, postcss@^6.0.18, postcss@^6.0.20, postcss@^6.0.21, postcss@^6.0.22, postcss@^6.0.23: version "6.0.23" resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.23.tgz#61c82cc328ac60e677645f979054eb98bc0e3324" dependencies: @@ -4136,6 +4529,14 @@ postcss@^6.0.1, postcss@^6.0.23: source-map "^0.6.1" supports-color "^5.4.0" +postcss@^7.0.0, postcss@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.2.tgz#7b5a109de356804e27f95a960bef0e4d5bc9bb18" + dependencies: + chalk "^2.4.1" + source-map "^0.6.1" + supports-color "^5.4.0" + prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -4468,6 +4869,10 @@ require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" +require-from-string@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + require-main-filename@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" @@ -4756,6 +5161,12 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" +simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + dependencies: + is-arrayish "^0.3.1" + slice-ansi@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-1.0.0.tgz#044f1a49d8842ff307aad6b505ed178bd950134d" @@ -5254,6 +5665,10 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^0.4.3" +uniq@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" + unique-filename@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3"