From 1adaadb0fac1104296da297a2cfc1b91e5e9f7c2 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Sun, 9 Feb 2020 13:52:37 -0800 Subject: [PATCH] 3.11.0 (#3468) * Move transpilation from Babel to TypeScript * Update tests to Mocha / Chai / Headless Chrome * Remove old Jasmine files * Fix plugin tests cross-platform * Add new build * Fix errors for Node 8 * Remove PhantomJS references and libs * Remove unnecessary less-node file caching * Add browser benchmark comparison test * Add browser benchmark comparison test * Dist files --- .travis.yml | 20 - CONTRIBUTING.md | 4 +- Gruntfile.js | 234 +- appveyor.yml | 2 + benchmark/benchmark.css | 5323 ++++ benchmark/browseroptions.js | 4 + benchmark/browserspec.js | 3 + bin/lessc | 24062 +++++++-------- build/rollup.js | 59 +- dist/less.cjs.js | 23031 +++++++-------- dist/less.js | 24164 +++++++--------- dist/less.min.js | 6 +- dist/less.min.js.map | 2 +- lib/less-node/file-manager.js | 59 +- lib/less/index.js | 2 +- lib/less/less-error.js | 24 +- lib/lessc.js | 23 +- package.json | 28 +- test/browser/common.js | 60 +- test/browser/generator/benchmark.config.js | 50 + test/browser/generator/generate.js | 78 + test/browser/generator/runner.config.js | 180 + test/browser/generator/runner.js | 2 + test/browser/generator/template.js | 83 + test/browser/onload.js | 13 - test/browser/runner-browser-options.js | 6 - test/browser/runner-browser-spec.js | 2 +- test/browser/runner-main-spec.js | 2 +- test/browser/runner-modify-vars-spec.js | 2 +- test/browser/runner-production-spec.js | 2 +- test/browser/test-runner-template.tmpl | 105 - test/browser/vendor/boot.js | 148 - test/browser/vendor/jasmine-jsreporter.js | 391 - test/browser/vendor/promise.js | 2 - test/css/comments.css | 2 +- test/css/css-3.css | 10 +- test/css/css-guards.css | 2 +- test/css/debug/linenumbers-all.css | 10 +- test/css/debug/linenumbers-comments.css | 10 +- test/css/debug/linenumbers-mediaquery.css | 10 +- test/css/extend-chaining.css | 6 +- test/css/extend-media.css | 2 +- test/css/extend-nest.css | 2 +- test/css/filemanagerPlugin/filemanager.css | 2 +- test/css/functions-each.css | 2 +- test/css/import-once.css | 4 +- test/css/import-reference-issues.css | 2 +- test/css/import-reference.css | 12 +- test/css/import.css | 2 +- test/css/javascript.css | 2 +- test/css/legacy/legacy.css | 2 +- test/css/math/parens-division/mixins-args.css | 2 +- test/css/math/parens-division/parens.css | 2 +- test/css/math/strict-legacy/mixins-args.css | 2 +- test/css/math/strict-legacy/parens.css | 2 +- test/css/math/strict/mixins-args.css | 2 +- test/css/math/strict/parens.css | 2 +- test/css/media.css | 28 +- test/css/merge.css | 20 +- test/css/mixins-guards.css | 12 +- test/css/mixins.css | 4 +- test/css/namespacing/namespacing-3.css | 2 +- test/css/namespacing/namespacing-4.css | 2 +- test/css/no-strict-math/mixins-guards.css | 2 +- test/css/permissive-parse.css | 2 +- test/css/plugin.css | 18 +- .../css/postProcessorPlugin/postProcessor.css | 4 +- test/css/preProcessorPlugin/preProcessor.css | 2 +- test/css/selectors.css | 4 +- test/css/variables.css | 2 +- test/css/visitorPlugin/visitor.css | 2 +- test/less/comments.less | 2 +- test/less/css-3.less | 10 +- test/less/css-guards.less | 4 +- test/less/debug/import/test.less | 4 +- test/less/debug/linenumbers.less | 6 +- .../less/errors/color-func-invalid-color.less | 2 +- test/less/errors/color-func-invalid-color.txt | 2 +- test/less/errors/plugin-1.txt | 4 +- test/less/errors/plugin-2.txt | 3 +- test/less/errors/plugin-3.txt | 3 +- test/less/errors/property-ie5-hack.less | 2 +- test/less/extend-chaining.less | 6 +- test/less/extend-media.less | 2 +- test/less/extend-nest.less | 2 +- test/less/filemanagerPlugin/filemanager.less | 2 +- test/less/functions-each.less | 2 +- test/less/import-reference-issues.less | 4 +- .../global-scope-import.less | 4 +- .../global-scope-nested.less | 2 +- test/less/import-reference.less | 2 +- test/less/import/import-reference.less | 2 +- test/less/import/import-test-f.less | 2 +- test/less/javascript.less | 2 +- test/less/legacy/legacy.less | 2 +- .../math/parens-division/mixins-args.less | 8 +- test/less/math/parens-division/parens.less | 2 +- test/less/math/strict-legacy/mixins-args.less | 8 +- test/less/math/strict-legacy/parens.less | 2 +- test/less/math/strict/mixins-args.less | 8 +- test/less/math/strict/parens.less | 2 +- test/less/media.less | 18 +- test/less/merge.less | 20 +- test/less/mixins-guards.less | 16 +- test/less/mixins-important.less | 6 +- test/less/mixins.less | 4 +- test/less/namespacing/namespacing-3.less | 2 +- test/less/namespacing/namespacing-4.less | 2 +- test/less/namespacing/namespacing-5.less | 4 +- test/less/no-strict-math/mixins-guards.less | 4 +- test/less/permissive-parse.less | 2 +- test/less/plugin.less | 18 +- .../postProcessorPlugin/postProcessor.less | 4 +- .../less/preProcessorPlugin/preProcessor.less | 2 +- test/less/selectors.less | 2 +- test/less/sourcemaps/imported.css | 2 +- test/less/variables.less | 2 +- test/less/visitorPlugin/visitor.less | 2 +- 118 files changed, 37419 insertions(+), 41171 deletions(-) create mode 100644 benchmark/benchmark.css create mode 100644 benchmark/browseroptions.js create mode 100644 benchmark/browserspec.js mode change 100644 => 100755 bin/lessc create mode 100644 test/browser/generator/benchmark.config.js create mode 100644 test/browser/generator/generate.js create mode 100644 test/browser/generator/runner.config.js create mode 100644 test/browser/generator/runner.js create mode 100644 test/browser/generator/template.js delete mode 100644 test/browser/onload.js delete mode 100644 test/browser/test-runner-template.tmpl delete mode 100644 test/browser/vendor/boot.js delete mode 100644 test/browser/vendor/jasmine-jsreporter.js delete mode 100644 test/browser/vendor/promise.js diff --git a/.travis.yml b/.travis.yml index 7fd765c54..4079a45d5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,33 +1,13 @@ language: node_js -cache: - directories: - - travis-phantomjs node_js: - "12" - "10" - "8" -before_install: - # from https://github.com/travis-ci/travis-ci/issues/3225#issuecomment-177592725 - # and also from https://github.com/travis-ci/travis-ci/issues/3225#issuecomment-200965782 - - phantomjs --version - - export PATH=$PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH - - phantomjs --version - # Clear cache and download new copy of PhantomJS if the current version doesn't match 2.1.1. - - "if [ $(phantomjs --version) != '2.1.1' ]; then rm -rf $PWD/travis-phantomjs; mkdir -p $PWD/travis-phantomjs; fi" - - "if [ $(phantomjs --version) != '2.1.1' ]; then wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2; fi" - - "if [ $(phantomjs --version) != '2.1.1' ]; then tar -xvf $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis-phantomjs; fi" - - phantomjs --version install: - npm install -g grunt-cli - # node 0.10 & 0.12 have race condition issues when running custom install scripts - # this can cause phantomjs-prebuilt install script to fail with the error: - # - # Seems related to: https://github.com/npm/npm/issues/8152 - # using solves this. - travis_retry npm install env: global: - - PHANTOMJS_CDNURL=http://cnpmjs.org/downloads - secure: TrNVruWYaUK5ALga1y7wRY+MLjWJECUSCsBmKW5EUmIevOUxqHWu7M89FANKxstEeFRRAGH3QJbloRxnzIgh0U0ah5npE9XA1bYXGO5khoXeIyk7pNRfjIo8aEnJH1Vp8vWA6J6ovxdJ7lCFKEGvGKxGde50knVl7KFVVULlX2U= - secure: Rzh+CEI7YRvvVkOruPE8Z0dkU0s13V6b6cpqbN72vxbJl/Jm5PUZkjTFJdkWJrW3ErhCKX6EC7XdGvrclqEA9WAqKzrecqCJYqTnw4MwqiAj6F9wqE/BqhoWg4xPxm0MK/7eJMvLCgjNpe+gc1CaeFJZkLSNWn6nOFke+vVlf9Q= sudo: false diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aa57b3b17..c81ecc15f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -35,13 +35,13 @@ _Pull requests are encouraged!_ * Start by adding a feature request to get feedback and see how your idea is received. * If your pull request solves an existing issue, but it's different in some way, _please create a new issue_ and make sure to discuss it with the core contributors. Otherwise you risk your hard work being rejected. * Do not change the **./dist/** folder, we do this when releasing -* _Please add tests_ for your work. Tests are invoked using `npm test` command. It will run both node.js tests and browser ([PhantomJS](http://phantomjs.org/)) tests. +* _Please add tests_ for your work. Tests are invoked using `npm test` command. It will run both node.js tests and browser (Headless Chrome) tests. ### Coding Standards * Always use spaces, never tabs * End lines in semi-colons. -* Loosely aim towards jsHint standards +* Loosely aim towards eslint standards ## Developing diff --git a/Gruntfile.js b/Gruntfile.js index f56e10435..9d40d3862 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -186,7 +186,7 @@ module.exports = function(grunt) { const nodeVersion = semver.major(process.versions.node); let scriptRuntime = 'node'; if (nodeVersion < 8) { - scriptRuntime = path.resolve(path.join('node_modules', '.bin', 'babel-node')) + ' --presets=@babel/env'; + scriptRuntime = path.resolve(path.join('node_modules', '.bin', 'ts-node')); } // Project configuration. @@ -206,21 +206,30 @@ module.exports = function(grunt) { command: [ scriptRuntime + " build/rollup.js --lessc --out=./tmp/lessc", scriptRuntime + " build/rollup.js --node --out=./tmp/less.cjs.js", - scriptRuntime + " build/rollup.js --browser --out=./test/browser/less.min.js" + scriptRuntime + " build/rollup.js --browser --out=./tmp/browser/less.min.js" ].join(" && ") }, testcjs: { command: scriptRuntime + " build/rollup.js --node --out=./tmp/less.cjs.js" }, testbrowser: { - command: scriptRuntime + " build/rollup.js --browser --out=./test/browser/less.min.js" + command: scriptRuntime + " build/rollup.js --browser --out=./tmp/browser/less.min.js" }, test: { command: "node test/index.js" }, + generatebrowser: { + command: 'node test/browser/generator/generate.js' + }, + runbrowser: { + command: 'node test/browser/generator/runner.js' + }, benchmark: { command: "node benchmark/index.js" }, + benchmarkbrowser: { + command: "node test/browser/generator/runner.js benchmark" + }, opts: { // test running with all current options (using `opts` since `options` means something already) command: [ @@ -277,201 +286,7 @@ module.exports = function(grunt) { } }, - jasmine: { - options: { - keepRunner: true, - host: "http://localhost:8081/", - polyfills: [ - "./node_modules/phantomjs-polyfill-object-assign/object-assign-polyfill.js", - "test/browser/vendor/promise.js" - ], - vendor: [ - "test/browser/vendor/jasmine-jsreporter.js", - "test/browser/common.js", - "test/browser/less.min.js" - ], - template: "test/browser/test-runner-template.tmpl" - }, - main: { - // src is used to build list of less files to compile - src: [ - "test/less/*.less", - "!test/less/plugin-preeval.less", // uses ES6 syntax - // Don't test NPM import, obviously - "!test/less/plugin-module.less", - "!test/less/import-module.less", - "!test/less/javascript.less", - "!test/less/urls.less", - "!test/less/empty.less" - ], - options: { - helpers: "test/browser/runner-main-options.js", - specs: "test/browser/runner-main-spec.js", - outfile: "tmp/browser/test-runner-main.html" - } - }, - legacy: { - src: ["test/less/legacy/*.less"], - options: { - helpers: "test/browser/runner-legacy-options.js", - specs: "test/browser/runner-legacy-spec.js", - outfile: "tmp/browser/test-runner-legacy.html" - } - }, - strictUnits: { - src: ["test/less/strict-units/*.less"], - options: { - helpers: "test/browser/runner-strict-units-options.js", - specs: "test/browser/runner-strict-units-spec.js", - outfile: "tmp/browser/test-runner-strict-units.html" - } - }, - errors: { - src: [ - "test/less/errors/*.less", - "!test/less/errors/javascript-error.less", - "test/browser/less/errors/*.less" - ], - options: { - timeout: 20000, - helpers: "test/browser/runner-errors-options.js", - specs: "test/browser/runner-errors-spec.js", - outfile: "tmp/browser/test-runner-errors.html" - } - }, - noJsErrors: { - src: ["test/less/no-js-errors/*.less"], - options: { - helpers: "test/browser/runner-no-js-errors-options.js", - specs: "test/browser/runner-no-js-errors-spec.js", - outfile: "tmp/browser/test-runner-no-js-errors.html" - } - }, - browser: { - src: [ - "test/browser/less/*.less", - "test/browser/less/plugin/*.less" - ], - options: { - helpers: "test/browser/runner-browser-options.js", - specs: "test/browser/runner-browser-spec.js", - outfile: "tmp/browser/test-runner-browser.html" - } - }, - relativeUrls: { - src: ["test/browser/less/relative-urls/*.less"], - options: { - helpers: "test/browser/runner-relative-urls-options.js", - specs: "test/browser/runner-relative-urls-spec.js", - outfile: "tmp/browser/test-runner-relative-urls.html" - } - }, - rewriteUrls: { - src: ["test/browser/less/rewrite-urls/*.less"], - options: { - helpers: "test/browser/runner-rewrite-urls-options.js", - specs: "test/browser/runner-rewrite-urls-spec.js", - outfile: "tmp/browser/test-runner-rewrite-urls.html" - } - }, - rootpath: { - src: ["test/browser/less/rootpath/*.less"], - options: { - helpers: "test/browser/runner-rootpath-options.js", - specs: "test/browser/runner-rootpath-spec.js", - outfile: "tmp/browser/test-runner-rootpath.html" - } - }, - rootpathRelative: { - src: ["test/browser/less/rootpath-relative/*.less"], - options: { - helpers: "test/browser/runner-rootpath-relative-options.js", - specs: "test/browser/runner-rootpath-relative-spec.js", - outfile: "tmp/browser/test-runner-rootpath-relative.html" - } - }, - rootpathRewriteUrls: { - src: ["test/browser/less/rootpath-rewrite-urls/*.less"], - options: { - helpers: - "test/browser/runner-rootpath-rewrite-urls-options.js", - specs: "test/browser/runner-rootpath-rewrite-urls-spec.js", - outfile: - "tmp/browser/test-runner-rootpath-rewrite-urls.html" - } - }, - production: { - src: ["test/browser/less/production/*.less"], - options: { - helpers: "test/browser/runner-production-options.js", - specs: "test/browser/runner-production-spec.js", - outfile: "tmp/browser/test-runner-production.html" - } - }, - modifyVars: { - src: ["test/browser/less/modify-vars/*.less"], - options: { - helpers: "test/browser/runner-modify-vars-options.js", - specs: "test/browser/runner-modify-vars-spec.js", - outfile: "tmp/browser/test-runner-modify-vars.html" - } - }, - globalVars: { - src: ["test/browser/less/global-vars/*.less"], - options: { - helpers: "test/browser/runner-global-vars-options.js", - specs: "test/browser/runner-global-vars-spec.js", - outfile: "tmp/browser/test-runner-global-vars.html" - } - }, - postProcessorPlugin: { - src: ["test/less/postProcessorPlugin/*.less"], - options: { - helpers: [ - "test/plugins/postprocess/index.js", - "test/browser/runner-postProcessorPlugin-options.js" - ], - specs: "test/browser/runner-postProcessorPlugin.js", - outfile: - "tmp/browser/test-runner-post-processor-plugin.html" - } - }, - preProcessorPlugin: { - src: ["test/less/preProcessorPlugin/*.less"], - options: { - helpers: [ - "test/plugins/preprocess/index.js", - "test/browser/runner-preProcessorPlugin-options.js" - ], - specs: "test/browser/runner-preProcessorPlugin.js", - outfile: "tmp/browser/test-runner-pre-processor-plugin.html" - } - }, - visitorPlugin: { - src: ["test/less/visitorPlugin/*.less"], - options: { - helpers: [ - "test/plugins/visitor/index.js", - "test/browser/runner-VisitorPlugin-options.js" - ], - specs: "test/browser/runner-VisitorPlugin.js", - outfile: "tmp/browser/test-runner-visitor-plugin.html" - } - }, - filemanagerPlugin: { - src: ["test/less/filemanagerPlugin/*.less"], - options: { - helpers: [ - "test/plugins/filemanager/index.js", - "test/browser/runner-filemanagerPlugin-options.js" - ], - specs: "test/browser/runner-filemanagerPlugin.js", - outfile: "tmp/browser/test-runner-filemanager-plugin.html" - } - } - }, - - "saucelabs-jasmine": sauceJobs, + "saucelabs-mocha": sauceJobs, // Clean the version of less built for the tests clean: { @@ -506,13 +321,13 @@ module.exports = function(grunt) { grunt.registerTask("browsertest", [ "browsertest-lessjs", "connect", - "jasmine" + "shell:runbrowser" ]); // setup a web server to run the browser tests in a browser rather than phantom grunt.registerTask("browsertest-server", [ "browsertest-lessjs", - "jasmine::build", + "shell:generatebrowser", "connect::keepalive" ]); @@ -530,13 +345,13 @@ module.exports = function(grunt) { grunt.registerTask("sauce", [ "browsertest-lessjs", - "jasmine::build", + "shell:generatebrowser", "connect", "sauce-after-setup" ]); grunt.registerTask("sauce-after-setup", [ - "saucelabs-jasmine:all", + "saucelabs-mocha:all", "clean:sauce_log" ]); @@ -548,14 +363,12 @@ module.exports = function(grunt) { "shell:opts", "shell:plugin", "connect", - "jasmine" + "shell:runbrowser" ]; if ( isNaN(Number(process.env.TRAVIS_PULL_REQUEST, 10)) && - Number(process.env.TRAVIS_NODE_VERSION) === 4 && - (process.env.TRAVIS_BRANCH === "master" || - process.env.TRAVIS_BRANCH === "3.x") + (process.env.TRAVIS_BRANCH === "master") ) { testTasks.push("force:on"); testTasks.push("sauce-after-setup"); @@ -586,8 +399,15 @@ module.exports = function(grunt) { ]); // Run benchmark - grunt.registerTask("benchmark", [ + grunt.registerTask("benchmark-node", [ "shell:testcjs", "shell:benchmark" ]); + + // Run all browser tests + grunt.registerTask("benchmark", [ + "browsertest-lessjs", + "connect", + "shell:benchmarkbrowser" + ]); }; diff --git a/appveyor.yml b/appveyor.yml index 834e6fb61..5617ebb76 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -13,6 +13,8 @@ install: # # Seems related to: https://github.com/npm/npm/issues/8152 # using solves this. + + # change now that we're not using phantomjs? - appveyor-retry call npm install # Grunt-specific stuff. diff --git a/benchmark/benchmark.css b/benchmark/benchmark.css new file mode 100644 index 000000000..aca398b03 --- /dev/null +++ b/benchmark/benchmark.css @@ -0,0 +1,5323 @@ +@charset "utf-8"; +div.browse { + margin: 0 0 20px; +} +div.browse.class { + padding: 0; +} +div.browse div.header { + padding: 10px 10px 9px; + text-align: left; + background: #f01 url('/images/panel_header_bg.png') repeat-x top left; + border-bottom: 1px solid #a8000b; + line-height: 1; + height: 18px; + color: #eee; +} +div.browse div.header h3 { + font-size: 16px; + margin: 0; + color: #fff; +} +div.browse div.header span.filter { + float: left; + display: block; + overflow: hidden; + position: relative; + z-index: 5; +} +div.browse div.header span.filter a { + margin: 0 1px 0 0; + display: block; + float: left; + padding: 0 8px; + height: 18px; + font-weight: bold; + font-size: 10px; + line-height: 18px; + text-transform: uppercase; + background: url('/images/transparent_backgrounds/black_50.png'); + color: #eee; + text-decoration: none; + position: relative; + z-index: 3; +} +div.browse div.header span.filter a .active { + background: #fff; + color: #000; + z-index: 4; +} +div.browse div.header span.filter a .active :hover { + color: #000; +} +div.browse div.header span.filter a :hover { + color: #fff; +} +div.browse div.header span.filter a :last-child { + margin-right: 0; +} +div.browse div.header span.filter.dropdown { + margin: 0; + position: relative; + overflow: visible; +} +div.browse div.header span.filter.dropdown a { + background: #fff; + color: #000; + margin: 0; + position: relative; + padding-right: 25px; +} +div.browse div.header span.filter.dropdown a img { + float: left; + margin: 4px 5px 0 0; +} +div.browse div.header span.filter.dropdown a b.arrow { + float: right; + display: block; + height: 0; + width: 0; + border: 5px solid transparent; + border-top: 5px solid #000; + border-bottom: none; + position: absolute; + top: 6px; + right: 10px; +} +div.browse div.header span.filter.dropdown a :hover { + background: #000; + color: #fff; +} +div.browse div.header span.filter.dropdown a :hover b.arrow { + border-top: 5px solid #fff; +} +div.browse div.header span.filter.dropdown ul { + position: absolute; + top: 100%; + left: 0; + margin: 1px 0 0; + padding: 0; + background: #fff; +} +div.browse div.header span.filter.dropdown ul li { + list-style: none; + display: block; + padding: 0; + margin: 0; +} +div.browse div.header span.filter.dropdown ul li a { + display: block; + height: 18px; + line-height: 18px; + color: #000; + font-size: 10px; + text-transform: uppercase; + background: transparent; + border-bottom: 1px solid #f1f1f1; + float: none; + margin: 0; + white-space: nowrap; +} +div.browse div.header span.filter.dropdown ul li a :hover { + background: url('/images/transparent_backgrounds/accent_colour_25.png'); + color: #000; +} +div.browse div.header span.filter.dropdown ul li :last-child a { + border: none; +} +div.browse div.header span.filter.dropdown.sort { + float: left; + margin: 0 0 0 10px; +} +div.browse div.header span.filter.dropdown.localisation { + float: left; + margin: 0 0 0 10px; +} +div.browse div.header a.more { + float: right; + color: #fff; + font-size: 14px; + font-weight: bold; + position: relative; + top: 2px; +} +div.browse div.header a.more :hover { + text-decoration: none; +} +div.browse > ul { + margin: 0; + background: #fff; + padding: 10px 0 0 10px; + position: relative; +} +div.browse > ul li { + display: block; + float: left; + list-style: none; + margin: 0 10px 10px 0; + padding: 5px; + position: relative; + background: #fff; + width: 130px; + border: 1px solid #f7f7f7; +} +div.browse > ul li a.remove { + position: absolute; + height: 16px; + width: 16px; + padding: 3px; + background: #000; + display: none; + z-index: 3; + top: -8px; + right: -8px; +} +div.browse > ul li a.remove img { + vertical-align: middle; +} +div.browse > ul li div.thumbnail { + position: relative; + z-index: 3; +} +div.browse > ul li div.thumbnail .marker { + position: absolute; + padding: 2px; + z-index: 3; + background: url('/images/transparent_backgrounds/white_75.png'); + height: 12px; + width: 12px; +} +div.browse > ul li div.thumbnail .marker.coupon { + height: auto; + width: auto; + top: 10px; + right: -3px; + padding: 0; + background: transparent; + overflow: hidden; + position: absolute; +} +div.browse > ul li div.thumbnail .marker.coupon b { + display: block; + height: 0; + width: 0; + border: 14px solid transparent; + border-top: 14px solid #000; + border-bottom: none; + border-right: none; + float: left; +} +div.browse > ul li div.thumbnail .marker.coupon span { + color: #fff; + font-size: 10px; + font-weight: bold; + text-transform: uppercase; + height: 14px; + line-height: 14px; + display: block; + padding: 0 4px 0 2px; + background: #000; + margin: 0 0 0 14px; +} +div.browse > ul li div.thumbnail .marker.video { + position: absolute; + left: 50%; + top: 50%; + background: #fff; + width: 10px; + height: 10px; +} +div.browse > ul li div.thumbnail .marker.video b { + display: block; + width: 0; + height: 0; + border: 5px solid transparent; + border-left: 10px solid #000; + border-right: none; +} +div.browse > ul li div.thumbnail .marker.endorsed_by_me { + background: none; + padding: 0; + right: 0; + bottom: -32px; + background: #fff; +} +div.browse > ul li div.thumbnail a.thumbnail { + display: block; + overflow: hidden; + position: relative; + text-align: center; +} +div.browse > ul li div.thumbnail a.thumbnail img { + position: relative; + display: block; + margin: auto; +} +div.browse > ul li div.text { + margin: 3px 0 0; + display: block; +} +div.browse > ul li div.text a { + text-decoration: none; +} +div.browse > ul li div.text a.title { + display: block; + text-decoration: none; + font-weight: bold; + font-size: 12px; + line-height: 16px; + white-space: nowrap; + height: 16px; + overflow: hidden; +} +div.browse > ul li div.text a.title :before { + display: block; + height: 32px; + width: 20px; + content: " "; + float: right; + right: -15px; + top: -8px; + background: #fff; + position: relative; + z-index: 1; +} +div.browse > ul li div.text small { + font-size: 11px; + line-height: 13px; + color: #eee; + display: block; + height: 13px; + overflow: hidden; + white-space: nowrap; +} +div.browse > ul li div.text small a { + font-weight: bold; +} +div.browse > ul li div.text small :before { + display: block; + height: 32px; + width: 20px; + content: " "; + float: right; + right: -15px; + top: -8px; + background: #fff; + position: relative; + z-index: 1; +} +div.browse > ul li :hover { + background: #000; +} +div.browse > ul li :hover a.remove { + display: block; +} +div.browse > ul li :hover div.thumbnail a.marker.remove b, +div.browse > ul li :hover div.thumbnail a.marker.video b { + display: inline-block; +} +div.browse > ul li :hover div.text a { + color: #fff; +} +div.browse > ul li :hover div.text a.title:before { + background: #000; +} +div.browse > ul li :hover div.text small { + color: #bfbfbf; +} +div.browse > ul li :hover div.text small :before { + background: #000; +} +div.browse > ul li :hover div.footer a { + color: #fff; +} +div.browse > ul > li.ad div.thumbnail a.thumbnail { + width: 130px; + height: 97px; +} +div.browse > ul > li.ad div.thumbnail a.thumbnail img { + width: 100%; + height: 100%; +} +div.browse > ul > li.brand div.thumbnail a.thumbnail { + width: 120px; + height: 87px; + padding: 5px; + background: #fff; +} +div.browse > ul > li.brand div.thumbnail a.thumbnail img { + max-width: 120px; + max-height: 87px; +} +div.browse > ul li.paginate { + margin-bottom: 0; +} +div.browse > ul li.paginate a { + display: block; + position: relative; + text-decoration: none; + height: 131px; +} +div.browse > ul li.paginate a div.arrow { + background: #81c153 url('/images/button_bg.png') repeat-x left top; + border: 1px solid #000000; + height: 44px; + width: 44px; + margin: 0 auto; + position: relative; + top: 32px; +} +div.browse > ul li.paginate a div.arrow b { + text-indent: -9000px; + display: block; + border: 10px solid transparent; + width: 0; + height: 0; + position: relative; + top: 12px; +} +div.browse > ul li.paginate a div.label { + position: absolute; + bottom: 5px; + left: 0; + right: 0; + line-height: 13px; + color: #000000; + text-decoration: none; + font-weight: bold; + font-size: 12px; + text-align: center; +} +div.browse > ul li.paginate a :hover div.arrow { + background: #abd56e url('/images/button_bg.png') repeat-x left -44px; +} +div.browse > ul li.paginate :hover { + background: transparent; +} +div.browse > ul li.paginate.previous a div b { + border-right: 15px solid #fff; + border-left: none; + left: 12px; +} +div.browse > ul li.paginate.next a div b { + border-left: 15px solid #fff; + border-right: none; + left: 16px; +} +div.browse > div.footer { + padding: 9px 10px 10px; + background: #f2f2f2; + overflow: hidden; + border-top: 1px solid #eee; +} +div.browse > div.footer div.info { + float: left; + color: #eee; +} +div.browse > div.footer div.info strong { + color: #000; + font-weight: normal; +} +div.browse > div.footer div.pagination { + float: right; +} +div.browse > div.footer div.pagination > * { + display: inline-block; + line-height: 1; + padding: 0 6px; + line-height: 18px; + height: 18px; + background: #fff; + text-decoration: none; + font-weight: bold; + font-size: 10px; + text-transform: uppercase; +} +div.browse > div.footer div.pagination a { + color: #eee; +} +div.browse > div.footer div.pagination a:hover { + color: #000; +} +div.browse > div.footer div.pagination span.disabled { + color: #eee; +} +div.browse > div.footer div.pagination span.current { + color: #fff; + background: #f01; + border: none; +} +div.browse > div.footer div.pagination span.current:hover { + color: #fff; +} +div.browse.with_categories { + margin: 0 0 0 160px; +} +/* Browse List */ +div.browse.list > ul { + margin: 0; + min-height: 320px; + padding: 10px 0 0 10px; + overflow: hidden; +} +div.browse.list > ul > li { + display: block; + list-style: none; + margin: 0 10px 10px 0; + padding: 5px; + position: relative; + line-height: normal; +} +div.browse.list > ul > li .marker { + position: absolute; + padding: 2px; + background: url('/images/transparent_backgrounds/white_75.png'); +} +div.browse.list > ul > li .marker img { + height: 12px; + width: 12px; +} +div.browse.list > ul > li img.marker { + height: 12px; + width: 12px; +} +div.browse.list > ul > li span.marker.new { + color: black; + left: -5px; + top: -5px; + background: none; + background-color: #8f2e2e; + line-height: 1; + padding: 2px 5px; + font-weight: bold; +} +div.browse.list > ul > li a.marker.media_type { + display: inline-block; + text-decoration: none; + top: 39px; + left: 8px; + font-size: 10px; +} +div.browse.list > ul > li a.marker.media_type b { + font-weight: normal; + margin: 0 0 0 2px; + line-height: 1; + display: none; +} +div.browse.list > ul > li a.marker.media_type img { + vertical-align: middle; +} +div.browse.list > ul > li a.thumbnail { + float: left; + width: 68px; + display: block; + overflow: hidden; + border: 1px solid #eee; +} +div.browse.list > ul > li a.thumbnail :hover { + border-color: #000; +} +div.browse.list > ul > li span.title_brand { + display: block; + margin: 0 0 2px 75px; +} +div.browse.list > ul > li span.title_brand a { + margin: 0; + display: inline; +} +div.browse.list > ul > li span.title_brand a.brand_name { + font-weight: normal; + font-size: 12px; +} +div.browse.list > ul > li a.ad_title { + font-weight: bold; + font-size: 14px; + margin: 0 0 0 75px; + display: block; +} +div.browse.list > ul > li a.brand_name { + font-weight: bold; + font-size: 14px; + margin: 0 0 0 75px; + display: block; +} +div.browse.list > ul > li small { + display: block; + color: #eee; + margin: 0 0 0 75px; + font-size: 12px; +} +div.browse.list > ul > li small.brand_name { + display: inline; + margin: 0; +} +div.browse.list > ul > li ul.chart { + margin: 0 0 0 80px; + height: 39px; +} +div.browse.list > ul > li ul.networks { + margin: 3px 0 0 75px; + padding: 0; + overflow: hidden; +} +div.browse.list > ul > li ul.networks li { + display: block; + float: left; + margin: 0 5px 0 0; + line-height: 1; +} +div.browse.list > ul > li div.points { + display: none; + font-size: 12px; + text-align: right; +} +div.browse.list > ul > li div.points label { + color: #eee; +} +div.browse.list > ul > li a.remove { + bottom: -3px; + right: -3px; +} +div.browse.list > ul li.ad a.thumbnail { + height: 51px; +} +div.browse.list > ul li.ad span.title_brand small.brand_name { + display: block; +} +div.browse.list > ul li.brand a.thumbnail { + height: 68px; +} +div.browse.list.cols_2 > ul > li { + width: 285px; + float: left; +} +div.browse.list.cols_2 > ul > li :hover { + background: #fff; +} +div.browse.ads.list > ul > li { + height: 53px; +} +div.browse.ads.list > ul > li a.thumbnail { + height: 51px; +} +div.browse.brands.list > ul > li { + height: 68px; +} +div.browse.brands.list > ul > li a.thumbnail { + height: 66px; +} +/* Categories List */ +#categories { + margin: 40px 0 0; + width: 160px; + float: left; + position: relative; + z-index: 1; +} +#categories ul { + margin: 0; + padding: 10px 0 0; +} +#categories ul li { + list-style: none; + margin: 0; + padding: 0; + font-size: 14px; +} +#categories ul li a { + color: #eee; + display: block; + padding: 5px 10px 5px 15px; + text-decoration: none; +} +#categories ul li a:hover { + color: #000; + background: #fcfcfc; +} +#categories ul .all a { + font-weight: bold; +} +#categories ul .current a { + background: #fff; + color: #000; + border: 1px solid #fbfbfb; + border-right: none; + border-left: 5px solid #f01; + padding-left: 10px; +} +/* Ads > Show */ +#ad div.header { + overflow: hidden; +} +#ad div.header h3 { + font-size: 16px; + margin: 0 0 3px; +} +#ad div.header small a.category { + font-weight: bold; + color: #000; +} +#ad div.header small span.networks img { + position: relative; + top: 3px; +} +#ad div.header span.brand { + float: right; + color: #fff; +} +#ad div.header span.brand a.brand_name { + font-weight: bold; + color: #000; +} +#ad div.content { + padding: 0; + position: relative; +} +#ad div.content a.toggle_size { + display: block; + background-color: #000; + padding: 0 5px 0 26px; + background-position: 5px center; + background-repeat: no-repeat; + text-decoration: none; + margin: 5px 5px 0 0; + position: absolute; + top: 0; + right: 0; + line-height: 25px; + z-index: 45; +} +#ad div.content img.creative { + margin: 0 auto; + max-width: 540px; + display: block; +} +#ad div.content object { + position: relative; + z-index: 44; +} +#ad div.content object.video { + line-height: 0; + font-size: 0; +} +#ad div.content object embed { + position: relative; + z-index: 45; + line-height: 0; + font-size: 0; +} +#ad div.content.not_video { + padding: 40px; + text-align: center; +} +#ad div.content.not_video * { + margin-left: auto; + margin-right: auto; +} +#ad div.content.not_video object.flash { + margin-bottom: 0; +} +#ad div.footer { + padding: 0; +} +#ad div.footer div.vote_views { + padding: 5px 10px; + overflow: hidden; +} +#ad div.footer div.vote_views div.share { + float: right; + margin: 2px 0 0 0; +} +#ad div.footer div.vote_views #login_register_msg, +#ad div.footer div.vote_views #encourage_vote_msg { + line-height: 22px; + font-weight: bold; + color: #000; +} +#sidebar #meta table { + margin: 0; +} +#sidebar #meta table tr:last-child td { + padding-bottom: 0; +} +#sidebar #meta table td { + padding: 0 0 5px; +} +#sidebar #meta table td ul.networks { + margin: 0; + padding: 0; +} +#sidebar #meta table td ul.networks li { + list-style: none; + display: inline; +} +#sidebar #meta table td.label { + color: #eee; + white-space: nowrap; + width: 1%; + text-align: right; + padding-right: 5px; +} +/* Voting */ +div.voted { + font-size: 12px; + line-height: 22px; + color: #000; + display: inline-block; + font-weight: bold; +} +div.voted img { + float: left; + margin-right: 5px; + padding: 3px; +} +#voted_up img { + background: #cf0003; +} +#voted_down img { + background: #cf0003; +} +#encourage_comment { + display: inline-block; + line-height: 22px; + font-weight: bold; +} +#vote { + overflow: hidden; + font-size: 12px; + line-height: 22px; + color: #000; + float: left; +} +#vote a { + color: #fff; + font-weight: bold; + overflow: hidden; + display: block; + width: 16px; + text-decoration: none; + text-align: center; + font-size: 10px; + padding: 3px; + text-transform: uppercase; +} +#vote a.up { + float: left; + background: #cf0003; +} +#vote a.up :hover { + background: #ff0003; +} +#vote a.down { + float: left; + background: #cf0003; + margin: 0 5px 0 1px; +} +#vote a.down :hover { + background: #ff0003; +} +#vote.disabled a.up { + background: #e9cacb; +} +#vote.disabled a.up :hover { + background: #f2b3b3; +} +#vote.disabled a.down { + background: #e9cacb; +} +#vote.disabled a.down :hover { + background: #f2b3b3; +} +/* Panels */ +div.panel { + margin: 0 0 20px; + position: relative; +} +div.panel > div.header { + background: #f01 url('/images/panel_header_bg.png') repeat-x top left; + border-bottom: 1px solid #a8000b; + padding: 5px 10px 4px; + min-height: 18px; +} +div.panel > div.header h2 { + font-size: 16px; + margin: 0; + color: #fff; +} +div.panel > div.header h3 { + color: #fff; + font-size: 14px; + margin: 0; + line-height: 18px; +} +div.panel > div.header small { + display: block; + font-size: 12px; + color: #fbfbfb; +} +div.panel > div.header span.filter { + float: left; + display: block; + overflow: hidden; + position: relative; + z-index: 5; +} +div.panel > div.header span.filter a { + margin: 0 1px 0 0; + display: block; + float: left; + padding: 0 8px; + height: 18px; + font-weight: bold; + font-size: 10px; + line-height: 18px; + text-transform: uppercase; + background: url('/images/transparent_backgrounds/black_50.png'); + color: #eee; + text-decoration: none; + position: relative; + z-index: 3; +} +div.panel > div.header span.filter a:last-child { + margin-right: 0; +} +div.panel > div.header span.filter a.active { + background: #fff; + color: #000; + z-index: 4; +} +div.panel > div.header span.filter a:hover { + color: #fff; +} +div.panel > div.header span.filter a.active:hover { + color: #000; +} +div.panel > div.header span.filter.dropdown { + margin: 0; + position: relative; + overflow: visible; +} +div.panel > div.header span.filter.dropdown a { + background: #fff; + color: #000; + margin: 0; + position: relative; + padding-right: 25px; +} +div.panel > div.header span.filter.dropdown a img { + float: left; + margin: 4px 5px 0 0; +} +div.panel > div.header span.filter.dropdown a b.arrow { + float: right; + display: block; + height: 0; + width: 0; + border: 5px solid transparent; + border-top: 5px solid #000; + border-bottom: none; + position: absolute; + top: 6px; + right: 10px; +} +div.panel > div.header span.filter.dropdown a :hover { + background: #000; + color: #fff; +} +div.panel > div.header span.filter.dropdown a :hover b.arrow { + border-top: 5px solid #fff; +} +div.panel > div.header span.filter.dropdown ul { + position: absolute; + top: 100%; + left: 0; + margin: 1px 0 0; + padding: 0; + background: #fff; +} +div.panel > div.header span.filter.dropdown ul li { + list-style: none; + display: block; + padding: 0; + margin: 0; +} +div.panel > div.header span.filter.dropdown ul li a { + display: block; + height: 18px; + line-height: 18px; + color: #000; + font-size: 10px; + text-transform: uppercase; + background: transparent; + border-bottom: 1px solid #f1f1f1; + float: none; + margin: 0; + white-space: nowrap; +} +div.panel > div.header span.filter.dropdown ul li a :hover { + background: url('/images/transparent_backgrounds/accent_colour_25.png'); + color: #000; +} +div.panel > div.header span.filter.dropdown ul li:last-child a { + border: none; +} +div.panel > div.header span.filter.dropdown.sort { + float: left; + margin: 0 0 0 10px; +} +div.panel > div.header span.filter.dropdown.localisation { + float: left; + margin: 0 0 0 10px; +} +div.panel > div.header a.more { + float: right; + color: #fff; + font-size: 14px; + font-weight: bold; + position: relative; + top: 2px; +} +div.panel > div.header a.more :hover { + text-decoration: none; +} +div.panel > div.content { + background: #fff; + padding: 10px; +} +div.panel > div.content .no_padding { + padding: 0; +} +div.panel > div.footer { + background: #f7f7f7; + border-top: 1px solid #f7f7f7; + padding: 4px 10px 5px; +} +div.panel.collapsable div.header { + cursor: pointer; +} +div.panel.collapsable div.header b.toggle { + float: right; + border: 5px solid transparent; + border-bottom: 5px solid #fff; + border-top: none; + display: block; + width: 0; + height: 0; + margin: 6px 0 0 0; +} +div.panel.collapsable div.header:hover { + background-color: #ff404d; +} +div.panel.collapsed div.header { + border-bottom: none; +} +div.panel.collapsed div.header b.toggle { + border-bottom: none; + border-top: 5px solid #fff; +} +div.panel.collapsed div.blank { + border-bottom: none; +} +div.panel.collapsed div.content, +div.panel.collapsed div.footer { + display: none; +} +/* Sidebar Actions */ +#sidebar #actions div.content { + background: url('/images/transparent_backgrounds/accent_colour_10.png'); + text-align: center; +} +#sidebar #actions div.content p.endorsement { + margin: 0 0 10px; + font-size: 14px; + font-weight: bold; +} +#sidebar #actions div.content p.endorsement small { + font-weight: normal; + line-height: inherit; + margin: 10px 0 0; +} +#sidebar #actions div.content p.endorsement :last-child { + margin: 0; +} +#sidebar #actions div.content div.share { + margin: 5px 0 0; +} +#sidebar #actions div.content a.button, +#sidebar #actions div.content a.btn { + font-size: 16px; + line-height: normal; + height: auto; + padding: 5px 10px 5px 35px; + font-weight: bold; + margin: 0; + position: relative; +} +#sidebar #actions div.content a.button img, +#sidebar #actions div.content a.btn img { + position: absolute; + top: 3px; + left: 6px; +} +#sidebar #actions div.content div.flash.notice { + margin: 10px 0 0; + font-size: 22px; +} +#sidebar #actions div.content div.flash.notice small { + font-weight: normal; + margin: 0 0 10px; +} +#sidebar #actions div.content div.flash.notice.done { + margin: 0; +} +#sidebar #actions div.content small { + display: block; + margin: 10px 0 0; + font-size: 11px; + color: #808080; + line-height: 12px; +} +#sidebar #actions div.content small img.favicon { + vertical-align: middle; +} +#sidebar #actions div.content div.blank { + border: none; + background: none; + padding: 10px 0 0; + border-top: 1px solid #808080; + margin: 10px 0 0; +} +/* People Lists */ +ul.people { + margin: 0; + padding: 10px 0 0 10px; + background: #fff; +} +ul.people > li { + display: block; + margin: 0 10px 10px 0; + float: left; + padding: 2px; + width: 57px; + position: relative; + background: #fff; + list-style: none; + border: 1px solid #f7f7f7; +} +ul.people > li a.avatar { + display: block; + width: 59px; + height: 59px; + overflow: hidden; +} +ul.people > li a.avatar img { + width: 100%; + height: 100%; +} +ul.people > li a.name { + display: block; + font-size: 10px; + text-align: center; +} +ul.people > li :hover { + background: #000; +} +ul.people > li :hover a.name { + color: #fff; +} +ul.people.list { + padding: 0; +} +ul.people.list > li { + margin: 0 0 10px; + padding: 0 0 10px; + overflow: hidden; + float: none; + width: auto; + border: none; + border-bottom: 1px solid #f7f7f7; +} +ul.people.list > li span.points { + float: right; + display: block; + padding: 5px; + background: #fcfcfc; + line-height: 1; + text-align: center; + width: 50px; + height: 30px; + margin: 0 0 0 10px; +} +ul.people.list > li span.points strong { + display: block; + color: #000; + font-size: 16px; + margin: 2px 0 0; +} +ul.people.list > li span.points label { + color: #eee; + text-transform: uppercase; + font-size: 10px; +} +ul.people.list > li span.points label.long { + display: block; +} +ul.people.list > li span.points label.short { + display: none; +} +ul.people.list > li a.avatar { + float: left; + width: 40px; + height: 40px; +} +ul.people.list > li a.name { + font-size: 14px; + font-weight: bold; + margin: 0 0 0 50px; + text-align: left; +} +ul.people.list > li a.name.long { + display: inline; +} +ul.people.list > li a.name.short { + display: none; +} +ul.people.list > li span.networks { + display: block; + margin: 0 0 0 50px; +} +ul.people.list > li span.networks img.favicon { + vertical-align: middle; +} +ul.people.list > li :hover { + background: transparent; +} +ul.people.list > li :hover a.name { + color: #000000; +} +ul.people.list > li :last-child { + padding-bottom: 0; + border-bottom: none; + margin-bottom: 0; +} +ul.people.list.small > li span.points { + padding: 3px 6px; + height: 18px; + font-size: 9px; + line-height: 17px; + width: 60px; +} +ul.people.list.small > li span.points strong { + font-size: 12px; + margin: 0; + display: inline; +} +ul.people.list.small > li span.points label { + font-size: 9px; +} +ul.people.list.small > li span.points label.long { + display: none; +} +ul.people.list.small > li span.points label.short { + display: inline; +} +ul.people.list.small > li a.avatar { + width: 24px; + height: 24px; +} +ul.people.list.small > li a.name { + display: inline; + line-height: 24px; + margin: 0 0 0 5px; + font-size: 12px; + height: 24px; +} +ul.people.list.small > li a.name.long { + display: none; +} +ul.people.list.small > li a.name.short { + display: inline; +} +ul.people.list.small > li span.networks { + display: inline; + margin: 0; +} +ul.people.list.small > li :last-child { + padding-bottom: 0; + border-bottom: none; + margin-bottom: 0; +} +ul.people.tiled > li { + width: 28px; + padding: 2px; +} +ul.people.tiled > li a.avatar { + width: 24px; + height: 24px; + background: #fff; + padding: 2px; +} +ul.people.tiled > li a.name, +ul.people.tiled > li small, +ul.people.tiled > li span.networks, +ul.people.tiled > li span.points { + display: none; +} +/* Comments */ +#comments ul { + margin: 0 0 20px; + padding: 0; +} +#comments ul li { + display: block; + list-style: none; + padding: 0; + margin: 0 0 10px; +} +#comments ul li span.meta { + margin: 0; + overflow: hidden; + display: block; +} +#comments ul li span.meta small { + font-size: 12px; + color: #eee; + float: right; + line-height: 16px; + display: inline-block; +} +#comments ul li span.meta a.avatar { + display: inline-block; + height: 16px; + width: 16px; + position: relative; + top: 3px; +} +#comments ul li span.meta a.avatar img { + height: 100%; + width: 100%; +} +#comments ul li span.meta a.name { + font-weight: bold; + line-height: 16px; + display: inline-block; +} +#comments ul li span.meta span.inactive { + color: #eee; + font-weight: bold; + line-height: 16px; + display: inline-block; +} +#comments ul li b.tail { + display: block; + width: 0; + height: 0; + margin: 3px 0 0 10px; + border: 5px solid transparent; + border-top: none; + border-bottom: 5px solid #fff; + position: relative; + z-index: 2; +} +#comments ul li blockquote { + margin: 0; + padding: 10px; + font-style: normal; + background: #fff; + color: #eee; +} +#comments form { + margin: 0; +} +#comments form textarea { + width: 500px; +} +/* Sidebar Categories */ +#sidebar #categories { + margin: 0 0 20px; + width: auto; +} +#sidebar #categories p { + margin: 0; +} +#sidebar #ads > ul li, +#sidebar #recommendations > ul li { + width: 81px; +} +#sidebar #ads > ul li div.thumbnail a.thumbnail, +#sidebar #recommendations > ul li div.thumbnail a.thumbnail { + height: 60px; + width: 81px; +} +#sidebar #ads > ul li div.text a.title, +#sidebar #recommendations > ul li div.text a.title { + font-size: 11px; + height: 14px; + line-height: 14px; +} +#sidebar #ads > ul li div.text small, +#sidebar #recommendations > ul li div.text small { + display: none; +} +#sidebar #brands > ul li { + width: 55px; +} +#sidebar #brands > ul li div.thumbnail a.thumbnail { + height: 45px; + width: 45px; +} +#sidebar #brands > ul li div.thumbnail a.thumbnail img { + max-height: 45px; + max-width: 45px; +} +#sidebar #brands > ul li div.text { + display: none; +} +/* My Account */ +#accounts_controller #top #page_title #page_options a.button.public_profile, +#accounts_controller #top #page_title #page_options a.btn.public_profile { + float: right; + font-size: 16px; + line-height: 1; + height: auto; + padding: 8px 35px 8px 15px; + position: relative; +} +#accounts_controller #top #page_title #page_options a.button.public_profile b.arrow, +#accounts_controller #top #page_title #page_options a.btn.public_profile b.arrow { + display: block; + height: 0; + width: 0; + position: absolute; + top: 10px; + right: 15px; + border: 6px solid transparent; + border-right: none; + border-left: 6px solid #fff; + margin: 0; +} +#accounts_controller #top #page_title #page_options a.button.goto_dashboard, +#accounts_controller #top #page_title #page_options a.btn.goto_dashboard { + float: right; + font-size: 16px; + line-height: 1; + height: auto; + padding: 8px 15px 8px 35px; + margin-right: 5px; + position: relative; +} +#accounts_controller #top #page_title #page_options a.button.goto_dashboard b.arrow, +#accounts_controller #top #page_title #page_options a.btn.goto_dashboard b.arrow { + display: block; + height: 0; + width: 0; + position: absolute; + top: 10px; + left: 15px; + border: 6px solid transparent; + border-left: none; + border-right: 6px solid #fff; + margin: 0; +} +#accounts_controller #account_nav { + float: left; + width: 200px; + margin: 0 20px 0 0; +} +#accounts_controller #account_nav ul.nav { + margin: 0; + padding: 0; +} +#accounts_controller #account_nav ul.nav li { + margin: 0 0 5px; + display: block; + list-style: none; + padding: 0; +} +#accounts_controller #account_nav ul.nav li a { + display: block; + height: 30px; + text-decoration: none; + color: #fff; +} +#accounts_controller #account_nav ul.nav li a b { + border: 15px solid transparent; + border-right: none; + border-left: 10px solid transparent; + width: 0; + height: 0; + float: right; + display: none; +} +#accounts_controller #account_nav ul.nav li a span { + background: #f01; + display: block; + line-height: 30px; + padding: 0 10px; + font-size: 14px; + font-weight: bold; + margin: 0 10px 0 0; +} +#accounts_controller #account_nav ul.nav li :hover a { + color: #fff; +} +#accounts_controller #account_nav ul.nav li :hover a b { + border-left-color: #f01; + display: block; +} +#accounts_controller #account_nav ul.nav li :hover a span { + background: #f01; +} +#accounts_controller #account_nav ul.nav li.current a b { + border-left-color: #000; + display: block; +} +#accounts_controller #account_nav ul.nav li.current a span { + background: #000; + color: #fff; +} +#accounts_controller #main > div { + margin: 0 0 20px; +} +#accounts_controller #main > div form { + margin: 0; +} +#accounts_controller #main #profile a.avatar { + float: left; + display: block; + width: 70px; + overflow: hidden; + position: relative; + text-decoration: none; +} +#accounts_controller #main #profile a.avatar img { + width: 100%; +} +#accounts_controller #main #profile a.avatar span { + display: block; + line-height: 1; + padding: 3px; + margin: 5px 0 0; + color: #fff; + background: #000; + text-align: center; + font-size: 10px; + font-weight: bold; + text-transform: uppercase; +} +#accounts_controller #main #profile form { + margin: 0 0 0 90px; +} +#accounts_controller #main #profile form h4 { + margin: 10px 0 20px; + border-bottom: 1px solid #f7f7f7; + padding: 0; + color: #f01; + font-size: 16px; +} +#accounts_controller #main #profile form ul.choices li { + width: 30%; +} +#accounts_controller #main #profile form div.extra { + margin-top: 20px; +} +#accounts_controller #main #networks ul { + margin: 0 -10px -10px 0; + padding: 0; + overflow: hidden; +} +#accounts_controller #main #networks ul li:hover { + background: #eee; + display: block; + float: left; + width: 180px; + padding: 10px; + margin: 0 10px 10px 0; + list-style: none; + position: relative; +} +#accounts_controller #main #networks ul li:hover * { + line-height: normal; +} +#accounts_controller #main #networks ul li:hover img { + vertical-align: middle; + float: left; +} +#accounts_controller #main #networks ul li:hover .name { + font-weight: bold; + font-size: 14px; + display: block; + margin: -2px 0 0 42px; +} +#accounts_controller #main #networks ul li:hover small { + font-size: 12px; + color: #eee; + display: block; + margin-left: 42px; +} +#accounts_controller #main #networks ul li:hover small strong { + color: #000; + font-weight: normal; +} +#accounts_controller #main #networks ul li.installed { + background: #fff; + border: 2px solid #000; + padding: 8px; +} +#accounts_controller #main #networks ul li.unavailable .name { + color: #000; +} +#accounts_controller #main #networks ul li.unavailable :hover { + background: #eee; +} +#accounts_controller #main #networks ul li:hover { + background: #f7f7f7; +} +/* Shopping Style Panel */ +#shopping_style div.header a.button.small, +#shopping_style div.header a.btn.small { + float: right; +} +#shopping_style div.content p { + margin: 0 0 10px; +} +#shopping_style div.content p label { + text-transform: uppercase; + font-size: 11px; + display: block; + color: #f01; + font-weight: bold; +} +#shopping_style div.content p span { + color: #000; +} +#shopping_style div.content p span.toggle { + white-space: nowrap; + color: #eee; +} +#shopping_style div.content p :last-child { + margin: 0; +} +#shopping_style div.content p.more { + text-align: left; + font-weight: normal; +} +#shopping_style div.content p.less { + display: none; + margin: 0; +} +/* People Controller */ +#people_controller.index #main div.panel { + float: left; + width: 300px; + margin: 0 20px 0 0; +} +#people_controller.index #main div.panel :last-child { + margin-right: 0; +} +#people_controller.show #content #shopping_style { + float: left; + width: 240px; + margin: 0 20px 0 0; +} +#people_controller.show #content #main { + width: 360px; +} +/* Search Results */ +#search_results { + margin: 0 0 20px; +} +#search_results li :hover small { + color: #bfbfbf; +} +#search div.content { + padding: 20px; +} +#search div.content form { + margin: 0; + float: none; +} +#search div.content form span.submit_and_options { + display: block; +} +#search div.content p { + margin: 0 0 15px; +} +#search div.content h4 { + font-weight: normal; + margin: 0 0 5px; +} +/* Recommendations */ +#recommendations div.browse { + margin: 0; + padding: 0; + background: none; +} +#recommendations div.browse ul { + min-height: 0; +} +/* Blank States */ +div.blank { + padding: 20px; + background: #f2e6e6; + position: relative; + border: 1px solid #e6ccce; + z-index: 1; +} +div.blank h4 { + font-size: 18px; + margin: 0 0 10px; +} +div.blank h4:last-child { + margin: 0; +} +div.blank p { + font-size: 16px; + margin: 0 0 10px; +} +div.blank p:last-child { + margin: 0; +} +div.blank p.with_list_number.large span { + margin-left: 48px; + display: block; + color: #fff; +} +div.blank p.earn span { + font-size: 22px; + color: #fff; + line-height: 48px; + font-weight: bold; +} +div.blank a { + white-space: nowrap; +} +div.blank a.hide { + position: absolute; + top: -5px; + right: -5px; + display: block; + height: 16px; + width: 16px; + padding: 3px; + background: #E7E9F6; +} +div.blank.small { + padding: 10px 20px; +} +div.blank.small h4 { + font-weight: normal; + font-size: 16px; +} +div.blank.small p { + margin: 0; +} +div.blank.tiny { + padding: 10px 20px; +} +div.blank.tiny h4 { + font-weight: normal; + font-size: 14px; +} +div.blank.tiny p { + margin: 0; + font-size: 12px; +} +div.blank.rounded { + margin: 0 0 20px; +} +div.blank.with_border_bottom { + border-bottom: 1px solid #e6ccce; +} +div.blank.no_border_top { + border-top: none; +} +div.blank.no_border_bottom { + border-bottom: none; +} +div.blank.no_side_borders { + border-right: none; + border-left: none; +} +div.panel div.blank { + padding: 10px 20px; + overflow: hidden; + margin: 0; +} +div.panel div.blank h4 { + font-weight: normal; + font-size: 14px; +} +div.panel div.blank p, +div.panel div.blank ul { + margin: 0 0 10px; + font-size: 12px; +} +div.panel div.blank p:last-child, +div.panel div.blank ul:last-child { + margin: 0; +} +/* Sidebar Browse */ +#sidebar div.panel div.content.browse { + padding: 0; + margin: 0; +} +#sidebar div.panel div.content.browse > ul { + min-height: 0; +} +#sidebar div.panel div.content.browse > ul > li div.thumbnail a.thumbnail { + padding: 5px; +} +#sidebar div.panel div.content.browse > ul > li div.thumbnail img.marker.media_type { + top: 48px; + left: 8px; +} +#sidebar div.panel div.content.browse > ul > li div.footer a.title, +#sidebar div.panel div.content.browse > ul > li div.footer a.name { + font-size: 11px; + font-weight: normal; +} +#sidebar div.panel div.content.browse.ads > ul > li { + width: 93px; +} +#sidebar div.panel div.content.browse.ads > ul > li > div.thumbnail a.thumbnail { + width: 83px; + height: 62px; +} +#sidebar div.panel div.content.browse.brands > ul { + background: none; +} +#sidebar div.panel div.content.browse.brands > ul > li { + width: 52px; +} +#sidebar div.panel div.content.browse.brands > ul > li > div.thumbnail { + padding: 3px; +} +#sidebar div.panel div.content.browse.brands > ul > li > div.thumbnail a.thumbnail { + width: 42px; + height: 42px; + padding: 2px; +} +#sidebar div.panel div.content.browse.brands > ul > li li.active { + background: #000; +} +#sidebar div.panel div.footer div.info { + float: none; +} +#sidebar div.panel div.footer div.pagination { + float: none; + margin: 3px 0 0; +} +/* List Numbers */ +label.list_number { + float: left; + background: url('/images/transparent_backgrounds/black_15.png'); + padding: 2px; + width: 24px; + height: 24px; + display: block; +} +label.list_number b { + display: block; + font-weight: bold; + font-size: 14px; + color: #fff; + background: #000; + height: 20px; + width: 20px; + line-height: 20px; + text-align: center; + border: 2px solid #fff; +} +label.list_number.large { + padding: 4px; + width: 48px; + height: 48px; + position: relative; + left: -10px; +} +label.list_number.large b { + font-size: 28px; + height: 40px; + width: 40px; + line-height: 40px; + border-width: 4px; +} +/* Dashboard */ +#dashboard_controller #ads span.filter.state { + float: right; +} +#dashboard_controller #sidebar #shopping_style div.content p.less { + display: block; +} +#dashboard_controller #sidebar #shopping_style div.content p.more { + display: none; +} +#dashboard_controller #sidebar #influences div.header { + padding-bottom: 0; +} +#dashboard_controller #sidebar #influences div.header ul.tabs { + position: relative; + top: 1px; + z-index: 3; +} +#dashboard_controller #sidebar #influences div.header ul.tabs li { + margin: 0 5px 0 0; +} +#dashboard_controller #sidebar #influences div.header ul.tabs li a { + border: none; + background: url('/images/transparent_backgrounds/white_75.png'); +} +#dashboard_controller #sidebar #influences div.header ul.tabs li a :hover { + color: #000; +} +#dashboard_controller #sidebar #influences div.header ul.tabs li.active a { + background: #fff; + border: none; +} +#dashboard_controller #sidebar #influences div.header ul.tabs li.active a :hover { + color: #000; +} +#dashboard_controller #sidebar #influences div.tab_content { + overflow: hidden; + padding: 0; +} +#dashboard_controller #sidebar #influences div.tab_content > ul { + padding: 10px 10px 0; + max-height: 280px; + min-height: 120px; + overflow-y: scroll; +} +#dashboard_controller #sidebar #influences div.footer form p { + margin: 0 0 5px; +} +#dashboard_controller #sidebar #influences div.footer form p img.marker { + float: right; + margin: 5px 0 0 0; +} +#dashboard_controller #sidebar #influences div.footer form p span.invitee { + line-height: 26px; + padding: 3px 3px 0; + font-size: 14px; +} +#dashboard_controller #sidebar #influences div.footer form p span.invitee small { + color: #eee; + font-size: 12px; +} +#dashboard_controller #sidebar #influences div.footer form p.indent { + margin-left: 36px; +} +#dashboard_controller #sidebar #influences div.footer form p.submit { + margin-top: 10px; +} +#dashboard_controller div.panel.full > div.content { + margin: 0; + padding: 0; + background: none; +} +#dashboard_controller div.panel.full > div.content ul li { + width: 148px; +} +#dashboard_controller div.panel.full > div.content ul li div.thumbnail img.marker.media_type { + top: 90px; +} +#dashboard_controller div.panel.full > div.content ul li div.thumbnail a.thumbnail { + width: 138px; + height: 104px; +} +#dashboard_controller #people form { + padding: 0 0 5px; +} +#dashboard_controller #people form input { + width: 225px; + float: left; + margin: 0 5px 0 0; +} +#dashboard_controller #people form a.button, +#dashboard_controller #people form a.btn { + height: 23px; + line-height: 23px; + width: 60px; + padding: 0; + text-align: center; +} +/* Remove Pages Titles when Browsing */ +#ads_controller #page_title, +#brands_controller #page_title { + display: none; +} +/* Brands > Show */ +#brands_controller.show #ads div.filters h3 { + font-size: 16px; + margin: 0; +} +#brands_controller.show #ads div.filters span.show { + float: right; +} +#brands_controller.show #ads div.filters span.filter.dropdown.localisation { + float: right; + margin: 0 0 0 10px; +} +#brands_controller.show #ads div.filters span.filter.state { + float: right; + margin: 0 0 0 10px; +} +/* FAQ */ +#pages_controller.faq #answers h3 { + margin-top: 20px; + padding-top: 20px; + border-top: 1px solid #f2f2f2; +} +#pages_controller.faq #answers h3.first { + margin-top: 0; + padding-top: 0; + border: none; +} +#pages_controller.faq #questions div.content { + padding: 20px; +} +#pages_controller.faq #questions div.content ul { + margin: 0; + padding: 0; +} +#pages_controller.faq #questions div.content ul li { + margin: 0 0 10px; + list-style: none; + display: block; + padding: 0; +} +#pages_controller.faq #questions div.content ul li a { + font-size: 14px; +} +#pages_controller.faq #questions div.content ul li:last-child { + margin: 0; +} +/* Person Overview */ +#person_overview { + padding: 20px 10px; + position: relative; + z-index: 25; +} +#person_overview #person { + float: left; + width: 620px; +} +#person_overview #person a.avatar { + display: block; + float: left; + width: 60px; + height: 60px; +} +#person_overview #person a.avatar img { + height: 100%; + width: 100%; +} +#person_overview #person > div { + margin: 0 0 0 75px; + color: #fff; + font-size: 14px; +} +#person_overview #person div.name h2 { + margin: 0 0 5px; + display: inline; +} +#person_overview #person div.name h2 a { + font-size: 20px; + font-weight: bold; + line-height: 1; + color: #fff; + text-decoration: none; +} +#person_overview #person div.name h2 a :hover { + text-decoration: underline; +} +#person_overview #person div.name h2 a.button.small, +#person_overview #person div.name h2 a.btn.small { + font-size: 10px; +} +#person_overview #person div.name h2 a.button.small :hover, +#person_overview #person div.name h2 a.btn.small :hover { + text-decoration: none; +} +#person_overview #person div.name span.points { + float: right; + display: block; + padding: 5px 10px; + text-align: center; + background: #fff; + position: relative; + min-width: 45px; +} +#person_overview #person div.name span.points strong { + color: #000; + font-weight: bold; + font-size: 24px; + line-height: 1; + display: block; +} +#person_overview #person div.name span.points label { + font-size: 9px; + text-transform: uppercase; + color: #eee; + display: block; + font-weight: bold; +} +#person_overview #person div.name span.points.with_redeem a.button, +#person_overview #person div.name span.points.with_redeem a.btn { + display: block; + text-align: center; + font-size: 10px; + font-weight: bold; + padding: 0; + position: absolute; + height: 18px; + left: 0; + right: 0; + bottom: -19px; + line-height: 18px; + text-transform: uppercase; + border: none; +} +#person_overview #person div.name div.options { + margin: 0; +} +#person_overview #person div.meta { + color: #fca8ae; +} +#person_overview #person div.meta span { + color: #fff; +} +#person_overview #person div.meta label { + color: #fca8ae; +} +#person_overview #person div.meta ul.networks { + display: inline; + margin: 0; + padding: 0; +} +#person_overview #person div.meta ul.networks li { + display: inline; + line-height: 1; +} +#person_overview #person div.meta ul.networks li img { + position: relative; + vertical-align: middle; + top: -1px; +} +#person_overview #person div.extra { + font-size: 12px; + margin-top: 20px; + margin-bottom: 20px; +} +#person_overview #person div.extra span.toggle a { + font-size: 10px; + font-weight: bold; + text-transform: uppercase; + text-decoration: none; + color: #000; +} +#person_overview #person div.extra span.toggle b.arrow { + display: inline-block; + width: 0; + height: 0; + border: 5px solid transparent; + position: relative; + top: -2px; +} +#person_overview #person div.extra #less_info span.toggle b.arrow { + border-top: 5px solid #000; + border-bottom: 0; +} +#person_overview #person div.extra #more_info span.toggle { + float: right; +} +#person_overview #person div.extra #more_info span.toggle b.arrow { + border-bottom: 5px solid #000; + border-top: 0; +} +#person_overview #person div.extra #more_info h4 { + color: #fff; + margin: 0 0 10px 0; + border-bottom: 1px solid #ff404d; +} +#person_overview #person div.extra #more_info h4 span { + font-size: 12px; +} +#person_overview #person div.extra #more_info p { + margin: 0 0 5px; +} +#person_overview #person div.extra #more_info p label { + display: block; + float: left; + width: 120px; + color: #fca8ae; +} +#person_overview #person div.extra #more_info p span { + display: block; + margin: 0 0 0 130px; +} +#person_overview #person div.extra #more_info p:last-child { + margin: 0; +} +#person_overview #person div.login { + margin: 0 0 0 75px; +} +#person_overview #person div.login a.button, +#person_overview #person div.login a.btn { + font-weight: bold; +} +/* Dashboard Nav */ +#dashboard_nav { + position: absolute; + bottom: 0; + left: 10px; + margin: 0; + padding: 0; + overflow: hidden; +} +#dashboard_nav li { + display: block; + float: left; + margin: 0 5px 0 0; +} +#dashboard_nav li a { + display: block; + height: 28px; + padding: 0 10px; + line-height: 28px; + text-decoration: none; + color: #fff; + background: url('/images/transparent_backgrounds/accent_colour_30.png'); + font-size: 14px; + font-weight: bold; +} +#dashboard_nav li a :hover { + background: url('/images/transparent_backgrounds/accent_colour_45.png'); +} +#dashboard_nav li.active a { + background: #fff; + color: #000; +} +#dashboard_nav li.active a :hover { + color: #000; +} +/* Dwellometer */ +#dwellometer { + z-index: 45; + float: right; + margin: 0; +} +#dwellometer div.content { + text-align: center; + position: relative; +} +#dwellometer div.content object, +#dwellometer div.content object embed { + position: relative; + z-index: 46; + line-height: 0; +} +#dwellometer div.content div.title { + position: absolute; + bottom: 10px; + left: 0; + right: 0; + z-index: 50; +} +#dwellometer div.content div.title img { + width: 120px; + display: block; + margin: 0 auto; + position: relative; + left: -5px; +} +/* Activity Stream */ +#activity div.content ul.events { + padding: 0; + margin: 0 0 -10px; +} +#activity div.content ul.events li { + margin: 0; + padding: 10px 0; + border-bottom: 1px solid #f7f7f7; + list-style: none; + overflow: hidden; + /* Temporarily removed avatar and symbol */ + /* div.symbols a.agent, b { display: none; }*/ +} +#activity div.content ul.events li small.meta { + font-size: 12px; + color: #eee; + float: right; +} +#activity div.content ul.events li a.button, +#activity div.content ul.events li a.btn { + float: right; + margin: 0 0 10px 10px; +} +#activity div.content ul.events li a.avatar, +#activity div.content ul.events li a.logo, +#activity div.content ul.events li a.thumbnail { + height: 32px; + display: block; + float: left; +} +#activity div.content ul.events li a.avatar img, +#activity div.content ul.events li a.logo img, +#activity div.content ul.events li a.thumbnail img { + width: 100%; + height: 100%; +} +#activity div.content ul.events li a.avatar, +#activity div.content ul.events li a.logo, +#activity div.content ul.events li a.icon { + width: 32px; +} +#activity div.content ul.events li a.thumbnail { + width: 42px; +} +#activity div.content ul.events li div.symbols { + float: left; + overflow: hidden; +} +#activity div.content ul.events li div.symbols b { + display: block; + float: left; + margin: 10px 5px 0; +} +#activity div.content ul.events li div.symbols b img { + height: 12px; + width: 12px; +} +#activity div.content ul.events li div.symbols b.voted { + margin: 10px 3px 0; + padding: 2px; +} +#activity div.content ul.events li div.symbols b.voted.for { + background: #fca8a8; +} +#activity div.content ul.events li div.symbols b.voted.against { + background: #fca8a8; +} +#activity div.content ul.events li div.description { + font-size: 12px; + color: #eee; +} +#activity div.content ul.events li div.description a.agent { + font-weight: bold; +} +#activity div.content ul.events li div.comment { + margin-top: 2px; +} +#activity div.content ul.events li div.comment b.tail { + display: block; + margin: 0 0 0 10px; + width: 0; + height: 0; + border: 5px solid transparent; + border-top: none; + border-bottom: 5px solid #fbfbfb; +} +#activity div.content ul.events li div.comment blockquote { + margin: 0; + font-style: normal; + color: #eee; + background: #fbfbfb; + padding: 5px 10px; +} +#activity div.content ul.events li div.comment blockquote span.view_comment { + color: #eee; +} +#activity div.content ul.events li div.content { + overflow: hidden; +} +#activity div.content ul.events li.new_comment.ad, +#activity div.content ul.events li.endorsed.ad, +#activity div.content ul.events li.voted { + /* div.description, div.content { margin-left: 53px; }*/ +} +#activity div.content ul.events li.new_comment.ad div.description, +#activity div.content ul.events li.endorsed.ad div.description, +#activity div.content ul.events li.voted div.description, +#activity div.content ul.events li.new_comment.ad div.content, +#activity div.content ul.events li.endorsed.ad div.content, +#activity div.content ul.events li.voted div.content { + margin-left: 106px; +} +#activity div.content ul.events li.new_comment.brand, +#activity div.content ul.events li.replied_to, +#activity div.content ul.events li.endorsed.brand, +#activity div.content ul.events li.connected, +#activity div.content ul.events li.sn_setup { + /* div.description, div.content { margin-left: 43px; }*/ +} +#activity div.content ul.events li.new_comment.brand div.description, +#activity div.content ul.events li.replied_to div.description, +#activity div.content ul.events li.endorsed.brand div.description, +#activity div.content ul.events li.connected div.description, +#activity div.content ul.events li.sn_setup div.description, +#activity div.content ul.events li.new_comment.brand div.content, +#activity div.content ul.events li.replied_to div.content, +#activity div.content ul.events li.endorsed.brand div.content, +#activity div.content ul.events li.connected div.content, +#activity div.content ul.events li.sn_setup div.content { + margin-left: 96px; +} +#activity div.content ul.events li.replied_to div.content a.thumbnail, +#activity div.content ul.events li.replied_to div.content a.logo { + margin-top: 7px; +} +#activity div.content ul.events li.replied_to.ad div.content div.comment { + margin-left: 52px; +} +#activity div.content ul.events li.replied_to.brand div.content div.comment { + margin-left: 42px; +} +#activity div.content ul.events li.voted div.description span.action { + color: #eee; + padding: 0 3px; + white-space: nowrap; +} +#activity div.content ul.events li.voted.for div.description span.action { + background: #ffd9d9; +} +#activity div.content ul.events li.voted.against div.description span.action { + background: #ffd9d9; +} +#activity div.content ul.events li:first-child { + padding-top: 0; +} +#activity div.content ul.events li:last-child { + border-bottom: none; +} +/* Login/Register Modal */ +#login_register div.location_select, +#login_register div.location_search { + margin-left: 130px; +} +#login_register h3 small { + font-size: 14px; + font-weight: normal; + color: #eee; + text-align: left; + margin: 0; + display: block; +} +/* Contact Form in Pages */ +#pages_controller #sidebar #contact { + margin: 15px 0 0; +} +#pages_controller #sidebar #contact form label { + text-align: left; + float: none; + width: auto; + font-size: 12px; + font-weight: bold; + line-height: 1; + margin: 0 0 5px; +} +#pages_controller #sidebar #contact form p.submit.indent { + margin: 0; +} +#pages_controller #sidebar #contact form p.submit.indent span.with_cancel { + display: none; +} +/* Exclusive Offers */ +#offers div.content a.gift { + display: block; + text-align: center; +} +#offers div.content a.gift img { + height: 100px; +} +div.browse { + margin: 0 0 20px; +} +div.browse.class { + padding: 0; +} +div.browse div.header { + padding: 10px 10px 9px; + text-align: left; + background: #f01 url('/images/panel_header_bg.png') repeat-x top left; + border-bottom: 1px solid #a8000b; + line-height: 1; + height: 18px; + color: #eee; +} +div.browse div.header h3 { + font-size: 16px; + margin: 0; + color: #fff; +} +div.browse div.header span.filter { + float: left; + display: block; + overflow: hidden; + position: relative; + z-index: 5; +} +div.browse div.header span.filter a { + margin: 0 1px 0 0; + display: block; + float: left; + padding: 0 8px; + height: 18px; + font-weight: bold; + font-size: 10px; + line-height: 18px; + text-transform: uppercase; + background: url('/images/transparent_backgrounds/black_50.png'); + color: #eee; + text-decoration: none; + position: relative; + z-index: 3; +} +div.browse div.header span.filter a .active { + background: #fff; + color: #000; + z-index: 4; +} +div.browse div.header span.filter a .active :hover { + color: #000; +} +div.browse div.header span.filter a :hover { + color: #fff; +} +div.browse div.header span.filter a :last-child { + margin-right: 0; +} +div.browse div.header span.filter.dropdown { + margin: 0; + position: relative; + overflow: visible; +} +div.browse div.header span.filter.dropdown a { + background: #fff; + color: #000; + margin: 0; + position: relative; + padding-right: 25px; +} +div.browse div.header span.filter.dropdown a img { + float: left; + margin: 4px 5px 0 0; +} +div.browse div.header span.filter.dropdown a b.arrow { + float: right; + display: block; + height: 0; + width: 0; + border: 5px solid transparent; + border-top: 5px solid #000; + border-bottom: none; + position: absolute; + top: 6px; + right: 10px; +} +div.browse div.header span.filter.dropdown a :hover { + background: #000; + color: #fff; +} +div.browse div.header span.filter.dropdown a :hover b.arrow { + border-top: 5px solid #fff; +} +div.browse div.header span.filter.dropdown ul { + position: absolute; + top: 100%; + left: 0; + margin: 1px 0 0; + padding: 0; + background: #fff; +} +div.browse div.header span.filter.dropdown ul li { + list-style: none; + display: block; + padding: 0; + margin: 0; +} +div.browse div.header span.filter.dropdown ul li a { + display: block; + height: 18px; + line-height: 18px; + color: #000; + font-size: 10px; + text-transform: uppercase; + background: transparent; + border-bottom: 1px solid #f1f1f1; + float: none; + margin: 0; + white-space: nowrap; +} +div.browse div.header span.filter.dropdown ul li a :hover { + background: url('/images/transparent_backgrounds/accent_colour_25.png'); + color: #000; +} +div.browse div.header span.filter.dropdown ul li :last-child a { + border: none; +} +div.browse div.header span.filter.dropdown.sort { + float: left; + margin: 0 0 0 10px; +} +div.browse div.header span.filter.dropdown.localisation { + float: left; + margin: 0 0 0 10px; +} +div.browse div.header a.more { + float: right; + color: #fff; + font-size: 14px; + font-weight: bold; + position: relative; + top: 2px; +} +div.browse div.header a.more :hover { + text-decoration: none; +} +div.browse > ul { + margin: 0; + background: #fff; + padding: 10px 0 0 10px; + position: relative; +} +div.browse > ul li { + display: block; + float: left; + list-style: none; + margin: 0 10px 10px 0; + padding: 5px; + position: relative; + background: #fff; + width: 130px; + border: 1px solid #f7f7f7; +} +div.browse > ul li a.remove { + position: absolute; + height: 16px; + width: 16px; + padding: 3px; + background: #000; + display: none; + z-index: 3; + top: -8px; + right: -8px; +} +div.browse > ul li a.remove img { + vertical-align: middle; +} +div.browse > ul li div.thumbnail { + position: relative; + z-index: 3; +} +div.browse > ul li div.thumbnail .marker { + position: absolute; + padding: 2px; + z-index: 3; + background: url('/images/transparent_backgrounds/white_75.png'); + height: 12px; + width: 12px; +} +div.browse > ul li div.thumbnail .marker.coupon { + height: auto; + width: auto; + top: 10px; + right: -3px; + padding: 0; + background: transparent; + overflow: hidden; + position: absolute; +} +div.browse > ul li div.thumbnail .marker.coupon b { + display: block; + height: 0; + width: 0; + border: 14px solid transparent; + border-top: 14px solid #000; + border-bottom: none; + border-right: none; + float: left; +} +div.browse > ul li div.thumbnail .marker.coupon span { + color: #fff; + font-size: 10px; + font-weight: bold; + text-transform: uppercase; + height: 14px; + line-height: 14px; + display: block; + padding: 0 4px 0 2px; + background: #000; + margin: 0 0 0 14px; +} +div.browse > ul li div.thumbnail .marker.video { + position: absolute; + left: 50%; + top: 50%; + background: #fff; + width: 10px; + height: 10px; +} +div.browse > ul li div.thumbnail .marker.video b { + display: block; + width: 0; + height: 0; + border: 5px solid transparent; + border-left: 10px solid #000; + border-right: none; +} +div.browse > ul li div.thumbnail .marker.endorsed_by_me { + background: none; + padding: 0; + right: 0; + bottom: -32px; + background: #fff; +} +div.browse > ul li div.thumbnail a.thumbnail { + display: block; + overflow: hidden; + position: relative; + text-align: center; +} +div.browse > ul li div.thumbnail a.thumbnail img { + position: relative; + display: block; + margin: auto; +} +div.browse > ul li div.text { + margin: 3px 0 0; + display: block; +} +div.browse > ul li div.text a { + text-decoration: none; +} +div.browse > ul li div.text a.title { + display: block; + text-decoration: none; + font-weight: bold; + font-size: 12px; + line-height: 16px; + white-space: nowrap; + height: 16px; + overflow: hidden; +} +div.browse > ul li div.text a.title :before { + display: block; + height: 32px; + width: 20px; + content: " "; + float: right; + right: -15px; + top: -8px; + background: #fff; + position: relative; + z-index: 1; +} +div.browse > ul li div.text small { + font-size: 11px; + line-height: 13px; + color: #eee; + display: block; + height: 13px; + overflow: hidden; + white-space: nowrap; +} +div.browse > ul li div.text small a { + font-weight: bold; +} +div.browse > ul li div.text small :before { + display: block; + height: 32px; + width: 20px; + content: " "; + float: right; + right: -15px; + top: -8px; + background: #fff; + position: relative; + z-index: 1; +} +div.browse > ul li :hover { + background: #000; +} +div.browse > ul li :hover a.remove { + display: block; +} +div.browse > ul li :hover div.thumbnail a.marker.remove b, +div.browse > ul li :hover div.thumbnail a.marker.video b { + display: inline-block; +} +div.browse > ul li :hover div.text a { + color: #fff; +} +div.browse > ul li :hover div.text a.title:before { + background: #000; +} +div.browse > ul li :hover div.text small { + color: #bfbfbf; +} +div.browse > ul li :hover div.text small :before { + background: #000; +} +div.browse > ul li :hover div.footer a { + color: #fff; +} +div.browse > ul > li.ad div.thumbnail a.thumbnail { + width: 130px; + height: 97px; +} +div.browse > ul > li.ad div.thumbnail a.thumbnail img { + width: 100%; + height: 100%; +} +div.browse > ul > li.brand div.thumbnail a.thumbnail { + width: 120px; + height: 87px; + padding: 5px; + background: #fff; +} +div.browse > ul > li.brand div.thumbnail a.thumbnail img { + max-width: 120px; + max-height: 87px; +} +div.browse > ul li.paginate { + margin-bottom: 0; +} +div.browse > ul li.paginate a { + display: block; + position: relative; + text-decoration: none; + height: 131px; +} +div.browse > ul li.paginate a div.arrow { + background: #81c153 url('/images/button_bg.png') repeat-x left top; + border: 1px solid #000000; + height: 44px; + width: 44px; + margin: 0 auto; + position: relative; + top: 32px; +} +div.browse > ul li.paginate a div.arrow b { + text-indent: -9000px; + display: block; + border: 10px solid transparent; + width: 0; + height: 0; + position: relative; + top: 12px; +} +div.browse > ul li.paginate a div.label { + position: absolute; + bottom: 5px; + left: 0; + right: 0; + line-height: 13px; + color: #000000; + text-decoration: none; + font-weight: bold; + font-size: 12px; + text-align: center; +} +div.browse > ul li.paginate a :hover div.arrow { + background: #abd56e url('/images/button_bg.png') repeat-x left -44px; +} +div.browse > ul li.paginate :hover { + background: transparent; +} +div.browse > ul li.paginate.previous a div b { + border-right: 15px solid #fff; + border-left: none; + left: 12px; +} +div.browse > ul li.paginate.next a div b { + border-left: 15px solid #fff; + border-right: none; + left: 16px; +} +div.browse > div.footer { + padding: 9px 10px 10px; + background: #f2f2f2; + overflow: hidden; + border-top: 1px solid #eee; +} +div.browse > div.footer div.info { + float: left; + color: #eee; +} +div.browse > div.footer div.info strong { + color: #000; + font-weight: normal; +} +div.browse > div.footer div.pagination { + float: right; +} +div.browse > div.footer div.pagination > * { + display: inline-block; + line-height: 1; + padding: 0 6px; + line-height: 18px; + height: 18px; + background: #fff; + text-decoration: none; + font-weight: bold; + font-size: 10px; + text-transform: uppercase; +} +div.browse > div.footer div.pagination a { + color: #eee; +} +div.browse > div.footer div.pagination a:hover { + color: #000; +} +div.browse > div.footer div.pagination span.disabled { + color: #eee; +} +div.browse > div.footer div.pagination span.current { + color: #fff; + background: #f01; + border: none; +} +div.browse > div.footer div.pagination span.current:hover { + color: #fff; +} +div.browse.with_categories { + margin: 0 0 0 160px; +} +/* Browse List */ +div.browse.list > ul { + margin: 0; + min-height: 320px; + padding: 10px 0 0 10px; + overflow: hidden; +} +div.browse.list > ul > li { + display: block; + list-style: none; + margin: 0 10px 10px 0; + padding: 5px; + position: relative; + line-height: normal; +} +div.browse.list > ul > li .marker { + position: absolute; + padding: 2px; + background: url('/images/transparent_backgrounds/white_75.png'); +} +div.browse.list > ul > li .marker img { + height: 12px; + width: 12px; +} +div.browse.list > ul > li img.marker { + height: 12px; + width: 12px; +} +div.browse.list > ul > li span.marker.new { + color: black; + left: -5px; + top: -5px; + background: none; + background-color: #8f2e2e; + line-height: 1; + padding: 2px 5px; + font-weight: bold; +} +div.browse.list > ul > li a.marker.media_type { + display: inline-block; + text-decoration: none; + top: 39px; + left: 8px; + font-size: 10px; +} +div.browse.list > ul > li a.marker.media_type b { + font-weight: normal; + margin: 0 0 0 2px; + line-height: 1; + display: none; +} +div.browse.list > ul > li a.marker.media_type img { + vertical-align: middle; +} +div.browse.list > ul > li a.thumbnail { + float: left; + width: 68px; + display: block; + overflow: hidden; + border: 1px solid #eee; +} +div.browse.list > ul > li a.thumbnail :hover { + border-color: #000; +} +div.browse.list > ul > li span.title_brand { + display: block; + margin: 0 0 2px 75px; +} +div.browse.list > ul > li span.title_brand a { + margin: 0; + display: inline; +} +div.browse.list > ul > li span.title_brand a.brand_name { + font-weight: normal; + font-size: 12px; +} +div.browse.list > ul > li a.ad_title { + font-weight: bold; + font-size: 14px; + margin: 0 0 0 75px; + display: block; +} +div.browse.list > ul > li a.brand_name { + font-weight: bold; + font-size: 14px; + margin: 0 0 0 75px; + display: block; +} +div.browse.list > ul > li small { + display: block; + color: #eee; + margin: 0 0 0 75px; + font-size: 12px; +} +div.browse.list > ul > li small.brand_name { + display: inline; + margin: 0; +} +div.browse.list > ul > li ul.chart { + margin: 0 0 0 80px; + height: 39px; +} +div.browse.list > ul > li ul.networks { + margin: 3px 0 0 75px; + padding: 0; + overflow: hidden; +} +div.browse.list > ul > li ul.networks li { + display: block; + float: left; + margin: 0 5px 0 0; + line-height: 1; +} +div.browse.list > ul > li div.points { + display: none; + font-size: 12px; + text-align: right; +} +div.browse.list > ul > li div.points label { + color: #eee; +} +div.browse.list > ul > li a.remove { + bottom: -3px; + right: -3px; +} +div.browse.list > ul li.ad a.thumbnail { + height: 51px; +} +div.browse.list > ul li.ad span.title_brand small.brand_name { + display: block; +} +div.browse.list > ul li.brand a.thumbnail { + height: 68px; +} +div.browse.list.cols_2 > ul > li { + width: 285px; + float: left; +} +div.browse.list.cols_2 > ul > li :hover { + background: #fff; +} +div.browse.ads.list > ul > li { + height: 53px; +} +div.browse.ads.list > ul > li a.thumbnail { + height: 51px; +} +div.browse.brands.list > ul > li { + height: 68px; +} +div.browse.brands.list > ul > li a.thumbnail { + height: 66px; +} +/* Categories List */ +#categories { + margin: 40px 0 0; + width: 160px; + float: left; + position: relative; + z-index: 1; +} +#categories ul { + margin: 0; + padding: 10px 0 0; +} +#categories ul li { + list-style: none; + margin: 0; + padding: 0; + font-size: 14px; +} +#categories ul li a { + color: #eee; + display: block; + padding: 5px 10px 5px 15px; + text-decoration: none; +} +#categories ul li a:hover { + color: #000; + background: #fcfcfc; +} +#categories ul .all a { + font-weight: bold; +} +#categories ul .current a { + background: #fff; + color: #000; + border: 1px solid #fbfbfb; + border-right: none; + border-left: 5px solid #f01; + padding-left: 10px; +} +/* Ads > Show */ +#ad div.header { + overflow: hidden; +} +#ad div.header h3 { + font-size: 16px; + margin: 0 0 3px; +} +#ad div.header small a.category { + font-weight: bold; + color: #000; +} +#ad div.header small span.networks img { + position: relative; + top: 3px; +} +#ad div.header span.brand { + float: right; + color: #fff; +} +#ad div.header span.brand a.brand_name { + font-weight: bold; + color: #000; +} +#ad div.content { + padding: 0; + position: relative; +} +#ad div.content a.toggle_size { + display: block; + background-color: #000; + padding: 0 5px 0 26px; + background-position: 5px center; + background-repeat: no-repeat; + text-decoration: none; + margin: 5px 5px 0 0; + position: absolute; + top: 0; + right: 0; + line-height: 25px; + z-index: 45; +} +#ad div.content img.creative { + margin: 0 auto; + max-width: 540px; + display: block; +} +#ad div.content object { + position: relative; + z-index: 44; +} +#ad div.content object.video { + line-height: 0; + font-size: 0; +} +#ad div.content object embed { + position: relative; + z-index: 45; + line-height: 0; + font-size: 0; +} +#ad div.content.not_video { + padding: 40px; + text-align: center; +} +#ad div.content.not_video * { + margin-left: auto; + margin-right: auto; +} +#ad div.content.not_video object.flash { + margin-bottom: 0; +} +#ad div.footer { + padding: 0; +} +#ad div.footer div.vote_views { + padding: 5px 10px; + overflow: hidden; +} +#ad div.footer div.vote_views div.share { + float: right; + margin: 2px 0 0 0; +} +#ad div.footer div.vote_views #login_register_msg, +#ad div.footer div.vote_views #encourage_vote_msg { + line-height: 22px; + font-weight: bold; + color: #000; +} +#sidebar #meta table { + margin: 0; +} +#sidebar #meta table tr:last-child td { + padding-bottom: 0; +} +#sidebar #meta table td { + padding: 0 0 5px; +} +#sidebar #meta table td ul.networks { + margin: 0; + padding: 0; +} +#sidebar #meta table td ul.networks li { + list-style: none; + display: inline; +} +#sidebar #meta table td.label { + color: #eee; + white-space: nowrap; + width: 1%; + text-align: right; + padding-right: 5px; +} +/* Voting */ +div.voted { + font-size: 12px; + line-height: 22px; + color: #000; + display: inline-block; + font-weight: bold; +} +div.voted img { + float: left; + margin-right: 5px; + padding: 3px; +} +#voted_up img { + background: #cf0003; +} +#voted_down img { + background: #cf0003; +} +#encourage_comment { + display: inline-block; + line-height: 22px; + font-weight: bold; +} +#vote { + overflow: hidden; + font-size: 12px; + line-height: 22px; + color: #000; + float: left; +} +#vote a { + color: #fff; + font-weight: bold; + overflow: hidden; + display: block; + width: 16px; + text-decoration: none; + text-align: center; + font-size: 10px; + padding: 3px; + text-transform: uppercase; +} +#vote a.up { + float: left; + background: #cf0003; +} +#vote a.up :hover { + background: #ff0003; +} +#vote a.down { + float: left; + background: #cf0003; + margin: 0 5px 0 1px; +} +#vote a.down :hover { + background: #ff0003; +} +#vote.disabled a.up { + background: #e9cacb; +} +#vote.disabled a.up :hover { + background: #f2b3b3; +} +#vote.disabled a.down { + background: #e9cacb; +} +#vote.disabled a.down :hover { + background: #f2b3b3; +} +#sidebar #ads > ul li, +#sidebar #recommendations > ul li { + width: 81px; +} +#sidebar #ads > ul li div.thumbnail a.thumbnail, +#sidebar #recommendations > ul li div.thumbnail a.thumbnail { + height: 60px; + width: 81px; +} +#sidebar #ads > ul li div.text a.title, +#sidebar #recommendations > ul li div.text a.title { + font-size: 11px; + height: 14px; + line-height: 14px; +} +#sidebar #ads > ul li div.text small, +#sidebar #recommendations > ul li div.text small { + display: none; +} +#sidebar #brands > ul li { + width: 55px; +} +#sidebar #brands > ul li div.thumbnail a.thumbnail { + height: 45px; + width: 45px; +} +#sidebar #brands > ul li div.thumbnail a.thumbnail img { + max-height: 45px; + max-width: 45px; +} +#sidebar #brands > ul li div.text { + display: none; +} +/* My Account */ +#accounts_controller #top #page_title #page_options a.button.public_profile, +#accounts_controller #top #page_title #page_options a.btn.public_profile { + float: right; + font-size: 16px; + line-height: 1; + height: auto; + padding: 8px 35px 8px 15px; + position: relative; +} +#accounts_controller #top #page_title #page_options a.button.public_profile b.arrow, +#accounts_controller #top #page_title #page_options a.btn.public_profile b.arrow { + display: block; + height: 0; + width: 0; + position: absolute; + top: 10px; + right: 15px; + border: 6px solid transparent; + border-right: none; + border-left: 6px solid #fff; + margin: 0; +} +#accounts_controller #top #page_title #page_options a.button.goto_dashboard, +#accounts_controller #top #page_title #page_options a.btn.goto_dashboard { + float: right; + font-size: 16px; + line-height: 1; + height: auto; + padding: 8px 15px 8px 35px; + margin-right: 5px; + position: relative; +} +#accounts_controller #top #page_title #page_options a.button.goto_dashboard b.arrow, +#accounts_controller #top #page_title #page_options a.btn.goto_dashboard b.arrow { + display: block; + height: 0; + width: 0; + position: absolute; + top: 10px; + left: 15px; + border: 6px solid transparent; + border-left: none; + border-right: 6px solid #fff; + margin: 0; +} +#accounts_controller #account_nav { + float: left; + width: 200px; + margin: 0 20px 0 0; +} +#accounts_controller #account_nav ul.nav { + margin: 0; + padding: 0; +} +#accounts_controller #account_nav ul.nav li { + margin: 0 0 5px; + display: block; + list-style: none; + padding: 0; +} +#accounts_controller #account_nav ul.nav li a { + display: block; + height: 30px; + text-decoration: none; + color: #fff; +} +#accounts_controller #account_nav ul.nav li a b { + border: 15px solid transparent; + border-right: none; + border-left: 10px solid transparent; + width: 0; + height: 0; + float: right; + display: none; +} +#accounts_controller #account_nav ul.nav li a span { + background: #f01; + display: block; + line-height: 30px; + padding: 0 10px; + font-size: 14px; + font-weight: bold; + margin: 0 10px 0 0; +} +#accounts_controller #account_nav ul.nav li :hover a { + color: #fff; +} +#accounts_controller #account_nav ul.nav li :hover a b { + border-left-color: #f01; + display: block; +} +#accounts_controller #account_nav ul.nav li :hover a span { + background: #f01; +} +#accounts_controller #account_nav ul.nav li.current a b { + border-left-color: #000; + display: block; +} +#accounts_controller #account_nav ul.nav li.current a span { + background: #000; + color: #fff; +} +#accounts_controller #main > div { + margin: 0 0 20px; +} +#accounts_controller #main > div form { + margin: 0; +} +#accounts_controller #main #profile a.avatar { + float: left; + display: block; + width: 70px; + overflow: hidden; + position: relative; + text-decoration: none; +} +#accounts_controller #main #profile a.avatar img { + width: 100%; +} +#accounts_controller #main #profile a.avatar span { + display: block; + line-height: 1; + padding: 3px; + margin: 5px 0 0; + color: #fff; + background: #000; + text-align: center; + font-size: 10px; + font-weight: bold; + text-transform: uppercase; +} +#accounts_controller #main #profile form { + margin: 0 0 0 90px; +} +#accounts_controller #main #profile form h4 { + margin: 10px 0 20px; + border-bottom: 1px solid #f7f7f7; + padding: 0; + color: #f01; + font-size: 16px; +} +#accounts_controller #main #profile form ul.choices li { + width: 30%; +} +#accounts_controller #main #profile form div.extra { + margin-top: 20px; +} +#accounts_controller #main #networks ul { + margin: 0 -10px -10px 0; + padding: 0; + overflow: hidden; +} +#accounts_controller #main #networks ul li:hover { + background: #eee; + display: block; + float: left; + width: 180px; + padding: 10px; + margin: 0 10px 10px 0; + list-style: none; + position: relative; +} +#accounts_controller #main #networks ul li:hover * { + line-height: normal; +} +#accounts_controller #main #networks ul li:hover img { + vertical-align: middle; + float: left; +} +#accounts_controller #main #networks ul li:hover .name { + font-weight: bold; + font-size: 14px; + display: block; + margin: -2px 0 0 42px; +} +#accounts_controller #main #networks ul li:hover small { + font-size: 12px; + color: #eee; + display: block; + margin-left: 42px; +} +#accounts_controller #main #networks ul li:hover small strong { + color: #000; + font-weight: normal; +} +#accounts_controller #main #networks ul li.installed { + background: #fff; + border: 2px solid #000; + padding: 8px; +} +#accounts_controller #main #networks ul li.unavailable .name { + color: #000; +} +#accounts_controller #main #networks ul li.unavailable :hover { + background: #eee; +} +#accounts_controller #main #networks ul li:hover { + background: #f7f7f7; +} +/* Shopping Style Panel */ +#shopping_style div.header a.button.small, +#shopping_style div.header a.btn.small { + float: right; +} +#shopping_style div.content p { + margin: 0 0 10px; +} +#shopping_style div.content p label { + text-transform: uppercase; + font-size: 11px; + display: block; + color: #f01; + font-weight: bold; +} +#shopping_style div.content p span { + color: #000; +} +#shopping_style div.content p span.toggle { + white-space: nowrap; + color: #eee; +} +#shopping_style div.content p :last-child { + margin: 0; +} +#shopping_style div.content p.more { + text-align: left; + font-weight: normal; +} +#shopping_style div.content p.less { + display: none; + margin: 0; +} +/* People Controller */ +#people_controller.index #main div.panel { + float: left; + width: 300px; + margin: 0 20px 0 0; +} +#people_controller.index #main div.panel :last-child { + margin-right: 0; +} +#people_controller.show #content #shopping_style { + float: left; + width: 240px; + margin: 0 20px 0 0; +} +#people_controller.show #content #main { + width: 360px; +} +/* Search Results */ +#search_results { + margin: 0 0 20px; +} +#search_results li :hover small { + color: #bfbfbf; +} +#search div.content { + padding: 20px; +} +#search div.content form { + margin: 0; + float: none; +} +#search div.content form span.submit_and_options { + display: block; +} +#search div.content p { + margin: 0 0 15px; +} +#search div.content h4 { + font-weight: normal; + margin: 0 0 5px; +} +/* Recommendations */ +#recommendations div.browse { + margin: 0; + padding: 0; + background: none; +} +#recommendations div.browse ul { + min-height: 0; +} +/* Blank States */ +div.blank { + padding: 20px; + background: #f2e6e6; + position: relative; + border: 1px solid #e6ccce; + z-index: 1; +} +div.blank h4 { + font-size: 18px; + margin: 0 0 10px; +} +div.blank h4:last-child { + margin: 0; +} +div.blank p { + font-size: 16px; + margin: 0 0 10px; +} +div.blank p:last-child { + margin: 0; +} +div.blank p.with_list_number.large span { + margin-left: 48px; + display: block; + color: #fff; +} +div.blank p.earn span { + font-size: 22px; + color: #fff; + line-height: 48px; + font-weight: bold; +} +div.blank a { + white-space: nowrap; +} +div.blank a.hide { + position: absolute; + top: -5px; + right: -5px; + display: block; + height: 16px; + width: 16px; + padding: 3px; + background: #E7E9F6; +} +div.blank.small { + padding: 10px 20px; +} +div.blank.small h4 { + font-weight: normal; + font-size: 16px; +} +div.blank.small p { + margin: 0; +} +div.blank.tiny { + padding: 10px 20px; +} +div.blank.tiny h4 { + font-weight: normal; + font-size: 14px; +} +div.blank.tiny p { + margin: 0; + font-size: 12px; +} +div.blank.rounded { + margin: 0 0 20px; +} +div.blank.with_border_bottom { + border-bottom: 1px solid #e6ccce; +} +div.blank.no_border_top { + border-top: none; +} +div.blank.no_border_bottom { + border-bottom: none; +} +div.blank.no_side_borders { + border-right: none; + border-left: none; +} +div.panel div.blank { + padding: 10px 20px; + overflow: hidden; + margin: 0; +} +div.panel div.blank h4 { + font-weight: normal; + font-size: 14px; +} +div.panel div.blank p, +div.panel div.blank ul { + margin: 0 0 10px; + font-size: 12px; +} +div.panel div.blank p:last-child, +div.panel div.blank ul:last-child { + margin: 0; +} +#yelow #short { + color: #fea; +} +#yelow #long { + color: #ffeeaa; +} +#yelow #rgba { + color: rgba(255, 238, 170, 0.1); +} +#blue #short { + color: #00f; +} +#blue #long { + color: #0000ff; +} +#blue #rgba { + color: rgba(0, 0, 255, 0.1); +} +#overflow .a { + color: #000000; +} +#overflow .b { + color: #ffffff; +} +#overflow .c { + color: #ffffff; +} +#overflow .d { + color: #00ff00; +} +#grey { + color: #c8c8c8; +} +#808080 { + color: hsl(0, 0%, 50%); +} +#00ff00 { + color: hsl(120, 100%, 50%); +} +/******************\ +* * +* Comment Header * +* * +\******************/ +/* + + Comment + +*/ +/* + * Comment Test + * + * - cloudhead (http://cloudhead.net) + * + */ +/* Colors + * ------ + * #EDF8FC (background blue) + * #166C89 (darkest blue) + * + * Text: + * #333 (standard text) // A comment within a comment! + * #1F9EC9 (standard link) + * + */ +/* @group Variables +------------------- */ +#comments { + /**/ + color: red; + /* A C-style comment */ + background-color: orange; + font-size: 12px; + /* lost comment */ + content: 100%; + border: 1px solid black; + padding: 0; + margin: 2em; +} +/* commented out + #more-comments { + color: grey; + } +*/ +#last { + color: blue; +} +.comma-delimited { + background: url(http://localhost:8081/benchmark/bg.jpg) no-repeat, url(http://localhost:8081/benchmark/bg.png) repeat-x top left, url(http://localhost:8081/benchmark/bg); + text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; + -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; +} +@font-face { + font-family: Headline; + src: local(Futura-Medium), url(http://localhost:8081/benchmark/fonts.svg#MyGeometricModern) format("svg"); +} +.other { + -moz-transform: translate(0, 11em) rotate(-90deg); +} +p:not([class*="lead"]) { + color: black; +} +input[type="text"].class#id[attr=32]:not(1) { + color: white; +} +div#id.class[a=1][b=2].class:not(1) { + color: white; +} +ul.comma > li:not(:only-child)::after { + color: white; +} +ol.comma > li:nth-last-child(2)::after { + color: white; +} +li:nth-child(4n+1), +li:nth-child(-5n), +li:nth-child(-n+2) { + color: white; +} +a[href^="http://"] { + color: black; +} +a[href$="http://"] { + color: black; +} +form[data-disabled] { + color: black; +} +p::before { + color: black; +} +div { + color: black; +} +div { + width: 99%; +} +* { + min-width: 45em; +} +h1, +h2 > a > p, +h3 { + color: none; +} +div.class { + color: blue; +} +div#id { + color: green; +} +.class#id { + color: purple; +} +.one.two.three { + color: grey; +} +@media print { + font-size: 3em; +} +@media screen { + font-size: 10px; +} +@font-face { + font-family: 'Garamond Pro'; + src: url("/fonts/garamond-pro.ttf"); +} +a:hover, +a:link { + color: #999; +} +p, +p:first-child { + text-transform: none; +} +q:lang(no) { + quotes: none; +} +p + h1 { + font-size: 2.2em; +} +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + margin: 1px 0; + padding: 0 auto; + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; +} +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; +} +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: 0.1em; + background-color: #009998; + background-image: url(http://localhost:8081/benchmark/images/image.jpg); + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; +} +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} +#functions { + color: #ff0000; + width: increment(15); + height: undefined("self"); + border-width: add(2, 3); + variable: increment(10); +} +#built-in { + escaped: -Some::weird(#thing, y); + lighten: #ffffff; + darken: #000000; + saturate: #203c31; + desaturate: #29332f; + greyscale: #2e2e2e; + format: "rgb(32, 128, 64)"; + format-string: "hello world"; + eformat: rgb(32, 128, 64); +} +.lazy-eval { + width: 100%; +} +.two-args { + color: blue; + width: 10px; + height: 99%; + two: 2; + three: 3; + border: 2px dotted black; +} +.one-arg { + width: 15px; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.no-parens { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.no-args { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.var-args { + width: 45; + height: 17%; + two: 2; + three: 3; +} +.multi-mix { + width: 10px; + height: 29%; + two: 2; + three: 3; + margin: 4; + padding: 5; +} +body { + padding: 30px; + color: #f00; +} +.scope-mix { + width: 8; +} +.content { + width: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +#same-var-name { + radius: 5px; +} +#var-inside { + width: 10px; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.zero { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.one { + width: 5; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.two { + width: 5; + height: 1%; + two: 2; + three: 3; +} +.three { + three-req: 3; + three: 3; +} +.left { + left: 1; +} +.right { + right: 1; +} +.border-right { + color: black; + border-right: 4px; +} +.border-left { + color: black; + border-left: 4px; +} +.only-right { + right: 33; +} +.only-left { + left: 33; +} +.left-right { + both: 330; +} +.mixin { + border: 1px solid black; +} +.mixout { + border-color: orange; +} +.borders { + border-style: dashed; +} +#namespace .borders { + border-style: dotted; +} +#namespace .biohazard { + content: "death"; +} +#namespace .biohazard .man { + color: transparent; +} +#theme > .mixin { + background-color: grey; +} +#container { + color: black; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + border-color: orange; + background-color: grey; +} +#header .milk { + color: white; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + background-color: grey; +} +#header #cookie { + border-style: dashed; +} +#header #cookie .chips { + border-style: dotted; +} +#header #cookie .chips .calories { + color: black; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + border-color: orange; + background-color: grey; +} +.secure-zone { + color: transparent; +} +.direct { + border-style: dotted; +} +#operations { + color: #111111; + height: 9px; + width: 3em; + subtraction: 0; + division: 1; +} +#operations .spacing { + height: 9px; + width: 3em; +} +.with-variables { + height: 20001%; + width: 10013%; + size: -9995cm; +} +.negative { + height: 30003px; + width: -29999px; +} +.shorthands { + padding: -1px 2px 0 -4px; +} +.colors { + color: #123; + border-color: #334455; + background-color: #000000; +} +.colors .other { + color: #222222; + border-color: #222222; +} +.parens { + border: 2px solid black; + margin: 1px 3px 16 3; + width: 36; + padding: 2px 36px; +} +.more-parens { + padding: 8 4 4 4px; + width: 96; + height: 113; + margin: 12; +} +.nested-parens { + width: 71; + height: 6; +} +.mixed-units { + margin: 2px 4em 1 5pc; + padding: 6px 1em 2px 2; +} +#first > .one { + font-size: 2em; +} +#first > .one > #second .two > #deux { + width: 50%; +} +#first > .one > #second .two > #deux #third { + height: 100%; +} +#first > .one > #second .two > #deux #third:focus { + color: black; +} +#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { + color: purple; +} +#first > .one > #second .two > #deux #fourth, +#first > .one > #second .two > #deux #five, +#first > .one > #second .two > #deux #six { + color: #110000; +} +#first > .one > #second .two > #deux #fourth .seven, +#first > .one > #second .two > #deux #five .seven, +#first > .one > #second .two > #deux #six .seven, +#first > .one > #second .two > #deux #fourth .eight > #nine, +#first > .one > #second .two > #deux #five .eight > #nine, +#first > .one > #second .two > #deux #six .eight > #nine { + border: 1px solid black; +} +#first > .one > #second .two > #deux #fourth #ten, +#first > .one > #second .two > #deux #five #ten, +#first > .one > #second .two > #deux #six #ten { + color: red; +} +.tiny-scope { + color: #989; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.scope1 { + color: 10000%; + border-color: black; +} +.scope1 .scope2 { + color: 10000%; +} +.scope1 .scope2 .scope3 { + color: red; + border-color: black; + background-color: white; +} +h1 a:hover, +h2 a:hover, +h3 a:hover, +h1 p:hover, +h2 p:hover, +h3 p:hover { + color: red; +} +#all { + color: blue; +} +#the { + color: blue; +} +#same { + color: blue; +} +ul, +li, +div, +q, +blockquote, +textarea { + margin: 0; +} +td { + margin: 0; + padding: 0; +} +td, +input { + line-height: 1em; +} +#strings { + background-image: url("http://son-of-a-banana.com"); + quotes: "~" "~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{" "}"; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#single-quote { + quotes: "'" "'"; + content: '""#!&""'; + empty: ''; +} +.variables { + width: 30002%; +} +.variables { + height: 11000%; + color: #888; + font-family: "Trebuchet MS", Verdana, sans-serif; + quotes: "~" "~"; +} +.redefinition { + three: 3; +} +.values { + font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white ; +} +.white, +.space, +.mania { + color: white; +} +.no-semi-column { + color: white; +} +.no-semi-column { + color: white; + white-space: pre; +} +.no-semi-column { + border: 2px solid white; +} +.newlines { + background: the, + great, + wall; + border: 2px + solid + black; +} +#yelow #short { + color: #fea; +} +#yelow #long { + color: #ffeeaa; +} +#yelow #rgba { + color: rgba(255, 238, 170, 0.1); +} +#blue #short { + color: #00f; +} +#blue #long { + color: #0000ff; +} +#blue #rgba { + color: rgba(0, 0, 255, 0.1); +} +#overflow .a { + color: #000000; +} +#overflow .b { + color: #ffffff; +} +#overflow .c { + color: #ffffff; +} +#overflow .d { + color: #00ff00; +} +#grey { + color: #c8c8c8; +} +#808080 { + color: hsl(0, 0%, 50%); +} +#00ff00 { + color: hsl(120, 100%, 50%); +} +/******************\ +* * +* Comment Header * +* * +\******************/ +/* + + Comment + +*/ +/* + * Comment Test + * + * - cloudhead (http://cloudhead.net) + * + */ +/* Colors + * ------ + * #EDF8FC (background blue) + * #166C89 (darkest blue) + * + * Text: + * #333 (standard text) // A comment within a comment! + * #1F9EC9 (standard link) + * + */ +/* @group Variables +------------------- */ +#comments { + /**/ + color: red; + /* A C-style comment */ + background-color: orange; + font-size: 12px; + /* lost comment */ + content: 100%; + border: 1px solid black; + padding: 0; + margin: 2em; +} +/* commented out + #more-comments { + color: grey; + } +*/ +#last { + color: blue; +} +.comma-delimited { + background: url(http://localhost:8081/benchmark/bg.jpg) no-repeat, url(http://localhost:8081/benchmark/bg.png) repeat-x top left, url(http://localhost:8081/benchmark/bg); + text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; + -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; +} +@font-face { + font-family: Headline; + src: local(Futura-Medium), url(http://localhost:8081/benchmark/fonts.svg#MyGeometricModern) format("svg"); +} +.other { + -moz-transform: translate(0, 11em) rotate(-90deg); +} +p:not([class*="lead"]) { + color: black; +} +input[type="text"].class#id[attr=32]:not(1) { + color: white; +} +div#id.class[a=1][b=2].class:not(1) { + color: white; +} +ul.comma > li:not(:only-child)::after { + color: white; +} +ol.comma > li:nth-last-child(2)::after { + color: white; +} +li:nth-child(4n+1), +li:nth-child(-5n), +li:nth-child(-n+2) { + color: white; +} +a[href^="http://"] { + color: black; +} +a[href$="http://"] { + color: black; +} +form[data-disabled] { + color: black; +} +p::before { + color: black; +} +div { + color: black; +} +div { + width: 99%; +} +* { + min-width: 45em; +} +h1, +h2 > a > p, +h3 { + color: none; +} +div.class { + color: blue; +} +div#id { + color: green; +} +.class#id { + color: purple; +} +.one.two.three { + color: grey; +} +@media print { + font-size: 3em; +} +@media screen { + font-size: 10px; +} +@font-face { + font-family: 'Garamond Pro'; + src: url("/fonts/garamond-pro.ttf"); +} +a:hover, +a:link { + color: #999; +} +p, +p:first-child { + text-transform: none; +} +q:lang(no) { + quotes: none; +} +p + h1 { + font-size: 2.2em; +} +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + margin: 1px 0; + padding: 0 auto; + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; +} +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; +} +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: 0.1em; + background-color: #009998; + background-image: url(http://localhost:8081/benchmark/images/image.jpg); + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; +} +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} +#functions { + color: #ff0000; + width: increment(15); + height: undefined("self"); + border-width: add(2, 3); + variable: increment(10); +} +#built-in { + escaped: -Some::weird(#thing, y); + lighten: #ffffff; + darken: #000000; + saturate: #203c31; + desaturate: #29332f; + greyscale: #2e2e2e; + format: "rgb(32, 128, 64)"; + format-string: "hello world"; + eformat: rgb(32, 128, 64); +} +.lazy-eval { + width: 100%; +} +.two-args { + color: blue; + width: 10px; + height: 99%; + two: 2; + three: 3; + border: 2px dotted black; +} +.one-arg { + width: 15px; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.no-parens { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.no-args { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.var-args { + width: 45; + height: 17%; + two: 2; + three: 3; +} +.multi-mix { + width: 10px; + height: 29%; + two: 2; + three: 3; + margin: 4; + padding: 5; +} +body { + padding: 30px; + color: #f00; +} +.scope-mix { + width: 8; +} +.content { + width: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +#same-var-name { + radius: 5px; +} +#var-inside { + width: 10px; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.zero { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.one { + width: 5; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.two { + width: 5; + height: 1%; + two: 2; + three: 3; +} +.three { + three-req: 3; + three: 3; +} +.left { + left: 1; +} +.right { + right: 1; +} +.border-right { + color: black; + border-right: 4px; +} +.border-left { + color: black; + border-left: 4px; +} +.only-right { + right: 33; +} +.only-left { + left: 33; +} +.left-right { + both: 330; +} +.mixin { + border: 1px solid black; +} +.mixout { + border-color: orange; +} +.borders { + border-style: dashed; +} +#namespace .borders { + border-style: dotted; +} +#namespace .biohazard { + content: "death"; +} +#namespace .biohazard .man { + color: transparent; +} +#theme > .mixin { + background-color: grey; +} +#container { + color: black; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + border-color: orange; + background-color: grey; +} +#header .milk { + color: white; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + background-color: grey; +} +#header #cookie { + border-style: dashed; +} +#header #cookie .chips { + border-style: dotted; +} +#header #cookie .chips .calories { + color: black; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; + border-color: orange; + background-color: grey; +} +.secure-zone { + color: transparent; +} +.direct { + border-style: dotted; +} +#operations { + color: #111111; + height: 9px; + width: 3em; + subtraction: 0; + division: 1; +} +#operations .spacing { + height: 9px; + width: 3em; +} +.with-variables { + height: 20001%; + width: 10013%; + size: -9995cm; +} +.negative { + height: 30003px; + width: -29999px; +} +.shorthands { + padding: -1px 2px 0 -4px; +} +.colors { + color: #123; + border-color: #334455; + background-color: #000000; +} +.colors .other { + color: #222222; + border-color: #222222; +} +.parens { + border: 2px solid black; + margin: 1px 3px 16 3; + width: 36; + padding: 2px 36px; +} +.more-parens { + padding: 8 4 4 4px; + width: 96; + height: 113; + margin: 12; +} +.nested-parens { + width: 71; + height: 6; +} +.mixed-units { + margin: 2px 4em 1 5pc; + padding: 6px 1em 2px 2; +} +#first > .one { + font-size: 2em; +} +#first > .one > #second .two > #deux { + width: 50%; +} +#first > .one > #second .two > #deux #third { + height: 100%; +} +#first > .one > #second .two > #deux #third:focus { + color: black; +} +#first > .one > #second .two > #deux #third:focus #fifth > #sixth .seventh #eighth + #ninth { + color: purple; +} +#first > .one > #second .two > #deux #fourth, +#first > .one > #second .two > #deux #five, +#first > .one > #second .two > #deux #six { + color: #110000; +} +#first > .one > #second .two > #deux #fourth .seven, +#first > .one > #second .two > #deux #five .seven, +#first > .one > #second .two > #deux #six .seven, +#first > .one > #second .two > #deux #fourth .eight > #nine, +#first > .one > #second .two > #deux #five .eight > #nine, +#first > .one > #second .two > #deux #six .eight > #nine { + border: 1px solid black; +} +#first > .one > #second .two > #deux #fourth #ten, +#first > .one > #second .two > #deux #five #ten, +#first > .one > #second .two > #deux #six #ten { + color: red; +} +.tiny-scope { + color: #989; + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.scope1 { + color: 10000%; + border-color: black; +} +.scope1 .scope2 { + color: 10000%; +} +.scope1 .scope2 .scope3 { + color: red; + border-color: black; + background-color: white; +} +h1 a:hover, +h2 a:hover, +h3 a:hover, +h1 p:hover, +h2 p:hover, +h3 p:hover { + color: red; +} +#all { + color: blue; +} +#the { + color: blue; +} +#same { + color: blue; +} +ul, +li, +div, +q, +blockquote, +textarea { + margin: 0; +} +td { + margin: 0; + padding: 0; +} +td, +input { + line-height: 1em; +} +#strings { + background-image: url("http://son-of-a-banana.com"); + quotes: "~" "~"; + content: "#*%:&^,)!.(~*})"; + empty: ""; + brackets: "{" "}"; +} +#comments { + content: "/* hello */ // not-so-secret"; +} +#single-quote { + quotes: "'" "'"; + content: '""#!&""'; + empty: ''; +} +.variables { + width: 30002%; +} +.variables { + height: 11000%; + color: #888; + font-family: "Trebuchet MS", Verdana, sans-serif; + quotes: "~" "~"; +} +.redefinition { + three: 3; +} +.values { + font-family: 'Trebuchet', 'Trebuchet', 'Trebuchet'; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white; +} +.whitespace { + color: white ; +} +.white, +.space, +.mania { + color: white; +} +.no-semi-column { + color: white; +} +.no-semi-column { + color: white; + white-space: pre; +} +.no-semi-column { + border: 2px solid white; +} +.newlines { + background: the, + great, + wall; + border: 2px + solid + black; +} +#yelow #short { + color: #fea; +} +#yelow #long { + color: #ffeeaa; +} +#yelow #rgba { + color: rgba(255, 238, 170, 0.1); +} +#blue #short { + color: #00f; +} +#blue #long { + color: #0000ff; +} +#blue #rgba { + color: rgba(0, 0, 255, 0.1); +} +#overflow .a { + color: #000000; +} +#overflow .b { + color: #ffffff; +} +#overflow .c { + color: #ffffff; +} +#overflow .d { + color: #00ff00; +} +#grey { + color: #c8c8c8; +} +#808080 { + color: hsl(0, 0%, 50%); +} +#00ff00 { + color: hsl(120, 100%, 50%); +} +/******************\ +* * +* Comment Header * +* * +\******************/ +/* + + Comment + +*/ +/* + * Comment Test + * + * - cloudhead (http://cloudhead.net) + * + */ +/* Colors + * ------ + * #EDF8FC (background blue) + * #166C89 (darkest blue) + * + * Text: + * #333 (standard text) // A comment within a comment! + * #1F9EC9 (standard link) + * + */ +/* @group Variables +------------------- */ +#comments { + /**/ + color: red; + /* A C-style comment */ + background-color: orange; + font-size: 12px; + /* lost comment */ + content: 100%; + border: 1px solid black; + padding: 0; + margin: 2em; +} +/* commented out + #more-comments { + color: grey; + } +*/ +#last { + color: blue; +} +.comma-delimited { + background: url(http://localhost:8081/benchmark/bg.jpg) no-repeat, url(http://localhost:8081/benchmark/bg.png) repeat-x top left, url(http://localhost:8081/benchmark/bg); + text-shadow: -1px -1px 1px red, 6px 5px 5px yellow; + -moz-box-shadow: 0pt 0pt 2px rgba(255, 255, 255, 0.4) inset, 0pt 4px 6px rgba(255, 255, 255, 0.4) inset; +} +@font-face { + font-family: Headline; + src: local(Futura-Medium), url(http://localhost:8081/benchmark/fonts.svg#MyGeometricModern) format("svg"); +} +.other { + -moz-transform: translate(0, 11em) rotate(-90deg); +} +p:not([class*="lead"]) { + color: black; +} +input[type="text"].class#id[attr=32]:not(1) { + color: white; +} +div#id.class[a=1][b=2].class:not(1) { + color: white; +} +ul.comma > li:not(:only-child)::after { + color: white; +} +ol.comma > li:nth-last-child(2)::after { + color: white; +} +li:nth-child(4n+1), +li:nth-child(-5n), +li:nth-child(-n+2) { + color: white; +} +a[href^="http://"] { + color: black; +} +a[href$="http://"] { + color: black; +} +form[data-disabled] { + color: black; +} +p::before { + color: black; +} +div { + color: black; +} +div { + width: 99%; +} +* { + min-width: 45em; +} +h1, +h2 > a > p, +h3 { + color: none; +} +div.class { + color: blue; +} +div#id { + color: green; +} +.class#id { + color: purple; +} +.one.two.three { + color: grey; +} +@media print { + font-size: 3em; +} +@media screen { + font-size: 10px; +} +@font-face { + font-family: 'Garamond Pro'; + src: url("/fonts/garamond-pro.ttf"); +} +a:hover, +a:link { + color: #999; +} +p, +p:first-child { + text-transform: none; +} +q:lang(no) { + quotes: none; +} +p + h1 { + font-size: 2.2em; +} +#shorthands { + border: 1px solid #000; + font: 12px/16px Arial; + margin: 1px 0; + padding: 0 auto; + background: url("http://www.lesscss.org/spec.html") no-repeat 0 4px; +} +#more-shorthands { + margin: 0; + padding: 1px 0 2px 0; + font: normal small / 20px 'Trebuchet MS', Verdana, sans-serif; +} +.misc { + -moz-border-radius: 2px; + display: -moz-inline-stack; + width: 0.1em; + background-color: #009998; + background-image: url(http://localhost:8081/benchmark/images/image.jpg); + background: -webkit-gradient(linear, left top, left bottom, from(red), to(blue)); + margin: ; +} +#important { + color: red !important; + width: 100%!important; + height: 20px ! important; +} +#functions { + color: #ff0000; + width: increment(15); + height: undefined("self"); + border-width: add(2, 3); + variable: increment(10); +} +#built-in { + escaped: -Some::weird(#thing, y); + lighten: #ffffff; + darken: #000000; + saturate: #203c31; + desaturate: #29332f; + greyscale: #2e2e2e; + format: "rgb(32, 128, 64)"; + format-string: "hello world"; + eformat: rgb(32, 128, 64); +} +.lazy-eval { + width: 100%; +} +.two-args { + color: blue; + width: 10px; + height: 99%; + two: 2; + three: 3; + border: 2px dotted black; +} +.one-arg { + width: 15px; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.no-parens { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.no-args { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.var-args { + width: 45; + height: 17%; + two: 2; + three: 3; +} +.multi-mix { + width: 10px; + height: 29%; + two: 2; + three: 3; + margin: 4; + padding: 5; +} +body { + padding: 30px; + color: #f00; +} +.scope-mix { + width: 8; +} +.content { + width: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +.content .column { + margin: 600px; +} +#same-var-name { + radius: 5px; +} +#var-inside { + width: 10px; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.class .inner { + height: 300; +} +.class .inner .innest { + width: 30; + border-width: 60; +} +.zero { + border: 1px solid black; + width: 5px; + height: 49%; + zero: 0; + one: 1; + two: 2; + three: 3; +} +.one { + width: 5; + height: 49%; + one: 1; + one-req: 1; + two: 2; + three: 3; +} +.two { + width: 5; + height: 1%; + two: 2; + three: 3; +} +.three { + three-req: 3; + three: 3; +} diff --git a/benchmark/browseroptions.js b/benchmark/browseroptions.js new file mode 100644 index 000000000..8728e4d00 --- /dev/null +++ b/benchmark/browseroptions.js @@ -0,0 +1,4 @@ +var less = { + logLevel: 4, + rewriteUrls: 0 +}; \ No newline at end of file diff --git a/benchmark/browserspec.js b/benchmark/browserspec.js new file mode 100644 index 000000000..e8468905e --- /dev/null +++ b/benchmark/browserspec.js @@ -0,0 +1,3 @@ +describe('Benchmark', function() { + testLessEqualsInDocument(); +}); diff --git a/bin/lessc b/bin/lessc old mode 100644 new mode 100755 index c8ea588b3..76a706156 --- a/bin/lessc +++ b/bin/lessc @@ -6,168 +6,144 @@ var path = require('path'); var os = require('os'); var CloneHelper = require('clone'); +var tslib = require('tslib'); var url = require('url'); var fs; - try { - fs = require('graceful-fs'); -} catch (e) { - fs = require('fs'); + fs = require('graceful-fs'); +} +catch (e) { + fs = require('fs'); } - var fs$1 = fs; var Math$1 = { - ALWAYS: 0, - PARENS_DIVISION: 1, - PARENS: 2, - STRICT_LEGACY: 3 + ALWAYS: 0, + PARENS_DIVISION: 1, + PARENS: 2, + STRICT_LEGACY: 3 }; var RewriteUrls = { - OFF: 0, - LOCAL: 1, - ALL: 2 + OFF: 0, + LOCAL: 1, + ALL: 2 }; /* jshint proto: true */ function getLocation(index, inputStream) { - var n = index + 1; - var line = null; - var column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || '').length; - } - - return { - line, - column - }; + var n = index + 1; + var line = null; + var column = -1; + while (--n >= 0 && inputStream.charAt(n) !== '\n') { + column++; + } + if (typeof index === 'number') { + line = (inputStream.slice(0, index).match(/\n/g) || '').length; + } + return { + line: line, + column: column + }; } function copyArray(arr) { - var i; - var length = arr.length; - var copy = new Array(length); - - for (i = 0; i < length; i++) { - copy[i] = arr[i]; - } - - return copy; + var i; + var length = arr.length; + var copy = new Array(length); + for (i = 0; i < length; i++) { + copy[i] = arr[i]; + } + return copy; } function clone(obj) { - var cloned = {}; - - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - cloned[prop] = obj[prop]; + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } } - } - - return cloned; + return cloned; } function defaults(obj1, obj2) { - var newObj = obj2 || {}; - - if (!obj2._defaults) { - newObj = {}; - - var _defaults = CloneHelper(obj1); - - newObj._defaults = _defaults; - var cloned = obj2 ? CloneHelper(obj2) : {}; - Object.assign(newObj, _defaults, cloned); - } - - return newObj; + var newObj = obj2 || {}; + if (!obj2._defaults) { + newObj = {}; + var defaults_1 = CloneHelper(obj1); + newObj._defaults = defaults_1; + var cloned = obj2 ? CloneHelper(obj2) : {}; + Object.assign(newObj, defaults_1, cloned); + } + return newObj; } function copyOptions(obj1, obj2) { - if (obj2 && obj2._defaults) { - return obj2; - } - - var opts = defaults(obj1, obj2); - - if (opts.strictMath) { - opts.math = Math$1.STRICT_LEGACY; - } // Back compat with changed relativeUrls option - - - if (opts.relativeUrls) { - opts.rewriteUrls = RewriteUrls.ALL; - } - - if (typeof opts.math === 'string') { - switch (opts.math.toLowerCase()) { - case 'always': - opts.math = Math$1.ALWAYS; - break; - - case 'parens-division': - opts.math = Math$1.PARENS_DIVISION; - break; - - case 'strict': - case 'parens': - opts.math = Math$1.PARENS; - break; - - case 'strict-legacy': + if (obj2 && obj2._defaults) { + return obj2; + } + var opts = defaults(obj1, obj2); + if (opts.strictMath) { opts.math = Math$1.STRICT_LEGACY; } - } - - if (typeof opts.rewriteUrls === 'string') { - switch (opts.rewriteUrls.toLowerCase()) { - case 'off': - opts.rewriteUrls = RewriteUrls.OFF; - break; - - case 'local': - opts.rewriteUrls = RewriteUrls.LOCAL; - break; - - case 'all': + // Back compat with changed relativeUrls option + if (opts.relativeUrls) { opts.rewriteUrls = RewriteUrls.ALL; - break; } - } - - return opts; + if (typeof opts.math === 'string') { + switch (opts.math.toLowerCase()) { + case 'always': + opts.math = Math$1.ALWAYS; + break; + case 'parens-division': + opts.math = Math$1.PARENS_DIVISION; + break; + case 'strict': + case 'parens': + opts.math = Math$1.PARENS; + break; + case 'strict-legacy': + opts.math = Math$1.STRICT_LEGACY; + } + } + if (typeof opts.rewriteUrls === 'string') { + switch (opts.rewriteUrls.toLowerCase()) { + case 'off': + opts.rewriteUrls = RewriteUrls.OFF; + break; + case 'local': + opts.rewriteUrls = RewriteUrls.LOCAL; + break; + case 'all': + opts.rewriteUrls = RewriteUrls.ALL; + break; + } + } + return opts; } function merge(obj1, obj2) { - for (var prop in obj2) { - if (obj2.hasOwnProperty(prop)) { - obj1[prop] = obj2[prop]; + for (var prop in obj2) { + if (obj2.hasOwnProperty(prop)) { + obj1[prop] = obj2[prop]; + } } - } - - return obj1; + return obj1; } -function flattenArray(arr) { - var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - - for (var i = 0, length = arr.length; i < length; i++) { - var value = arr[i]; - - if (Array.isArray(value)) { - flattenArray(value, result); - } else { - if (value !== undefined) { - result.push(value); - } - } - } - - return result; +function flattenArray(arr, result) { + if (result === void 0) { result = []; } + for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) { + var value = arr[i_1]; + if (Array.isArray(value)) { + flattenArray(value, result); + } + else { + if (value !== undefined) { + result.push(value); + } + } + } + return result; } var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, getLocation: getLocation, copyArray: copyArray, clone: clone, @@ -178,1479 +154,1038 @@ var utils = /*#__PURE__*/Object.freeze({ }); var environment = { - encodeBase64: function encodeBase64(str) { - // Avoid Buffer constructor on newer versions of Node.js. - var buffer = Buffer.from ? Buffer.from(str) : new Buffer(str); - return buffer.toString('base64'); - }, - mimeLookup: function mimeLookup(filename) { - return require('mime').lookup(filename); - }, - charsetLookup: function charsetLookup(mime) { - return require('mime').charsets.lookup(mime); - }, - getSourceMapGenerator: function getSourceMapGenerator() { - return require('source-map').SourceMapGenerator; - } + encodeBase64: function encodeBase64(str) { + // Avoid Buffer constructor on newer versions of Node.js. + var buffer = (Buffer.from ? Buffer.from(str) : (new Buffer(str))); + return buffer.toString('base64'); + }, + mimeLookup: function (filename) { + return require('mime').lookup(filename); + }, + charsetLookup: function (mime) { + return require('mime').charsets.lookup(mime); + }, + getSourceMapGenerator: function getSourceMapGenerator() { + return require('source-map').SourceMapGenerator; + } }; -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} - -function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } -} - -function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; -} - -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) _setPrototypeOf(subClass, superClass); -} - -function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); -} - -function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); -} - -function isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); - return true; - } catch (e) { - return false; - } -} - -function _construct(Parent, args, Class) { - if (isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); -} - -function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; -} - -function _possibleConstructorReturn(self, call) { - if (call && (typeof call === "object" || typeof call === "function")) { - return call; - } - - return _assertThisInitialized(self); -} - -function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); -} - -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } -} - -function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); -} - -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); -} - -var AbstractFileManager = -/*#__PURE__*/ -function () { - function AbstractFileManager() { - _classCallCheck(this, AbstractFileManager); - } - - _createClass(AbstractFileManager, [{ - key: "getPath", - value: function getPath(filename) { - var j = filename.lastIndexOf('?'); - - if (j > 0) { - filename = filename.slice(0, j); - } - - j = filename.lastIndexOf('/'); - - if (j < 0) { - j = filename.lastIndexOf('\\'); - } - - if (j < 0) { - return ''; - } - - return filename.slice(0, j + 1); - } - }, { - key: "tryAppendExtension", - value: function tryAppendExtension(path, ext) { - return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext; - } - }, { - key: "tryAppendLessExtension", - value: function tryAppendLessExtension(path) { - return this.tryAppendExtension(path, '.less'); - } - }, { - key: "supportsSync", - value: function supportsSync() { - return false; - } - }, { - key: "alwaysMakePathsAbsolute", - value: function alwaysMakePathsAbsolute() { - return false; - } - }, { - key: "isPathAbsolute", - value: function isPathAbsolute(filename) { - return /^(?:[a-z-]+:|\/|\\|#)/i.test(filename); - } // TODO: pull out / replace? - - }, { - key: "join", - value: function join(basePath, laterPath) { - if (!basePath) { - return laterPath; - } - - return basePath + laterPath; - } - }, { - key: "pathDiff", - value: function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - var urlParts = this.extractUrlParts(url); - var baseUrlParts = this.extractUrlParts(baseUrl); - var i; - var max; - var urlDirectories; - var baseUrlDirectories; - var diff = ''; - - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ''; - } - - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - - for (i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { - break; - } - } - - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - - for (i = 0; i < baseUrlDirectories.length - 1; i++) { - diff += '../'; - } - - for (i = 0; i < urlDirectories.length - 1; i++) { - diff += `${urlDirectories[i]}/`; - } - - return diff; +var AbstractFileManager = /** @class */ (function () { + function AbstractFileManager() { } - }, { - key: "extractUrlParts", - // helper function, not part of API - value: function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol://hostname/ OR / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; - var urlParts = url.match(urlPartsRegex); - var returner = {}; - var rawDirectories = []; - var directories = []; - var i; - var baseUrlParts; - - if (!urlParts) { - throw new Error(`Could not parse sheet href - '${url}'`); - } // Stylesheets in IE don't always return the full path - - - if (baseUrl && (!urlParts[1] || urlParts[2])) { - baseUrlParts = baseUrl.match(urlPartsRegex); - - if (!baseUrlParts) { - throw new Error(`Could not parse page url - '${baseUrl}'`); + AbstractFileManager.prototype.getPath = function (filename) { + var j = filename.lastIndexOf('?'); + if (j > 0) { + filename = filename.slice(0, j); } - - urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; - - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; + j = filename.lastIndexOf('/'); + if (j < 0) { + j = filename.lastIndexOf('\\'); } - } - - if (urlParts[3]) { - rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); // collapse '..' and skip '.' - - for (i = 0; i < rawDirectories.length; i++) { - if (rawDirectories[i] === '..') { - directories.pop(); - } else if (rawDirectories[i] !== '.') { - directories.push(rawDirectories[i]); - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); - returner.path = (urlParts[1] || '') + directories.join('/'); - returner.filename = urlParts[4]; - returner.fileUrl = returner.path + (urlParts[4] || ''); - returner.url = returner.fileUrl + (urlParts[5] || ''); - return returner; - } - }]); - - return AbstractFileManager; -}(); - -var FileManager = -/*#__PURE__*/ -function (_AbstractFileManager) { - _inherits(FileManager, _AbstractFileManager); - - function FileManager() { - var _this; - - _classCallCheck(this, FileManager); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(FileManager).call(this)); - _this.contents = {}; - return _this; - } - - _createClass(FileManager, [{ - key: "supports", - value: function supports(filename, currentDirectory, options, environment) { - return true; - } - }, { - key: "supportsSync", - value: function supportsSync(filename, currentDirectory, options, environment) { - return true; - } - }, { - key: "loadFile", - value: function loadFile(filename, currentDirectory, options, environment, callback) { - var fullFilename; - var isAbsoluteFilename = this.isPathAbsolute(filename); - var filenamesTried = []; - var self = this; - var prefix = filename.slice(0, 1); - var explicit = prefix === '.' || prefix === '/'; - var result = null; - var isNodeModule = false; - var npmPrefix = 'npm://'; - options = options || {}; - var paths = isAbsoluteFilename ? [''] : [currentDirectory]; - - if (options.paths) { - paths.push.apply(paths, _toConsumableArray(options.paths)); - } - - if (!isAbsoluteFilename && paths.indexOf('.') === -1) { - paths.push('.'); - } - - var prefixes = options.prefixes || ['']; - var fileParts = this.extractUrlParts(filename); - - if (options.syncImport) { - getFileData(returnData, returnData); - - if (callback) { - callback(result.error, result); - } else { - return result; - } - } else { - // promise is guaranteed to be asyncronous - // which helps as it allows the file handle - // to be closed before it continues with the next file - return new Promise(getFileData); - } - - function returnData(data) { - if (!data.filename) { - result = { - error: data - }; - } else { - result = data; - } - } - - function getFileData(fulfill, reject) { - (function tryPathIndex(i) { - if (i < paths.length) { - (function tryPrefix(j) { - if (j < prefixes.length) { - isNodeModule = false; - fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename; - - if (paths[i]) { - fullFilename = path.join(paths[i], fullFilename); + if (j < 0) { + return ''; + } + return filename.slice(0, j + 1); + }; + AbstractFileManager.prototype.isPathWithExtension = function (path, ext) { + var extPos = path.lastIndexOf(ext); + return extPos !== -1 && extPos === path.length - ext.length; + }; + AbstractFileManager.prototype.tryAppendExtension = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return path; + } + return path + ext; + }; + AbstractFileManager.prototype.tryAppendLessExtension = function (path) { + return this.tryAppendExtension(path, '.less'); + }; + AbstractFileManager.prototype.supportsSync = function () { return false; }; + AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () { return false; }; + AbstractFileManager.prototype.isPathAbsolute = function (filename) { + return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename); + }; + // TODO: pull out / replace? + AbstractFileManager.prototype.join = function (basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return basePath + laterPath; + }; + AbstractFileManager.prototype.pathDiff = function (url, baseUrl) { + // diff between two paths to create a relative path + var urlParts = this.extractUrlParts(url); + var baseUrlParts = this.extractUrlParts(baseUrl); + var i; + var max; + var urlDirectories; + var baseUrlDirectories; + var diff = ''; + if (urlParts.hostPart !== baseUrlParts.hostPart) { + return ''; + } + max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); + for (i = 0; i < max; i++) { + if (baseUrlParts.directories[i] !== urlParts.directories[i]) { + break; + } + } + baseUrlDirectories = baseUrlParts.directories.slice(i); + urlDirectories = urlParts.directories.slice(i); + for (i = 0; i < baseUrlDirectories.length - 1; i++) { + diff += '../'; + } + for (i = 0; i < urlDirectories.length - 1; i++) { + diff += urlDirectories[i] + "/"; + } + return diff; + }; + // helper function, not part of API + AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) { + // urlParts[1] = protocol://hostname/ OR / + // urlParts[2] = / if path relative to host base + // urlParts[3] = directories + // urlParts[4] = filename + // urlParts[5] = parameters + var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; + var urlParts = url.match(urlPartsRegex); + var returner = {}; + var rawDirectories = []; + var directories = []; + var i; + var baseUrlParts; + if (!urlParts) { + throw new Error("Could not parse sheet href - '" + url + "'"); + } + // Stylesheets in IE don't always return the full path + if (baseUrl && (!urlParts[1] || urlParts[2])) { + baseUrlParts = baseUrl.match(urlPartsRegex); + if (!baseUrlParts) { + throw new Error("Could not parse page url - '" + baseUrl + "'"); + } + urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; + if (!urlParts[2]) { + urlParts[3] = baseUrlParts[3] + urlParts[3]; + } + } + if (urlParts[3]) { + rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); + // collapse '..' and skip '.' + for (i = 0; i < rawDirectories.length; i++) { + if (rawDirectories[i] === '..') { + directories.pop(); } - - if (!explicit && paths[i] === '.') { - try { - fullFilename = require.resolve(fullFilename); - isNodeModule = true; - } catch (e) { - filenamesTried.push(npmPrefix + fullFilename); - tryWithExtension(); - } - } else { - tryWithExtension(); + else if (rawDirectories[i] !== '.') { + directories.push(rawDirectories[i]); } + } + } + returner.hostPart = urlParts[1]; + returner.directories = directories; + returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); + returner.path = (urlParts[1] || '') + directories.join('/'); + returner.filename = urlParts[4]; + returner.fileUrl = returner.path + (urlParts[4] || ''); + returner.url = returner.fileUrl + (urlParts[5] || ''); + return returner; + }; + return AbstractFileManager; +}()); - function tryWithExtension() { - var extFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename; - - if (extFilename !== fullFilename && !explicit && paths[i] === '.') { - try { - fullFilename = require.resolve(extFilename); - isNodeModule = true; - } catch (e) { - filenamesTried.push(npmPrefix + extFilename); - fullFilename = extFilename; - } - } else { - fullFilename = extFilename; - } +var FileManager = /** @class */ (function (_super) { + tslib.__extends(FileManager, _super); + function FileManager() { + var _this = _super.call(this) || this; + _this.contents = {}; + return _this; + } + FileManager.prototype.supports = function (filename, currentDirectory, options, environment) { + return true; + }; + FileManager.prototype.supportsSync = function (filename, currentDirectory, options, environment) { + return true; + }; + FileManager.prototype.getPossibleFileExtensions = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return ['']; + } + return ['', ext]; + }; + FileManager.prototype.loadFile = function (filename, currentDirectory, options, environment, callback) { + var fullFilename; + var isAbsoluteFilename = this.isPathAbsolute(filename); + var filenamesTried = []; + var prefix = filename.slice(0, 1); + var explicit = prefix === '.' || prefix === '/'; + var result = null; + var isNodeModule = false; + var npmPrefix = 'npm://'; + options = options || {}; + var paths = isAbsoluteFilename ? [''] : [currentDirectory]; + if (options.paths) { + paths.push.apply(paths, options.paths); + } + if (!isAbsoluteFilename && paths.indexOf('.') === -1) { + paths.push('.'); + } + var prefixes = options.prefixes || ['']; + var extensions = this.getPossibleFileExtensions(filename, options.ext); + var fileParts = this.extractUrlParts(filename); + if (options.syncImport) { + getFileData(returnData, returnData); + if (callback) { + callback(result.error, result); + } + else { + return result; + } + } + else { + // promise is guaranteed to be asyncronous + // which helps as it allows the file handle + // to be closed before it continues with the next file + return new Promise(getFileData); + } + function returnData(data) { + if (!data.filename) { + result = { error: data }; + } + else { + result = data; + } + } + function getFileData(fulfill, reject) { + (function tryPathIndex(i) { + if (i < paths.length) { + (function tryPrefix(j) { + if (j < prefixes.length) { + (function tryExtension(k) { + if (k < extensions.length) { + isNodeModule = false; + fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename + extensions[k]; + if (paths[i]) { + fullFilename = path.join(paths[i], fullFilename); + } + if (!explicit && paths[i] === '.') { + try { + fullFilename = require.resolve(fullFilename); + isNodeModule = true; + } + catch (e) { + filenamesTried.push(npmPrefix + fullFilename); + } + } + var readFileArgs = [fullFilename]; + if (!options.rawBuffer) { + readFileArgs.push('utf-8'); + } + if (options.syncImport) { + try { + var data = fs$1.readFileSync.apply(this, readFileArgs); + fulfill({ contents: data, filename: fullFilename }); + } + catch (e) { + filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); + return tryExtension(k + 1); + } + } + else { + readFileArgs.push(function (e, data) { + if (e) { + filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); + return tryExtension(k + 1); + } + fulfill({ contents: data, filename: fullFilename }); + }); + fs$1.readFile.apply(this, readFileArgs); + } + } + else { + tryPrefix(j + 1); + } + })(0); + } + else { + tryPathIndex(i + 1); + } + })(0); } - - var modified = false; - - if (self.contents[fullFilename]) { - try { - var stat = fs$1.statSync.apply(this, [fullFilename]); - - if (stat.mtime.getTime() === self.contents[fullFilename].mtime.getTime()) { - fulfill({ - contents: self.contents[fullFilename].data, - filename: fullFilename - }); - } else { - modified = true; - } - } catch (e) { - modified = true; - } + else { + reject({ type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(',') }); } - - if (modified || !self.contents[fullFilename]) { - var readFileArgs = [fullFilename]; - - if (!options.rawBuffer) { - readFileArgs.push('utf-8'); - } - - if (options.syncImport) { - try { - var data = fs$1.readFileSync.apply(this, readFileArgs); - var stat = fs$1.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { - data, - mtime: stat.mtime - }; - fulfill({ - contents: data, - filename: fullFilename - }); - } catch (e) { - filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); - return tryPrefix(j + 1); - } - } else { - readFileArgs.push(function (e, data) { - if (e) { - filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); - return tryPrefix(j + 1); - } - - var stat = fs$1.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { - data, - mtime: stat.mtime - }; - fulfill({ - contents: data, - filename: fullFilename - }); - }); - fs$1.readFile.apply(this, readFileArgs); - } - } - } else { - tryPathIndex(i + 1); - } - })(0); - } else { - reject({ - type: 'File', - message: `'${filename}' wasn't found. Tried - ${filenamesTried.join(',')}` - }); - } - })(0); - } - } - }, { - key: "loadFileSync", - value: function loadFileSync(filename, currentDirectory, options, environment) { - options.syncImport = true; - return this.loadFile(filename, currentDirectory, options, environment); - } - }]); - - return FileManager; -}(AbstractFileManager); + }(0)); + } + }; + FileManager.prototype.loadFileSync = function (filename, currentDirectory, options, environment) { + options.syncImport = true; + return this.loadFile(filename, currentDirectory, options, environment); + }; + return FileManager; +}(AbstractFileManager)); var logger = { - error: function error(msg) { - this._fireEvent('error', msg); - }, - warn: function warn(msg) { - this._fireEvent('warn', msg); - }, - info: function info(msg) { - this._fireEvent('info', msg); - }, - debug: function debug(msg) { - this._fireEvent('debug', msg); - }, - addListener: function addListener(listener) { - this._listeners.push(listener); - }, - removeListener: function removeListener(listener) { - for (var i = 0; i < this._listeners.length; i++) { - if (this._listeners[i] === listener) { - this._listeners.splice(i, 1); - - return; - } - } - }, - _fireEvent: function _fireEvent(type, msg) { - for (var i = 0; i < this._listeners.length; i++) { - var logFunction = this._listeners[i][type]; - - if (logFunction) { - logFunction(msg); - } - } - }, - _listeners: [] + error: function (msg) { + this._fireEvent('error', msg); + }, + warn: function (msg) { + this._fireEvent('warn', msg); + }, + info: function (msg) { + this._fireEvent('info', msg); + }, + debug: function (msg) { + this._fireEvent('debug', msg); + }, + addListener: function (listener) { + this._listeners.push(listener); + }, + removeListener: function (listener) { + for (var i_1 = 0; i_1 < this._listeners.length; i_1++) { + if (this._listeners[i_1] === listener) { + this._listeners.splice(i_1, 1); + return; + } + } + }, + _fireEvent: function (type, msg) { + for (var i_2 = 0; i_2 < this._listeners.length; i_2++) { + var logFunction = this._listeners[i_2][type]; + if (logFunction) { + logFunction(msg); + } + } + }, + _listeners: [] }; var isUrlRe = /^(?:https?:)?\/\//i; var request; - -var UrlFileManager = -/*#__PURE__*/ -function (_AbstractFileManager) { - _inherits(UrlFileManager, _AbstractFileManager); - - function UrlFileManager() { - _classCallCheck(this, UrlFileManager); - - return _possibleConstructorReturn(this, _getPrototypeOf(UrlFileManager).apply(this, arguments)); - } - - _createClass(UrlFileManager, [{ - key: "supports", - value: function supports(filename, currentDirectory, options, environment) { - return isUrlRe.test(filename) || isUrlRe.test(currentDirectory); - } - }, { - key: "loadFile", - value: function loadFile(filename, currentDirectory, options, environment) { - return new Promise(function (fulfill, reject) { - if (request === undefined) { - try { - request = require('request'); - } catch (e) { - request = null; - } - } - - if (!request) { - reject({ - type: 'File', - message: 'optional dependency \'request\' required to import over http(s)\n' - }); - return; - } - - var urlStr = isUrlRe.test(filename) ? filename : url.resolve(currentDirectory, filename); - var urlObj = url.parse(urlStr); - - if (!urlObj.protocol) { - urlObj.protocol = 'http'; - urlStr = urlObj.format(); - } - - request.get({ - uri: urlStr, - strictSSL: !options.insecure - }, function (error, res, body) { - if (error) { - reject({ - type: 'File', - message: `resource '${urlStr}' gave this Error:\n ${error}\n` - }); - return; - } - - if (res && res.statusCode === 404) { - reject({ - type: 'File', - message: `resource '${urlStr}' was not found\n` +var UrlFileManager = /** @class */ (function (_super) { + tslib.__extends(UrlFileManager, _super); + function UrlFileManager() { + return _super !== null && _super.apply(this, arguments) || this; + } + UrlFileManager.prototype.supports = function (filename, currentDirectory, options, environment) { + return isUrlRe.test(filename) || isUrlRe.test(currentDirectory); + }; + UrlFileManager.prototype.loadFile = function (filename, currentDirectory, options, environment) { + return new Promise(function (fulfill, reject) { + if (request === undefined) { + try { + request = require('request'); + } + catch (e) { + request = null; + } + } + if (!request) { + reject({ type: 'File', message: 'optional dependency \'request\' required to import over http(s)\n' }); + return; + } + var urlStr = isUrlRe.test(filename) ? filename : url.resolve(currentDirectory, filename); + var urlObj = url.parse(urlStr); + if (!urlObj.protocol) { + urlObj.protocol = 'http'; + urlStr = urlObj.format(); + } + request.get({ uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) { + if (error) { + reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n " + error + "\n" }); + return; + } + if (res && res.statusCode === 404) { + reject({ type: 'File', message: "resource '" + urlStr + "' was not found\n" }); + return; + } + if (!body) { + logger.warn("Warning: Empty body (HTTP " + res.statusCode + ") returned by \"" + urlStr + "\""); + } + fulfill({ contents: body, filename: urlStr }); }); - return; - } - - if (!body) { - logger.warn(`Warning: Empty body (HTTP ${res.statusCode}) returned by "${urlStr}"`); - } - - fulfill({ - contents: body, - filename: urlStr - }); }); - }); - } - }]); - - return UrlFileManager; -}(AbstractFileManager); + }; + return UrlFileManager; +}(AbstractFileManager)); var colors = { - 'aliceblue': '#f0f8ff', - 'antiquewhite': '#faebd7', - 'aqua': '#00ffff', - 'aquamarine': '#7fffd4', - 'azure': '#f0ffff', - 'beige': '#f5f5dc', - 'bisque': '#ffe4c4', - 'black': '#000000', - 'blanchedalmond': '#ffebcd', - 'blue': '#0000ff', - 'blueviolet': '#8a2be2', - 'brown': '#a52a2a', - 'burlywood': '#deb887', - 'cadetblue': '#5f9ea0', - 'chartreuse': '#7fff00', - 'chocolate': '#d2691e', - 'coral': '#ff7f50', - 'cornflowerblue': '#6495ed', - 'cornsilk': '#fff8dc', - 'crimson': '#dc143c', - 'cyan': '#00ffff', - 'darkblue': '#00008b', - 'darkcyan': '#008b8b', - 'darkgoldenrod': '#b8860b', - 'darkgray': '#a9a9a9', - 'darkgrey': '#a9a9a9', - 'darkgreen': '#006400', - 'darkkhaki': '#bdb76b', - 'darkmagenta': '#8b008b', - 'darkolivegreen': '#556b2f', - 'darkorange': '#ff8c00', - 'darkorchid': '#9932cc', - 'darkred': '#8b0000', - 'darksalmon': '#e9967a', - 'darkseagreen': '#8fbc8f', - 'darkslateblue': '#483d8b', - 'darkslategray': '#2f4f4f', - 'darkslategrey': '#2f4f4f', - 'darkturquoise': '#00ced1', - 'darkviolet': '#9400d3', - 'deeppink': '#ff1493', - 'deepskyblue': '#00bfff', - 'dimgray': '#696969', - 'dimgrey': '#696969', - 'dodgerblue': '#1e90ff', - 'firebrick': '#b22222', - 'floralwhite': '#fffaf0', - 'forestgreen': '#228b22', - 'fuchsia': '#ff00ff', - 'gainsboro': '#dcdcdc', - 'ghostwhite': '#f8f8ff', - 'gold': '#ffd700', - 'goldenrod': '#daa520', - 'gray': '#808080', - 'grey': '#808080', - 'green': '#008000', - 'greenyellow': '#adff2f', - 'honeydew': '#f0fff0', - 'hotpink': '#ff69b4', - 'indianred': '#cd5c5c', - 'indigo': '#4b0082', - 'ivory': '#fffff0', - 'khaki': '#f0e68c', - 'lavender': '#e6e6fa', - 'lavenderblush': '#fff0f5', - 'lawngreen': '#7cfc00', - 'lemonchiffon': '#fffacd', - 'lightblue': '#add8e6', - 'lightcoral': '#f08080', - 'lightcyan': '#e0ffff', - 'lightgoldenrodyellow': '#fafad2', - 'lightgray': '#d3d3d3', - 'lightgrey': '#d3d3d3', - 'lightgreen': '#90ee90', - 'lightpink': '#ffb6c1', - 'lightsalmon': '#ffa07a', - 'lightseagreen': '#20b2aa', - 'lightskyblue': '#87cefa', - 'lightslategray': '#778899', - 'lightslategrey': '#778899', - 'lightsteelblue': '#b0c4de', - 'lightyellow': '#ffffe0', - 'lime': '#00ff00', - 'limegreen': '#32cd32', - 'linen': '#faf0e6', - 'magenta': '#ff00ff', - 'maroon': '#800000', - 'mediumaquamarine': '#66cdaa', - 'mediumblue': '#0000cd', - 'mediumorchid': '#ba55d3', - 'mediumpurple': '#9370d8', - 'mediumseagreen': '#3cb371', - 'mediumslateblue': '#7b68ee', - 'mediumspringgreen': '#00fa9a', - 'mediumturquoise': '#48d1cc', - 'mediumvioletred': '#c71585', - 'midnightblue': '#191970', - 'mintcream': '#f5fffa', - 'mistyrose': '#ffe4e1', - 'moccasin': '#ffe4b5', - 'navajowhite': '#ffdead', - 'navy': '#000080', - 'oldlace': '#fdf5e6', - 'olive': '#808000', - 'olivedrab': '#6b8e23', - 'orange': '#ffa500', - 'orangered': '#ff4500', - 'orchid': '#da70d6', - 'palegoldenrod': '#eee8aa', - 'palegreen': '#98fb98', - 'paleturquoise': '#afeeee', - 'palevioletred': '#d87093', - 'papayawhip': '#ffefd5', - 'peachpuff': '#ffdab9', - 'peru': '#cd853f', - 'pink': '#ffc0cb', - 'plum': '#dda0dd', - 'powderblue': '#b0e0e6', - 'purple': '#800080', - 'rebeccapurple': '#663399', - 'red': '#ff0000', - 'rosybrown': '#bc8f8f', - 'royalblue': '#4169e1', - 'saddlebrown': '#8b4513', - 'salmon': '#fa8072', - 'sandybrown': '#f4a460', - 'seagreen': '#2e8b57', - 'seashell': '#fff5ee', - 'sienna': '#a0522d', - 'silver': '#c0c0c0', - 'skyblue': '#87ceeb', - 'slateblue': '#6a5acd', - 'slategray': '#708090', - 'slategrey': '#708090', - 'snow': '#fffafa', - 'springgreen': '#00ff7f', - 'steelblue': '#4682b4', - 'tan': '#d2b48c', - 'teal': '#008080', - 'thistle': '#d8bfd8', - 'tomato': '#ff6347', - 'turquoise': '#40e0d0', - 'violet': '#ee82ee', - 'wheat': '#f5deb3', - 'white': '#ffffff', - 'whitesmoke': '#f5f5f5', - 'yellow': '#ffff00', - 'yellowgreen': '#9acd32' + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgrey': '#a9a9a9', + 'darkgreen': '#006400', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'grey': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgrey': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370d8', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#d87093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'rebeccapurple': '#663399', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32' }; var unitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1 / (2 * Math.PI), - 'deg': 1 / 360, - 'grad': 1 / 400, - 'turn': 1 - } -}; - -var data = { - colors, - unitConversions + length: { + 'm': 1, + 'cm': 0.01, + 'mm': 0.001, + 'in': 0.0254, + 'px': 0.0254 / 96, + 'pt': 0.0254 / 72, + 'pc': 0.0254 / 72 * 12 + }, + duration: { + 's': 1, + 'ms': 0.001 + }, + angle: { + 'rad': 1 / (2 * Math.PI), + 'deg': 1 / 360, + 'grad': 1 / 400, + 'turn': 1 + } }; -var Node = -/*#__PURE__*/ -function () { - function Node() { - _classCallCheck(this, Node); - - this.parent = null; - this.visibilityBlocks = undefined; - this.nodeVisible = undefined; - this.rootNode = null; - this.parsed = null; - var self = this; - Object.defineProperty(this, 'currentFileInfo', { - get: function get() { - return self.fileInfo(); - } - }); - Object.defineProperty(this, 'index', { - get: function get() { - return self.getIndex(); - } - }); - } - - _createClass(Node, [{ - key: "setParent", - value: function setParent(nodes, parent) { - function set(node) { - if (node && node instanceof Node) { - node.parent = parent; - } - } - - if (Array.isArray(nodes)) { - nodes.forEach(set); - } else { - set(nodes); - } - } - }, { - key: "getIndex", - value: function getIndex() { - return this._index || this.parent && this.parent.getIndex() || 0; - } - }, { - key: "fileInfo", - value: function fileInfo() { - return this._fileInfo || this.parent && this.parent.fileInfo() || {}; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return false; - } - }, { - key: "toCSS", - value: function toCSS(context) { - var strs = []; - this.genCSS(context, { - add: function add(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function isEmpty() { - return strs.length === 0; - } - }); - return strs.join(''); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.value); - } - }, { - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval() { - return this; - } - }, { - key: "_operate", - value: function _operate(context, op, a, b) { - switch (op) { - case '+': - return a + b; - - case '-': - return a - b; - - case '*': - return a * b; +var data = { colors: colors, unitConversions: unitConversions }; - case '/': - return a / b; - } - } - }, { - key: "fround", - value: function fround(context, value) { - var precision = context && context.numPrecision; // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: - - return precision ? Number((value + 2e-16).toFixed(precision)) : value; - } // Returns true if this node represents root of ast imported by reference - - }, { - key: "blocksVisibility", - value: function blocksVisibility() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - return this.visibilityBlocks !== 0; - } - }, { - key: "addVisibilityBlock", - value: function addVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - this.visibilityBlocks = this.visibilityBlocks + 1; - } - }, { - key: "removeVisibilityBlock", - value: function removeVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - this.visibilityBlocks = this.visibilityBlocks - 1; - } // Turns on node visibility - if called node will be shown in output regardless +var Node = /** @class */ (function () { + function Node() { + this.parent = null; + this.visibilityBlocks = undefined; + this.nodeVisible = undefined; + this.rootNode = null; + this.parsed = null; + var self = this; + Object.defineProperty(this, 'currentFileInfo', { + get: function () { return self.fileInfo(); } + }); + Object.defineProperty(this, 'index', { + get: function () { return self.getIndex(); } + }); + } + Node.prototype.setParent = function (nodes, parent) { + function set(node) { + if (node && node instanceof Node) { + node.parent = parent; + } + } + if (Array.isArray(nodes)) { + nodes.forEach(set); + } + else { + set(nodes); + } + }; + Node.prototype.getIndex = function () { + return this._index || (this.parent && this.parent.getIndex()) || 0; + }; + Node.prototype.fileInfo = function () { + return this._fileInfo || (this.parent && this.parent.fileInfo()) || {}; + }; + Node.prototype.isRulesetLike = function () { + return false; + }; + Node.prototype.toCSS = function (context) { + var strs = []; + this.genCSS(context, { + add: function (chunk, fileInfo, index) { + strs.push(chunk); + }, + isEmpty: function () { + return strs.length === 0; + } + }); + return strs.join(''); + }; + Node.prototype.genCSS = function (context, output) { + output.add(this.value); + }; + Node.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Node.prototype.eval = function () { return this; }; + Node.prototype._operate = function (context, op, a, b) { + switch (op) { + case '+': return a + b; + case '-': return a - b; + case '*': return a * b; + case '/': return a / b; + } + }; + Node.prototype.fround = function (context, value) { + var precision = context && context.numPrecision; + // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: + return (precision) ? Number((value + 2e-16).toFixed(precision)) : value; + }; + // Returns true if this node represents root of ast imported by reference + Node.prototype.blocksVisibility = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + return this.visibilityBlocks !== 0; + }; + Node.prototype.addVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks + 1; + }; + Node.prototype.removeVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks - 1; + }; + // Turns on node visibility - if called node will be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureVisibility", - value: function ensureVisibility() { - this.nodeVisible = true; - } // Turns off node visibility - if called node will NOT be shown in output regardless + Node.prototype.ensureVisibility = function () { + this.nodeVisible = true; + }; + // Turns off node visibility - if called node will NOT be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureInvisibility", - value: function ensureInvisibility() { - this.nodeVisible = false; - } // return values: + Node.prototype.ensureInvisibility = function () { + this.nodeVisible = false; + }; + // return values: // false - the node must not be visible // true - the node must be visible // undefined or null - the node has the same visibility as its parent - - }, { - key: "isVisible", - value: function isVisible() { - return this.nodeVisible; - } - }, { - key: "visibilityInfo", - value: function visibilityInfo() { - return { - visibilityBlocks: this.visibilityBlocks, - nodeVisible: this.nodeVisible - }; - } - }, { - key: "copyVisibilityInfo", - value: function copyVisibilityInfo(info) { - if (!info) { - return; - } - - this.visibilityBlocks = info.visibilityBlocks; - this.nodeVisible = info.nodeVisible; - } - }]); - - return Node; -}(); - + Node.prototype.isVisible = function () { + return this.nodeVisible; + }; + Node.prototype.visibilityInfo = function () { + return { + visibilityBlocks: this.visibilityBlocks, + nodeVisible: this.nodeVisible + }; + }; + Node.prototype.copyVisibilityInfo = function (info) { + if (!info) { + return; + } + this.visibilityBlocks = info.visibilityBlocks; + this.nodeVisible = info.nodeVisible; + }; + return Node; +}()); Node.compare = function (a, b) { - /* returns: - -1: a < b - 0: a = b - 1: a > b - and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ - if (a.compare && // for "symmetric results" force toCSS-based comparison - // of Quoted or Anonymous if either value is one of those - !(b.type === 'Quoted' || b.type === 'Anonymous')) { - return a.compare(b); - } else if (b.compare) { - return -b.compare(a); - } else if (a.type !== b.type) { - return undefined; - } - - a = a.value; - b = b.value; - - if (!Array.isArray(a)) { - return a === b ? 0 : undefined; - } - - if (a.length !== b.length) { - return undefined; - } - - for (var i = 0; i < a.length; i++) { - if (Node.compare(a[i], b[i]) !== 0) { - return undefined; + /* returns: + -1: a < b + 0: a = b + 1: a > b + and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ + if ((a.compare) && + // for "symmetric results" force toCSS-based comparison + // of Quoted or Anonymous if either value is one of those + !(b.type === 'Quoted' || b.type === 'Anonymous')) { + return a.compare(b); + } + else if (b.compare) { + return -b.compare(a); + } + else if (a.type !== b.type) { + return undefined; } - } - - return 0; -}; - -Node.numericCompare = function (a, b) { - return a < b ? -1 : a === b ? 0 : a > b ? 1 : undefined; + a = a.value; + b = b.value; + if (!Array.isArray(a)) { + return a === b ? 0 : undefined; + } + if (a.length !== b.length) { + return undefined; + } + for (var i_1 = 0; i_1 < a.length; i_1++) { + if (Node.compare(a[i_1], b[i_1]) !== 0) { + return undefined; + } + } + return 0; }; +Node.numericCompare = function (a, b) { return a < b ? -1 + : a === b ? 0 + : a > b ? 1 : undefined; }; +// // RGB Colors - #ff0014, #eee // - -var Color = -/*#__PURE__*/ -function (_Node) { - _inherits(Color, _Node); - - function Color(rgb, a, originalForm) { - var _this; - - _classCallCheck(this, Color); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Color).call(this)); - - var self = _assertThisInitialized(_this); // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - - - if (Array.isArray(rgb)) { - _this.rgb = rgb; - } else if (rgb.length >= 6) { - _this.rgb = []; - rgb.match(/.{2}/g).map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c, 16)); - } else { - self.alpha = parseInt(c, 16) / 255; - } - }); - } else { - _this.rgb = []; - rgb.split('').map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c + c, 16)); - } else { - self.alpha = parseInt(c + c, 16) / 255; - } - }); - } - - _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); - - if (typeof originalForm !== 'undefined') { - _this.value = originalForm; +var Color = /** @class */ (function (_super) { + tslib.__extends(Color, _super); + function Color(rgb, a, originalForm) { + var _this = _super.call(this) || this; + var self = _this; + // + // The end goal here, is to parse the arguments + // into an integer triplet, such as `128, 255, 0` + // + // This facilitates operations and conversions. + // + if (Array.isArray(rgb)) { + _this.rgb = rgb; + } + else if (rgb.length >= 6) { + _this.rgb = []; + rgb.match(/.{2}/g).map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c, 16)); + } + else { + self.alpha = (parseInt(c, 16)) / 255; + } + }); + } + else { + _this.rgb = []; + rgb.split('').map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c + c, 16)); + } + else { + self.alpha = (parseInt(c + c, 16)) / 255; + } + }); + } + _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); + if (typeof originalForm !== 'undefined') { + _this.value = originalForm; + } + return _this; } - - return _this; - } - - _createClass(Color, [{ - key: "luma", - value: function luma() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - r = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4); - g = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4); - b = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4); - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context, doNotCompress) { - var compress = context && context.compress && !doNotCompress; - var color; - var alpha; - var colorFunction; - var args = []; // `value` is set if this color was originally - // converted from a named color string so we need - // to respect this and try to output named color too. - - alpha = this.fround(context, this.alpha); - - if (this.value) { - if (this.value.indexOf('rgb') === 0) { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } else if (this.value.indexOf('hsl') === 0) { - if (alpha < 1) { - colorFunction = 'hsla'; - } else { - colorFunction = 'hsl'; - } - } else { - return this.value; - } - } else { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } - - switch (colorFunction) { - case 'rgba': - args = this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)); - break; - - case 'hsla': - args.push(clamp(alpha, 1)); - - case 'hsl': - color = this.toHSL(); - args = [this.fround(context, color.h), `${this.fround(context, color.s * 100)}%`, `${this.fround(context, color.l * 100)}%`].concat(args); - } - - if (colorFunction) { - // Values are capped between `0` and `255`, rounded and zero-padded. - return `${colorFunction}(${args.join(`,${compress ? '' : ' '}`)})`; - } - - color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); // Convert color to short format - - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = `#${splitcolor[1]}${splitcolor[3]}${splitcolor[5]}`; + Color.prototype.luma = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); + g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); + b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); + return 0.2126 * r + 0.7152 * g + 0.0722 * b; + }; + Color.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Color.prototype.toCSS = function (context, doNotCompress) { + var compress = context && context.compress && !doNotCompress; + var color; + var alpha; + var colorFunction; + var args = []; + // `value` is set if this color was originally + // converted from a named color string so we need + // to respect this and try to output named color too. + alpha = this.fround(context, this.alpha); + if (this.value) { + if (this.value.indexOf('rgb') === 0) { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + else if (this.value.indexOf('hsl') === 0) { + if (alpha < 1) { + colorFunction = 'hsla'; + } + else { + colorFunction = 'hsl'; + } + } + else { + return this.value; + } } - } - - return color; - } // + else { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + switch (colorFunction) { + case 'rgba': + args = this.rgb.map(function (c) { return clamp(Math.round(c), 255); }).concat(clamp(alpha, 1)); + break; + case 'hsla': + args.push(clamp(alpha, 1)); + case 'hsl': + color = this.toHSL(); + args = [ + this.fround(context, color.h), + this.fround(context, color.s * 100) + "%", + this.fround(context, color.l * 100) + "%" + ].concat(args); + } + if (colorFunction) { + // Values are capped between `0` and `255`, rounded and zero-padded. + return colorFunction + "(" + args.join("," + (compress ? '' : ' ')) + ")"; + } + color = this.toRGB(); + if (compress) { + var splitcolor = color.split(''); + // Convert color to short format + if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { + color = "#" + splitcolor[1] + splitcolor[3] + splitcolor[5]; + } + } + return color; + }; + // // Operations have to be done per-channel, if not, // channels will spill onto each other. Once we have // our result, in the form of an integer triplet, // we create a new Color node to hold the result. // - - }, { - key: "operate", - value: function operate(context, op, other) { - var rgb = new Array(3); - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - - for (var c = 0; c < 3; c++) { - rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); - } - - return new Color(rgb, alpha); - } - }, { - key: "toRGB", - value: function toRGB() { - return toHex(this.rgb); - } - }, { - key: "toHSL", - value: function toHSL() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var l = (max + min) / 2; - var d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + Color.prototype.operate = function (context, op, other) { + var rgb = new Array(3); + var alpha = this.alpha * (1 - other.alpha) + other.alpha; + for (var c = 0; c < 3; c++) { + rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); } - - h /= 6; - } - - return { - h: h * 360, - s, - l, - a - }; - } // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - - }, { - key: "toHSV", - value: function toHSV() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var v = max; - var d = max - min; - - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + return new Color(rgb, alpha); + }; + Color.prototype.toRGB = function () { + return toHex(this.rgb); + }; + Color.prototype.toHSL = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var l = (max + min) / 2; + var d = max - min; + if (max === min) { + h = s = 0; + } + else { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; } - - h /= 6; - } - - return { - h: h * 360, - s, - v, - a - }; - } - }, { - key: "toARGB", - value: function toARGB() { - return toHex([this.alpha * 255].concat(this.rgb)); - } - }, { - key: "compare", - value: function compare(x) { - return x.rgb && x.rgb[0] === this.rgb[0] && x.rgb[1] === this.rgb[1] && x.rgb[2] === this.rgb[2] && x.alpha === this.alpha ? 0 : undefined; - } - }]); - - return Color; -}(Node); - + return { h: h * 360, s: s, l: l, a: a }; + }; + // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + Color.prototype.toHSV = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var v = max; + var d = max - min; + if (max === 0) { + s = 0; + } + else { + s = d / max; + } + if (max === min) { + h = 0; + } + else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return { h: h * 360, s: s, v: v, a: a }; + }; + Color.prototype.toARGB = function () { + return toHex([this.alpha * 255].concat(this.rgb)); + }; + Color.prototype.compare = function (x) { + return (x.rgb && + x.rgb[0] === this.rgb[0] && + x.rgb[1] === this.rgb[1] && + x.rgb[2] === this.rgb[2] && + x.alpha === this.alpha) ? 0 : undefined; + }; + return Color; +}(Node)); Color.prototype.type = 'Color'; - function clamp(v, max) { - return Math.min(Math.max(v, 0), max); + return Math.min(Math.max(v, 0), max); } - function toHex(v) { - return `#${v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join('')}`; + return "#" + v.map(function (c) { + c = clamp(Math.round(c), 255); + return (c < 16 ? '0' : '') + c.toString(16); + }).join(''); } - Color.fromKeyword = function (keyword) { - var c; - var key = keyword.toLowerCase(); - - if (colors.hasOwnProperty(key)) { - c = new Color(colors[key].slice(1)); - } else if (key === 'transparent') { - c = new Color([0, 0, 0], 0); - } - - if (c) { - c.value = keyword; - return c; - } + var c; + var key = keyword.toLowerCase(); + if (colors.hasOwnProperty(key)) { + c = new Color(colors[key].slice(1)); + } + else if (key === 'transparent') { + c = new Color([0, 0, 0], 0); + } + if (c) { + c.value = keyword; + return c; + } }; -var Paren = -/*#__PURE__*/ -function (_Node) { - _inherits(Paren, _Node); - - function Paren(node) { - var _this; - - _classCallCheck(this, Paren); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Paren).call(this)); - _this.value = node; - return _this; - } - - _createClass(Paren, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - return new Paren(this.value.eval(context)); - } - }]); - - return Paren; -}(Node); - +var Paren = /** @class */ (function (_super) { + tslib.__extends(Paren, _super); + function Paren(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; + } + Paren.prototype.genCSS = function (context, output) { + output.add('('); + this.value.genCSS(context, output); + output.add(')'); + }; + Paren.prototype.eval = function (context) { + return new Paren(this.value.eval(context)); + }; + return Paren; +}(Node)); Paren.prototype.type = 'Paren'; var _noSpaceCombinators = { - '': true, - ' ': true, - '|': true + '': true, + ' ': true, + '|': true }; - -var Combinator = -/*#__PURE__*/ -function (_Node) { - _inherits(Combinator, _Node); - - function Combinator(value) { - var _this; - - _classCallCheck(this, Combinator); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Combinator).call(this)); - - if (value === ' ') { - _this.value = ' '; - _this.emptyOrWhitespace = true; - } else { - _this.value = value ? value.trim() : ''; - _this.emptyOrWhitespace = _this.value === ''; - } - - return _this; - } - - _createClass(Combinator, [{ - key: "genCSS", - value: function genCSS(context, output) { - var spaceOrEmpty = context.compress || _noSpaceCombinators[this.value] ? '' : ' '; - output.add(spaceOrEmpty + this.value + spaceOrEmpty); - } - }]); - - return Combinator; -}(Node); - +var Combinator = /** @class */ (function (_super) { + tslib.__extends(Combinator, _super); + function Combinator(value) { + var _this = _super.call(this) || this; + if (value === ' ') { + _this.value = ' '; + _this.emptyOrWhitespace = true; + } + else { + _this.value = value ? value.trim() : ''; + _this.emptyOrWhitespace = _this.value === ''; + } + return _this; + } + Combinator.prototype.genCSS = function (context, output) { + var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' '; + output.add(spaceOrEmpty + this.value + spaceOrEmpty); + }; + return Combinator; +}(Node)); Combinator.prototype.type = 'Combinator'; -var Element = -/*#__PURE__*/ -function (_Node) { - _inherits(Element, _Node); - - function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Element); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Element).call(this)); - _this.combinator = combinator instanceof Combinator ? combinator : new Combinator(combinator); - - if (typeof value === 'string') { - _this.value = value.trim(); - } else if (value) { - _this.value = value; - } else { - _this.value = ''; - } - - _this.isVariable = isVariable; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.combinator, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Element, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - - if (typeof value === 'object') { - this.value = visitor.visit(value); - } - } - }, { - key: "eval", - value: function _eval(context) { - return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone() { - return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); - } - }, { - key: "toCSS", - value: function toCSS() { - var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var value = this.value; - var firstSelector = context.firstSelector; - - if (value instanceof Paren) { - // selector in parens should not be affected by outer selector - // flags (breaks only interpolated selectors - see #1973) - context.firstSelector = true; - } - - value = value.toCSS ? value.toCSS(context) : value; - context.firstSelector = firstSelector; - - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(context) + value; - } - } - }]); - - return Element; -}(Node); - +var Element = /** @class */ (function (_super) { + tslib.__extends(Element, _super); + function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.combinator = combinator instanceof Combinator ? + combinator : new Combinator(combinator); + if (typeof value === 'string') { + _this.value = value.trim(); + } + else if (value) { + _this.value = value; + } + else { + _this.value = ''; + } + _this.isVariable = isVariable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.combinator, _this); + return _this; + } + Element.prototype.accept = function (visitor) { + var value = this.value; + this.combinator = visitor.visit(this.combinator); + if (typeof value === 'object') { + this.value = visitor.visit(value); + } + }; + Element.prototype.eval = function (context) { + return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.clone = function () { + return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); + }; + Element.prototype.toCSS = function (context) { + if (context === void 0) { context = {}; } + var value = this.value; + var firstSelector = context.firstSelector; + if (value instanceof Paren) { + // selector in parens should not be affected by outer selector + // flags (breaks only interpolated selectors - see #1973) + context.firstSelector = true; + } + value = value.toCSS ? value.toCSS(context) : value; + context.firstSelector = firstSelector; + if (value === '' && this.combinator.value.charAt(0) === '&') { + return ''; + } + else { + return this.combinator.toCSS(context) + value; + } + }; + return Element; +}(Node)); Element.prototype.type = 'Element'; +var anonymousFunc = /(|Function):(\d+):(\d+)/; /** * This is a centralized class of any error that could be thrown internally (mostly by the parser). * Besides standard .message it keeps some additional data like a path to the file where the error @@ -1673,55 +1208,68 @@ Element.prototype.type = 'Element'; * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager? * @param {string} [currentFilename] */ - var LessError = function LessError(e, fileContentMap, currentFilename) { - Error.call(this); - var filename = e.filename || currentFilename; - this.message = e.message; - this.stack = e.stack; - - if (fileContentMap && filename) { - var input = fileContentMap.contents[filename]; - var loc = getLocation(e.index, input); - var line = loc.line; - var col = loc.column; - var callLine = e.call && getLocation(e.call, input).line; - var lines = input ? input.split('\n') : ''; - this.type = e.type || 'Syntax'; - this.filename = filename; - this.index = e.index; - this.line = typeof line === 'number' ? line + 1 : null; - this.column = col; - - if (!this.line && this.stack) { - var found = this.stack.match(/(|Function):(\d+):(\d+)/); - - if (found) { - if (found[2]) { - this.line = parseInt(found[2]) - 2; - } - - if (found[3]) { - this.column = parseInt(found[3]); + Error.call(this); + var filename = e.filename || currentFilename; + this.message = e.message; + this.stack = e.stack; + if (fileContentMap && filename) { + var input = fileContentMap.contents[filename]; + var loc = getLocation(e.index, input); + var line = loc.line; + var col = loc.column; + var callLine = e.call && getLocation(e.call, input).line; + var lines = input ? input.split('\n') : ''; + this.type = e.type || 'Syntax'; + this.filename = filename; + this.index = e.index; + this.line = typeof line === 'number' ? line + 1 : null; + this.column = col; + if (!this.line && this.stack) { + var found = this.stack.match(anonymousFunc); + /** + * We have to figure out how this environment stringifies anonymous functions + * so we can correctly map plugin errors. + * + * Note, in Node 8, the output of anonymous funcs varied based on parameters + * being present or not, so we inject dummy params. + */ + var func = new Function('a', 'throw new Error()'); + var lineAdjust = 0; + try { + func(); + } + catch (e) { + var match = e.stack.match(anonymousFunc); + var line_1 = parseInt(match[2]); + lineAdjust = 1 - line_1; + } + if (found) { + if (found[2]) { + this.line = parseInt(found[2]) + lineAdjust; + } + if (found[3]) { + this.column = parseInt(found[3]); + } + } } - } + this.callLine = callLine + 1; + this.callExtract = lines[callLine]; + this.extract = [ + lines[this.line - 2], + lines[this.line - 1], + lines[this.line] + ]; } - - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.extract = [lines[this.line - 2], lines[this.line - 1], lines[this.line]]; - } }; - if (typeof Object.create === 'undefined') { - var F = function F() {}; - - F.prototype = Error.prototype; - LessError.prototype = new F(); -} else { - LessError.prototype = Object.create(Error.prototype); + var F = function () { }; + F.prototype = Error.prototype; + LessError.prototype = new F(); +} +else { + LessError.prototype = Object.create(Error.prototype); } - LessError.prototype.constructor = LessError; /** * An overridden version of the default Object.prototype.toString @@ -1730,2619 +1278,1984 @@ LessError.prototype.constructor = LessError; * @param {Object} options * @returns {string} */ - -LessError.prototype.toString = function () { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var message = ''; - var extract = this.extract || []; - var error = []; - - var stylize = function stylize(str) { - return str; - }; - - if (options.stylize) { - var type = typeof options.stylize; - - if (type !== 'function') { - throw Error(`options.stylize should be a function, got a ${type}!`); +LessError.prototype.toString = function (options) { + if (options === void 0) { options = {}; } + var message = ''; + var extract = this.extract || []; + var error = []; + var stylize = function (str) { return str; }; + if (options.stylize) { + var type = typeof options.stylize; + if (type !== 'function') { + throw Error("options.stylize should be a function, got a " + type + "!"); + } + stylize = options.stylize; + } + if (this.line !== null) { + if (typeof extract[0] === 'string') { + error.push(stylize(this.line - 1 + " " + extract[0], 'grey')); + } + if (typeof extract[1] === 'string') { + var errorTxt = this.line + " "; + if (extract[1]) { + errorTxt += extract[1].slice(0, this.column) + + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + + extract[1].slice(this.column + 1), 'red'), 'inverse'); + } + error.push(errorTxt); + } + if (typeof extract[2] === 'string') { + error.push(stylize(this.line + 1 + " " + extract[2], 'grey')); + } + error = error.join('\n') + stylize('', 'reset') + "\n"; } - - stylize = options.stylize; - } - - if (this.line !== null) { - if (typeof extract[0] === 'string') { - error.push(stylize(`${this.line - 1} ${extract[0]}`, 'grey')); + message += stylize(this.type + "Error: " + this.message, 'red'); + if (this.filename) { + message += stylize(' in ', 'red') + this.filename; } - - if (typeof extract[1] === 'string') { - var errorTxt = `${this.line} `; - - if (extract[1]) { - errorTxt += extract[1].slice(0, this.column) + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + extract[1].slice(this.column + 1), 'red'), 'inverse'); - } - - error.push(errorTxt); + if (this.line) { + message += stylize(" on line " + this.line + ", column " + (this.column + 1) + ":", 'grey'); } - - if (typeof extract[2] === 'string') { - error.push(stylize(`${this.line + 1} ${extract[2]}`, 'grey')); + message += "\n" + error; + if (this.callLine) { + message += stylize('from ', 'red') + (this.filename || '') + "/n"; + message += stylize(this.callLine, 'grey') + " " + this.callExtract + "/n"; } - - error = `${error.join('\n') + stylize('', 'reset')}\n`; - } - - message += stylize(`${this.type}Error: ${this.message}`, 'red'); - - if (this.filename) { - message += stylize(' in ', 'red') + this.filename; - } - - if (this.line) { - message += stylize(` on line ${this.line}, column ${this.column + 1}:`, 'grey'); - } - - message += `\n${error}`; - - if (this.callLine) { - message += `${stylize('from ', 'red') + (this.filename || '')}/n`; - message += `${stylize(this.callLine, 'grey')} ${this.callExtract}/n`; - } - - return message; + return message; }; -var Selector = -/*#__PURE__*/ -function (_Node) { - _inherits(Selector, _Node); - - function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Selector); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Selector).call(this)); - _this.extendList = extendList; - _this.condition = condition; - _this.evaldCondition = !condition; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.elements = _this.getElements(elements); - _this.mixinElements_ = undefined; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.elements, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Selector, [{ - key: "accept", - value: function accept(visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "createDerived", - value: function createDerived(elements, extendList, evaldCondition) { - elements = this.getElements(elements); - var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - newSelector.evaldCondition = evaldCondition != null ? evaldCondition : this.evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - } - }, { - key: "getElements", - value: function getElements(els) { - if (!els) { - return [new Element('', '&', false, this._index, this._fileInfo)]; - } - - if (typeof els === 'string') { - this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { - if (err) { - throw new LessError({ - index: err.index, - message: err.message - }, this.parse.imports, this._fileInfo.filename); - } - - els = result[0].elements; - }); - } - - return els; - } - }, { - key: "createEmptySelectors", - value: function createEmptySelectors() { - var el = new Element('', '&', false, this._index, this._fileInfo); - var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; - sels[0].mediaEmpty = true; - return sels; - } - }, { - key: "match", - value: function match(other) { - var elements = this.elements; - var len = elements.length; - var olen; - var i; - other = other.mixinElements(); - olen = other.length; - - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other[i]) { - return 0; - } +var Selector = /** @class */ (function (_super) { + tslib.__extends(Selector, _super); + function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.extendList = extendList; + _this.condition = condition; + _this.evaldCondition = !condition; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.elements = _this.getElements(elements); + _this.mixinElements_ = undefined; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.elements, _this); + return _this; + } + Selector.prototype.accept = function (visitor) { + if (this.elements) { + this.elements = visitor.visitArray(this.elements); + } + if (this.extendList) { + this.extendList = visitor.visitArray(this.extendList); + } + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } - - return olen; // return number of matched elements - } - }, { - key: "mixinElements", - value: function mixinElements() { - if (this.mixinElements_) { - return this.mixinElements_; - } - - var elements = this.elements.map(function (v) { - return v.combinator.value + (v.value.value || v.value); - }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); - - if (elements) { - if (elements[0] === '&') { - elements.shift(); + }; + Selector.prototype.createDerived = function (elements, extendList, evaldCondition) { + elements = this.getElements(elements); + var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; + newSelector.mediaEmpty = this.mediaEmpty; + return newSelector; + }; + Selector.prototype.getElements = function (els) { + if (!els) { + return [new Element('', '&', false, this._index, this._fileInfo)]; + } + if (typeof els === 'string') { + this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { + if (err) { + throw new LessError({ + index: err.index, + message: err.message + }, this.parse.imports, this._fileInfo.filename); + } + els = result[0].elements; + }); } - } else { - elements = []; - } - - return this.mixinElements_ = elements; - } - }, { - key: "isJustParentSelector", - value: function isJustParentSelector() { - return !this.mediaEmpty && this.elements.length === 1 && this.elements[0].value === '&' && (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - } - }, { - key: "eval", - value: function _eval(context) { - var evaldCondition = this.condition && this.condition.eval(context); - var elements = this.elements; - var extendList = this.extendList; - elements = elements && elements.map(function (e) { - return e.eval(context); - }); - extendList = extendList && extendList.map(function (extend) { - return extend.eval(context); - }); - return this.createDerived(elements, extendList, evaldCondition); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var element; - - if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { - output.add(' ', this.fileInfo(), this.getIndex()); - } - - for (i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(context, output); - } - } - }, { - key: "getIsOutput", - value: function getIsOutput() { - return this.evaldCondition; - } - }]); - - return Selector; -}(Node); - + return els; + }; + Selector.prototype.createEmptySelectors = function () { + var el = new Element('', '&', false, this._index, this._fileInfo); + var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; + sels[0].mediaEmpty = true; + return sels; + }; + Selector.prototype.match = function (other) { + var elements = this.elements; + var len = elements.length; + var olen; + var i; + other = other.mixinElements(); + olen = other.length; + if (olen === 0 || len < olen) { + return 0; + } + else { + for (i = 0; i < olen; i++) { + if (elements[i].value !== other[i]) { + return 0; + } + } + } + return olen; // return number of matched elements + }; + Selector.prototype.mixinElements = function () { + if (this.mixinElements_) { + return this.mixinElements_; + } + var elements = this.elements.map(function (v) { return v.combinator.value + (v.value.value || v.value); }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); + if (elements) { + if (elements[0] === '&') { + elements.shift(); + } + } + else { + elements = []; + } + return (this.mixinElements_ = elements); + }; + Selector.prototype.isJustParentSelector = function () { + return !this.mediaEmpty && + this.elements.length === 1 && + this.elements[0].value === '&' && + (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); + }; + Selector.prototype.eval = function (context) { + var evaldCondition = this.condition && this.condition.eval(context); + var elements = this.elements; + var extendList = this.extendList; + elements = elements && elements.map(function (e) { return e.eval(context); }); + extendList = extendList && extendList.map(function (extend) { return extend.eval(context); }); + return this.createDerived(elements, extendList, evaldCondition); + }; + Selector.prototype.genCSS = function (context, output) { + var i; + var element; + if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { + output.add(' ', this.fileInfo(), this.getIndex()); + } + for (i = 0; i < this.elements.length; i++) { + element = this.elements[i]; + element.genCSS(context, output); + } + }; + Selector.prototype.getIsOutput = function () { + return this.evaldCondition; + }; + return Selector; +}(Node)); Selector.prototype.type = 'Selector'; -var Value = -/*#__PURE__*/ -function (_Node) { - _inherits(Value, _Node); - - function Value(value) { - var _this; - - _classCallCheck(this, Value); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Value).call(this)); - - if (!value) { - throw new Error('Value requires an array argument'); - } - - if (!Array.isArray(value)) { - _this.value = [value]; - } else { - _this.value = value; - } - - return _this; - } - - _createClass(Value, [{ - key: "accept", - value: function accept(visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.length === 1) { - return this.value[0].eval(context); - } else { - return new Value(this.value.map(function (v) { - return v.eval(context); - })); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - - for (i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (i + 1 < this.value.length) { - output.add(context && context.compress ? ',' : ', '); +var Value = /** @class */ (function (_super) { + tslib.__extends(Value, _super); + function Value(value) { + var _this = _super.call(this) || this; + if (!value) { + throw new Error('Value requires an array argument'); } - } + if (!Array.isArray(value)) { + _this.value = [value]; + } + else { + _this.value = value; + } + return _this; } - }]); - - return Value; -}(Node); - + Value.prototype.accept = function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } + }; + Value.prototype.eval = function (context) { + if (this.value.length === 1) { + return this.value[0].eval(context); + } + else { + return new Value(this.value.map(function (v) { return v.eval(context); })); + } + }; + Value.prototype.genCSS = function (context, output) { + var i; + for (i = 0; i < this.value.length; i++) { + this.value[i].genCSS(context, output); + if (i + 1 < this.value.length) { + output.add((context && context.compress) ? ',' : ', '); + } + } + }; + return Value; +}(Node)); Value.prototype.type = 'Value'; -var Keyword = -/*#__PURE__*/ -function (_Node) { - _inherits(Keyword, _Node); - - function Keyword(value) { - var _this; - - _classCallCheck(this, Keyword); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Keyword).call(this)); - _this.value = value; - return _this; - } - - _createClass(Keyword, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.value === '%') { - throw { - type: 'Syntax', - message: 'Invalid % without number' - }; - } - - output.add(this.value); +var Keyword = /** @class */ (function (_super) { + tslib.__extends(Keyword, _super); + function Keyword(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; } - }]); - - return Keyword; -}(Node); - + Keyword.prototype.genCSS = function (context, output) { + if (this.value === '%') { + throw { type: 'Syntax', message: 'Invalid % without number' }; + } + output.add(this.value); + }; + return Keyword; +}(Node)); Keyword.prototype.type = 'Keyword'; Keyword.True = new Keyword('true'); Keyword.False = new Keyword('false'); -var Anonymous = -/*#__PURE__*/ -function (_Node) { - _inherits(Anonymous, _Node); - - function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { - var _this; - - _classCallCheck(this, Anonymous); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Anonymous).call(this)); - _this.value = value; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.mapLines = mapLines; - _this.rulesetLike = typeof rulesetLike === 'undefined' ? false : rulesetLike; - _this.allowRoot = true; - - _this.copyVisibilityInfo(visibilityInfo); - - return _this; - } - - _createClass(Anonymous, [{ - key: "eval", - value: function _eval() { - return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); - } - }, { - key: "compare", - value: function compare(other) { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rulesetLike; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.nodeVisible = Boolean(this.value); - - if (this.nodeVisible) { - output.add(this.value, this._fileInfo, this._index, this.mapLines); - } - } - }]); - - return Anonymous; -}(Node); - +var Anonymous = /** @class */ (function (_super) { + tslib.__extends(Anonymous, _super); + function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.mapLines = mapLines; + _this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike; + _this.allowRoot = true; + _this.copyVisibilityInfo(visibilityInfo); + return _this; + } + Anonymous.prototype.eval = function () { + return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); + }; + Anonymous.prototype.compare = function (other) { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + }; + Anonymous.prototype.isRulesetLike = function () { + return this.rulesetLike; + }; + Anonymous.prototype.genCSS = function (context, output) { + this.nodeVisible = Boolean(this.value); + if (this.nodeVisible) { + output.add(this.value, this._fileInfo, this._index, this.mapLines); + } + }; + return Anonymous; +}(Node)); Anonymous.prototype.type = 'Anonymous'; var MATH = Math$1; - -var Declaration = -/*#__PURE__*/ -function (_Node) { - _inherits(Declaration, _Node); - - function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { - var _this; - - _classCallCheck(this, Declaration); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Declaration).call(this)); - _this.name = name; - _this.value = value instanceof Node ? value : new Value([value ? new Anonymous(value) : null]); - _this.important = important ? ` ${important.trim()}` : ''; - _this.merge = merge; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.inline = inline || false; - _this.variable = variable !== undefined ? variable : name.charAt && name.charAt(0) === '@'; - _this.allowRoot = true; - - _this.setParent(_this.value, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Declaration, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); - - try { - this.value.genCSS(context, output); - } catch (e) { - e.index = this._index; - e.filename = this._fileInfo.filename; - throw e; - } - - output.add(this.important + (this.inline || context.lastRule && context.compress ? '' : ';'), this._fileInfo, this._index); - } - }, { - key: "eval", - value: function _eval(context) { - var mathBypass = false; - var prevMath; - var name = this.name; - var evaldValue; - var variable = this.variable; - - if (typeof name !== 'string') { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = name.length === 1 && name[0] instanceof Keyword ? name[0].value : evalName(context, name); - variable = false; // never treat expanded interpolation as new variable name - } // @todo remove when parens-division is default - - - if (name === 'font' && context.math === MATH.ALWAYS) { - mathBypass = true; - prevMath = context.math; - context.math = MATH.PARENS_DIVISION; - } - - try { - context.importantScope.push({}); - evaldValue = this.value.eval(context); - - if (!this.variable && evaldValue.type === 'DetachedRuleset') { - throw { - message: 'Rulesets cannot be evaluated on a property.', - index: this.getIndex(), - filename: this.fileInfo().filename - }; +var Declaration = /** @class */ (function (_super) { + tslib.__extends(Declaration, _super); + function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { + var _this = _super.call(this) || this; + _this.name = name; + _this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]); + _this.important = important ? " " + important.trim() : ''; + _this.merge = merge; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.inline = inline || false; + _this.variable = (variable !== undefined) ? variable + : (name.charAt && (name.charAt(0) === '@')); + _this.allowRoot = true; + _this.setParent(_this.value, _this); + return _this; + } + Declaration.prototype.genCSS = function (context, output) { + output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); + try { + this.value.genCSS(context, output); } - - var important = this.important; - var importantResult = context.importantScope.pop(); - - if (!important && importantResult.important) { - important = importantResult.important; + catch (e) { + e.index = this._index; + e.filename = this._fileInfo.filename; + throw e; } - - return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); - } catch (e) { - if (typeof e.index !== 'number') { - e.index = this.getIndex(); - e.filename = this.fileInfo().filename; + output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index); + }; + Declaration.prototype.eval = function (context) { + var mathBypass = false; + var prevMath; + var name = this.name; + var evaldValue; + var variable = this.variable; + if (typeof name !== 'string') { + // expand 'primitive' name directly to get + // things faster (~10% for benchmark.less): + name = (name.length === 1) && (name[0] instanceof Keyword) ? + name[0].value : evalName(context, name); + variable = false; // never treat expanded interpolation as new variable name + } + // @todo remove when parens-division is default + if (name === 'font' && context.math === MATH.ALWAYS) { + mathBypass = true; + prevMath = context.math; + context.math = MATH.PARENS_DIVISION; } - - throw e; - } finally { - if (mathBypass) { - context.math = prevMath; + try { + context.importantScope.push({}); + evaldValue = this.value.eval(context); + if (!this.variable && evaldValue.type === 'DetachedRuleset') { + throw { message: 'Rulesets cannot be evaluated on a property.', + index: this.getIndex(), filename: this.fileInfo().filename }; + } + var important = this.important; + var importantResult = context.importantScope.pop(); + if (!important && importantResult.important) { + important = importantResult.important; + } + return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); - } - }]); - - return Declaration; -}(Node); - + catch (e) { + if (typeof e.index !== 'number') { + e.index = this.getIndex(); + e.filename = this.fileInfo().filename; + } + throw e; + } + finally { + if (mathBypass) { + context.math = prevMath; + } + } + }; + Declaration.prototype.makeImportant = function () { + return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); + }; + return Declaration; +}(Node)); function evalName(context, name) { - var value = ''; - var i; - var n = name.length; - var output = { - add: function add(s) { - value += s; - } - }; - - for (i = 0; i < n; i++) { - name[i].eval(context).genCSS(context, output); - } - - return value; + var value = ''; + var i; + var n = name.length; + var output = { add: function (s) { value += s; } }; + for (i = 0; i < n; i++) { + name[i].eval(context).genCSS(context, output); + } + return value; } - Declaration.prototype.type = 'Declaration'; -var debugInfo = function debugInfo(context, ctx, lineSeparator) { - var result = ''; - - if (context.dumpLineNumbers && !context.compress) { - switch (context.dumpLineNumbers) { - case 'comments': - result = debugInfo.asComment(ctx); - break; - - case 'mediaquery': - result = debugInfo.asMediaQuery(ctx); - break; - - case 'all': - result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); - break; +var debugInfo = function (context, ctx, lineSeparator) { + var result = ''; + if (context.dumpLineNumbers && !context.compress) { + switch (context.dumpLineNumbers) { + case 'comments': + result = debugInfo.asComment(ctx); + break; + case 'mediaquery': + result = debugInfo.asMediaQuery(ctx); + break; + case 'all': + result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); + break; + } } - } - - return result; -}; - -debugInfo.asComment = function (ctx) { - return `/* line ${ctx.debugInfo.lineNumber}, ${ctx.debugInfo.fileName} */\n`; + return result; }; - +debugInfo.asComment = function (ctx) { return "/* line " + ctx.debugInfo.lineNumber + ", " + ctx.debugInfo.fileName + " */\n"; }; debugInfo.asMediaQuery = function (ctx) { - var filenameWithProtocol = ctx.debugInfo.fileName; - - if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { - filenameWithProtocol = `file://${filenameWithProtocol}`; - } - - return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; + var filenameWithProtocol = ctx.debugInfo.fileName; + if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { + filenameWithProtocol = "file://" + filenameWithProtocol; } - - return `\\${a}`; - })}}line{font-family:\\00003${ctx.debugInfo.lineNumber}}}\n`; + return "@media -sass-debug-info{filename{font-family:" + filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { + if (a == '\\') { + a = '\/'; + } + return "\\" + a; + }) + "}line{font-family:\\00003" + ctx.debugInfo.lineNumber + "}}\n"; }; -var Comment = -/*#__PURE__*/ -function (_Node) { - _inherits(Comment, _Node); - - function Comment(value, isLineComment, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Comment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Comment).call(this)); - _this.value = value; - _this.isLineComment = isLineComment; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(Comment, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.debugInfo) { - output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - } - }, { - key: "isSilent", - value: function isSilent(context) { - var isCompressed = context.compress && this.value[2] !== '!'; - return this.isLineComment || isCompressed; - } - }]); - - return Comment; -}(Node); - +var Comment = /** @class */ (function (_super) { + tslib.__extends(Comment, _super); + function Comment(value, isLineComment, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this.isLineComment = isLineComment; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + Comment.prototype.genCSS = function (context, output) { + if (this.debugInfo) { + output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); + } + output.add(this.value); + }; + Comment.prototype.isSilent = function (context) { + var isCompressed = context.compress && this.value[2] !== '!'; + return this.isLineComment || isCompressed; + }; + return Comment; +}(Node)); Comment.prototype.type = 'Comment'; var contexts = {}; - var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) { - if (!original) { - return; - } - - for (var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; + if (!original) { + return; + } + for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) { + if (original.hasOwnProperty(propertiesToCopy[i_1])) { + destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]]; + } } - } }; /* parse is used whilst parsing */ - - -var parseCopyProperties = [// options -'paths', // option - unmodified - paths to search for imports on -'rewriteUrls', // option - whether to adjust URL's to be relative -'rootpath', // option - rootpath to append to URL's -'strictImports', // option - -'insecure', // option - whether to allow imports from insecure ssl hosts -'dumpLineNumbers', // option - whether to dump line numbers -'compress', // option - whether to compress -'syncImport', // option - whether to import synchronously -'chunkInput', // option - whether to chunk input. more performant but causes parse issues. -'mime', // browser only - mime type for sheet import -'useFileCache', // browser only - whether to use the per file session cache -// context -'processImports', // option & context - whether to process imports. if false then imports will not be imported. -// Used by the import manager to stop multiple import visitors being created. -'pluginManager' // Used as the plugin manager for the session +var parseCopyProperties = [ + // options + 'paths', + 'rewriteUrls', + 'rootpath', + 'strictImports', + 'insecure', + 'dumpLineNumbers', + 'compress', + 'syncImport', + 'chunkInput', + 'mime', + 'useFileCache', + // context + 'processImports', + // Used by the import manager to stop multiple import visitors being created. + 'pluginManager' // Used as the plugin manager for the session ]; - contexts.Parse = function (options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } + copyFromOriginal(options, this, parseCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } }; - -var evalCopyProperties = ['paths', // additional include paths -'compress', // whether to compress -'math', // whether math has to be within parenthesis -'strictUnits', // whether units need to evaluate correctly -'sourceMap', // whether to output a source map -'importMultiple', // whether we are currently importing multiple copies -'urlArgs', // whether to add args into url tokens -'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false -'pluginManager', // Used as the plugin manager for the session -'importantScope', // used to bubble up !important statements -'rewriteUrls' // option - whether to adjust URL's to be relative +var evalCopyProperties = [ + 'paths', + 'compress', + 'math', + 'strictUnits', + 'sourceMap', + 'importMultiple', + 'urlArgs', + 'javascriptEnabled', + 'pluginManager', + 'importantScope', + 'rewriteUrls' // option - whether to adjust URL's to be relative ]; - function isPathRelative(path) { - return !/^(?:[a-z-]+:|\/|#)/i.test(path); + return !/^(?:[a-z-]+:|\/|#)/i.test(path); } - function isPathLocalRelative(path) { - return path.charAt(0) === '.'; + return path.charAt(0) === '.'; } - -contexts.Eval = -/*#__PURE__*/ -function () { - function _class(options, frames) { - _classCallCheck(this, _class); - - copyFromOriginal(options, this, evalCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } - - this.frames = frames || []; - this.importantScope = this.importantScope || []; - this.inCalc = false; - this.mathOn = true; - } - - _createClass(_class, [{ - key: "enterCalc", - value: function enterCalc() { - if (!this.calcStack) { - this.calcStack = []; - } - - this.calcStack.push(true); - this.inCalc = true; - } - }, { - key: "exitCalc", - value: function exitCalc() { - this.calcStack.pop(); - - if (!this.calcStack) { +contexts.Eval = /** @class */ (function () { + function Eval(options, frames) { + copyFromOriginal(options, this, evalCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } + this.frames = frames || []; + this.importantScope = this.importantScope || []; this.inCalc = false; - } - } - }, { - key: "inParenthesis", - value: function inParenthesis() { - if (!this.parensStack) { - this.parensStack = []; - } - - this.parensStack.push(true); + this.mathOn = true; } - }, { - key: "outOfParenthesis", - value: function outOfParenthesis() { - this.parensStack.pop(); - } - }, { - key: "isMathOn", - value: function isMathOn(op) { - if (!this.mathOn) { - return false; - } - - if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { - return false; - } - - if (this.math > Math$1.PARENS_DIVISION) { - return this.parensStack && this.parensStack.length; - } - - return true; - } - }, { - key: "pathRequiresRewrite", - value: function pathRequiresRewrite(path) { - var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; - return isRelative(path); - } - }, { - key: "rewritePath", - value: function rewritePath(path, rootpath) { - var newPath; - rootpath = rootpath || ''; - newPath = this.normalizePath(rootpath + path); // If a path was explicit relative and the rootpath was not an absolute path - // we must ensure that the new path is also explicit relative. - - if (isPathLocalRelative(path) && isPathRelative(rootpath) && isPathLocalRelative(newPath) === false) { - newPath = `./${newPath}`; - } - - return newPath; - } - }, { - key: "normalizePath", - value: function normalizePath(path) { - var segments = path.split('/').reverse(); - var segment; - path = []; - - while (segments.length !== 0) { - segment = segments.pop(); - - switch (segment) { - case '.': - break; - - case '..': - if (path.length === 0 || path[path.length - 1] === '..') { - path.push(segment); - } else { - path.pop(); + Eval.prototype.enterCalc = function () { + if (!this.calcStack) { + this.calcStack = []; + } + this.calcStack.push(true); + this.inCalc = true; + }; + Eval.prototype.exitCalc = function () { + this.calcStack.pop(); + if (!this.calcStack) { + this.inCalc = false; + } + }; + Eval.prototype.inParenthesis = function () { + if (!this.parensStack) { + this.parensStack = []; + } + this.parensStack.push(true); + }; + Eval.prototype.outOfParenthesis = function () { + this.parensStack.pop(); + }; + Eval.prototype.isMathOn = function (op) { + if (!this.mathOn) { + return false; + } + if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { + return false; + } + if (this.math > Math$1.PARENS_DIVISION) { + return this.parensStack && this.parensStack.length; + } + return true; + }; + Eval.prototype.pathRequiresRewrite = function (path) { + var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; + return isRelative(path); + }; + Eval.prototype.rewritePath = function (path, rootpath) { + var newPath; + rootpath = rootpath || ''; + newPath = this.normalizePath(rootpath + path); + // If a path was explicit relative and the rootpath was not an absolute path + // we must ensure that the new path is also explicit relative. + if (isPathLocalRelative(path) && + isPathRelative(rootpath) && + isPathLocalRelative(newPath) === false) { + newPath = "./" + newPath; + } + return newPath; + }; + Eval.prototype.normalizePath = function (path) { + var segments = path.split('/').reverse(); + var segment; + path = []; + while (segments.length !== 0) { + segment = segments.pop(); + switch (segment) { + case '.': + break; + case '..': + if ((path.length === 0) || (path[path.length - 1] === '..')) { + path.push(segment); + } + else { + path.pop(); + } + break; + default: + path.push(segment); + break; } - - break; - - default: - path.push(segment); - break; } - } - - return path.join('/'); - } - }]); - - return _class; -}(); + return path.join('/'); + }; + return Eval; +}()); function makeRegistry(base) { - return { - _data: {}, - add: function add(name, func) { - // precautionary case conversion, as later querying of - // the registry by function-caller uses lower case as well. - name = name.toLowerCase(); - - if (this._data.hasOwnProperty(name)) ; - - this._data[name] = func; - }, - addMultiple: function addMultiple(functions) { - var _this = this; - - Object.keys(functions).forEach(function (name) { - _this.add(name, functions[name]); - }); - }, - get: function get(name) { - return this._data[name] || base && base.get(name); - }, - getLocalFunctions: function getLocalFunctions() { - return this._data; - }, - inherit: function inherit() { - return makeRegistry(this); - }, - create: function create(base) { - return makeRegistry(base); - } - }; + return { + _data: {}, + add: function (name, func) { + // precautionary case conversion, as later querying of + // the registry by function-caller uses lower case as well. + name = name.toLowerCase(); + if (this._data.hasOwnProperty(name)) ; + this._data[name] = func; + }, + addMultiple: function (functions) { + var _this = this; + Object.keys(functions).forEach(function (name) { + _this.add(name, functions[name]); + }); + }, + get: function (name) { + return this._data[name] || (base && base.get(name)); + }, + getLocalFunctions: function () { + return this._data; + }, + inherit: function () { + return makeRegistry(this); + }, + create: function (base) { + return makeRegistry(base); + } + }; } - var functionRegistry = makeRegistry(null); var defaultFunc = { - eval: function _eval() { - var v = this.value_; - var e = this.error_; - - if (e) { - throw e; + eval: function () { + var v = this.value_; + var e = this.error_; + if (e) { + throw e; + } + if (v != null) { + return v ? Keyword.True : Keyword.False; + } + }, + value: function (v) { + this.value_ = v; + }, + error: function (e) { + this.error_ = e; + }, + reset: function () { + this.value_ = this.error_ = null; } - - if (v != null) { - return v ? Keyword.True : Keyword.False; - } - }, - value: function value(v) { - this.value_ = v; - }, - error: function error(e) { - this.error_ = e; - }, - reset: function reset() { - this.value_ = this.error_ = null; - } }; -var Ruleset = -/*#__PURE__*/ -function (_Node) { - _inherits(Ruleset, _Node); - - function Ruleset(selectors, rules, strictImports, visibilityInfo) { - var _this; - - _classCallCheck(this, Ruleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Ruleset).call(this)); - _this.selectors = selectors; - _this.rules = rules; - _this._lookups = {}; - _this._variables = null; - _this._properties = null; - _this.strictImports = strictImports; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(_this.selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Ruleset, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.paths) { - this.paths = visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "eval", - value: function _eval(context) { - var selectors; - var selCnt; - var selector; - var i; - var hasVariable; - var hasOnePassingSelector = false; - - if (this.selectors && (selCnt = this.selectors.length)) { - selectors = new Array(selCnt); - defaultFunc.error({ - type: 'Syntax', - message: 'it is currently only allowed in parametric mixin guards,' - }); - - for (i = 0; i < selCnt; i++) { - selector = this.selectors[i].eval(context); - - for (var j = 0; j < selector.elements.length; j++) { - if (selector.elements[j].isVariable) { - hasVariable = true; - break; +var Ruleset = /** @class */ (function (_super) { + tslib.__extends(Ruleset, _super); + function Ruleset(selectors, rules, strictImports, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selectors = selectors; + _this.rules = rules; + _this._lookups = {}; + _this._variables = null; + _this._properties = null; + _this.strictImports = strictImports; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(_this.selectors, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Ruleset.prototype.isRulesetLike = function () { + return true; + }; + Ruleset.prototype.accept = function (visitor) { + if (this.paths) { + this.paths = visitor.visitArray(this.paths, true); + } + else if (this.selectors) { + this.selectors = visitor.visitArray(this.selectors); + } + if (this.rules && this.rules.length) { + this.rules = visitor.visitArray(this.rules); + } + }; + Ruleset.prototype.eval = function (context) { + var selectors; + var selCnt; + var selector; + var i; + var hasVariable; + var hasOnePassingSelector = false; + if (this.selectors && (selCnt = this.selectors.length)) { + selectors = new Array(selCnt); + defaultFunc.error({ + type: 'Syntax', + message: 'it is currently only allowed in parametric mixin guards,' + }); + for (i = 0; i < selCnt; i++) { + selector = this.selectors[i].eval(context); + for (var j = 0; j < selector.elements.length; j++) { + if (selector.elements[j].isVariable) { + hasVariable = true; + break; + } + } + selectors[i] = selector; + if (selector.evaldCondition) { + hasOnePassingSelector = true; + } } - } - - selectors[i] = selector; - - if (selector.evaldCondition) { + if (hasVariable) { + var toParseSelectors = new Array(selCnt); + for (i = 0; i < selCnt; i++) { + selector = selectors[i]; + toParseSelectors[i] = selector.toCSS(context); + } + this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { + if (result) { + selectors = flattenArray(result); + } + }); + } + defaultFunc.reset(); + } + else { hasOnePassingSelector = true; - } } - - if (hasVariable) { - var toParseSelectors = new Array(selCnt); - - for (i = 0; i < selCnt; i++) { - selector = selectors[i]; - toParseSelectors[i] = selector.toCSS(context); - } - - this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { - if (result) { - selectors = flattenArray(result); + var rules = this.rules ? copyArray(this.rules) : null; + var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); + var rule; + var subRule; + ruleset.originalRuleset = this; + ruleset.root = this.root; + ruleset.firstRoot = this.firstRoot; + ruleset.allowImports = this.allowImports; + if (this.debugInfo) { + ruleset.debugInfo = this.debugInfo; + } + if (!hasOnePassingSelector) { + rules.length = 0; + } + // inherit a function registry from the frames stack when possible; + // otherwise from the global registry + ruleset.functionRegistry = (function (frames) { + var i = 0; + var n = frames.length; + var found; + for (; i !== n; ++i) { + found = frames[i].functionRegistry; + if (found) { + return found; + } + } + return functionRegistry; + })(context.frames).inherit(); + // push the current ruleset to the frames stack + var ctxFrames = context.frames; + ctxFrames.unshift(ruleset); + // currrent selectors + var ctxSelectors = context.selectors; + if (!ctxSelectors) { + context.selectors = ctxSelectors = []; + } + ctxSelectors.unshift(this.selectors); + // Evaluate imports + if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { + ruleset.evalImports(context); + } + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + var rsRules = ruleset.rules; + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.evalFirst) { + rsRules[i] = rule.eval(context); } - }); } - - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? copyArray(this.rules) : null; - var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); - var rule; - var subRule; - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if (this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } // inherit a function registry from the frames stack when possible; - // otherwise from the global registry - - - ruleset.functionRegistry = function (frames) { - var i = 0; - var n = frames.length; - var found; - - for (; i !== n; ++i) { - found = frames[i].functionRegistry; - - if (found) { - return found; - } + var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0; + // Evaluate mixin calls. + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.type === 'MixinCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope if the variable is + // already there. consider returning false here + // but we need a way to "return" variable from mixins + return !(ruleset.variable(r.name)); + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } + else if (rule.type === 'VariableCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).rules.filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope at all + return false; + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } } - - return functionRegistry; - }(context.frames).inherit(); // push the current ruleset to the frames stack - - - var ctxFrames = context.frames; - ctxFrames.unshift(ruleset); // currrent selectors - - var ctxSelectors = context.selectors; - - if (!ctxSelectors) { - context.selectors = ctxSelectors = []; - } - - ctxSelectors.unshift(this.selectors); // Evaluate imports - - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(context); - } // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - - - var rsRules = ruleset.rules; - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.evalFirst) { - rsRules[i] = rule.eval(context); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + if (!rule.evalFirst) { + rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + } } - } - - var mediaBlockCount = context.mediaBlocks && context.mediaBlocks.length || 0; // Evaluate mixin calls. - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.type === 'MixinCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !ruleset.variable(r.name); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + // for rulesets, check if it is a css guard and can be removed + if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { + // check if it can be folded in (e.g. & where) + if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { + rsRules.splice(i--, 1); + for (var j = 0; (subRule = rule.rules[j]); j++) { + if (subRule instanceof Node) { + subRule.copyVisibilityInfo(rule.visibilityInfo()); + if (!(subRule instanceof Declaration) || !subRule.variable) { + rsRules.splice(++i, 0, subRule); + } + } + } + } } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); - } else if (rule.type === 'VariableCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).rules.filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope at all - return false; + } + // Pop the stack + ctxFrames.shift(); + ctxSelectors.shift(); + if (context.mediaBlocks) { + for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { + context.mediaBlocks[i].bubbleSelectors(selectors); } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - if (!rule.evalFirst) { - rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + return ruleset; + }; + Ruleset.prototype.evalImports = function (context) { + var rules = this.rules; + var i; + var importRules; + if (!rules) { + return; } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for (var j = 0; subRule = rule.rules[j]; j++) { - if (subRule instanceof Node) { - subRule.copyVisibilityInfo(rule.visibilityInfo()); - - if (!(subRule instanceof Declaration) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); + for (i = 0; i < rules.length; i++) { + if (rules[i].type === 'Import') { + importRules = rules[i].eval(context); + if (importRules && (importRules.length || importRules.length === 0)) { + rules.splice.apply(rules, [i, 1].concat(importRules)); + i += importRules.length - 1; + } + else { + rules.splice(i, 1, importRules); } - } + this.resetCache(); } - } - } - } // Pop the stack - - - ctxFrames.shift(); - ctxSelectors.shift(); - - if (context.mediaBlocks) { - for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { - context.mediaBlocks[i].bubbleSelectors(selectors); } - } - - return ruleset; - } - }, { - key: "evalImports", - value: function evalImports(context) { - var rules = this.rules; - var i; - var importRules; - - if (!rules) { - return; - } - - for (i = 0; i < rules.length; i++) { - if (rules[i].type === 'Import') { - importRules = rules[i].eval(context); - - if (importRules && (importRules.length || importRules.length === 0)) { - rules.splice.apply(rules, _toConsumableArray([i, 1].concat(importRules))); - i += importRules.length - 1; - } else { - rules.splice(i, 1, importRules); - } - - this.resetCache(); - } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - var result = new Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports, this.visibilityInfo()); - return result; - } - }, { - key: "matchArgs", - value: function matchArgs(args) { - return !args || args.length === 0; - } // lets you call a css selector with a guard - - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - var lastSelector = this.selectors[this.selectors.length - 1]; - - if (!lastSelector.evaldCondition) { - return false; - } - - if (lastSelector.condition && !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { - return false; - } - - return true; - } - }, { - key: "resetCache", - value: function resetCache() { - this._rulesets = null; - this._variables = null; - this._properties = null; - this._lookups = {}; - } - }, { - key: "variables", - value: function variables() { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable === true) { - hash[r.name] = r; - } // when evaluating variables in an import statement, imports have not been eval'd - // so we need to go inside import statements. - // guard against root being a string (in the case of inlined less) - - - if (r.type === 'Import' && r.root && r.root.variables) { - var vars = r.root.variables(); - - for (var name in vars) { - if (vars.hasOwnProperty(name)) { - hash[name] = r.root.variable(name); - } + }; + Ruleset.prototype.makeImportant = function () { + var result = new Ruleset(this.selectors, this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(); } - } - - return hash; - }, {}); - } - - return this._variables; - } - }, { - key: "properties", - value: function properties() { - if (!this._properties) { - this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable !== true) { - var name = r.name.length === 1 && r.name[0] instanceof Keyword ? r.name[0].value : r.name; // Properties don't overwrite as they can merge - - if (!hash[`$${name}`]) { - hash[`$${name}`] = [r]; - } else { - hash[`$${name}`].push(r); + else { + return r; } - } - - return hash; - }, {}); - } - - return this._properties; - } - }, { - key: "variable", - value: function variable(name) { - var decl = this.variables()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "property", - value: function property(name) { - var decl = this.properties()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "lastDeclaration", - value: function lastDeclaration() { - for (var i = this.rules.length; i > 0; i--) { - var decl = this.rules[i - 1]; - - if (decl instanceof Declaration) { - return this.parseValue(decl); - } - } - } - }, { - key: "parseValue", - value: function parseValue(toParse) { - var self = this; - - function transformDeclaration(decl) { - if (decl.value instanceof Anonymous && !decl.parsed) { - if (typeof decl.value.value === 'string') { - this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { - if (err) { - decl.parsed = true; - } - - if (result) { - decl.value = result[0]; - decl.important = result[1] || ''; - decl.parsed = true; - } - }); - } else { - decl.parsed = true; - } - - return decl; - } else { - return decl; + }), this.strictImports, this.visibilityInfo()); + return result; + }; + Ruleset.prototype.matchArgs = function (args) { + return !args || args.length === 0; + }; + // lets you call a css selector with a guard + Ruleset.prototype.matchCondition = function (args, context) { + var lastSelector = this.selectors[this.selectors.length - 1]; + if (!lastSelector.evaldCondition) { + return false; } - } - - if (!Array.isArray(toParse)) { - return transformDeclaration.call(self, toParse); - } else { - var nodes = []; - toParse.forEach(function (n) { - nodes.push(transformDeclaration.call(self, n)); - }); - return nodes; - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (!this.rules) { - return []; - } - - var filtRules = []; - var rules = this.rules; - var i; - var rule; - - for (i = 0; rule = rules[i]; i++) { - if (rule.isRuleset) { - filtRules.push(rule); + if (lastSelector.condition && + !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { + return false; } - } - - return filtRules; - } - }, { - key: "prependRule", - value: function prependRule(rule) { - var rules = this.rules; - - if (rules) { - rules.unshift(rule); - } else { - this.rules = [rule]; - } - - this.setParent(rule, this); - } - }, { - key: "find", - value: function find(selector) { - var self = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this; - var filter = arguments.length > 2 ? arguments[2] : undefined; - var rules = []; - var match; - var foundMixins; - var key = selector.toCSS(); - - if (key in this._lookups) { - return this._lookups[key]; - } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - - if (match) { - if (selector.elements.length > match) { - if (!filter || filter(rule)) { - foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); - - for (var i = 0; i < foundMixins.length; ++i) { - foundMixins[i].path.push(rule); - } - - Array.prototype.push.apply(rules, foundMixins); + return true; + }; + Ruleset.prototype.resetCache = function () { + this._rulesets = null; + this._variables = null; + this._properties = null; + this._lookups = {}; + }; + Ruleset.prototype.variables = function () { + if (!this._variables) { + this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable === true) { + hash[r.name] = r; } - } else { - rules.push({ - rule, - path: [] - }); - } - - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var j; - var charsetRuleNodes = []; - var ruleNodes = []; - var // Line number debugging - debugInfo$1; - var rule; - var path; - context.tabLevel = context.tabLevel || 0; - - if (!this.root) { - context.tabLevel++; - } - - var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); - var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); - var sep; - var charsetNodeIndex = 0; - var importNodeIndex = 0; - - for (i = 0; rule = this.rules[i]; i++) { - if (rule instanceof Comment) { - if (importNodeIndex === i) { - importNodeIndex++; - } - - ruleNodes.push(rule); - } else if (rule.isCharset && rule.isCharset()) { - ruleNodes.splice(charsetNodeIndex, 0, rule); - charsetNodeIndex++; - importNodeIndex++; - } else if (rule.type === 'Import') { - ruleNodes.splice(importNodeIndex, 0, rule); - importNodeIndex++; - } else { - ruleNodes.push(rule); - } - } - - ruleNodes = charsetRuleNodes.concat(ruleNodes); // If this is the root node, we don't render - // a selector, or {}. - - if (!this.root) { - debugInfo$1 = debugInfo(context, this, tabSetStr); - - if (debugInfo$1) { - output.add(debugInfo$1); - output.add(tabSetStr); - } - - var paths = this.paths; - var pathCnt = paths.length; - var pathSubCnt; - sep = context.compress ? ',' : `,\n${tabSetStr}`; - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - - if (!(pathSubCnt = path.length)) { - continue; - } - - if (i > 0) { - output.add(sep); - } - - context.firstSelector = true; - path[0].genCSS(context, output); - context.firstSelector = false; - - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(context, output); - } + // when evaluating variables in an import statement, imports have not been eval'd + // so we need to go inside import statements. + // guard against root being a string (in the case of inlined less) + if (r.type === 'Import' && r.root && r.root.variables) { + var vars = r.root.variables(); + for (var name_1 in vars) { + if (vars.hasOwnProperty(name_1)) { + hash[name_1] = r.root.variable(name_1); + } + } + } + return hash; + }, {}); } - - output.add((context.compress ? '{' : ' {\n') + tabRuleStr); - } // Compile rules and rulesets - - - for (i = 0; rule = ruleNodes[i]; i++) { - if (i + 1 === ruleNodes.length) { - context.lastRule = true; + return this._variables; + }; + Ruleset.prototype.properties = function () { + if (!this._properties) { + this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable !== true) { + var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ? + r.name[0].value : r.name; + // Properties don't overwrite as they can merge + if (!hash["$" + name_2]) { + hash["$" + name_2] = [r]; + } + else { + hash["$" + name_2].push(r); + } + } + return hash; + }, {}); } - - var currentLastRule = context.lastRule; - - if (rule.isRulesetLike(rule)) { - context.lastRule = false; + return this._properties; + }; + Ruleset.prototype.variable = function (name) { + var decl = this.variables()[name]; + if (decl) { + return this.parseValue(decl); } - - if (rule.genCSS) { - rule.genCSS(context, output); - } else if (rule.value) { - output.add(rule.value.toString()); + }; + Ruleset.prototype.property = function (name) { + var decl = this.properties()[name]; + if (decl) { + return this.parseValue(decl); } - - context.lastRule = currentLastRule; - - if (!context.lastRule && rule.isVisible()) { - output.add(context.compress ? '' : `\n${tabRuleStr}`); - } else { - context.lastRule = false; + }; + Ruleset.prototype.lastDeclaration = function () { + for (var i_1 = this.rules.length; i_1 > 0; i_1--) { + var decl = this.rules[i_1 - 1]; + if (decl instanceof Declaration) { + return this.parseValue(decl); + } } - } - - if (!this.root) { - output.add(context.compress ? '}' : `\n${tabSetStr}}`); - context.tabLevel--; - } - - if (!output.isEmpty() && !context.compress && this.firstRoot) { - output.add('\n'); - } - } - }, { - key: "joinSelectors", - value: function joinSelectors(paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - } - }, { - key: "joinSelector", - value: function joinSelector(paths, context, selector) { - function createParenthesis(elementsToPak, originalElement) { - var replacementParen; - var j; - - if (elementsToPak.length === 0) { - replacementParen = new Paren(elementsToPak[0]); - } else { - var insideParent = new Array(elementsToPak.length); - - for (j = 0; j < elementsToPak.length; j++) { - insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); - } - - replacementParen = new Paren(new Selector(insideParent)); + }; + Ruleset.prototype.parseValue = function (toParse) { + var self = this; + function transformDeclaration(decl) { + if (decl.value instanceof Anonymous && !decl.parsed) { + if (typeof decl.value.value === 'string') { + this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { + if (err) { + decl.parsed = true; + } + if (result) { + decl.value = result[0]; + decl.important = result[1] || ''; + decl.parsed = true; + } + }); + } + else { + decl.parsed = true; + } + return decl; + } + else { + return decl; + } } - - return replacementParen; - } - - function createSelector(containedElement, originalElement) { - var element; - var selector; - element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); - selector = new Selector([element]); - return selector; - } // joins selector path from `beginningPath` with selector path in `addPath` - // `replacedElement` contains element that is being replaced by `addPath` - // returns concatenated path - - - function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { - var newSelectorPath; - var lastSelector; - var newJoinedSelector; // our new selector path - - newSelectorPath = []; // construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - - if (beginningPath.length > 0) { - newSelectorPath = copyArray(beginningPath); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); - } else { - newJoinedSelector = originalSelector.createDerived([]); + if (!Array.isArray(toParse)) { + return transformDeclaration.call(self, toParse); } - - if (addPath.length > 0) { - // /deep/ is a CSS4 selector - (removed, so should deprecate) - // that is valid without anything in front of it - // so if the & does not have a combinator that is "" or " " then - // and there is a combinator on the parent, then grab that. - // this also allows + a { & .b { .a & { ... though not sure why you would want to do that - var combinator = replacedElement.combinator; - var parentEl = addPath[0].elements[0]; - - if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { - combinator = parentEl.combinator; - } // join the elements so far with the first part of the parent - - - newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); - } // now add the joined selector - but only if it is not empty - - - if (newJoinedSelector.elements.length !== 0) { - newSelectorPath.push(newJoinedSelector); - } // put together the parent selectors after the join (e.g. the rest of the parent) - - - if (addPath.length > 1) { - var restOfPath = addPath.slice(1); - restOfPath = restOfPath.map(function (selector) { - return selector.createDerived(selector.elements, []); - }); - newSelectorPath = newSelectorPath.concat(restOfPath); + else { + var nodes_1 = []; + toParse.forEach(function (n) { + nodes_1.push(transformDeclaration.call(self, n)); + }); + return nodes_1; } - - return newSelectorPath; - } // joins selector path from `beginningPath` with every selector path in `addPaths` array - // `replacedElement` contains element that is being replaced by `addPath` - // returns array with all concatenated paths - - - function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { - var j; - - for (j = 0; j < beginningPath.length; j++) { - var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); - result.push(newSelectorPath); + }; + Ruleset.prototype.rulesets = function () { + if (!this.rules) { + return []; } - - return result; - } - - function mergeElementsOnToSelectors(elements, selectors) { + var filtRules = []; + var rules = this.rules; var i; - var sel; - - if (elements.length === 0) { - return; + var rule; + for (i = 0; (rule = rules[i]); i++) { + if (rule.isRuleset) { + filtRules.push(rule); + } } - - if (selectors.length === 0) { - selectors.push([new Selector(elements)]); - return; + return filtRules; + }; + Ruleset.prototype.prependRule = function (rule) { + var rules = this.rules; + if (rules) { + rules.unshift(rule); } - - for (i = 0; sel = selectors[i]; i++) { - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } else { - sel.push(new Selector(elements)); - } - } - } // replace all parent selectors inside `inSelector` by content of `context` array - // resulting selectors are returned inside `paths` array - // returns true if `inSelector` contained at least one parent selector - - - function replaceParentSelector(paths, context, inSelector) { - // The paths are [[Selector]] - // The first list is a list of comma separated selectors - // The inner list is a list of inheritance separated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // + else { + this.rules = [rule]; + } + this.setParent(rule, this); + }; + Ruleset.prototype.find = function (selector, self, filter) { + if (self === void 0) { self = this; } + var rules = []; + var match; + var foundMixins; + var key = selector.toCSS(); + if (key in this._lookups) { + return this._lookups[key]; + } + this.rulesets().forEach(function (rule) { + if (rule !== self) { + for (var j = 0; j < rule.selectors.length; j++) { + match = selector.match(rule.selectors[j]); + if (match) { + if (selector.elements.length > match) { + if (!filter || filter(rule)) { + foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); + for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) { + foundMixins[i_2].path.push(rule); + } + Array.prototype.push.apply(rules, foundMixins); + } + } + else { + rules.push({ rule: rule, path: [] }); + } + break; + } + } + } + }); + this._lookups[key] = rules; + return rules; + }; + Ruleset.prototype.genCSS = function (context, output) { var i; var j; - var k; - var currentElements; - var newSelectors; - var selectorsMultiplied; - var sel; - var el; - var hadParentSelector = false; - var length; - var lastSelector; - - function findNestedSelector(element) { - var maybeSelector; - - if (!(element.value instanceof Paren)) { - return null; - } - - maybeSelector = element.value.value; - - if (!(maybeSelector instanceof Selector)) { - return null; - } - - return maybeSelector; - } // the elements from the current selector so far - - - currentElements = []; // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - - newSelectors = [[]]; - - for (i = 0; el = inSelector.elements[i]; i++) { - // non parent reference elements just get added - if (el.value !== '&') { - var nestedSelector = findNestedSelector(el); - - if (nestedSelector != null) { - // merge the current list of non parent selector elements - // on to the current list of selectors to add - mergeElementsOnToSelectors(currentElements, newSelectors); - var nestedPaths = []; - var replaced = void 0; - var replacedNewSelectors = []; - replaced = replaceParentSelector(nestedPaths, context, nestedSelector); - hadParentSelector = hadParentSelector || replaced; // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors - - for (k = 0; k < nestedPaths.length; k++) { - var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); - addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); - } - - newSelectors = replacedNewSelectors; - currentElements = []; - } else { - currentElements.push(el); + var charsetRuleNodes = []; + var ruleNodes = []; + var // Line number debugging + debugInfo$1; + var rule; + var path; + context.tabLevel = (context.tabLevel || 0); + if (!this.root) { + context.tabLevel++; + } + var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); + var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); + var sep; + var charsetNodeIndex = 0; + var importNodeIndex = 0; + for (i = 0; (rule = this.rules[i]); i++) { + if (rule instanceof Comment) { + if (importNodeIndex === i) { + importNodeIndex++; + } + ruleNodes.push(rule); } - } else { - hadParentSelector = true; // the new list of selectors to add - - selectorsMultiplied = []; // merge the current list of non parent selector elements - // on to the current list of selectors to add - - mergeElementsOnToSelectors(currentElements, newSelectors); // loop through our current selectors - - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + else if (rule.isCharset && rule.isCharset()) { + ruleNodes.splice(charsetNodeIndex, 0, rule); + charsetNodeIndex++; + importNodeIndex++; + } + else if (rule.type === 'Import') { + ruleNodes.splice(importNodeIndex, 0, rule); + importNodeIndex++; + } + else { + ruleNodes.push(rule); + } + } + ruleNodes = charsetRuleNodes.concat(ruleNodes); + // If this is the root node, we don't render + // a selector, or {}. + if (!this.root) { + debugInfo$1 = debugInfo(context, this, tabSetStr); + if (debugInfo$1) { + output.add(debugInfo$1); + output.add(tabSetStr); + } + var paths = this.paths; + var pathCnt = paths.length; + var pathSubCnt = void 0; + sep = context.compress ? ',' : (",\n" + tabSetStr); + for (i = 0; i < pathCnt; i++) { + path = paths[i]; + if (!(pathSubCnt = path.length)) { + continue; } - - selectorsMultiplied.push(sel); - } else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); // add that to our new set of selectors - - selectorsMultiplied.push(newSelectorPath); + if (i > 0) { + output.add(sep); } - } - } // our new selectors has been multiplied, so reset the state - - - newSelectors = selectorsMultiplied; + context.firstSelector = true; + path[0].genCSS(context, output); + context.firstSelector = false; + for (j = 1; j < pathSubCnt; j++) { + path[j].genCSS(context, output); + } + } + output.add((context.compress ? '{' : ' {\n') + tabRuleStr); + } + // Compile rules and rulesets + for (i = 0; (rule = ruleNodes[i]); i++) { + if (i + 1 === ruleNodes.length) { + context.lastRule = true; + } + var currentLastRule = context.lastRule; + if (rule.isRulesetLike(rule)) { + context.lastRule = false; + } + if (rule.genCSS) { + rule.genCSS(context, output); + } + else if (rule.value) { + output.add(rule.value.toString()); + } + context.lastRule = currentLastRule; + if (!context.lastRule && rule.isVisible()) { + output.add(context.compress ? '' : ("\n" + tabRuleStr)); + } + else { + context.lastRule = false; + } + } + if (!this.root) { + output.add((context.compress ? '}' : "\n" + tabSetStr + "}")); + context.tabLevel--; + } + if (!output.isEmpty() && !context.compress && this.firstRoot) { + output.add('\n'); + } + }; + Ruleset.prototype.joinSelectors = function (paths, context, selectors) { + for (var s = 0; s < selectors.length; s++) { + this.joinSelector(paths, context, selectors[s]); + } + }; + Ruleset.prototype.joinSelector = function (paths, context, selector) { + function createParenthesis(elementsToPak, originalElement) { + var replacementParen; + var j; + if (elementsToPak.length === 0) { + replacementParen = new Paren(elementsToPak[0]); + } + else { + var insideParent = new Array(elementsToPak.length); + for (j = 0; j < elementsToPak.length; j++) { + insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); + } + replacementParen = new Paren(new Selector(insideParent)); + } + return replacementParen; + } + function createSelector(containedElement, originalElement) { + var element; + var selector; + element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); + selector = new Selector([element]); + return selector; + } + // joins selector path from `beginningPath` with selector path in `addPath` + // `replacedElement` contains element that is being replaced by `addPath` + // returns concatenated path + function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { + var newSelectorPath; + var lastSelector; + var newJoinedSelector; + // our new selector path + newSelectorPath = []; + // construct the joined selector - if & is the first thing this will be empty, + // if not newJoinedSelector will be the last set of elements in the selector + if (beginningPath.length > 0) { + newSelectorPath = copyArray(beginningPath); + lastSelector = newSelectorPath.pop(); + newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); + } + else { + newJoinedSelector = originalSelector.createDerived([]); + } + if (addPath.length > 0) { + // /deep/ is a CSS4 selector - (removed, so should deprecate) + // that is valid without anything in front of it + // so if the & does not have a combinator that is "" or " " then + // and there is a combinator on the parent, then grab that. + // this also allows + a { & .b { .a & { ... though not sure why you would want to do that + var combinator = replacedElement.combinator; + var parentEl = addPath[0].elements[0]; + if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { + combinator = parentEl.combinator; + } + // join the elements so far with the first part of the parent + newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); + newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); + } + // now add the joined selector - but only if it is not empty + if (newJoinedSelector.elements.length !== 0) { + newSelectorPath.push(newJoinedSelector); + } + // put together the parent selectors after the join (e.g. the rest of the parent) + if (addPath.length > 1) { + var restOfPath = addPath.slice(1); + restOfPath = restOfPath.map(function (selector) { return selector.createDerived(selector.elements, []); }); + newSelectorPath = newSelectorPath.concat(restOfPath); + } + return newSelectorPath; + } + // joins selector path from `beginningPath` with every selector path in `addPaths` array + // `replacedElement` contains element that is being replaced by `addPath` + // returns array with all concatenated paths + function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { + var j; + for (j = 0; j < beginningPath.length; j++) { + var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); + result.push(newSelectorPath); + } + return result; + } + function mergeElementsOnToSelectors(elements, selectors) { + var i; + var sel; + if (elements.length === 0) { + return; + } + if (selectors.length === 0) { + selectors.push([new Selector(elements)]); + return; + } + for (i = 0; (sel = selectors[i]); i++) { + // if the previous thing in sel is a parent this needs to join on to it + if (sel.length > 0) { + sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); + } + else { + sel.push(new Selector(elements)); + } + } + } + // replace all parent selectors inside `inSelector` by content of `context` array + // resulting selectors are returned inside `paths` array + // returns true if `inSelector` contained at least one parent selector + function replaceParentSelector(paths, context, inSelector) { + // The paths are [[Selector]] + // The first list is a list of comma separated selectors + // The inner list is a list of inheritance separated selectors + // e.g. + // .a, .b { + // .c { + // } + // } + // == [[.a] [.c]] [[.b] [.c]] + // + var i; + var j; + var k; + var currentElements; + var newSelectors; + var selectorsMultiplied; + var sel; + var el; + var hadParentSelector = false; + var length; + var lastSelector; + function findNestedSelector(element) { + var maybeSelector; + if (!(element.value instanceof Paren)) { + return null; + } + maybeSelector = element.value.value; + if (!(maybeSelector instanceof Selector)) { + return null; + } + return maybeSelector; + } + // the elements from the current selector so far currentElements = []; - } - } // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - - - mergeElementsOnToSelectors(currentElements, newSelectors); - - for (i = 0; i < newSelectors.length; i++) { - length = newSelectors[i].length; - - if (length > 0) { - paths.push(newSelectors[i]); - lastSelector = newSelectors[i][length - 1]; - newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); - } + // the current list of new selectors to add to the path. + // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors + // by the parents + newSelectors = [ + [] + ]; + for (i = 0; (el = inSelector.elements[i]); i++) { + // non parent reference elements just get added + if (el.value !== '&') { + var nestedSelector = findNestedSelector(el); + if (nestedSelector != null) { + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + var nestedPaths = []; + var replaced = void 0; + var replacedNewSelectors = []; + replaced = replaceParentSelector(nestedPaths, context, nestedSelector); + hadParentSelector = hadParentSelector || replaced; + // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors + for (k = 0; k < nestedPaths.length; k++) { + var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); + addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); + } + newSelectors = replacedNewSelectors; + currentElements = []; + } + else { + currentElements.push(el); + } + } + else { + hadParentSelector = true; + // the new list of selectors to add + selectorsMultiplied = []; + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + // loop through our current selectors + for (j = 0; j < newSelectors.length; j++) { + sel = newSelectors[j]; + // if we don't have any parent paths, the & might be in a mixin so that it can be used + // whether there are parents or not + if (context.length === 0) { + // the combinator used on el should now be applied to the next element instead so that + // it is not lost + if (sel.length > 0) { + sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + } + selectorsMultiplied.push(sel); + } + else { + // and the parent selectors + for (k = 0; k < context.length; k++) { + // We need to put the current selectors + // then join the last selector's elements on to the parents selectors + var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); + // add that to our new set of selectors + selectorsMultiplied.push(newSelectorPath); + } + } + } + // our new selectors has been multiplied, so reset the state + newSelectors = selectorsMultiplied; + currentElements = []; + } + } + // if we have any elements left over (e.g. .a& .b == .b) + // add them on to all the current selectors + mergeElementsOnToSelectors(currentElements, newSelectors); + for (i = 0; i < newSelectors.length; i++) { + length = newSelectors[i].length; + if (length > 0) { + paths.push(newSelectors[i]); + lastSelector = newSelectors[i][length - 1]; + newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); + } + } + return hadParentSelector; } - - return hadParentSelector; - } - - function deriveSelector(visibilityInfo, deriveFrom) { - var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); - newSelector.copyVisibilityInfo(visibilityInfo); - return newSelector; - } // joinSelector code follows - - - var i; - var newPaths; - var hadParentSelector; - newPaths = []; - hadParentSelector = replaceParentSelector(newPaths, context, selector); - - if (!hadParentSelector) { - if (context.length > 0) { - newPaths = []; - - for (i = 0; i < context.length; i++) { - var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); - concatenated.push(selector); - newPaths.push(concatenated); - } - } else { - newPaths = [[selector]]; - } - } - - for (i = 0; i < newPaths.length; i++) { - paths.push(newPaths[i]); - } - } - }]); - - return Ruleset; -}(Node); - + function deriveSelector(visibilityInfo, deriveFrom) { + var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); + newSelector.copyVisibilityInfo(visibilityInfo); + return newSelector; + } + // joinSelector code follows + var i; + var newPaths; + var hadParentSelector; + newPaths = []; + hadParentSelector = replaceParentSelector(newPaths, context, selector); + if (!hadParentSelector) { + if (context.length > 0) { + newPaths = []; + for (i = 0; i < context.length; i++) { + var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); + concatenated.push(selector); + newPaths.push(concatenated); + } + } + else { + newPaths = [[selector]]; + } + } + for (i = 0; i < newPaths.length; i++) { + paths.push(newPaths[i]); + } + }; + return Ruleset; +}(Node)); Ruleset.prototype.type = 'Ruleset'; Ruleset.prototype.isRuleset = true; -var AtRule = -/*#__PURE__*/ -function (_Node) { - _inherits(AtRule, _Node); - - function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { - var _this; - - _classCallCheck(this, AtRule); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(AtRule).call(this)); - var i; - _this.name = name; - _this.value = value instanceof Node ? value : value ? new Anonymous(value) : value; - - if (rules) { - if (Array.isArray(rules)) { - _this.rules = rules; - } else { - _this.rules = [rules]; - _this.rules[0].selectors = new Selector([], null, null, index, currentFileInfo).createEmptySelectors(); - } - - for (i = 0; i < _this.rules.length; i++) { - _this.rules[i].allowImports = true; - } - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - } - - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.debugInfo = debugInfo; - _this.isRooted = isRooted || false; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(AtRule, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - var rules = this.rules; - - if (rules) { - this.rules = visitor.visitArray(rules); - } - - if (value) { - this.value = visitor.visit(value); - } - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rules || !this.isCharset(); - } - }, { - key: "isCharset", - value: function isCharset() { - return '@charset' === this.name; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var value = this.value; - var rules = this.rules; - output.add(this.name, this.fileInfo(), this.getIndex()); - - if (value) { - output.add(' '); - value.genCSS(context, output); - } - - if (rules) { - this.outputRuleset(context, output, rules); - } else { - output.add(';'); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mediaPathBackup; - var mediaBlocksBackup; - var value = this.value; - var rules = this.rules; // media stored inside other atrule should not bubble over it - // backpup media bubbling information - - mediaPathBackup = context.mediaPath; - mediaBlocksBackup = context.mediaBlocks; // deleted media bubbling information - - context.mediaPath = []; - context.mediaBlocks = []; - - if (value) { - value = value.eval(context); - } - - if (rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - rules = [rules[0].eval(context)]; - rules[0].root = true; - } // restore media bubbling information - - - context.mediaPath = mediaPathBackup; - context.mediaBlocks = mediaBlocksBackup; - return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); - } - }, { - key: "variable", - value: function variable(name) { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.variable.call(this.rules[0], name); - } - } - }, { - key: "find", - value: function find() { - if (this.rules) { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; +var AtRule = /** @class */ (function (_super) { + tslib.__extends(AtRule, _super); + function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { + var _this = _super.call(this) || this; + var i; + _this.name = name; + _this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value); + if (rules) { + if (Array.isArray(rules)) { + _this.rules = rules; + } + else { + _this.rules = [rules]; + _this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors(); + } + for (i = 0; i < _this.rules.length; i++) { + _this.rules[i].allowImports = true; + } + _this.setParent(_this.rules, _this); + } + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.debugInfo = debugInfo; + _this.isRooted = isRooted || false; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + AtRule.prototype.accept = function (visitor) { + var value = this.value; + var rules = this.rules; + if (rules) { + this.rules = visitor.visitArray(rules); } - - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.find.apply(this.rules[0], args); - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.rulesets.apply(this.rules[0]); - } - } - }, { - key: "outputRuleset", - value: function outputRuleset(context, output, rules) { - var ruleCnt = rules.length; - var i; - context.tabLevel = (context.tabLevel | 0) + 1; // Compressed - - if (context.compress) { - output.add('{'); - - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(context, output); + if (value) { + this.value = visitor.visit(value); } - - output.add('}'); - context.tabLevel--; - return; - } // Non-compressed - - - var tabSetStr = `\n${Array(context.tabLevel).join(' ')}`; - var tabRuleStr = `${tabSetStr} `; - - if (!ruleCnt) { - output.add(` {${tabSetStr}}`); - } else { - output.add(` {${tabRuleStr}`); - rules[0].genCSS(context, output); - - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(context, output); + }; + AtRule.prototype.isRulesetLike = function () { + return this.rules || !this.isCharset(); + }; + AtRule.prototype.isCharset = function () { + return '@charset' === this.name; + }; + AtRule.prototype.genCSS = function (context, output) { + var value = this.value; + var rules = this.rules; + output.add(this.name, this.fileInfo(), this.getIndex()); + if (value) { + output.add(' '); + value.genCSS(context, output); } - - output.add(`${tabSetStr}}`); - } - - context.tabLevel--; - } - }]); - - return AtRule; -}(Node); - + if (rules) { + this.outputRuleset(context, output, rules); + } + else { + output.add(';'); + } + }; + AtRule.prototype.eval = function (context) { + var mediaPathBackup; + var mediaBlocksBackup; + var value = this.value; + var rules = this.rules; + // media stored inside other atrule should not bubble over it + // backpup media bubbling information + mediaPathBackup = context.mediaPath; + mediaBlocksBackup = context.mediaBlocks; + // deleted media bubbling information + context.mediaPath = []; + context.mediaBlocks = []; + if (value) { + value = value.eval(context); + } + if (rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + rules = [rules[0].eval(context)]; + rules[0].root = true; + } + // restore media bubbling information + context.mediaPath = mediaPathBackup; + context.mediaBlocks = mediaBlocksBackup; + return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); + }; + AtRule.prototype.variable = function (name) { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.variable.call(this.rules[0], name); + } + }; + AtRule.prototype.find = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.find.apply(this.rules[0], args); + } + }; + AtRule.prototype.rulesets = function () { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.rulesets.apply(this.rules[0]); + } + }; + AtRule.prototype.outputRuleset = function (context, output, rules) { + var ruleCnt = rules.length; + var i; + context.tabLevel = (context.tabLevel | 0) + 1; + // Compressed + if (context.compress) { + output.add('{'); + for (i = 0; i < ruleCnt; i++) { + rules[i].genCSS(context, output); + } + output.add('}'); + context.tabLevel--; + return; + } + // Non-compressed + var tabSetStr = "\n" + Array(context.tabLevel).join(' '); + var tabRuleStr = tabSetStr + " "; + if (!ruleCnt) { + output.add(" {" + tabSetStr + "}"); + } + else { + output.add(" {" + tabRuleStr); + rules[0].genCSS(context, output); + for (i = 1; i < ruleCnt; i++) { + output.add(tabRuleStr); + rules[i].genCSS(context, output); + } + output.add(tabSetStr + "}"); + } + context.tabLevel--; + }; + return AtRule; +}(Node)); AtRule.prototype.type = 'AtRule'; -var DetachedRuleset = -/*#__PURE__*/ -function (_Node) { - _inherits(DetachedRuleset, _Node); - - function DetachedRuleset(ruleset, frames) { - var _this; - - _classCallCheck(this, DetachedRuleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(DetachedRuleset).call(this)); - _this.ruleset = ruleset; - _this.frames = frames; - - _this.setParent(_this.ruleset, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(DetachedRuleset, [{ - key: "accept", - value: function accept(visitor) { - this.ruleset = visitor.visit(this.ruleset); - } - }, { - key: "eval", - value: function _eval(context) { - var frames = this.frames || copyArray(context.frames); - return new DetachedRuleset(this.ruleset, frames); - } - }, { - key: "callEval", - value: function callEval(context) { - return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); - } - }]); - - return DetachedRuleset; -}(Node); - +var DetachedRuleset = /** @class */ (function (_super) { + tslib.__extends(DetachedRuleset, _super); + function DetachedRuleset(ruleset, frames) { + var _this = _super.call(this) || this; + _this.ruleset = ruleset; + _this.frames = frames; + _this.setParent(_this.ruleset, _this); + return _this; + } + DetachedRuleset.prototype.accept = function (visitor) { + this.ruleset = visitor.visit(this.ruleset); + }; + DetachedRuleset.prototype.eval = function (context) { + var frames = this.frames || copyArray(context.frames); + return new DetachedRuleset(this.ruleset, frames); + }; + DetachedRuleset.prototype.callEval = function (context) { + return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); + }; + return DetachedRuleset; +}(Node)); DetachedRuleset.prototype.type = 'DetachedRuleset'; DetachedRuleset.prototype.evalFirst = true; -var Unit = -/*#__PURE__*/ -function (_Node) { - _inherits(Unit, _Node); - - function Unit(numerator, denominator, backupUnit) { - var _this; - - _classCallCheck(this, Unit); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Unit).call(this)); - _this.numerator = numerator ? copyArray(numerator).sort() : []; - _this.denominator = denominator ? copyArray(denominator).sort() : []; - - if (backupUnit) { - _this.backupUnit = backupUnit; - } else if (numerator && numerator.length) { - _this.backupUnit = numerator[0]; +var Unit = /** @class */ (function (_super) { + tslib.__extends(Unit, _super); + function Unit(numerator, denominator, backupUnit) { + var _this = _super.call(this) || this; + _this.numerator = numerator ? copyArray(numerator).sort() : []; + _this.denominator = denominator ? copyArray(denominator).sort() : []; + if (backupUnit) { + _this.backupUnit = backupUnit; + } + else if (numerator && numerator.length) { + _this.backupUnit = numerator[0]; + } + return _this; } - - return _this; - } - - _createClass(Unit, [{ - key: "clone", - value: function clone() { - return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - // Dimension checks the unit is singular and throws an error if in strict math mode. - var strictUnits = context && context.strictUnits; - - if (this.numerator.length === 1) { - output.add(this.numerator[0]); // the ideal situation - } else if (!strictUnits && this.backupUnit) { - output.add(this.backupUnit); - } else if (!strictUnits && this.denominator.length) { - output.add(this.denominator[0]); - } - } - }, { - key: "toString", - value: function toString() { - var i; - var returnStr = this.numerator.join('*'); - - for (i = 0; i < this.denominator.length; i++) { - returnStr += `/${this.denominator[i]}`; - } - - return returnStr; - } - }, { - key: "compare", - value: function compare(other) { - return this.is(other.toString()) ? 0 : undefined; - } - }, { - key: "is", - value: function is(unitString) { - return this.toString().toUpperCase() === unitString.toUpperCase(); - } - }, { - key: "isLength", - value: function isLength() { - return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this.numerator.length === 0 && this.denominator.length === 0; - } - }, { - key: "isSingular", - value: function isSingular() { - return this.numerator.length <= 1 && this.denominator.length === 0; - } - }, { - key: "map", - value: function map(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - } - }, { - key: "usedUnits", - value: function usedUnits() { - var group; - var result = {}; - var mapUnit; - var groupName; - - mapUnit = function mapUnit(atomicUnit) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; + Unit.prototype.clone = function () { + return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); + }; + Unit.prototype.genCSS = function (context, output) { + // Dimension checks the unit is singular and throws an error if in strict math mode. + var strictUnits = context && context.strictUnits; + if (this.numerator.length === 1) { + output.add(this.numerator[0]); // the ideal situation } - - return atomicUnit; - }; - - for (groupName in unitConversions) { - if (unitConversions.hasOwnProperty(groupName)) { - group = unitConversions[groupName]; - this.map(mapUnit); + else if (!strictUnits && this.backupUnit) { + output.add(this.backupUnit); } - } - - return result; - } - }, { - key: "cancel", - value: function cancel() { - var counter = {}; - var atomicUnit; - var i; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); + else if (!strictUnits && this.denominator.length) { + output.add(this.denominator[0]); + } + }; + Unit.prototype.toString = function () { + var i; + var returnStr = this.numerator.join('*'); + for (i = 0; i < this.denominator.length; i++) { + returnStr += "/" + this.denominator[i]; + } + return returnStr; + }; + Unit.prototype.compare = function (other) { + return this.is(other.toString()) ? 0 : undefined; + }; + Unit.prototype.is = function (unitString) { + return this.toString().toUpperCase() === unitString.toUpperCase(); + }; + Unit.prototype.isLength = function () { + return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); + }; + Unit.prototype.isEmpty = function () { + return this.numerator.length === 0 && this.denominator.length === 0; + }; + Unit.prototype.isSingular = function () { + return this.numerator.length <= 1 && this.denominator.length === 0; + }; + Unit.prototype.map = function (callback) { + var i; + for (i = 0; i < this.numerator.length; i++) { + this.numerator[i] = callback(this.numerator[i], false); + } + for (i = 0; i < this.denominator.length; i++) { + this.denominator[i] = callback(this.denominator[i], true); + } + }; + Unit.prototype.usedUnits = function () { + var group; + var result = {}; + var mapUnit; + var groupName; + mapUnit = function (atomicUnit) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { + result[groupName] = atomicUnit; } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); + return atomicUnit; + }; + for (groupName in unitConversions) { + if (unitConversions.hasOwnProperty(groupName)) { + group = unitConversions[groupName]; + this.map(mapUnit); } - } } - } - - this.numerator.sort(); - this.denominator.sort(); - } - }]); - - return Unit; -}(Node); - + return result; + }; + Unit.prototype.cancel = function () { + var counter = {}; + var atomicUnit; + var i; + for (i = 0; i < this.numerator.length; i++) { + atomicUnit = this.numerator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; + } + for (i = 0; i < this.denominator.length; i++) { + atomicUnit = this.denominator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; + } + this.numerator = []; + this.denominator = []; + for (atomicUnit in counter) { + if (counter.hasOwnProperty(atomicUnit)) { + var count = counter[atomicUnit]; + if (count > 0) { + for (i = 0; i < count; i++) { + this.numerator.push(atomicUnit); + } + } + else if (count < 0) { + for (i = 0; i < -count; i++) { + this.denominator.push(atomicUnit); + } + } + } + } + this.numerator.sort(); + this.denominator.sort(); + }; + return Unit; +}(Node)); Unit.prototype.type = 'Unit'; +// // A number with a unit // - -var Dimension = -/*#__PURE__*/ -function (_Node) { - _inherits(Dimension, _Node); - - function Dimension(value, unit) { - var _this; - - _classCallCheck(this, Dimension); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Dimension).call(this)); - _this.value = parseFloat(value); - - if (isNaN(_this.value)) { - throw new Error('Dimension is not a number.'); - } - - _this.unit = unit && unit instanceof Unit ? unit : new Unit(unit ? [unit] : undefined); - - _this.setParent(_this.unit, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Dimension, [{ - key: "accept", - value: function accept(visitor) { - this.unit = visitor.visit(this.unit); - } - }, { - key: "eval", - value: function _eval(context) { - return this; - } - }, { - key: "toColor", - value: function toColor() { - return new Color([this.value, this.value, this.value]); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (context && context.strictUnits && !this.unit.isSingular()) { - throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`); - } - - var value = this.fround(context, this.value); - var strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ''); - } - - if (context && context.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } // Float values doesn't need a leading zero - - - if (value > 0 && value < 1) { - strValue = strValue.substr(1); +var Dimension = /** @class */ (function (_super) { + tslib.__extends(Dimension, _super); + function Dimension(value, unit) { + var _this = _super.call(this) || this; + _this.value = parseFloat(value); + if (isNaN(_this.value)) { + throw new Error('Dimension is not a number.'); + } + _this.unit = (unit && unit instanceof Unit) ? unit : + new Unit(unit ? [unit] : undefined); + _this.setParent(_this.unit, _this); + return _this; + } + Dimension.prototype.accept = function (visitor) { + this.unit = visitor.visit(this.unit); + }; + Dimension.prototype.eval = function (context) { + return this; + }; + Dimension.prototype.toColor = function () { + return new Color([this.value, this.value, this.value]); + }; + Dimension.prototype.genCSS = function (context, output) { + if ((context && context.strictUnits) && !this.unit.isSingular()) { + throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString()); + } + var value = this.fround(context, this.value); + var strValue = String(value); + if (value !== 0 && value < 0.000001 && value > -0.000001) { + // would be output 1e-6 etc. + strValue = value.toFixed(20).replace(/0+$/, ''); + } + if (context && context.compress) { + // Zero values doesn't need a unit + if (value === 0 && this.unit.isLength()) { + output.add(strValue); + return; + } + // Float values doesn't need a leading zero + if (value > 0 && value < 1) { + strValue = (strValue).substr(1); + } } - } - - output.add(strValue); - this.unit.genCSS(context, output); - } // In an operation between two Dimensions, + output.add(strValue); + this.unit.genCSS(context, output); + }; + // In an operation between two Dimensions, // we default to the first Dimension's unit, // so `1px + 2` will yield `3px`. - - }, { - key: "operate", - value: function operate(context, op, other) { - /* jshint noempty:false */ - var value = this._operate(context, op, this.value, other.value); - - var unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit = other.unit.clone(); - - if (this.unit.backupUnit) { - unit.backupUnit = this.unit.backupUnit; - } - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; else { - other = other.convertTo(this.unit.usedUnits()); - - if (context.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error(`Incompatible units. Change the units or use the unit function. ` + `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`); - } - - value = this._operate(context, op, this.value, other.value); + Dimension.prototype.operate = function (context, op, other) { + /* jshint noempty:false */ + var value = this._operate(context, op, this.value, other.value); + var unit = this.unit.clone(); + if (op === '+' || op === '-') { + if (unit.numerator.length === 0 && unit.denominator.length === 0) { + unit = other.unit.clone(); + if (this.unit.backupUnit) { + unit.backupUnit = this.unit.backupUnit; + } + } + else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; + else { + other = other.convertTo(this.unit.usedUnits()); + if (context.strictUnits && other.unit.toString() !== unit.toString()) { + throw new Error("Incompatible units. Change the units or use the unit function. " + + ("Bad units: '" + unit.toString() + "' and '" + other.unit.toString() + "'.")); + } + value = this._operate(context, op, this.value, other.value); + } } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - - return new Dimension(value, unit); - } - }, { - key: "compare", - value: function compare(other) { - var a; - var b; - - if (!(other instanceof Dimension)) { - return undefined; - } - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - - if (a.unit.compare(b.unit) !== 0) { - return undefined; + else if (op === '*') { + unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); + unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); + unit.cancel(); } - } - - return Node.numericCompare(a.value, b.value); - } - }, { - key: "unify", - value: function unify() { - return this.convertTo({ - length: 'px', - duration: 's', - angle: 'rad' - }); - } - }, { - key: "convertTo", - value: function convertTo(conversions) { - var value = this.value; - var unit = this.unit.clone(); - var i; - var groupName; - var group; - var targetUnit; - var derivedConversions = {}; - var applyUnit; - - if (typeof conversions === 'string') { - for (i in unitConversions) { - if (unitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } + else if (op === '/') { + unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); + unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); + unit.cancel(); } - - conversions = derivedConversions; - } - - applyUnit = function applyUnit(atomicUnit, denominator) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; + return new Dimension(value, unit); + }; + Dimension.prototype.compare = function (other) { + var a; + var b; + if (!(other instanceof Dimension)) { + return undefined; + } + if (this.unit.isEmpty() || other.unit.isEmpty()) { + a = this; + b = other; + } + else { + a = this.unify(); + b = other.unify(); + if (a.unit.compare(b.unit) !== 0) { + return undefined; + } } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = unitConversions[groupName]; - unit.map(applyUnit); + return Node.numericCompare(a.value, b.value); + }; + Dimension.prototype.unify = function () { + return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); + }; + Dimension.prototype.convertTo = function (conversions) { + var value = this.value; + var unit = this.unit.clone(); + var i; + var groupName; + var group; + var targetUnit; + var derivedConversions = {}; + var applyUnit; + if (typeof conversions === 'string') { + for (i in unitConversions) { + if (unitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; } - } - - unit.cancel(); - return new Dimension(value, unit); - } - }]); - - return Dimension; -}(Node); - + applyUnit = function (atomicUnit, denominator) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit)) { + if (denominator) { + value = value / (group[atomicUnit] / group[targetUnit]); + } + else { + value = value * (group[atomicUnit] / group[targetUnit]); + } + return targetUnit; + } + return atomicUnit; + }; + for (groupName in conversions) { + if (conversions.hasOwnProperty(groupName)) { + targetUnit = conversions[groupName]; + group = unitConversions[groupName]; + unit.map(applyUnit); + } + } + unit.cancel(); + return new Dimension(value, unit); + }; + return Dimension; +}(Node)); Dimension.prototype.type = 'Dimension'; var MATH$1 = Math$1; - -var Operation = -/*#__PURE__*/ -function (_Node) { - _inherits(Operation, _Node); - - function Operation(op, operands, isSpaced) { - var _this; - - _classCallCheck(this, Operation); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Operation).call(this)); - _this.op = op.trim(); - _this.operands = operands; - _this.isSpaced = isSpaced; - return _this; - } - - _createClass(Operation, [{ - key: "accept", - value: function accept(visitor) { - this.operands = visitor.visitArray(this.operands); - } - }, { - key: "eval", - value: function _eval(context) { - var a = this.operands[0].eval(context); - var b = this.operands[1].eval(context); - var op; - - if (context.isMathOn(this.op)) { - op = this.op === './' ? '/' : this.op; - - if (a instanceof Dimension && b instanceof Color) { - a = a.toColor(); - } - - if (b instanceof Dimension && a instanceof Color) { - b = b.toColor(); +var Operation = /** @class */ (function (_super) { + tslib.__extends(Operation, _super); + function Operation(op, operands, isSpaced) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.operands = operands; + _this.isSpaced = isSpaced; + return _this; + } + Operation.prototype.accept = function (visitor) { + this.operands = visitor.visitArray(this.operands); + }; + Operation.prototype.eval = function (context) { + var a = this.operands[0].eval(context); + var b = this.operands[1].eval(context); + var op; + if (context.isMathOn(this.op)) { + op = this.op === './' ? '/' : this.op; + if (a instanceof Dimension && b instanceof Color) { + a = a.toColor(); + } + if (b instanceof Dimension && a instanceof Color) { + b = b.toColor(); + } + if (!a.operate) { + if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + return new Operation(this.op, [a, b], this.isSpaced); + } + throw { type: 'Operation', + message: 'Operation on an invalid type' }; + } + return a.operate(context, op, b); } - - if (!a.operate) { - if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + else { return new Operation(this.op, [a, b], this.isSpaced); - } - - throw { - type: 'Operation', - message: 'Operation on an invalid type' - }; } - - return a.operate(context, op, b); - } else { - return new Operation(this.op, [a, b], this.isSpaced); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.operands[0].genCSS(context, output); - - if (this.isSpaced) { - output.add(' '); - } - - output.add(this.op); - - if (this.isSpaced) { - output.add(' '); - } - - this.operands[1].genCSS(context, output); - } - }]); - - return Operation; -}(Node); - + }; + Operation.prototype.genCSS = function (context, output) { + this.operands[0].genCSS(context, output); + if (this.isSpaced) { + output.add(' '); + } + output.add(this.op); + if (this.isSpaced) { + output.add(' '); + } + this.operands[1].genCSS(context, output); + }; + return Operation; +}(Node)); Operation.prototype.type = 'Operation'; var MATH$2 = Math$1; - -var Expression = -/*#__PURE__*/ -function (_Node) { - _inherits(Expression, _Node); - - function Expression(value, noSpacing) { - var _this; - - _classCallCheck(this, Expression); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Expression).call(this)); - _this.value = value; - _this.noSpacing = noSpacing; - - if (!value) { - throw new Error('Expression requires an array parameter'); - } - - return _this; - } - - _createClass(Expression, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visitArray(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - var returnValue; - var mathOn = context.isMathOn(); - var inParenthesis = this.parens && (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); - var doubleParen = false; - - if (inParenthesis) { - context.inParenthesis(); - } - - if (this.value.length > 1) { - returnValue = new Expression(this.value.map(function (e) { - if (!e.eval) { - return e; - } - - return e.eval(context); - }), this.noSpacing); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { - doubleParen = true; +var Expression = /** @class */ (function (_super) { + tslib.__extends(Expression, _super); + function Expression(value, noSpacing) { + var _this = _super.call(this) || this; + _this.value = value; + _this.noSpacing = noSpacing; + if (!value) { + throw new Error('Expression requires an array parameter'); } - - returnValue = this.value[0].eval(context); - } else { - returnValue = this; - } - - if (inParenthesis) { - context.outOfParenthesis(); - } - - if (this.parens && this.parensInOp && !mathOn && !doubleParen && !(returnValue instanceof Dimension)) { - returnValue = new Paren(returnValue); - } - - return returnValue; + return _this; } - }, { - key: "genCSS", - value: function genCSS(context, output) { - for (var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (!this.noSpacing && i + 1 < this.value.length) { - output.add(' '); + Expression.prototype.accept = function (visitor) { + this.value = visitor.visitArray(this.value); + }; + Expression.prototype.eval = function (context) { + var returnValue; + var mathOn = context.isMathOn(); + var inParenthesis = this.parens && + (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); + var doubleParen = false; + if (inParenthesis) { + context.inParenthesis(); + } + if (this.value.length > 1) { + returnValue = new Expression(this.value.map(function (e) { + if (!e.eval) { + return e; + } + return e.eval(context); + }), this.noSpacing); } - } - } - }, { - key: "throwAwayComments", - value: function throwAwayComments() { - this.value = this.value.filter(function (v) { - return !(v instanceof Comment); - }); - } - }]); - - return Expression; -}(Node); - -Expression.prototype.type = 'Expression'; - -var functionCaller = -/*#__PURE__*/ -function () { - function functionCaller(name, context, index, currentFileInfo) { - _classCallCheck(this, functionCaller); - - this.name = name.toLowerCase(); - this.index = index; - this.context = context; - this.currentFileInfo = currentFileInfo; - this.func = context.frames[0].functionRegistry.get(this.name); - } - - _createClass(functionCaller, [{ - key: "isValid", - value: function isValid() { - return Boolean(this.func); - } - }, { - key: "call", - value: function call(args) { - // This code is terrible and should be replaced as per this issue... - // https://github.com/less/less.js/issues/2477 - if (Array.isArray(args)) { - args = args.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }).map(function (item) { - if (item.type === 'Expression') { - var subNodes = item.value.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }); - - if (subNodes.length === 1) { - return subNodes[0]; - } else { - return new Expression(subNodes); + else if (this.value.length === 1) { + if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { + doubleParen = true; } - } - - return item; - }); - } + returnValue = this.value[0].eval(context); + } + else { + returnValue = this; + } + if (inParenthesis) { + context.outOfParenthesis(); + } + if (this.parens && this.parensInOp && !mathOn && !doubleParen + && (!(returnValue instanceof Dimension))) { + returnValue = new Paren(returnValue); + } + return returnValue; + }; + Expression.prototype.genCSS = function (context, output) { + for (var i_1 = 0; i_1 < this.value.length; i_1++) { + this.value[i_1].genCSS(context, output); + if (!this.noSpacing && i_1 + 1 < this.value.length) { + output.add(' '); + } + } + }; + Expression.prototype.throwAwayComments = function () { + this.value = this.value.filter(function (v) { return !(v instanceof Comment); }); + }; + return Expression; +}(Node)); +Expression.prototype.type = 'Expression'; - return this.func.apply(this, _toConsumableArray(args)); +var functionCaller = /** @class */ (function () { + function functionCaller(name, context, index, currentFileInfo) { + this.name = name.toLowerCase(); + this.index = index; + this.context = context; + this.currentFileInfo = currentFileInfo; + this.func = context.frames[0].functionRegistry.get(this.name); } - }]); - - return functionCaller; -}(); + functionCaller.prototype.isValid = function () { + return Boolean(this.func); + }; + functionCaller.prototype.call = function (args) { + // This code is terrible and should be replaced as per this issue... + // https://github.com/less/less.js/issues/2477 + if (Array.isArray(args)) { + args = args.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }) + .map(function (item) { + if (item.type === 'Expression') { + var subNodes = item.value.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }); + if (subNodes.length === 1) { + return subNodes[0]; + } + else { + return new Expression(subNodes); + } + } + return item; + }); + } + return this.func.apply(this, args); + }; + return functionCaller; +}()); +// // A function call node. // - -var Call = -/*#__PURE__*/ -function (_Node) { - _inherits(Call, _Node); - - function Call(name, args, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Call); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Call).call(this)); - _this.name = name; - _this.args = args; - _this.calc = name === 'calc'; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Call, [{ - key: "accept", - value: function accept(visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - } // +var Call = /** @class */ (function (_super) { + tslib.__extends(Call, _super); + function Call(name, args, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this.args = args; + _this.calc = name === 'calc'; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Call.prototype.accept = function (visitor) { + if (this.args) { + this.args = visitor.visitArray(this.args); + } + }; + // // When evaluating a function call, // we either find the function in the functionRegistry, // in which case we call it, passing the evaluated arguments, @@ -4353,645 +3266,466 @@ function (_Node) { // we try to pass a variable to a function, like: `saturate(@color)`. // The function should receive the value, not the variable. // - - }, { - key: "eval", - value: function _eval(context) { - /** - * Turn off math for calc(), and switch back on for evaluating nested functions - */ - var currentMathContext = context.mathOn; - context.mathOn = !this.calc; - - if (this.calc || context.inCalc) { - context.enterCalc(); - } - - var args = this.args.map(function (a) { - return a.eval(context); - }); - - if (this.calc || context.inCalc) { - context.exitCalc(); - } - - context.mathOn = currentMathContext; - var result; - var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); - - if (funcCaller.isValid()) { - try { - result = funcCaller.call(args); - } catch (e) { - throw { - type: e.type || 'Runtime', - message: `error evaluating function \`${this.name}\`${e.message ? `: ${e.message}` : ''}`, - index: this.getIndex(), - filename: this.fileInfo().filename, - line: e.lineNumber, - column: e.columnNumber - }; + Call.prototype.eval = function (context) { + /** + * Turn off math for calc(), and switch back on for evaluating nested functions + */ + var currentMathContext = context.mathOn; + context.mathOn = !this.calc; + if (this.calc || context.inCalc) { + context.enterCalc(); } - - if (result !== null && result !== undefined) { - // Results that that are not nodes are cast as Anonymous nodes - // Falsy values or booleans are returned as empty nodes - if (!(result instanceof Node)) { - if (!result || result === true) { - result = new Anonymous(null); - } else { - result = new Anonymous(result.toString()); - } - } - - result._index = this._index; - result._fileInfo = this._fileInfo; - return result; + var args = this.args.map(function (a) { return a.eval(context); }); + if (this.calc || context.inCalc) { + context.exitCalc(); } - } - - return new Call(this.name, args, this.getIndex(), this.fileInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(`${this.name}(`, this.fileInfo(), this.getIndex()); - - for (var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(context, output); - - if (i + 1 < this.args.length) { - output.add(', '); + context.mathOn = currentMathContext; + var result; + var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); + if (funcCaller.isValid()) { + try { + result = funcCaller.call(args); + } + catch (e) { + throw { + type: e.type || 'Runtime', + message: "error evaluating function `" + this.name + "`" + (e.message ? ": " + e.message : ''), + index: this.getIndex(), + filename: this.fileInfo().filename, + line: e.lineNumber, + column: e.columnNumber + }; + } + if (result !== null && result !== undefined) { + // Results that that are not nodes are cast as Anonymous nodes + // Falsy values or booleans are returned as empty nodes + if (!(result instanceof Node)) { + if (!result || result === true) { + result = new Anonymous(null); + } + else { + result = new Anonymous(result.toString()); + } + } + result._index = this._index; + result._fileInfo = this._fileInfo; + return result; + } } - } - - output.add(')'); - } - }]); - - return Call; -}(Node); - + return new Call(this.name, args, this.getIndex(), this.fileInfo()); + }; + Call.prototype.genCSS = function (context, output) { + output.add(this.name + "(", this.fileInfo(), this.getIndex()); + for (var i_1 = 0; i_1 < this.args.length; i_1++) { + this.args[i_1].genCSS(context, output); + if (i_1 + 1 < this.args.length) { + output.add(', '); + } + } + output.add(')'); + }; + return Call; +}(Node)); Call.prototype.type = 'Call'; -var Variable = -/*#__PURE__*/ -function (_Node) { - _inherits(Variable, _Node); - - function Variable(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Variable); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Variable).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Variable, [{ - key: "eval", - value: function _eval(context) { - var variable; - var name = this.name; - - if (name.indexOf('@@') === 0) { - name = `@${new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value}`; - } - - if (this.evaluating) { - throw { - type: 'Name', - message: `Recursive variable definition for ${name}`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - variable = this.find(context.frames, function (frame) { - var v = frame.variable(name); - - if (v) { - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } // If in calc, wrap vars in a function call to cascade evaluate args first - - - if (context.inCalc) { - return new Call('_SELF', [v.value]).eval(context); - } else { - return v.value.eval(context); - } +var Variable = /** @class */ (function (_super) { + tslib.__extends(Variable, _super); + function Variable(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Variable.prototype.eval = function (context) { + var variable; + var name = this.name; + if (name.indexOf('@@') === 0) { + name = "@" + new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value; + } + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive variable definition for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + variable = this.find(context.frames, function (frame) { + var v = frame.variable(name); + if (v) { + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + // If in calc, wrap vars in a function call to cascade evaluate args first + if (context.inCalc) { + return (new Call('_SELF', [v.value])).eval(context); + } + else { + return v.value.eval(context); + } + } + }); + if (variable) { + this.evaluating = false; + return variable; } - }); - - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { - type: 'Name', - message: `variable ${name} is undefined`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "variable " + name + " is undefined", + filename: this.fileInfo().filename, + index: this.getIndex() }; } - } - - return null; - } - }]); - - return Variable; -}(Node); - + }; + Variable.prototype.find = function (obj, fun) { + for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) { + r = fun.call(obj, obj[i_1]); + if (r) { + return r; + } + } + return null; + }; + return Variable; +}(Node)); Variable.prototype.type = 'Variable'; -var Property = -/*#__PURE__*/ -function (_Node) { - _inherits(Property, _Node); - - function Property(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Property); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Property).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Property, [{ - key: "eval", - value: function _eval(context) { - var property; - var name = this.name; // TODO: shorten this reference - - var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; - - if (this.evaluating) { - throw { - type: 'Name', - message: `Recursive property reference for ${name}`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - property = this.find(context.frames, function (frame) { - var v; - var vArr = frame.property(name); - - if (vArr) { - for (var i = 0; i < vArr.length; i++) { - v = vArr[i]; - vArr[i] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); - } - - mergeRules(vArr); - v = vArr[vArr.length - 1]; - - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } - - v = v.value.eval(context); - return v; +var Property = /** @class */ (function (_super) { + tslib.__extends(Property, _super); + function Property(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Property.prototype.eval = function (context) { + var property; + var name = this.name; + // TODO: shorten this reference + var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive property reference for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + property = this.find(context.frames, function (frame) { + var v; + var vArr = frame.property(name); + if (vArr) { + for (var i_1 = 0; i_1 < vArr.length; i_1++) { + v = vArr[i_1]; + vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); + } + mergeRules(vArr); + v = vArr[vArr.length - 1]; + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + v = v.value.eval(context); + return v; + } + }); + if (property) { + this.evaluating = false; + return property; } - }); - - if (property) { - this.evaluating = false; - return property; - } else { - throw { - type: 'Name', - message: `Property '${name}' is undefined`, - filename: this.currentFileInfo.filename, - index: this.index - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "Property '" + name + "' is undefined", + filename: this.currentFileInfo.filename, + index: this.index }; } - } - - return null; - } - }]); - - return Property; -}(Node); - + }; + Property.prototype.find = function (obj, fun) { + for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) { + r = fun.call(obj, obj[i_2]); + if (r) { + return r; + } + } + return null; + }; + return Property; +}(Node)); Property.prototype.type = 'Property'; -var Attribute = -/*#__PURE__*/ -function (_Node) { - _inherits(Attribute, _Node); - - function Attribute(key, op, value) { - var _this; - - _classCallCheck(this, Attribute); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Attribute).call(this)); - _this.key = key; - _this.op = op; - _this.value = value; - return _this; - } - - _createClass(Attribute, [{ - key: "eval", - value: function _eval(context) { - return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, this.value && this.value.eval ? this.value.eval(context) : this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context) { - var value = this.key.toCSS ? this.key.toCSS(context) : this.key; - - if (this.op) { - value += this.op; - value += this.value.toCSS ? this.value.toCSS(context) : this.value; - } - - return `[${value}]`; - } - }]); - - return Attribute; -}(Node); - +var Attribute = /** @class */ (function (_super) { + tslib.__extends(Attribute, _super); + function Attribute(key, op, value) { + var _this = _super.call(this) || this; + _this.key = key; + _this.op = op; + _this.value = value; + return _this; + } + Attribute.prototype.eval = function (context) { + return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value); + }; + Attribute.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Attribute.prototype.toCSS = function (context) { + var value = this.key.toCSS ? this.key.toCSS(context) : this.key; + if (this.op) { + value += this.op; + value += (this.value.toCSS ? this.value.toCSS(context) : this.value); + } + return "[" + value + "]"; + }; + return Attribute; +}(Node)); Attribute.prototype.type = 'Attribute'; -var Quoted = -/*#__PURE__*/ -function (_Node) { - _inherits(Quoted, _Node); - - function Quoted(str, content, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Quoted); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Quoted).call(this)); - _this.escaped = escaped == null ? true : escaped; - _this.value = content || ''; - _this.quote = str.charAt(0); - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.variableRegex = /@\{([\w-]+)\}/g; - _this.propRegex = /\$\{([\w-]+)\}/g; - _this.allowRoot = escaped; - return _this; - } - - _createClass(Quoted, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (!this.escaped) { - output.add(this.quote, this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - - if (!this.escaped) { - output.add(this.quote); - } - } - }, { - key: "containsVariables", - value: function containsVariables() { - return this.value.match(this.variableRegex); - } - }, { - key: "eval", - value: function _eval(context) { - var that = this; - var value = this.value; - - var variableReplacement = function variableReplacement(_, name) { - var v = new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - var propertyReplacement = function propertyReplacement(_, name) { - var v = new Property(`$${name}`, that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - function iterativeReplace(value, regexp, replacementFnc) { - var evaluatedValue = value; - - do { - value = evaluatedValue.toString(); - evaluatedValue = value.replace(regexp, replacementFnc); - } while (value !== evaluatedValue); - - return evaluatedValue; - } - - value = iterativeReplace(value, this.variableRegex, variableReplacement); - value = iterativeReplace(value, this.propRegex, propertyReplacement); - return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); - } - }, { - key: "compare", - value: function compare(other) { - // when comparing quoted strings allow the quote to differ - if (other.type === 'Quoted' && !this.escaped && !other.escaped) { - return Node.numericCompare(this.value, other.value); - } else { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - } - }]); - - return Quoted; -}(Node); - +var Quoted = /** @class */ (function (_super) { + tslib.__extends(Quoted, _super); + function Quoted(str, content, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = (escaped == null) ? true : escaped; + _this.value = content || ''; + _this.quote = str.charAt(0); + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.variableRegex = /@\{([\w-]+)\}/g; + _this.propRegex = /\$\{([\w-]+)\}/g; + _this.allowRoot = escaped; + return _this; + } + Quoted.prototype.genCSS = function (context, output) { + if (!this.escaped) { + output.add(this.quote, this.fileInfo(), this.getIndex()); + } + output.add(this.value); + if (!this.escaped) { + output.add(this.quote); + } + }; + Quoted.prototype.containsVariables = function () { + return this.value.match(this.variableRegex); + }; + Quoted.prototype.eval = function (context) { + var that = this; + var value = this.value; + var variableReplacement = function (_, name) { + var v = new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + var propertyReplacement = function (_, name) { + var v = new Property("$" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + function iterativeReplace(value, regexp, replacementFnc) { + var evaluatedValue = value; + do { + value = evaluatedValue.toString(); + evaluatedValue = value.replace(regexp, replacementFnc); + } while (value !== evaluatedValue); + return evaluatedValue; + } + value = iterativeReplace(value, this.variableRegex, variableReplacement); + value = iterativeReplace(value, this.propRegex, propertyReplacement); + return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); + }; + Quoted.prototype.compare = function (other) { + // when comparing quoted strings allow the quote to differ + if (other.type === 'Quoted' && !this.escaped && !other.escaped) { + return Node.numericCompare(this.value, other.value); + } + else { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + } + }; + return Quoted; +}(Node)); Quoted.prototype.type = 'Quoted'; -var URL = -/*#__PURE__*/ -function (_Node) { - _inherits(URL, _Node); - - function URL(val, index, currentFileInfo, isEvald) { - var _this; - - _classCallCheck(this, URL); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(URL).call(this)); - _this.value = val; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.isEvald = isEvald; - return _this; - } - - _createClass(URL, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('url('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - var val = this.value.eval(context); - var rootpath; - - if (!this.isEvald) { - // Add the rootpath if the URL requires a rewrite - rootpath = this.fileInfo() && this.fileInfo().rootpath; - - if (typeof rootpath === 'string' && typeof val.value === 'string' && context.pathRequiresRewrite(val.value)) { - if (!val.quote) { - rootpath = escapePath(rootpath); - } - - val.value = context.rewritePath(val.value, rootpath); - } else { - val.value = context.normalizePath(val.value); - } // Add url args if enabled - - - if (context.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + context.urlArgs; - - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', `${urlArgs}#`); - } else { - val.value += urlArgs; +var URL = /** @class */ (function (_super) { + tslib.__extends(URL, _super); + function URL(val, index, currentFileInfo, isEvald) { + var _this = _super.call(this) || this; + _this.value = val; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.isEvald = isEvald; + return _this; + } + URL.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + URL.prototype.genCSS = function (context, output) { + output.add('url('); + this.value.genCSS(context, output); + output.add(')'); + }; + URL.prototype.eval = function (context) { + var val = this.value.eval(context); + var rootpath; + if (!this.isEvald) { + // Add the rootpath if the URL requires a rewrite + rootpath = this.fileInfo() && this.fileInfo().rootpath; + if (typeof rootpath === 'string' && + typeof val.value === 'string' && + context.pathRequiresRewrite(val.value)) { + if (!val.quote) { + rootpath = escapePath(rootpath); + } + val.value = context.rewritePath(val.value, rootpath); + } + else { + val.value = context.normalizePath(val.value); + } + // Add url args if enabled + if (context.urlArgs) { + if (!val.value.match(/^\s*data:/)) { + var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; + var urlArgs = delimiter + context.urlArgs; + if (val.value.indexOf('#') !== -1) { + val.value = val.value.replace('#', urlArgs + "#"); + } + else { + val.value += urlArgs; + } + } } - } } - } - - return new URL(val, this.getIndex(), this.fileInfo(), true); - } - }]); - - return URL; -}(Node); - + return new URL(val, this.getIndex(), this.fileInfo(), true); + }; + return URL; +}(Node)); URL.prototype.type = 'Url'; - function escapePath(path) { - return path.replace(/[\(\)'"\s]/g, function (match) { - return `\\${match}`; - }); + return path.replace(/[\(\)'"\s]/g, function (match) { return "\\" + match; }); } -var Media = -/*#__PURE__*/ -function (_AtRule) { - _inherits(Media, _AtRule); - - function Media(value, features, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Media); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Media).call(this)); - _this._index = index; - _this._fileInfo = currentFileInfo; - var selectors = new Selector([], null, null, _this._index, _this._fileInfo).createEmptySelectors(); - _this.features = new Value(features); - _this.rules = [new Ruleset(selectors, value)]; - _this.rules[0].allowImports = true; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Media, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('@media ', this._fileInfo, this._index); - this.features.genCSS(context, output); - this.outputRuleset(context, output, this.rules); - } - }, { - key: "eval", - value: function _eval(context) { - if (!context.mediaBlocks) { - context.mediaBlocks = []; - context.mediaPath = []; - } - - var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); - - if (this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - - media.features = this.features.eval(context); - context.mediaPath.push(media); - context.mediaBlocks.push(media); - this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); - context.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(context)]; - context.frames.shift(); - context.mediaPath.pop(); - return context.mediaPath.length === 0 ? media.evalTop(context) : media.evalNested(context); - } - }, { - key: "evalTop", - value: function evalTop(context) { - var result = this; // Render all dependent Media blocks. - - if (context.mediaBlocks.length > 1) { - var selectors = new Selector([], null, null, this.getIndex(), this.fileInfo()).createEmptySelectors(); - result = new Ruleset(selectors, context.mediaBlocks); - result.multiMedia = true; - result.copyVisibilityInfo(this.visibilityInfo()); - this.setParent(result, this); - } - - delete context.mediaBlocks; - delete context.mediaPath; - return result; - } - }, { - key: "evalNested", - value: function evalNested(context) { - var i; - var value; - var path = context.mediaPath.concat([this]); // Extract the media-query conditions separated with `,` (OR). - - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof Value ? path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - - - this.features = new Value(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new Anonymous(fragment); - }); - - for (i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new Anonymous('and')); +var Media = /** @class */ (function (_super) { + tslib.__extends(Media, _super); + function Media(value, features, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this._index = index; + _this._fileInfo = currentFileInfo; + var selectors = (new Selector([], null, null, _this._index, _this._fileInfo)).createEmptySelectors(); + _this.features = new Value(features); + _this.rules = [new Ruleset(selectors, value)]; + _this.rules[0].allowImports = true; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(selectors, _this); + _this.setParent(_this.features, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Media.prototype.isRulesetLike = function () { + return true; + }; + Media.prototype.accept = function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); } - - return new Expression(path); - })); - this.setParent(this.features, this); // Fake a tree-node that doesn't output anything. - - return new Ruleset([], []); - } - }, { - key: "permute", - value: function permute(arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } + if (this.rules) { + this.rules = visitor.visitArray(this.rules); } - + }; + Media.prototype.genCSS = function (context, output) { + output.add('@media ', this._fileInfo, this._index); + this.features.genCSS(context, output); + this.outputRuleset(context, output, this.rules); + }; + Media.prototype.eval = function (context) { + if (!context.mediaBlocks) { + context.mediaBlocks = []; + context.mediaPath = []; + } + var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); + if (this.debugInfo) { + this.rules[0].debugInfo = this.debugInfo; + media.debugInfo = this.debugInfo; + } + media.features = this.features.eval(context); + context.mediaPath.push(media); + context.mediaBlocks.push(media); + this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); + context.frames.unshift(this.rules[0]); + media.rules = [this.rules[0].eval(context)]; + context.frames.shift(); + context.mediaPath.pop(); + return context.mediaPath.length === 0 ? media.evalTop(context) : + media.evalNested(context); + }; + Media.prototype.evalTop = function (context) { + var result = this; + // Render all dependent Media blocks. + if (context.mediaBlocks.length > 1) { + var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors(); + result = new Ruleset(selectors, context.mediaBlocks); + result.multiMedia = true; + result.copyVisibilityInfo(this.visibilityInfo()); + this.setParent(result, this); + } + delete context.mediaBlocks; + delete context.mediaPath; return result; - } - } - }, { - key: "bubbleSelectors", - value: function bubbleSelectors(selectors) { - if (!selectors) { - return; - } - - this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; - this.setParent(this.rules, this); - } - }]); - - return Media; -}(AtRule); - + }; + Media.prototype.evalNested = function (context) { + var i; + var value; + var path = context.mediaPath.concat([this]); + // Extract the media-query conditions separated with `,` (OR). + for (i = 0; i < path.length; i++) { + value = path[i].features instanceof Value ? + path[i].features.value : path[i].features; + path[i] = Array.isArray(value) ? value : [value]; + } + // Trace all permutations to generate the resulting media-query. + // + // (a, b and c) with nested (d, e) -> + // a and d + // a and e + // b and c and d + // b and c and e + this.features = new Value(this.permute(path).map(function (path) { + path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); }); + for (i = path.length - 1; i > 0; i--) { + path.splice(i, 0, new Anonymous('and')); + } + return new Expression(path); + })); + this.setParent(this.features, this); + // Fake a tree-node that doesn't output anything. + return new Ruleset([], []); + }; + Media.prototype.permute = function (arr) { + if (arr.length === 0) { + return []; + } + else if (arr.length === 1) { + return arr[0]; + } + else { + var result = []; + var rest = this.permute(arr.slice(1)); + for (var i_1 = 0; i_1 < rest.length; i_1++) { + for (var j = 0; j < arr[0].length; j++) { + result.push([arr[0][j]].concat(rest[i_1])); + } + } + return result; + } + }; + Media.prototype.bubbleSelectors = function (selectors) { + if (!selectors) { + return; + } + this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; + this.setParent(this.rules, this); + }; + return Media; +}(AtRule)); Media.prototype.type = 'Media'; +// // CSS @import node // // The general strategy here is that we don't want to wait @@ -5003,3738 +3737,2854 @@ Media.prototype.type = 'Media'; // `import,push`, we also pass it a callback, which it'll call once // the file has been fetched, and parsed. // - -var Import = -/*#__PURE__*/ -function (_Node) { - _inherits(Import, _Node); - - function Import(path, features, options, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Import); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Import).call(this)); - _this.options = options; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.path = path; - _this.features = features; - _this.allowRoot = true; - - if (_this.options.less !== undefined || _this.options.inline) { - _this.css = !_this.options.less || _this.options.inline; - } else { - var pathValue = _this.getPath(); - - if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { - _this.css = true; - } +var Import = /** @class */ (function (_super) { + tslib.__extends(Import, _super); + function Import(path, features, options, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.options = options; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.path = path; + _this.features = features; + _this.allowRoot = true; + if (_this.options.less !== undefined || _this.options.inline) { + _this.css = !_this.options.less || _this.options.inline; + } + else { + var pathValue = _this.getPath(); + if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { + _this.css = true; + } + } + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.features, _this); + _this.setParent(_this.path, _this); + return _this; } - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.path, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Import, [{ - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - this.path = visitor.visit(this.path); - - if (!this.options.isPlugin && !this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (this.css && this.path._fileInfo.reference === undefined) { - output.add('@import ', this._fileInfo, this._index); - this.path.genCSS(context, output); - + Import.prototype.accept = function (visitor) { if (this.features) { - output.add(' '); - this.features.genCSS(context, output); + this.features = visitor.visit(this.features); } - - output.add(';'); - } - } - }, { - key: "getPath", - value: function getPath() { - return this.path instanceof URL ? this.path.value.value : this.path.value; - } - }, { - key: "isVariableImport", - value: function isVariableImport() { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - if (path instanceof Quoted) { - return path.containsVariables(); - } - - return true; - } - }, { - key: "evalForImport", - value: function evalForImport(context) { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); - } - }, { - key: "evalPath", - value: function evalPath(context) { - var path = this.path.eval(context); - var fileInfo = this._fileInfo; - - if (!(path instanceof URL)) { - // Add the rootpath if the URL requires a rewrite - var pathValue = path.value; - - if (fileInfo && pathValue && context.pathRequiresRewrite(pathValue)) { - path.value = context.rewritePath(pathValue, fileInfo.rootpath); - } else { - path.value = context.normalizePath(path.value); + this.path = visitor.visit(this.path); + if (!this.options.isPlugin && !this.options.inline && this.root) { + this.root = visitor.visit(this.root); } - } - - return path; - } - }, { - key: "eval", - value: function _eval(context) { - var result = this.doEval(context); - - if (this.options.reference || this.blocksVisibility()) { - if (result.length || result.length === 0) { - result.forEach(function (node) { - node.addVisibilityBlock(); - }); - } else { - result.addVisibilityBlock(); - } - } - - return result; - } - }, { - key: "doEval", - value: function doEval(context) { - var ruleset; - var registry; - var features = this.features && this.features.eval(context); - - if (this.options.isPlugin) { - if (this.root && this.root.eval) { - try { - this.root.eval(context); - } catch (e) { - e.message = 'Plugin error during evaluation'; - throw new LessError(e, this.root.imports, this.root.filename); - } + }; + Import.prototype.genCSS = function (context, output) { + if (this.css && this.path._fileInfo.reference === undefined) { + output.add('@import ', this._fileInfo, this._index); + this.path.genCSS(context, output); + if (this.features) { + output.add(' '); + this.features.genCSS(context, output); + } + output.add(';'); } - - registry = context.frames[0] && context.frames[0].functionRegistry; - - if (registry && this.root && this.root.functions) { - registry.addMultiple(this.root.functions); + }; + Import.prototype.getPath = function () { + return (this.path instanceof URL) ? + this.path.value.value : this.path.value; + }; + Import.prototype.isVariableImport = function () { + var path = this.path; + if (path instanceof URL) { + path = path.value; } - - return []; - } - - if (this.skip) { - if (typeof this.skip === 'function') { - this.skip = this.skip(); + if (path instanceof Quoted) { + return path.containsVariables(); + } + return true; + }; + Import.prototype.evalForImport = function (context) { + var path = this.path; + if (path instanceof URL) { + path = path.value; + } + return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); + }; + Import.prototype.evalPath = function (context) { + var path = this.path.eval(context); + var fileInfo = this._fileInfo; + if (!(path instanceof URL)) { + // Add the rootpath if the URL requires a rewrite + var pathValue = path.value; + if (fileInfo && + pathValue && + context.pathRequiresRewrite(pathValue)) { + path.value = context.rewritePath(pathValue, fileInfo.rootpath); + } + else { + path.value = context.normalizePath(path.value); + } + } + return path; + }; + Import.prototype.eval = function (context) { + var result = this.doEval(context); + if (this.options.reference || this.blocksVisibility()) { + if (result.length || result.length === 0) { + result.forEach(function (node) { + node.addVisibilityBlock(); + }); + } + else { + result.addVisibilityBlock(); + } + } + return result; + }; + Import.prototype.doEval = function (context) { + var ruleset; + var registry; + var features = this.features && this.features.eval(context); + if (this.options.isPlugin) { + if (this.root && this.root.eval) { + try { + this.root.eval(context); + } + catch (e) { + e.message = 'Plugin error during evaluation'; + throw new LessError(e, this.root.imports, this.root.filename); + } + } + registry = context.frames[0] && context.frames[0].functionRegistry; + if (registry && this.root && this.root.functions) { + registry.addMultiple(this.root.functions); + } + return []; } - if (this.skip) { - return []; + if (typeof this.skip === 'function') { + this.skip = this.skip(); + } + if (this.skip) { + return []; + } } - } - - if (this.options.inline) { - var contents = new Anonymous(this.root, 0, { - filename: this.importedFilename, - reference: this.path._fileInfo && this.path._fileInfo.reference - }, true, true); - return this.features ? new Media([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new Import(this.evalPath(context), features, this.options, this._index); - - if (!newImport.css && this.error) { - throw this.error; + if (this.options.inline) { + var contents = new Anonymous(this.root, 0, { + filename: this.importedFilename, + reference: this.path._fileInfo && this.path._fileInfo.reference + }, true, true); + return this.features ? new Media([contents], this.features.value) : [contents]; + } + else if (this.css) { + var newImport = new Import(this.evalPath(context), features, this.options, this._index); + if (!newImport.css && this.error) { + throw this.error; + } + return newImport; } - - return newImport; - } else { - ruleset = new Ruleset(null, copyArray(this.root.rules)); - ruleset.evalImports(context); - return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; - } - } - }]); - - return Import; -}(Node); - + else { + ruleset = new Ruleset(null, copyArray(this.root.rules)); + ruleset.evalImports(context); + return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; + } + }; + return Import; +}(Node)); Import.prototype.type = 'Import'; -var JsEvalNode = -/*#__PURE__*/ -function (_Node) { - _inherits(JsEvalNode, _Node); - - function JsEvalNode() { - _classCallCheck(this, JsEvalNode); - - return _possibleConstructorReturn(this, _getPrototypeOf(JsEvalNode).apply(this, arguments)); - } - - _createClass(JsEvalNode, [{ - key: "evaluateJavaScript", - value: function evaluateJavaScript(expression, context) { - var result; - var that = this; - var evalContext = {}; - - if (!context.javascriptEnabled) { - throw { - message: 'Inline JavaScript is not enabled. Is it set in your options?', - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return that.jsify(new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context)); - }); - - try { - expression = new Function(`return (${expression})`); - } catch (e) { - throw { - message: `JavaScript evaluation error: ${e.message} from \`${expression}\``, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - var variables = context.frames[0].variables(); - - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /* jshint loopfunc:true */ - evalContext[k.slice(1)] = { - value: variables[k].value, - toJS: function toJS() { - return this.value.eval(context).toCSS(); +var JsEvalNode = /** @class */ (function (_super) { + tslib.__extends(JsEvalNode, _super); + function JsEvalNode() { + return _super !== null && _super.apply(this, arguments) || this; + } + JsEvalNode.prototype.evaluateJavaScript = function (expression, context) { + var result; + var that = this; + var evalContext = {}; + if (!context.javascriptEnabled) { + throw { message: 'Inline JavaScript is not enabled. Is it set in your options?', + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { return that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context)); }); + try { + expression = new Function("return (" + expression + ")"); + } + catch (e) { + throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + var variables = context.frames[0].variables(); + for (var k in variables) { + if (variables.hasOwnProperty(k)) { + /* jshint loopfunc:true */ + evalContext[k.slice(1)] = { + value: variables[k].value, + toJS: function () { + return this.value.eval(context).toCSS(); + } + }; } - }; } - } - - try { - result = expression.call(evalContext); - } catch (e) { - throw { - message: `JavaScript evaluation error: '${e.name}: ${e.message.replace(/["]/g, '\'')}'`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - return result; - } - }, { - key: "jsify", - value: function jsify(obj) { - if (Array.isArray(obj.value) && obj.value.length > 1) { - return `[${obj.value.map(function (v) { - return v.toCSS(); - }).join(', ')}]`; - } else { - return obj.toCSS(); - } - } - }]); - - return JsEvalNode; -}(Node); - -var JavaScript = -/*#__PURE__*/ -function (_JsEvalNode) { - _inherits(JavaScript, _JsEvalNode); - - function JavaScript(string, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, JavaScript); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(JavaScript).call(this)); - _this.escaped = escaped; - _this.expression = string; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(JavaScript, [{ - key: "eval", - value: function _eval(context) { - var result = this.evaluateJavaScript(this.expression, context); - var type = typeof result; - - if (type === 'number' && !isNaN(result)) { - return new Dimension(result); - } else if (type === 'string') { - return new Quoted(`"${result}"`, result, this.escaped, this._index); - } else if (Array.isArray(result)) { - return new Anonymous(result.join(', ')); - } else { - return new Anonymous(result); - } - } - }]); - - return JavaScript; -}(JsEvalNode); - + try { + result = expression.call(evalContext); + } + catch (e) { + throw { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + return result; + }; + JsEvalNode.prototype.jsify = function (obj) { + if (Array.isArray(obj.value) && (obj.value.length > 1)) { + return "[" + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + "]"; + } + else { + return obj.toCSS(); + } + }; + return JsEvalNode; +}(Node)); + +var JavaScript = /** @class */ (function (_super) { + tslib.__extends(JavaScript, _super); + function JavaScript(string, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = escaped; + _this.expression = string; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + JavaScript.prototype.eval = function (context) { + var result = this.evaluateJavaScript(this.expression, context); + var type = typeof result; + if (type === 'number' && !isNaN(result)) { + return new Dimension(result); + } + else if (type === 'string') { + return new Quoted("\"" + result + "\"", result, this.escaped, this._index); + } + else if (Array.isArray(result)) { + return new Anonymous(result.join(', ')); + } + else { + return new Anonymous(result); + } + }; + return JavaScript; +}(JsEvalNode)); JavaScript.prototype.type = 'JavaScript'; -var Assignment = -/*#__PURE__*/ -function (_Node) { - _inherits(Assignment, _Node); - - function Assignment(key, val) { - var _this; - - _classCallCheck(this, Assignment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Assignment).call(this)); - _this.key = key; - _this.value = val; - return _this; - } - - _createClass(Assignment, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.eval) { - return new Assignment(this.key, this.value.eval(context)); - } - - return this; +var Assignment = /** @class */ (function (_super) { + tslib.__extends(Assignment, _super); + function Assignment(key, val) { + var _this = _super.call(this) || this; + _this.key = key; + _this.value = val; + return _this; } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(`${this.key}=`); - - if (this.value.genCSS) { - this.value.genCSS(context, output); - } else { - output.add(this.value); - } - } - }]); - - return Assignment; -}(Node); - + Assignment.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Assignment.prototype.eval = function (context) { + if (this.value.eval) { + return new Assignment(this.key, this.value.eval(context)); + } + return this; + }; + Assignment.prototype.genCSS = function (context, output) { + output.add(this.key + "="); + if (this.value.genCSS) { + this.value.genCSS(context, output); + } + else { + output.add(this.value); + } + }; + return Assignment; +}(Node)); Assignment.prototype.type = 'Assignment'; -var Condition = -/*#__PURE__*/ -function (_Node) { - _inherits(Condition, _Node); - - function Condition(op, l, r, i, negate) { - var _this; - - _classCallCheck(this, Condition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Condition).call(this)); - _this.op = op.trim(); - _this.lvalue = l; - _this.rvalue = r; - _this._index = i; - _this.negate = negate; - return _this; - } - - _createClass(Condition, [{ - key: "accept", - value: function accept(visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - } - }, { - key: "eval", - value: function _eval(context) { - var result = function (op, a, b) { - switch (op) { - case 'and': - return a && b; - - case 'or': - return a || b; - - default: - switch (Node.compare(a, b)) { - case -1: - return op === '<' || op === '=<' || op === '<='; - - case 0: - return op === '=' || op === '>=' || op === '=<' || op === '<='; - - case 1: - return op === '>' || op === '>='; - - default: - return false; +var Condition = /** @class */ (function (_super) { + tslib.__extends(Condition, _super); + function Condition(op, l, r, i, negate) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.lvalue = l; + _this.rvalue = r; + _this._index = i; + _this.negate = negate; + return _this; + } + Condition.prototype.accept = function (visitor) { + this.lvalue = visitor.visit(this.lvalue); + this.rvalue = visitor.visit(this.rvalue); + }; + Condition.prototype.eval = function (context) { + var result = (function (op, a, b) { + switch (op) { + case 'and': return a && b; + case 'or': return a || b; + default: + switch (Node.compare(a, b)) { + case -1: + return op === '<' || op === '=<' || op === '<='; + case 0: + return op === '=' || op === '>=' || op === '=<' || op === '<='; + case 1: + return op === '>' || op === '>='; + default: + return false; + } } - - } - }(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); - - return this.negate ? !result : result; - } - }]); - - return Condition; -}(Node); - + })(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); + return this.negate ? !result : result; + }; + return Condition; +}(Node)); Condition.prototype.type = 'Condition'; -var UnicodeDescriptor = -/*#__PURE__*/ -function (_Node) { - _inherits(UnicodeDescriptor, _Node); - - function UnicodeDescriptor(value) { - var _this; - - _classCallCheck(this, UnicodeDescriptor); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(UnicodeDescriptor).call(this)); - _this.value = value; - return _this; - } - - return UnicodeDescriptor; -}(Node); - +var UnicodeDescriptor = /** @class */ (function (_super) { + tslib.__extends(UnicodeDescriptor, _super); + function UnicodeDescriptor(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; + } + return UnicodeDescriptor; +}(Node)); UnicodeDescriptor.prototype.type = 'UnicodeDescriptor'; -var Negative = -/*#__PURE__*/ -function (_Node) { - _inherits(Negative, _Node); - - function Negative(node) { - var _this; - - _classCallCheck(this, Negative); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Negative).call(this)); - _this.value = node; - return _this; - } - - _createClass(Negative, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('-'); - this.value.genCSS(context, output); - } - }, { - key: "eval", - value: function _eval(context) { - if (context.isMathOn()) { - return new Operation('*', [new Dimension(-1), this.value]).eval(context); - } - - return new Negative(this.value.eval(context)); +var Negative = /** @class */ (function (_super) { + tslib.__extends(Negative, _super); + function Negative(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; } - }]); - - return Negative; -}(Node); - + Negative.prototype.genCSS = function (context, output) { + output.add('-'); + this.value.genCSS(context, output); + }; + Negative.prototype.eval = function (context) { + if (context.isMathOn()) { + return (new Operation('*', [new Dimension(-1), this.value])).eval(context); + } + return new Negative(this.value.eval(context)); + }; + return Negative; +}(Node)); Negative.prototype.type = 'Negative'; -var Extend = -/*#__PURE__*/ -function (_Node) { - _inherits(Extend, _Node); - - function Extend(selector, option, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Extend); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Extend).call(this)); - _this.selector = selector; - _this.option = option; - _this.object_id = Extend.next_id++; - _this.parent_ids = [_this.object_id]; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - switch (option) { - case 'all': - _this.allowBefore = true; - _this.allowAfter = true; - break; - - default: - _this.allowBefore = false; - _this.allowAfter = false; - break; - } - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Extend, [{ - key: "accept", - value: function accept(visitor) { - this.selector = visitor.visit(this.selector); - } - }, { - key: "eval", - value: function _eval(context) { - return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone(context) { - return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } // it concatenates (joins) all selectors in selector array - - }, { - key: "findSelfSelectors", - value: function findSelfSelectors(selectors) { - var selfElements = []; - var i; - var selectorElements; - - for (i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { - selectorElements[0].combinator.value = ' '; +var Extend = /** @class */ (function (_super) { + tslib.__extends(Extend, _super); + function Extend(selector, option, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selector = selector; + _this.option = option; + _this.object_id = Extend.next_id++; + _this.parent_ids = [_this.object_id]; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + switch (option) { + case 'all': + _this.allowBefore = true; + _this.allowAfter = true; + break; + default: + _this.allowBefore = false; + _this.allowAfter = false; + break; } - - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [new Selector(selfElements)]; - this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + _this.setParent(_this.selector, _this); + return _this; } - }]); - - return Extend; -}(Node); - + Extend.prototype.accept = function (visitor) { + this.selector = visitor.visit(this.selector); + }; + Extend.prototype.eval = function (context) { + return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Extend.prototype.clone = function (context) { + return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + // it concatenates (joins) all selectors in selector array + Extend.prototype.findSelfSelectors = function (selectors) { + var selfElements = []; + var i; + var selectorElements; + for (i = 0; i < selectors.length; i++) { + selectorElements = selectors[i].elements; + // duplicate the logic in genCSS function inside the selector node. + // future TODO - move both logics into the selector joiner visitor + if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { + selectorElements[0].combinator.value = ' '; + } + selfElements = selfElements.concat(selectors[i].elements); + } + this.selfSelectors = [new Selector(selfElements)]; + this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + }; + return Extend; +}(Node)); Extend.next_id = 0; Extend.prototype.type = 'Extend'; -var VariableCall = -/*#__PURE__*/ -function (_Node) { - _inherits(VariableCall, _Node); - - function VariableCall(variable, index, currentFileInfo) { - var _this; - - _classCallCheck(this, VariableCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(VariableCall).call(this)); - _this.variable = variable; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(VariableCall, [{ - key: "eval", - value: function _eval(context) { - var rules; - var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); - var error = new LessError({ - message: `Could not evaluate variable call ${this.variable}` - }); - - if (!detachedRuleset.ruleset) { - if (detachedRuleset.rules) { - rules = detachedRuleset; - } else if (Array.isArray(detachedRuleset)) { - rules = new Ruleset('', detachedRuleset); - } else if (Array.isArray(detachedRuleset.value)) { - rules = new Ruleset('', detachedRuleset.value); - } else { - throw error; +var VariableCall = /** @class */ (function (_super) { + tslib.__extends(VariableCall, _super); + function VariableCall(variable, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.variable = variable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + VariableCall.prototype.eval = function (context) { + var rules; + var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); + var error = new LessError({ message: "Could not evaluate variable call " + this.variable }); + if (!detachedRuleset.ruleset) { + if (detachedRuleset.rules) { + rules = detachedRuleset; + } + else if (Array.isArray(detachedRuleset)) { + rules = new Ruleset('', detachedRuleset); + } + else if (Array.isArray(detachedRuleset.value)) { + rules = new Ruleset('', detachedRuleset.value); + } + else { + throw error; + } + detachedRuleset = new DetachedRuleset(rules); } - - detachedRuleset = new DetachedRuleset(rules); - } - - if (detachedRuleset.ruleset) { - return detachedRuleset.callEval(context); - } - - throw error; - } - }]); - - return VariableCall; -}(Node); - -VariableCall.prototype.type = 'VariableCall'; - -var NamespaceValue = -/*#__PURE__*/ -function (_Node) { - _inherits(NamespaceValue, _Node); - - function NamespaceValue(ruleCall, lookups, important, index, fileInfo) { - var _this; - - _classCallCheck(this, NamespaceValue); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(NamespaceValue).call(this)); - _this.value = ruleCall; - _this.lookups = lookups; - _this.important = important; - _this._index = index; - _this._fileInfo = fileInfo; - return _this; - } - - _createClass(NamespaceValue, [{ - key: "eval", - value: function _eval(context) { - var i; - var name; - var rules = this.value.eval(context); - - for (i = 0; i < this.lookups.length; i++) { - name = this.lookups[i]; - /** - * Eval'd DRs return rulesets. - * Eval'd mixins return rules, so let's make a ruleset if we need it. - * We need to do this because of late parsing of values - */ - - if (Array.isArray(rules)) { - rules = new Ruleset([new Selector()], rules); + if (detachedRuleset.ruleset) { + return detachedRuleset.callEval(context); } + throw error; + }; + return VariableCall; +}(Node)); +VariableCall.prototype.type = 'VariableCall'; - if (name === '') { - rules = rules.lastDeclaration(); - } else if (name.charAt(0) === '@') { - if (name.charAt(1) === '@') { - name = `@${new Variable(name.substr(1)).eval(context).value}`; - } - - if (rules.variables) { - rules = rules.variable(name); - } - - if (!rules) { - throw { - type: 'Name', - message: `variable ${name} not found`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } else { - if (name.substring(0, 2) === '$@') { - name = `$${new Variable(name.substr(1)).eval(context).value}`; - } else { - name = name.charAt(0) === '$' ? name : `$${name}`; - } - - if (rules.properties) { - rules = rules.property(name); - } - - if (!rules) { - throw { - type: 'Name', - message: `property "${name.substr(1)}" not found`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } // Properties are an array of values, since a ruleset can have multiple props. - // We pick the last one (the "cascaded" value) - - - rules = rules[rules.length - 1]; +var NamespaceValue = /** @class */ (function (_super) { + tslib.__extends(NamespaceValue, _super); + function NamespaceValue(ruleCall, lookups, index, fileInfo) { + var _this = _super.call(this) || this; + _this.value = ruleCall; + _this.lookups = lookups; + _this._index = index; + _this._fileInfo = fileInfo; + return _this; + } + NamespaceValue.prototype.eval = function (context) { + var i; + var name; + var rules = this.value.eval(context); + for (i = 0; i < this.lookups.length; i++) { + name = this.lookups[i]; + /** + * Eval'd DRs return rulesets. + * Eval'd mixins return rules, so let's make a ruleset if we need it. + * We need to do this because of late parsing of values + */ + if (Array.isArray(rules)) { + rules = new Ruleset([new Selector()], rules); + } + if (name === '') { + rules = rules.lastDeclaration(); + } + else if (name.charAt(0) === '@') { + if (name.charAt(1) === '@') { + name = "@" + new Variable(name.substr(1)).eval(context).value; + } + if (rules.variables) { + rules = rules.variable(name); + } + if (!rules) { + throw { type: 'Name', + message: "variable " + name + " not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + } + else { + if (name.substring(0, 2) === '$@') { + name = "$" + new Variable(name.substr(1)).eval(context).value; + } + else { + name = name.charAt(0) === '$' ? name : "$" + name; + } + if (rules.properties) { + rules = rules.property(name); + } + if (!rules) { + throw { type: 'Name', + message: "property \"" + name.substr(1) + "\" not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + // Properties are an array of values, since a ruleset can have multiple props. + // We pick the last one (the "cascaded" value) + rules = rules[rules.length - 1]; + } + if (rules.value) { + rules = rules.eval(context).value; + } + if (rules.ruleset) { + rules = rules.ruleset.eval(context); + } } + return rules; + }; + return NamespaceValue; +}(Node)); +NamespaceValue.prototype.type = 'NamespaceValue'; - if (rules.value) { - rules = rules.eval(context).value; +var Definition = /** @class */ (function (_super) { + tslib.__extends(Definition, _super); + function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { + var _this = _super.call(this) || this; + _this.name = name || 'anonymous mixin'; + _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; + _this.params = params; + _this.condition = condition; + _this.variadic = variadic; + _this.arity = params.length; + _this.rules = rules; + _this._lookups = {}; + var optionalParameters = []; + _this.required = params.reduce(function (count, p) { + if (!p.name || (p.name && !p.value)) { + return count + 1; + } + else { + optionalParameters.push(p.name); + return count; + } + }, 0); + _this.optionalParameters = optionalParameters; + _this.frames = frames; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + Definition.prototype.accept = function (visitor) { + if (this.params && this.params.length) { + this.params = visitor.visitArray(this.params); } - - if (rules.ruleset) { - rules = rules.ruleset.eval(context); + this.rules = visitor.visitArray(this.rules); + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } - - return rules; - } - }]); - - return NamespaceValue; -}(Node); - -NamespaceValue.prototype.type = 'NamespaceValue'; - -var Definition = -/*#__PURE__*/ -function (_Ruleset) { - _inherits(Definition, _Ruleset); - - function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { - var _this; - - _classCallCheck(this, Definition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Definition).call(this)); - _this.name = name || 'anonymous mixin'; - _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; - _this.params = params; - _this.condition = condition; - _this.variadic = variadic; - _this.arity = params.length; - _this.rules = rules; - _this._lookups = {}; - var optionalParameters = []; - _this.required = params.reduce(function (count, p) { - if (!p.name || p.name && !p.value) { - return count + 1; - } else { - optionalParameters.push(p.name); - return count; - } - }, 0); - _this.optionalParameters = optionalParameters; - _this.frames = frames; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(Definition, [{ - key: "accept", - value: function accept(visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - - this.rules = visitor.visitArray(this.rules); - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "evalParams", - value: function evalParams(context, mixinEnv, args, evaldArguments) { - /* jshint boss:true */ - var frame = new Ruleset(null, null); - var varargs; - var arg; - var params = copyArray(this.params); - var i; - var j; - var val; - var name; - var isNamedFound; - var argIndex; - var argsLength = 0; - - if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { - frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); - } - - mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = copyArray(args); - argsLength = args.length; - - for (i = 0; i < argsLength; i++) { - arg = args[i]; - - if (name = arg && arg.name) { - isNamedFound = false; - - for (j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(context); - frame.prependRule(new Declaration(name, arg.value.eval(context))); - isNamedFound = true; - break; - } + }; + Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) { + /* jshint boss:true */ + var frame = new Ruleset(null, null); + var varargs; + var arg; + var params = copyArray(this.params); + var i; + var j; + var val; + var name; + var isNamedFound; + var argIndex; + var argsLength = 0; + if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { + frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); + } + mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); + if (args) { + args = copyArray(args); + argsLength = args.length; + for (i = 0; i < argsLength; i++) { + arg = args[i]; + if (name = (arg && arg.name)) { + isNamedFound = false; + for (j = 0; j < params.length; j++) { + if (!evaldArguments[j] && name === params[j].name) { + evaldArguments[j] = arg.value.eval(context); + frame.prependRule(new Declaration(name, arg.value.eval(context))); + isNamedFound = true; + break; + } + } + if (isNamedFound) { + args.splice(i, 1); + i--; + continue; + } + else { + throw { type: 'Runtime', message: "Named argument for " + this.name + " " + args[i].name + " not found" }; + } + } } - - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { - type: 'Runtime', - message: `Named argument for ${this.name} ${args[i].name} not found` - }; - } - } - } - } - - argIndex = 0; - - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { - continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(context)); + argIndex = 0; + for (i = 0; i < params.length; i++) { + if (evaldArguments[i]) { + continue; } - - frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); - } else { - val = arg && arg.value; - - if (val) { - // This was a mixin call, pass in a detached ruleset of it's eval'd rules - if (Array.isArray(val)) { - val = new DetachedRuleset(new Ruleset('', val)); - } else { - val = val.eval(context); - } - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { - type: 'Runtime', - message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` - }; + arg = args && args[argIndex]; + if (name = params[i].name) { + if (params[i].variadic) { + varargs = []; + for (j = argIndex; j < argsLength; j++) { + varargs.push(args[j].value.eval(context)); + } + frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); + } + else { + val = arg && arg.value; + if (val) { + // This was a mixin call, pass in a detached ruleset of it's eval'd rules + if (Array.isArray(val)) { + val = new DetachedRuleset(new Ruleset('', val)); + } + else { + val = val.eval(context); + } + } + else if (params[i].value) { + val = params[i].value.eval(mixinEnv); + frame.resetCache(); + } + else { + throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + " (" + argsLength + " for " + this.arity + ")" }; + } + frame.prependRule(new Declaration(name, val)); + evaldArguments[i] = val; + } } - - frame.prependRule(new Declaration(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(context); - } + if (params[i].variadic && args) { + for (j = argIndex; j < argsLength; j++) { + evaldArguments[j] = args[j].value.eval(context); + } + } + argIndex++; } - - argIndex++; - } - - return frame; - } - }, { - key: "makeImportant", - value: function makeImportant() { - var rules = !this.rules ? this.rules : this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(true); - } else { - return r; - } - }); - var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); - return result; - } - }, { - key: "eval", - value: function _eval(context) { - return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); - } - }, { - key: "evalCall", - value: function evalCall(context, args, important) { - var _arguments = []; - var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; - var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); - var rules; - var ruleset; - frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); - rules = copyArray(this.rules); - ruleset = new Ruleset(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); - - if (important) { - ruleset = ruleset.makeImportant(); - } - - return ruleset; - } - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, - /* the parameter variables */ - new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])].concat(this.frames || []) // the parent namespace/mixin frames - .concat(context.frames)))) { - // the current environment frames - return false; - } - - return true; - } - }, { - key: "matchArgs", - value: function matchArgs(args, context) { - var allArgsCnt = args && args.length || 0; - var len; - var optionalParameters = this.optionalParameters; - var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { - if (optionalParameters.indexOf(p.name) < 0) { - return count + 1; - } else { - return count; - } - }, 0); - - if (!this.variadic) { - if (requiredArgsCnt < this.required) { - return false; + return frame; + }; + Definition.prototype.makeImportant = function () { + var rules = !this.rules ? this.rules : this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(true); + } + else { + return r; + } + }); + var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); + return result; + }; + Definition.prototype.eval = function (context) { + return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); + }; + Definition.prototype.evalCall = function (context, args, important) { + var _arguments = []; + var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; + var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); + var rules; + var ruleset; + frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); + rules = copyArray(this.rules); + ruleset = new Ruleset(null, rules); + ruleset.originalRuleset = this; + ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); + if (important) { + ruleset = ruleset.makeImportant(); + } + return ruleset; + }; + Definition.prototype.matchCondition = function (args, context) { + if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, /* the parameter variables */ new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])] + .concat(this.frames || []) // the parent namespace/mixin frames + .concat(context.frames)))) { // the current environment frames + return false; } - - if (allArgsCnt > this.params.length) { - return false; + return true; + }; + Definition.prototype.matchArgs = function (args, context) { + var allArgsCnt = (args && args.length) || 0; + var len; + var optionalParameters = this.optionalParameters; + var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { + if (optionalParameters.indexOf(p.name) < 0) { + return count + 1; + } + else { + return count; + } + }, 0); + if (!this.variadic) { + if (requiredArgsCnt < this.required) { + return false; + } + if (allArgsCnt > this.params.length) { + return false; + } } - } else { - if (requiredArgsCnt < this.required - 1) { - return false; + else { + if (requiredArgsCnt < (this.required - 1)) { + return false; + } } - } // check patterns - - - len = Math.min(requiredArgsCnt, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) { - return false; - } + // check patterns + len = Math.min(requiredArgsCnt, this.arity); + for (var i_1 = 0; i_1 < len; i_1++) { + if (!this.params[i_1].name && !this.params[i_1].variadic) { + if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) { + return false; + } + } } - } - - return true; - } - }]); - - return Definition; -}(Ruleset); - + return true; + }; + return Definition; +}(Ruleset)); Definition.prototype.type = 'MixinDefinition'; Definition.prototype.evalFirst = true; -var MixinCall = -/*#__PURE__*/ -function (_Node) { - _inherits(MixinCall, _Node); - - function MixinCall(elements, args, index, currentFileInfo, important) { - var _this; - - _classCallCheck(this, MixinCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(MixinCall).call(this)); - _this.selector = new Selector(elements); - _this.arguments = args || []; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.important = important; - _this.allowRoot = true; - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(MixinCall, [{ - key: "accept", - value: function accept(visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - - if (this.arguments.length) { - this.arguments = visitor.visitArray(this.arguments); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mixins; - var mixin; - var mixinPath; - var args = []; - var arg; - var argValue; - var rules = []; - var match = false; - var i; - var m; - var f; - var isRecursive; - var isOneFound; - var candidates = []; - var candidate; - var conditionResult = []; - var defaultResult; - var defFalseEitherCase = -1; - var defNone = 0; - var defTrue = 1; - var defFalse = 2; - var count; - var originalRuleset; - var noArgumentsFilter; - this.selector = this.selector.eval(context); - - function calcDefGroup(mixin, mixinPath) { +var MixinCall = /** @class */ (function (_super) { + tslib.__extends(MixinCall, _super); + function MixinCall(elements, args, index, currentFileInfo, important) { + var _this = _super.call(this) || this; + _this.selector = new Selector(elements); + _this.arguments = args || []; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.important = important; + _this.allowRoot = true; + _this.setParent(_this.selector, _this); + return _this; + } + MixinCall.prototype.accept = function (visitor) { + if (this.selector) { + this.selector = visitor.visit(this.selector); + } + if (this.arguments.length) { + this.arguments = visitor.visitArray(this.arguments); + } + }; + MixinCall.prototype.eval = function (context) { + var mixins; + var mixin; + var mixinPath; + var args = []; + var arg; + var argValue; + var rules = []; + var match = false; + var i; + var m; var f; - var p; - var namespace; - - for (f = 0; f < 2; f++) { - conditionResult[f] = true; - defaultFunc.value(f); - - for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { - namespace = mixinPath[p]; - - if (namespace.matchCondition) { - conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + var isRecursive; + var isOneFound; + var candidates = []; + var candidate; + var conditionResult = []; + var defaultResult; + var defFalseEitherCase = -1; + var defNone = 0; + var defTrue = 1; + var defFalse = 2; + var count; + var originalRuleset; + var noArgumentsFilter; + this.selector = this.selector.eval(context); + function calcDefGroup(mixin, mixinPath) { + var f; + var p; + var namespace; + for (f = 0; f < 2; f++) { + conditionResult[f] = true; + defaultFunc.value(f); + for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { + namespace = mixinPath[p]; + if (namespace.matchCondition) { + conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + } + } + if (mixin.matchCondition) { + conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); + } } - } - - if (mixin.matchCondition) { - conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); - } - } - - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - return conditionResult[1] ? defTrue : defFalse; - } - - return defNone; - } - - return defFalseEitherCase; - } - - for (i = 0; i < this.arguments.length; i++) { - arg = this.arguments[i]; - argValue = arg.value.eval(context); - - if (arg.expand && Array.isArray(argValue.value)) { - argValue = argValue.value; - - for (m = 0; m < argValue.length; m++) { - args.push({ - value: argValue[m] - }); - } - } else { - args.push({ - name: arg.name, - value: argValue - }); - } - } - - noArgumentsFilter = function noArgumentsFilter(rule) { - return rule.matchArgs(null, context); - }; - - for (i = 0; i < context.frames.length; i++) { - if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { - isOneFound = true; // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m].rule; - mixinPath = mixins[m].path; - isRecursive = false; - - for (f = 0; f < context.frames.length; f++) { - if (!(mixin instanceof Definition) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { - isRecursive = true; - break; - } + if (conditionResult[0] || conditionResult[1]) { + if (conditionResult[0] != conditionResult[1]) { + return conditionResult[1] ? + defTrue : defFalse; + } + return defNone; } - - if (isRecursive) { - continue; + return defFalseEitherCase; + } + for (i = 0; i < this.arguments.length; i++) { + arg = this.arguments[i]; + argValue = arg.value.eval(context); + if (arg.expand && Array.isArray(argValue.value)) { + argValue = argValue.value; + for (m = 0; m < argValue.length; m++) { + args.push({ value: argValue[m] }); + } } - - if (mixin.matchArgs(args, context)) { - candidate = { - mixin, - group: calcDefGroup(mixin, mixinPath) - }; - - if (candidate.group !== defFalseEitherCase) { - candidates.push(candidate); - } - - match = true; + else { + args.push({ name: arg.name, value: argValue }); } - } - - defaultFunc.reset(); - count = [0, 0, 0]; - - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - - if (count[defTrue] + count[defFalse] > 1) { - throw { - type: 'Runtime', - message: `Ambiguous use of \`default()\` found when matching for \`${this.format(args)}\``, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - - if (candidate === defNone || candidate === defaultResult) { - try { - mixin = candidates[m].mixin; - - if (!(mixin instanceof Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); - mixin.originalRuleset = originalRuleset; + } + noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); }; + for (i = 0; i < context.frames.length; i++) { + if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { + isOneFound = true; + // To make `default()` function independent of definition order we have two "subpasses" here. + // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), + // and build candidate list with corresponding flags. Then, when we know all possible matches, + // we make a final decision. + for (m = 0; m < mixins.length; m++) { + mixin = mixins[m].rule; + mixinPath = mixins[m].path; + isRecursive = false; + for (f = 0; f < context.frames.length; f++) { + if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { + isRecursive = true; + break; + } + } + if (isRecursive) { + continue; + } + if (mixin.matchArgs(args, context)) { + candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) }; + if (candidate.group !== defFalseEitherCase) { + candidates.push(candidate); + } + match = true; + } + } + defaultFunc.reset(); + count = [0, 0, 0]; + for (m = 0; m < candidates.length; m++) { + count[candidates[m].group]++; + } + if (count[defNone] > 0) { + defaultResult = defFalse; + } + else { + defaultResult = defTrue; + if ((count[defTrue] + count[defFalse]) > 1) { + throw { type: 'Runtime', + message: "Ambiguous use of `default()` found when matching for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; + } + } + for (m = 0; m < candidates.length; m++) { + candidate = candidates[m].group; + if ((candidate === defNone) || (candidate === defaultResult)) { + try { + mixin = candidates[m].mixin; + if (!(mixin instanceof Definition)) { + originalRuleset = mixin.originalRuleset || mixin; + mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); + mixin.originalRuleset = originalRuleset; + } + var newRules = mixin.evalCall(context, args, this.important).rules; + this._setVisibilityToReplacement(newRules); + Array.prototype.push.apply(rules, newRules); + } + catch (e) { + throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack }; + } + } + } + if (match) { + return rules; } - - var newRules = mixin.evalCall(context, args, this.important).rules; - - this._setVisibilityToReplacement(newRules); - - Array.prototype.push.apply(rules, newRules); - } catch (e) { - throw { - message: e.message, - index: this.getIndex(), - filename: this.fileInfo().filename, - stack: e.stack - }; - } } - } - - if (match) { - return rules; - } } - } - - if (isOneFound) { - throw { - type: 'Runtime', - message: `No matching definition was found for \`${this.format(args)}\``, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } else { - throw { - type: 'Name', - message: `${this.selector.toCSS().trim()} is undefined`, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - }, { - key: "_setVisibilityToReplacement", - value: function _setVisibilityToReplacement(replacement) { - var i; - var rule; - - if (this.blocksVisibility()) { - for (i = 0; i < replacement.length; i++) { - rule = replacement[i]; - rule.addVisibilityBlock(); - } - } - } - }, { - key: "format", - value: function format(args) { - return `${this.selector.toCSS().trim()}(${args ? args.map(function (a) { - var argValue = ''; - - if (a.name) { - argValue += `${a.name}:`; + if (isOneFound) { + throw { type: 'Runtime', + message: "No matching definition was found for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; } - - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += '???'; + else { + throw { type: 'Name', + message: this.selector.toCSS().trim() + " is undefined", + index: this.getIndex(), filename: this.fileInfo().filename }; } + }; + MixinCall.prototype._setVisibilityToReplacement = function (replacement) { + var i; + var rule; + if (this.blocksVisibility()) { + for (i = 0; i < replacement.length; i++) { + rule = replacement[i]; + rule.addVisibilityBlock(); + } + } + }; + MixinCall.prototype.format = function (args) { + return this.selector.toCSS().trim() + "(" + (args ? args.map(function (a) { + var argValue = ''; + if (a.name) { + argValue += a.name + ":"; + } + if (a.value.toCSS) { + argValue += a.value.toCSS(); + } + else { + argValue += '???'; + } + return argValue; + }).join(', ') : '') + ")"; + }; + return MixinCall; +}(Node)); +MixinCall.prototype.type = 'MixinCall'; - return argValue; - }).join(', ') : ''})`; - } - }]); - - return MixinCall; -}(Node); - -MixinCall.prototype.type = 'MixinCall'; - -var tree = { - Node, - Color, - AtRule, - DetachedRuleset, - Operation, - Dimension, - Unit, - Keyword, - Variable, - Property, - Ruleset, - Element, - Attribute, - Combinator, - Selector, - Quoted, - Expression, - Declaration, - Call, - URL, - Import, - Comment, - Anonymous, - Value, - JavaScript, - Assignment, - Condition, - Paren, - Media, - UnicodeDescriptor, - Negative, - Extend, - VariableCall, - NamespaceValue, - mixin: { - Call: MixinCall, - Definition: Definition - } -}; - -var environment$1 = -/*#__PURE__*/ -function () { - function environment(externalEnvironment, fileManagers) { - _classCallCheck(this, environment); - - this.fileManagers = fileManagers || []; - externalEnvironment = externalEnvironment || {}; - var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; - var requiredFunctions = []; - var functions = requiredFunctions.concat(optionalFunctions); - - for (var i = 0; i < functions.length; i++) { - var propName = functions[i]; - var environmentFunc = externalEnvironment[propName]; - - if (environmentFunc) { - this[propName] = environmentFunc.bind(externalEnvironment); - } else if (i < requiredFunctions.length) { - this.warn(`missing required function in environment - ${propName}`); - } +var tree = { + Node: Node, Color: Color, AtRule: AtRule, DetachedRuleset: DetachedRuleset, Operation: Operation, + Dimension: Dimension, Unit: Unit, Keyword: Keyword, Variable: Variable, Property: Property, + Ruleset: Ruleset, Element: Element, Attribute: Attribute, Combinator: Combinator, Selector: Selector, + Quoted: Quoted, Expression: Expression, Declaration: Declaration, Call: Call, URL: URL, Import: Import, + Comment: Comment, Anonymous: Anonymous, Value: Value, JavaScript: JavaScript, Assignment: Assignment, + Condition: Condition, Paren: Paren, Media: Media, UnicodeDescriptor: UnicodeDescriptor, Negative: Negative, + Extend: Extend, VariableCall: VariableCall, NamespaceValue: NamespaceValue, + mixin: { + Call: MixinCall, + Definition: Definition } - } - - _createClass(environment, [{ - key: "getFileManager", - value: function getFileManager(filename, currentDirectory, options, environment, isSync) { - if (!filename) { - logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); - } - - if (currentDirectory == null) { - logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); - } - - var fileManagers = this.fileManagers; - - if (options.pluginManager) { - fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); - } - - for (var i = fileManagers.length - 1; i >= 0; i--) { - var fileManager = fileManagers[i]; +}; - if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { - return fileManager; +/** + * @todo Document why this abstraction exists, and the relationship between + * environment, file managers, and plugin manager + */ +var environment$1 = /** @class */ (function () { + function environment(externalEnvironment, fileManagers) { + this.fileManagers = fileManagers || []; + externalEnvironment = externalEnvironment || {}; + var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; + var requiredFunctions = []; + var functions = requiredFunctions.concat(optionalFunctions); + for (var i_1 = 0; i_1 < functions.length; i_1++) { + var propName = functions[i_1]; + var environmentFunc = externalEnvironment[propName]; + if (environmentFunc) { + this[propName] = environmentFunc.bind(externalEnvironment); + } + else if (i_1 < requiredFunctions.length) { + this.warn("missing required function in environment - " + propName); + } } - } - - return null; } - }, { - key: "addFileManager", - value: function addFileManager(fileManager) { - this.fileManagers.push(fileManager); - } - }, { - key: "clearFileManagers", - value: function clearFileManagers() { - this.fileManagers = []; - } - }]); - - return environment; -}(); - -var AbstractPluginLoader = -/*#__PURE__*/ -function () { - function AbstractPluginLoader() { - _classCallCheck(this, AbstractPluginLoader); - - // Implemented by Node.js plugin loader - this.require = function () { - return null; + environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) { + if (!filename) { + logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); + } + if (currentDirectory == null) { + logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); + } + var fileManagers = this.fileManagers; + if (options.pluginManager) { + fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); + } + for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) { + var fileManager = fileManagers[i_2]; + if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { + return fileManager; + } + } + return null; }; - } - - _createClass(AbstractPluginLoader, [{ - key: "evalPlugin", - value: function evalPlugin(contents, context, imports, pluginOptions, fileInfo) { - var loader; - var registry; - var pluginObj; - var localModule; - var pluginManager; - var filename; - var result; - pluginManager = context.pluginManager; - - if (fileInfo) { - if (typeof fileInfo === 'string') { - filename = fileInfo; - } else { - filename = fileInfo.filename; + environment.prototype.addFileManager = function (fileManager) { + this.fileManagers.push(fileManager); + }; + environment.prototype.clearFileManagers = function () { + this.fileManagers = []; + }; + return environment; +}()); + +var AbstractPluginLoader = /** @class */ (function () { + function AbstractPluginLoader() { + // Implemented by Node.js plugin loader + this.require = function () { return null; }; + } + AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) { + var loader; + var registry; + var pluginObj; + var localModule; + var pluginManager; + var filename; + var result; + pluginManager = context.pluginManager; + if (fileInfo) { + if (typeof fileInfo === 'string') { + filename = fileInfo; + } + else { + filename = fileInfo.filename; + } } - } - - var shortname = new this.less.FileManager().extractUrlParts(filename).filename; - - if (filename) { - pluginObj = pluginManager.get(filename); - - if (pluginObj) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - - try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); + var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename; + if (filename) { + pluginObj = pluginManager.get(filename); + if (pluginObj) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + return pluginObj; } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - - return pluginObj; } - } - - localModule = { - exports: {}, - pluginManager, - fileInfo - }; - registry = functionRegistry.create(); - - var registerPlugin = function registerPlugin(obj) { - pluginObj = obj; - }; - - try { - loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); - loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); - } catch (e) { - return new LessError(e, imports, filename); - } - - if (!pluginObj) { - pluginObj = localModule.exports; - } - - pluginObj = this.validatePlugin(pluginObj, filename, shortname); - - if (pluginObj instanceof LessError) { - return pluginObj; - } - - if (pluginObj) { - pluginObj.imports = imports; - pluginObj.filename = filename; // For < 3.x (or unspecified minVersion) - setOptions() before install() - - if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - } // Run on first load - - - pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); - pluginObj.functions = registry.getLocalFunctions(); // Need to call setOptions again because the pluginObj might have functions - - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } // Run every @plugin call - - + localModule = { + exports: {}, + pluginManager: pluginManager, + fileInfo: fileInfo + }; + registry = functionRegistry.create(); + var registerPlugin = function (obj) { + pluginObj = obj; + }; try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); - } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - } else { - return new LessError({ - message: 'Not a valid plugin' - }, imports, filename); - } - - return pluginObj; - } - }, { - key: "trySetOptions", - value: function trySetOptions(plugin, filename, name, options) { - if (options && !plugin.setOptions) { - return new LessError({ - message: `Options have been provided but the plugin ${name} does not support any options.` - }); - } - - try { - plugin.setOptions && plugin.setOptions(options); - } catch (e) { - return new LessError(e); - } - } - }, { - key: "validatePlugin", - value: function validatePlugin(plugin, filename, name) { - if (plugin) { - // support plugins being a function - // so that the plugin can be more usable programmatically - if (typeof plugin === 'function') { - plugin = new plugin(); + loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); + loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); } - - if (plugin.minVersion) { - if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + catch (e) { + return new LessError(e, imports, filename); + } + if (!pluginObj) { + pluginObj = localModule.exports; + } + pluginObj = this.validatePlugin(pluginObj, filename, shortname); + if (pluginObj instanceof LessError) { + return pluginObj; + } + if (pluginObj) { + pluginObj.imports = imports; + pluginObj.filename = filename; + // For < 3.x (or unspecified minVersion) - setOptions() before install() + if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + } + // Run on first load + pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); + pluginObj.functions = registry.getLocalFunctions(); + // Need to call setOptions again because the pluginObj might have functions + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + // Run every @plugin call + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + } + else { + return new LessError({ message: 'Not a valid plugin' }, imports, filename); + } + return pluginObj; + }; + AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) { + if (options && !plugin.setOptions) { return new LessError({ - message: `Plugin ${name} requires version ${this.versionToString(plugin.minVersion)}` + message: "Options have been provided but the plugin " + name + " does not support any options." }); - } } - - return plugin; - } - - return null; - } - }, { - key: "compareVersion", - value: function compareVersion(aVersion, bVersion) { - if (typeof aVersion === 'string') { - aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); - aVersion.shift(); - } - - for (var i = 0; i < aVersion.length; i++) { - if (aVersion[i] !== bVersion[i]) { - return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1; + try { + plugin.setOptions && plugin.setOptions(options); } - } - - return 0; - } - }, { - key: "versionToString", - value: function versionToString(version) { - var versionString = ''; - - for (var i = 0; i < version.length; i++) { - versionString += (versionString ? '.' : '') + version[i]; - } - - return versionString; - } - }, { - key: "printUsage", - value: function printUsage(plugins) { - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; - - if (plugin.printUsage) { - plugin.printUsage(); + catch (e) { + return new LessError(e); } - } - } - }]); - - return AbstractPluginLoader; -}(); + }; + AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) { + if (plugin) { + // support plugins being a function + // so that the plugin can be more usable programmatically + if (typeof plugin === 'function') { + plugin = new plugin(); + } + if (plugin.minVersion) { + if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + return new LessError({ + message: "Plugin " + name + " requires version " + this.versionToString(plugin.minVersion) + }); + } + } + return plugin; + } + return null; + }; + AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) { + if (typeof aVersion === 'string') { + aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); + aVersion.shift(); + } + for (var i_1 = 0; i_1 < aVersion.length; i_1++) { + if (aVersion[i_1] !== bVersion[i_1]) { + return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1; + } + } + return 0; + }; + AbstractPluginLoader.prototype.versionToString = function (version) { + var versionString = ''; + for (var i_2 = 0; i_2 < version.length; i_2++) { + versionString += (versionString ? '.' : '') + version[i_2]; + } + return versionString; + }; + AbstractPluginLoader.prototype.printUsage = function (plugins) { + for (var i_3 = 0; i_3 < plugins.length; i_3++) { + var plugin = plugins[i_3]; + if (plugin.printUsage) { + plugin.printUsage(); + } + } + }; + return AbstractPluginLoader; +}()); -var _visitArgs = { - visitDeeper: true -}; +var _visitArgs = { visitDeeper: true }; var _hasIndexed = false; - function _noop(node) { - return node; + return node; } - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key; - var child; - - for (key in parent) { - /* eslint guard-for-in: 0 */ - child = parent[key]; - - switch (typeof child) { - case 'function': - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; + // add .typeIndex to tree node types for lookup table + var key; + var child; + for (key in parent) { + /* eslint guard-for-in: 0 */ + child = parent[key]; + switch (typeof child) { + case 'function': + // ignore bound functions directly on tree which do not have a prototype + // or aren't nodes + if (child.prototype && child.prototype.type) { + child.prototype.typeIndex = ticker++; + } + break; + case 'object': + ticker = indexNodeTypes(child, ticker); + break; } - - break; - - case 'object': - ticker = indexNodeTypes(child, ticker); - break; } - } - - return ticker; + return ticker; } - -var Visitor = -/*#__PURE__*/ -function () { - function Visitor(implementation) { - _classCallCheck(this, Visitor); - - this._implementation = implementation; - this._visitInCache = {}; - this._visitOutCache = {}; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - } - - _createClass(Visitor, [{ - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - - if (!nodeTypeIndex) { - // MixinCall args aren't a node type? - if (node.value && node.value.typeIndex) { - this.visit(node.value); - } - - return node; - } - - var impl = this._implementation; - var func = this._visitInCache[nodeTypeIndex]; - var funcOut = this._visitOutCache[nodeTypeIndex]; - var visitArgs = _visitArgs; - var fnName; - visitArgs.visitDeeper = true; - - if (!func) { - fnName = `visit${node.type}`; - func = impl[fnName] || _noop; - funcOut = impl[`${fnName}Out`] || _noop; - this._visitInCache[nodeTypeIndex] = func; - this._visitOutCache[nodeTypeIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - - if (node && impl.isReplacing) { - node = newNode; +var Visitor = /** @class */ (function () { + function Visitor(implementation) { + this._implementation = implementation; + this._visitInCache = {}; + this._visitOutCache = {}; + if (!_hasIndexed) { + indexNodeTypes(tree, 1); + _hasIndexed = true; + } + } + Visitor.prototype.visit = function (node) { + if (!node) { + return node; + } + var nodeTypeIndex = node.typeIndex; + if (!nodeTypeIndex) { + // MixinCall args aren't a node type? + if (node.value && node.value.typeIndex) { + this.visit(node.value); + } + return node; + } + var impl = this._implementation; + var func = this._visitInCache[nodeTypeIndex]; + var funcOut = this._visitOutCache[nodeTypeIndex]; + var visitArgs = _visitArgs; + var fnName; + visitArgs.visitDeeper = true; + if (!func) { + fnName = "visit" + node.type; + func = impl[fnName] || _noop; + funcOut = impl[fnName + "Out"] || _noop; + this._visitInCache[nodeTypeIndex] = func; + this._visitOutCache[nodeTypeIndex] = funcOut; + } + if (func !== _noop) { + var newNode = func.call(impl, node, visitArgs); + if (node && impl.isReplacing) { + node = newNode; + } } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - } - }, { - key: "visitArray", - value: function visitArray(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; // Non-replacing - - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); + if (visitArgs.visitDeeper && node) { + if (node.length) { + for (var i = 0, cnt = node.length; i < cnt; i++) { + if (node[i].accept) { + node[i].accept(this); + } + } + } + else if (node.accept) { + node.accept(this); + } } - - return nodes; - } // Replacing - - - var out = []; - - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - - if (evald === undefined) { - continue; + if (funcOut != _noop) { + funcOut.call(impl, node); } - - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); + return node; + }; + Visitor.prototype.visitArray = function (nodes, nonReplacing) { + if (!nodes) { + return nodes; } - } - - return out; - } - }, { - key: "flatten", - value: function flatten(arr, out) { - if (!out) { - out = []; - } - - var cnt; - var i; - var item; - var nestedCnt; - var j; - var nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - - if (item === undefined) { - continue; + var cnt = nodes.length; + var i; + // Non-replacing + if (nonReplacing || !this._implementation.isReplacing) { + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); + } + return nodes; } - - if (!item.splice) { - out.push(item); - continue; + // Replacing + var out = []; + for (i = 0; i < cnt; i++) { + var evald = this.visit(nodes[i]); + if (evald === undefined) { + continue; + } + if (!evald.splice) { + out.push(evald); + } + else if (evald.length) { + this.flatten(evald, out); + } } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - - if (nestedItem === undefined) { - continue; - } - - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } + return out; + }; + Visitor.prototype.flatten = function (arr, out) { + if (!out) { + out = []; } - } - - return out; - } - }]); - - return Visitor; -}(); - -var ImportSequencer = -/*#__PURE__*/ -function () { - function ImportSequencer(onSequencerEmpty) { - _classCallCheck(this, ImportSequencer); - - this.imports = []; - this.variableImports = []; - this._onSequencerEmpty = onSequencerEmpty; - this._currentDepth = 0; - } - - _createClass(ImportSequencer, [{ - key: "addImport", - value: function addImport(callback) { - var importSequencer = this; - var importItem = { - callback, - args: null, - isReady: false - }; - this.imports.push(importItem); - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; + var cnt; + var i; + var item; + var nestedCnt; + var j; + var nestedItem; + for (i = 0, cnt = arr.length; i < cnt; i++) { + item = arr[i]; + if (item === undefined) { + continue; + } + if (!item.splice) { + out.push(item); + continue; + } + for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { + nestedItem = item[j]; + if (nestedItem === undefined) { + continue; + } + if (!nestedItem.splice) { + out.push(nestedItem); + } + else if (nestedItem.length) { + this.flatten(nestedItem, out); + } + } } - - importItem.args = Array.prototype.slice.call(args, 0); - importItem.isReady = true; - importSequencer.tryRun(); - }; - } - }, { - key: "addVariableImport", - value: function addVariableImport(callback) { - this.variableImports.push(callback); - } - }, { - key: "tryRun", - value: function tryRun() { - this._currentDepth++; - - try { - while (true) { - while (this.imports.length > 0) { - var importItem = this.imports[0]; - - if (!importItem.isReady) { - return; + return out; + }; + return Visitor; +}()); + +var ImportSequencer = /** @class */ (function () { + function ImportSequencer(onSequencerEmpty) { + this.imports = []; + this.variableImports = []; + this._onSequencerEmpty = onSequencerEmpty; + this._currentDepth = 0; + } + ImportSequencer.prototype.addImport = function (callback) { + var importSequencer = this; + var importItem = { + callback: callback, + args: null, + isReady: false + }; + this.imports.push(importItem); + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + importItem.args = Array.prototype.slice.call(args, 0); + importItem.isReady = true; + importSequencer.tryRun(); + }; + }; + ImportSequencer.prototype.addVariableImport = function (callback) { + this.variableImports.push(callback); + }; + ImportSequencer.prototype.tryRun = function () { + this._currentDepth++; + try { + while (true) { + while (this.imports.length > 0) { + var importItem = this.imports[0]; + if (!importItem.isReady) { + return; + } + this.imports = this.imports.slice(1); + importItem.callback.apply(null, importItem.args); + } + if (this.variableImports.length === 0) { + break; + } + var variableImport = this.variableImports[0]; + this.variableImports = this.variableImports.slice(1); + variableImport(); } - - this.imports = this.imports.slice(1); - importItem.callback.apply(null, importItem.args); - } - - if (this.variableImports.length === 0) { - break; - } - - var variableImport = this.variableImports[0]; - this.variableImports = this.variableImports.slice(1); - variableImport(); } - } finally { - this._currentDepth--; - } - - if (this._currentDepth === 0 && this._onSequencerEmpty) { - this._onSequencerEmpty(); - } - } - }]); - - return ImportSequencer; -}(); + finally { + this._currentDepth--; + } + if (this._currentDepth === 0 && this._onSequencerEmpty) { + this._onSequencerEmpty(); + } + }; + return ImportSequencer; +}()); -var ImportVisitor = function ImportVisitor(importer, finish) { - this._visitor = new Visitor(this); - this._importer = importer; - this._finish = finish; - this.context = new contexts.Eval(); - this.importCount = 0; - this.onceFileDetectionMap = {}; - this.recursionDetector = {}; - this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); +var ImportVisitor = function (importer, finish) { + this._visitor = new Visitor(this); + this._importer = importer; + this._finish = finish; + this.context = new contexts.Eval(); + this.importCount = 0; + this.onceFileDetectionMap = {}; + this.recursionDetector = {}; + this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); }; - ImportVisitor.prototype = { - isReplacing: false, - run: function run(root) { - try { - // process the contents - this._visitor.visit(root); - } catch (e) { - this.error = e; - } - - this.isFinished = true; - - this._sequencer.tryRun(); - }, - _onSequencerEmpty: function _onSequencerEmpty() { - if (!this.isFinished) { - return; - } - - this._finish(this.error); - }, - visitImport: function visitImport(importNode, visitArgs) { - var inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - var context = new contexts.Eval(this.context, copyArray(this.context.frames)); - var importParent = context.frames[0]; - this.importCount++; - - if (importNode.isVariableImport()) { - this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); - } else { - this.processImportNode(importNode, context, importParent); - } - } - - visitArgs.visitDeeper = false; - }, - processImportNode: function processImportNode(importNode, context, importParent) { - var evaldImportNode; - var inlineCSS = importNode.options.inline; - - try { - evaldImportNode = importNode.evalForImport(context); - } catch (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } // attempt to eval properly and treat as css - - - importNode.css = true; // if that fails, this error will be thrown - - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - if (evaldImportNode.options.multiple) { - context.importMultiple = true; - } // try appending if we haven't determined if it is css or not - - - var tryAppendLessExtension = evaldImportNode.css === undefined; - - for (var i = 0; i < importParent.rules.length; i++) { - if (importParent.rules[i] === importNode) { - importParent.rules[i] = evaldImportNode; - break; + isReplacing: false, + run: function (root) { + try { + // process the contents + this._visitor.visit(root); } - } - - var onImported = this.onImported.bind(this, evaldImportNode, context); - - var sequencedOnImported = this._sequencer.addImport(onImported); - - this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); - } else { - this.importCount--; - - if (this.isFinished) { + catch (e) { + this.error = e; + } + this.isFinished = true; this._sequencer.tryRun(); - } - } - }, - onImported: function onImported(importNode, context, e, root, importedAtRoot, fullPath) { - if (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } - - this.error = e; - } - - var importVisitor = this; - var inlineCSS = importNode.options.inline; - var isPlugin = importNode.options.isPlugin; - var isOptional = importNode.options.optional; - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - - if (!context.importMultiple) { - if (duplicateImport) { - importNode.skip = true; - } else { - importNode.skip = function () { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - if (!fullPath && isOptional) { - importNode.skip = true; - } - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - - if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - var oldContext = this.context; - this.context = context; - + }, + _onSequencerEmpty: function () { + if (!this.isFinished) { + return; + } + this._finish(this.error); + }, + visitImport: function (importNode, visitArgs) { + var inlineCSS = importNode.options.inline; + if (!importNode.css || inlineCSS) { + var context = new contexts.Eval(this.context, copyArray(this.context.frames)); + var importParent = context.frames[0]; + this.importCount++; + if (importNode.isVariableImport()) { + this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); + } + else { + this.processImportNode(importNode, context, importParent); + } + } + visitArgs.visitDeeper = false; + }, + processImportNode: function (importNode, context, importParent) { + var evaldImportNode; + var inlineCSS = importNode.options.inline; try { - this._visitor.visit(root); - } catch (e) { - this.error = e; + evaldImportNode = importNode.evalForImport(context); } - - this.context = oldContext; - } + catch (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + // attempt to eval properly and treat as css + importNode.css = true; + // if that fails, this error will be thrown + importNode.error = e; + } + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { + if (evaldImportNode.options.multiple) { + context.importMultiple = true; + } + // try appending if we haven't determined if it is css or not + var tryAppendLessExtension = evaldImportNode.css === undefined; + for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) { + if (importParent.rules[i_1] === importNode) { + importParent.rules[i_1] = evaldImportNode; + break; + } + } + var onImported = this.onImported.bind(this, evaldImportNode, context); + var sequencedOnImported = this._sequencer.addImport(onImported); + this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); + } + else { + this.importCount--; + if (this.isFinished) { + this._sequencer.tryRun(); + } + } + }, + onImported: function (importNode, context, e, root, importedAtRoot, fullPath) { + if (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + this.error = e; + } + var importVisitor = this; + var inlineCSS = importNode.options.inline; + var isPlugin = importNode.options.isPlugin; + var isOptional = importNode.options.optional; + var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; + if (!context.importMultiple) { + if (duplicateImport) { + importNode.skip = true; + } + else { + importNode.skip = function () { + if (fullPath in importVisitor.onceFileDetectionMap) { + return true; + } + importVisitor.onceFileDetectionMap[fullPath] = true; + return false; + }; + } + } + if (!fullPath && isOptional) { + importNode.skip = true; + } + if (root) { + importNode.root = root; + importNode.importedFilename = fullPath; + if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { + importVisitor.recursionDetector[fullPath] = true; + var oldContext = this.context; + this.context = context; + try { + this._visitor.visit(root); + } + catch (e) { + this.error = e; + } + this.context = oldContext; + } + } + importVisitor.importCount--; + if (importVisitor.isFinished) { + importVisitor._sequencer.tryRun(); + } + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.unshift(declNode); + } + else { + visitArgs.visitDeeper = false; + } + }, + visitDeclarationOut: function (declNode) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.shift(); + } + }, + visitAtRule: function (atRuleNode, visitArgs) { + this.context.frames.unshift(atRuleNode); + }, + visitAtRuleOut: function (atRuleNode) { + this.context.frames.shift(); + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + this.context.frames.unshift(mixinDefinitionNode); + }, + visitMixinDefinitionOut: function (mixinDefinitionNode) { + this.context.frames.shift(); + }, + visitRuleset: function (rulesetNode, visitArgs) { + this.context.frames.unshift(rulesetNode); + }, + visitRulesetOut: function (rulesetNode) { + this.context.frames.shift(); + }, + visitMedia: function (mediaNode, visitArgs) { + this.context.frames.unshift(mediaNode.rules[0]); + }, + visitMediaOut: function (mediaNode) { + this.context.frames.shift(); } - - importVisitor.importCount--; - - if (importVisitor.isFinished) { - importVisitor._sequencer.tryRun(); - } - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.unshift(declNode); - } else { - visitArgs.visitDeeper = false; - } - }, - visitDeclarationOut: function visitDeclarationOut(declNode) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.shift(); - } - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - this.context.frames.unshift(atRuleNode); - }, - visitAtRuleOut: function visitAtRuleOut(atRuleNode) { - this.context.frames.shift(); - }, - visitMixinDefinition: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - this.context.frames.unshift(mixinDefinitionNode); - }, - visitMixinDefinitionOut: function visitMixinDefinitionOut(mixinDefinitionNode) { - this.context.frames.shift(); - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - this.context.frames.unshift(rulesetNode); - }, - visitRulesetOut: function visitRulesetOut(rulesetNode) { - this.context.frames.shift(); - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - this.context.frames.unshift(mediaNode.rules[0]); - }, - visitMediaOut: function visitMediaOut(mediaNode) { - this.context.frames.shift(); - } }; -var SetTreeVisibilityVisitor = -/*#__PURE__*/ -function () { - function SetTreeVisibilityVisitor(visible) { - _classCallCheck(this, SetTreeVisibilityVisitor); - - this.visible = visible; - } - - _createClass(SetTreeVisibilityVisitor, [{ - key: "run", - value: function run(root) { - this.visit(root); - } - }, { - key: "visitArray", - value: function visitArray(nodes) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; - - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - - return nodes; - } - }, { - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - if (node.constructor === Array) { - return this.visitArray(node); - } - - if (!node.blocksVisibility || node.blocksVisibility()) { - return node; - } - - if (this.visible) { - node.ensureVisibility(); - } else { - node.ensureInvisibility(); - } - - node.accept(this); - return node; +var SetTreeVisibilityVisitor = /** @class */ (function () { + function SetTreeVisibilityVisitor(visible) { + this.visible = visible; } - }]); - - return SetTreeVisibilityVisitor; -}(); - -/* jshint loopfunc:true */ - -var ExtendFinderVisitor = -/*#__PURE__*/ -function () { - function ExtendFinderVisitor() { - _classCallCheck(this, ExtendFinderVisitor); - - this._visitor = new Visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - } - - _createClass(ExtendFinderVisitor, [{ - key: "run", - value: function run(root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i; - var j; - var extend; - var allSelectorsExtendList = []; - var extendList; // get &:extend(.a); rules which apply to all selectors in this ruleset - - var rules = rulesetNode.rules; - var ruleCnt = rules ? rules.length : 0; - - for (i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; + SetTreeVisibilityVisitor.prototype.run = function (root) { + this.visit(root); + }; + SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) { + if (!nodes) { + return nodes; } - } // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - - - var paths = rulesetNode.paths; - - for (i = 0; i < paths.length; i++) { - var selectorPath = paths[i]; - var selector = selectorPath[selectorPath.length - 1]; - var selExtendList = selector.extendList; - extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function (allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); + var cnt = nodes.length; + var i; + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); } - - for (j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - - if (j === 0) { - extend.firstExtendOnThisSelectorPath = true; - } - - this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); + return nodes; + }; + SetTreeVisibilityVisitor.prototype.visit = function (node) { + if (!node) { + return node; } - } - - this.contexts.push(rulesetNode.selectors); - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - atRuleNode.allExtends = []; - this.allExtendsStack.push(atRuleNode.allExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }]); - - return ExtendFinderVisitor; -}(); - -var ProcessExtendsVisitor = -/*#__PURE__*/ -function () { - function ProcessExtendsVisitor() { - _classCallCheck(this, ProcessExtendsVisitor); - - this._visitor = new Visitor(this); - } - - _createClass(ProcessExtendsVisitor, [{ - key: "run", - value: function run(root) { - var extendFinder = new ExtendFinderVisitor(); - this.extendIndices = {}; - extendFinder.run(root); - - if (!extendFinder.foundExtends) { - return root; - } - - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - - var newRoot = this._visitor.visit(root); - - this.checkExtendsForNonMatched(root.allExtends); - return newRoot; - } - }, { - key: "checkExtendsForNonMatched", - value: function checkExtendsForNonMatched(extendList) { - var indices = this.extendIndices; - extendList.filter(function (extend) { - return !extend.hasFoundMatches && extend.parent_ids.length == 1; - }).forEach(function (extend) { - var selector = '_unknown_'; - - try { - selector = extend.selector.toCSS({}); - } catch (_) {} - - if (!indices[`${extend.index} ${selector}`]) { - indices[`${extend.index} ${selector}`] = true; - logger.warn(`extend '${selector}' has no matches`); - } - }); - } - }, { - key: "doExtendChaining", - value: function doExtendChaining(extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering - // and pasting the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already - // processed if we look at each selector at a time, as is done in visitRuleset - var extendIndex; - var targetExtendIndex; - var matches; - var extendsToAdd = []; - var newSelector; - var extendVisitor = this; - var selectorPath; - var extend; - var targetExtend; - var newExtend; - iterationCount = iterationCount || 0; // loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the separation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - - for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { - for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; // look for circular references - - if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { - continue; - } // find a match in the target extends self selector (the bit before :extend) - - - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - extend.hasFoundMatches = true; // we found a match, so for each self selector.. - - extend.selfSelectors.forEach(function (selfSelector) { - var info = targetExtend.visibilityInfo(); // process the extend as usual - - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); // but now we create a new extend from it - - newExtend = new tree.Extend(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); - newExtend.selfSelectors = newSelector; // add the extend onto the list of extends for that selector - - newSelector[newSelector.length - 1].extendList = [newExtend]; // record that we need to add it. - - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; // remember its parents for circular references - - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } + if (node.constructor === Array) { + return this.visitArray(node); } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - - if (iterationCount > 100) { - var selectorOne = '{unable to calculate}'; - var selectorTwo = '{unable to calculate}'; - - try { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } catch (e) {} - - throw { - message: `extend circular reference detected. One of the circular extends is currently:${selectorOne}:extend(${selectorTwo})` - }; - } // now process the new extends on the existing rules so that we can handle a extending b extending c extending - // d extending e... - - - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); - } else { - return extendsToAdd; - } - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitSelector", - value: function visitSelector(selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var matches; - var pathIndex; - var extendIndex; - var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; - var selectorsToAdd = []; - var extendVisitor = this; - var selectorPath; // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; // extending extends happens initially, before the main pass - - if (rulesetNode.extendOnEveryPath) { - continue; - } - - var extendList = selectorPath[selectorPath.length - 1].extendList; - - if (extendList && extendList.length) { - continue; - } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - allExtends[extendIndex].hasFoundMatches = true; - allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { - var extendedSelectors; - extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); - selectorsToAdd.push(extendedSelectors); - }); - } + if (!node.blocksVisibility || node.blocksVisibility()) { + return node; } - } - - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - } - }, { - key: "findMatch", - value: function findMatch(extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex; - var hackstackSelector; - var hackstackElementIndex; - var haystackElement; - var targetCombinator; - var i; - var extendVisitor = this; - var needleElements = extend.selector.elements; - var potentialMatches = []; - var potentialMatch; - var matches = []; // loop through the haystack elements - - for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - haystackElement = hackstackSelector.elements[hackstackElementIndex]; // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - - if (extend.allowBefore || haystackSelectorIndex === 0 && hackstackElementIndex === 0) { - potentialMatches.push({ - pathIndex: haystackSelectorIndex, - index: hackstackElementIndex, - matched: 0, - initialCombinator: haystackElement.combinator - }); - } - - for (i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to - // work out what the resulting combinator will be - - targetCombinator = haystackElement.combinator.value; - - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } // if we don't match, null our match to indicate failure - - - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } // if we are still valid and have finished, test whether we have elements after and whether these are allowed - - - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - - if (potentialMatch.finished && !extend.allowAfter && (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length)) { - potentialMatch = null; - } - } // if null we remove, if not, we are still valid, so either push as a valid match or continue - - - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } + if (this.visible) { + node.ensureVisibility(); } - } - - return matches; - } - }, { - key: "isElementValuesEqual", - value: function isElementValuesEqual(elementValue1, elementValue2) { - if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { - return elementValue1 === elementValue2; - } - - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; + else { + node.ensureInvisibility(); } + node.accept(this); + return node; + }; + return SetTreeVisibilityVisitor; +}()); - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - - return true; +/* jshint loopfunc:true */ +var ExtendFinderVisitor = /** @class */ (function () { + function ExtendFinderVisitor() { + this._visitor = new Visitor(this); + this.contexts = []; + this.allExtendsStack = [[]]; + } + ExtendFinderVisitor.prototype.run = function (root) { + root = this._visitor.visit(root); + root.allExtends = this.allExtendsStack[0]; + return root; + }; + ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; + var i; + var j; + var extend; + var allSelectorsExtendList = []; + var extendList; + // get &:extend(.a); rules which apply to all selectors in this ruleset + var rules = rulesetNode.rules; + var ruleCnt = rules ? rules.length : 0; + for (i = 0; i < ruleCnt; i++) { + if (rulesetNode.rules[i] instanceof tree.Extend) { + allSelectorsExtendList.push(rules[i]); + rulesetNode.extendOnEveryPath = true; + } } - - for (var i = 0; i < elementValue1.elements.length; i++) { - if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) { - if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) { - return false; + // now find every selector and apply the extends that apply to all extends + // and the ones which apply to an individual extend + var paths = rulesetNode.paths; + for (i = 0; i < paths.length; i++) { + var selectorPath = paths[i]; + var selector = selectorPath[selectorPath.length - 1]; + var selExtendList = selector.extendList; + extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) + : allSelectorsExtendList; + if (extendList) { + extendList = extendList.map(function (allSelectorsExtend) { return allSelectorsExtend.clone(); }); + } + for (j = 0; j < extendList.length; j++) { + this.foundExtends = true; + extend = extendList[j]; + extend.findSelfSelectors(selectorPath); + extend.ruleset = rulesetNode; + if (j === 0) { + extend.firstExtendOnThisSelectorPath = true; + } + this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); } - } - - if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) { - return false; - } } - - return true; - } - - return false; - } - }, { - key: "extendSelector", - value: function extendSelector(matches, selectorPath, replacementSelector, isVisible) { - // for a set of matches, replace each match with the replacement selector - var currentSelectorPathIndex = 0; - var currentSelectorPathElementIndex = 0; - var path = []; - var matchIndex; - var selector; - var firstElement; - var match; - var newElements; - - for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { - match = matches[matchIndex]; - selector = selectorPath[match.pathIndex]; - firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); - - if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + this.contexts.push(rulesetNode.selectors); + }; + ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) { + if (!rulesetNode.root) { + this.contexts.length = this.contexts.length - 1; } - - newElements = selector.elements.slice(currentSelectorPathElementIndex, match.index).concat([firstElement]).concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - path.push(new tree.Selector(newElements)); + }; + ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + mediaNode.allExtends = []; + this.allExtendsStack.push(mediaNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + atRuleNode.allExtends = []; + this.allExtendsStack.push(atRuleNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + return ExtendFinderVisitor; +}()); +var ProcessExtendsVisitor = /** @class */ (function () { + function ProcessExtendsVisitor() { + this._visitor = new Visitor(this); + } + ProcessExtendsVisitor.prototype.run = function (root) { + var extendFinder = new ExtendFinderVisitor(); + this.extendIndices = {}; + extendFinder.run(root); + if (!extendFinder.foundExtends) { + return root; + } + root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); + this.allExtendsStack = [root.allExtends]; + var newRoot = this._visitor.visit(root); + this.checkExtendsForNonMatched(root.allExtends); + return newRoot; + }; + ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) { + var indices = this.extendIndices; + extendList.filter(function (extend) { return !extend.hasFoundMatches && extend.parent_ids.length == 1; }).forEach(function (extend) { + var selector = '_unknown_'; + try { + selector = extend.selector.toCSS({}); + } + catch (_) { } + if (!indices[extend.index + " " + selector]) { + indices[extend.index + " " + selector] = true; + logger.warn("extend '" + selector + "' has no matches"); + } + }); + }; + ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) { + // + // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering + // and pasting the selector we would do normally, but we are also adding an extend with the same target selector + // this means this new extend can then go and alter other extends + // + // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors + // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already + // processed if we look at each selector at a time, as is done in visitRuleset + var extendIndex; + var targetExtendIndex; + var matches; + var extendsToAdd = []; + var newSelector; + var extendVisitor = this; + var selectorPath; + var extend; + var targetExtend; + var newExtend; + iterationCount = iterationCount || 0; + // loop through comparing every extend with every target extend. + // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place + // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one + // and the second is the target. + // the separation into two lists allows us to process a subset of chains with a bigger set, as is the + // case when processing media queries + for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { + for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { + extend = extendsList[extendIndex]; + targetExtend = extendsListTarget[targetExtendIndex]; + // look for circular references + if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { + continue; + } + // find a match in the target extends self selector (the bit before :extend) + selectorPath = [targetExtend.selfSelectors[0]]; + matches = extendVisitor.findMatch(extend, selectorPath); + if (matches.length) { + extend.hasFoundMatches = true; + // we found a match, so for each self selector.. + extend.selfSelectors.forEach(function (selfSelector) { + var info = targetExtend.visibilityInfo(); + // process the extend as usual + newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); + // but now we create a new extend from it + newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); + newExtend.selfSelectors = newSelector; + // add the extend onto the list of extends for that selector + newSelector[newSelector.length - 1].extendList = [newExtend]; + // record that we need to add it. + extendsToAdd.push(newExtend); + newExtend.ruleset = targetExtend.ruleset; + // remember its parents for circular references + newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); + // only process the selector once.. if we have :extend(.a,.b) then multiple + // extends will look at the same selector path, so when extending + // we know that any others will be duplicates in terms of what is added to the css + if (targetExtend.firstExtendOnThisSelectorPath) { + newExtend.firstExtendOnThisSelectorPath = true; + targetExtend.ruleset.paths.push(newSelector); + } + }); + } + } } - - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + if (extendsToAdd.length) { + // try to detect circular references to stop a stack overflow. + // may no longer be needed. + this.extendChainCount++; + if (iterationCount > 100) { + var selectorOne = '{unable to calculate}'; + var selectorTwo = '{unable to calculate}'; + try { + selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); + selectorTwo = extendsToAdd[0].selector.toCSS(); + } + catch (e) { } + throw { message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")" }; + } + // now process the new extends on the existing rules so that we can handle a extending b extending c extending + // d extending e... + return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - path = path.map(function (currentValue) { - // we can re-use elements here, because the visibility property matters only for selectors - var derived = currentValue.createDerived(currentValue.elements); - - if (isVisible) { - derived.ensureVisibility(); - } else { - derived.ensureInvisibility(); + else { + return extendsToAdd; } - - return derived; - }); - return path; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }]); - - return ProcessExtendsVisitor; -}(); - -var JoinSelectorVisitor = -/*#__PURE__*/ -function () { - function JoinSelectorVisitor() { - _classCallCheck(this, JoinSelectorVisitor); - - this.contexts = [[]]; - this._visitor = new Visitor(this); - } - - _createClass(JoinSelectorVisitor, [{ - key: "run", - value: function run(root) { - return this._visitor.visit(root); - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - var paths = []; - var selectors; - this.contexts.push(paths); - - if (!rulesetNode.root) { - selectors = rulesetNode.selectors; - - if (selectors) { - selectors = selectors.filter(function (selector) { - return selector.getIsOutput(); - }); - rulesetNode.selectors = selectors.length ? selectors : selectors = null; - - if (selectors) { - rulesetNode.joinSelectors(paths, context, selectors); - } + }; + ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - if (!selectors) { - rulesetNode.rules = null; + var matches; + var pathIndex; + var extendIndex; + var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; + var selectorsToAdd = []; + var extendVisitor = this; + var selectorPath; + // look at each selector path in the ruleset, find any extend matches and then copy, find and replace + for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { + for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { + selectorPath = rulesetNode.paths[pathIndex]; + // extending extends happens initially, before the main pass + if (rulesetNode.extendOnEveryPath) { + continue; + } + var extendList = selectorPath[selectorPath.length - 1].extendList; + if (extendList && extendList.length) { + continue; + } + matches = this.findMatch(allExtends[extendIndex], selectorPath); + if (matches.length) { + allExtends[extendIndex].hasFoundMatches = true; + allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { + var extendedSelectors; + extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); + selectorsToAdd.push(extendedSelectors); + }); + } + } } - - rulesetNode.paths = paths; - } - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - this.contexts.length = this.contexts.length - 1; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = context.length === 0 || context[0].multiMedia; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - - if (atRuleNode.rules && atRuleNode.rules.length) { - atRuleNode.rules[0].root = atRuleNode.isRooted || context.length === 0 || null; - } - } - }]); - - return JoinSelectorVisitor; -}(); - -var CSSVisitorUtils = -/*#__PURE__*/ -function () { - function CSSVisitorUtils(context) { - _classCallCheck(this, CSSVisitorUtils); - - this._visitor = new Visitor(this); - this._context = context; - } - - _createClass(CSSVisitorUtils, [{ - key: "containsSilentNonBlockedChild", - value: function containsSilentNonBlockedChild(bodyRules) { - var rule; - - if (!bodyRules) { - return false; - } - - for (var r = 0; r < bodyRules.length; r++) { - rule = bodyRules[r]; - - if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { - // the atrule contains something that was referenced (likely by extend) - // therefore it needs to be shown in output too - return true; + rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); + }; + ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) { + // + // look through the haystack selector path to try and find the needle - extend.selector + // returns an array of selector matches that can then be replaced + // + var haystackSelectorIndex; + var hackstackSelector; + var hackstackElementIndex; + var haystackElement; + var targetCombinator; + var i; + var extendVisitor = this; + var needleElements = extend.selector.elements; + var potentialMatches = []; + var potentialMatch; + var matches = []; + // loop through the haystack elements + for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { + hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; + for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { + haystackElement = hackstackSelector.elements[hackstackElementIndex]; + // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. + if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { + potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, + initialCombinator: haystackElement.combinator }); + } + for (i = 0; i < potentialMatches.length; i++) { + potentialMatch = potentialMatches[i]; + // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't + // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to + // work out what the resulting combinator will be + targetCombinator = haystackElement.combinator.value; + if (targetCombinator === '' && hackstackElementIndex === 0) { + targetCombinator = ' '; + } + // if we don't match, null our match to indicate failure + if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || + (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { + potentialMatch = null; + } + else { + potentialMatch.matched++; + } + // if we are still valid and have finished, test whether we have elements after and whether these are allowed + if (potentialMatch) { + potentialMatch.finished = potentialMatch.matched === needleElements.length; + if (potentialMatch.finished && + (!extend.allowAfter && + (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) { + potentialMatch = null; + } + } + // if null we remove, if not, we are still valid, so either push as a valid match or continue + if (potentialMatch) { + if (potentialMatch.finished) { + potentialMatch.length = needleElements.length; + potentialMatch.endPathIndex = haystackSelectorIndex; + potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match + potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again + matches.push(potentialMatch); + } + } + else { + potentialMatches.splice(i, 1); + i--; + } + } + } } - } - - return false; - } - }, { - key: "keepOnlyVisibleChilds", - value: function keepOnlyVisibleChilds(owner) { - if (owner && owner.rules) { - owner.rules = owner.rules.filter(function (thing) { - return thing.isVisible(); - }); - } - } - }, { - key: "isEmpty", - value: function isEmpty(owner) { - return owner && owner.rules ? owner.rules.length === 0 : true; - } - }, { - key: "hasVisibleSelector", - value: function hasVisibleSelector(rulesetNode) { - return rulesetNode && rulesetNode.paths ? rulesetNode.paths.length > 0 : false; - } - }, { - key: "resolveVisibility", - value: function resolveVisibility(node, originalRules) { - if (!node.blocksVisibility()) { - if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { - return; + return matches; + }; + ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) { + if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { + return elementValue1 === elementValue2; + } + if (elementValue1 instanceof tree.Attribute) { + if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { + return false; + } + if (!elementValue1.value || !elementValue2.value) { + if (elementValue1.value || elementValue2.value) { + return false; + } + return true; + } + elementValue1 = elementValue1.value.value || elementValue1.value; + elementValue2 = elementValue2.value.value || elementValue2.value; + return elementValue1 === elementValue2; + } + elementValue1 = elementValue1.value; + elementValue2 = elementValue2.value; + if (elementValue1 instanceof tree.Selector) { + if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { + return false; + } + for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) { + if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) { + if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) { + return false; + } + } + if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) { + return false; + } + } + return true; } - - return node; - } - - var compiledRulesBody = node.rules[0]; - this.keepOnlyVisibleChilds(compiledRulesBody); - - if (this.isEmpty(compiledRulesBody)) { - return; - } - - node.ensureVisibility(); - node.removeVisibilityBlock(); - return node; - } - }, { - key: "isVisibleRuleset", - value: function isVisibleRuleset(rulesetNode) { - if (rulesetNode.firstRoot) { - return true; - } - - if (this.isEmpty(rulesetNode)) { - return false; - } - - if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { return false; - } - - return true; - } - }]); - - return CSSVisitorUtils; -}(); - -var ToCSSVisitor = function ToCSSVisitor(context) { - this._visitor = new Visitor(this); - this._context = context; - this.utils = new CSSVisitorUtils(context); -}; - -ToCSSVisitor.prototype = { - isReplacing: true, - run: function run(root) { - return this._visitor.visit(root); - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.blocksVisibility() || declNode.variable) { - return; - } - - return declNode; - }, - visitMixinDefinition: function visitMixinDefinition(mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - }, - visitExtend: function visitExtend(extendNode, visitArgs) {}, - visitComment: function visitComment(commentNode, visitArgs) { - if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { - return; - } - - return commentNode; - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - var originalRules = mediaNode.rules[0].rules; - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - return this.utils.resolveVisibility(mediaNode, originalRules); - }, - visitImport: function visitImport(importNode, visitArgs) { - if (importNode.blocksVisibility()) { - return; - } - - return importNode; - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - if (atRuleNode.rules && atRuleNode.rules.length) { - return this.visitAtRuleWithBody(atRuleNode, visitArgs); - } else { - return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); - } - }, - visitAnonymous: function visitAnonymous(anonymousNode, visitArgs) { - if (!anonymousNode.blocksVisibility()) { - anonymousNode.accept(this._visitor); - return anonymousNode; - } - }, - visitAtRuleWithBody: function visitAtRuleWithBody(atRuleNode, visitArgs) { - // if there is only one nested ruleset and that one has no path, then it is - // just fake ruleset - function hasFakeRuleset(atRuleNode) { - var bodyRules = atRuleNode.rules; - return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); - } - - function getBodyRules(atRuleNode) { - var nodeRules = atRuleNode.rules; - - if (hasFakeRuleset(atRuleNode)) { - return nodeRules[0].rules; - } - - return nodeRules; - } // it is still true that it is only one ruleset in array - // this is last such moment - // process childs - - - var originalRules = getBodyRules(atRuleNode); - atRuleNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!this.utils.isEmpty(atRuleNode)) { - this._mergeRules(atRuleNode.rules[0].rules); - } - - return this.utils.resolveVisibility(atRuleNode, originalRules); - }, - visitAtRuleWithoutBody: function visitAtRuleWithoutBody(atRuleNode, visitArgs) { - if (atRuleNode.blocksVisibility()) { - return; - } - - if (atRuleNode.name === '@charset') { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset atrule would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (atRuleNode.debugInfo) { - var comment = new tree.Comment(`/* ${atRuleNode.toCSS(this._context).replace(/\n/g, '')} */\n`); - comment.debugInfo = atRuleNode.debugInfo; - return this._visitor.visit(comment); + }; + ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) { + // for a set of matches, replace each match with the replacement selector + var currentSelectorPathIndex = 0; + var currentSelectorPathElementIndex = 0; + var path = []; + var matchIndex; + var selector; + var firstElement; + var match; + var newElements; + for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { + match = matches[matchIndex]; + selector = selectorPath[match.pathIndex]; + firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); + if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + newElements = selector.elements + .slice(currentSelectorPathElementIndex, match.index) + .concat([firstElement]) + .concat(replacementSelector.elements.slice(1)); + if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { + path[path.length - 1].elements = + path[path.length - 1].elements.concat(newElements); + } + else { + path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); + path.push(new tree.Selector(newElements)); + } + currentSelectorPathIndex = match.endPathIndex; + currentSelectorPathElementIndex = match.endPathElementIndex; + if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } } + if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathIndex++; + } + path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); + path = path.map(function (currentValue) { + // we can re-use elements here, because the visibility property matters only for selectors + var derived = currentValue.createDerived(currentValue.elements); + if (isVisible) { + derived.ensureVisibility(); + } + else { + derived.ensureInvisibility(); + } + return derived; + }); + return path; + }; + ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + return ProcessExtendsVisitor; +}()); - return; - } - - this.charset = true; - } - - return atRuleNode; - }, - checkValidNodes: function checkValidNodes(rules, isRoot) { - if (!rules) { - return; +var JoinSelectorVisitor = /** @class */ (function () { + function JoinSelectorVisitor() { + this.contexts = [[]]; + this._visitor = new Visitor(this); } - - for (var i = 0; i < rules.length; i++) { - var ruleNode = rules[i]; - - if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { - throw { - message: 'Properties must be inside selector blocks. They cannot be in the root', - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode instanceof tree.Call) { - throw { - message: `Function '${ruleNode.name}' is undefined`, - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode.type && !ruleNode.allowRoot) { - throw { - message: `${ruleNode.type} node returned by a function is not valid here`, - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - } - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - // at this point rulesets are nested into each other - var rule; - var rulesets = []; - this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); - - if (!rulesetNode.root) { - // remove invisible paths - this._compileRulesetPaths(rulesetNode); // remove rulesets from this ruleset body and compile them separately - - - var nodeRules = rulesetNode.rules; - var nodeRuleCnt = nodeRules ? nodeRules.length : 0; - - for (var i = 0; i < nodeRuleCnt;) { - rule = nodeRules[i]; - - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; + JoinSelectorVisitor.prototype.run = function (root) { + return this._visitor.visit(root); + }; + JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + var paths = []; + var selectors; + this.contexts.push(paths); + if (!rulesetNode.root) { + selectors = rulesetNode.selectors; + if (selectors) { + selectors = selectors.filter(function (selector) { return selector.getIsOutput(); }); + rulesetNode.selectors = selectors.length ? selectors : (selectors = null); + if (selectors) { + rulesetNode.joinSelectors(paths, context, selectors); + } + } + if (!selectors) { + rulesetNode.rules = null; + } + rulesetNode.paths = paths; } + }; + JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) { + this.contexts.length = this.contexts.length - 1; + }; + JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); + }; + JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + if (atRuleNode.rules && atRuleNode.rules.length) { + atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null); + } + }; + return JoinSelectorVisitor; +}()); - i++; - } // accept the visitor to remove rules and refactor itself - // then we can decide nogw whether we want it or not - // compile body - - - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - - visitArgs.visitDeeper = false; - } else { - // if (! rulesetNode.root) { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - } - - if (rulesetNode.rules) { - this._mergeRules(rulesetNode.rules); - - this._removeDuplicateRules(rulesetNode.rules); - } // now decide whether we keep the ruleset - - - if (this.utils.isVisibleRuleset(rulesetNode)) { - rulesetNode.ensureVisibility(); - rulesets.splice(0, 0, rulesetNode); - } - - if (rulesets.length === 1) { - return rulesets[0]; +var CSSVisitorUtils = /** @class */ (function () { + function CSSVisitorUtils(context) { + this._visitor = new Visitor(this); + this._context = context; } - - return rulesets; - }, - _compileRulesetPaths: function _compileRulesetPaths(rulesetNode) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths.filter(function (p) { - var i; - - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new tree.Combinator(''); + CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) { + var rule; + if (!bodyRules) { + return false; } - - for (i = 0; i < p.length; i++) { - if (p[i].isVisible() && p[i].getIsOutput()) { - return true; - } + for (var r = 0; r < bodyRules.length; r++) { + rule = bodyRules[r]; + if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { + // the atrule contains something that was referenced (likely by extend) + // therefore it needs to be shown in output too + return true; + } } - return false; - }); - } - }, - _removeDuplicateRules: function _removeDuplicateRules(rules) { - if (!rules) { - return; - } // remove duplicates - - - var ruleCache = {}; - var ruleList; - var rule; - var i; - - for (i = rules.length - 1; i >= 0; i--) { - rule = rules[i]; - - if (rule instanceof tree.Declaration) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - - if (ruleList instanceof tree.Declaration) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; - } - - var ruleCSS = rule.toCSS(this._context); - - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } + }; + CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) { + if (owner && owner.rules) { + owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); }); } - } - } - }, - _mergeRules: function _mergeRules(rules) { - if (!rules) { - return; - } - - var groups = {}; - var groupsArr = []; - - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - - if (rule.merge) { - var key = rule.name; - groups[key] ? rules.splice(i--, 1) : groupsArr.push(groups[key] = []); - groups[key].push(rule); - } - } - - groupsArr.forEach(function (group) { - if (group.length > 0) { - var result = group[0]; - var space = []; - var comma = [new tree.Expression(space)]; - group.forEach(function (rule) { - if (rule.merge === '+' && space.length > 0) { - comma.push(new tree.Expression(space = [])); - } - - space.push(rule.value); - result.important = result.important || rule.important; - }); - result.value = new tree.Value(comma); - } - }); - } -}; - -var visitors = { - Visitor, - ImportVisitor, - MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, - ExtendVisitor: ProcessExtendsVisitor, - JoinSelectorVisitor, - ToCSSVisitor + }; + CSSVisitorUtils.prototype.isEmpty = function (owner) { + return (owner && owner.rules) + ? (owner.rules.length === 0) : true; + }; + CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) { + return (rulesetNode && rulesetNode.paths) + ? (rulesetNode.paths.length > 0) : false; + }; + CSSVisitorUtils.prototype.resolveVisibility = function (node, originalRules) { + if (!node.blocksVisibility()) { + if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { + return; + } + return node; + } + var compiledRulesBody = node.rules[0]; + this.keepOnlyVisibleChilds(compiledRulesBody); + if (this.isEmpty(compiledRulesBody)) { + return; + } + node.ensureVisibility(); + node.removeVisibilityBlock(); + return node; + }; + CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) { + if (rulesetNode.firstRoot) { + return true; + } + if (this.isEmpty(rulesetNode)) { + return false; + } + if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { + return false; + } + return true; + }; + return CSSVisitorUtils; +}()); +var ToCSSVisitor = function (context) { + this._visitor = new Visitor(this); + this._context = context; + this.utils = new CSSVisitorUtils(context); }; - -// Split the input into chunks. -var chunker = (function (input, fail) { - var len = input.length; - var level = 0; - var parenLevel = 0; - var lastOpening; - var lastOpeningParen; - var lastMultiComment; - var lastMultiCommentEndBrace; - var chunks = []; - var emitFrom = 0; - var chunkerCurrentIndex; - var currentChunkStartIndex; - var cc; - var cc2; - var matched; - - function emitChunk(force) { - var len = chunkerCurrentIndex - emitFrom; - - if (len < 512 && !force || !len) { - return; - } - - chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); - emitFrom = chunkerCurrentIndex + 1; - } - - for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc = input.charCodeAt(chunkerCurrentIndex); - - if (cc >= 97 && cc <= 122 || cc < 34) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: - // ( - parenLevel++; - lastOpeningParen = chunkerCurrentIndex; - continue; - - case 41: - // ) - if (--parenLevel < 0) { - return fail('missing opening `(`', chunkerCurrentIndex); +ToCSSVisitor.prototype = { + isReplacing: true, + run: function (root) { + return this._visitor.visit(root); + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.blocksVisibility() || declNode.variable) { + return; } - - continue; - - case 59: - // ; - if (!parenLevel) { - emitChunk(); + return declNode; + }, + visitMixinDefinition: function (mixinNode, visitArgs) { + // mixin definitions do not get eval'd - this means they keep state + // so we have to clear that state here so it isn't used if toCSS is called twice + mixinNode.frames = []; + }, + visitExtend: function (extendNode, visitArgs) { + }, + visitComment: function (commentNode, visitArgs) { + if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { + return; } - - continue; - - case 123: - // { - level++; - lastOpening = chunkerCurrentIndex; - continue; - - case 125: - // } - if (--level < 0) { - return fail('missing opening `{`', chunkerCurrentIndex); + return commentNode; + }, + visitMedia: function (mediaNode, visitArgs) { + var originalRules = mediaNode.rules[0].rules; + mediaNode.accept(this._visitor); + visitArgs.visitDeeper = false; + return this.utils.resolveVisibility(mediaNode, originalRules); + }, + visitImport: function (importNode, visitArgs) { + if (importNode.blocksVisibility()) { + return; } - - if (!level && !parenLevel) { - emitChunk(); + return importNode; + }, + visitAtRule: function (atRuleNode, visitArgs) { + if (atRuleNode.rules && atRuleNode.rules.length) { + return this.visitAtRuleWithBody(atRuleNode, visitArgs); } - - continue; - - case 92: - // \ - if (chunkerCurrentIndex < len - 1) { - chunkerCurrentIndex++; - continue; + else { + return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); } - - return fail('unescaped `\\`', chunkerCurrentIndex); - - case 34: - case 39: - case 96: - // ", ' and ` - matched = 0; - currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 > 96) { - continue; - } - - if (cc2 == cc) { - matched = 1; - break; - } - - if (cc2 == 92) { - // \ - if (chunkerCurrentIndex == len - 1) { - return fail('unescaped `\\`', chunkerCurrentIndex); + }, + visitAnonymous: function (anonymousNode, visitArgs) { + if (!anonymousNode.blocksVisibility()) { + anonymousNode.accept(this._visitor); + return anonymousNode; + } + }, + visitAtRuleWithBody: function (atRuleNode, visitArgs) { + // if there is only one nested ruleset and that one has no path, then it is + // just fake ruleset + function hasFakeRuleset(atRuleNode) { + var bodyRules = atRuleNode.rules; + return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); + } + function getBodyRules(atRuleNode) { + var nodeRules = atRuleNode.rules; + if (hasFakeRuleset(atRuleNode)) { + return nodeRules[0].rules; } - - chunkerCurrentIndex++; - } + return nodeRules; + } + // it is still true that it is only one ruleset in array + // this is last such moment + // process childs + var originalRules = getBodyRules(atRuleNode); + atRuleNode.accept(this._visitor); + visitArgs.visitDeeper = false; + if (!this.utils.isEmpty(atRuleNode)) { + this._mergeRules(atRuleNode.rules[0].rules); + } + return this.utils.resolveVisibility(atRuleNode, originalRules); + }, + visitAtRuleWithoutBody: function (atRuleNode, visitArgs) { + if (atRuleNode.blocksVisibility()) { + return; } - - if (matched) { - continue; + if (atRuleNode.name === '@charset') { + // Only output the debug info together with subsequent @charset definitions + // a comment (or @media statement) before the actual @charset atrule would + // be considered illegal css as it has to be on the first line + if (this.charset) { + if (atRuleNode.debugInfo) { + var comment = new tree.Comment("/* " + atRuleNode.toCSS(this._context).replace(/\n/g, '') + " */\n"); + comment.debugInfo = atRuleNode.debugInfo; + return this._visitor.visit(comment); + } + return; + } + this.charset = true; } - - return fail(`unmatched \`${String.fromCharCode(cc)}\``, currentChunkStartIndex); - - case 47: - // /, check for comment - if (parenLevel || chunkerCurrentIndex == len - 1) { - continue; + return atRuleNode; + }, + checkValidNodes: function (rules, isRoot) { + if (!rules) { + return; } - - cc2 = input.charCodeAt(chunkerCurrentIndex + 1); - - if (cc2 == 47) { - // //, find lnfeed - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 <= 13 && (cc2 == 10 || cc2 == 13)) { - break; + for (var i_1 = 0; i_1 < rules.length; i_1++) { + var ruleNode = rules[i_1]; + if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { + throw { message: 'Properties must be inside selector blocks. They cannot be in the root', + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 == 125) { - lastMultiCommentEndBrace = chunkerCurrentIndex; + if (ruleNode instanceof tree.Call) { + throw { message: "Function '" + ruleNode.name + "' is undefined", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - - if (cc2 != 42) { - continue; + if (ruleNode.type && !ruleNode.allowRoot) { + throw { message: ruleNode.type + " node returned by a function is not valid here", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - - if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - break; + } + }, + visitRuleset: function (rulesetNode, visitArgs) { + // at this point rulesets are nested into each other + var rule; + var rulesets = []; + this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); + if (!rulesetNode.root) { + // remove invisible paths + this._compileRulesetPaths(rulesetNode); + // remove rulesets from this ruleset body and compile them separately + var nodeRules = rulesetNode.rules; + var nodeRuleCnt = nodeRules ? nodeRules.length : 0; + for (var i_2 = 0; i_2 < nodeRuleCnt;) { + rule = nodeRules[i_2]; + if (rule && rule.rules) { + // visit because we are moving them out from being a child + rulesets.push(this._visitor.visit(rule)); + nodeRules.splice(i_2, 1); + nodeRuleCnt--; + continue; + } + i_2++; } - } - - if (chunkerCurrentIndex == len - 1) { - return fail('missing closing `*/`', currentChunkStartIndex); - } - - chunkerCurrentIndex++; + // accept the visitor to remove rules and refactor itself + // then we can decide nogw whether we want it or not + // compile body + if (nodeRuleCnt > 0) { + rulesetNode.accept(this._visitor); + } + else { + rulesetNode.rules = null; + } + visitArgs.visitDeeper = false; } - - continue; - - case 42: - // *, check for unmatched */ - if (chunkerCurrentIndex < len - 1 && input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - return fail('unmatched `/*`', chunkerCurrentIndex); + else { // if (! rulesetNode.root) { + rulesetNode.accept(this._visitor); + visitArgs.visitDeeper = false; } - - continue; - } - } - - if (level !== 0) { - if (lastMultiComment > lastOpening && lastMultiCommentEndBrace > lastMultiComment) { - return fail('missing closing `}` or `*/`', lastOpening); - } else { - return fail('missing closing `}`', lastOpening); - } - } else if (parenLevel !== 0) { - return fail('missing closing `)`', lastOpeningParen); - } - - emitChunk(true); - return chunks; -}); - -var getParserInput = (function () { - var // Less input string - input; - var // current chunk - j; - var // holds state for backtracking - saveStack = []; - var // furthest index the parser has gone to - furthest; - var // if this is furthest we got to, this is the probably cause - furthestPossibleErrorMessage; - var // chunkified input - chunks; - var // current chunk - current; - var // index of current chunk, in `input` - currentPos; - var parserInput = {}; - var CHARCODE_SPACE = 32; - var CHARCODE_TAB = 9; - var CHARCODE_LF = 10; - var CHARCODE_CR = 13; - var CHARCODE_PLUS = 43; - var CHARCODE_COMMA = 44; - var CHARCODE_FORWARD_SLASH = 47; - var CHARCODE_9 = 57; - - function skipWhitespace(length) { - var oldi = parserInput.i; - var oldj = j; - var curr = parserInput.i - currentPos; - var endIndex = parserInput.i + current.length - curr; - var mem = parserInput.i += length; - var inp = input; - var c; - var nextChar; - var comment; - - for (; parserInput.i < endIndex; parserInput.i++) { - c = inp.charCodeAt(parserInput.i); - - if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { - nextChar = inp.charAt(parserInput.i + 1); - - if (nextChar === '/') { - comment = { - index: parserInput.i, - isLineComment: true - }; - var nextNewLine = inp.indexOf('\n', parserInput.i + 2); - - if (nextNewLine < 0) { - nextNewLine = endIndex; - } - - parserInput.i = nextNewLine; - comment.text = inp.substr(comment.index, parserInput.i - comment.index); - parserInput.commentStore.push(comment); - continue; - } else if (nextChar === '*') { - var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); - - if (nextStarSlash >= 0) { - comment = { - index: parserInput.i, - text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), - isLineComment: false - }; - parserInput.i += comment.text.length - 1; - parserInput.commentStore.push(comment); - continue; - } + if (rulesetNode.rules) { + this._mergeRules(rulesetNode.rules); + this._removeDuplicateRules(rulesetNode.rules); } - - break; - } - - if (c !== CHARCODE_SPACE && c !== CHARCODE_LF && c !== CHARCODE_TAB && c !== CHARCODE_CR) { - break; - } - } - - current = current.slice(length + parserInput.i - mem + curr); - currentPos = parserInput.i; - - if (!current.length) { - if (j < chunks.length - 1) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - - return true; // things changed - } - - parserInput.finished = true; + // now decide whether we keep the ruleset + if (this.utils.isVisibleRuleset(rulesetNode)) { + rulesetNode.ensureVisibility(); + rulesets.splice(0, 0, rulesetNode); + } + if (rulesets.length === 1) { + return rulesets[0]; + } + return rulesets; + }, + _compileRulesetPaths: function (rulesetNode) { + if (rulesetNode.paths) { + rulesetNode.paths = rulesetNode.paths + .filter(function (p) { + var i; + if (p[0].elements[0].combinator.value === ' ') { + p[0].elements[0].combinator = new (tree.Combinator)(''); + } + for (i = 0; i < p.length; i++) { + if (p[i].isVisible() && p[i].getIsOutput()) { + return true; + } + } + return false; + }); + } + }, + _removeDuplicateRules: function (rules) { + if (!rules) { + return; + } + // remove duplicates + var ruleCache = {}; + var ruleList; + var rule; + var i; + for (i = rules.length - 1; i >= 0; i--) { + rule = rules[i]; + if (rule instanceof tree.Declaration) { + if (!ruleCache[rule.name]) { + ruleCache[rule.name] = rule; + } + else { + ruleList = ruleCache[rule.name]; + if (ruleList instanceof tree.Declaration) { + ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; + } + var ruleCSS = rule.toCSS(this._context); + if (ruleList.indexOf(ruleCSS) !== -1) { + rules.splice(i, 1); + } + else { + ruleList.push(ruleCSS); + } + } + } + } + }, + _mergeRules: function (rules) { + if (!rules) { + return; + } + var groups = {}; + var groupsArr = []; + for (var i_3 = 0; i_3 < rules.length; i_3++) { + var rule = rules[i_3]; + if (rule.merge) { + var key = rule.name; + groups[key] ? rules.splice(i_3--, 1) : + groupsArr.push(groups[key] = []); + groups[key].push(rule); + } + } + groupsArr.forEach(function (group) { + if (group.length > 0) { + var result_1 = group[0]; + var space_1 = []; + var comma_1 = [new tree.Expression(space_1)]; + group.forEach(function (rule) { + if ((rule.merge === '+') && (space_1.length > 0)) { + comma_1.push(new tree.Expression(space_1 = [])); + } + space_1.push(rule.value); + result_1.important = result_1.important || rule.important; + }); + result_1.value = new tree.Value(comma_1); + } + }); } +}; - return oldi !== parserInput.i || oldj !== j; - } - - parserInput.save = function () { - currentPos = parserInput.i; - saveStack.push({ - current, - i: parserInput.i, - j - }); - }; +var visitors = { + Visitor: Visitor, + ImportVisitor: ImportVisitor, + MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, + ExtendVisitor: ProcessExtendsVisitor, + JoinSelectorVisitor: JoinSelectorVisitor, + ToCSSVisitor: ToCSSVisitor +}; - parserInput.restore = function (possibleErrorMessage) { - if (parserInput.i > furthest || parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage) { - furthest = parserInput.i; - furthestPossibleErrorMessage = possibleErrorMessage; +// Split the input into chunks. +var chunker = (function (input, fail) { + var len = input.length; + var level = 0; + var parenLevel = 0; + var lastOpening; + var lastOpeningParen; + var lastMultiComment; + var lastMultiCommentEndBrace; + var chunks = []; + var emitFrom = 0; + var chunkerCurrentIndex; + var currentChunkStartIndex; + var cc; + var cc2; + var matched; + function emitChunk(force) { + var len = chunkerCurrentIndex - emitFrom; + if (((len < 512) && !force) || !len) { + return; + } + chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); + emitFrom = chunkerCurrentIndex + 1; } - - var state = saveStack.pop(); - current = state.current; - currentPos = parserInput.i = state.i; - j = state.j; - }; - - parserInput.forget = function () { - saveStack.pop(); - }; - - parserInput.isWhitespace = function (offset) { - var pos = parserInput.i + (offset || 0); - var code = input.charCodeAt(pos); - return code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF; - }; // Specialization of $(tok) - - - parserInput.$re = function (tok) { - if (parserInput.i > currentPos) { - current = current.slice(parserInput.i - currentPos); - currentPos = parserInput.i; + for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc = input.charCodeAt(chunkerCurrentIndex); + if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { + // a-z or whitespace + continue; + } + switch (cc) { + case 40: // ( + parenLevel++; + lastOpeningParen = chunkerCurrentIndex; + continue; + case 41: // ) + if (--parenLevel < 0) { + return fail('missing opening `(`', chunkerCurrentIndex); + } + continue; + case 59: // ; + if (!parenLevel) { + emitChunk(); + } + continue; + case 123: // { + level++; + lastOpening = chunkerCurrentIndex; + continue; + case 125: // } + if (--level < 0) { + return fail('missing opening `{`', chunkerCurrentIndex); + } + if (!level && !parenLevel) { + emitChunk(); + } + continue; + case 92: // \ + if (chunkerCurrentIndex < len - 1) { + chunkerCurrentIndex++; + continue; + } + return fail('unescaped `\\`', chunkerCurrentIndex); + case 34: + case 39: + case 96: // ", ' and ` + matched = 0; + currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 > 96) { + continue; + } + if (cc2 == cc) { + matched = 1; + break; + } + if (cc2 == 92) { // \ + if (chunkerCurrentIndex == len - 1) { + return fail('unescaped `\\`', chunkerCurrentIndex); + } + chunkerCurrentIndex++; + } + } + if (matched) { + continue; + } + return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); + case 47: // /, check for comment + if (parenLevel || (chunkerCurrentIndex == len - 1)) { + continue; + } + cc2 = input.charCodeAt(chunkerCurrentIndex + 1); + if (cc2 == 47) { + // //, find lnfeed + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { + break; + } + } + } + else if (cc2 == 42) { + // /*, find */ + lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 == 125) { + lastMultiCommentEndBrace = chunkerCurrentIndex; + } + if (cc2 != 42) { + continue; + } + if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { + break; + } + } + if (chunkerCurrentIndex == len - 1) { + return fail('missing closing `*/`', currentChunkStartIndex); + } + chunkerCurrentIndex++; + } + continue; + case 42: // *, check for unmatched */ + if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) { + return fail('unmatched `/*`', chunkerCurrentIndex); + } + continue; + } } - - var m = tok.exec(current); - - if (!m) { - return null; + if (level !== 0) { + if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { + return fail('missing closing `}` or `*/`', lastOpening); + } + else { + return fail('missing closing `}`', lastOpening); + } } - - skipWhitespace(m[0].length); - - if (typeof m === 'string') { - return m; + else if (parenLevel !== 0) { + return fail('missing closing `)`', lastOpeningParen); } + emitChunk(true); + return chunks; +}); - return m.length === 1 ? m[0] : m; - }; - - parserInput.$char = function (tok) { - if (input.charAt(parserInput.i) !== tok) { - return null; +var getParserInput = (function () { + var // Less input string + input; + var // current chunk + j; + var // holds state for backtracking + saveStack = []; + var // furthest index the parser has gone to + furthest; + var // if this is furthest we got to, this is the probably cause + furthestPossibleErrorMessage; + var // chunkified input + chunks; + var // current chunk + current; + var // index of current chunk, in `input` + currentPos; + var parserInput = {}; + var CHARCODE_SPACE = 32; + var CHARCODE_TAB = 9; + var CHARCODE_LF = 10; + var CHARCODE_CR = 13; + var CHARCODE_PLUS = 43; + var CHARCODE_COMMA = 44; + var CHARCODE_FORWARD_SLASH = 47; + var CHARCODE_9 = 57; + function skipWhitespace(length) { + var oldi = parserInput.i; + var oldj = j; + var curr = parserInput.i - currentPos; + var endIndex = parserInput.i + current.length - curr; + var mem = (parserInput.i += length); + var inp = input; + var c; + var nextChar; + var comment; + for (; parserInput.i < endIndex; parserInput.i++) { + c = inp.charCodeAt(parserInput.i); + if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { + nextChar = inp.charAt(parserInput.i + 1); + if (nextChar === '/') { + comment = { index: parserInput.i, isLineComment: true }; + var nextNewLine = inp.indexOf('\n', parserInput.i + 2); + if (nextNewLine < 0) { + nextNewLine = endIndex; + } + parserInput.i = nextNewLine; + comment.text = inp.substr(comment.index, parserInput.i - comment.index); + parserInput.commentStore.push(comment); + continue; + } + else if (nextChar === '*') { + var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); + if (nextStarSlash >= 0) { + comment = { + index: parserInput.i, + text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), + isLineComment: false + }; + parserInput.i += comment.text.length - 1; + parserInput.commentStore.push(comment); + continue; + } + } + break; + } + if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) { + break; + } + } + current = current.slice(length + parserInput.i - mem + curr); + currentPos = parserInput.i; + if (!current.length) { + if (j < chunks.length - 1) { + current = chunks[++j]; + skipWhitespace(0); // skip space at the beginning of a chunk + return true; // things changed + } + parserInput.finished = true; + } + return oldi !== parserInput.i || oldj !== j; } - - skipWhitespace(1); - return tok; - }; - - parserInput.$str = function (tok) { - var tokLength = tok.length; // https://jsperf.com/string-startswith/21 - - for (var i = 0; i < tokLength; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { + parserInput.save = function () { + currentPos = parserInput.i; + saveStack.push({ current: current, i: parserInput.i, j: j }); + }; + parserInput.restore = function (possibleErrorMessage) { + if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) { + furthest = parserInput.i; + furthestPossibleErrorMessage = possibleErrorMessage; + } + var state = saveStack.pop(); + current = state.current; + currentPos = parserInput.i = state.i; + j = state.j; + }; + parserInput.forget = function () { + saveStack.pop(); + }; + parserInput.isWhitespace = function (offset) { + var pos = parserInput.i + (offset || 0); + var code = input.charCodeAt(pos); + return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF); + }; + // Specialization of $(tok) + parserInput.$re = function (tok) { + if (parserInput.i > currentPos) { + current = current.slice(parserInput.i - currentPos); + currentPos = parserInput.i; + } + var m = tok.exec(current); + if (!m) { + return null; + } + skipWhitespace(m[0].length); + if (typeof m === 'string') { + return m; + } + return m.length === 1 ? m[0] : m; + }; + parserInput.$char = function (tok) { + if (input.charAt(parserInput.i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + }; + parserInput.$str = function (tok) { + var tokLength = tok.length; + // https://jsperf.com/string-startswith/21 + for (var i_1 = 0; i_1 < tokLength; i_1++) { + if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) { + return null; + } + } + skipWhitespace(tokLength); + return tok; + }; + parserInput.$quoted = function (loc) { + var pos = loc || parserInput.i; + var startChar = input.charAt(pos); + if (startChar !== '\'' && startChar !== '"') { + return; + } + var length = input.length; + var currentPosition = pos; + for (var i_2 = 1; i_2 + currentPosition < length; i_2++) { + var nextChar = input.charAt(i_2 + currentPosition); + switch (nextChar) { + case '\\': + i_2++; + continue; + case '\r': + case '\n': + break; + case startChar: + var str = input.substr(currentPosition, i_2 + 1); + if (!loc && loc !== 0) { + skipWhitespace(i_2 + 1); + return str; + } + return [startChar, str]; + } + } return null; - } - } - - skipWhitespace(tokLength); - return tok; - }; - - parserInput.$quoted = function (loc) { - var pos = loc || parserInput.i; - var startChar = input.charAt(pos); - - if (startChar !== '\'' && startChar !== '"') { - return; - } - - var length = input.length; - var currentPosition = pos; - - for (var i = 1; i + currentPosition < length; i++) { - var nextChar = input.charAt(i + currentPosition); - - switch (nextChar) { - case '\\': - i++; - continue; - - case '\r': - case '\n': - break; - - case startChar: - var str = input.substr(currentPosition, i + 1); - - if (!loc && loc !== 0) { - skipWhitespace(i + 1); - return str; - } - - return [startChar, str]; - - default: - } - } - - return null; - }; - /** - * Permissive parsing. Ignores everything except matching {} [] () and quotes - * until matching token (outside of blocks) - */ - - - parserInput.$parseUntil = function (tok) { - var quote = ''; - var returnVal = null; - var inComment = false; - var blockDepth = 0; - var blockStack = []; - var parseGroups = []; - var length = input.length; - var startPos = parserInput.i; - var lastPos = parserInput.i; - var i = parserInput.i; - var loop = true; - var testChar; - - if (typeof tok === 'string') { - testChar = function testChar(char) { - return char === tok; - }; - } else { - testChar = function testChar(char) { - return tok.test(char); - }; - } - - do { - var nextChar = input.charAt(i); - - if (blockDepth === 0 && testChar(nextChar)) { - returnVal = input.substr(lastPos, i - lastPos); - - if (returnVal) { - parseGroups.push(returnVal); - } else { - parseGroups.push(' '); + }; + /** + * Permissive parsing. Ignores everything except matching {} [] () and quotes + * until matching token (outside of blocks) + */ + parserInput.$parseUntil = function (tok) { + var quote = ''; + var returnVal = null; + var inComment = false; + var blockDepth = 0; + var blockStack = []; + var parseGroups = []; + var length = input.length; + var startPos = parserInput.i; + var lastPos = parserInput.i; + var i = parserInput.i; + var loop = true; + var testChar; + if (typeof tok === 'string') { + testChar = function (char) { return char === tok; }; } - - returnVal = parseGroups; - skipWhitespace(i - startPos); - loop = false; - } else { - if (inComment) { - if (nextChar === '*' && input.charAt(i + 1) === '/') { - i++; - blockDepth--; - inComment = false; - } - - i++; - continue; + else { + testChar = function (char) { return tok.test(char); }; } - - switch (nextChar) { - case '\\': - i++; - nextChar = input.charAt(i); - parseGroups.push(input.substr(lastPos, i - lastPos + 1)); - lastPos = i + 1; - break; - - case '/': - if (input.charAt(i + 1) === '*') { - i++; - inComment = true; - blockDepth++; + do { + var nextChar = input.charAt(i); + if (blockDepth === 0 && testChar(nextChar)) { + returnVal = input.substr(lastPos, i - lastPos); + if (returnVal) { + parseGroups.push(returnVal); + } + else { + parseGroups.push(' '); + } + returnVal = parseGroups; + skipWhitespace(i - startPos); + loop = false; } - - break; - - case '\'': - case '"': - quote = parserInput.$quoted(i); - - if (quote) { - parseGroups.push(input.substr(lastPos, i - lastPos), quote); - i += quote[1].length - 1; - lastPos = i + 1; - } else { - skipWhitespace(i - startPos); - returnVal = nextChar; - loop = false; + else { + if (inComment) { + if (nextChar === '*' && + input.charAt(i + 1) === '/') { + i++; + blockDepth--; + inComment = false; + } + i++; + continue; + } + switch (nextChar) { + case '\\': + i++; + nextChar = input.charAt(i); + parseGroups.push(input.substr(lastPos, i - lastPos + 1)); + lastPos = i + 1; + break; + case '/': + if (input.charAt(i + 1) === '*') { + i++; + inComment = true; + blockDepth++; + } + break; + case '\'': + case '"': + quote = parserInput.$quoted(i); + if (quote) { + parseGroups.push(input.substr(lastPos, i - lastPos), quote); + i += quote[1].length - 1; + lastPos = i + 1; + } + else { + skipWhitespace(i - startPos); + returnVal = nextChar; + loop = false; + } + break; + case '{': + blockStack.push('}'); + blockDepth++; + break; + case '(': + blockStack.push(')'); + blockDepth++; + break; + case '[': + blockStack.push(']'); + blockDepth++; + break; + case '}': + case ')': + case ']': + var expected = blockStack.pop(); + if (nextChar === expected) { + blockDepth--; + } + else { + // move the parser to the error and return expected + skipWhitespace(i - startPos); + returnVal = expected; + loop = false; + } + } + i++; + if (i > length) { + loop = false; + } } - - break; - - case '{': - blockStack.push('}'); - blockDepth++; - break; - - case '(': - blockStack.push(')'); - blockDepth++; - break; - - case '[': - blockStack.push(']'); - blockDepth++; - break; - - case '}': - case ')': - case ']': - var expected = blockStack.pop(); - - if (nextChar === expected) { - blockDepth--; - } else { - // move the parser to the error and return expected - skipWhitespace(i - startPos); - returnVal = expected; - loop = false; + } while (loop); + return returnVal ? returnVal : null; + }; + parserInput.autoCommentAbsorb = true; + parserInput.commentStore = []; + parserInput.finished = false; + // Same as $(), but don't change the state of the parser, + // just return the match. + parserInput.peek = function (tok) { + if (typeof tok === 'string') { + // https://jsperf.com/string-startswith/21 + for (var i_3 = 0; i_3 < tok.length; i_3++) { + if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) { + return false; + } } - + return true; } - - i++; - - if (i > length) { - loop = false; + else { + return tok.test(current); } - } - } while (loop); - - return returnVal ? returnVal : null; - }; - - parserInput.autoCommentAbsorb = true; - parserInput.commentStore = []; - parserInput.finished = false; // Same as $(), but don't change the state of the parser, - // just return the match. - - parserInput.peek = function (tok) { - if (typeof tok === 'string') { - // https://jsperf.com/string-startswith/21 - for (var i = 0; i < tok.length; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { - return false; - } - } - - return true; - } else { - return tok.test(current); - } - }; // Specialization of peek() - // TODO remove or change some currentChar calls to peekChar - - - parserInput.peekChar = function (tok) { - return input.charAt(parserInput.i) === tok; - }; - - parserInput.currentChar = function () { - return input.charAt(parserInput.i); - }; - - parserInput.prevChar = function () { - return input.charAt(parserInput.i - 1); - }; - - parserInput.getInput = function () { - return input; - }; - - parserInput.peekNotNumeric = function () { - var c = input.charCodeAt(parserInput.i); // Is the first char of the dimension 0-9, '.', '+' or '-' - - return c > CHARCODE_9 || c < CHARCODE_PLUS || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; - }; - - parserInput.start = function (str, chunkInput, failFunction) { - input = str; - parserInput.i = j = currentPos = furthest = 0; // chunking apparently makes things quicker (but my tests indicate - // it might actually make things slower in node at least) - // and it is a non-perfect parse - it can't recognise - // unquoted urls, meaning it can't distinguish comments - // meaning comments with quotes or {}() in them get 'counted' - // and then lead to parse errors. - // In addition if the chunking chunks in the wrong place we might - // not be able to parse a parser statement in one go - // this is officially deprecated but can be switched on via an option - // in the case it causes too much performance issues. - - if (chunkInput) { - chunks = chunker(str, failFunction); - } else { - chunks = [str]; - } - - current = chunks[0]; - skipWhitespace(0); - }; - - parserInput.end = function () { - var message; - var isFinished = parserInput.i >= input.length; - - if (parserInput.i < furthest) { - message = furthestPossibleErrorMessage; - parserInput.i = furthest; - } - - return { - isFinished, - furthest: parserInput.i, - furthestPossibleErrorMessage: message, - furthestReachedEnd: parserInput.i >= input.length - 1, - furthestChar: input[parserInput.i] }; - }; - - return parserInput; + // Specialization of peek() + // TODO remove or change some currentChar calls to peekChar + parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; }; + parserInput.currentChar = function () { return input.charAt(parserInput.i); }; + parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); }; + parserInput.getInput = function () { return input; }; + parserInput.peekNotNumeric = function () { + var c = input.charCodeAt(parserInput.i); + // Is the first char of the dimension 0-9, '.', '+' or '-' + return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; + }; + parserInput.start = function (str, chunkInput, failFunction) { + input = str; + parserInput.i = j = currentPos = furthest = 0; + // chunking apparently makes things quicker (but my tests indicate + // it might actually make things slower in node at least) + // and it is a non-perfect parse - it can't recognise + // unquoted urls, meaning it can't distinguish comments + // meaning comments with quotes or {}() in them get 'counted' + // and then lead to parse errors. + // In addition if the chunking chunks in the wrong place we might + // not be able to parse a parser statement in one go + // this is officially deprecated but can be switched on via an option + // in the case it causes too much performance issues. + if (chunkInput) { + chunks = chunker(str, failFunction); + } + else { + chunks = [str]; + } + current = chunks[0]; + skipWhitespace(0); + }; + parserInput.end = function () { + var message; + var isFinished = parserInput.i >= input.length; + if (parserInput.i < furthest) { + message = furthestPossibleErrorMessage; + parserInput.i = furthest; + } + return { + isFinished: isFinished, + furthest: parserInput.i, + furthestPossibleErrorMessage: message, + furthestReachedEnd: parserInput.i >= input.length - 1, + furthestChar: input[parserInput.i] + }; + }; + return parserInput; }); +// // less.js - parser // // A relatively straight-forward predictive parser. @@ -8766,4660 +6616,4002 @@ var getParserInput = (function () { // a terminal string or regexp, or a non-terminal function to call. // It also takes care of moving all the indices forwards. // - var Parser = function Parser(context, imports, fileInfo) { - var parsers; - var parserInput = getParserInput(); - - function error(msg, type) { - throw new LessError({ - index: parserInput.i, - filename: fileInfo.filename, - type: type || 'Syntax', - message: msg - }, imports); - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = arg instanceof Function ? arg.call(parsers) : parserInput.$re(arg); - - if (result) { - return result; - } - - error(msg || (typeof arg === 'string' ? `expected '${arg}' got '${parserInput.currentChar()}'` : 'unexpected token')); - } // Specialization of expect() - - - function expectChar(arg, msg) { - if (parserInput.$char(arg)) { - return arg; + var parsers; + var parserInput = getParserInput(); + function error(msg, type) { + throw new LessError({ + index: parserInput.i, + filename: fileInfo.filename, + type: type || 'Syntax', + message: msg + }, imports); } - - error(msg || `expected '${arg}' got '${parserInput.currentChar()}'`); - } - - function getDebugInfo(index) { - var filename = fileInfo.filename; - return { - lineNumber: getLocation(index, parserInput.getInput()).line + 1, - fileName: filename - }; - } - /** - * Used after initial parsing to create nodes on the fly - * - * @param {String} str - string to parse - * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] - * @param {Number} currentIndex - start number to begin indexing - * @param {Object} fileInfo - fileInfo to attach to created nodes - */ - - - function parseNode(str, parseList, currentIndex, fileInfo, callback) { - var result; - var returnNodes = []; - var parser = parserInput; - - try { - parser.start(str, false, function fail(msg, index) { - callback({ - message: msg, - index: index + currentIndex - }); - }); - - for (var x = 0, p, i; p = parseList[x]; x++) { - i = parser.i; - result = parsers[p](); - + function expect(arg, msg) { + // some older browsers return typeof 'function' for RegExp + var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg); if (result) { - try { - result._index = i + currentIndex; - result._fileInfo = fileInfo; - } catch (e) {} - - returnNodes.push(result); - } else { - returnNodes.push(null); + return result; } - } - - var endInfo = parser.end(); - - if (endInfo.isFinished) { - callback(null, returnNodes); - } else { - callback(true, null); - } - } catch (e) { - throw new LessError({ - index: e.index + currentIndex, - message: e.message - }, imports, fileInfo.filename); - } - } // - // The Parser - // - - - return { - parserInput, - imports, - fileInfo, - parseNode, + error(msg || (typeof arg === 'string' + ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'" + : 'unexpected token')); + } + // Specialization of expect() + function expectChar(arg, msg) { + if (parserInput.$char(arg)) { + return arg; + } + error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'"); + } + function getDebugInfo(index) { + var filename = fileInfo.filename; + return { + lineNumber: getLocation(index, parserInput.getInput()).line + 1, + fileName: filename + }; + } + /** + * Used after initial parsing to create nodes on the fly + * + * @param {String} str - string to parse + * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] + * @param {Number} currentIndex - start number to begin indexing + * @param {Object} fileInfo - fileInfo to attach to created nodes + */ + function parseNode(str, parseList, currentIndex, fileInfo, callback) { + var result; + var returnNodes = []; + var parser = parserInput; + try { + parser.start(str, false, function fail(msg, index) { + callback({ + message: msg, + index: index + currentIndex + }); + }); + for (var x = 0, p = void 0, i_1; (p = parseList[x]); x++) { + i_1 = parser.i; + result = parsers[p](); + if (result) { + try { + result._index = i_1 + currentIndex; + result._fileInfo = fileInfo; + } + catch (e) { } + returnNodes.push(result); + } + else { + returnNodes.push(null); + } + } + var endInfo = parser.end(); + if (endInfo.isFinished) { + callback(null, returnNodes); + } + else { + callback(true, null); + } + } + catch (e) { + throw new LessError({ + index: e.index + currentIndex, + message: e.message + }, imports, fileInfo.filename); + } + } // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply + // The Parser // - parse: function parse(str, callback, additionalData) { - var root; - var error = null; - var globalVars; - var modifyVars; - var ignored; - var preText = ''; - globalVars = additionalData && additionalData.globalVars ? `${Parser.serializeVars(additionalData.globalVars)}\n` : ''; - modifyVars = additionalData && additionalData.modifyVars ? `\n${Parser.serializeVars(additionalData.modifyVars)}` : ''; - - if (context.pluginManager) { - var preProcessors = context.pluginManager.getPreProcessors(); - - for (var i = 0; i < preProcessors.length; i++) { - str = preProcessors[i].process(str, { - context, - imports, - fileInfo - }); - } - } - - if (globalVars || additionalData && additionalData.banner) { - preText = (additionalData && additionalData.banner ? additionalData.banner : '') + globalVars; - ignored = imports.contentsIgnoredChars; - ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; - ignored[fileInfo.filename] += preText.length; - } - - str = str.replace(/\r\n?/g, '\n'); // Remove potential UTF Byte Order Mark - - str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - imports.contents[fileInfo.filename] = str; // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - - try { - parserInput.start(str, context.chunkInput, function fail(msg, index) { - throw new LessError({ - index, - type: 'Parse', - message: msg, - filename: fileInfo.filename - }, imports); - }); - tree.Node.prototype.parse = this; - root = new tree.Ruleset(null, this.parsers.primary()); - tree.Node.prototype.rootNode = root; - root.root = true; - root.firstRoot = true; - root.functionRegistry = functionRegistry.inherit(); - } catch (e) { - return callback(new LessError(e, imports, fileInfo.filename)); - } // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occurred. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - - - var endInfo = parserInput.end(); - - if (!endInfo.isFinished) { - var message = endInfo.furthestPossibleErrorMessage; - - if (!message) { - message = 'Unrecognised input'; - - if (endInfo.furthestChar === '}') { - message += '. Possibly missing opening \'{\''; - } else if (endInfo.furthestChar === ')') { - message += '. Possibly missing opening \'(\''; - } else if (endInfo.furthestReachedEnd) { - message += '. Possibly missing something'; - } - } - - error = new LessError({ - type: 'Parse', - message, - index: endInfo.furthest, - filename: fileInfo.filename - }, imports); - } - - var finish = function finish(e) { - e = error || e || imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new LessError(e, imports, fileInfo.filename); - } - - return callback(e); - } else { - return callback(null, root); - } - }; - - if (context.processImports !== false) { - new visitors.ImportVisitor(imports, finish).run(root); - } else { - return finish(); - } - }, - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Declaration -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Declaration ("color", Value ([Expression [Color #fff]])) - // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$re()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | declaration)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function primary() { - var mixin = this.mixin; - var root = []; - var node; - - while (true) { - while (true) { - node = this.comment(); - - if (!node) { - break; - } - - root.push(node); - } // always process comments before deciding if finished - - - if (parserInput.finished) { - break; - } - - if (parserInput.peek('}')) { - break; - } - - node = this.extendRule(); - - if (node) { - root = root.concat(node); - continue; - } - - node = mixin.definition() || this.declaration() || this.ruleset() || mixin.call(false, false) || this.variableCall() || this.entities.call() || this.atrule(); - - if (node) { - root.push(node); - } else { - var foundSemiColon = false; - - while (parserInput.$char(';')) { - foundSemiColon = true; - } - - if (!foundSemiColon) { - break; - } - } - } - - return root; - }, - // comments are collected by the main parsing mechanism and then assigned to nodes - // where the current structure allows it - comment: function comment() { - if (parserInput.commentStore.length) { - var comment = parserInput.commentStore.shift(); - return new tree.Comment(comment.text, comment.isLineComment, comment.index, fileInfo); - } - }, - // - // Entities are tokens which can be found inside an Expression - // - entities: { - mixinLookup: function mixinLookup() { - return parsers.mixin.call(true, true); - }, - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function quoted(forceEscaped) { - var str; - var index = parserInput.i; - var isEscaped = false; - parserInput.save(); - - if (parserInput.$char('~')) { - isEscaped = true; - } else if (forceEscaped) { - parserInput.restore(); - return; - } - - str = parserInput.$quoted(); - - if (!str) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return new tree.Quoted(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); - }, - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function keyword() { - var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); - - if (k) { - return tree.Color.fromKeyword(k) || new tree.Keyword(k); - } - }, - // - // A function call - // - // rgb(255, 0, 255) + return { + parserInput: parserInput, + imports: imports, + fileInfo: fileInfo, + parseNode: parseNode, // - // The arguments are parsed with the `entities.arguments` parser. + // Parse an input string into an abstract syntax tree, + // @param str A string containing 'less' markup + // @param callback call `callback` when done. + // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply // - call: function call() { - var name; - var args; - var func; - var index = parserInput.i; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (parserInput.peek(/^url\(/i)) { - return; - } - - parserInput.save(); - name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); - - if (!name) { - parserInput.forget(); - return; - } - - name = name[1]; - func = this.customFuncCall(name); - - if (func) { - args = func.parse(); - - if (args && func.stop) { - parserInput.forget(); - return args; + parse: function (str, callback, additionalData) { + var root; + var error = null; + var globalVars; + var modifyVars; + var ignored; + var preText = ''; + globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : ''; + modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : ''; + if (context.pluginManager) { + var preProcessors = context.pluginManager.getPreProcessors(); + for (var i_2 = 0; i_2 < preProcessors.length; i_2++) { + str = preProcessors[i_2].process(str, { context: context, imports: imports, fileInfo: fileInfo }); + } } - } - - args = this.arguments(args); - - if (!parserInput.$char(')')) { - parserInput.restore('Could not parse call arguments or missing \')\''); - return; - } - - parserInput.forget(); - return new tree.Call(name, args, index, fileInfo); - }, - // - // Parsing rules for functions with non-standard args, e.g.: - // - // boolean(not(2 > 1)) - // - // This is a quick prototype, to be modified/improved when - // more custom-parsed funcs come (e.g. `selector(...)`) - // - customFuncCall: function customFuncCall(name) { - /* Ideally the table is to be moved out of here for faster perf., - but it's quite tricky since it relies on all these `parsers` - and `expect` available only here */ - return { - alpha: f(parsers.ieAlpha, true), - boolean: f(condition), - 'if': f(condition) - }[name.toLowerCase()]; - - function f(parse, stop) { - return { - parse, - // parsing function - stop // when true - stop after parse() and return its result, - // otherwise continue for plain args - - }; - } - - function condition() { - return [expect(parsers.condition, 'expected condition')]; - } - }, - arguments: function _arguments(prevArgs) { - var argsComma = prevArgs || []; - var argsSemiColon = []; - var isSemiColonSeparated; - var value; - parserInput.save(); - - while (true) { - if (prevArgs) { - prevArgs = false; - } else { - value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); - - if (!value) { - break; - } - - if (value.value && value.value.length == 1) { - value = value.value[0]; - } - - argsComma.push(value); + if (globalVars || (additionalData && additionalData.banner)) { + preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars; + ignored = imports.contentsIgnoredChars; + ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; + ignored[fileInfo.filename] += preText.length; } - - if (parserInput.$char(',')) { - continue; + str = str.replace(/\r\n?/g, '\n'); + // Remove potential UTF Byte Order Mark + str = preText + str.replace(/^\uFEFF/, '') + modifyVars; + imports.contents[fileInfo.filename] = str; + // Start with the primary rule. + // The whole syntax tree is held under a Ruleset node, + // with the `root` property set to true, so no `{}` are + // output. The callback is called when the input is parsed. + try { + parserInput.start(str, context.chunkInput, function fail(msg, index) { + throw new LessError({ + index: index, + type: 'Parse', + message: msg, + filename: fileInfo.filename + }, imports); + }); + tree.Node.prototype.parse = this; + root = new tree.Ruleset(null, this.parsers.primary()); + tree.Node.prototype.rootNode = root; + root.root = true; + root.firstRoot = true; + root.functionRegistry = functionRegistry.inherit(); } - - if (parserInput.$char(';') || isSemiColonSeparated) { - isSemiColonSeparated = true; - value = argsComma.length < 1 ? argsComma[0] : new tree.Value(argsComma); - argsSemiColon.push(value); - argsComma = []; + catch (e) { + return callback(new LessError(e, imports, fileInfo.filename)); } - } - - parserInput.forget(); - return isSemiColonSeparated ? argsSemiColon : argsComma; - }, - literal: function literal() { - return this.dimension() || this.color() || this.quoted() || this.unicodeDescriptor(); - }, - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - assignment: function assignment() { - var key; - var value; - parserInput.save(); - key = parserInput.$re(/^\w+(?=\s?=)/i); - - if (!key) { - parserInput.restore(); - return; - } - - if (!parserInput.$char('=')) { - parserInput.restore(); - return; - } - - value = parsers.entity(); - - if (value) { - parserInput.forget(); - return new tree.Assignment(key, value); - } else { - parserInput.restore(); - } - }, - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function url() { - var value; - var index = parserInput.i; - parserInput.autoCommentAbsorb = false; - - if (!parserInput.$str('url(')) { - parserInput.autoCommentAbsorb = true; - return; - } - - value = this.quoted() || this.variable() || this.property() || parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; - parserInput.autoCommentAbsorb = true; - expectChar(')'); - return new tree.URL(value.value != null || value instanceof tree.Variable || value instanceof tree.Property ? value : new tree.Anonymous(value, index), index, fileInfo); - }, - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function variable() { - var ch; - var name; - var index = parserInput.i; - parserInput.save(); - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { - ch = parserInput.currentChar(); - - if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { - // this may be a VariableCall lookup - var result = parsers.variableCall(name); - - if (result) { - parserInput.forget(); - return result; - } + // If `i` is smaller than the `input.length - 1`, + // it means the parser wasn't able to parse the whole + // string, so we've got a parsing error. + // + // We try to extract a \n delimited string, + // showing the line where the parse error occurred. + // We split it up into two parts (the part which parsed, + // and the part which didn't), so we can color them differently. + var endInfo = parserInput.end(); + if (!endInfo.isFinished) { + var message = endInfo.furthestPossibleErrorMessage; + if (!message) { + message = 'Unrecognised input'; + if (endInfo.furthestChar === '}') { + message += '. Possibly missing opening \'{\''; + } + else if (endInfo.furthestChar === ')') { + message += '. Possibly missing opening \'(\''; + } + else if (endInfo.furthestReachedEnd) { + message += '. Possibly missing something'; + } + } + error = new LessError({ + type: 'Parse', + message: message, + index: endInfo.furthest, + filename: fileInfo.filename + }, imports); } - - parserInput.forget(); - return new tree.Variable(name, index, fileInfo); - } - - parserInput.restore(); - }, - // A variable entity using the protective {} e.g. @{var} - variableCurly: function variableCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { - return new tree.Variable(`@${curly[1]}`, index, fileInfo); - } - }, - // - // A Property accessor, such as `$color`, in - // - // background-color: $color - // - property: function property() { - var name; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { - return new tree.Property(name, index, fileInfo); - } - }, - // A property entity useing the protective {} e.g. ${prop} - propertyCurly: function propertyCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { - return new tree.Property(`$${curly[1]}`, index, fileInfo); - } - }, - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function color() { - var rgb; - parserInput.save(); - - if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { - if (!rgb[2]) { - parserInput.forget(); - return new tree.Color(rgb[1], undefined, rgb[0]); + var finish = function (e) { + e = error || e || imports.error; + if (e) { + if (!(e instanceof LessError)) { + e = new LessError(e, imports, fileInfo.filename); + } + return callback(e); + } + else { + return callback(null, root); + } + }; + if (context.processImports !== false) { + new visitors.ImportVisitor(imports, finish) + .run(root); + } + else { + return finish(); } - } - - parserInput.restore(); - }, - colorKeyword: function colorKeyword() { - parserInput.save(); - var autoCommentAbsorb = parserInput.autoCommentAbsorb; - parserInput.autoCommentAbsorb = false; - var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); - parserInput.autoCommentAbsorb = autoCommentAbsorb; - - if (!k) { - parserInput.forget(); - return; - } - - parserInput.restore(); - var color = tree.Color.fromKeyword(k); - - if (color) { - parserInput.$str(k); - return color; - } - }, - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function dimension() { - if (parserInput.peekNotNumeric()) { - return; - } - - var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); - - if (value) { - return new tree.Dimension(value[1], value[2]); - } - }, - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function unicodeDescriptor() { - var ud; - ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - - if (ud) { - return new tree.UnicodeDescriptor(ud[0]); - } }, // - // JavaScript code to be evaluated + // Here in, the parsing rules/functions // - // `window.location.href` + // The basic structure of the syntax tree generated is as follows: // - javascript: function javascript() { - var js; - var index = parserInput.i; - parserInput.save(); - var escape = parserInput.$char('~'); - var jsQuote = parserInput.$char('`'); - - if (!jsQuote) { - parserInput.restore(); - return; - } - - js = parserInput.$re(/^[^`]*`/); - - if (js) { - parserInput.forget(); - return new tree.JavaScript(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); - } - - parserInput.restore('invalid javascript definition'); - } - }, - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function variable() { - var name; - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { - return name[1]; - } - }, - // - // Call a variable value to retrieve a detached ruleset - // or a value from a detached ruleset's rules. - // - // @fink(); - // @fink; - // color: @fink[@color]; - // - variableCall: function variableCall(parsedName) { - var lookups; - var important; - var i = parserInput.i; - var inValue = !!parsedName; - var name = parsedName; - parserInput.save(); - - if (name || parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/))) { - lookups = this.mixin.ruleLookups(); - - if (!lookups && (inValue && parserInput.$str('()') !== '()' || name[2] !== '()')) { - parserInput.restore('Missing \'[...]\' lookup in variable call'); - return; - } - - if (!inValue) { - name = name[1]; - } - - if (lookups && parsers.important()) { - important = true; - } - - var call = new tree.VariableCall(name, i, fileInfo); - - if (!inValue && parsers.end()) { - parserInput.forget(); - return call; - } else { - parserInput.forget(); - return new tree.NamespaceValue(call, lookups, important, i, fileInfo); - } - } - - parserInput.restore(); - }, - // - // extend syntax - used to extend selectors - // - extend: function extend(isRule) { - var elements; - var e; - var index = parserInput.i; - var option; - var extendList; - var extend; - - if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { - return; - } - - do { - option = null; - elements = null; - - while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - - if (!e) { - break; - } - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - } - - option = option && option[1]; - - if (!elements) { - error('Missing target selector for :extend().'); - } - - extend = new tree.Extend(new tree.Selector(elements), option, index, fileInfo); - - if (extendList) { - extendList.push(extend); - } else { - extendList = [extend]; - } - } while (parserInput.$char(',')); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function extendRule() { - return this.extend(true); - }, - // - // Mixins - // - mixin: { + // Ruleset -> Declaration -> Value -> Expression -> Entity // - // A Mixin call, with an optional argument list + // Here's some Less code: // - // #mixins > .square(#fff); - // #mixins.square(#fff); - // .rounded(4px, black); - // .button; + // .class { + // color: #fff; + // border: 1px solid #000; + // width: @w + 4px; + // > .child {...} + // } // - // We can lookup / return a value using the lookup syntax: + // And here's what the parse tree might look like: // - // color: #mixin.square(#fff)[@color]; + // Ruleset (Selector '.class', [ + // Declaration ("color", Value ([Expression [Color #fff]])) + // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) + // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) + // Ruleset (Selector [Element '>', '.child'], [...]) + // ]) // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. + // In general, most rules will try to parse a token with the `$re()` function, and if the return + // value is truly, will return a new node, of the relevant type. Sometimes, we need to check + // first, before parsing, that's when we use `peek()`. // - call: function call(inValue, getLookup) { - var s = parserInput.currentChar(); - var important = false; - var lookups; - var index = parserInput.i; - var elements; - var args; - var hasParens; - - if (s !== '.' && s !== '#') { - return; - } - - parserInput.save(); // stop us absorbing part of an invalid selector - - elements = this.elements(); - - if (elements) { - if (parserInput.$char('(')) { - args = this.args(true).args; - expectChar(')'); - hasParens = true; - } - - if (getLookup !== false) { - lookups = this.ruleLookups(); - } - - if (getLookup === true && !lookups) { - parserInput.restore(); - return; - } - - if (inValue && !lookups && !hasParens) { - // This isn't a valid in-value mixin call - parserInput.restore(); - return; - } - - if (!inValue && parsers.important()) { - important = true; - } - - if (inValue || parsers.end()) { - parserInput.forget(); - var mixin = new tree.mixin.Call(elements, args, index, fileInfo, !lookups && important); - - if (lookups) { - return new tree.NamespaceValue(mixin, lookups, important); - } else { - return mixin; - } - } - } - - parserInput.restore(); - }, - - /** - * Matching elements for mixins - * (Start with . or # and can have > ) - */ - elements: function elements() { - var elements; - var e; - var c; - var elem; - var elemIndex; - var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; - - while (true) { - elemIndex = parserInput.i; - e = parserInput.$re(re); - - if (!e) { - break; - } - - elem = new tree.Element(c, e, false, elemIndex, fileInfo); - - if (elements) { - elements.push(elem); - } else { - elements = [elem]; - } - - c = parserInput.$char('>'); - } - - return elements; - }, - args: function args(isCall) { - var entities = parsers.entities; - var returner = { - args: null, - variadic: false - }; - var expressions = []; - var argsSemiColon = []; - var argsComma = []; - var isSemiColonSeparated; - var expressionContainsNamed; - var name; - var nameLoop; - var value; - var arg; - var expand; - var hasSep = true; - parserInput.save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parserInput.commentStore.length = 0; - - if (parserInput.$str('...')) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; + parsers: parsers = { + // + // The `primary` rule is the *entry* and *exit* point of the parser. + // The rules here can appear at any level of the parse tree. + // + // The recursive nature of the grammar is an interplay between the `block` + // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, + // as represented by this simplified grammar: + // + // primary → (ruleset | declaration)+ + // ruleset → selector+ block + // block → '{' primary '}' + // + // Only at one point is the primary rule not called from the + // block rule: at the root level. + // + primary: function () { + var mixin = this.mixin; + var root = []; + var node; + while (true) { + while (true) { + node = this.comment(); + if (!node) { + break; + } + root.push(node); + } + // always process comments before deciding if finished + if (parserInput.finished) { + break; + } + if (parserInput.peek('}')) { + break; + } + node = this.extendRule(); + if (node) { + root = root.concat(node); + continue; + } + node = mixin.definition() || this.declaration() || mixin.call(false, false) || + this.ruleset() || this.variableCall() || this.entities.call() || this.atrule(); + if (node) { + root.push(node); + } + else { + var foundSemiColon = false; + while (parserInput.$char(';')) { + foundSemiColon = true; + } + if (!foundSemiColon) { + break; + } + } } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - variadic: true - }); - break; - } - - arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); - } - - if (!arg || !hasSep) { - break; - } - - nameLoop = null; - - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { - if (parserInput.$char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeparated) { - error('Cannot mix ; and , as delimiter types'); - } - - expressionContainsNamed = true; + return root; + }, + // comments are collected by the main parsing mechanism and then assigned to nodes + // where the current structure allows it + comment: function () { + if (parserInput.commentStore.length) { + var comment = parserInput.commentStore.shift(); + return new (tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo); } - - value = parsers.detachedRuleset() || parsers.expression(); - - if (!value) { - if (isCall) { - error('could not understand value for named argument'); - } else { + }, + // + // Entities are tokens which can be found inside an Expression + // + entities: { + mixinLookup: function () { + return parsers.mixin.call(true, true); + }, + // + // A string, which supports escaping " and ' + // + // "milky way" 'he\'s the one!' + // + quoted: function (forceEscaped) { + var str; + var index = parserInput.i; + var isEscaped = false; + parserInput.save(); + if (parserInput.$char('~')) { + isEscaped = true; + } + else if (forceEscaped) { + parserInput.restore(); + return; + } + str = parserInput.$quoted(); + if (!str) { + parserInput.restore(); + return; + } + parserInput.forget(); + return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); + }, + // + // A catch-all word, such as: + // + // black border-collapse + // + keyword: function () { + var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); + if (k) { + return tree.Color.fromKeyword(k) || new (tree.Keyword)(k); + } + }, + // + // A function call + // + // rgb(255, 0, 255) + // + // The arguments are parsed with the `entities.arguments` parser. + // + call: function () { + var name; + var args; + var func; + var index = parserInput.i; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (parserInput.peek(/^url\(/i)) { + return; + } + parserInput.save(); + name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); + if (!name) { + parserInput.forget(); + return; + } + name = name[1]; + func = this.customFuncCall(name); + if (func) { + args = func.parse(); + if (args && func.stop) { + parserInput.forget(); + return args; + } + } + args = this.arguments(args); + if (!parserInput.$char(')')) { + parserInput.restore('Could not parse call arguments or missing \')\''); + return; + } + parserInput.forget(); + return new (tree.Call)(name, args, index, fileInfo); + }, + // + // Parsing rules for functions with non-standard args, e.g.: + // + // boolean(not(2 > 1)) + // + // This is a quick prototype, to be modified/improved when + // more custom-parsed funcs come (e.g. `selector(...)`) + // + customFuncCall: function (name) { + /* Ideally the table is to be moved out of here for faster perf., + but it's quite tricky since it relies on all these `parsers` + and `expect` available only here */ + return { + alpha: f(parsers.ieAlpha, true), + boolean: f(condition), + 'if': f(condition) + }[name.toLowerCase()]; + function f(parse, stop) { + return { + parse: parse, + stop: stop // when true - stop after parse() and return its result, + // otherwise continue for plain args + }; + } + function condition() { + return [expect(parsers.condition, 'expected condition')]; + } + }, + arguments: function (prevArgs) { + var argsComma = prevArgs || []; + var argsSemiColon = []; + var isSemiColonSeparated; + var value; + parserInput.save(); + while (true) { + if (prevArgs) { + prevArgs = false; + } + else { + value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); + if (!value) { + break; + } + if (value.value && value.value.length == 1) { + value = value.value[0]; + } + argsComma.push(value); + } + if (parserInput.$char(',')) { + continue; + } + if (parserInput.$char(';') || isSemiColonSeparated) { + isSemiColonSeparated = true; + value = (argsComma.length < 1) ? argsComma[0] + : new tree.Value(argsComma); + argsSemiColon.push(value); + argsComma = []; + } + } + parserInput.forget(); + return isSemiColonSeparated ? argsSemiColon : argsComma; + }, + literal: function () { + return this.dimension() || + this.color() || + this.quoted() || + this.unicodeDescriptor(); + }, + // Assignments are argument entities for calls. + // They are present in ie filter properties as shown below. + // + // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) + // + assignment: function () { + var key; + var value; + parserInput.save(); + key = parserInput.$re(/^\w+(?=\s?=)/i); + if (!key) { + parserInput.restore(); + return; + } + if (!parserInput.$char('=')) { + parserInput.restore(); + return; + } + value = parsers.entity(); + if (value) { + parserInput.forget(); + return new (tree.Assignment)(key, value); + } + else { + parserInput.restore(); + } + }, + // + // Parse url() tokens + // + // We use a specific rule for urls, because they don't really behave like + // standard function calls. The difference is that the argument doesn't have + // to be enclosed within a string, so it can't be parsed as an Expression. + // + url: function () { + var value; + var index = parserInput.i; + parserInput.autoCommentAbsorb = false; + if (!parserInput.$str('url(')) { + parserInput.autoCommentAbsorb = true; + return; + } + value = this.quoted() || this.variable() || this.property() || + parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; + parserInput.autoCommentAbsorb = true; + expectChar(')'); + return new (tree.URL)((value.value != null || + value instanceof tree.Variable || + value instanceof tree.Property) ? + value : new (tree.Anonymous)(value, index), index, fileInfo); + }, + // + // A Variable entity, such as `@fink`, in + // + // width: @fink + 2px + // + // We use a different parser for variable definitions, + // see `parsers.variable`. + // + variable: function () { + var ch; + var name; + var index = parserInput.i; + parserInput.save(); + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { + ch = parserInput.currentChar(); + if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { + // this may be a VariableCall lookup + var result = parsers.variableCall(name); + if (result) { + parserInput.forget(); + return result; + } + } + parserInput.forget(); + return new (tree.Variable)(name, index, fileInfo); + } + parserInput.restore(); + }, + // A variable entity using the protective {} e.g. @{var} + variableCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { + return new (tree.Variable)("@" + curly[1], index, fileInfo); + } + }, + // + // A Property accessor, such as `$color`, in + // + // background-color: $color + // + property: function () { + var name; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { + return new (tree.Property)(name, index, fileInfo); + } + }, + // A property entity useing the protective {} e.g. ${prop} + propertyCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { + return new (tree.Property)("$" + curly[1], index, fileInfo); + } + }, + // + // A Hexadecimal color + // + // #4F3C2F + // + // `rgb` and `hsl` colors are parsed through the `entities.call` parser. + // + color: function () { + var rgb; + parserInput.save(); + if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { + if (!rgb[2]) { + parserInput.forget(); + return new (tree.Color)(rgb[1], undefined, rgb[0]); + } + } + parserInput.restore(); + }, + colorKeyword: function () { + parserInput.save(); + var autoCommentAbsorb = parserInput.autoCommentAbsorb; + parserInput.autoCommentAbsorb = false; + var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); + parserInput.autoCommentAbsorb = autoCommentAbsorb; + if (!k) { + parserInput.forget(); + return; + } + parserInput.restore(); + var color = tree.Color.fromKeyword(k); + if (color) { + parserInput.$str(k); + return color; + } + }, + // + // A Dimension, that is, a number and a unit + // + // 0.5em 95% + // + dimension: function () { + if (parserInput.peekNotNumeric()) { + return; + } + var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); + if (value) { + return new (tree.Dimension)(value[1], value[2]); + } + }, + // + // A unicode descriptor, as is used in unicode-range + // + // U+0?? or U+00A1-00A9 + // + unicodeDescriptor: function () { + var ud; + ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + if (ud) { + return new (tree.UnicodeDescriptor)(ud[0]); + } + }, + // + // JavaScript code to be evaluated + // + // `window.location.href` + // + javascript: function () { + var js; + var index = parserInput.i; + parserInput.save(); + var escape = parserInput.$char('~'); + var jsQuote = parserInput.$char('`'); + if (!jsQuote) { + parserInput.restore(); + return; + } + js = parserInput.$re(/^[^`]*`/); + if (js) { + parserInput.forget(); + return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); + } + parserInput.restore('invalid javascript definition'); + } + }, + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink: + // + variable: function () { + var name; + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { + return name[1]; + } + }, + // + // Call a variable value to retrieve a detached ruleset + // or a value from a detached ruleset's rules. + // + // @fink(); + // @fink; + // color: @fink[@color]; + // + variableCall: function (parsedName) { + var lookups; + var i = parserInput.i; + var inValue = !!parsedName; + var name = parsedName; + parserInput.save(); + if (name || (parserInput.currentChar() === '@' + && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) { + lookups = this.mixin.ruleLookups(); + if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) { + parserInput.restore('Missing \'[...]\' lookup in variable call'); + return; + } + if (!inValue) { + name = name[1]; + } + var call = new tree.VariableCall(name, i, fileInfo); + if (!inValue && parsers.end()) { + parserInput.forget(); + return call; + } + else { + parserInput.forget(); + return new tree.NamespaceValue(call, lookups, i, fileInfo); + } + } + parserInput.restore(); + }, + // + // extend syntax - used to extend selectors + // + extend: function (isRule) { + var elements; + var e; + var index = parserInput.i; + var option; + var extendList; + var extend; + if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { + return; + } + do { + option = null; + elements = null; + while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { + e = this.element(); + if (!e) { + break; + } + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + } + option = option && option[1]; + if (!elements) { + error('Missing target selector for :extend().'); + } + extend = new (tree.Extend)(new (tree.Selector)(elements), option, index, fileInfo); + if (extendList) { + extendList.push(extend); + } + else { + extendList = [extend]; + } + } while (parserInput.$char(',')); + expect(/^\)/); + if (isRule) { + expect(/^;/); + } + return extendList; + }, + // + // extendRule - used in a rule to extend all the parent selectors + // + extendRule: function () { + return this.extend(true); + }, + // + // Mixins + // + mixin: { + // + // A Mixin call, with an optional argument list + // + // #mixins > .square(#fff); + // #mixins.square(#fff); + // .rounded(4px, black); + // .button; + // + // We can lookup / return a value using the lookup syntax: + // + // color: #mixin.square(#fff)[@color]; + // + // The `while` loop is there because mixins can be + // namespaced, but we only support the child and descendant + // selector for now. + // + call: function (inValue, getLookup) { + var s = parserInput.currentChar(); + var important = false; + var lookups; + var index = parserInput.i; + var elements; + var args; + var hasParens; + if (s !== '.' && s !== '#') { + return; + } + parserInput.save(); // stop us absorbing part of an invalid selector + elements = this.elements(); + if (elements) { + if (parserInput.$char('(')) { + args = this.args(true).args; + expectChar(')'); + hasParens = true; + } + if (getLookup !== false) { + lookups = this.ruleLookups(); + } + if (getLookup === true && !lookups) { + parserInput.restore(); + return; + } + if (inValue && !lookups && !hasParens) { + // This isn't a valid in-value mixin call + parserInput.restore(); + return; + } + if (!inValue && parsers.important()) { + important = true; + } + if (inValue || parsers.end()) { + parserInput.forget(); + var mixin = new (tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important); + if (lookups) { + return new tree.NamespaceValue(mixin, lookups); + } + else { + return mixin; + } + } + } parserInput.restore(); - returner.args = []; + }, + /** + * Matching elements for mixins + * (Start with . or # and can have > ) + */ + elements: function () { + var elements; + var e; + var c; + var elem; + var elemIndex; + var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; + while (true) { + elemIndex = parserInput.i; + e = parserInput.$re(re); + if (!e) { + break; + } + elem = new (tree.Element)(c, e, false, elemIndex, fileInfo); + if (elements) { + elements.push(elem); + } + else { + elements = [elem]; + } + c = parserInput.$char('>'); + } + return elements; + }, + args: function (isCall) { + var entities = parsers.entities; + var returner = { args: null, variadic: false }; + var expressions = []; + var argsSemiColon = []; + var argsComma = []; + var isSemiColonSeparated; + var expressionContainsNamed; + var name; + var nameLoop; + var value; + var arg; + var expand; + var hasSep = true; + parserInput.save(); + while (true) { + if (isCall) { + arg = parsers.detachedRuleset() || parsers.expression(); + } + else { + parserInput.commentStore.length = 0; + if (parserInput.$str('...')) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ variadic: true }); + break; + } + arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); + } + if (!arg || !hasSep) { + break; + } + nameLoop = null; + if (arg.throwAwayComments) { + arg.throwAwayComments(); + } + value = arg; + var val = null; + if (isCall) { + // Variable + if (arg.value && arg.value.length == 1) { + val = arg.value[0]; + } + } + else { + val = arg; + } + if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { + if (parserInput.$char(':')) { + if (expressions.length > 0) { + if (isSemiColonSeparated) { + error('Cannot mix ; and , as delimiter types'); + } + expressionContainsNamed = true; + } + value = parsers.detachedRuleset() || parsers.expression(); + if (!value) { + if (isCall) { + error('could not understand value for named argument'); + } + else { + parserInput.restore(); + returner.args = []; + return returner; + } + } + nameLoop = (name = val.name); + } + else if (parserInput.$str('...')) { + if (!isCall) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ name: arg.name, variadic: true }); + break; + } + else { + expand = true; + } + } + else if (!isCall) { + name = nameLoop = val.name; + value = null; + } + } + if (value) { + expressions.push(value); + } + argsComma.push({ name: nameLoop, value: value, expand: expand }); + if (parserInput.$char(',')) { + hasSep = true; + continue; + } + hasSep = parserInput.$char(';') === ';'; + if (hasSep || isSemiColonSeparated) { + if (expressionContainsNamed) { + error('Cannot mix ; and , as delimiter types'); + } + isSemiColonSeparated = true; + if (expressions.length > 1) { + value = new (tree.Value)(expressions); + } + argsSemiColon.push({ name: name, value: value, expand: expand }); + name = null; + expressions = []; + expressionContainsNamed = false; + } + } + parserInput.forget(); + returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; return returner; - } + }, + // + // A Mixin definition, with a list of parameters + // + // .rounded (@radius: 2px, @color) { + // ... + // } + // + // Until we have a finer grained state-machine, we have to + // do a look-ahead, to make sure we don't have a mixin call. + // See the `rule` function for more information. + // + // We start by matching `.rounded (`, and then proceed on to + // the argument list, which has optional default values. + // We store the parameters in `params`, with a `value` key, + // if there is a value, such as in the case of `@radius`. + // + // Once we've got our params list, and a closing `)`, we parse + // the `{...}` block. + // + definition: function () { + var name; + var params = []; + var match; + var ruleset; + var cond; + var variadic = false; + if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') || + parserInput.peek(/^[^{]*\}/)) { + return; + } + parserInput.save(); + match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); + if (match) { + name = match[1]; + var argInfo = this.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + // .mixincall("@{a}"); + // looks a bit like a mixin definition.. + // also + // .mixincall(@a: {rule: set;}); + // so we have to be nice and restore + if (!parserInput.$char(')')) { + parserInput.restore('Missing closing \')\''); + return; + } + parserInput.commentStore.length = 0; + if (parserInput.$str('when')) { // Guard + cond = expect(parsers.conditions, 'expected condition'); + } + ruleset = parsers.block(); + if (ruleset) { + parserInput.forget(); + return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + ruleLookups: function () { + var rule; + var lookups = []; + if (parserInput.currentChar() !== '[') { + return; + } + while (true) { + parserInput.save(); + rule = this.lookupValue(); + if (!rule && rule !== '') { + parserInput.restore(); + break; + } + lookups.push(rule); + parserInput.forget(); + } + if (lookups.length > 0) { + return lookups; + } + }, + lookupValue: function () { + parserInput.save(); + if (!parserInput.$char('[')) { + parserInput.restore(); + return; + } + var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); + if (!parserInput.$char(']')) { + parserInput.restore(); + return; + } + if (name || name === '') { + parserInput.forget(); + return name; + } + parserInput.restore(); } - - nameLoop = name = val.name; - } else if (parserInput.$str('...')) { - if (!isCall) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; - } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - name: arg.name, - variadic: true - }); - break; - } else { - expand = true; - } - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ - name: nameLoop, - value, - expand - }); - - if (parserInput.$char(',')) { - hasSep = true; - continue; - } - - hasSep = parserInput.$char(';') === ';'; - - if (hasSep || isSemiColonSeparated) { - if (expressionContainsNamed) { - error('Cannot mix ; and , as delimiter types'); - } - - isSemiColonSeparated = true; - - if (expressions.length > 1) { - value = new tree.Value(expressions); - } - - argsSemiColon.push({ - name, - value, - expand - }); - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - parserInput.forget(); - returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function definition() { - var name; - var params = []; - var match; - var ruleset; - var cond; - var variadic = false; - - if (parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#' || parserInput.peek(/^[^{]*\}/)) { - return; - } - - parserInput.save(); - match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - - if (match) { - name = match[1]; - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - - if (!parserInput.$char(')')) { - parserInput.restore('Missing closing \')\''); - return; - } - - parserInput.commentStore.length = 0; - - if (parserInput.$str('when')) { - // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - parserInput.forget(); - return new tree.mixin.Definition(name, params, ruleset, cond, variadic); - } else { - parserInput.restore(); - } - } else { - parserInput.forget(); - } - }, - ruleLookups: function ruleLookups() { - var rule; - var lookups = []; - - if (parserInput.currentChar() !== '[') { - return; - } - - while (true) { - parserInput.save(); - rule = this.lookupValue(); - - if (!rule && rule !== '') { - parserInput.restore(); - break; - } - - lookups.push(rule); - parserInput.forget(); - } - - if (lookups.length > 0) { - return lookups; - } - }, - lookupValue: function lookupValue() { - parserInput.save(); - - if (!parserInput.$char('[')) { - parserInput.restore(); - return; - } - - var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); - - if (!parserInput.$char(']')) { - parserInput.restore(); - return; - } - - if (name || name === '') { - parserInput.forget(); - return name; - } - - parserInput.restore(); - } - }, - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function entity() { - var entities = this.entities; - return this.comment() || entities.literal() || entities.variable() || entities.url() || entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || entities.javascript(); - }, - // - // A Declaration terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was omitted. - // - end: function end() { - return parserInput.$char(';') || parserInput.peek('}'); - }, - // - // IE's alpha function - // - // alpha(opacity=88) - // - ieAlpha: function ieAlpha() { - var value; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (!parserInput.$re(/^opacity=/i)) { - return; - } - - value = parserInput.$re(/^\d+/); - - if (!value) { - value = expect(parsers.entities.variable, 'Could not parse alpha'); - value = `@{${value.name.slice(1)}}`; - } - - expectChar(')'); - return new tree.Quoted('', `alpha(opacity=${value})`); - }, - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function element() { - var e; - var c; - var v; - var index = parserInput.i; - c = this.combinator(); - e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || this.entities.variableCurly(); - - if (!e) { - parserInput.save(); - - if (parserInput.$char('(')) { - if ((v = this.selector(false)) && parserInput.$char(')')) { - e = new tree.Paren(v); - parserInput.forget(); - } else { - parserInput.restore('Missing closing \')\''); - } - } else { - parserInput.forget(); - } - } - - if (e) { - return new tree.Element(c, e, e instanceof tree.Variable, index, fileInfo); - } - }, - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function combinator() { - var c = parserInput.currentChar(); - - if (c === '/') { - parserInput.save(); - var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); - - if (slashedCombinator) { - parserInput.forget(); - return new tree.Combinator(slashedCombinator); - } - - parserInput.restore(); - } - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - parserInput.i++; - - if (c === '^' && parserInput.currentChar() === '^') { - c = '^^'; - parserInput.i++; - } - - while (parserInput.isWhitespace()) { - parserInput.i++; - } - - return new tree.Combinator(c); - } else if (parserInput.isWhitespace(-1)) { - return new tree.Combinator(' '); - } else { - return new tree.Combinator(null); - } - }, - // - // A CSS Selector - // with less extensions e.g. the ability to extend and guard - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function selector(isLess) { - var index = parserInput.i; - var elements; - var extendList; - var c; - var e; - var allExtends; - var when; - var condition; - isLess = isLess !== false; - - while (isLess && (extendList = this.extend()) || isLess && (when = parserInput.$str('when')) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error('CSS guard can only be used at the end of selector'); - } else if (extendList) { - if (allExtends) { - allExtends = allExtends.concat(extendList); - } else { - allExtends = extendList; - } - } else { - if (allExtends) { - error('Extend can only be used at the end of selector'); - } - - c = parserInput.currentChar(); - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - - e = null; - } - - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { - return new tree.Selector(elements, allExtends, condition, index, fileInfo); - } - - if (allExtends) { - error('Extend must be used to extend a selector, it cannot be used on its own'); - } - }, - selectors: function selectors() { - var s; - var selectors; - - while (true) { - s = this.selector(); - - if (!s) { - break; - } - - if (selectors) { - selectors.push(s); - } else { - selectors = [s]; - } - - parserInput.commentStore.length = 0; - - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - - if (!parserInput.$char(',')) { - break; - } - - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - - parserInput.commentStore.length = 0; - } - - return selectors; - }, - attribute: function attribute() { - if (!parserInput.$char('[')) { - return; - } - - var entities = this.entities; - var key; - var val; - var op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = parserInput.$re(/^[|~*$^]?=/); - - if (op) { - val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - return new tree.Attribute(key, op, val); - }, - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function block() { - var content; - - if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { - return content; - } - }, - blockRuleset: function blockRuleset() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - - return block; - }, - detachedRuleset: function detachedRuleset() { - var argInfo; - var params; - var variadic; - parserInput.save(); - - if (parserInput.$re(/^[.#]\(/)) { - /** - * DR args currently only implemented for each() function, and not - * yet settable as `@dr: #(@arg) {}` - * This should be done when DRs are merged with mixins. - * See: https://github.com/less/less-meta/issues/16 - */ - argInfo = this.mixin.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - } - - var blockRuleset = this.blockRuleset(); - - if (blockRuleset) { - parserInput.forget(); - - if (params) { - return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); - } - - return new tree.DetachedRuleset(blockRuleset); - } - - parserInput.restore(); - }, - // - // div, .class, body > p {...} - // - ruleset: function ruleset() { - var selectors; - var rules; - var debugInfo; - parserInput.save(); - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(parserInput.i); - } - - selectors = this.selectors(); - - if (selectors && (rules = this.block())) { - parserInput.forget(); - var ruleset = new tree.Ruleset(selectors, rules, context.strictImports); - - if (context.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - - return ruleset; - } else { - parserInput.restore(); - } - }, - declaration: function declaration() { - var name; - var value; - var index = parserInput.i; - var hasDR; - var c = parserInput.currentChar(); - var important; - var merge; - var isVariable; - - if (c === '.' || c === '#' || c === '&' || c === ':') { - return; - } - - parserInput.save(); - name = this.variable() || this.ruleProperty(); - - if (name) { - isVariable = typeof name === 'string'; - - if (isVariable) { - value = this.detachedRuleset(); - - if (value) { - hasDR = true; - } - } - - parserInput.commentStore.length = 0; - - if (!value) { - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.length > 1 && name.pop().value; // Custom property values get permissive parsing - - if (name[0].value && name[0].value.slice(0, 2) === '--') { - value = this.permissiveValue(); - } // Try to store values as anonymous - // If we need the value later we'll re-parse it in ruleset.parseValue - else { - value = this.anonymousValue(); - } - - if (value) { - parserInput.forget(); // anonymous values absorb the end ';' which is required for them to work - - return new tree.Declaration(name, value, false, merge, index, fileInfo); - } - - if (!value) { - value = this.value(); - } - - if (value) { - important = this.important(); - } else if (isVariable) { - // As a last resort, try permissiveValue - value = this.permissiveValue(); - } - } - - if (value && (this.end() || hasDR)) { - parserInput.forget(); - return new tree.Declaration(name, value, important, merge, index, fileInfo); - } else { - parserInput.restore(); - } - } else { - parserInput.restore(); - } - }, - anonymousValue: function anonymousValue() { - var index = parserInput.i; - var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); - - if (match) { - return new tree.Anonymous(match[1], index); - } - }, - - /** - * Used for custom properties, at-rules, and variables (as fallback) - * Parses almost anything inside of {} [] () "" blocks - * until it reaches outer-most tokens. - * - * First, it will try to parse comments and entities to reach - * the end. This is mostly like the Expression parser except no - * math is allowed. - */ - permissiveValue: function permissiveValue(untilTokens) { - var i; - var e; - var done; - var value; - var tok = untilTokens || ';'; - var index = parserInput.i; - var result = []; - - function testCurrentChar() { - var char = parserInput.currentChar(); - - if (typeof tok === 'string') { - return char === tok; - } else { - return tok.test(char); - } - } - - if (testCurrentChar()) { - return; - } - - value = []; - - do { - e = this.comment(); - - if (e) { - value.push(e); - continue; - } - - e = this.entity(); - - if (e) { - value.push(e); - } - } while (e); - - done = testCurrentChar(); - - if (value.length > 0) { - value = new tree.Expression(value); - - if (done) { - return value; - } else { - result.push(value); - } // Preserve space before $parseUntil as it will not - - - if (parserInput.prevChar() === ' ') { - result.push(new tree.Anonymous(' ', index)); - } - } - - parserInput.save(); - value = parserInput.$parseUntil(tok); - - if (value) { - if (typeof value === 'string') { - error(`Expected '${value}'`, 'Parse'); - } - - if (value.length === 1 && value[0] === ' ') { - parserInput.forget(); - return new tree.Anonymous('', index); - } - - var item; - - for (i = 0; i < value.length; i++) { - item = value[i]; - - if (Array.isArray(item)) { - // Treat actual quotes as normal quoted values - result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); - } else { - if (i === value.length - 1) { - item = item.trim(); - } // Treat like quoted values, but replace vars like unquoted expressions - - - var quote = new tree.Quoted('\'', item, true, index, fileInfo); - quote.variableRegex = /@([\w-]+)/g; - quote.propRegex = /\$([\w-]+)/g; - result.push(quote); - } - } - - parserInput.forget(); - return new tree.Expression(result, true); - } - - parserInput.restore(); - }, - // - // An @import atrule - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - 'import': function _import() { - var path; - var features; - var index = parserInput.i; - var dir = parserInput.$re(/^@import?\s+/); - - if (dir) { - var options = (dir ? this.importOptions() : null) || {}; - - if (path = this.entities.quoted() || this.entities.url()) { - features = this.mediaFeatures(); - - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon or unrecognised media features on import'); - } - - features = features && new tree.Value(features); - return new tree.Import(path, features, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed import statement'); - } - } - }, - importOptions: function importOptions() { - var o; - var options = {}; - var optionName; - var value; // list of options, surrounded by parens - - if (!parserInput.$char('(')) { - return null; - } - - do { - o = this.importOption(); - - if (o) { - optionName = o; - value = true; - - switch (optionName) { - case 'css': - optionName = 'less'; - value = false; - break; - - case 'once': - optionName = 'multiple'; - value = false; - break; - } - - options[optionName] = value; - - if (!parserInput.$char(',')) { - break; - } - } - } while (o); - - expectChar(')'); - return options; - }, - importOption: function importOption() { - var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); - - if (opt) { - return opt[1]; - } - }, - mediaFeature: function mediaFeature() { - var entities = this.entities; - var nodes = []; - var e; - var p; - parserInput.save(); - - do { - e = entities.keyword() || entities.variable() || entities.mixinLookup(); - - if (e) { - nodes.push(e); - } else if (parserInput.$char('(')) { - p = this.property(); - e = this.value(); - - if (parserInput.$char(')')) { - if (p && e) { - nodes.push(new tree.Paren(new tree.Declaration(p, e, null, null, parserInput.i, fileInfo, true))); - } else if (e) { - nodes.push(new tree.Paren(e)); - } else { - error('badly formed media feature definition'); - } - } else { - error('Missing closing \')\'', 'Parse'); - } - } - } while (e); - - parserInput.forget(); - - if (nodes.length > 0) { - return new tree.Expression(nodes); - } - }, - mediaFeatures: function mediaFeatures() { - var entities = this.entities; - var features = []; - var e; - - do { - e = this.mediaFeature(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } else { - e = entities.variable() || entities.mixinLookup(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - media: function media() { - var features; - var rules; - var media; - var debugInfo; - var index = parserInput.i; - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(index); - } - - parserInput.save(); - - if (parserInput.$str('@media')) { - features = this.mediaFeatures(); - rules = this.block(); - - if (!rules) { - error('media definitions require block statements after any features'); - } - - parserInput.forget(); - media = new tree.Media(rules, features, index, fileInfo); - - if (context.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - - return media; - } - - parserInput.restore(); - }, - // - // A @plugin directive, used to import plugins dynamically. - // - // @plugin (args) "lib"; - // - plugin: function plugin() { - var path; - var args; - var options; - var index = parserInput.i; - var dir = parserInput.$re(/^@plugin?\s+/); - - if (dir) { - args = this.pluginArgs(); - - if (args) { - options = { - pluginArgs: args, - isPlugin: true - }; - } else { - options = { - isPlugin: true - }; - } - - if (path = this.entities.quoted() || this.entities.url()) { - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon on @plugin'); - } - - return new tree.Import(path, null, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed @plugin statement'); - } - } - }, - pluginArgs: function pluginArgs() { - // list of options, surrounded by parens - parserInput.save(); - - if (!parserInput.$char('(')) { - parserInput.restore(); - return null; - } - - var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); - - if (args[1]) { - parserInput.forget(); - return args[1].trim(); - } else { - parserInput.restore(); - return null; - } - }, - // - // A CSS AtRule - // - // @charset "utf-8"; - // - atrule: function atrule() { - var index = parserInput.i; - var name; - var value; - var rules; - var nonVendorSpecificName; - var hasIdentifier; - var hasExpression; - var hasUnknown; - var hasBlock = true; - var isRooted = true; - - if (parserInput.currentChar() !== '@') { - return; - } - - value = this['import']() || this.plugin() || this.media(); - - if (value) { - return value; - } - - parserInput.save(); - name = parserInput.$re(/^@[a-z-]+/); - - if (!name) { - return; - } - - nonVendorSpecificName = name; - - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = `@${name.slice(name.indexOf('-', 2) + 1)}`; - } - - switch (nonVendorSpecificName) { - case '@charset': - hasIdentifier = true; - hasBlock = false; - break; - - case '@namespace': - hasExpression = true; - hasBlock = false; - break; - - case '@keyframes': - case '@counter-style': - hasIdentifier = true; - break; - - case '@document': - case '@supports': - hasUnknown = true; - isRooted = false; - break; - - default: - hasUnknown = true; - break; - } - - parserInput.commentStore.length = 0; - - if (hasIdentifier) { - value = this.entity(); - - if (!value) { - error(`expected ${name} identifier`); - } - } else if (hasExpression) { - value = this.expression(); - - if (!value) { - error(`expected ${name} expression`); - } - } else if (hasUnknown) { - value = this.permissiveValue(/^[{;]/); - hasBlock = parserInput.currentChar() === '{'; - - if (!value) { - if (!hasBlock && parserInput.currentChar() !== ';') { - error(`${name} rule is missing block or ending semi-colon`); - } - } else if (!value.value) { - value = null; - } - } - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || !hasBlock && value && parserInput.$char(';')) { - parserInput.forget(); - return new tree.AtRule(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); - } - - parserInput.restore('at-rule options not recognised'); - }, - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function value() { - var e; - var expressions = []; - var index = parserInput.i; - - do { - e = this.expression(); - - if (e) { - expressions.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } while (e); - - if (expressions.length > 0) { - return new tree.Value(expressions, index); - } - }, - important: function important() { - if (parserInput.currentChar() === '!') { - return parserInput.$re(/^! *important/); - } - }, - sub: function sub() { - var a; - var e; - parserInput.save(); - - if (parserInput.$char('(')) { - a = this.addition(); - - if (a && parserInput.$char(')')) { - parserInput.forget(); - e = new tree.Expression([a]); - e.parens = true; - return e; - } - - parserInput.restore('Expected \')\''); - return; - } - - parserInput.restore(); - }, - multiplication: function multiplication() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.operand(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - if (parserInput.peek(/^\/[*\/]/)) { - break; - } - - parserInput.save(); - op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); - - if (!op) { - parserInput.forget(); - break; - } - - a = this.operand(); - - if (!a) { - parserInput.restore(); - break; - } - - parserInput.forget(); - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - addition: function addition() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.multiplication(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - op = parserInput.$re(/^[-+]\s+/) || !isSpaced && (parserInput.$char('+') || parserInput.$char('-')); - - if (!op) { - break; - } - - a = this.multiplication(); - - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - conditions: function conditions() { - var a; - var b; - var index = parserInput.i; - var condition; - a = this.condition(true); - - if (a) { - while (true) { - if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { - break; - } - - b = this.condition(true); - - if (!b) { - break; - } - - condition = new tree.Condition('or', condition || a, b, index); - } - - return condition || a; - } - }, - condition: function condition(needsParens) { - var result; - var logical; - var next; - - function or() { - return parserInput.$str('or'); - } - - result = this.conditionAnd(needsParens); - - if (!result) { - return; - } - - logical = or(); - - if (logical) { - next = this.condition(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - conditionAnd: function conditionAnd(needsParens) { - var result; - var logical; - var next; - var self = this; - - function insideCondition() { - var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); - - if (!cond && !needsParens) { - return self.atomicCondition(needsParens); - } - - return cond; - } - - function and() { - return parserInput.$str('and'); - } - - result = insideCondition(); - - if (!result) { - return; - } - - logical = and(); - - if (logical) { - next = this.conditionAnd(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - negatedCondition: function negatedCondition(needsParens) { - if (parserInput.$str('not')) { - var result = this.parenthesisCondition(needsParens); - - if (result) { - result.negate = !result.negate; - } - - return result; - } - }, - parenthesisCondition: function parenthesisCondition(needsParens) { - function tryConditionFollowedByParenthesis(me) { - var body; - parserInput.save(); - body = me.condition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return body; - } - - var body; - parserInput.save(); - - if (!parserInput.$str('(')) { - parserInput.restore(); - return; - } - - body = tryConditionFollowedByParenthesis(this); - - if (body) { - parserInput.forget(); - return body; - } - - body = this.atomicCondition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore(`expected ')' got '${parserInput.currentChar()}'`); - return; - } - - parserInput.forget(); - return body; - }, - atomicCondition: function atomicCondition(needsParens) { - var entities = this.entities; - var index = parserInput.i; - var a; - var b; - var c; - var op; - - function cond() { - return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); - } - - cond = cond.bind(this); - a = cond(); - - if (a) { - if (parserInput.$char('>')) { - if (parserInput.$char('=')) { - op = '>='; - } else { - op = '>'; - } - } else if (parserInput.$char('<')) { - if (parserInput.$char('=')) { - op = '<='; - } else { - op = '<'; - } - } else if (parserInput.$char('=')) { - if (parserInput.$char('>')) { - op = '=>'; - } else if (parserInput.$char('<')) { - op = '=<'; - } else { - op = '='; - } - } - - if (op) { - b = cond(); - - if (b) { - c = new tree.Condition(op, a, b, index, false); - } else { - error('expected expression'); - } - } else { - c = new tree.Condition('=', a, new tree.Keyword('true'), index, false); - } - - return c; - } - }, - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function operand() { - var entities = this.entities; - var negate; - - if (parserInput.peek(/^-[@\$\(]/)) { - negate = parserInput.$char('-'); - } - - var o = this.sub() || entities.dimension() || entities.color() || entities.variable() || entities.property() || entities.call() || entities.quoted(true) || entities.colorKeyword() || entities.mixinLookup(); - - if (negate) { - o.parensInOp = true; - o = new tree.Negative(o); - } - - return o; - }, - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function expression() { - var entities = []; - var e; - var delim; - var index = parserInput.i; - - do { - e = this.comment(); - - if (e) { - entities.push(e); - continue; - } - - e = this.addition() || this.entity(); - - if (e) { - entities.push(e); // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - - if (!parserInput.peek(/^\/[\/*]/)) { - delim = parserInput.$char('/'); - - if (delim) { - entities.push(new tree.Anonymous(delim, index)); - } - } - } - } while (e); - - if (entities.length > 0) { - return new tree.Expression(entities); - } - }, - property: function property() { - var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - - if (name) { - return name[1]; - } - }, - ruleProperty: function ruleProperty() { - var name = []; - var index = []; - var s; - var k; - parserInput.save(); - var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); - - if (simpleProperty) { - name = [new tree.Keyword(simpleProperty[1])]; - parserInput.forget(); - return name; - } - - function match(re) { - var i = parserInput.i; - var chunk = parserInput.$re(re); - - if (chunk) { - index.push(i); - return name.push(chunk[1]); - } - } - - match(/^(\*?)/); - - while (true) { - if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { - break; - } - } - - if (name.length > 1 && match(/^((?:\+_|\+)?)\s*:/)) { - parserInput.forget(); // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - - if (name[0] === '') { - name.shift(); - index.shift(); - } - - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = s.charAt(0) !== '@' && s.charAt(0) !== '$' ? new tree.Keyword(s) : s.charAt(0) === '@' ? new tree.Variable(`@${s.slice(2, -1)}`, index[k], fileInfo) : new tree.Property(`$${s.slice(2, -1)}`, index[k], fileInfo); - } - - return name; - } - - parserInput.restore(); - } - } - }; -}; - -Parser.serializeVars = function (vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += `${(name[0] === '@' ? '' : '@') + name}: ${value}${String(value).slice(-1) === ';' ? '' : ';'}`; - } - } - - return s; -}; - -function boolean(condition) { - return condition ? Keyword.True : Keyword.False; -} - -function If(condition, trueValue, falseValue) { - return condition ? trueValue : falseValue || new Anonymous(); -} - -var boolean$1 = { - boolean, - 'if': If -}; - -var colorFunctions; - -function clamp$1(val) { - return Math.min(1, Math.max(0, val)); -} - -function hsla(origColor, hsl) { - var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); - - if (color) { - if (origColor.value && /^(rgb|hsl)/.test(origColor.value)) { - color.value = origColor.value; - } else { - color.value = 'rgb'; - } - - return color; - } -} - -function toHSL(color) { - if (color.toHSL) { - return color.toHSL(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } -} - -function toHSV(color) { - if (color.toHSV) { - return color.toHSV(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } -} - -function number(n) { - if (n instanceof Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof n === 'number') { - return n; - } else { - throw { - type: 'Argument', - message: 'color functions take numbers as parameters' - }; - } -} - -function scaled(n, size) { - if (n instanceof Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -colorFunctions = { - rgb: function rgb(r, g, b) { - var color = colorFunctions.rgba(r, g, b, 1.0); - - if (color) { - color.value = 'rgb'; - return color; - } - }, - rgba: function rgba(r, g, b, a) { - try { - if (r instanceof Color) { - if (g) { - a = number(g); - } else { - a = r.alpha; - } - - return new Color(r.rgb, a, 'rgba'); - } - - var rgb = [r, g, b].map(function (c) { - return scaled(c, 255); - }); - a = number(a); - return new Color(rgb, a, 'rgba'); - } catch (e) {} - }, - hsl: function hsl(h, s, l) { - var color = colorFunctions.hsla(h, s, l, 1.0); - - if (color) { - color.value = 'hsl'; - return color; - } - }, - hsla: function hsla(h, s, l, a) { - try { - if (h instanceof Color) { - if (s) { - a = number(s); - } else { - a = h.alpha; - } - - return new Color(h.rgb, a, 'hsla'); - } - - var m1; - var m2; - - function hue(h) { - h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; - - if (h * 6 < 1) { - return m1 + (m2 - m1) * h * 6; - } else if (h * 2 < 1) { - return m2; - } else if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - } else { - return m1; - } - } - - h = number(h) % 360 / 360; - s = clamp$1(number(s)); - l = clamp$1(number(l)); - a = clamp$1(number(a)); - m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - var rgb = [hue(h + 1 / 3) * 255, hue(h) * 255, hue(h - 1 / 3) * 255]; - a = number(a); - return new Color(rgb, a, 'hsla'); - } catch (e) {} - }, - hsv: function hsv(h, s, v) { - return colorFunctions.hsva(h, s, v, 1.0); - }, - hsva: function hsva(h, s, v, a) { - h = number(h) % 360 / 360 * 360; - s = number(s); - v = number(v); - a = number(a); - var i; - var f; - i = Math.floor(h / 60 % 6); - f = h / 60 - i; - var vs = [v, v * (1 - s), v * (1 - f * s), v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], [2, 0, 1], [1, 0, 3], [1, 2, 0], [3, 1, 0], [0, 1, 2]]; - return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); - }, - hue: function hue(color) { - return new Dimension(toHSL(color).h); - }, - saturation: function saturation(color) { - return new Dimension(toHSL(color).s * 100, '%'); - }, - lightness: function lightness(color) { - return new Dimension(toHSL(color).l * 100, '%'); - }, - hsvhue: function hsvhue(color) { - return new Dimension(toHSV(color).h); - }, - hsvsaturation: function hsvsaturation(color) { - return new Dimension(toHSV(color).s * 100, '%'); - }, - hsvvalue: function hsvvalue(color) { - return new Dimension(toHSV(color).v * 100, '%'); - }, - red: function red(color) { - return new Dimension(color.rgb[0]); - }, - green: function green(color) { - return new Dimension(color.rgb[1]); - }, - blue: function blue(color) { - return new Dimension(color.rgb[2]); - }, - alpha: function alpha(color) { - return new Dimension(toHSL(color).a); - }, - luma: function luma(color) { - return new Dimension(color.luma() * color.alpha * 100, '%'); - }, - luminance: function luminance(color) { - var luminance = 0.2126 * color.rgb[0] / 255 + 0.7152 * color.rgb[1] / 255 + 0.0722 * color.rgb[2] / 255; - return new Dimension(luminance * color.alpha * 100, '%'); - }, - saturate: function saturate(color, amount, method) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s += hsl.s * amount.value / 100; - } else { - hsl.s += amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - desaturate: function desaturate(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s -= hsl.s * amount.value / 100; - } else { - hsl.s -= amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - lighten: function lighten(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l += hsl.l * amount.value / 100; - } else { - hsl.l += amount.value / 100; - } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - darken: function darken(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l -= hsl.l * amount.value / 100; - } else { - hsl.l -= amount.value / 100; - } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - fadein: function fadein(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a += hsl.a * amount.value / 100; - } else { - hsl.a += amount.value / 100; - } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fadeout: function fadeout(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a -= hsl.a * amount.value / 100; - } else { - hsl.a -= amount.value / 100; - } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fade: function fade(color, amount) { - var hsl = toHSL(color); - hsl.a = amount.value / 100; - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - spin: function spin(color, amount) { - var hsl = toHSL(color); - var hue = (hsl.h + amount.value) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return hsla(color, hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function mix(color1, color2, weight) { - if (!weight) { - weight = new Dimension(50); - } - - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = toHSL(color1).a - toHSL(color2).a; - var w1 = ((w * a == -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, color1.rgb[1] * w1 + color2.rgb[1] * w2, color1.rgb[2] * w1 + color2.rgb[2] * w2]; - var alpha = color1.alpha * p + color2.alpha * (1 - p); - return new Color(rgb, alpha); - }, - greyscale: function greyscale(color) { - return colorFunctions.desaturate(color, new Dimension(100)); - }, - contrast: function contrast(color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - - if (typeof light === 'undefined') { - light = colorFunctions.rgba(255, 255, 255, 1.0); - } - - if (typeof dark === 'undefined') { - dark = colorFunctions.rgba(0, 0, 0, 1.0); - } // Figure out which is actually light and dark: - - - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - // Changes made in 2.7.0 - Reverted in 3.0.0 - // contrast: function (color, color1, color2, threshold) { - // // Return which of `color1` and `color2` has the greatest contrast with `color` - // // according to the standard WCAG contrast ratio calculation. - // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - // // The threshold param is no longer used, in line with SASS. - // // filter: contrast(3.2); - // // should be kept as is, so check for color - // if (!color.rgb) { - // return null; - // } - // if (typeof color1 === 'undefined') { - // color1 = colorFunctions.rgba(0, 0, 0, 1.0); - // } - // if (typeof color2 === 'undefined') { - // color2 = colorFunctions.rgba(255, 255, 255, 1.0); - // } - // var contrast1, contrast2; - // var luma = color.luma(); - // var luma1 = color1.luma(); - // var luma2 = color2.luma(); - // // Calculate contrast ratios for each color - // if (luma > luma1) { - // contrast1 = (luma + 0.05) / (luma1 + 0.05); - // } else { - // contrast1 = (luma1 + 0.05) / (luma + 0.05); - // } - // if (luma > luma2) { - // contrast2 = (luma + 0.05) / (luma2 + 0.05); - // } else { - // contrast2 = (luma2 + 0.05) / (luma + 0.05); - // } - // if (contrast1 > contrast2) { - // return color1; - // } else { - // return color2; - // } - // }, - argb: function argb(color) { - return new Anonymous(color.toARGB()); - }, - color: function color(c) { - if (c instanceof Quoted && /^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value)) { - var val = c.value.slice(1); - return new Color(val, undefined, `#${val}`); - } - - if (c instanceof Color || (c = Color.fromKeyword(c.value))) { - c.value = undefined; - return c; - } - - throw { - type: 'Argument', - message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' - }; - }, - tint: function tint(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); - }, - shade: function shade(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); - } -}; -var color = colorFunctions; - -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha; // result - - var // backdrop - cb; - var as = color2.alpha; - var // source - cs; - var ar; - var cr; - var r = []; - ar = as + ab * (1 - as); - - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - - if (ar) { - cr = (as * cs + ab * (cb - as * (cb + cs - cr))) / ar; - } - - r[i] = cr * 255; - } - - return new Color(r, ar); -} - -var colorBlendModeFunctions = { - multiply: function multiply(cb, cs) { - return cb * cs; - }, - screen: function screen(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function overlay(cb, cs) { - cb *= 2; - return cb <= 1 ? colorBlendModeFunctions.multiply(cb, cs) : colorBlendModeFunctions.screen(cb - 1, cs); - }, - softlight: function softlight(cb, cs) { - var d = 1; - var e = cb; - - if (cs > 0.5) { - e = 1; - d = cb > 0.25 ? Math.sqrt(cb) : ((16 * cb - 12) * cb + 4) * cb; - } - - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function hardlight(cb, cs) { - return colorBlendModeFunctions.overlay(cs, cb); - }, - difference: function difference(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function exclusion(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - // non-w3c functions: - average: function average(cb, cs) { - return (cb + cs) / 2; - }, - negation: function negation(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } -}; - -for (var f in colorBlendModeFunctions) { - if (colorBlendModeFunctions.hasOwnProperty(f)) { - colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); - } -} - -var dataUri = (function (environment) { - var fallback = function fallback(functionThis, node) { - return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); - }; - - return { - 'data-uri': function dataUri(mimetypeNode, filePathNode) { - if (!filePathNode) { - filePathNode = mimetypeNode; - mimetypeNode = null; - } - - var mimetype = mimetypeNode && mimetypeNode.value; - var filePath = filePathNode.value; - var currentFileInfo = this.currentFileInfo; - var currentDirectory = currentFileInfo.rewriteUrls ? currentFileInfo.currentDirectory : currentFileInfo.entryPath; - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - var context = clone(this.context); - context.rawBuffer = true; - var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); - - if (!fileManager) { - return fallback(this, filePathNode); - } - - var useBase64 = false; // detect the mimetype if not given - - if (!mimetypeNode) { - mimetype = environment.mimeLookup(filePath); - - if (mimetype === 'image/svg+xml') { - useBase64 = false; - } else { - // use base 64 unless it's an ASCII or UTF-8 format - var charset = environment.charsetLookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - } - - if (useBase64) { - mimetype += ';base64'; - } - } else { - useBase64 = /;base64$/.test(mimetype); - } - - var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); - - if (!fileSync.contents) { - logger.warn(`Skipped data-uri embedding of ${filePath} because file not found`); - return fallback(this, filePathNode || mimetypeNode); - } - - var buf = fileSync.contents; - - if (useBase64 && !environment.encodeBase64) { - return fallback(this, filePathNode); - } - - buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); - var uri = `data:${mimetype},${buf}${fragment}`; - return new URL(new Quoted(`"${uri}"`, uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); - } - }; -}); - -var getItemsFromNode = function getItemsFromNode(node) { - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - var items = Array.isArray(node.value) ? node.value : Array(node); - return items; -}; - -var list = { - _SELF: function _SELF(n) { - return n; - }, - extract: function extract(values, index) { - // (1-based index) - index = index.value - 1; - return getItemsFromNode(values)[index]; - }, - length: function length(values) { - return new Dimension(getItemsFromNode(values).length); - }, - - /** - * Creates a Less list of incremental values. - * Modeled after Lodash's range function, also exists natively in PHP - * - * @param {Dimension} [start=1] - * @param {Dimension} end - e.g. 10 or 10px - unit is added to output - * @param {Dimension} [step=1] - */ - range: function range(start, end, step) { - var from; - var to; - var stepValue = 1; - var list = []; - - if (end) { - to = end; - from = start.value; - - if (step) { - stepValue = step.value; - } - } else { - from = 1; - to = start; - } - - for (var i = from; i <= to.value; i += stepValue) { - list.push(new Dimension(i, to.unit)); - } - - return new Expression(list); - }, - each: function each(list, rs) { - var rules = []; - var newRules; - var iterator; - - if (list.value && !(list instanceof Quoted)) { - if (Array.isArray(list.value)) { - iterator = list.value; - } else { - iterator = [list.value]; - } - } else if (list.ruleset) { - iterator = list.ruleset.rules; - } else if (list.rules) { - iterator = list.rules; - } else if (Array.isArray(list)) { - iterator = list; - } else { - iterator = [list]; - } - - var valueName = '@value'; - var keyName = '@key'; - var indexName = '@index'; - - if (rs.params) { - valueName = rs.params[0] && rs.params[0].name; - keyName = rs.params[1] && rs.params[1].name; - indexName = rs.params[2] && rs.params[2].name; - rs = rs.rules; - } else { - rs = rs.ruleset; - } - - for (var i = 0; i < iterator.length; i++) { - var key = void 0; - var value = void 0; - var item = iterator[i]; - - if (item instanceof Declaration) { - key = typeof item.name === 'string' ? item.name : item.name[0].value; - value = item.value; - } else { - key = new Dimension(i + 1); - value = item; - } - - if (item instanceof Comment) { - continue; - } - - newRules = rs.rules.slice(0); - - if (valueName) { - newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); - } - - if (indexName) { - newRules.push(new Declaration(indexName, new Dimension(i + 1), false, false, this.index, this.currentFileInfo)); - } - - if (keyName) { - newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); - } - - rules.push(new Ruleset([new Selector([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); - } - - return new Ruleset([new Selector([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); - } -}; - -var MathHelper = function MathHelper(fn, unit, n) { - if (!(n instanceof Dimension)) { - throw { - type: 'Argument', - message: 'argument must be a number' + }, + // + // Entities are the smallest recognized token, + // and can be found inside a rule's value. + // + entity: function () { + var entities = this.entities; + return this.comment() || entities.literal() || entities.variable() || entities.url() || + entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || + entities.javascript(); + }, + // + // A Declaration terminator. Note that we use `peek()` to check for '}', + // because the `block` rule will be expecting it, but we still need to make sure + // it's there, if ';' was omitted. + // + end: function () { + return parserInput.$char(';') || parserInput.peek('}'); + }, + // + // IE's alpha function + // + // alpha(opacity=88) + // + ieAlpha: function () { + var value; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (!parserInput.$re(/^opacity=/i)) { + return; + } + value = parserInput.$re(/^\d+/); + if (!value) { + value = expect(parsers.entities.variable, 'Could not parse alpha'); + value = "@{" + value.name.slice(1) + "}"; + } + expectChar(')'); + return new tree.Quoted('', "alpha(opacity=" + value + ")"); + }, + // + // A Selector Element + // + // div + // + h1 + // #socks + // input[type="text"] + // + // Elements are the building blocks for Selectors, + // they are made out of a `Combinator` (see combinator rule), + // and an element name, such as a tag a class, or `*`. + // + element: function () { + var e; + var c; + var v; + var index = parserInput.i; + c = this.combinator(); + e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || + parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || + parserInput.$char('*') || parserInput.$char('&') || this.attribute() || + parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || + this.entities.variableCurly(); + if (!e) { + parserInput.save(); + if (parserInput.$char('(')) { + if ((v = this.selector(false)) && parserInput.$char(')')) { + e = new (tree.Paren)(v); + parserInput.forget(); + } + else { + parserInput.restore('Missing closing \')\''); + } + } + else { + parserInput.forget(); + } + } + if (e) { + return new (tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo); + } + }, + // + // Combinators combine elements together, in a Selector. + // + // Because our parser isn't white-space sensitive, special care + // has to be taken, when parsing the descendant combinator, ` `, + // as it's an empty space. We have to check the previous character + // in the input, to see if it's a ` ` character. More info on how + // we deal with this in *combinator.js*. + // + combinator: function () { + var c = parserInput.currentChar(); + if (c === '/') { + parserInput.save(); + var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); + if (slashedCombinator) { + parserInput.forget(); + return new (tree.Combinator)(slashedCombinator); + } + parserInput.restore(); + } + if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { + parserInput.i++; + if (c === '^' && parserInput.currentChar() === '^') { + c = '^^'; + parserInput.i++; + } + while (parserInput.isWhitespace()) { + parserInput.i++; + } + return new (tree.Combinator)(c); + } + else if (parserInput.isWhitespace(-1)) { + return new (tree.Combinator)(' '); + } + else { + return new (tree.Combinator)(null); + } + }, + // + // A CSS Selector + // with less extensions e.g. the ability to extend and guard + // + // .class > div + h1 + // li a:hover + // + // Selectors are made out of one or more Elements, see above. + // + selector: function (isLess) { + var index = parserInput.i; + var elements; + var extendList; + var c; + var e; + var allExtends; + var when; + var condition; + isLess = isLess !== false; + while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) { + if (when) { + condition = expect(this.conditions, 'expected condition'); + } + else if (condition) { + error('CSS guard can only be used at the end of selector'); + } + else if (extendList) { + if (allExtends) { + allExtends = allExtends.concat(extendList); + } + else { + allExtends = extendList; + } + } + else { + if (allExtends) { + error('Extend can only be used at the end of selector'); + } + c = parserInput.currentChar(); + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + e = null; + } + if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { + break; + } + } + if (elements) { + return new (tree.Selector)(elements, allExtends, condition, index, fileInfo); + } + if (allExtends) { + error('Extend must be used to extend a selector, it cannot be used on its own'); + } + }, + selectors: function () { + var s; + var selectors; + while (true) { + s = this.selector(); + if (!s) { + break; + } + if (selectors) { + selectors.push(s); + } + else { + selectors = [s]; + } + parserInput.commentStore.length = 0; + if (s.condition && selectors.length > 1) { + error("Guards are only currently allowed on a single selector."); + } + if (!parserInput.$char(',')) { + break; + } + if (s.condition) { + error("Guards are only currently allowed on a single selector."); + } + parserInput.commentStore.length = 0; + } + return selectors; + }, + attribute: function () { + if (!parserInput.$char('[')) { + return; + } + var entities = this.entities; + var key; + var val; + var op; + if (!(key = entities.variableCurly())) { + key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + } + op = parserInput.$re(/^[|~*$^]?=/); + if (op) { + val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); + } + expectChar(']'); + return new (tree.Attribute)(key, op, val); + }, + // + // The `block` rule is used by `ruleset` and `mixin.definition`. + // It's a wrapper around the `primary` rule, with added `{}`. + // + block: function () { + var content; + if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { + return content; + } + }, + blockRuleset: function () { + var block = this.block(); + if (block) { + block = new tree.Ruleset(null, block); + } + return block; + }, + detachedRuleset: function () { + var argInfo; + var params; + var variadic; + parserInput.save(); + if (parserInput.$re(/^[.#]\(/)) { + /** + * DR args currently only implemented for each() function, and not + * yet settable as `@dr: #(@arg) {}` + * This should be done when DRs are merged with mixins. + * See: https://github.com/less/less-meta/issues/16 + */ + argInfo = this.mixin.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + } + var blockRuleset = this.blockRuleset(); + if (blockRuleset) { + parserInput.forget(); + if (params) { + return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); + } + return new tree.DetachedRuleset(blockRuleset); + } + parserInput.restore(); + }, + // + // div, .class, body > p {...} + // + ruleset: function () { + var selectors; + var rules; + var debugInfo; + parserInput.save(); + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(parserInput.i); + } + selectors = this.selectors(); + if (selectors && (rules = this.block())) { + parserInput.forget(); + var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports); + if (context.dumpLineNumbers) { + ruleset.debugInfo = debugInfo; + } + return ruleset; + } + else { + parserInput.restore(); + } + }, + declaration: function () { + var name; + var value; + var index = parserInput.i; + var hasDR; + var c = parserInput.currentChar(); + var important; + var merge; + var isVariable; + if (c === '.' || c === '#' || c === '&' || c === ':') { + return; + } + parserInput.save(); + name = this.variable() || this.ruleProperty(); + if (name) { + isVariable = typeof name === 'string'; + if (isVariable) { + value = this.detachedRuleset(); + if (value) { + hasDR = true; + } + } + parserInput.commentStore.length = 0; + if (!value) { + // a name returned by this.ruleProperty() is always an array of the form: + // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] + // where each item is a tree.Keyword or tree.Variable + merge = !isVariable && name.length > 1 && name.pop().value; + // Custom property values get permissive parsing + if (name[0].value && name[0].value.slice(0, 2) === '--') { + value = this.permissiveValue(); + } + // Try to store values as anonymous + // If we need the value later we'll re-parse it in ruleset.parseValue + else { + value = this.anonymousValue(); + } + if (value) { + parserInput.forget(); + // anonymous values absorb the end ';' which is required for them to work + return new (tree.Declaration)(name, value, false, merge, index, fileInfo); + } + if (!value) { + value = this.value(); + } + if (value) { + important = this.important(); + } + else if (isVariable) { + // As a last resort, try permissiveValue + value = this.permissiveValue(); + } + } + if (value && (this.end() || hasDR)) { + parserInput.forget(); + return new (tree.Declaration)(name, value, important, merge, index, fileInfo); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + anonymousValue: function () { + var index = parserInput.i; + var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); + if (match) { + return new (tree.Anonymous)(match[1], index); + } + }, + /** + * Used for custom properties, at-rules, and variables (as fallback) + * Parses almost anything inside of {} [] () "" blocks + * until it reaches outer-most tokens. + * + * First, it will try to parse comments and entities to reach + * the end. This is mostly like the Expression parser except no + * math is allowed. + */ + permissiveValue: function (untilTokens) { + var i; + var e; + var done; + var value; + var tok = untilTokens || ';'; + var index = parserInput.i; + var result = []; + function testCurrentChar() { + var char = parserInput.currentChar(); + if (typeof tok === 'string') { + return char === tok; + } + else { + return tok.test(char); + } + } + if (testCurrentChar()) { + return; + } + value = []; + do { + e = this.comment(); + if (e) { + value.push(e); + continue; + } + e = this.entity(); + if (e) { + value.push(e); + } + } while (e); + done = testCurrentChar(); + if (value.length > 0) { + value = new (tree.Expression)(value); + if (done) { + return value; + } + else { + result.push(value); + } + // Preserve space before $parseUntil as it will not + if (parserInput.prevChar() === ' ') { + result.push(new tree.Anonymous(' ', index)); + } + } + parserInput.save(); + value = parserInput.$parseUntil(tok); + if (value) { + if (typeof value === 'string') { + error("Expected '" + value + "'", 'Parse'); + } + if (value.length === 1 && value[0] === ' ') { + parserInput.forget(); + return new tree.Anonymous('', index); + } + var item = void 0; + for (i = 0; i < value.length; i++) { + item = value[i]; + if (Array.isArray(item)) { + // Treat actual quotes as normal quoted values + result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); + } + else { + if (i === value.length - 1) { + item = item.trim(); + } + // Treat like quoted values, but replace vars like unquoted expressions + var quote = new tree.Quoted('\'', item, true, index, fileInfo); + quote.variableRegex = /@([\w-]+)/g; + quote.propRegex = /\$([\w-]+)/g; + result.push(quote); + } + } + parserInput.forget(); + return new tree.Expression(result, true); + } + parserInput.restore(); + }, + // + // An @import atrule + // + // @import "lib"; + // + // Depending on our environment, importing is done differently: + // In the browser, it's an XHR request, in Node, it would be a + // file-system operation. The function used for importing is + // stored in `import`, which we pass to the Import constructor. + // + 'import': function () { + var path; + var features; + var index = parserInput.i; + var dir = parserInput.$re(/^@import?\s+/); + if (dir) { + var options_1 = (dir ? this.importOptions() : null) || {}; + if ((path = this.entities.quoted() || this.entities.url())) { + features = this.mediaFeatures(); + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon or unrecognised media features on import'); + } + features = features && new (tree.Value)(features); + return new (tree.Import)(path, features, options_1, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed import statement'); + } + } + }, + importOptions: function () { + var o; + var options = {}; + var optionName; + var value; + // list of options, surrounded by parens + if (!parserInput.$char('(')) { + return null; + } + do { + o = this.importOption(); + if (o) { + optionName = o; + value = true; + switch (optionName) { + case 'css': + optionName = 'less'; + value = false; + break; + case 'once': + optionName = 'multiple'; + value = false; + break; + } + options[optionName] = value; + if (!parserInput.$char(',')) { + break; + } + } + } while (o); + expectChar(')'); + return options; + }, + importOption: function () { + var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); + if (opt) { + return opt[1]; + } + }, + mediaFeature: function () { + var entities = this.entities; + var nodes = []; + var e; + var p; + parserInput.save(); + do { + e = entities.keyword() || entities.variable() || entities.mixinLookup(); + if (e) { + nodes.push(e); + } + else if (parserInput.$char('(')) { + p = this.property(); + e = this.value(); + if (parserInput.$char(')')) { + if (p && e) { + nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true))); + } + else if (e) { + nodes.push(new (tree.Paren)(e)); + } + else { + error('badly formed media feature definition'); + } + } + else { + error('Missing closing \')\'', 'Parse'); + } + } + } while (e); + parserInput.forget(); + if (nodes.length > 0) { + return new (tree.Expression)(nodes); + } + }, + mediaFeatures: function () { + var entities = this.entities; + var features = []; + var e; + do { + e = this.mediaFeature(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + else { + e = entities.variable() || entities.mixinLookup(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } + } while (e); + return features.length > 0 ? features : null; + }, + media: function () { + var features; + var rules; + var media; + var debugInfo; + var index = parserInput.i; + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(index); + } + parserInput.save(); + if (parserInput.$str('@media')) { + features = this.mediaFeatures(); + rules = this.block(); + if (!rules) { + error('media definitions require block statements after any features'); + } + parserInput.forget(); + media = new (tree.Media)(rules, features, index, fileInfo); + if (context.dumpLineNumbers) { + media.debugInfo = debugInfo; + } + return media; + } + parserInput.restore(); + }, + // + // A @plugin directive, used to import plugins dynamically. + // + // @plugin (args) "lib"; + // + plugin: function () { + var path; + var args; + var options; + var index = parserInput.i; + var dir = parserInput.$re(/^@plugin?\s+/); + if (dir) { + args = this.pluginArgs(); + if (args) { + options = { + pluginArgs: args, + isPlugin: true + }; + } + else { + options = { isPlugin: true }; + } + if ((path = this.entities.quoted() || this.entities.url())) { + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon on @plugin'); + } + return new (tree.Import)(path, null, options, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed @plugin statement'); + } + } + }, + pluginArgs: function () { + // list of options, surrounded by parens + parserInput.save(); + if (!parserInput.$char('(')) { + parserInput.restore(); + return null; + } + var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); + if (args[1]) { + parserInput.forget(); + return args[1].trim(); + } + else { + parserInput.restore(); + return null; + } + }, + // + // A CSS AtRule + // + // @charset "utf-8"; + // + atrule: function () { + var index = parserInput.i; + var name; + var value; + var rules; + var nonVendorSpecificName; + var hasIdentifier; + var hasExpression; + var hasUnknown; + var hasBlock = true; + var isRooted = true; + if (parserInput.currentChar() !== '@') { + return; + } + value = this['import']() || this.plugin() || this.media(); + if (value) { + return value; + } + parserInput.save(); + name = parserInput.$re(/^@[a-z-]+/); + if (!name) { + return; + } + nonVendorSpecificName = name; + if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { + nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); + } + switch (nonVendorSpecificName) { + case '@charset': + hasIdentifier = true; + hasBlock = false; + break; + case '@namespace': + hasExpression = true; + hasBlock = false; + break; + case '@keyframes': + case '@counter-style': + hasIdentifier = true; + break; + case '@document': + case '@supports': + hasUnknown = true; + isRooted = false; + break; + default: + hasUnknown = true; + break; + } + parserInput.commentStore.length = 0; + if (hasIdentifier) { + value = this.entity(); + if (!value) { + error("expected " + name + " identifier"); + } + } + else if (hasExpression) { + value = this.expression(); + if (!value) { + error("expected " + name + " expression"); + } + } + else if (hasUnknown) { + value = this.permissiveValue(/^[{;]/); + hasBlock = (parserInput.currentChar() === '{'); + if (!value) { + if (!hasBlock && parserInput.currentChar() !== ';') { + error(name + " rule is missing block or ending semi-colon"); + } + } + else if (!value.value) { + value = null; + } + } + if (hasBlock) { + rules = this.blockRuleset(); + } + if (rules || (!hasBlock && value && parserInput.$char(';'))) { + parserInput.forget(); + return new (tree.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); + } + parserInput.restore('at-rule options not recognised'); + }, + // + // A Value is a comma-delimited list of Expressions + // + // font-family: Baskerville, Georgia, serif; + // + // In a Rule, a Value represents everything after the `:`, + // and before the `;`. + // + value: function () { + var e; + var expressions = []; + var index = parserInput.i; + do { + e = this.expression(); + if (e) { + expressions.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } while (e); + if (expressions.length > 0) { + return new (tree.Value)(expressions, index); + } + }, + important: function () { + if (parserInput.currentChar() === '!') { + return parserInput.$re(/^! *important/); + } + }, + sub: function () { + var a; + var e; + parserInput.save(); + if (parserInput.$char('(')) { + a = this.addition(); + if (a && parserInput.$char(')')) { + parserInput.forget(); + e = new (tree.Expression)([a]); + e.parens = true; + return e; + } + parserInput.restore('Expected \')\''); + return; + } + parserInput.restore(); + }, + multiplication: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.operand(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + if (parserInput.peek(/^\/[*\/]/)) { + break; + } + parserInput.save(); + op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); + if (!op) { + parserInput.forget(); + break; + } + a = this.operand(); + if (!a) { + parserInput.restore(); + break; + } + parserInput.forget(); + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + addition: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.multiplication(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-'))); + if (!op) { + break; + } + a = this.multiplication(); + if (!a) { + break; + } + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + conditions: function () { + var a; + var b; + var index = parserInput.i; + var condition; + a = this.condition(true); + if (a) { + while (true) { + if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { + break; + } + b = this.condition(true); + if (!b) { + break; + } + condition = new (tree.Condition)('or', condition || a, b, index); + } + return condition || a; + } + }, + condition: function (needsParens) { + var result; + var logical; + var next; + function or() { + return parserInput.$str('or'); + } + result = this.conditionAnd(needsParens); + if (!result) { + return; + } + logical = or(); + if (logical) { + next = this.condition(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + conditionAnd: function (needsParens) { + var result; + var logical; + var next; + var self = this; + function insideCondition() { + var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); + if (!cond && !needsParens) { + return self.atomicCondition(needsParens); + } + return cond; + } + function and() { + return parserInput.$str('and'); + } + result = insideCondition(); + if (!result) { + return; + } + logical = and(); + if (logical) { + next = this.conditionAnd(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + negatedCondition: function (needsParens) { + if (parserInput.$str('not')) { + var result = this.parenthesisCondition(needsParens); + if (result) { + result.negate = !result.negate; + } + return result; + } + }, + parenthesisCondition: function (needsParens) { + function tryConditionFollowedByParenthesis(me) { + var body; + parserInput.save(); + body = me.condition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + parserInput.forget(); + return body; + } + var body; + parserInput.save(); + if (!parserInput.$str('(')) { + parserInput.restore(); + return; + } + body = tryConditionFollowedByParenthesis(this); + if (body) { + parserInput.forget(); + return body; + } + body = this.atomicCondition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'"); + return; + } + parserInput.forget(); + return body; + }, + atomicCondition: function (needsParens) { + var entities = this.entities; + var index = parserInput.i; + var a; + var b; + var c; + var op; + function cond() { + return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); + } + cond = cond.bind(this); + a = cond(); + if (a) { + if (parserInput.$char('>')) { + if (parserInput.$char('=')) { + op = '>='; + } + else { + op = '>'; + } + } + else if (parserInput.$char('<')) { + if (parserInput.$char('=')) { + op = '<='; + } + else { + op = '<'; + } + } + else if (parserInput.$char('=')) { + if (parserInput.$char('>')) { + op = '=>'; + } + else if (parserInput.$char('<')) { + op = '=<'; + } + else { + op = '='; + } + } + if (op) { + b = cond(); + if (b) { + c = new (tree.Condition)(op, a, b, index, false); + } + else { + error('expected expression'); + } + } + else { + c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, false); + } + return c; + } + }, + // + // An operand is anything that can be part of an operation, + // such as a Color, or a Variable + // + operand: function () { + var entities = this.entities; + var negate; + if (parserInput.peek(/^-[@\$\(]/)) { + negate = parserInput.$char('-'); + } + var o = this.sub() || entities.dimension() || + entities.color() || entities.variable() || + entities.property() || entities.call() || + entities.quoted(true) || entities.colorKeyword() || + entities.mixinLookup(); + if (negate) { + o.parensInOp = true; + o = new (tree.Negative)(o); + } + return o; + }, + // + // Expressions either represent mathematical operations, + // or white-space delimited Entities. + // + // 1px solid black + // @var * 2 + // + expression: function () { + var entities = []; + var e; + var delim; + var index = parserInput.i; + do { + e = this.comment(); + if (e) { + entities.push(e); + continue; + } + e = this.addition() || this.entity(); + if (e) { + entities.push(e); + // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here + if (!parserInput.peek(/^\/[\/*]/)) { + delim = parserInput.$char('/'); + if (delim) { + entities.push(new (tree.Anonymous)(delim, index)); + } + } + } + } while (e); + if (entities.length > 0) { + return new (tree.Expression)(entities); + } + }, + property: function () { + var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); + if (name) { + return name[1]; + } + }, + ruleProperty: function () { + var name = []; + var index = []; + var s; + var k; + parserInput.save(); + var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); + if (simpleProperty) { + name = [new (tree.Keyword)(simpleProperty[1])]; + parserInput.forget(); + return name; + } + function match(re) { + var i = parserInput.i; + var chunk = parserInput.$re(re); + if (chunk) { + index.push(i); + return name.push(chunk[1]); + } + } + match(/^(\*?)/); + while (true) { + if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { + break; + } + } + if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) { + parserInput.forget(); + // at last, we have the complete match now. move forward, + // convert name particles to tree objects and return: + if (name[0] === '') { + name.shift(); + index.shift(); + } + for (k = 0; k < name.length; k++) { + s = name[k]; + name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ? + new (tree.Keyword)(s) : + (s.charAt(0) === '@' ? + new (tree.Variable)("@" + s.slice(2, -1), index[k], fileInfo) : + new (tree.Property)("$" + s.slice(2, -1), index[k], fileInfo)); + } + return name; + } + parserInput.restore(); + } + } }; - } - - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - - return new Dimension(fn(parseFloat(n.value)), unit); }; - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: '', - sin: '', - cos: '', - atan: 'rad', - asin: 'rad', - acos: 'rad' +Parser.serializeVars = function (vars) { + var s = ''; + for (var name_1 in vars) { + if (Object.hasOwnProperty.call(vars, name_1)) { + var value = vars[name_1]; + s += ((name_1[0] === '@') ? '' : '@') + name_1 + ": " + value + ((String(value).slice(-1) === ';') ? '' : ';'); + } + } + return s; }; -for (var f$1 in mathFunctions) { - if (mathFunctions.hasOwnProperty(f$1)) { - mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); - } +function boolean(condition) { + return condition ? Keyword.True : Keyword.False; } +function If(condition, trueValue, falseValue) { + return condition ? trueValue + : (falseValue || new Anonymous); +} +var boolean$1 = { boolean: boolean, 'if': If }; -mathFunctions.round = function (n, f) { - var fraction = typeof f === 'undefined' ? 0 : f.value; - return MathHelper(function (num) { - return num.toFixed(fraction); - }, null, n); -}; - -var minMax = function minMax(isMin, args) { - args = Array.prototype.slice.call(args); - - switch (args.length) { - case 0: - throw { - type: 'Argument', - message: 'one or more arguments required' - }; - } - - var i; // key is the unit.toString() for unified Dimension values, - - var j; - var current; - var currentUnified; - var referenceUnified; - var unit; - var unitStatic; - var unitClone; - var // elems only contains original argument values. - order = []; - var values = {}; // value is the index into the order array. - - for (i = 0; i < args.length; i++) { - current = args[i]; - - if (!(current instanceof Dimension)) { - if (Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - - continue; +var colorFunctions; +function clamp$1(val) { + return Math.min(1, Math.max(0, val)); +} +function hsla(origColor, hsl) { + var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); + if (color) { + if (origColor.value && + /^(rgb|hsl)/.test(origColor.value)) { + color.value = origColor.value; + } + else { + color.value = 'rgb'; + } + return color; } - - currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; - unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; - - if (j === undefined) { - if (unitStatic !== undefined && unit !== unitStatic) { - throw { - type: 'Argument', - message: 'incompatible types' - }; - } - - values[unit] = order.length; - order.push(current); - continue; +} +function toHSL(color) { + if (color.toHSL) { + return color.toHSL(); } - - referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); - - if (isMin && currentUnified.value < referenceUnified.value || !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; + else { + throw new Error('Argument cannot be evaluated to a color'); } - } - - if (order.length == 1) { - return order[0]; - } - - args = order.map(function (a) { - return a.toCSS(this.context); - }).join(this.context.compress ? ',' : ', '); - return new Anonymous(`${isMin ? 'min' : 'max'}(${args})`); -}; - -var number$1 = { - min: function min() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; +} +function toHSV(color) { + if (color.toHSV) { + return color.toHSV(); } - - return minMax(true, args); - }, - max: function max() { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; + else { + throw new Error('Argument cannot be evaluated to a color'); } - - return minMax(false, args); - }, - convert: function convert(val, unit) { - return val.convertTo(unit.value); - }, - pi: function pi() { - return new Dimension(Math.PI); - }, - mod: function mod(a, b) { - return new Dimension(a.value % b.value, a.unit); - }, - pow: function pow(x, y) { - if (typeof x === 'number' && typeof y === 'number') { - x = new Dimension(x); - y = new Dimension(y); - } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { - throw { - type: 'Argument', - message: 'arguments must be numbers' - }; +} +function number(n) { + if (n instanceof Dimension) { + return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); } - - return new Dimension(Math.pow(x.value, y.value), x.unit); - }, - percentage: function percentage(n) { - var result = MathHelper(function (num) { - return num * 100; - }, '%', n); - return result; - } -}; - -var string = { - e: function e(str) { - return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); - }, - escape: function escape(str) { - return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B').replace(/\(/g, '%28').replace(/\)/g, '%29')); - }, - replace: function replace(string, pattern, replacement, flags) { - var result = string.value; - replacement = replacement.type === 'Quoted' ? replacement.value : replacement.toCSS(); - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); - return new Quoted(string.quote || '', result, string.escaped); - }, - '%': function _(string - /* arg, arg, ... */ - ) { - var args = Array.prototype.slice.call(arguments, 1); - var result = string.value; - - var _loop = function _loop(i) { - /* jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function (token) { - var value = args[i].type === 'Quoted' && token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - }; - - for (var i = 0; i < args.length; i++) { - _loop(i); + else if (typeof n === 'number') { + return n; } - - result = result.replace(/%%/g, '%'); - return new Quoted(string.quote || '', result, string.escaped); - } -}; - -var svg = (function (environment) { - return { - 'svg-gradient': function svgGradient(direction) { - var stops; - var gradientDirectionSvg; - var gradientType = 'linear'; - var rectangleDimension = 'x="0" y="0" width="1" height="1"'; - var renderEnv = { - compress: false - }; - var returner; - var directionValue = direction.toCSS(renderEnv); - var i; - var color; - var position; - var positionValue; - var alpha; - - function throwArgumentDescriptor() { + else { throw { - type: 'Argument', - message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + ' end_color [end_position] or direction, color list' + type: 'Argument', + message: 'color functions take numbers as parameters' }; - } - - if (arguments.length == 2) { - if (arguments[1].value.length < 2) { - throwArgumentDescriptor(); + } +} +function scaled(n, size) { + if (n instanceof Dimension && n.unit.is('%')) { + return parseFloat(n.value * size / 100); + } + else { + return number(n); + } +} +colorFunctions = { + rgb: function (r, g, b) { + var color = colorFunctions.rgba(r, g, b, 1.0); + if (color) { + color.value = 'rgb'; + return color; } - - stops = arguments[1].value; - } else if (arguments.length < 3) { - throwArgumentDescriptor(); - } else { - stops = Array.prototype.slice.call(arguments, 1); - } - - switch (directionValue) { - case 'to bottom': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - - case 'to right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - - case 'to bottom right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - - case 'to top right': - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - - case 'ellipse': - case 'ellipse at center': - gradientType = 'radial'; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - - default: - throw { - type: 'Argument', - message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' - }; - } - - returner = `<${gradientType}Gradient id="g" ${gradientDirectionSvg}>`; - - for (i = 0; i < stops.length; i += 1) { - if (stops[i] instanceof Expression) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; + }, + rgba: function (r, g, b, a) { + try { + if (r instanceof Color) { + if (g) { + a = number(g); + } + else { + a = r.alpha; + } + return new Color(r.rgb, a, 'rgba'); + } + var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); + a = number(a); + return new Color(rgb, a, 'rgba'); } - - if (!(color instanceof Color) || !((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension)) { - throwArgumentDescriptor(); + catch (e) { } + }, + hsl: function (h, s, l) { + var color = colorFunctions.hsla(h, s, l, 1.0); + if (color) { + color.value = 'hsl'; + return color; } - - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; - alpha = color.alpha; - returner += ``; - } - - returner += ``; - returner = encodeURIComponent(returner); - returner = `data:image/svg+xml,${returner}`; - return new URL(new Quoted(`'${returner}'`, returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + }, + hsla: function (h, s, l, a) { + try { + if (h instanceof Color) { + if (s) { + a = number(s); + } + else { + a = h.alpha; + } + return new Color(h.rgb, a, 'hsla'); + } + var m1_1; + var m2_1; + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { + return m1_1 + (m2_1 - m1_1) * h * 6; + } + else if (h * 2 < 1) { + return m2_1; + } + else if (h * 3 < 2) { + return m1_1 + (m2_1 - m1_1) * (2 / 3 - h) * 6; + } + else { + return m1_1; + } + } + h = (number(h) % 360) / 360; + s = clamp$1(number(s)); + l = clamp$1(number(l)); + a = clamp$1(number(a)); + m2_1 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + m1_1 = l * 2 - m2_1; + var rgb = [ + hue(h + 1 / 3) * 255, + hue(h) * 255, + hue(h - 1 / 3) * 255 + ]; + a = number(a); + return new Color(rgb, a, 'hsla'); + } + catch (e) { } + }, + hsv: function (h, s, v) { + return colorFunctions.hsva(h, s, v, 1.0); + }, + hsva: function (h, s, v, a) { + h = ((number(h) % 360) / 360) * 360; + s = number(s); + v = number(v); + a = number(a); + var i; + var f; + i = Math.floor((h / 60) % 6); + f = (h / 60) - i; + var vs = [v, + v * (1 - s), + v * (1 - f * s), + v * (1 - (1 - f) * s)]; + var perm = [[0, 3, 1], + [2, 0, 1], + [1, 0, 3], + [1, 2, 0], + [3, 1, 0], + [0, 1, 2]]; + return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); + }, + hue: function (color) { + return new Dimension(toHSL(color).h); + }, + saturation: function (color) { + return new Dimension(toHSL(color).s * 100, '%'); + }, + lightness: function (color) { + return new Dimension(toHSL(color).l * 100, '%'); + }, + hsvhue: function (color) { + return new Dimension(toHSV(color).h); + }, + hsvsaturation: function (color) { + return new Dimension(toHSV(color).s * 100, '%'); + }, + hsvvalue: function (color) { + return new Dimension(toHSV(color).v * 100, '%'); + }, + red: function (color) { + return new Dimension(color.rgb[0]); + }, + green: function (color) { + return new Dimension(color.rgb[1]); + }, + blue: function (color) { + return new Dimension(color.rgb[2]); + }, + alpha: function (color) { + return new Dimension(toHSL(color).a); + }, + luma: function (color) { + return new Dimension(color.luma() * color.alpha * 100, '%'); + }, + luminance: function (color) { + var luminance = (0.2126 * color.rgb[0] / 255) + + (0.7152 * color.rgb[1] / 255) + + (0.0722 * color.rgb[2] / 255); + return new Dimension(luminance * color.alpha * 100, '%'); + }, + saturate: function (color, amount, method) { + // filter: saturate(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s += hsl.s * amount.value / 100; + } + else { + hsl.s += amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + desaturate: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s -= hsl.s * amount.value / 100; + } + else { + hsl.s -= amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + lighten: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l += hsl.l * amount.value / 100; + } + else { + hsl.l += amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + darken: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l -= hsl.l * amount.value / 100; + } + else { + hsl.l -= amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + fadein: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a += hsl.a * amount.value / 100; + } + else { + hsl.a += amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fadeout: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a -= hsl.a * amount.value / 100; + } + else { + hsl.a -= amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fade: function (color, amount) { + var hsl = toHSL(color); + hsl.a = amount.value / 100; + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + spin: function (color, amount) { + var hsl = toHSL(color); + var hue = (hsl.h + amount.value) % 360; + hsl.h = hue < 0 ? 360 + hue : hue; + return hsla(color, hsl); + }, + // + // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein + // http://sass-lang.com + // + mix: function (color1, color2, weight) { + if (!weight) { + weight = new Dimension(50); + } + var p = weight.value / 100.0; + var w = p * 2 - 1; + var a = toHSL(color1).a - toHSL(color2).a; + var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, + color1.rgb[1] * w1 + color2.rgb[1] * w2, + color1.rgb[2] * w1 + color2.rgb[2] * w2]; + var alpha = color1.alpha * p + color2.alpha * (1 - p); + return new Color(rgb, alpha); + }, + greyscale: function (color) { + return colorFunctions.desaturate(color, new Dimension(100)); + }, + contrast: function (color, dark, light, threshold) { + // filter: contrast(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + if (typeof light === 'undefined') { + light = colorFunctions.rgba(255, 255, 255, 1.0); + } + if (typeof dark === 'undefined') { + dark = colorFunctions.rgba(0, 0, 0, 1.0); + } + // Figure out which is actually light and dark: + if (dark.luma() > light.luma()) { + var t = light; + light = dark; + dark = t; + } + if (typeof threshold === 'undefined') { + threshold = 0.43; + } + else { + threshold = number(threshold); + } + if (color.luma() < threshold) { + return light; + } + else { + return dark; + } + }, + // Changes made in 2.7.0 - Reverted in 3.0.0 + // contrast: function (color, color1, color2, threshold) { + // // Return which of `color1` and `color2` has the greatest contrast with `color` + // // according to the standard WCAG contrast ratio calculation. + // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + // // The threshold param is no longer used, in line with SASS. + // // filter: contrast(3.2); + // // should be kept as is, so check for color + // if (!color.rgb) { + // return null; + // } + // if (typeof color1 === 'undefined') { + // color1 = colorFunctions.rgba(0, 0, 0, 1.0); + // } + // if (typeof color2 === 'undefined') { + // color2 = colorFunctions.rgba(255, 255, 255, 1.0); + // } + // var contrast1, contrast2; + // var luma = color.luma(); + // var luma1 = color1.luma(); + // var luma2 = color2.luma(); + // // Calculate contrast ratios for each color + // if (luma > luma1) { + // contrast1 = (luma + 0.05) / (luma1 + 0.05); + // } else { + // contrast1 = (luma1 + 0.05) / (luma + 0.05); + // } + // if (luma > luma2) { + // contrast2 = (luma + 0.05) / (luma2 + 0.05); + // } else { + // contrast2 = (luma2 + 0.05) / (luma + 0.05); + // } + // if (contrast1 > contrast2) { + // return color1; + // } else { + // return color2; + // } + // }, + argb: function (color) { + return new Anonymous(color.toARGB()); + }, + color: function (c) { + if ((c instanceof Quoted) && + (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) { + var val = c.value.slice(1); + return new Color(val, undefined, "#" + val); + } + if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) { + c.value = undefined; + return c; + } + throw { + type: 'Argument', + message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' + }; + }, + tint: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); + }, + shade: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); } - }; -}); - -var isa = function isa(n, Type) { - return n instanceof Type ? Keyword.True : Keyword.False; -}; - -var isunit = function isunit(n, unit) { - if (unit === undefined) { - throw { - type: 'Argument', - message: 'missing the required second argument to isunit.' - }; - } - - unit = typeof unit.value === 'string' ? unit.value : unit; - - if (typeof unit !== 'string') { - throw { - type: 'Argument', - message: 'Second argument to isunit should be a unit or a string.' - }; - } - - return n instanceof Dimension && n.unit.is(unit) ? Keyword.True : Keyword.False; }; +var color = colorFunctions; -var types = { - isruleset: function isruleset(n) { - return isa(n, DetachedRuleset); - }, - iscolor: function iscolor(n) { - return isa(n, Color); - }, - isnumber: function isnumber(n) { - return isa(n, Dimension); - }, - isstring: function isstring(n) { - return isa(n, Quoted); - }, - iskeyword: function iskeyword(n) { - return isa(n, Keyword); - }, - isurl: function isurl(n) { - return isa(n, URL); - }, - ispixel: function ispixel(n) { - return isunit(n, 'px'); - }, - ispercentage: function ispercentage(n) { - return isunit(n, '%'); - }, - isem: function isem(n) { - return isunit(n, 'em'); - }, - isunit, - unit: function unit(val, _unit) { - if (!(val instanceof Dimension)) { - throw { - type: 'Argument', - message: `the first argument to unit must be a number${val instanceof Operation ? '. Have you forgotten parenthesis?' : ''}` - }; - } - - if (_unit) { - if (_unit instanceof Keyword) { - _unit = _unit.value; - } else { - _unit = _unit.toCSS(); - } - } else { - _unit = ''; +// Color Blending +// ref: http://www.w3.org/TR/compositing-1 +function colorBlend(mode, color1, color2) { + var ab = color1.alpha; // result + var // backdrop + cb; + var as = color2.alpha; + var // source + cs; + var ar; + var cr; + var r = []; + ar = as + ab * (1 - as); + for (var i_1 = 0; i_1 < 3; i_1++) { + cb = color1.rgb[i_1] / 255; + cs = color2.rgb[i_1] / 255; + cr = mode(cb, cs); + if (ar) { + cr = (as * cs + ab * (cb - + as * (cb + cs - cr))) / ar; + } + r[i_1] = cr * 255; + } + return new Color(r, ar); +} +var colorBlendModeFunctions = { + multiply: function (cb, cs) { + return cb * cs; + }, + screen: function (cb, cs) { + return cb + cs - cb * cs; + }, + overlay: function (cb, cs) { + cb *= 2; + return (cb <= 1) ? + colorBlendModeFunctions.multiply(cb, cs) : + colorBlendModeFunctions.screen(cb - 1, cs); + }, + softlight: function (cb, cs) { + var d = 1; + var e = cb; + if (cs > 0.5) { + e = 1; + d = (cb > 0.25) ? Math.sqrt(cb) + : ((16 * cb - 12) * cb + 4) * cb; + } + return cb - (1 - 2 * cs) * e * (d - cb); + }, + hardlight: function (cb, cs) { + return colorBlendModeFunctions.overlay(cs, cb); + }, + difference: function (cb, cs) { + return Math.abs(cb - cs); + }, + exclusion: function (cb, cs) { + return cb + cs - 2 * cb * cs; + }, + // non-w3c functions: + average: function (cb, cs) { + return (cb + cs) / 2; + }, + negation: function (cb, cs) { + return 1 - Math.abs(cb + cs - 1); } - - return new Dimension(val.value, _unit); - }, - 'get-unit': function getUnit(n) { - return new Anonymous(n.unit); - } }; - -var Functions = (function (environment) { - var functions = { - functionRegistry, - functionCaller - }; // register functions - - functionRegistry.addMultiple(boolean$1); - functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); - functionRegistry.addMultiple(color); - functionRegistry.addMultiple(colorBlend); - functionRegistry.addMultiple(dataUri(environment)); - functionRegistry.addMultiple(list); - functionRegistry.addMultiple(mathFunctions); - functionRegistry.addMultiple(number$1); - functionRegistry.addMultiple(string); - functionRegistry.addMultiple(svg()); - functionRegistry.addMultiple(types); - return functions; -}); - -var sourceMapOutput = (function (environment) { - var SourceMapOutput = - /*#__PURE__*/ - function () { - function SourceMapOutput(options) { - _classCallCheck(this, SourceMapOutput); - - this._css = []; - this._rootNode = options.rootNode; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - - if (options.sourceMapFilename) { - this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); - } - - this._outputFilename = options.outputFilename; - this.sourceMapURL = options.sourceMapURL; - - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - - if (options.sourceMapRootpath) { - this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); - - if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { - this._sourceMapRootpath += '/'; - } - } else { - this._sourceMapRootpath = ''; - } - - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); - this._lineNumber = 0; - this._column = 0; +for (var f in colorBlendModeFunctions) { + if (colorBlendModeFunctions.hasOwnProperty(f)) { + colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); } +} - _createClass(SourceMapOutput, [{ - key: "removeBasepath", - value: function removeBasepath(path) { - if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { - path = path.substring(this._sourceMapBasepath.length); +var dataUri = (function (environment) { + var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); }; + return { 'data-uri': function (mimetypeNode, filePathNode) { + if (!filePathNode) { + filePathNode = mimetypeNode; + mimetypeNode = null; + } + var mimetype = mimetypeNode && mimetypeNode.value; + var filePath = filePathNode.value; + var currentFileInfo = this.currentFileInfo; + var currentDirectory = currentFileInfo.rewriteUrls ? + currentFileInfo.currentDirectory : currentFileInfo.entryPath; + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart !== -1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + var context = clone(this.context); + context.rawBuffer = true; + var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); + if (!fileManager) { + return fallback(this, filePathNode); + } + var useBase64 = false; + // detect the mimetype if not given + if (!mimetypeNode) { + mimetype = environment.mimeLookup(filePath); + if (mimetype === 'image/svg+xml') { + useBase64 = false; + } + else { + // use base 64 unless it's an ASCII or UTF-8 format + var charset = environment.charsetLookup(mimetype); + useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; + } + if (useBase64) { + mimetype += ';base64'; + } + } + else { + useBase64 = /;base64$/.test(mimetype); + } + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); + if (!fileSync.contents) { + logger.warn("Skipped data-uri embedding of " + filePath + " because file not found"); + return fallback(this, filePathNode || mimetypeNode); + } + var buf = fileSync.contents; + if (useBase64 && !environment.encodeBase64) { + return fallback(this, filePathNode); + } + buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); + var uri = "data:" + mimetype + "," + buf + fragment; + return new URL(new Quoted("\"" + uri + "\"", uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; +}); - if (path.charAt(0) === '\\' || path.charAt(0) === '/') { - path = path.substring(1); - } +var getItemsFromNode = function (node) { + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + var items = Array.isArray(node.value) ? + node.value : Array(node); + return items; +}; +var list = { + _SELF: function (n) { + return n; + }, + extract: function (values, index) { + // (1-based index) + index = index.value - 1; + return getItemsFromNode(values)[index]; + }, + length: function (values) { + return new Dimension(getItemsFromNode(values).length); + }, + /** + * Creates a Less list of incremental values. + * Modeled after Lodash's range function, also exists natively in PHP + * + * @param {Dimension} [start=1] + * @param {Dimension} end - e.g. 10 or 10px - unit is added to output + * @param {Dimension} [step=1] + */ + range: function (start, end, step) { + var from; + var to; + var stepValue = 1; + var list = []; + if (end) { + to = end; + from = start.value; + if (step) { + stepValue = step.value; + } } - - return path; - } - }, { - key: "normalizeFilename", - value: function normalizeFilename(filename) { - filename = filename.replace(/\\/g, '/'); - filename = this.removeBasepath(filename); - return (this._sourceMapRootpath || '') + filename; - } - }, { - key: "add", - value: function add(chunk, fileInfo, index, mapLines) { - // ignore adding empty strings - if (!chunk) { - return; + else { + from = 1; + to = start; } - - var lines; - var sourceLines; - var columns; - var sourceColumns; - var i; - - if (fileInfo && fileInfo.filename) { - var inputSource = this._contentsMap[fileInfo.filename]; // remove vars/banner added to the top of the file - - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - - if (index < 0) { - index = 0; - } // adjust the source - - - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } // ignore empty content - - - if (inputSource === undefined) { - return; - } - - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split('\n'); - sourceColumns = sourceLines[sourceLines.length - 1]; + for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) { + list.push(new Dimension(i_1, to.unit)); } - - lines = chunk.split('\n'); - columns = lines[lines.length - 1]; - - if (fileInfo && fileInfo.filename) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + 1, - column: this._column - }, - original: { - line: sourceLines.length, - column: sourceColumns.length - }, - source: this.normalizeFilename(fileInfo.filename) - }); - } else { - for (i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + i + 1, - column: i === 0 ? this._column : 0 - }, - original: { - line: sourceLines.length + i, - column: i === 0 ? sourceColumns.length : 0 - }, - source: this.normalizeFilename(fileInfo.filename) - }); + return new Expression(list); + }, + each: function (list, rs) { + var rules = []; + var newRules; + var iterator; + if (list.value && !(list instanceof Quoted)) { + if (Array.isArray(list.value)) { + iterator = list.value; + } + else { + iterator = [list.value]; } - } } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; + else if (list.ruleset) { + iterator = list.ruleset.rules; + } + else if (list.rules) { + iterator = list.rules; + } + else if (Array.isArray(list)) { + iterator = list; + } + else { + iterator = [list]; + } + var valueName = '@value'; + var keyName = '@key'; + var indexName = '@index'; + if (rs.params) { + valueName = rs.params[0] && rs.params[0].name; + keyName = rs.params[1] && rs.params[1].name; + indexName = rs.params[2] && rs.params[2].name; + rs = rs.rules; + } + else { + rs = rs.ruleset; + } + for (var i_2 = 0; i_2 < iterator.length; i_2++) { + var key = void 0; + var value = void 0; + var item = iterator[i_2]; + if (item instanceof Declaration) { + key = typeof item.name === 'string' ? item.name : item.name[0].value; + value = item.value; + } + else { + key = new Dimension(i_2 + 1); + value = item; + } + if (item instanceof Comment) { + continue; + } + newRules = rs.rules.slice(0); + if (valueName) { + newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); + } + if (indexName) { + newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo)); + } + if (keyName) { + newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); + } + rules.push(new Ruleset([new (Selector)([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); } + return new Ruleset([new (Selector)([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); + } +}; - this._css.push(chunk); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this._css.length === 0; - } - }, { - key: "toCSS", - value: function toCSS(context) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ - file: this._outputFilename, - sourceRoot: null - }); - - if (this._outputSourceFiles) { - for (var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) { - var source = this._contentsMap[filename]; +var MathHelper = function (fn, unit, n) { + if (!(n instanceof Dimension)) { + throw { type: 'Argument', message: 'argument must be a number' }; + } + if (unit == null) { + unit = n.unit; + } + else { + n = n.unify(); + } + return new Dimension(fn(parseFloat(n.value)), unit); +}; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } +var mathFunctions = { + // name, unit + ceil: null, + floor: null, + sqrt: null, + abs: null, + tan: '', + sin: '', + cos: '', + atan: 'rad', + asin: 'rad', + acos: 'rad' +}; +for (var f$1 in mathFunctions) { + if (mathFunctions.hasOwnProperty(f$1)) { + mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); + } +} +mathFunctions.round = function (n, f) { + var fraction = typeof f === 'undefined' ? 0 : f.value; + return MathHelper(function (num) { return num.toFixed(fraction); }, null, n); +}; - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); +var minMax = function (isMin, args) { + args = Array.prototype.slice.call(args); + switch (args.length) { + case 0: throw { type: 'Argument', message: 'one or more arguments required' }; + } + var i; // key is the unit.toString() for unified Dimension values, + var j; + var current; + var currentUnified; + var referenceUnified; + var unit; + var unitStatic; + var unitClone; + var // elems only contains original argument values. + order = []; + var values = {}; + // value is the index into the order array. + for (i = 0; i < args.length; i++) { + current = args[i]; + if (!(current instanceof Dimension)) { + if (Array.isArray(args[i].value)) { + Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); } - } + continue; } - - this._rootNode.genCSS(context, this); - - if (this._css.length > 0) { - var sourceMapURL; - var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this.sourceMapURL) { - sourceMapURL = this.sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this._sourceMapFilename; - } - - this.sourceMapURL = sourceMapURL; - this.sourceMap = sourceMapContent; + currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); + unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); + unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; + unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; + j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; + if (j === undefined) { + if (unitStatic !== undefined && unit !== unitStatic) { + throw { type: 'Argument', message: 'incompatible types' }; + } + values[unit] = order.length; + order.push(current); + continue; + } + referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); + if (isMin && currentUnified.value < referenceUnified.value || + !isMin && currentUnified.value > referenceUnified.value) { + order[j] = current; } - - return this._css.join(''); - } - }]); - - return SourceMapOutput; - }(); - - return SourceMapOutput; -}); - -var sourceMapBuilder = (function (SourceMapOutput, environment) { - var SourceMapBuilder = - /*#__PURE__*/ - function () { - function SourceMapBuilder(options) { - _classCallCheck(this, SourceMapBuilder); - - this.options = options; } - - _createClass(SourceMapBuilder, [{ - key: "toCSS", - value: function toCSS(rootNode, options, imports) { - var sourceMapOutput = new SourceMapOutput({ - contentsIgnoredCharsMap: imports.contentsIgnoredChars, - rootNode, - contentsMap: imports.contents, - sourceMapFilename: this.options.sourceMapFilename, - sourceMapURL: this.options.sourceMapURL, - outputFilename: this.options.sourceMapOutputFilename, - sourceMapBasepath: this.options.sourceMapBasepath, - sourceMapRootpath: this.options.sourceMapRootpath, - outputSourceFiles: this.options.outputSourceFiles, - sourceMapGenerator: this.options.sourceMapGenerator, - sourceMapFileInline: this.options.sourceMapFileInline - }); - var css = sourceMapOutput.toCSS(options); - this.sourceMap = sourceMapOutput.sourceMap; - this.sourceMapURL = sourceMapOutput.sourceMapURL; - - if (this.options.sourceMapInputFilename) { - this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + if (order.length == 1) { + return order[0]; + } + args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', '); + return new Anonymous((isMin ? 'min' : 'max') + "(" + args + ")"); +}; +var number$1 = { + min: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; } - - if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { - this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); + return minMax(true, args); + }, + max: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; } - - return css + this.getCSSAppendage(); - } - }, { - key: "getCSSAppendage", - value: function getCSSAppendage() { - var sourceMapURL = this.sourceMapURL; - - if (this.options.sourceMapFileInline) { - if (this.sourceMap === undefined) { - return ''; - } - - sourceMapURL = `data:application/json;base64,${environment.encodeBase64(this.sourceMap)}`; + return minMax(false, args); + }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, + pi: function () { + return new Dimension(Math.PI); + }, + mod: function (a, b) { + return new Dimension(a.value % b.value, a.unit); + }, + pow: function (x, y) { + if (typeof x === 'number' && typeof y === 'number') { + x = new Dimension(x); + y = new Dimension(y); } - - if (sourceMapURL) { - return `/*# sourceMappingURL=${sourceMapURL} */`; + else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { + throw { type: 'Argument', message: 'arguments must be numbers' }; } + return new Dimension(Math.pow(x.value, y.value), x.unit); + }, + percentage: function (n) { + var result = MathHelper(function (num) { return num * 100; }, '%', n); + return result; + } +}; - return ''; - } - }, { - key: "getExternalSourceMap", - value: function getExternalSourceMap() { - return this.sourceMap; - } - }, { - key: "setExternalSourceMap", - value: function setExternalSourceMap(sourceMap) { - this.sourceMap = sourceMap; - } - }, { - key: "isInline", - value: function isInline() { - return this.options.sourceMapFileInline; - } - }, { - key: "getSourceMapURL", - value: function getSourceMapURL() { - return this.sourceMapURL; - } - }, { - key: "getOutputFilename", - value: function getOutputFilename() { - return this.options.sourceMapOutputFilename; - } - }, { - key: "getInputFilename", - value: function getInputFilename() { - return this.sourceMapInputFilename; - } - }]); - - return SourceMapBuilder; - }(); - - return SourceMapBuilder; -}); - -var transformTree = (function (root) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var evaldRoot; - var variables = options.variables; - var evalEnv = new contexts.Eval(options); // - // Allows setting variables with a hash, so: - // - // `{ color: new tree.Color('#f01') }` will become: - // - // new tree.Declaration('@color', - // new tree.Value([ - // new tree.Expression([ - // new tree.Color('#f01') - // ]) - // ]) - // ) - // - - if (typeof variables === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (!(value instanceof tree.Value)) { - if (!(value instanceof tree.Expression)) { - value = new tree.Expression([value]); +var string = { + e: function (str) { + return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); + }, + escape: function (str) { + return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B') + .replace(/\(/g, '%28').replace(/\)/g, '%29')); + }, + replace: function (string, pattern, replacement, flags) { + var result = string.value; + replacement = (replacement.type === 'Quoted') ? + replacement.value : replacement.toCSS(); + result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); + return new Quoted(string.quote || '', result, string.escaped); + }, + '%': function (string /* arg, arg, ... */) { + var args = Array.prototype.slice.call(arguments, 1); + var result = string.value; + var _loop_1 = function (i_1) { + /* jshint loopfunc:true */ + result = result.replace(/%[sda]/i, function (token) { + var value = ((args[i_1].type === 'Quoted') && + token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS(); + return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; + }); + }; + for (var i_1 = 0; i_1 < args.length; i_1++) { + _loop_1(i_1); } - - value = new tree.Value([value]); - } - - return new tree.Declaration(`@${k}`, value, false, null, 0); - }); - evalEnv.frames = [new tree.Ruleset(null, variables)]; - } - - var visitors$1 = [new visitors.JoinSelectorVisitor(), new visitors.MarkVisibleSelectorsVisitor(true), new visitors.ExtendVisitor(), new visitors.ToCSSVisitor({ - compress: Boolean(options.compress) - })]; - var preEvalVisitors = []; - var v; - var visitorIterator; - /** - * first() / get() allows visitors to be added while visiting - * - * @todo Add scoping for visitors just like functions for @plugin; right now they're global - */ - - if (options.pluginManager) { - visitorIterator = options.pluginManager.visitor(); - - for (var i = 0; i < 2; i++) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (v.isPreEvalVisitor) { - if (i === 0 || preEvalVisitors.indexOf(v) === -1) { - preEvalVisitors.push(v); - v.run(root); - } - } else { - if (i === 0 || visitors$1.indexOf(v) === -1) { - if (v.isPreVisitor) { - visitors$1.unshift(v); - } else { - visitors$1.push(v); - } - } - } - } - } - } - - evaldRoot = root.eval(evalEnv); - - for (var i = 0; i < visitors$1.length; i++) { - visitors$1[i].run(evaldRoot); - } // Run any remaining visitors added after eval pass - - - if (options.pluginManager) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { - v.run(evaldRoot); - } + result = result.replace(/%%/g, '%'); + return new Quoted(string.quote || '', result, string.escaped); } - } +}; - return evaldRoot; +var svg = (function (environment) { + return { 'svg-gradient': function (direction) { + var stops; + var gradientDirectionSvg; + var gradientType = 'linear'; + var rectangleDimension = 'x="0" y="0" width="1" height="1"'; + var renderEnv = { compress: false }; + var returner; + var directionValue = direction.toCSS(renderEnv); + var i; + var color; + var position; + var positionValue; + var alpha; + function throwArgumentDescriptor() { + throw { type: 'Argument', + message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + + ' end_color [end_position] or direction, color list' }; + } + if (arguments.length == 2) { + if (arguments[1].value.length < 2) { + throwArgumentDescriptor(); + } + stops = arguments[1].value; + } + else if (arguments.length < 3) { + throwArgumentDescriptor(); + } + else { + stops = Array.prototype.slice.call(arguments, 1); + } + switch (directionValue) { + case 'to bottom': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; + break; + case 'to right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; + break; + case 'to bottom right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; + break; + case 'to top right': + gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; + break; + case 'ellipse': + case 'ellipse at center': + gradientType = 'radial'; + gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; + rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; + break; + default: + throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' }; + } + returner = "<" + gradientType + "Gradient id=\"g\" " + gradientDirectionSvg + ">"; + for (i = 0; i < stops.length; i += 1) { + if (stops[i] instanceof Expression) { + color = stops[i].value[0]; + position = stops[i].value[1]; + } + else { + color = stops[i]; + position = undefined; + } + if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) { + throwArgumentDescriptor(); + } + positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; + alpha = color.alpha; + returner += ""; + } + returner += ""; + returner = encodeURIComponent(returner); + returner = "data:image/svg+xml," + returner; + return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; }); -var parseTree = (function (SourceMapBuilder) { - var ParseTree = - /*#__PURE__*/ - function () { - function ParseTree(root, imports) { - _classCallCheck(this, ParseTree); - - this.root = root; - this.imports = imports; +var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; }; +var isunit = function (n, unit) { + if (unit === undefined) { + throw { type: 'Argument', message: 'missing the required second argument to isunit.' }; } - - _createClass(ParseTree, [{ - key: "toCSS", - value: function toCSS(options) { - var evaldRoot; - var result = {}; - var sourceMapBuilder; - - try { - evaldRoot = transformTree(this.root, options); - } catch (e) { - throw new LessError(e, this.imports); + unit = typeof unit.value === 'string' ? unit.value : unit; + if (typeof unit !== 'string') { + throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' }; + } + return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False; +}; +var types = { + isruleset: function (n) { + return isa(n, DetachedRuleset); + }, + iscolor: function (n) { + return isa(n, Color); + }, + isnumber: function (n) { + return isa(n, Dimension); + }, + isstring: function (n) { + return isa(n, Quoted); + }, + iskeyword: function (n) { + return isa(n, Keyword); + }, + isurl: function (n) { + return isa(n, URL); + }, + ispixel: function (n) { + return isunit(n, 'px'); + }, + ispercentage: function (n) { + return isunit(n, '%'); + }, + isem: function (n) { + return isunit(n, 'em'); + }, + isunit: isunit, + unit: function (val, unit) { + if (!(val instanceof Dimension)) { + throw { type: 'Argument', + message: "the first argument to unit must be a number" + (val instanceof Operation ? '. Have you forgotten parenthesis?' : '') }; + } + if (unit) { + if (unit instanceof Keyword) { + unit = unit.value; + } + else { + unit = unit.toCSS(); + } } - - try { - var compress = Boolean(options.compress); - - if (compress) { - logger.warn('The compress option has been deprecated. ' + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); - } - - var toCSSOptions = { - compress, - dumpLineNumbers: options.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8 - }; - - if (options.sourceMap) { - sourceMapBuilder = new SourceMapBuilder(options.sourceMap); - result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); - } else { - result.css = evaldRoot.toCSS(toCSSOptions); - } - } catch (e) { - throw new LessError(e, this.imports); + else { + unit = ''; } + return new Dimension(val.value, unit); + }, + 'get-unit': function (n) { + return new Anonymous(n.unit); + } +}; - if (options.pluginManager) { - var postProcessors = options.pluginManager.getPostProcessors(); +var Functions = (function (environment) { + var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller }; + // register functions + functionRegistry.addMultiple(boolean$1); + functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); + functionRegistry.addMultiple(color); + functionRegistry.addMultiple(colorBlend); + functionRegistry.addMultiple(dataUri(environment)); + functionRegistry.addMultiple(list); + functionRegistry.addMultiple(mathFunctions); + functionRegistry.addMultiple(number$1); + functionRegistry.addMultiple(string); + functionRegistry.addMultiple(svg()); + functionRegistry.addMultiple(types); + return functions; +}); + +var sourceMapOutput = (function (environment) { + var SourceMapOutput = /** @class */ (function () { + function SourceMapOutput(options) { + this._css = []; + this._rootNode = options.rootNode; + this._contentsMap = options.contentsMap; + this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; + if (options.sourceMapFilename) { + this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); + } + this._outputFilename = options.outputFilename; + this.sourceMapURL = options.sourceMapURL; + if (options.sourceMapBasepath) { + this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); + } + if (options.sourceMapRootpath) { + this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); + if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { + this._sourceMapRootpath += '/'; + } + } + else { + this._sourceMapRootpath = ''; + } + this._outputSourceFiles = options.outputSourceFiles; + this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); + this._lineNumber = 0; + this._column = 0; + } + SourceMapOutput.prototype.removeBasepath = function (path) { + if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { + path = path.substring(this._sourceMapBasepath.length); + if (path.charAt(0) === '\\' || path.charAt(0) === '/') { + path = path.substring(1); + } + } + return path; + }; + SourceMapOutput.prototype.normalizeFilename = function (filename) { + filename = filename.replace(/\\/g, '/'); + filename = this.removeBasepath(filename); + return (this._sourceMapRootpath || '') + filename; + }; + SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) { + // ignore adding empty strings + if (!chunk) { + return; + } + var lines; + var sourceLines; + var columns; + var sourceColumns; + var i; + if (fileInfo && fileInfo.filename) { + var inputSource = this._contentsMap[fileInfo.filename]; + // remove vars/banner added to the top of the file + if (this._contentsIgnoredCharsMap[fileInfo.filename]) { + // adjust the index + index -= this._contentsIgnoredCharsMap[fileInfo.filename]; + if (index < 0) { + index = 0; + } + // adjust the source + inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); + } + // ignore empty content + if (inputSource === undefined) { + return; + } + inputSource = inputSource.substring(0, index); + sourceLines = inputSource.split('\n'); + sourceColumns = sourceLines[sourceLines.length - 1]; + } + lines = chunk.split('\n'); + columns = lines[lines.length - 1]; + if (fileInfo && fileInfo.filename) { + if (!mapLines) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column }, + original: { line: sourceLines.length, column: sourceColumns.length }, + source: this.normalizeFilename(fileInfo.filename) }); + } + else { + for (i = 0; i < lines.length; i++) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 }, + original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 }, + source: this.normalizeFilename(fileInfo.filename) }); + } + } + } + if (lines.length === 1) { + this._column += columns.length; + } + else { + this._lineNumber += lines.length - 1; + this._column = columns.length; + } + this._css.push(chunk); + }; + SourceMapOutput.prototype.isEmpty = function () { + return this._css.length === 0; + }; + SourceMapOutput.prototype.toCSS = function (context) { + this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); + if (this._outputSourceFiles) { + for (var filename in this._contentsMap) { + if (this._contentsMap.hasOwnProperty(filename)) { + var source = this._contentsMap[filename]; + if (this._contentsIgnoredCharsMap[filename]) { + source = source.slice(this._contentsIgnoredCharsMap[filename]); + } + this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + } + } + } + this._rootNode.genCSS(context, this); + if (this._css.length > 0) { + var sourceMapURL = void 0; + var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); + if (this.sourceMapURL) { + sourceMapURL = this.sourceMapURL; + } + else if (this._sourceMapFilename) { + sourceMapURL = this._sourceMapFilename; + } + this.sourceMapURL = sourceMapURL; + this.sourceMap = sourceMapContent; + } + return this._css.join(''); + }; + return SourceMapOutput; + }()); + return SourceMapOutput; +}); - for (var i = 0; i < postProcessors.length; i++) { - result.css = postProcessors[i].process(result.css, { - sourceMap: sourceMapBuilder, - options, - imports: this.imports +var sourceMapBuilder = (function (SourceMapOutput, environment) { + var SourceMapBuilder = /** @class */ (function () { + function SourceMapBuilder(options) { + this.options = options; + } + SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) { + var sourceMapOutput = new SourceMapOutput({ + contentsIgnoredCharsMap: imports.contentsIgnoredChars, + rootNode: rootNode, + contentsMap: imports.contents, + sourceMapFilename: this.options.sourceMapFilename, + sourceMapURL: this.options.sourceMapURL, + outputFilename: this.options.sourceMapOutputFilename, + sourceMapBasepath: this.options.sourceMapBasepath, + sourceMapRootpath: this.options.sourceMapRootpath, + outputSourceFiles: this.options.outputSourceFiles, + sourceMapGenerator: this.options.sourceMapGenerator, + sourceMapFileInline: this.options.sourceMapFileInline }); - } - } + var css = sourceMapOutput.toCSS(options); + this.sourceMap = sourceMapOutput.sourceMap; + this.sourceMapURL = sourceMapOutput.sourceMapURL; + if (this.options.sourceMapInputFilename) { + this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + } + if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { + this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); + } + return css + this.getCSSAppendage(); + }; + SourceMapBuilder.prototype.getCSSAppendage = function () { + var sourceMapURL = this.sourceMapURL; + if (this.options.sourceMapFileInline) { + if (this.sourceMap === undefined) { + return ''; + } + sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap); + } + if (sourceMapURL) { + return "/*# sourceMappingURL=" + sourceMapURL + " */"; + } + return ''; + }; + SourceMapBuilder.prototype.getExternalSourceMap = function () { + return this.sourceMap; + }; + SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) { + this.sourceMap = sourceMap; + }; + SourceMapBuilder.prototype.isInline = function () { + return this.options.sourceMapFileInline; + }; + SourceMapBuilder.prototype.getSourceMapURL = function () { + return this.sourceMapURL; + }; + SourceMapBuilder.prototype.getOutputFilename = function () { + return this.options.sourceMapOutputFilename; + }; + SourceMapBuilder.prototype.getInputFilename = function () { + return this.sourceMapInputFilename; + }; + return SourceMapBuilder; + }()); + return SourceMapBuilder; +}); - if (options.sourceMap) { - result.map = sourceMapBuilder.getExternalSourceMap(); +var transformTree = (function (root, options) { + if (options === void 0) { options = {}; } + var evaldRoot; + var variables = options.variables; + var evalEnv = new contexts.Eval(options); + // + // Allows setting variables with a hash, so: + // + // `{ color: new tree.Color('#f01') }` will become: + // + // new tree.Declaration('@color', + // new tree.Value([ + // new tree.Expression([ + // new tree.Color('#f01') + // ]) + // ]) + // ) + // + if (typeof variables === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables).map(function (k) { + var value = variables[k]; + if (!(value instanceof tree.Value)) { + if (!(value instanceof tree.Expression)) { + value = new tree.Expression([value]); + } + value = new tree.Value([value]); + } + return new tree.Declaration("@" + k, value, false, null, 0); + }); + evalEnv.frames = [new tree.Ruleset(null, variables)]; + } + var visitors$1 = [ + new visitors.JoinSelectorVisitor(), + new visitors.MarkVisibleSelectorsVisitor(true), + new visitors.ExtendVisitor(), + new visitors.ToCSSVisitor({ compress: Boolean(options.compress) }) + ]; + var preEvalVisitors = []; + var v; + var visitorIterator; + /** + * first() / get() allows visitors to be added while visiting + * + * @todo Add scoping for visitors just like functions for @plugin; right now they're global + */ + if (options.pluginManager) { + visitorIterator = options.pluginManager.visitor(); + for (var i = 0; i < 2; i++) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (v.isPreEvalVisitor) { + if (i === 0 || preEvalVisitors.indexOf(v) === -1) { + preEvalVisitors.push(v); + v.run(root); + } + } + else { + if (i === 0 || visitors$1.indexOf(v) === -1) { + if (v.isPreVisitor) { + visitors$1.unshift(v); + } + else { + visitors$1.push(v); + } + } + } + } } - - result.imports = []; - - for (var file in this.imports.files) { - if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) { - result.imports.push(file); - } + } + evaldRoot = root.eval(evalEnv); + for (var i = 0; i < visitors$1.length; i++) { + visitors$1[i].run(evaldRoot); + } + // Run any remaining visitors added after eval pass + if (options.pluginManager) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { + v.run(evaldRoot); + } } + } + return evaldRoot; +}); - return result; - } - }]); - +var parseTree = (function (SourceMapBuilder) { + var ParseTree = /** @class */ (function () { + function ParseTree(root, imports) { + this.root = root; + this.imports = imports; + } + ParseTree.prototype.toCSS = function (options) { + var evaldRoot; + var result = {}; + var sourceMapBuilder; + try { + evaldRoot = transformTree(this.root, options); + } + catch (e) { + throw new LessError(e, this.imports); + } + try { + var compress = Boolean(options.compress); + if (compress) { + logger.warn('The compress option has been deprecated. ' + + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); + } + var toCSSOptions = { + compress: compress, + dumpLineNumbers: options.dumpLineNumbers, + strictUnits: Boolean(options.strictUnits), + numPrecision: 8 + }; + if (options.sourceMap) { + sourceMapBuilder = new SourceMapBuilder(options.sourceMap); + result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); + } + else { + result.css = evaldRoot.toCSS(toCSSOptions); + } + } + catch (e) { + throw new LessError(e, this.imports); + } + if (options.pluginManager) { + var postProcessors = options.pluginManager.getPostProcessors(); + for (var i_1 = 0; i_1 < postProcessors.length; i_1++) { + result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports }); + } + } + if (options.sourceMap) { + result.map = sourceMapBuilder.getExternalSourceMap(); + } + result.imports = []; + for (var file_1 in this.imports.files) { + if (this.imports.files.hasOwnProperty(file_1) && file_1 !== this.imports.rootFilename) { + result.imports.push(file_1); + } + } + return result; + }; + return ParseTree; + }()); return ParseTree; - }(); - - return ParseTree; }); var importManager = (function (environment) { - // FileInfo = { - // 'rewriteUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - var ImportManager = - /*#__PURE__*/ - function () { - function ImportManager(less, context, rootFileInfo) { - _classCallCheck(this, ImportManager); - - this.less = less; - this.rootFilename = rootFileInfo.filename; - this.paths = context.paths || []; // Search paths, when importing - - this.contents = {}; // map - filename to contents of all the files - - this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore - - this.mime = context.mime; - this.error = null; - this.context = context; // Deprecated? Unused outside of here, could be useful. - - this.queue = []; // Files which haven't been imported yet - - this.files = {}; // Holds the imported parse trees. - } - /** - * Add an import to be imported - * @param path - the raw path - * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) - * @param currentFileInfo - the current file info (used for instance to work out relative paths) - * @param importOptions - import options - * @param callback - callback for when it is imported - */ - - - _createClass(ImportManager, [{ - key: "push", - value: function push(path, tryAppendExtension, currentFileInfo, importOptions, callback) { - var importManager = this; - var pluginLoader = this.context.pluginManager.Loader; - this.queue.push(path); - - var fileParsedFunc = function fileParsedFunc(e, root, fullPath) { - importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue - - var importedEqualsRoot = fullPath === importManager.rootFilename; - - if (importOptions.optional && e) { - callback(null, { - rules: [] - }, false, null); - logger.info(`The file ${fullPath} was skipped because it was not found and the import was marked optional.`); - } else { - // Inline imports aren't cached here. - // If we start to cache them, please make sure they won't conflict with non-inline imports of the - // same name as they used to do before this comment and the condition below have been added. - if (!importManager.files[fullPath] && !importOptions.inline) { - importManager.files[fullPath] = { - root, - options: importOptions - }; + // FileInfo = { + // 'rewriteUrls' - option - whether to adjust URL's to be relative + // 'filename' - full resolved filename of current file + // 'rootpath' - path to append to normal URLs for this node + // 'currentDirectory' - path to the current file, absolute + // 'rootFilename' - filename of the base file + // 'entryPath' - absolute path to the entry file + // 'reference' - whether the file should not be output and only output parts that are referenced + var ImportManager = /** @class */ (function () { + function ImportManager(less, context, rootFileInfo) { + this.less = less; + this.rootFilename = rootFileInfo.filename; + this.paths = context.paths || []; // Search paths, when importing + this.contents = {}; // map - filename to contents of all the files + this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore + this.mime = context.mime; + this.error = null; + this.context = context; + // Deprecated? Unused outside of here, could be useful. + this.queue = []; // Files which haven't been imported yet + this.files = {}; // Holds the imported parse trees. + } + /** + * Add an import to be imported + * @param path - the raw path + * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) + * @param currentFileInfo - the current file info (used for instance to work out relative paths) + * @param importOptions - import options + * @param callback - callback for when it is imported + */ + ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) { + var importManager = this; + var pluginLoader = this.context.pluginManager.Loader; + this.queue.push(path); + var fileParsedFunc = function (e, root, fullPath) { + importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue + var importedEqualsRoot = fullPath === importManager.rootFilename; + if (importOptions.optional && e) { + callback(null, { rules: [] }, false, null); + logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional."); + } + else { + // Inline imports aren't cached here. + // If we start to cache them, please make sure they won't conflict with non-inline imports of the + // same name as they used to do before this comment and the condition below have been added. + if (!importManager.files[fullPath] && !importOptions.inline) { + importManager.files[fullPath] = { root: root, options: importOptions }; + } + if (e && !importManager.error) { + importManager.error = e; + } + callback(e, root, importedEqualsRoot, fullPath); + } + }; + var newFileInfo = { + rewriteUrls: this.context.rewriteUrls, + entryPath: currentFileInfo.entryPath, + rootpath: currentFileInfo.rootpath, + rootFilename: currentFileInfo.rootFilename + }; + var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + if (!fileManager) { + fileParsedFunc({ message: "Could not find a file-manager for " + path }); + return; + } + var loadFileCallback = function (loadedFile) { + var plugin; + var resolvedFilename = loadedFile.filename; + var contents = loadedFile.contents.replace(/^\uFEFF/, ''); + // Pass on an updated rootpath if path of imported file is relative and file + // is in a (sub|sup) directory + // + // Examples: + // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', + // then rootpath should become 'less/module/nav/' + // - If path of imported file is '../mixins.less' and rootpath is 'less/', + // then rootpath should become 'less/../' + newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); + if (newFileInfo.rewriteUrls) { + newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); + if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { + newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + } + } + newFileInfo.filename = resolvedFilename; + var newEnv = new contexts.Parse(importManager.context); + newEnv.processImports = false; + importManager.contents[resolvedFilename] = contents; + if (currentFileInfo.reference || importOptions.reference) { + newFileInfo.reference = true; + } + if (importOptions.isPlugin) { + plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); + if (plugin instanceof LessError) { + fileParsedFunc(plugin, null, resolvedFilename); + } + else { + fileParsedFunc(null, plugin, resolvedFilename); + } + } + else if (importOptions.inline) { + fileParsedFunc(null, contents, resolvedFilename); + } + else { + // import (multiple) parse trees apparently get altered and can't be cached. + // TODO: investigate why this is + if (importManager.files[resolvedFilename] + && !importManager.files[resolvedFilename].options.multiple + && !importOptions.multiple) { + fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); + } + else { + new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { + fileParsedFunc(e, root, resolvedFilename); + }); + } + } + }; + var promise; + var context = clone(this.context); + if (tryAppendExtension) { + context.ext = importOptions.isPlugin ? '.js' : '.less'; } - - if (e && !importManager.error) { - importManager.error = e; + if (importOptions.isPlugin) { + context.mime = 'application/javascript'; + promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); } - - callback(e, root, importedEqualsRoot, fullPath); - } - }; - - var newFileInfo = { - rewriteUrls: this.context.rewriteUrls, - entryPath: currentFileInfo.entryPath, - rootpath: currentFileInfo.rootpath, - rootFilename: currentFileInfo.rootFilename - }; - var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); - - if (!fileManager) { - fileParsedFunc({ - message: `Could not find a file-manager for ${path}` - }); - return; - } - - var loadFileCallback = function loadFileCallback(loadedFile) { - var plugin; - var resolvedFilename = loadedFile.filename; - var contents = loadedFile.contents.replace(/^\uFEFF/, ''); // Pass on an updated rootpath if path of imported file is relative and file - // is in a (sub|sup) directory - // - // Examples: - // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', - // then rootpath should become 'less/module/nav/' - // - If path of imported file is '../mixins.less' and rootpath is 'less/', - // then rootpath should become 'less/../' - - newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); - - if (newFileInfo.rewriteUrls) { - newFileInfo.rootpath = fileManager.join(importManager.context.rootpath || '', fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); - - if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { - newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + else { + promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { + if (err) { + fileParsedFunc(err); + } + else { + loadFileCallback(loadedFile); + } + }); + } + if (promise) { + promise.then(loadFileCallback, fileParsedFunc); } - } - - newFileInfo.filename = resolvedFilename; - var newEnv = new contexts.Parse(importManager.context); - newEnv.processImports = false; - importManager.contents[resolvedFilename] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.isPlugin) { - plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); - - if (plugin instanceof LessError) { - fileParsedFunc(plugin, null, resolvedFilename); - } else { - fileParsedFunc(null, plugin, resolvedFilename); - } - } else if (importOptions.inline) { - fileParsedFunc(null, contents, resolvedFilename); - } else { - // import (multiple) parse trees apparently get altered and can't be cached. - // TODO: investigate why this is - if (importManager.files[resolvedFilename] && !importManager.files[resolvedFilename].options.multiple && !importOptions.multiple) { - fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); - } else { - new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { - fileParsedFunc(e, root, resolvedFilename); - }); - } - } }; - - var promise; - var context = clone(this.context); - - if (tryAppendExtension) { - context.ext = importOptions.isPlugin ? '.js' : '.less'; - } - - if (importOptions.isPlugin) { - context.mime = 'application/javascript'; - promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); - } else { - promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { - if (err) { - fileParsedFunc(err); - } else { - loadFileCallback(loadedFile); - } - }); - } - - if (promise) { - promise.then(loadFileCallback, fileParsedFunc); - } - } - }]); - + return ImportManager; + }()); return ImportManager; - }(); - - return ImportManager; }); var Render = (function (environment, ParseTree, ImportManager) { - var render = function render(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - render.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - this.parse(input, options, function (err, root, imports, options) { - if (err) { - return callback(err); + var render = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + render.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - - var result; - - try { - var parseTree = new ParseTree(root, imports); - result = parseTree.toCSS(options); - } catch (err) { - return callback(err); + else { + this.parse(input, options, function (err, root, imports, options) { + if (err) { + return callback(err); + } + var result; + try { + var parseTree = new ParseTree(root, imports); + result = parseTree.toCSS(options); + } + catch (err) { + return callback(err); + } + callback(null, result); + }); } - - callback(null, result); - }); - } - }; - - return render; + }; + return render; }); /** * Plugin Manager */ -var PluginManager = -/*#__PURE__*/ -function () { - function PluginManager(less) { - _classCallCheck(this, PluginManager); - - this.less = less; - this.visitors = []; - this.preProcessors = []; - this.postProcessors = []; - this.installedPlugins = []; - this.fileManagers = []; - this.iterator = -1; - this.pluginCache = {}; - this.Loader = new less.PluginLoader(less); - } - /** - * Adds all the plugins in the array - * @param {Array} plugins - */ - - - _createClass(PluginManager, [{ - key: "addPlugins", - value: function addPlugins(plugins) { - if (plugins) { - for (var i = 0; i < plugins.length; i++) { - this.addPlugin(plugins[i]); - } - } +var PluginManager = /** @class */ (function () { + function PluginManager(less) { + this.less = less; + this.visitors = []; + this.preProcessors = []; + this.postProcessors = []; + this.installedPlugins = []; + this.fileManagers = []; + this.iterator = -1; + this.pluginCache = {}; + this.Loader = new less.PluginLoader(less); } + /** + * Adds all the plugins in the array + * @param {Array} plugins + */ + PluginManager.prototype.addPlugins = function (plugins) { + if (plugins) { + for (var i_1 = 0; i_1 < plugins.length; i_1++) { + this.addPlugin(plugins[i_1]); + } + } + }; /** * * @param plugin * @param {String} filename */ - - }, { - key: "addPlugin", - value: function addPlugin(plugin, filename, functionRegistry) { - this.installedPlugins.push(plugin); - - if (filename) { - this.pluginCache[filename] = plugin; - } - - if (plugin.install) { - plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); - } - } + PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) { + this.installedPlugins.push(plugin); + if (filename) { + this.pluginCache[filename] = plugin; + } + if (plugin.install) { + plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); + } + }; /** * * @param filename */ - - }, { - key: "get", - value: function get(filename) { - return this.pluginCache[filename]; - } + PluginManager.prototype.get = function (filename) { + return this.pluginCache[filename]; + }; /** * Adds a visitor. The visitor object has options on itself to determine * when it should run. * @param visitor */ - - }, { - key: "addVisitor", - value: function addVisitor(visitor) { - this.visitors.push(visitor); - } + PluginManager.prototype.addVisitor = function (visitor) { + this.visitors.push(visitor); + }; /** * Adds a pre processor object * @param {object} preProcessor * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import */ - - }, { - key: "addPreProcessor", - value: function addPreProcessor(preProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { - if (this.preProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPreProcessor = function (preProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { + if (this.preProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.preProcessors.splice(indexToInsertAt, 0, { - preProcessor, - priority - }); - } + this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority }); + }; /** * Adds a post processor object * @param {object} postProcessor * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression */ - - }, { - key: "addPostProcessor", - value: function addPostProcessor(postProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { - if (this.postProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPostProcessor = function (postProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { + if (this.postProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.postProcessors.splice(indexToInsertAt, 0, { - postProcessor, - priority - }); - } + this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority }); + }; /** * * @param manager */ - - }, { - key: "addFileManager", - value: function addFileManager(manager) { - this.fileManagers.push(manager); - } + PluginManager.prototype.addFileManager = function (manager) { + this.fileManagers.push(manager); + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPreProcessors", - value: function getPreProcessors() { - var preProcessors = []; - - for (var i = 0; i < this.preProcessors.length; i++) { - preProcessors.push(this.preProcessors[i].preProcessor); - } - - return preProcessors; - } + PluginManager.prototype.getPreProcessors = function () { + var preProcessors = []; + for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) { + preProcessors.push(this.preProcessors[i_2].preProcessor); + } + return preProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPostProcessors", - value: function getPostProcessors() { - var postProcessors = []; - - for (var i = 0; i < this.postProcessors.length; i++) { - postProcessors.push(this.postProcessors[i].postProcessor); - } - - return postProcessors; - } + PluginManager.prototype.getPostProcessors = function () { + var postProcessors = []; + for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) { + postProcessors.push(this.postProcessors[i_3].postProcessor); + } + return postProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getVisitors", - value: function getVisitors() { - return this.visitors; - } - }, { - key: "visitor", - value: function visitor() { - var self = this; - return { - first: function first() { - self.iterator = -1; - return self.visitors[self.iterator]; - }, - get: function get() { - self.iterator += 1; - return self.visitors[self.iterator]; - } - }; - } + PluginManager.prototype.getVisitors = function () { + return this.visitors; + }; + PluginManager.prototype.visitor = function () { + var self = this; + return { + first: function () { + self.iterator = -1; + return self.visitors[self.iterator]; + }, + get: function () { + self.iterator += 1; + return self.visitors[self.iterator]; + } + }; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getFileManagers", - value: function getFileManagers() { - return this.fileManagers; - } - }]); - - return PluginManager; -}(); - + PluginManager.prototype.getFileManagers = function () { + return this.fileManagers; + }; + return PluginManager; +}()); var pm; - function PluginManagerFactory(less, newFactory) { - if (newFactory || !pm) { - pm = new PluginManager(less); - } - - return pm; + if (newFactory || !pm) { + pm = new PluginManager(less); + } + return pm; } var Parse = (function (environment, ParseTree, ImportManager) { - var parse = function parse(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - parse.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - var context; - var rootFileInfo; - var pluginManager = new PluginManagerFactory(this, !options.reUsePluginManager); - options.pluginManager = pluginManager; - context = new contexts.Parse(options); - - if (options.rootFileInfo) { - rootFileInfo = options.rootFileInfo; - } else { - var filename = options.filename || 'input'; - var entryPath = filename.replace(/[^\/\\]*$/, ''); - rootFileInfo = { - filename, - rewriteUrls: context.rewriteUrls, - rootpath: context.rootpath || '', - currentDirectory: entryPath, - entryPath, - rootFilename: filename - }; // add in a missing trailing slash - - if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { - rootFileInfo.rootpath += '/'; + var parse = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + parse.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - } - - var imports = new ImportManager(this, context, rootFileInfo); - this.importManager = imports; // TODO: allow the plugins to be just a list of paths or names - // Do an async plugin queue like lessc - - if (options.plugins) { - options.plugins.forEach(function (plugin) { - var evalResult; - var contents; - - if (plugin.fileContent) { - contents = plugin.fileContent.replace(/^\uFEFF/, ''); - evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename); - - if (evalResult instanceof LessError) { - return callback(evalResult); + else { + var context_1; + var rootFileInfo = void 0; + var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager); + options.pluginManager = pluginManager_1; + context_1 = new contexts.Parse(options); + if (options.rootFileInfo) { + rootFileInfo = options.rootFileInfo; } - } else { - pluginManager.addPlugin(plugin); - } - }); - } - - new Parser(context, imports, rootFileInfo).parse(input, function (e, root) { - if (e) { - return callback(e); + else { + var filename = options.filename || 'input'; + var entryPath = filename.replace(/[^\/\\]*$/, ''); + rootFileInfo = { + filename: filename, + rewriteUrls: context_1.rewriteUrls, + rootpath: context_1.rootpath || '', + currentDirectory: entryPath, + entryPath: entryPath, + rootFilename: filename + }; + // add in a missing trailing slash + if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { + rootFileInfo.rootpath += '/'; + } + } + var imports_1 = new ImportManager(this, context_1, rootFileInfo); + this.importManager = imports_1; + // TODO: allow the plugins to be just a list of paths or names + // Do an async plugin queue like lessc + if (options.plugins) { + options.plugins.forEach(function (plugin) { + var evalResult; + var contents; + if (plugin.fileContent) { + contents = plugin.fileContent.replace(/^\uFEFF/, ''); + evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename); + if (evalResult instanceof LessError) { + return callback(evalResult); + } + } + else { + pluginManager_1.addPlugin(plugin); + } + }); + } + new Parser(context_1, imports_1, rootFileInfo) + .parse(input, function (e, root) { + if (e) { + return callback(e); + } + callback(null, root, imports_1, options); + }, options); } - - callback(null, root, imports, options); - }, options); - } - }; - - return parse; + }; + return parse; }); var createFromEnvironment = (function (environment, fileManagers) { - /** - * @todo - * This original code could be improved quite a bit. - * Many classes / modules currently add side-effects / mutations to passed in objects, - * which makes it hard to refactor and reason about. - */ - environment = new environment$1(environment, fileManagers); - var SourceMapOutput = sourceMapOutput(environment); - var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment); - var ParseTree = parseTree(SourceMapBuilder); - var ImportManager = importManager(environment); - var render = Render(environment, ParseTree); - var parse = Parse(environment, ParseTree, ImportManager); - var functions = Functions(environment); - /** - * @todo - * This root properties / methods need to be organized. - * It's not clear what should / must be public and why. - */ - - var initial = { - version: [3, 10, 3], - data, - tree, - Environment: environment$1, - AbstractFileManager, - AbstractPluginLoader, - environment, - visitors, - Parser, - functions, - contexts, - SourceMapOutput, - SourceMapBuilder, - ParseTree, - ImportManager, - render, - parse, - LessError, - transformTree, - utils, - PluginManager: PluginManagerFactory, - logger - }; // Create a public API - - var ctor = function ctor(t) { - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return _construct(t, args); + /** + * @todo + * This original code could be improved quite a bit. + * Many classes / modules currently add side-effects / mutations to passed in objects, + * which makes it hard to refactor and reason about. + */ + environment = new environment$1(environment, fileManagers); + var SourceMapOutput = sourceMapOutput(environment); + var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment); + var ParseTree = parseTree(SourceMapBuilder); + var ImportManager = importManager(environment); + var render = Render(environment, ParseTree); + var parse = Parse(environment, ParseTree, ImportManager); + var functions = Functions(environment); + /** + * @todo + * This root properties / methods need to be organized. + * It's not clear what should / must be public and why. + */ + var initial = { + version: [3, 11, 0], + data: data, + tree: tree, + Environment: environment$1, + AbstractFileManager: AbstractFileManager, + AbstractPluginLoader: AbstractPluginLoader, + environment: environment, + visitors: visitors, + Parser: Parser, + functions: functions, + contexts: contexts, + SourceMapOutput: SourceMapOutput, + SourceMapBuilder: SourceMapBuilder, + ParseTree: ParseTree, + ImportManager: ImportManager, + render: render, + parse: parse, + LessError: LessError, + transformTree: transformTree, + utils: utils, + PluginManager: PluginManagerFactory, + logger: logger }; - }; - - var t; - var api = Object.create(initial); - - for (var n in initial.tree) { - /* eslint guard-for-in: 0 */ - t = initial.tree[n]; - - if (typeof t === 'function') { - api[n.toLowerCase()] = ctor(t); - } else { - api[n] = Object.create(null); - - for (var o in t) { + // Create a public API + var ctor = function (t) { return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new (t.bind.apply(t, tslib.__spreadArrays([void 0], args)))(); + }; }; + var t; + var api = Object.create(initial); + for (var n in initial.tree) { /* eslint guard-for-in: 0 */ - api[n][o.toLowerCase()] = ctor(t[o]); - } + t = initial.tree[n]; + if (typeof t === 'function') { + api[n.toLowerCase()] = ctor(t); + } + else { + api[n] = Object.create(null); + for (var o in t) { + /* eslint guard-for-in: 0 */ + api[n][o.toLowerCase()] = ctor(t[o]); + } + } } - } - - return api; + return api; }); function createCommonjsModule(fn, module) { @@ -13427,303 +10619,264 @@ function createCommonjsModule(fn, module) { } var lesscHelper = createCommonjsModule(function (module, exports) { - // lessc_helper.js - // - // helper functions for lessc - var lessc_helper = { - // Stylize a string - stylize: function stylize(str, style) { - var styles = { - 'reset': [0, 0], - 'bold': [1, 22], - 'inverse': [7, 27], - 'underline': [4, 24], - 'yellow': [33, 39], - 'green': [32, 39], - 'red': [31, 39], - 'grey': [90, 39] - }; - return `\x1b[${styles[style][0]}m${str}\x1b[${styles[style][1]}m`; - }, - // Print command line options - printUsage: function printUsage() { - console.log('usage: lessc [option option=parameter ...] [destination]'); - console.log(''); - console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.'); - console.log(''); - console.log('options:'); - console.log(' -h, --help Prints help (this message) and exit.'); - console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.'); - console.log(' -M, --depends Outputs a makefile import dependency list to stdout.'); - console.log(' --no-color Disables colorized output.'); - console.log(' --ie-compat Enables IE8 compatibility checks.'); - console.log(' --js Enables inline JavaScript in less files'); - console.log(' -l, --lint Syntax check only (lint).'); - console.log(' -s, --silent Suppresses output of error messages.'); - console.log(' --strict-imports Forces evaluation of imports.'); - console.log(' --insecure Allows imports from insecure https hosts.'); - console.log(' -v, --version Prints version number and exit.'); - console.log(' --verbose Be verbose.'); - console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).'); - console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.'); - console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.'); - console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.'); - console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.'); - console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment'); - console.log(' in generated CSS file.'); - console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls'); - console.log(' Works with or without the relative-urls option.'); - console.log(' -ru=, --rewrite-urls= Rewrites URLs to make them relative to the base less file.'); - console.log(' all|local|off \'all\' rewrites all URLs, \'local\' just those starting with a \'.\''); - console.log(''); - console.log(' -m=, --math='); - console.log(' always Less will eagerly perform math operations always.'); - console.log(' parens-division Math performed except for division (/) operator'); - console.log(' parens | strict Math only performed inside parentheses'); - console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)'); - console.log(''); - console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units'); - console.log(' --strict-units=on|off that cannot be represented.'); - console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.'); - console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.'); - console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')'); - console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins'); - console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css'); - console.log(' once installed (npm install less-plugin-clean-css), use either with'); - console.log(' --plugin=less-plugin-clean-css or just --clean-css'); - console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"'); - console.log(' or --clean-css="advanced"'); - console.log(''); - console.log('-------------------------- Deprecated ----------------'); - console.log(' -sm=on|off Legacy parens-only math. Use --math'); - console.log(' --strict-math=on|off '); - console.log(''); - console.log(' --line-numbers=TYPE Outputs filename and line numbers.'); - console.log(' TYPE can be either \'comments\', which will output'); - console.log(' the debug info within comments, \'mediaquery\''); - console.log(' that will output the information within a fake'); - console.log(' media query which is compatible with the SASS'); - console.log(' format, and \'all\' which will do both.'); - console.log(' -x, --compress Compresses output by removing some whitespaces.'); - console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css'); - console.log(''); - console.log('Report bugs to: http://github.com/less/less.js/issues'); - console.log('Home page: '); - } - }; // Exports helper functions - - for (var h in lessc_helper) { - if (lessc_helper.hasOwnProperty(h)) { - exports[h] = lessc_helper[h]; + // lessc_helper.js + // + // helper functions for lessc + var lessc_helper = { + // Stylize a string + stylize: function (str, style) { + var styles = { + 'reset': [0, 0], + 'bold': [1, 22], + 'inverse': [7, 27], + 'underline': [4, 24], + 'yellow': [33, 39], + 'green': [32, 39], + 'red': [31, 39], + 'grey': [90, 39] + }; + return "\u001B[" + styles[style][0] + "m" + str + "\u001B[" + styles[style][1] + "m"; + }, + // Print command line options + printUsage: function () { + console.log('usage: lessc [option option=parameter ...] [destination]'); + console.log(''); + console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.'); + console.log(''); + console.log('options:'); + console.log(' -h, --help Prints help (this message) and exit.'); + console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.'); + console.log(' -M, --depends Outputs a makefile import dependency list to stdout.'); + console.log(' --no-color Disables colorized output.'); + console.log(' --ie-compat Enables IE8 compatibility checks.'); + console.log(' --js Enables inline JavaScript in less files'); + console.log(' -l, --lint Syntax check only (lint).'); + console.log(' -s, --silent Suppresses output of error messages.'); + console.log(' --strict-imports Forces evaluation of imports.'); + console.log(' --insecure Allows imports from insecure https hosts.'); + console.log(' -v, --version Prints version number and exit.'); + console.log(' --verbose Be verbose.'); + console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).'); + console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.'); + console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.'); + console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.'); + console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.'); + console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment'); + console.log(' in generated CSS file.'); + console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls'); + console.log(' Works with or without the relative-urls option.'); + console.log(' -ru=, --rewrite-urls= Rewrites URLs to make them relative to the base less file.'); + console.log(' all|local|off \'all\' rewrites all URLs, \'local\' just those starting with a \'.\''); + console.log(''); + console.log(' -m=, --math='); + console.log(' always Less will eagerly perform math operations always.'); + console.log(' parens-division Math performed except for division (/) operator'); + console.log(' parens | strict Math only performed inside parentheses'); + console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)'); + console.log(''); + console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units'); + console.log(' --strict-units=on|off that cannot be represented.'); + console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.'); + console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.'); + console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')'); + console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins'); + console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css'); + console.log(' once installed (npm install less-plugin-clean-css), use either with'); + console.log(' --plugin=less-plugin-clean-css or just --clean-css'); + console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"'); + console.log(' or --clean-css="advanced"'); + console.log(''); + console.log('-------------------------- Deprecated ----------------'); + console.log(' -sm=on|off Legacy parens-only math. Use --math'); + console.log(' --strict-math=on|off '); + console.log(''); + console.log(' --line-numbers=TYPE Outputs filename and line numbers.'); + console.log(' TYPE can be either \'comments\', which will output'); + console.log(' the debug info within comments, \'mediaquery\''); + console.log(' that will output the information within a fake'); + console.log(' media query which is compatible with the SASS'); + console.log(' format, and \'all\' which will do both.'); + console.log(' -x, --compress Compresses output by removing some whitespaces.'); + console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css'); + console.log(''); + console.log('Report bugs to: http://github.com/less/less.js/issues'); + console.log('Home page: '); + } + }; + // Exports helper functions + for (var h in lessc_helper) { + if (lessc_helper.hasOwnProperty(h)) { + exports[h] = lessc_helper[h]; + } } - } }); /** * Node Plugin Loader */ - -var PluginLoader = -/*#__PURE__*/ -function (_AbstractPluginLoader) { - _inherits(PluginLoader, _AbstractPluginLoader); - - function PluginLoader(less) { - var _this; - - _classCallCheck(this, PluginLoader); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(PluginLoader).call(this)); - _this.less = less; - - _this.require = function (prefix) { - prefix = path.dirname(prefix); - return function (id) { - var str = id.substr(0, 2); - - if (str === '..' || str === './') { - return require(path.join(prefix, id)); - } else { - return require(id); - } - }; - }; - - return _this; - } - - _createClass(PluginLoader, [{ - key: "loadPlugin", - value: function loadPlugin(filename, basePath, context, environment, fileManager) { - var prefix = filename.slice(0, 1); - var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js'; - - if (!explicit) { - context.prefixes = ['less-plugin-', '']; - } - - return new Promise(function (fulfill, reject) { - fileManager.loadFile(filename, basePath, context, environment).then(function (data) { - try { - fulfill(data); - } catch (e) { - console.log(e); - reject(e); - } - }).catch(function (err) { - reject(err); +var PluginLoader = /** @class */ (function (_super) { + tslib.__extends(PluginLoader, _super); + function PluginLoader(less) { + var _this = _super.call(this) || this; + _this.less = less; + _this.require = function (prefix) { + prefix = path.dirname(prefix); + return function (id) { + var str = id.substr(0, 2); + if (str === '..' || str === './') { + return require(path.join(prefix, id)); + } + else { + return require(id); + } + }; + }; + return _this; + } + PluginLoader.prototype.loadPlugin = function (filename, basePath, context, environment, fileManager) { + var prefix = filename.slice(0, 1); + var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js'; + if (!explicit) { + context.prefixes = ['less-plugin-', '']; + } + return new Promise(function (fulfill, reject) { + fileManager.loadFile(filename, basePath, context, environment).then(function (data) { + try { + fulfill(data); + } + catch (e) { + console.log(e); + reject(e); + } + }).catch(function (err) { + reject(err); + }); }); - }); - } - }]); - - return PluginLoader; -}(AbstractPluginLoader); + }; + return PluginLoader; +}(AbstractPluginLoader)); // Export a new default each time -var defaultOptions = (function () { - return { +var defaultOptions = (function () { return ({ /* Inline Javascript - @plugin still allowed */ javascriptEnabled: false, - /* Outputs a makefile import dependency list to stdout. */ depends: false, - - /* (DEPRECATED) Compress using less built-in compression. - * This does an okay job but does not utilise all the tricks of - * dedicated css compression. */ + /* (DEPRECATED) Compress using less built-in compression. + * This does an okay job but does not utilise all the tricks of + * dedicated css compression. */ compress: false, - /* Runs the less parser and just reports errors without any output. */ lint: false, - /* Sets available include paths. - * If the file in an @import rule does not exist at that exact location, - * less will look for it at the location(s) passed to this option. - * You might use this for instance to specify a path to a library which - * you want to be referenced simply and relatively in the less files. */ + * If the file in an @import rule does not exist at that exact location, + * less will look for it at the location(s) passed to this option. + * You might use this for instance to specify a path to a library which + * you want to be referenced simply and relatively in the less files. */ paths: [], - /* color output in the terminal */ color: true, - - /* The strictImports controls whether the compiler will allow an @import inside of either - * @media blocks or (a later addition) other selector blocks. - * See: https://github.com/less/less.js/issues/656 */ + /* The strictImports controls whether the compiler will allow an @import inside of either + * @media blocks or (a later addition) other selector blocks. + * See: https://github.com/less/less.js/issues/656 */ strictImports: false, - /* Allow Imports from Insecure HTTPS Hosts */ insecure: false, - - /* Allows you to add a path to every generated import and url in your css. - * This does not affect less import statements that are processed, just ones - * that are left in the output css. */ + /* Allows you to add a path to every generated import and url in your css. + * This does not affect less import statements that are processed, just ones + * that are left in the output css. */ rootpath: '', - - /* By default URLs are kept as-is, so if you import a file in a sub-directory - * that references an image, exactly the same URL will be output in the css. - * This option allows you to re-write URL's in imported files so that the - * URL is always relative to the base imported file */ + /* By default URLs are kept as-is, so if you import a file in a sub-directory + * that references an image, exactly the same URL will be output in the css. + * This option allows you to re-write URL's in imported files so that the + * URL is always relative to the base imported file */ rewriteUrls: false, - - /* How to process math - * 0 always - eagerly try to solve all operations - * 1 parens-division - require parens for division "/" - * 2 parens | strict - require parens for all operations - * 3 strict-legacy - legacy strict behavior (super-strict) - */ + /* How to process math + * 0 always - eagerly try to solve all operations + * 1 parens-division - require parens for division "/" + * 2 parens | strict - require parens for all operations + * 3 strict-legacy - legacy strict behavior (super-strict) + */ math: 0, - /* Without this option, less attempts to guess at the output unit when it does maths. */ strictUnits: false, - - /* Effectively the declaration is put at the top of your base Less file, - * meaning it can be used but it also can be overridden if this variable - * is defined in the file. */ + /* Effectively the declaration is put at the top of your base Less file, + * meaning it can be used but it also can be overridden if this variable + * is defined in the file. */ globalVars: null, - /* As opposed to the global variable option, this puts the declaration at the - * end of your base file, meaning it will override anything defined in your Less file. */ + * end of your base file, meaning it will override anything defined in your Less file. */ modifyVars: null, - /* This option allows you to specify a argument to go on to every URL. */ urlArgs: '' - }; -}); +}); }); var imageSize = (function (environment) { - function _imageSize(functionContext, filePathNode) { - var filePath = filePathNode.value; - var currentFileInfo = functionContext.currentFileInfo; - var currentDirectory = currentFileInfo.rewriteUrls ? currentFileInfo.currentDirectory : currentFileInfo.entryPath; - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - var fileManager = environment.getFileManager(filePath, currentDirectory, functionContext.context, environment, true); - - if (!fileManager) { - throw { - type: 'File', - message: `Can not set up FileManager for ${filePathNode}` - }; - } - - var fileSync = fileManager.loadFileSync(filePath, currentDirectory, functionContext.context, environment); - - if (fileSync.error) { - throw fileSync.error; - } - - var sizeOf = require('image-size'); - - return sizeOf(fileSync.filename); - } - - var imageFunctions = { - 'image-size': function imageSize(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Expression([new Dimension(size.width, 'px'), new Dimension(size.height, 'px')]); - }, - 'image-width': function imageWidth(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Dimension(size.width, 'px'); - }, - 'image-height': function imageHeight(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Dimension(size.height, 'px'); + function imageSize(functionContext, filePathNode) { + var filePath = filePathNode.value; + var currentFileInfo = functionContext.currentFileInfo; + var currentDirectory = currentFileInfo.rewriteUrls ? + currentFileInfo.currentDirectory : currentFileInfo.entryPath; + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart !== -1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + var fileManager = environment.getFileManager(filePath, currentDirectory, functionContext.context, environment, true); + if (!fileManager) { + throw { + type: 'File', + message: "Can not set up FileManager for " + filePathNode + }; + } + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, functionContext.context, environment); + if (fileSync.error) { + throw fileSync.error; + } + var sizeOf = require('image-size'); + return sizeOf(fileSync.filename); } - }; - functionRegistry.addMultiple(imageFunctions); + var imageFunctions = { + 'image-size': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Expression([ + new Dimension(size.width, 'px'), + new Dimension(size.height, 'px') + ]); + }, + 'image-width': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Dimension(size.width, 'px'); + }, + 'image-height': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Dimension(size.height, 'px'); + } + }; + functionRegistry.addMultiple(imageFunctions); }); -var less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]); // allow people to create less with their own environment - +var less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]); +// allow people to create less with their own environment less.createFromEnvironment = createFromEnvironment; less.lesscHelper = lesscHelper; less.PluginLoader = PluginLoader; less.fs = fs$1; less.FileManager = FileManager; -less.UrlFileManager = UrlFileManager; // Set up options - -less.options = defaultOptions(); // provide image-size functionality - +less.UrlFileManager = UrlFileManager; +// Set up options +less.options = defaultOptions(); +// provide image-size functionality imageSize(less.environment); var errno; var mkdirp; - try { - errno = require('errno'); -} catch (err) { - errno = null; + errno = require('errno'); +} +catch (err) { + errno = null; } var pluginManager = new less.PluginManager(less); var fileManager = new less.FileManager(); @@ -13736,605 +10889,490 @@ var options = less.options; options.plugins = plugins; options.reUsePluginManager = true; var sourceMapOptions = {}; -var continueProcessing = true; // Calling process.exit does not flush stdout always. Instead of exiting the process, we set the process' exitCode, -// close all handles and wait for the event loop to exit the process. -// @see https://github.com/nodejs/node/issues/6409 -// Unfortunately, node 0.10.x does not support setting process.exitCode, so we need to call reallyExit() explicitly. -// @see https://nodejs.org/api/process.html#process_process_exitcode -// Additionally we also need to make sure that uncaughtExceptions are never swallowed. -// @see https://github.com/less/less.js/issues/2881 -// This code can safely be removed if node 0.10.x is not supported anymore. - -process.on('exit', function () { - process.reallyExit(process.exitCode); -}); -process.on('uncaughtException', function (err) { - console.error(err); - process.exitCode = 1; -}); // This code will still be required because otherwise rejected promises would not be reported to the user - -process.on('unhandledRejection', function (err) { - console.error(err); - process.exitCode = 1; -}); - -var checkArgFunc = function checkArgFunc(arg, option) { - if (!option) { - console.error(`${arg} option requires a parameter`); - continueProcessing = false; - process.exitCode = 1; - return false; - } - - return true; +var continueProcessing = true; +var checkArgFunc = function (arg, option) { + if (!option) { + console.error(arg + " option requires a parameter"); + continueProcessing = false; + process.exitCode = 1; + return false; + } + return true; }; - -var checkBooleanArg = function checkBooleanArg(arg) { - var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg); - - if (!onOff) { - console.error(` unable to parse ${arg} as a boolean. use one of on/t/true/y/yes/off/f/false/n/no`); - continueProcessing = false; - process.exitCode = 1; - return false; - } - - return Boolean(onOff[2]); +var checkBooleanArg = function (arg) { + var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg); + if (!onOff) { + console.error(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no"); + continueProcessing = false; + process.exitCode = 1; + return false; + } + return Boolean(onOff[2]); }; - -var parseVariableOption = function parseVariableOption(option, variables) { - var parts = option.split('=', 2); - variables[parts[0]] = parts[1]; +var parseVariableOption = function (option, variables) { + var parts = option.split('=', 2); + variables[parts[0]] = parts[1]; }; - var sourceMapFileInline = false; - function printUsage() { - less.lesscHelper.printUsage(); - pluginManager.Loader.printUsage(plugins); - continueProcessing = false; + less.lesscHelper.printUsage(); + pluginManager.Loader.printUsage(plugins); + continueProcessing = false; } - function render() { - if (!continueProcessing) { - return; - } - - var input = args[1]; - - if (input && input != '-') { - input = path.resolve(process.cwd(), input); - } - - var output = args[2]; - var outputbase = args[2]; - - if (output) { - output = path.resolve(process.cwd(), output); - } - - if (options.sourceMap) { - sourceMapOptions.sourceMapInputFilename = input; - - if (!sourceMapOptions.sourceMapFullFilename) { - if (!output && !sourceMapFileInline) { - console.error('the sourcemap option only has an optional filename if the css filename is given'); - console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css'); - process.exitCode = 1; + if (!continueProcessing) { return; - } // its in the same directory, so always just the basename - - - if (output) { - sourceMapOptions.sourceMapOutputFilename = path.basename(output); - sourceMapOptions.sourceMapFullFilename = `${output}.map`; - } // its in the same directory, so always just the basename - - - if ('sourceMapFullFilename' in sourceMapOptions) { - sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename); - } - } else if (options.sourceMap && !sourceMapFileInline) { - var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename); - var mapDir = path.dirname(mapFilename); - var outputDir = path.dirname(output); // find the path from the map to the output file - - sourceMapOptions.sourceMapOutputFilename = path.join(path.relative(mapDir, outputDir), path.basename(output)); // make the sourcemap filename point to the sourcemap relative to the css file output directory - - sourceMapOptions.sourceMapFilename = path.join(path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename)); - } - } - - if (sourceMapOptions.sourceMapBasepath === undefined) { - sourceMapOptions.sourceMapBasepath = input ? path.dirname(input) : process.cwd(); - } - - if (sourceMapOptions.sourceMapRootpath === undefined) { - var pathToMap = path.dirname((sourceMapFileInline ? output : sourceMapOptions.sourceMapFullFilename) || '.'); - var pathToInput = path.dirname(sourceMapOptions.sourceMapInputFilename || '.'); - sourceMapOptions.sourceMapRootpath = path.relative(pathToMap, pathToInput); - } - - if (!input) { - console.error('lessc: no input files'); - console.error(''); - printUsage(); - process.exitCode = 1; - return; - } - - var ensureDirectory = function ensureDirectory(filepath) { - var dir = path.dirname(filepath); - var cmd; - var existsSync = fs$1.existsSync || path.existsSync; - - if (!existsSync(dir)) { - if (mkdirp === undefined) { - try { - mkdirp = require('mkdirp'); - } catch (e) { - mkdirp = null; - } - } - - cmd = mkdirp && mkdirp.sync || fs$1.mkdirSync; - cmd(dir); - } - }; - - if (options.depends) { - if (!outputbase) { - console.error('option --depends requires an output path to be specified'); - process.exitCode = 1; - return; - } - - process.stdout.write(`${outputbase}: `); - } - - if (!sourceMapFileInline) { - var writeSourceMap = function writeSourceMap() { - var output = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : ''; - var onDone = arguments.length > 1 ? arguments[1] : undefined; - var filename = sourceMapOptions.sourceMapFullFilename; - ensureDirectory(filename); - fs$1.writeFile(filename, output, 'utf8', function (err) { - if (err) { - var description = 'Error: '; - - if (errno && errno.errno[err.errno]) { - description += errno.errno[err.errno].description; - } else { - description += `${err.code} ${err.message}`; - } - - console.error(`lessc: failed to create file ${filename}`); - console.error(description); - process.exitCode = 1; - } else { - less.logger.info(`lessc: wrote ${filename}`); - } - - onDone(); - }); - }; - } - - var writeSourceMapIfNeeded = function writeSourceMapIfNeeded(output, onDone) { - if (options.sourceMap && !sourceMapFileInline) { - writeSourceMap(output, onDone); - } else { - onDone(); - } - }; - - var writeOutput = function writeOutput(output, result, onSuccess) { - if (options.depends) { - onSuccess(); - } else if (output) { - ensureDirectory(output); - fs$1.writeFile(output, result.css, { - encoding: 'utf8' - }, function (err) { - if (err) { - var description = 'Error: '; - - if (errno && errno.errno[err.errno]) { - description += errno.errno[err.errno].description; - } else { - description += `${err.code} ${err.message}`; - } - - console.error(`lessc: failed to create file ${output}`); - console.error(description); - process.exitCode = 1; - } else { - less.logger.info(`lessc: wrote ${output}`); - onSuccess(); - } - }); - } else if (!options.depends) { - process.stdout.write(result.css); - onSuccess(); - } - }; - - var logDependencies = function logDependencies(options, result) { - if (options.depends) { - var depends = ''; - - for (var i = 0; i < result.imports.length; i++) { - depends += `${result.imports[i]} `; - } - - console.log(depends); } - }; - - var parseLessFile = function parseLessFile(e, data) { - if (e) { - console.error(`lessc: ${e.message}`); - process.exitCode = 1; - return; + var input = args[1]; + if (input && input != '-') { + input = path.resolve(process.cwd(), input); } - - data = data.replace(/^\uFEFF/, ''); - options.paths = [path.dirname(input)].concat(options.paths); - options.filename = input; - - if (options.lint) { - options.sourceMap = false; + var output = args[2]; + var outputbase = args[2]; + if (output) { + output = path.resolve(process.cwd(), output); } - - sourceMapOptions.sourceMapFileInline = sourceMapFileInline; - if (options.sourceMap) { - options.sourceMap = sourceMapOptions; - } - - less.logger.addListener({ - info: function info(msg) { - if (verbose) { - console.log(msg); - } - }, - warn: function warn(msg) { - // do not show warning if the silent option is used - if (!silent) { - console.warn(msg); - } - }, - error: function error(msg) { - console.error(msg); - } - }); - less.render(data, options).then(function (result) { - if (!options.lint) { - writeOutput(output, result, function () { - writeSourceMapIfNeeded(result.map, function () { - logDependencies(options, result); - }); - }); - } - }, function (err) { - if (!options.silent) { - console.error(err.toString({ - stylize: options.color && less.lesscHelper.stylize - })); - } - - process.exitCode = 1; - }); - }; - - if (input != '-') { - fs$1.readFile(input, 'utf8', parseLessFile); - } else { - process.stdin.resume(); - process.stdin.setEncoding('utf8'); - var buffer = ''; - process.stdin.on('data', function (data) { - buffer += data; - }); - process.stdin.on('end', function () { - parseLessFile(false, buffer); - }); - } -} - -function processPluginQueue() { - var x = 0; - - function pluginError(name) { - console.error(`Unable to load plugin ${name} please make sure that it is installed under or at the same level as less`); - process.exitCode = 1; - } - - function pluginFinished(plugin) { - x++; - plugins.push(plugin); - - if (x === queuePlugins.length) { - render(); + sourceMapOptions.sourceMapInputFilename = input; + if (!sourceMapOptions.sourceMapFullFilename) { + if (!output && !sourceMapFileInline) { + console.error('the sourcemap option only has an optional filename if the css filename is given'); + console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css'); + process.exitCode = 1; + return; + } + // its in the same directory, so always just the basename + if (output) { + sourceMapOptions.sourceMapOutputFilename = path.basename(output); + sourceMapOptions.sourceMapFullFilename = output + ".map"; + } + // its in the same directory, so always just the basename + if ('sourceMapFullFilename' in sourceMapOptions) { + sourceMapOptions.sourceMapFilename = path.basename(sourceMapOptions.sourceMapFullFilename); + } + } + else if (options.sourceMap && !sourceMapFileInline) { + var mapFilename = path.resolve(process.cwd(), sourceMapOptions.sourceMapFullFilename); + var mapDir = path.dirname(mapFilename); + var outputDir = path.dirname(output); + // find the path from the map to the output file + sourceMapOptions.sourceMapOutputFilename = path.join(path.relative(mapDir, outputDir), path.basename(output)); + // make the sourcemap filename point to the sourcemap relative to the css file output directory + sourceMapOptions.sourceMapFilename = path.join(path.relative(outputDir, mapDir), path.basename(sourceMapOptions.sourceMapFullFilename)); + } } - } - - queuePlugins.forEach(function (queue) { - var context = clone(options); - pluginManager.Loader.loadPlugin(queue.name, process.cwd(), context, less.environment, fileManager).then(function (data) { - pluginFinished({ - fileContent: data.contents, - filename: data.filename, - options: queue.options - }); - }).catch(function () { - pluginError(queue.name); - }); - }); -} // self executing function so we can return - - -(function () { - args = args.filter(function (arg) { - var match; - match = arg.match(/^-I(.+)$/); - - if (match) { - options.paths.push(match[1]); - return false; + if (sourceMapOptions.sourceMapBasepath === undefined) { + sourceMapOptions.sourceMapBasepath = input ? path.dirname(input) : process.cwd(); } - - match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i); - - if (match) { - arg = match[1]; - } else { - return arg; + if (sourceMapOptions.sourceMapRootpath === undefined) { + var pathToMap = path.dirname((sourceMapFileInline ? output : sourceMapOptions.sourceMapFullFilename) || '.'); + var pathToInput = path.dirname(sourceMapOptions.sourceMapInputFilename || '.'); + sourceMapOptions.sourceMapRootpath = path.relative(pathToMap, pathToInput); } - - switch (arg) { - case 'v': - case 'version': - console.log(`lessc ${less.version.join('.')} (Less Compiler) [JavaScript]`); - continueProcessing = false; - break; - - case 'verbose': - verbose = true; - break; - - case 's': - case 'silent': - silent = true; - break; - - case 'l': - case 'lint': - options.lint = true; - break; - - case 'strict-imports': - options.strictImports = true; - break; - - case 'h': - case 'help': + if (!input) { + console.error('lessc: no input files'); + console.error(''); printUsage(); - break; - - case 'x': - case 'compress': - options.compress = true; - break; - - case 'insecure': - options.insecure = true; - break; - - case 'M': - case 'depends': - options.depends = true; - break; - - case 'max-line-len': - if (checkArgFunc(arg, match[2])) { - options.maxLineLen = parseInt(match[2], 10); - - if (options.maxLineLen <= 0) { - options.maxLineLen = -1; - } - } - - break; - - case 'no-color': - options.color = false; - break; - - case 'js': - options.javascriptEnabled = true; - break; - - case 'no-js': - console.error('The "--no-js" argument is deprecated, as inline JavaScript ' + 'is disabled by default. Use "--js" to enable inline JavaScript (not recommended).'); - break; - - case 'include-path': - if (checkArgFunc(arg, match[2])) { - // ; supported on windows. - // : supported on windows and linux, excluding a drive letter like C:\ so C:\file:D:\file parses to 2 - options.paths = match[2].split(os.type().match(/Windows/) ? /:(?!\\)|;/ : ':').map(function (p) { - if (p) { - return path.resolve(process.cwd(), p); + process.exitCode = 1; + return; + } + var ensureDirectory = function (filepath) { + var dir = path.dirname(filepath); + var cmd; + var existsSync = fs$1.existsSync || path.existsSync; + if (!existsSync(dir)) { + if (mkdirp === undefined) { + try { + mkdirp = require('mkdirp'); + } + catch (e) { + mkdirp = null; + } } - }); + cmd = mkdirp && mkdirp.sync || fs$1.mkdirSync; + cmd(dir); } - - break; - - case 'line-numbers': - if (checkArgFunc(arg, match[2])) { - options.dumpLineNumbers = match[2]; + }; + if (options.depends) { + if (!outputbase) { + console.error('option --depends requires an output path to be specified'); + process.exitCode = 1; + return; } - - break; - - case 'source-map': - options.sourceMap = true; - - if (match[2]) { - sourceMapOptions.sourceMapFullFilename = match[2]; + process.stdout.write(outputbase + ": "); + } + if (!sourceMapFileInline) { + var writeSourceMap = function (output, onDone) { + if (output === void 0) { output = ''; } + var filename = sourceMapOptions.sourceMapFullFilename; + ensureDirectory(filename); + fs$1.writeFile(filename, output, 'utf8', function (err) { + if (err) { + var description = 'Error: '; + if (errno && errno.errno[err.errno]) { + description += errno.errno[err.errno].description; + } + else { + description += err.code + " " + err.message; + } + console.error("lessc: failed to create file " + filename); + console.error(description); + process.exitCode = 1; + } + else { + less.logger.info("lessc: wrote " + filename); + } + onDone(); + }); + }; + } + var writeSourceMapIfNeeded = function (output, onDone) { + if (options.sourceMap && !sourceMapFileInline) { + writeSourceMap(output, onDone); } - - break; - - case 'source-map-rootpath': - if (checkArgFunc(arg, match[2])) { - sourceMapOptions.sourceMapRootpath = match[2]; + else { + onDone(); } - - break; - - case 'source-map-basepath': - if (checkArgFunc(arg, match[2])) { - sourceMapOptions.sourceMapBasepath = match[2]; + }; + var writeOutput = function (output, result, onSuccess) { + if (options.depends) { + onSuccess(); + } + else if (output) { + ensureDirectory(output); + fs$1.writeFile(output, result.css, { encoding: 'utf8' }, function (err) { + if (err) { + var description = 'Error: '; + if (errno && errno.errno[err.errno]) { + description += errno.errno[err.errno].description; + } + else { + description += err.code + " " + err.message; + } + console.error("lessc: failed to create file " + output); + console.error(description); + process.exitCode = 1; + } + else { + less.logger.info("lessc: wrote " + output); + onSuccess(); + } + }); } - - break; - - case 'source-map-inline': - case 'source-map-map-inline': - sourceMapFileInline = true; - options.sourceMap = true; - break; - - case 'source-map-include-source': - case 'source-map-less-inline': - sourceMapOptions.outputSourceFiles = true; - break; - - case 'source-map-url': - if (checkArgFunc(arg, match[2])) { - sourceMapOptions.sourceMapURL = match[2]; + else if (!options.depends) { + process.stdout.write(result.css); + onSuccess(); } - - break; - - case 'rp': - case 'rootpath': - if (checkArgFunc(arg, match[2])) { - options.rootpath = match[2].replace(/\\/g, '/'); + }; + var logDependencies = function (options, result) { + if (options.depends) { + var depends = ''; + for (var i_1 = 0; i_1 < result.imports.length; i_1++) { + depends += result.imports[i_1] + " "; + } + console.log(depends); } - - break; - - case 'relative-urls': - console.warn('The --relative-urls option has been deprecated. Use --rewrite-urls=all.'); - options.rewriteUrls = RewriteUrls.ALL; - break; - - case 'ru': - case 'rewrite-urls': - var m = match[2]; - - if (m) { - if (m === 'local') { - options.rewriteUrls = RewriteUrls.LOCAL; - } else if (m === 'off') { - options.rewriteUrls = RewriteUrls.OFF; - } else if (m === 'all') { - options.rewriteUrls = RewriteUrls.ALL; - } else { - console.error(`Unknown rewrite-urls argument ${m}`); - continueProcessing = false; + }; + var parseLessFile = function (e, data) { + if (e) { + console.error("lessc: " + e.message); process.exitCode = 1; - } - } else { - options.rewriteUrls = RewriteUrls.ALL; + return; } - - break; - - case 'sm': - case 'strict-math': - console.warn('The --strict-math option has been deprecated. Use --math=strict.'); - - if (checkArgFunc(arg, match[2])) { - if (checkBooleanArg(match[2])) { - options.math = Math$1.STRICT_LEGACY; - } + data = data.replace(/^\uFEFF/, ''); + options.paths = [path.dirname(input)].concat(options.paths); + options.filename = input; + if (options.lint) { + options.sourceMap = false; } - - break; - - case 'm': - case 'math': - if (checkArgFunc(arg, match[2])) { - options.math = match[2]; + sourceMapOptions.sourceMapFileInline = sourceMapFileInline; + if (options.sourceMap) { + options.sourceMap = sourceMapOptions; } - - break; - - case 'su': - case 'strict-units': - if (checkArgFunc(arg, match[2])) { - options.strictUnits = checkBooleanArg(match[2]); + less.logger.addListener({ + info: function (msg) { + if (verbose) { + console.log(msg); + } + }, + warn: function (msg) { + // do not show warning if the silent option is used + if (!silent) { + console.warn(msg); + } + }, + error: function (msg) { + console.error(msg); + } + }); + less.render(data, options) + .then(function (result) { + if (!options.lint) { + writeOutput(output, result, function () { + writeSourceMapIfNeeded(result.map, function () { + logDependencies(options, result); + }); + }); + } + }, function (err) { + if (!options.silent) { + console.error(err.toString({ + stylize: options.color && less.lesscHelper.stylize + })); + } + process.exitCode = 1; + }); + }; + if (input != '-') { + fs$1.readFile(input, 'utf8', parseLessFile); + } + else { + process.stdin.resume(); + process.stdin.setEncoding('utf8'); + var buffer_1 = ''; + process.stdin.on('data', function (data) { + buffer_1 += data; + }); + process.stdin.on('end', function () { + parseLessFile(false, buffer_1); + }); + } +} +function processPluginQueue() { + var x = 0; + function pluginError(name) { + console.error("Unable to load plugin " + name + " please make sure that it is installed under or at the same level as less"); + process.exitCode = 1; + } + function pluginFinished(plugin) { + x++; + plugins.push(plugin); + if (x === queuePlugins.length) { + render(); + } + } + queuePlugins.forEach(function (queue) { + var context = clone(options); + pluginManager.Loader.loadPlugin(queue.name, process.cwd(), context, less.environment, fileManager) + .then(function (data) { + pluginFinished({ + fileContent: data.contents, + filename: data.filename, + options: queue.options + }); + }) + .catch(function () { + pluginError(queue.name); + }); + }); +} +// self executing function so we can return +(function () { + args = args.filter(function (arg) { + var match; + match = arg.match(/^-I(.+)$/); + if (match) { + options.paths.push(match[1]); + return false; } - - break; - - case 'global-var': - if (checkArgFunc(arg, match[2])) { - if (!options.globalVars) { - options.globalVars = {}; - } - - parseVariableOption(match[2], options.globalVars); + match = arg.match(/^--?([a-z][0-9a-z-]*)(?:=(.*))?$/i); + if (match) { + arg = match[1]; } - - break; - - case 'modify-var': - if (checkArgFunc(arg, match[2])) { - if (!options.modifyVars) { - options.modifyVars = {}; - } - - parseVariableOption(match[2], options.modifyVars); + else { + return arg; } - - break; - - case 'url-args': - if (checkArgFunc(arg, match[2])) { - options.urlArgs = match[2]; + switch (arg) { + case 'v': + case 'version': + console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]"); + continueProcessing = false; + break; + case 'verbose': + verbose = true; + break; + case 's': + case 'silent': + silent = true; + break; + case 'l': + case 'lint': + options.lint = true; + break; + case 'strict-imports': + options.strictImports = true; + break; + case 'h': + case 'help': + printUsage(); + break; + case 'x': + case 'compress': + options.compress = true; + break; + case 'insecure': + options.insecure = true; + break; + case 'M': + case 'depends': + options.depends = true; + break; + case 'max-line-len': + if (checkArgFunc(arg, match[2])) { + options.maxLineLen = parseInt(match[2], 10); + if (options.maxLineLen <= 0) { + options.maxLineLen = -1; + } + } + break; + case 'no-color': + options.color = false; + break; + case 'js': + options.javascriptEnabled = true; + break; + case 'no-js': + console.error('The "--no-js" argument is deprecated, as inline JavaScript ' + + 'is disabled by default. Use "--js" to enable inline JavaScript (not recommended).'); + break; + case 'include-path': + if (checkArgFunc(arg, match[2])) { + // ; supported on windows. + // : supported on windows and linux, excluding a drive letter like C:\ so C:\file:D:\file parses to 2 + options.paths = match[2] + .split(os.type().match(/Windows/) ? /:(?!\\)|;/ : ':') + .map(function (p) { + if (p) { + return path.resolve(process.cwd(), p); + } + }); + } + break; + case 'line-numbers': + if (checkArgFunc(arg, match[2])) { + options.dumpLineNumbers = match[2]; + } + break; + case 'source-map': + options.sourceMap = true; + if (match[2]) { + sourceMapOptions.sourceMapFullFilename = match[2]; + } + break; + case 'source-map-rootpath': + if (checkArgFunc(arg, match[2])) { + sourceMapOptions.sourceMapRootpath = match[2]; + } + break; + case 'source-map-basepath': + if (checkArgFunc(arg, match[2])) { + sourceMapOptions.sourceMapBasepath = match[2]; + } + break; + case 'source-map-inline': + case 'source-map-map-inline': + sourceMapFileInline = true; + options.sourceMap = true; + break; + case 'source-map-include-source': + case 'source-map-less-inline': + sourceMapOptions.outputSourceFiles = true; + break; + case 'source-map-url': + if (checkArgFunc(arg, match[2])) { + sourceMapOptions.sourceMapURL = match[2]; + } + break; + case 'rp': + case 'rootpath': + if (checkArgFunc(arg, match[2])) { + options.rootpath = match[2].replace(/\\/g, '/'); + } + break; + case 'relative-urls': + console.warn('The --relative-urls option has been deprecated. Use --rewrite-urls=all.'); + options.rewriteUrls = RewriteUrls.ALL; + break; + case 'ru': + case 'rewrite-urls': + var m = match[2]; + if (m) { + if (m === 'local') { + options.rewriteUrls = RewriteUrls.LOCAL; + } + else if (m === 'off') { + options.rewriteUrls = RewriteUrls.OFF; + } + else if (m === 'all') { + options.rewriteUrls = RewriteUrls.ALL; + } + else { + console.error("Unknown rewrite-urls argument " + m); + continueProcessing = false; + process.exitCode = 1; + } + } + else { + options.rewriteUrls = RewriteUrls.ALL; + } + break; + case 'sm': + case 'strict-math': + console.warn('The --strict-math option has been deprecated. Use --math=strict.'); + if (checkArgFunc(arg, match[2])) { + if (checkBooleanArg(match[2])) { + options.math = Math$1.STRICT_LEGACY; + } + } + break; + case 'm': + case 'math': + if (checkArgFunc(arg, match[2])) { + options.math = match[2]; + } + break; + case 'su': + case 'strict-units': + if (checkArgFunc(arg, match[2])) { + options.strictUnits = checkBooleanArg(match[2]); + } + break; + case 'global-var': + if (checkArgFunc(arg, match[2])) { + if (!options.globalVars) { + options.globalVars = {}; + } + parseVariableOption(match[2], options.globalVars); + } + break; + case 'modify-var': + if (checkArgFunc(arg, match[2])) { + if (!options.modifyVars) { + options.modifyVars = {}; + } + parseVariableOption(match[2], options.modifyVars); + } + break; + case 'url-args': + if (checkArgFunc(arg, match[2])) { + options.urlArgs = match[2]; + } + break; + case 'plugin': + var splitupArg = match[2].match(/^([^=]+)(=(.*))?/); + var name_1 = splitupArg[1]; + var pluginOptions = splitupArg[3]; + queuePlugins.push({ name: name_1, options: pluginOptions }); + break; + default: + queuePlugins.push({ name: arg, options: match[2], default: true }); + break; } - - break; - - case 'plugin': - var splitupArg = match[2].match(/^([^=]+)(=(.*))?/); - var name = splitupArg[1]; - var pluginOptions = splitupArg[3]; - queuePlugins.push({ - name, - options: pluginOptions - }); - break; - - default: - queuePlugins.push({ - name: arg, - options: match[2], - default: true - }); - break; + }); + if (queuePlugins.length > 0) { + processPluginQueue(); + } + else { + render(); } - }); - - if (queuePlugins.length > 0) { - processPluginQueue(); - } else { - render(); - } })(); diff --git a/build/rollup.js b/build/rollup.js index dba41ad6f..10bc4f3de 100644 --- a/build/rollup.js +++ b/build/rollup.js @@ -1,5 +1,5 @@ const rollup = require('rollup'); -const babel = require('rollup-plugin-babel'); +const typescript = require('rollup-plugin-typescript2'); const resolve = require('rollup-plugin-node-resolve'); const commonjs = require('rollup-plugin-commonjs'); const terser = require('rollup-plugin-terser').terser; @@ -26,15 +26,22 @@ async function buildBrowser() { } ], plugins: [ - resolve(), + // resolve(), commonjs(), - babel({ - exclude: 'node_modules/**', // only transpile our source code - presets: [["@babel/env", { - targets: '> 0.25%, not dead' - }]] + typescript({ + verbosity: 2, + tsconfigDefaults: { + compilerOptions: { + allowJs: true, + sourceMap: true, + target: 'ES5' + } + }, + include: [ '*.ts', '**/*.ts', '*.js', '**/*.js' ], + exclude: ['node_modules'] // only transpile our source code }), terser({ + compress: true, include: [/^.+\.min\.js$/], output: { comments: function(node, comment) { @@ -81,13 +88,18 @@ async function buildNode() { plugins: [ resolve(), commonjs(), - babel({ - exclude: 'node_modules/**', // only transpile our source code - presets: [["@babel/env", { - targets: { - node: '4' - } - }]] + typescript({ + verbosity: 1, + tsconfigDefaults: { + compilerOptions: { + allowJs: true, + // checkJs: true, + sourceMap: true, + target: 'ES5' + }, + }, + include: [ '*.ts', '**/*.ts', '*.js', '**/*.js' ], + exclude: ['node_modules'] // only transpile our source code }) ] }); @@ -111,13 +123,18 @@ async function buildLessC() { plugins: [ resolve(), commonjs(), - babel({ - exclude: 'node_modules/**', // only transpile our source code - presets: [["@babel/env", { - targets: { - node: '4' - } - }]] + typescript({ + verbosity: 1, + tsconfigDefaults: { + compilerOptions: { + allowJs: true, + // checkJs: true, + sourceMap: true, + target: 'ES5' + }, + }, + include: [ '*.ts', '**/*.ts', '*.js', '**/*.js' ], + exclude: ['node_modules'] // only transpile our source code }) ] }); diff --git a/dist/less.cjs.js b/dist/less.cjs.js index b08dee514..44ff9b71b 100644 --- a/dist/less.cjs.js +++ b/dist/less.cjs.js @@ -1,1643 +1,1177 @@ 'use strict'; +var tslib = require('tslib'); var path = require('path'); var url = require('url'); var CloneHelper = require('clone'); var environment = { - encodeBase64: function encodeBase64(str) { - // Avoid Buffer constructor on newer versions of Node.js. - var buffer = Buffer.from ? Buffer.from(str) : new Buffer(str); - return buffer.toString('base64'); - }, - mimeLookup: function mimeLookup(filename) { - return require('mime').lookup(filename); - }, - charsetLookup: function charsetLookup(mime) { - return require('mime').charsets.lookup(mime); - }, - getSourceMapGenerator: function getSourceMapGenerator() { - return require('source-map').SourceMapGenerator; - } + encodeBase64: function encodeBase64(str) { + // Avoid Buffer constructor on newer versions of Node.js. + var buffer = (Buffer.from ? Buffer.from(str) : (new Buffer(str))); + return buffer.toString('base64'); + }, + mimeLookup: function (filename) { + return require('mime').lookup(filename); + }, + charsetLookup: function (mime) { + return require('mime').charsets.lookup(mime); + }, + getSourceMapGenerator: function getSourceMapGenerator() { + return require('source-map').SourceMapGenerator; + } }; -function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } -} - -function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } -} - -function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; -} - -function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) _setPrototypeOf(subClass, superClass); -} - -function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); -} - -function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); -} - -function isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); - return true; - } catch (e) { - return false; - } -} - -function _construct(Parent, args, Class) { - if (isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); -} - -function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; -} - -function _possibleConstructorReturn(self, call) { - if (call && (typeof call === "object" || typeof call === "function")) { - return call; - } - - return _assertThisInitialized(self); -} - -function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); -} - -function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } -} - -function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); -} - -function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); -} - var fs; - try { - fs = require('graceful-fs'); -} catch (e) { - fs = require('fs'); + fs = require('graceful-fs'); +} +catch (e) { + fs = require('fs'); } - var fs$1 = fs; -var AbstractFileManager = -/*#__PURE__*/ -function () { - function AbstractFileManager() { - _classCallCheck(this, AbstractFileManager); - } - - _createClass(AbstractFileManager, [{ - key: "getPath", - value: function getPath(filename) { - var j = filename.lastIndexOf('?'); - - if (j > 0) { - filename = filename.slice(0, j); - } - - j = filename.lastIndexOf('/'); - - if (j < 0) { - j = filename.lastIndexOf('\\'); - } - - if (j < 0) { - return ''; - } - - return filename.slice(0, j + 1); - } - }, { - key: "tryAppendExtension", - value: function tryAppendExtension(path, ext) { - return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext; - } - }, { - key: "tryAppendLessExtension", - value: function tryAppendLessExtension(path) { - return this.tryAppendExtension(path, '.less'); - } - }, { - key: "supportsSync", - value: function supportsSync() { - return false; - } - }, { - key: "alwaysMakePathsAbsolute", - value: function alwaysMakePathsAbsolute() { - return false; - } - }, { - key: "isPathAbsolute", - value: function isPathAbsolute(filename) { - return /^(?:[a-z-]+:|\/|\\|#)/i.test(filename); - } // TODO: pull out / replace? - - }, { - key: "join", - value: function join(basePath, laterPath) { - if (!basePath) { - return laterPath; - } - - return basePath + laterPath; - } - }, { - key: "pathDiff", - value: function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - var urlParts = this.extractUrlParts(url); - var baseUrlParts = this.extractUrlParts(baseUrl); - var i; - var max; - var urlDirectories; - var baseUrlDirectories; - var diff = ''; - - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ''; - } - - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - - for (i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { - break; - } - } - - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - - for (i = 0; i < baseUrlDirectories.length - 1; i++) { - diff += '../'; - } - - for (i = 0; i < urlDirectories.length - 1; i++) { - diff += `${urlDirectories[i]}/`; - } - - return diff; +var AbstractFileManager = /** @class */ (function () { + function AbstractFileManager() { } - }, { - key: "extractUrlParts", - // helper function, not part of API - value: function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol://hostname/ OR / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; - var urlParts = url.match(urlPartsRegex); - var returner = {}; - var rawDirectories = []; - var directories = []; - var i; - var baseUrlParts; - - if (!urlParts) { - throw new Error(`Could not parse sheet href - '${url}'`); - } // Stylesheets in IE don't always return the full path - - - if (baseUrl && (!urlParts[1] || urlParts[2])) { - baseUrlParts = baseUrl.match(urlPartsRegex); - - if (!baseUrlParts) { - throw new Error(`Could not parse page url - '${baseUrl}'`); + AbstractFileManager.prototype.getPath = function (filename) { + var j = filename.lastIndexOf('?'); + if (j > 0) { + filename = filename.slice(0, j); } - - urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; - - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; + j = filename.lastIndexOf('/'); + if (j < 0) { + j = filename.lastIndexOf('\\'); } - } - - if (urlParts[3]) { - rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); // collapse '..' and skip '.' - - for (i = 0; i < rawDirectories.length; i++) { - if (rawDirectories[i] === '..') { - directories.pop(); - } else if (rawDirectories[i] !== '.') { - directories.push(rawDirectories[i]); - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); - returner.path = (urlParts[1] || '') + directories.join('/'); - returner.filename = urlParts[4]; - returner.fileUrl = returner.path + (urlParts[4] || ''); - returner.url = returner.fileUrl + (urlParts[5] || ''); - return returner; - } - }]); - - return AbstractFileManager; -}(); - -var FileManager = -/*#__PURE__*/ -function (_AbstractFileManager) { - _inherits(FileManager, _AbstractFileManager); - - function FileManager() { - var _this; - - _classCallCheck(this, FileManager); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(FileManager).call(this)); - _this.contents = {}; - return _this; - } - - _createClass(FileManager, [{ - key: "supports", - value: function supports(filename, currentDirectory, options, environment) { - return true; - } - }, { - key: "supportsSync", - value: function supportsSync(filename, currentDirectory, options, environment) { - return true; - } - }, { - key: "loadFile", - value: function loadFile(filename, currentDirectory, options, environment, callback) { - var fullFilename; - var isAbsoluteFilename = this.isPathAbsolute(filename); - var filenamesTried = []; - var self = this; - var prefix = filename.slice(0, 1); - var explicit = prefix === '.' || prefix === '/'; - var result = null; - var isNodeModule = false; - var npmPrefix = 'npm://'; - options = options || {}; - var paths = isAbsoluteFilename ? [''] : [currentDirectory]; - - if (options.paths) { - paths.push.apply(paths, _toConsumableArray(options.paths)); - } - - if (!isAbsoluteFilename && paths.indexOf('.') === -1) { - paths.push('.'); - } - - var prefixes = options.prefixes || ['']; - var fileParts = this.extractUrlParts(filename); - - if (options.syncImport) { - getFileData(returnData, returnData); - - if (callback) { - callback(result.error, result); - } else { - return result; - } - } else { - // promise is guaranteed to be asyncronous - // which helps as it allows the file handle - // to be closed before it continues with the next file - return new Promise(getFileData); - } - - function returnData(data) { - if (!data.filename) { - result = { - error: data - }; - } else { - result = data; - } - } - - function getFileData(fulfill, reject) { - (function tryPathIndex(i) { - if (i < paths.length) { - (function tryPrefix(j) { - if (j < prefixes.length) { - isNodeModule = false; - fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename; - - if (paths[i]) { - fullFilename = path.join(paths[i], fullFilename); + if (j < 0) { + return ''; + } + return filename.slice(0, j + 1); + }; + AbstractFileManager.prototype.isPathWithExtension = function (path, ext) { + var extPos = path.lastIndexOf(ext); + return extPos !== -1 && extPos === path.length - ext.length; + }; + AbstractFileManager.prototype.tryAppendExtension = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return path; + } + return path + ext; + }; + AbstractFileManager.prototype.tryAppendLessExtension = function (path) { + return this.tryAppendExtension(path, '.less'); + }; + AbstractFileManager.prototype.supportsSync = function () { return false; }; + AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () { return false; }; + AbstractFileManager.prototype.isPathAbsolute = function (filename) { + return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename); + }; + // TODO: pull out / replace? + AbstractFileManager.prototype.join = function (basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return basePath + laterPath; + }; + AbstractFileManager.prototype.pathDiff = function (url, baseUrl) { + // diff between two paths to create a relative path + var urlParts = this.extractUrlParts(url); + var baseUrlParts = this.extractUrlParts(baseUrl); + var i; + var max; + var urlDirectories; + var baseUrlDirectories; + var diff = ''; + if (urlParts.hostPart !== baseUrlParts.hostPart) { + return ''; + } + max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); + for (i = 0; i < max; i++) { + if (baseUrlParts.directories[i] !== urlParts.directories[i]) { + break; + } + } + baseUrlDirectories = baseUrlParts.directories.slice(i); + urlDirectories = urlParts.directories.slice(i); + for (i = 0; i < baseUrlDirectories.length - 1; i++) { + diff += '../'; + } + for (i = 0; i < urlDirectories.length - 1; i++) { + diff += urlDirectories[i] + "/"; + } + return diff; + }; + // helper function, not part of API + AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) { + // urlParts[1] = protocol://hostname/ OR / + // urlParts[2] = / if path relative to host base + // urlParts[3] = directories + // urlParts[4] = filename + // urlParts[5] = parameters + var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; + var urlParts = url.match(urlPartsRegex); + var returner = {}; + var rawDirectories = []; + var directories = []; + var i; + var baseUrlParts; + if (!urlParts) { + throw new Error("Could not parse sheet href - '" + url + "'"); + } + // Stylesheets in IE don't always return the full path + if (baseUrl && (!urlParts[1] || urlParts[2])) { + baseUrlParts = baseUrl.match(urlPartsRegex); + if (!baseUrlParts) { + throw new Error("Could not parse page url - '" + baseUrl + "'"); + } + urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; + if (!urlParts[2]) { + urlParts[3] = baseUrlParts[3] + urlParts[3]; + } + } + if (urlParts[3]) { + rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); + // collapse '..' and skip '.' + for (i = 0; i < rawDirectories.length; i++) { + if (rawDirectories[i] === '..') { + directories.pop(); } - - if (!explicit && paths[i] === '.') { - try { - fullFilename = require.resolve(fullFilename); - isNodeModule = true; - } catch (e) { - filenamesTried.push(npmPrefix + fullFilename); - tryWithExtension(); - } - } else { - tryWithExtension(); + else if (rawDirectories[i] !== '.') { + directories.push(rawDirectories[i]); } + } + } + returner.hostPart = urlParts[1]; + returner.directories = directories; + returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); + returner.path = (urlParts[1] || '') + directories.join('/'); + returner.filename = urlParts[4]; + returner.fileUrl = returner.path + (urlParts[4] || ''); + returner.url = returner.fileUrl + (urlParts[5] || ''); + return returner; + }; + return AbstractFileManager; +}()); - function tryWithExtension() { - var extFilename = options.ext ? self.tryAppendExtension(fullFilename, options.ext) : fullFilename; - - if (extFilename !== fullFilename && !explicit && paths[i] === '.') { - try { - fullFilename = require.resolve(extFilename); - isNodeModule = true; - } catch (e) { - filenamesTried.push(npmPrefix + extFilename); - fullFilename = extFilename; - } - } else { - fullFilename = extFilename; - } +var FileManager = /** @class */ (function (_super) { + tslib.__extends(FileManager, _super); + function FileManager() { + var _this = _super.call(this) || this; + _this.contents = {}; + return _this; + } + FileManager.prototype.supports = function (filename, currentDirectory, options, environment) { + return true; + }; + FileManager.prototype.supportsSync = function (filename, currentDirectory, options, environment) { + return true; + }; + FileManager.prototype.getPossibleFileExtensions = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return ['']; + } + return ['', ext]; + }; + FileManager.prototype.loadFile = function (filename, currentDirectory, options, environment, callback) { + var fullFilename; + var isAbsoluteFilename = this.isPathAbsolute(filename); + var filenamesTried = []; + var prefix = filename.slice(0, 1); + var explicit = prefix === '.' || prefix === '/'; + var result = null; + var isNodeModule = false; + var npmPrefix = 'npm://'; + options = options || {}; + var paths = isAbsoluteFilename ? [''] : [currentDirectory]; + if (options.paths) { + paths.push.apply(paths, options.paths); + } + if (!isAbsoluteFilename && paths.indexOf('.') === -1) { + paths.push('.'); + } + var prefixes = options.prefixes || ['']; + var extensions = this.getPossibleFileExtensions(filename, options.ext); + var fileParts = this.extractUrlParts(filename); + if (options.syncImport) { + getFileData(returnData, returnData); + if (callback) { + callback(result.error, result); + } + else { + return result; + } + } + else { + // promise is guaranteed to be asyncronous + // which helps as it allows the file handle + // to be closed before it continues with the next file + return new Promise(getFileData); + } + function returnData(data) { + if (!data.filename) { + result = { error: data }; + } + else { + result = data; + } + } + function getFileData(fulfill, reject) { + (function tryPathIndex(i) { + if (i < paths.length) { + (function tryPrefix(j) { + if (j < prefixes.length) { + (function tryExtension(k) { + if (k < extensions.length) { + isNodeModule = false; + fullFilename = fileParts.rawPath + prefixes[j] + fileParts.filename + extensions[k]; + if (paths[i]) { + fullFilename = path.join(paths[i], fullFilename); + } + if (!explicit && paths[i] === '.') { + try { + fullFilename = require.resolve(fullFilename); + isNodeModule = true; + } + catch (e) { + filenamesTried.push(npmPrefix + fullFilename); + } + } + var readFileArgs = [fullFilename]; + if (!options.rawBuffer) { + readFileArgs.push('utf-8'); + } + if (options.syncImport) { + try { + var data = fs$1.readFileSync.apply(this, readFileArgs); + fulfill({ contents: data, filename: fullFilename }); + } + catch (e) { + filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); + return tryExtension(k + 1); + } + } + else { + readFileArgs.push(function (e, data) { + if (e) { + filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); + return tryExtension(k + 1); + } + fulfill({ contents: data, filename: fullFilename }); + }); + fs$1.readFile.apply(this, readFileArgs); + } + } + else { + tryPrefix(j + 1); + } + })(0); + } + else { + tryPathIndex(i + 1); + } + })(0); } - - var modified = false; - - if (self.contents[fullFilename]) { - try { - var stat = fs$1.statSync.apply(this, [fullFilename]); - - if (stat.mtime.getTime() === self.contents[fullFilename].mtime.getTime()) { - fulfill({ - contents: self.contents[fullFilename].data, - filename: fullFilename - }); - } else { - modified = true; - } - } catch (e) { - modified = true; - } + else { + reject({ type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(',') }); } - - if (modified || !self.contents[fullFilename]) { - var readFileArgs = [fullFilename]; - - if (!options.rawBuffer) { - readFileArgs.push('utf-8'); - } - - if (options.syncImport) { - try { - var data = fs$1.readFileSync.apply(this, readFileArgs); - var stat = fs$1.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { - data, - mtime: stat.mtime - }; - fulfill({ - contents: data, - filename: fullFilename - }); - } catch (e) { - filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); - return tryPrefix(j + 1); - } - } else { - readFileArgs.push(function (e, data) { - if (e) { - filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); - return tryPrefix(j + 1); - } - - var stat = fs$1.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { - data, - mtime: stat.mtime - }; - fulfill({ - contents: data, - filename: fullFilename - }); - }); - fs$1.readFile.apply(this, readFileArgs); - } - } - } else { - tryPathIndex(i + 1); - } - })(0); - } else { - reject({ - type: 'File', - message: `'${filename}' wasn't found. Tried - ${filenamesTried.join(',')}` - }); - } - })(0); - } - } - }, { - key: "loadFileSync", - value: function loadFileSync(filename, currentDirectory, options, environment) { - options.syncImport = true; - return this.loadFile(filename, currentDirectory, options, environment); - } - }]); - - return FileManager; -}(AbstractFileManager); + }(0)); + } + }; + FileManager.prototype.loadFileSync = function (filename, currentDirectory, options, environment) { + options.syncImport = true; + return this.loadFile(filename, currentDirectory, options, environment); + }; + return FileManager; +}(AbstractFileManager)); var logger = { - error: function error(msg) { - this._fireEvent('error', msg); - }, - warn: function warn(msg) { - this._fireEvent('warn', msg); - }, - info: function info(msg) { - this._fireEvent('info', msg); - }, - debug: function debug(msg) { - this._fireEvent('debug', msg); - }, - addListener: function addListener(listener) { - this._listeners.push(listener); - }, - removeListener: function removeListener(listener) { - for (var i = 0; i < this._listeners.length; i++) { - if (this._listeners[i] === listener) { - this._listeners.splice(i, 1); - - return; - } - } - }, - _fireEvent: function _fireEvent(type, msg) { - for (var i = 0; i < this._listeners.length; i++) { - var logFunction = this._listeners[i][type]; - - if (logFunction) { - logFunction(msg); - } - } - }, - _listeners: [] + error: function (msg) { + this._fireEvent('error', msg); + }, + warn: function (msg) { + this._fireEvent('warn', msg); + }, + info: function (msg) { + this._fireEvent('info', msg); + }, + debug: function (msg) { + this._fireEvent('debug', msg); + }, + addListener: function (listener) { + this._listeners.push(listener); + }, + removeListener: function (listener) { + for (var i_1 = 0; i_1 < this._listeners.length; i_1++) { + if (this._listeners[i_1] === listener) { + this._listeners.splice(i_1, 1); + return; + } + } + }, + _fireEvent: function (type, msg) { + for (var i_2 = 0; i_2 < this._listeners.length; i_2++) { + var logFunction = this._listeners[i_2][type]; + if (logFunction) { + logFunction(msg); + } + } + }, + _listeners: [] }; var isUrlRe = /^(?:https?:)?\/\//i; var request; - -var UrlFileManager = -/*#__PURE__*/ -function (_AbstractFileManager) { - _inherits(UrlFileManager, _AbstractFileManager); - - function UrlFileManager() { - _classCallCheck(this, UrlFileManager); - - return _possibleConstructorReturn(this, _getPrototypeOf(UrlFileManager).apply(this, arguments)); - } - - _createClass(UrlFileManager, [{ - key: "supports", - value: function supports(filename, currentDirectory, options, environment) { - return isUrlRe.test(filename) || isUrlRe.test(currentDirectory); - } - }, { - key: "loadFile", - value: function loadFile(filename, currentDirectory, options, environment) { - return new Promise(function (fulfill, reject) { - if (request === undefined) { - try { - request = require('request'); - } catch (e) { - request = null; - } - } - - if (!request) { - reject({ - type: 'File', - message: 'optional dependency \'request\' required to import over http(s)\n' - }); - return; - } - - var urlStr = isUrlRe.test(filename) ? filename : url.resolve(currentDirectory, filename); - var urlObj = url.parse(urlStr); - - if (!urlObj.protocol) { - urlObj.protocol = 'http'; - urlStr = urlObj.format(); - } - - request.get({ - uri: urlStr, - strictSSL: !options.insecure - }, function (error, res, body) { - if (error) { - reject({ - type: 'File', - message: `resource '${urlStr}' gave this Error:\n ${error}\n` - }); - return; - } - - if (res && res.statusCode === 404) { - reject({ - type: 'File', - message: `resource '${urlStr}' was not found\n` +var UrlFileManager = /** @class */ (function (_super) { + tslib.__extends(UrlFileManager, _super); + function UrlFileManager() { + return _super !== null && _super.apply(this, arguments) || this; + } + UrlFileManager.prototype.supports = function (filename, currentDirectory, options, environment) { + return isUrlRe.test(filename) || isUrlRe.test(currentDirectory); + }; + UrlFileManager.prototype.loadFile = function (filename, currentDirectory, options, environment) { + return new Promise(function (fulfill, reject) { + if (request === undefined) { + try { + request = require('request'); + } + catch (e) { + request = null; + } + } + if (!request) { + reject({ type: 'File', message: 'optional dependency \'request\' required to import over http(s)\n' }); + return; + } + var urlStr = isUrlRe.test(filename) ? filename : url.resolve(currentDirectory, filename); + var urlObj = url.parse(urlStr); + if (!urlObj.protocol) { + urlObj.protocol = 'http'; + urlStr = urlObj.format(); + } + request.get({ uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) { + if (error) { + reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n " + error + "\n" }); + return; + } + if (res && res.statusCode === 404) { + reject({ type: 'File', message: "resource '" + urlStr + "' was not found\n" }); + return; + } + if (!body) { + logger.warn("Warning: Empty body (HTTP " + res.statusCode + ") returned by \"" + urlStr + "\""); + } + fulfill({ contents: body, filename: urlStr }); }); - return; - } - - if (!body) { - logger.warn(`Warning: Empty body (HTTP ${res.statusCode}) returned by "${urlStr}"`); - } - - fulfill({ - contents: body, - filename: urlStr - }); }); - }); - } - }]); - - return UrlFileManager; -}(AbstractFileManager); + }; + return UrlFileManager; +}(AbstractFileManager)); var colors = { - 'aliceblue': '#f0f8ff', - 'antiquewhite': '#faebd7', - 'aqua': '#00ffff', - 'aquamarine': '#7fffd4', - 'azure': '#f0ffff', - 'beige': '#f5f5dc', - 'bisque': '#ffe4c4', - 'black': '#000000', - 'blanchedalmond': '#ffebcd', - 'blue': '#0000ff', - 'blueviolet': '#8a2be2', - 'brown': '#a52a2a', - 'burlywood': '#deb887', - 'cadetblue': '#5f9ea0', - 'chartreuse': '#7fff00', - 'chocolate': '#d2691e', - 'coral': '#ff7f50', - 'cornflowerblue': '#6495ed', - 'cornsilk': '#fff8dc', - 'crimson': '#dc143c', - 'cyan': '#00ffff', - 'darkblue': '#00008b', - 'darkcyan': '#008b8b', - 'darkgoldenrod': '#b8860b', - 'darkgray': '#a9a9a9', - 'darkgrey': '#a9a9a9', - 'darkgreen': '#006400', - 'darkkhaki': '#bdb76b', - 'darkmagenta': '#8b008b', - 'darkolivegreen': '#556b2f', - 'darkorange': '#ff8c00', - 'darkorchid': '#9932cc', - 'darkred': '#8b0000', - 'darksalmon': '#e9967a', - 'darkseagreen': '#8fbc8f', - 'darkslateblue': '#483d8b', - 'darkslategray': '#2f4f4f', - 'darkslategrey': '#2f4f4f', - 'darkturquoise': '#00ced1', - 'darkviolet': '#9400d3', - 'deeppink': '#ff1493', - 'deepskyblue': '#00bfff', - 'dimgray': '#696969', - 'dimgrey': '#696969', - 'dodgerblue': '#1e90ff', - 'firebrick': '#b22222', - 'floralwhite': '#fffaf0', - 'forestgreen': '#228b22', - 'fuchsia': '#ff00ff', - 'gainsboro': '#dcdcdc', - 'ghostwhite': '#f8f8ff', - 'gold': '#ffd700', - 'goldenrod': '#daa520', - 'gray': '#808080', - 'grey': '#808080', - 'green': '#008000', - 'greenyellow': '#adff2f', - 'honeydew': '#f0fff0', - 'hotpink': '#ff69b4', - 'indianred': '#cd5c5c', - 'indigo': '#4b0082', - 'ivory': '#fffff0', - 'khaki': '#f0e68c', - 'lavender': '#e6e6fa', - 'lavenderblush': '#fff0f5', - 'lawngreen': '#7cfc00', - 'lemonchiffon': '#fffacd', - 'lightblue': '#add8e6', - 'lightcoral': '#f08080', - 'lightcyan': '#e0ffff', - 'lightgoldenrodyellow': '#fafad2', - 'lightgray': '#d3d3d3', - 'lightgrey': '#d3d3d3', - 'lightgreen': '#90ee90', - 'lightpink': '#ffb6c1', - 'lightsalmon': '#ffa07a', - 'lightseagreen': '#20b2aa', - 'lightskyblue': '#87cefa', - 'lightslategray': '#778899', - 'lightslategrey': '#778899', - 'lightsteelblue': '#b0c4de', - 'lightyellow': '#ffffe0', - 'lime': '#00ff00', - 'limegreen': '#32cd32', - 'linen': '#faf0e6', - 'magenta': '#ff00ff', - 'maroon': '#800000', - 'mediumaquamarine': '#66cdaa', - 'mediumblue': '#0000cd', - 'mediumorchid': '#ba55d3', - 'mediumpurple': '#9370d8', - 'mediumseagreen': '#3cb371', - 'mediumslateblue': '#7b68ee', - 'mediumspringgreen': '#00fa9a', - 'mediumturquoise': '#48d1cc', - 'mediumvioletred': '#c71585', - 'midnightblue': '#191970', - 'mintcream': '#f5fffa', - 'mistyrose': '#ffe4e1', - 'moccasin': '#ffe4b5', - 'navajowhite': '#ffdead', - 'navy': '#000080', - 'oldlace': '#fdf5e6', - 'olive': '#808000', - 'olivedrab': '#6b8e23', - 'orange': '#ffa500', - 'orangered': '#ff4500', - 'orchid': '#da70d6', - 'palegoldenrod': '#eee8aa', - 'palegreen': '#98fb98', - 'paleturquoise': '#afeeee', - 'palevioletred': '#d87093', - 'papayawhip': '#ffefd5', - 'peachpuff': '#ffdab9', - 'peru': '#cd853f', - 'pink': '#ffc0cb', - 'plum': '#dda0dd', - 'powderblue': '#b0e0e6', - 'purple': '#800080', - 'rebeccapurple': '#663399', - 'red': '#ff0000', - 'rosybrown': '#bc8f8f', - 'royalblue': '#4169e1', - 'saddlebrown': '#8b4513', - 'salmon': '#fa8072', - 'sandybrown': '#f4a460', - 'seagreen': '#2e8b57', - 'seashell': '#fff5ee', - 'sienna': '#a0522d', - 'silver': '#c0c0c0', - 'skyblue': '#87ceeb', - 'slateblue': '#6a5acd', - 'slategray': '#708090', - 'slategrey': '#708090', - 'snow': '#fffafa', - 'springgreen': '#00ff7f', - 'steelblue': '#4682b4', - 'tan': '#d2b48c', - 'teal': '#008080', - 'thistle': '#d8bfd8', - 'tomato': '#ff6347', - 'turquoise': '#40e0d0', - 'violet': '#ee82ee', - 'wheat': '#f5deb3', - 'white': '#ffffff', - 'whitesmoke': '#f5f5f5', - 'yellow': '#ffff00', - 'yellowgreen': '#9acd32' + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgrey': '#a9a9a9', + 'darkgreen': '#006400', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'grey': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgrey': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370d8', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#d87093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'rebeccapurple': '#663399', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32' }; var unitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1 / (2 * Math.PI), - 'deg': 1 / 360, - 'grad': 1 / 400, - 'turn': 1 - } -}; - -var data = { - colors, - unitConversions + length: { + 'm': 1, + 'cm': 0.01, + 'mm': 0.001, + 'in': 0.0254, + 'px': 0.0254 / 96, + 'pt': 0.0254 / 72, + 'pc': 0.0254 / 72 * 12 + }, + duration: { + 's': 1, + 'ms': 0.001 + }, + angle: { + 'rad': 1 / (2 * Math.PI), + 'deg': 1 / 360, + 'grad': 1 / 400, + 'turn': 1 + } }; -var Node = -/*#__PURE__*/ -function () { - function Node() { - _classCallCheck(this, Node); - - this.parent = null; - this.visibilityBlocks = undefined; - this.nodeVisible = undefined; - this.rootNode = null; - this.parsed = null; - var self = this; - Object.defineProperty(this, 'currentFileInfo', { - get: function get() { - return self.fileInfo(); - } - }); - Object.defineProperty(this, 'index', { - get: function get() { - return self.getIndex(); - } - }); - } - - _createClass(Node, [{ - key: "setParent", - value: function setParent(nodes, parent) { - function set(node) { - if (node && node instanceof Node) { - node.parent = parent; - } - } - - if (Array.isArray(nodes)) { - nodes.forEach(set); - } else { - set(nodes); - } - } - }, { - key: "getIndex", - value: function getIndex() { - return this._index || this.parent && this.parent.getIndex() || 0; - } - }, { - key: "fileInfo", - value: function fileInfo() { - return this._fileInfo || this.parent && this.parent.fileInfo() || {}; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return false; - } - }, { - key: "toCSS", - value: function toCSS(context) { - var strs = []; - this.genCSS(context, { - add: function add(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function isEmpty() { - return strs.length === 0; - } - }); - return strs.join(''); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.value); - } - }, { - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval() { - return this; - } - }, { - key: "_operate", - value: function _operate(context, op, a, b) { - switch (op) { - case '+': - return a + b; - - case '-': - return a - b; - - case '*': - return a * b; - - case '/': - return a / b; - } - } - }, { - key: "fround", - value: function fround(context, value) { - var precision = context && context.numPrecision; // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: - - return precision ? Number((value + 2e-16).toFixed(precision)) : value; - } // Returns true if this node represents root of ast imported by reference - - }, { - key: "blocksVisibility", - value: function blocksVisibility() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - return this.visibilityBlocks !== 0; - } - }, { - key: "addVisibilityBlock", - value: function addVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - this.visibilityBlocks = this.visibilityBlocks + 1; - } - }, { - key: "removeVisibilityBlock", - value: function removeVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } +var data = { colors: colors, unitConversions: unitConversions }; - this.visibilityBlocks = this.visibilityBlocks - 1; - } // Turns on node visibility - if called node will be shown in output regardless +var Node = /** @class */ (function () { + function Node() { + this.parent = null; + this.visibilityBlocks = undefined; + this.nodeVisible = undefined; + this.rootNode = null; + this.parsed = null; + var self = this; + Object.defineProperty(this, 'currentFileInfo', { + get: function () { return self.fileInfo(); } + }); + Object.defineProperty(this, 'index', { + get: function () { return self.getIndex(); } + }); + } + Node.prototype.setParent = function (nodes, parent) { + function set(node) { + if (node && node instanceof Node) { + node.parent = parent; + } + } + if (Array.isArray(nodes)) { + nodes.forEach(set); + } + else { + set(nodes); + } + }; + Node.prototype.getIndex = function () { + return this._index || (this.parent && this.parent.getIndex()) || 0; + }; + Node.prototype.fileInfo = function () { + return this._fileInfo || (this.parent && this.parent.fileInfo()) || {}; + }; + Node.prototype.isRulesetLike = function () { + return false; + }; + Node.prototype.toCSS = function (context) { + var strs = []; + this.genCSS(context, { + add: function (chunk, fileInfo, index) { + strs.push(chunk); + }, + isEmpty: function () { + return strs.length === 0; + } + }); + return strs.join(''); + }; + Node.prototype.genCSS = function (context, output) { + output.add(this.value); + }; + Node.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Node.prototype.eval = function () { return this; }; + Node.prototype._operate = function (context, op, a, b) { + switch (op) { + case '+': return a + b; + case '-': return a - b; + case '*': return a * b; + case '/': return a / b; + } + }; + Node.prototype.fround = function (context, value) { + var precision = context && context.numPrecision; + // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: + return (precision) ? Number((value + 2e-16).toFixed(precision)) : value; + }; + // Returns true if this node represents root of ast imported by reference + Node.prototype.blocksVisibility = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + return this.visibilityBlocks !== 0; + }; + Node.prototype.addVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks + 1; + }; + Node.prototype.removeVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks - 1; + }; + // Turns on node visibility - if called node will be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureVisibility", - value: function ensureVisibility() { - this.nodeVisible = true; - } // Turns off node visibility - if called node will NOT be shown in output regardless + Node.prototype.ensureVisibility = function () { + this.nodeVisible = true; + }; + // Turns off node visibility - if called node will NOT be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureInvisibility", - value: function ensureInvisibility() { - this.nodeVisible = false; - } // return values: + Node.prototype.ensureInvisibility = function () { + this.nodeVisible = false; + }; + // return values: // false - the node must not be visible // true - the node must be visible // undefined or null - the node has the same visibility as its parent - - }, { - key: "isVisible", - value: function isVisible() { - return this.nodeVisible; - } - }, { - key: "visibilityInfo", - value: function visibilityInfo() { - return { - visibilityBlocks: this.visibilityBlocks, - nodeVisible: this.nodeVisible - }; - } - }, { - key: "copyVisibilityInfo", - value: function copyVisibilityInfo(info) { - if (!info) { - return; - } - - this.visibilityBlocks = info.visibilityBlocks; - this.nodeVisible = info.nodeVisible; - } - }]); - - return Node; -}(); - + Node.prototype.isVisible = function () { + return this.nodeVisible; + }; + Node.prototype.visibilityInfo = function () { + return { + visibilityBlocks: this.visibilityBlocks, + nodeVisible: this.nodeVisible + }; + }; + Node.prototype.copyVisibilityInfo = function (info) { + if (!info) { + return; + } + this.visibilityBlocks = info.visibilityBlocks; + this.nodeVisible = info.nodeVisible; + }; + return Node; +}()); Node.compare = function (a, b) { - /* returns: - -1: a < b - 0: a = b - 1: a > b - and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ - if (a.compare && // for "symmetric results" force toCSS-based comparison - // of Quoted or Anonymous if either value is one of those - !(b.type === 'Quoted' || b.type === 'Anonymous')) { - return a.compare(b); - } else if (b.compare) { - return -b.compare(a); - } else if (a.type !== b.type) { - return undefined; - } - - a = a.value; - b = b.value; - - if (!Array.isArray(a)) { - return a === b ? 0 : undefined; - } - - if (a.length !== b.length) { - return undefined; - } - - for (var i = 0; i < a.length; i++) { - if (Node.compare(a[i], b[i]) !== 0) { - return undefined; + /* returns: + -1: a < b + 0: a = b + 1: a > b + and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ + if ((a.compare) && + // for "symmetric results" force toCSS-based comparison + // of Quoted or Anonymous if either value is one of those + !(b.type === 'Quoted' || b.type === 'Anonymous')) { + return a.compare(b); + } + else if (b.compare) { + return -b.compare(a); + } + else if (a.type !== b.type) { + return undefined; } - } - - return 0; -}; - -Node.numericCompare = function (a, b) { - return a < b ? -1 : a === b ? 0 : a > b ? 1 : undefined; + a = a.value; + b = b.value; + if (!Array.isArray(a)) { + return a === b ? 0 : undefined; + } + if (a.length !== b.length) { + return undefined; + } + for (var i_1 = 0; i_1 < a.length; i_1++) { + if (Node.compare(a[i_1], b[i_1]) !== 0) { + return undefined; + } + } + return 0; }; +Node.numericCompare = function (a, b) { return a < b ? -1 + : a === b ? 0 + : a > b ? 1 : undefined; }; +// // RGB Colors - #ff0014, #eee // - -var Color = -/*#__PURE__*/ -function (_Node) { - _inherits(Color, _Node); - - function Color(rgb, a, originalForm) { - var _this; - - _classCallCheck(this, Color); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Color).call(this)); - - var self = _assertThisInitialized(_this); // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - - - if (Array.isArray(rgb)) { - _this.rgb = rgb; - } else if (rgb.length >= 6) { - _this.rgb = []; - rgb.match(/.{2}/g).map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c, 16)); - } else { - self.alpha = parseInt(c, 16) / 255; - } - }); - } else { - _this.rgb = []; - rgb.split('').map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c + c, 16)); - } else { - self.alpha = parseInt(c + c, 16) / 255; - } - }); - } - - _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); - - if (typeof originalForm !== 'undefined') { - _this.value = originalForm; +var Color = /** @class */ (function (_super) { + tslib.__extends(Color, _super); + function Color(rgb, a, originalForm) { + var _this = _super.call(this) || this; + var self = _this; + // + // The end goal here, is to parse the arguments + // into an integer triplet, such as `128, 255, 0` + // + // This facilitates operations and conversions. + // + if (Array.isArray(rgb)) { + _this.rgb = rgb; + } + else if (rgb.length >= 6) { + _this.rgb = []; + rgb.match(/.{2}/g).map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c, 16)); + } + else { + self.alpha = (parseInt(c, 16)) / 255; + } + }); + } + else { + _this.rgb = []; + rgb.split('').map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c + c, 16)); + } + else { + self.alpha = (parseInt(c + c, 16)) / 255; + } + }); + } + _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); + if (typeof originalForm !== 'undefined') { + _this.value = originalForm; + } + return _this; } - - return _this; - } - - _createClass(Color, [{ - key: "luma", - value: function luma() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - r = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4); - g = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4); - b = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4); - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context, doNotCompress) { - var compress = context && context.compress && !doNotCompress; - var color; - var alpha; - var colorFunction; - var args = []; // `value` is set if this color was originally - // converted from a named color string so we need - // to respect this and try to output named color too. - - alpha = this.fround(context, this.alpha); - - if (this.value) { - if (this.value.indexOf('rgb') === 0) { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } else if (this.value.indexOf('hsl') === 0) { - if (alpha < 1) { - colorFunction = 'hsla'; - } else { - colorFunction = 'hsl'; - } - } else { - return this.value; - } - } else { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } - - switch (colorFunction) { - case 'rgba': - args = this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)); - break; - - case 'hsla': - args.push(clamp(alpha, 1)); - - case 'hsl': - color = this.toHSL(); - args = [this.fround(context, color.h), `${this.fround(context, color.s * 100)}%`, `${this.fround(context, color.l * 100)}%`].concat(args); - } - - if (colorFunction) { - // Values are capped between `0` and `255`, rounded and zero-padded. - return `${colorFunction}(${args.join(`,${compress ? '' : ' '}`)})`; - } - - color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); // Convert color to short format - - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = `#${splitcolor[1]}${splitcolor[3]}${splitcolor[5]}`; + Color.prototype.luma = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); + g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); + b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); + return 0.2126 * r + 0.7152 * g + 0.0722 * b; + }; + Color.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Color.prototype.toCSS = function (context, doNotCompress) { + var compress = context && context.compress && !doNotCompress; + var color; + var alpha; + var colorFunction; + var args = []; + // `value` is set if this color was originally + // converted from a named color string so we need + // to respect this and try to output named color too. + alpha = this.fround(context, this.alpha); + if (this.value) { + if (this.value.indexOf('rgb') === 0) { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + else if (this.value.indexOf('hsl') === 0) { + if (alpha < 1) { + colorFunction = 'hsla'; + } + else { + colorFunction = 'hsl'; + } + } + else { + return this.value; + } } - } - - return color; - } // + else { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + switch (colorFunction) { + case 'rgba': + args = this.rgb.map(function (c) { return clamp(Math.round(c), 255); }).concat(clamp(alpha, 1)); + break; + case 'hsla': + args.push(clamp(alpha, 1)); + case 'hsl': + color = this.toHSL(); + args = [ + this.fround(context, color.h), + this.fround(context, color.s * 100) + "%", + this.fround(context, color.l * 100) + "%" + ].concat(args); + } + if (colorFunction) { + // Values are capped between `0` and `255`, rounded and zero-padded. + return colorFunction + "(" + args.join("," + (compress ? '' : ' ')) + ")"; + } + color = this.toRGB(); + if (compress) { + var splitcolor = color.split(''); + // Convert color to short format + if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { + color = "#" + splitcolor[1] + splitcolor[3] + splitcolor[5]; + } + } + return color; + }; + // // Operations have to be done per-channel, if not, // channels will spill onto each other. Once we have // our result, in the form of an integer triplet, // we create a new Color node to hold the result. // - - }, { - key: "operate", - value: function operate(context, op, other) { - var rgb = new Array(3); - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - - for (var c = 0; c < 3; c++) { - rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); - } - - return new Color(rgb, alpha); - } - }, { - key: "toRGB", - value: function toRGB() { - return toHex(this.rgb); - } - }, { - key: "toHSL", - value: function toHSL() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var l = (max + min) / 2; - var d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + Color.prototype.operate = function (context, op, other) { + var rgb = new Array(3); + var alpha = this.alpha * (1 - other.alpha) + other.alpha; + for (var c = 0; c < 3; c++) { + rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); } - - h /= 6; - } - - return { - h: h * 360, - s, - l, - a - }; - } // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - - }, { - key: "toHSV", - value: function toHSV() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var v = max; - var d = max - min; - - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + return new Color(rgb, alpha); + }; + Color.prototype.toRGB = function () { + return toHex(this.rgb); + }; + Color.prototype.toHSL = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var l = (max + min) / 2; + var d = max - min; + if (max === min) { + h = s = 0; + } + else { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; } - - h /= 6; - } - - return { - h: h * 360, - s, - v, - a - }; - } - }, { - key: "toARGB", - value: function toARGB() { - return toHex([this.alpha * 255].concat(this.rgb)); - } - }, { - key: "compare", - value: function compare(x) { - return x.rgb && x.rgb[0] === this.rgb[0] && x.rgb[1] === this.rgb[1] && x.rgb[2] === this.rgb[2] && x.alpha === this.alpha ? 0 : undefined; - } - }]); - - return Color; -}(Node); - + return { h: h * 360, s: s, l: l, a: a }; + }; + // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + Color.prototype.toHSV = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var v = max; + var d = max - min; + if (max === 0) { + s = 0; + } + else { + s = d / max; + } + if (max === min) { + h = 0; + } + else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return { h: h * 360, s: s, v: v, a: a }; + }; + Color.prototype.toARGB = function () { + return toHex([this.alpha * 255].concat(this.rgb)); + }; + Color.prototype.compare = function (x) { + return (x.rgb && + x.rgb[0] === this.rgb[0] && + x.rgb[1] === this.rgb[1] && + x.rgb[2] === this.rgb[2] && + x.alpha === this.alpha) ? 0 : undefined; + }; + return Color; +}(Node)); Color.prototype.type = 'Color'; - function clamp(v, max) { - return Math.min(Math.max(v, 0), max); + return Math.min(Math.max(v, 0), max); } - function toHex(v) { - return `#${v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join('')}`; + return "#" + v.map(function (c) { + c = clamp(Math.round(c), 255); + return (c < 16 ? '0' : '') + c.toString(16); + }).join(''); } - Color.fromKeyword = function (keyword) { - var c; - var key = keyword.toLowerCase(); - - if (colors.hasOwnProperty(key)) { - c = new Color(colors[key].slice(1)); - } else if (key === 'transparent') { - c = new Color([0, 0, 0], 0); - } - - if (c) { - c.value = keyword; - return c; - } + var c; + var key = keyword.toLowerCase(); + if (colors.hasOwnProperty(key)) { + c = new Color(colors[key].slice(1)); + } + else if (key === 'transparent') { + c = new Color([0, 0, 0], 0); + } + if (c) { + c.value = keyword; + return c; + } }; -var Paren = -/*#__PURE__*/ -function (_Node) { - _inherits(Paren, _Node); - - function Paren(node) { - var _this; - - _classCallCheck(this, Paren); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Paren).call(this)); - _this.value = node; - return _this; - } - - _createClass(Paren, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - return new Paren(this.value.eval(context)); - } - }]); - - return Paren; -}(Node); - +var Paren = /** @class */ (function (_super) { + tslib.__extends(Paren, _super); + function Paren(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; + } + Paren.prototype.genCSS = function (context, output) { + output.add('('); + this.value.genCSS(context, output); + output.add(')'); + }; + Paren.prototype.eval = function (context) { + return new Paren(this.value.eval(context)); + }; + return Paren; +}(Node)); Paren.prototype.type = 'Paren'; var _noSpaceCombinators = { - '': true, - ' ': true, - '|': true + '': true, + ' ': true, + '|': true }; - -var Combinator = -/*#__PURE__*/ -function (_Node) { - _inherits(Combinator, _Node); - - function Combinator(value) { - var _this; - - _classCallCheck(this, Combinator); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Combinator).call(this)); - - if (value === ' ') { - _this.value = ' '; - _this.emptyOrWhitespace = true; - } else { - _this.value = value ? value.trim() : ''; - _this.emptyOrWhitespace = _this.value === ''; - } - - return _this; - } - - _createClass(Combinator, [{ - key: "genCSS", - value: function genCSS(context, output) { - var spaceOrEmpty = context.compress || _noSpaceCombinators[this.value] ? '' : ' '; - output.add(spaceOrEmpty + this.value + spaceOrEmpty); - } - }]); - - return Combinator; -}(Node); - +var Combinator = /** @class */ (function (_super) { + tslib.__extends(Combinator, _super); + function Combinator(value) { + var _this = _super.call(this) || this; + if (value === ' ') { + _this.value = ' '; + _this.emptyOrWhitespace = true; + } + else { + _this.value = value ? value.trim() : ''; + _this.emptyOrWhitespace = _this.value === ''; + } + return _this; + } + Combinator.prototype.genCSS = function (context, output) { + var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' '; + output.add(spaceOrEmpty + this.value + spaceOrEmpty); + }; + return Combinator; +}(Node)); Combinator.prototype.type = 'Combinator'; -var Element = -/*#__PURE__*/ -function (_Node) { - _inherits(Element, _Node); - - function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Element); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Element).call(this)); - _this.combinator = combinator instanceof Combinator ? combinator : new Combinator(combinator); - - if (typeof value === 'string') { - _this.value = value.trim(); - } else if (value) { - _this.value = value; - } else { - _this.value = ''; - } - - _this.isVariable = isVariable; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.combinator, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Element, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - - if (typeof value === 'object') { - this.value = visitor.visit(value); - } - } - }, { - key: "eval", - value: function _eval(context) { - return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone() { - return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); - } - }, { - key: "toCSS", - value: function toCSS() { - var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var value = this.value; - var firstSelector = context.firstSelector; - - if (value instanceof Paren) { - // selector in parens should not be affected by outer selector - // flags (breaks only interpolated selectors - see #1973) - context.firstSelector = true; - } - - value = value.toCSS ? value.toCSS(context) : value; - context.firstSelector = firstSelector; - - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(context) + value; - } - } - }]); - - return Element; -}(Node); - +var Element = /** @class */ (function (_super) { + tslib.__extends(Element, _super); + function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.combinator = combinator instanceof Combinator ? + combinator : new Combinator(combinator); + if (typeof value === 'string') { + _this.value = value.trim(); + } + else if (value) { + _this.value = value; + } + else { + _this.value = ''; + } + _this.isVariable = isVariable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.combinator, _this); + return _this; + } + Element.prototype.accept = function (visitor) { + var value = this.value; + this.combinator = visitor.visit(this.combinator); + if (typeof value === 'object') { + this.value = visitor.visit(value); + } + }; + Element.prototype.eval = function (context) { + return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.clone = function () { + return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); + }; + Element.prototype.toCSS = function (context) { + if (context === void 0) { context = {}; } + var value = this.value; + var firstSelector = context.firstSelector; + if (value instanceof Paren) { + // selector in parens should not be affected by outer selector + // flags (breaks only interpolated selectors - see #1973) + context.firstSelector = true; + } + value = value.toCSS ? value.toCSS(context) : value; + context.firstSelector = firstSelector; + if (value === '' && this.combinator.value.charAt(0) === '&') { + return ''; + } + else { + return this.combinator.toCSS(context) + value; + } + }; + return Element; +}(Node)); Element.prototype.type = 'Element'; var Math$1 = { - ALWAYS: 0, - PARENS_DIVISION: 1, - PARENS: 2, - STRICT_LEGACY: 3 + ALWAYS: 0, + PARENS_DIVISION: 1, + PARENS: 2, + STRICT_LEGACY: 3 }; var RewriteUrls = { - OFF: 0, - LOCAL: 1, - ALL: 2 + OFF: 0, + LOCAL: 1, + ALL: 2 }; /* jshint proto: true */ function getLocation(index, inputStream) { - var n = index + 1; - var line = null; - var column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || '').length; - } - - return { - line, - column - }; + var n = index + 1; + var line = null; + var column = -1; + while (--n >= 0 && inputStream.charAt(n) !== '\n') { + column++; + } + if (typeof index === 'number') { + line = (inputStream.slice(0, index).match(/\n/g) || '').length; + } + return { + line: line, + column: column + }; } function copyArray(arr) { - var i; - var length = arr.length; - var copy = new Array(length); - - for (i = 0; i < length; i++) { - copy[i] = arr[i]; - } - - return copy; + var i; + var length = arr.length; + var copy = new Array(length); + for (i = 0; i < length; i++) { + copy[i] = arr[i]; + } + return copy; } function clone(obj) { - var cloned = {}; - - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - cloned[prop] = obj[prop]; + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } } - } - - return cloned; + return cloned; } function defaults(obj1, obj2) { - var newObj = obj2 || {}; - - if (!obj2._defaults) { - newObj = {}; - - var _defaults = CloneHelper(obj1); - - newObj._defaults = _defaults; - var cloned = obj2 ? CloneHelper(obj2) : {}; - Object.assign(newObj, _defaults, cloned); - } - - return newObj; + var newObj = obj2 || {}; + if (!obj2._defaults) { + newObj = {}; + var defaults_1 = CloneHelper(obj1); + newObj._defaults = defaults_1; + var cloned = obj2 ? CloneHelper(obj2) : {}; + Object.assign(newObj, defaults_1, cloned); + } + return newObj; } function copyOptions(obj1, obj2) { - if (obj2 && obj2._defaults) { - return obj2; - } - - var opts = defaults(obj1, obj2); - - if (opts.strictMath) { - opts.math = Math$1.STRICT_LEGACY; - } // Back compat with changed relativeUrls option - - - if (opts.relativeUrls) { - opts.rewriteUrls = RewriteUrls.ALL; - } - - if (typeof opts.math === 'string') { - switch (opts.math.toLowerCase()) { - case 'always': - opts.math = Math$1.ALWAYS; - break; - - case 'parens-division': - opts.math = Math$1.PARENS_DIVISION; - break; - - case 'strict': - case 'parens': - opts.math = Math$1.PARENS; - break; - - case 'strict-legacy': + if (obj2 && obj2._defaults) { + return obj2; + } + var opts = defaults(obj1, obj2); + if (opts.strictMath) { opts.math = Math$1.STRICT_LEGACY; } - } - - if (typeof opts.rewriteUrls === 'string') { - switch (opts.rewriteUrls.toLowerCase()) { - case 'off': - opts.rewriteUrls = RewriteUrls.OFF; - break; - - case 'local': - opts.rewriteUrls = RewriteUrls.LOCAL; - break; - - case 'all': + // Back compat with changed relativeUrls option + if (opts.relativeUrls) { opts.rewriteUrls = RewriteUrls.ALL; - break; } - } - - return opts; + if (typeof opts.math === 'string') { + switch (opts.math.toLowerCase()) { + case 'always': + opts.math = Math$1.ALWAYS; + break; + case 'parens-division': + opts.math = Math$1.PARENS_DIVISION; + break; + case 'strict': + case 'parens': + opts.math = Math$1.PARENS; + break; + case 'strict-legacy': + opts.math = Math$1.STRICT_LEGACY; + } + } + if (typeof opts.rewriteUrls === 'string') { + switch (opts.rewriteUrls.toLowerCase()) { + case 'off': + opts.rewriteUrls = RewriteUrls.OFF; + break; + case 'local': + opts.rewriteUrls = RewriteUrls.LOCAL; + break; + case 'all': + opts.rewriteUrls = RewriteUrls.ALL; + break; + } + } + return opts; } function merge(obj1, obj2) { - for (var prop in obj2) { - if (obj2.hasOwnProperty(prop)) { - obj1[prop] = obj2[prop]; + for (var prop in obj2) { + if (obj2.hasOwnProperty(prop)) { + obj1[prop] = obj2[prop]; + } } - } - - return obj1; + return obj1; } -function flattenArray(arr) { - var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - - for (var i = 0, length = arr.length; i < length; i++) { - var value = arr[i]; - - if (Array.isArray(value)) { - flattenArray(value, result); - } else { - if (value !== undefined) { - result.push(value); - } - } - } - - return result; +function flattenArray(arr, result) { + if (result === void 0) { result = []; } + for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) { + var value = arr[i_1]; + if (Array.isArray(value)) { + flattenArray(value, result); + } + else { + if (value !== undefined) { + result.push(value); + } + } + } + return result; } var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, getLocation: getLocation, copyArray: copyArray, clone: clone, @@ -1647,6 +1181,7 @@ var utils = /*#__PURE__*/Object.freeze({ flattenArray: flattenArray }); +var anonymousFunc = /(|Function):(\d+):(\d+)/; /** * This is a centralized class of any error that could be thrown internally (mostly by the parser). * Besides standard .message it keeps some additional data like a path to the file where the error @@ -1669,55 +1204,68 @@ var utils = /*#__PURE__*/Object.freeze({ * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager? * @param {string} [currentFilename] */ - var LessError = function LessError(e, fileContentMap, currentFilename) { - Error.call(this); - var filename = e.filename || currentFilename; - this.message = e.message; - this.stack = e.stack; - - if (fileContentMap && filename) { - var input = fileContentMap.contents[filename]; - var loc = getLocation(e.index, input); - var line = loc.line; - var col = loc.column; - var callLine = e.call && getLocation(e.call, input).line; - var lines = input ? input.split('\n') : ''; - this.type = e.type || 'Syntax'; - this.filename = filename; - this.index = e.index; - this.line = typeof line === 'number' ? line + 1 : null; - this.column = col; - - if (!this.line && this.stack) { - var found = this.stack.match(/(|Function):(\d+):(\d+)/); - - if (found) { - if (found[2]) { - this.line = parseInt(found[2]) - 2; - } - - if (found[3]) { - this.column = parseInt(found[3]); + Error.call(this); + var filename = e.filename || currentFilename; + this.message = e.message; + this.stack = e.stack; + if (fileContentMap && filename) { + var input = fileContentMap.contents[filename]; + var loc = getLocation(e.index, input); + var line = loc.line; + var col = loc.column; + var callLine = e.call && getLocation(e.call, input).line; + var lines = input ? input.split('\n') : ''; + this.type = e.type || 'Syntax'; + this.filename = filename; + this.index = e.index; + this.line = typeof line === 'number' ? line + 1 : null; + this.column = col; + if (!this.line && this.stack) { + var found = this.stack.match(anonymousFunc); + /** + * We have to figure out how this environment stringifies anonymous functions + * so we can correctly map plugin errors. + * + * Note, in Node 8, the output of anonymous funcs varied based on parameters + * being present or not, so we inject dummy params. + */ + var func = new Function('a', 'throw new Error()'); + var lineAdjust = 0; + try { + func(); + } + catch (e) { + var match = e.stack.match(anonymousFunc); + var line_1 = parseInt(match[2]); + lineAdjust = 1 - line_1; + } + if (found) { + if (found[2]) { + this.line = parseInt(found[2]) + lineAdjust; + } + if (found[3]) { + this.column = parseInt(found[3]); + } + } } - } + this.callLine = callLine + 1; + this.callExtract = lines[callLine]; + this.extract = [ + lines[this.line - 2], + lines[this.line - 1], + lines[this.line] + ]; } - - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.extract = [lines[this.line - 2], lines[this.line - 1], lines[this.line]]; - } }; - if (typeof Object.create === 'undefined') { - var F = function F() {}; - - F.prototype = Error.prototype; - LessError.prototype = new F(); -} else { - LessError.prototype = Object.create(Error.prototype); + var F = function () { }; + F.prototype = Error.prototype; + LessError.prototype = new F(); +} +else { + LessError.prototype = Object.create(Error.prototype); } - LessError.prototype.constructor = LessError; /** * An overridden version of the default Object.prototype.toString @@ -1726,2619 +1274,1984 @@ LessError.prototype.constructor = LessError; * @param {Object} options * @returns {string} */ - -LessError.prototype.toString = function () { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var message = ''; - var extract = this.extract || []; - var error = []; - - var stylize = function stylize(str) { - return str; - }; - - if (options.stylize) { - var type = typeof options.stylize; - - if (type !== 'function') { - throw Error(`options.stylize should be a function, got a ${type}!`); +LessError.prototype.toString = function (options) { + if (options === void 0) { options = {}; } + var message = ''; + var extract = this.extract || []; + var error = []; + var stylize = function (str) { return str; }; + if (options.stylize) { + var type = typeof options.stylize; + if (type !== 'function') { + throw Error("options.stylize should be a function, got a " + type + "!"); + } + stylize = options.stylize; + } + if (this.line !== null) { + if (typeof extract[0] === 'string') { + error.push(stylize(this.line - 1 + " " + extract[0], 'grey')); + } + if (typeof extract[1] === 'string') { + var errorTxt = this.line + " "; + if (extract[1]) { + errorTxt += extract[1].slice(0, this.column) + + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + + extract[1].slice(this.column + 1), 'red'), 'inverse'); + } + error.push(errorTxt); + } + if (typeof extract[2] === 'string') { + error.push(stylize(this.line + 1 + " " + extract[2], 'grey')); + } + error = error.join('\n') + stylize('', 'reset') + "\n"; } - - stylize = options.stylize; - } - - if (this.line !== null) { - if (typeof extract[0] === 'string') { - error.push(stylize(`${this.line - 1} ${extract[0]}`, 'grey')); + message += stylize(this.type + "Error: " + this.message, 'red'); + if (this.filename) { + message += stylize(' in ', 'red') + this.filename; } - - if (typeof extract[1] === 'string') { - var errorTxt = `${this.line} `; - - if (extract[1]) { - errorTxt += extract[1].slice(0, this.column) + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + extract[1].slice(this.column + 1), 'red'), 'inverse'); - } - - error.push(errorTxt); + if (this.line) { + message += stylize(" on line " + this.line + ", column " + (this.column + 1) + ":", 'grey'); } - - if (typeof extract[2] === 'string') { - error.push(stylize(`${this.line + 1} ${extract[2]}`, 'grey')); + message += "\n" + error; + if (this.callLine) { + message += stylize('from ', 'red') + (this.filename || '') + "/n"; + message += stylize(this.callLine, 'grey') + " " + this.callExtract + "/n"; } - - error = `${error.join('\n') + stylize('', 'reset')}\n`; - } - - message += stylize(`${this.type}Error: ${this.message}`, 'red'); - - if (this.filename) { - message += stylize(' in ', 'red') + this.filename; - } - - if (this.line) { - message += stylize(` on line ${this.line}, column ${this.column + 1}:`, 'grey'); - } - - message += `\n${error}`; - - if (this.callLine) { - message += `${stylize('from ', 'red') + (this.filename || '')}/n`; - message += `${stylize(this.callLine, 'grey')} ${this.callExtract}/n`; - } - - return message; + return message; }; -var Selector = -/*#__PURE__*/ -function (_Node) { - _inherits(Selector, _Node); - - function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Selector); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Selector).call(this)); - _this.extendList = extendList; - _this.condition = condition; - _this.evaldCondition = !condition; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.elements = _this.getElements(elements); - _this.mixinElements_ = undefined; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.elements, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Selector, [{ - key: "accept", - value: function accept(visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "createDerived", - value: function createDerived(elements, extendList, evaldCondition) { - elements = this.getElements(elements); - var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - newSelector.evaldCondition = evaldCondition != null ? evaldCondition : this.evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - } - }, { - key: "getElements", - value: function getElements(els) { - if (!els) { - return [new Element('', '&', false, this._index, this._fileInfo)]; - } - - if (typeof els === 'string') { - this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { - if (err) { - throw new LessError({ - index: err.index, - message: err.message - }, this.parse.imports, this._fileInfo.filename); - } - - els = result[0].elements; - }); - } - - return els; - } - }, { - key: "createEmptySelectors", - value: function createEmptySelectors() { - var el = new Element('', '&', false, this._index, this._fileInfo); - var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; - sels[0].mediaEmpty = true; - return sels; - } - }, { - key: "match", - value: function match(other) { - var elements = this.elements; - var len = elements.length; - var olen; - var i; - other = other.mixinElements(); - olen = other.length; - - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - } - }, { - key: "mixinElements", - value: function mixinElements() { - if (this.mixinElements_) { - return this.mixinElements_; - } - - var elements = this.elements.map(function (v) { - return v.combinator.value + (v.value.value || v.value); - }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); - - if (elements) { - if (elements[0] === '&') { - elements.shift(); +var Selector = /** @class */ (function (_super) { + tslib.__extends(Selector, _super); + function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.extendList = extendList; + _this.condition = condition; + _this.evaldCondition = !condition; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.elements = _this.getElements(elements); + _this.mixinElements_ = undefined; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.elements, _this); + return _this; + } + Selector.prototype.accept = function (visitor) { + if (this.elements) { + this.elements = visitor.visitArray(this.elements); + } + if (this.extendList) { + this.extendList = visitor.visitArray(this.extendList); + } + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } else { - elements = []; - } - - return this.mixinElements_ = elements; - } - }, { - key: "isJustParentSelector", - value: function isJustParentSelector() { - return !this.mediaEmpty && this.elements.length === 1 && this.elements[0].value === '&' && (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - } - }, { - key: "eval", - value: function _eval(context) { - var evaldCondition = this.condition && this.condition.eval(context); - var elements = this.elements; - var extendList = this.extendList; - elements = elements && elements.map(function (e) { - return e.eval(context); - }); - extendList = extendList && extendList.map(function (extend) { - return extend.eval(context); - }); - return this.createDerived(elements, extendList, evaldCondition); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var element; - - if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { - output.add(' ', this.fileInfo(), this.getIndex()); - } - - for (i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(context, output); - } - } - }, { - key: "getIsOutput", - value: function getIsOutput() { - return this.evaldCondition; - } - }]); - - return Selector; -}(Node); - + }; + Selector.prototype.createDerived = function (elements, extendList, evaldCondition) { + elements = this.getElements(elements); + var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; + newSelector.mediaEmpty = this.mediaEmpty; + return newSelector; + }; + Selector.prototype.getElements = function (els) { + if (!els) { + return [new Element('', '&', false, this._index, this._fileInfo)]; + } + if (typeof els === 'string') { + this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { + if (err) { + throw new LessError({ + index: err.index, + message: err.message + }, this.parse.imports, this._fileInfo.filename); + } + els = result[0].elements; + }); + } + return els; + }; + Selector.prototype.createEmptySelectors = function () { + var el = new Element('', '&', false, this._index, this._fileInfo); + var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; + sels[0].mediaEmpty = true; + return sels; + }; + Selector.prototype.match = function (other) { + var elements = this.elements; + var len = elements.length; + var olen; + var i; + other = other.mixinElements(); + olen = other.length; + if (olen === 0 || len < olen) { + return 0; + } + else { + for (i = 0; i < olen; i++) { + if (elements[i].value !== other[i]) { + return 0; + } + } + } + return olen; // return number of matched elements + }; + Selector.prototype.mixinElements = function () { + if (this.mixinElements_) { + return this.mixinElements_; + } + var elements = this.elements.map(function (v) { return v.combinator.value + (v.value.value || v.value); }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); + if (elements) { + if (elements[0] === '&') { + elements.shift(); + } + } + else { + elements = []; + } + return (this.mixinElements_ = elements); + }; + Selector.prototype.isJustParentSelector = function () { + return !this.mediaEmpty && + this.elements.length === 1 && + this.elements[0].value === '&' && + (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); + }; + Selector.prototype.eval = function (context) { + var evaldCondition = this.condition && this.condition.eval(context); + var elements = this.elements; + var extendList = this.extendList; + elements = elements && elements.map(function (e) { return e.eval(context); }); + extendList = extendList && extendList.map(function (extend) { return extend.eval(context); }); + return this.createDerived(elements, extendList, evaldCondition); + }; + Selector.prototype.genCSS = function (context, output) { + var i; + var element; + if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { + output.add(' ', this.fileInfo(), this.getIndex()); + } + for (i = 0; i < this.elements.length; i++) { + element = this.elements[i]; + element.genCSS(context, output); + } + }; + Selector.prototype.getIsOutput = function () { + return this.evaldCondition; + }; + return Selector; +}(Node)); Selector.prototype.type = 'Selector'; -var Value = -/*#__PURE__*/ -function (_Node) { - _inherits(Value, _Node); - - function Value(value) { - var _this; - - _classCallCheck(this, Value); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Value).call(this)); - - if (!value) { - throw new Error('Value requires an array argument'); - } - - if (!Array.isArray(value)) { - _this.value = [value]; - } else { - _this.value = value; - } - - return _this; - } - - _createClass(Value, [{ - key: "accept", - value: function accept(visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.length === 1) { - return this.value[0].eval(context); - } else { - return new Value(this.value.map(function (v) { - return v.eval(context); - })); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - - for (i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (i + 1 < this.value.length) { - output.add(context && context.compress ? ',' : ', '); +var Value = /** @class */ (function (_super) { + tslib.__extends(Value, _super); + function Value(value) { + var _this = _super.call(this) || this; + if (!value) { + throw new Error('Value requires an array argument'); + } + if (!Array.isArray(value)) { + _this.value = [value]; } - } + else { + _this.value = value; + } + return _this; } - }]); - - return Value; -}(Node); - + Value.prototype.accept = function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } + }; + Value.prototype.eval = function (context) { + if (this.value.length === 1) { + return this.value[0].eval(context); + } + else { + return new Value(this.value.map(function (v) { return v.eval(context); })); + } + }; + Value.prototype.genCSS = function (context, output) { + var i; + for (i = 0; i < this.value.length; i++) { + this.value[i].genCSS(context, output); + if (i + 1 < this.value.length) { + output.add((context && context.compress) ? ',' : ', '); + } + } + }; + return Value; +}(Node)); Value.prototype.type = 'Value'; -var Keyword = -/*#__PURE__*/ -function (_Node) { - _inherits(Keyword, _Node); - - function Keyword(value) { - var _this; - - _classCallCheck(this, Keyword); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Keyword).call(this)); - _this.value = value; - return _this; - } - - _createClass(Keyword, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.value === '%') { - throw { - type: 'Syntax', - message: 'Invalid % without number' - }; - } - - output.add(this.value); +var Keyword = /** @class */ (function (_super) { + tslib.__extends(Keyword, _super); + function Keyword(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; } - }]); - - return Keyword; -}(Node); - + Keyword.prototype.genCSS = function (context, output) { + if (this.value === '%') { + throw { type: 'Syntax', message: 'Invalid % without number' }; + } + output.add(this.value); + }; + return Keyword; +}(Node)); Keyword.prototype.type = 'Keyword'; Keyword.True = new Keyword('true'); Keyword.False = new Keyword('false'); -var Anonymous = -/*#__PURE__*/ -function (_Node) { - _inherits(Anonymous, _Node); - - function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { - var _this; - - _classCallCheck(this, Anonymous); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Anonymous).call(this)); - _this.value = value; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.mapLines = mapLines; - _this.rulesetLike = typeof rulesetLike === 'undefined' ? false : rulesetLike; - _this.allowRoot = true; - - _this.copyVisibilityInfo(visibilityInfo); - - return _this; - } - - _createClass(Anonymous, [{ - key: "eval", - value: function _eval() { - return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); - } - }, { - key: "compare", - value: function compare(other) { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rulesetLike; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.nodeVisible = Boolean(this.value); - - if (this.nodeVisible) { - output.add(this.value, this._fileInfo, this._index, this.mapLines); - } - } - }]); - - return Anonymous; -}(Node); - +var Anonymous = /** @class */ (function (_super) { + tslib.__extends(Anonymous, _super); + function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.mapLines = mapLines; + _this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike; + _this.allowRoot = true; + _this.copyVisibilityInfo(visibilityInfo); + return _this; + } + Anonymous.prototype.eval = function () { + return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); + }; + Anonymous.prototype.compare = function (other) { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + }; + Anonymous.prototype.isRulesetLike = function () { + return this.rulesetLike; + }; + Anonymous.prototype.genCSS = function (context, output) { + this.nodeVisible = Boolean(this.value); + if (this.nodeVisible) { + output.add(this.value, this._fileInfo, this._index, this.mapLines); + } + }; + return Anonymous; +}(Node)); Anonymous.prototype.type = 'Anonymous'; var MATH = Math$1; - -var Declaration = -/*#__PURE__*/ -function (_Node) { - _inherits(Declaration, _Node); - - function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { - var _this; - - _classCallCheck(this, Declaration); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Declaration).call(this)); - _this.name = name; - _this.value = value instanceof Node ? value : new Value([value ? new Anonymous(value) : null]); - _this.important = important ? ` ${important.trim()}` : ''; - _this.merge = merge; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.inline = inline || false; - _this.variable = variable !== undefined ? variable : name.charAt && name.charAt(0) === '@'; - _this.allowRoot = true; - - _this.setParent(_this.value, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Declaration, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); - - try { - this.value.genCSS(context, output); - } catch (e) { - e.index = this._index; - e.filename = this._fileInfo.filename; - throw e; - } - - output.add(this.important + (this.inline || context.lastRule && context.compress ? '' : ';'), this._fileInfo, this._index); - } - }, { - key: "eval", - value: function _eval(context) { - var mathBypass = false; - var prevMath; - var name = this.name; - var evaldValue; - var variable = this.variable; - - if (typeof name !== 'string') { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = name.length === 1 && name[0] instanceof Keyword ? name[0].value : evalName(context, name); - variable = false; // never treat expanded interpolation as new variable name - } // @todo remove when parens-division is default - - - if (name === 'font' && context.math === MATH.ALWAYS) { - mathBypass = true; - prevMath = context.math; - context.math = MATH.PARENS_DIVISION; - } - - try { - context.importantScope.push({}); - evaldValue = this.value.eval(context); - - if (!this.variable && evaldValue.type === 'DetachedRuleset') { - throw { - message: 'Rulesets cannot be evaluated on a property.', - index: this.getIndex(), - filename: this.fileInfo().filename - }; +var Declaration = /** @class */ (function (_super) { + tslib.__extends(Declaration, _super); + function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { + var _this = _super.call(this) || this; + _this.name = name; + _this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]); + _this.important = important ? " " + important.trim() : ''; + _this.merge = merge; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.inline = inline || false; + _this.variable = (variable !== undefined) ? variable + : (name.charAt && (name.charAt(0) === '@')); + _this.allowRoot = true; + _this.setParent(_this.value, _this); + return _this; + } + Declaration.prototype.genCSS = function (context, output) { + output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); + try { + this.value.genCSS(context, output); } - - var important = this.important; - var importantResult = context.importantScope.pop(); - - if (!important && importantResult.important) { - important = importantResult.important; + catch (e) { + e.index = this._index; + e.filename = this._fileInfo.filename; + throw e; } - - return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); - } catch (e) { - if (typeof e.index !== 'number') { - e.index = this.getIndex(); - e.filename = this.fileInfo().filename; + output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index); + }; + Declaration.prototype.eval = function (context) { + var mathBypass = false; + var prevMath; + var name = this.name; + var evaldValue; + var variable = this.variable; + if (typeof name !== 'string') { + // expand 'primitive' name directly to get + // things faster (~10% for benchmark.less): + name = (name.length === 1) && (name[0] instanceof Keyword) ? + name[0].value : evalName(context, name); + variable = false; // never treat expanded interpolation as new variable name + } + // @todo remove when parens-division is default + if (name === 'font' && context.math === MATH.ALWAYS) { + mathBypass = true; + prevMath = context.math; + context.math = MATH.PARENS_DIVISION; } - - throw e; - } finally { - if (mathBypass) { - context.math = prevMath; + try { + context.importantScope.push({}); + evaldValue = this.value.eval(context); + if (!this.variable && evaldValue.type === 'DetachedRuleset') { + throw { message: 'Rulesets cannot be evaluated on a property.', + index: this.getIndex(), filename: this.fileInfo().filename }; + } + var important = this.important; + var importantResult = context.importantScope.pop(); + if (!important && importantResult.important) { + important = importantResult.important; + } + return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); - } - }]); - - return Declaration; -}(Node); - + catch (e) { + if (typeof e.index !== 'number') { + e.index = this.getIndex(); + e.filename = this.fileInfo().filename; + } + throw e; + } + finally { + if (mathBypass) { + context.math = prevMath; + } + } + }; + Declaration.prototype.makeImportant = function () { + return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); + }; + return Declaration; +}(Node)); function evalName(context, name) { - var value = ''; - var i; - var n = name.length; - var output = { - add: function add(s) { - value += s; - } - }; - - for (i = 0; i < n; i++) { - name[i].eval(context).genCSS(context, output); - } - - return value; + var value = ''; + var i; + var n = name.length; + var output = { add: function (s) { value += s; } }; + for (i = 0; i < n; i++) { + name[i].eval(context).genCSS(context, output); + } + return value; } - Declaration.prototype.type = 'Declaration'; -var debugInfo = function debugInfo(context, ctx, lineSeparator) { - var result = ''; - - if (context.dumpLineNumbers && !context.compress) { - switch (context.dumpLineNumbers) { - case 'comments': - result = debugInfo.asComment(ctx); - break; - - case 'mediaquery': - result = debugInfo.asMediaQuery(ctx); - break; - - case 'all': - result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); - break; +var debugInfo = function (context, ctx, lineSeparator) { + var result = ''; + if (context.dumpLineNumbers && !context.compress) { + switch (context.dumpLineNumbers) { + case 'comments': + result = debugInfo.asComment(ctx); + break; + case 'mediaquery': + result = debugInfo.asMediaQuery(ctx); + break; + case 'all': + result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); + break; + } } - } - - return result; -}; - -debugInfo.asComment = function (ctx) { - return `/* line ${ctx.debugInfo.lineNumber}, ${ctx.debugInfo.fileName} */\n`; + return result; }; - +debugInfo.asComment = function (ctx) { return "/* line " + ctx.debugInfo.lineNumber + ", " + ctx.debugInfo.fileName + " */\n"; }; debugInfo.asMediaQuery = function (ctx) { - var filenameWithProtocol = ctx.debugInfo.fileName; - - if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { - filenameWithProtocol = `file://${filenameWithProtocol}`; - } - - return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; + var filenameWithProtocol = ctx.debugInfo.fileName; + if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { + filenameWithProtocol = "file://" + filenameWithProtocol; } - - return `\\${a}`; - })}}line{font-family:\\00003${ctx.debugInfo.lineNumber}}}\n`; + return "@media -sass-debug-info{filename{font-family:" + filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { + if (a == '\\') { + a = '\/'; + } + return "\\" + a; + }) + "}line{font-family:\\00003" + ctx.debugInfo.lineNumber + "}}\n"; }; -var Comment = -/*#__PURE__*/ -function (_Node) { - _inherits(Comment, _Node); - - function Comment(value, isLineComment, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Comment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Comment).call(this)); - _this.value = value; - _this.isLineComment = isLineComment; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(Comment, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.debugInfo) { - output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - } - }, { - key: "isSilent", - value: function isSilent(context) { - var isCompressed = context.compress && this.value[2] !== '!'; - return this.isLineComment || isCompressed; - } - }]); - - return Comment; -}(Node); - +var Comment = /** @class */ (function (_super) { + tslib.__extends(Comment, _super); + function Comment(value, isLineComment, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this.isLineComment = isLineComment; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + Comment.prototype.genCSS = function (context, output) { + if (this.debugInfo) { + output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); + } + output.add(this.value); + }; + Comment.prototype.isSilent = function (context) { + var isCompressed = context.compress && this.value[2] !== '!'; + return this.isLineComment || isCompressed; + }; + return Comment; +}(Node)); Comment.prototype.type = 'Comment'; var contexts = {}; - var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) { - if (!original) { - return; - } - - for (var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; + if (!original) { + return; + } + for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) { + if (original.hasOwnProperty(propertiesToCopy[i_1])) { + destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]]; + } } - } }; /* parse is used whilst parsing */ - - -var parseCopyProperties = [// options -'paths', // option - unmodified - paths to search for imports on -'rewriteUrls', // option - whether to adjust URL's to be relative -'rootpath', // option - rootpath to append to URL's -'strictImports', // option - -'insecure', // option - whether to allow imports from insecure ssl hosts -'dumpLineNumbers', // option - whether to dump line numbers -'compress', // option - whether to compress -'syncImport', // option - whether to import synchronously -'chunkInput', // option - whether to chunk input. more performant but causes parse issues. -'mime', // browser only - mime type for sheet import -'useFileCache', // browser only - whether to use the per file session cache -// context -'processImports', // option & context - whether to process imports. if false then imports will not be imported. -// Used by the import manager to stop multiple import visitors being created. -'pluginManager' // Used as the plugin manager for the session +var parseCopyProperties = [ + // options + 'paths', + 'rewriteUrls', + 'rootpath', + 'strictImports', + 'insecure', + 'dumpLineNumbers', + 'compress', + 'syncImport', + 'chunkInput', + 'mime', + 'useFileCache', + // context + 'processImports', + // Used by the import manager to stop multiple import visitors being created. + 'pluginManager' // Used as the plugin manager for the session ]; - contexts.Parse = function (options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } + copyFromOriginal(options, this, parseCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } }; - -var evalCopyProperties = ['paths', // additional include paths -'compress', // whether to compress -'math', // whether math has to be within parenthesis -'strictUnits', // whether units need to evaluate correctly -'sourceMap', // whether to output a source map -'importMultiple', // whether we are currently importing multiple copies -'urlArgs', // whether to add args into url tokens -'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false -'pluginManager', // Used as the plugin manager for the session -'importantScope', // used to bubble up !important statements -'rewriteUrls' // option - whether to adjust URL's to be relative +var evalCopyProperties = [ + 'paths', + 'compress', + 'math', + 'strictUnits', + 'sourceMap', + 'importMultiple', + 'urlArgs', + 'javascriptEnabled', + 'pluginManager', + 'importantScope', + 'rewriteUrls' // option - whether to adjust URL's to be relative ]; - function isPathRelative(path) { - return !/^(?:[a-z-]+:|\/|#)/i.test(path); + return !/^(?:[a-z-]+:|\/|#)/i.test(path); } - function isPathLocalRelative(path) { - return path.charAt(0) === '.'; + return path.charAt(0) === '.'; } - -contexts.Eval = -/*#__PURE__*/ -function () { - function _class(options, frames) { - _classCallCheck(this, _class); - - copyFromOriginal(options, this, evalCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } - - this.frames = frames || []; - this.importantScope = this.importantScope || []; - this.inCalc = false; - this.mathOn = true; - } - - _createClass(_class, [{ - key: "enterCalc", - value: function enterCalc() { - if (!this.calcStack) { - this.calcStack = []; - } - - this.calcStack.push(true); - this.inCalc = true; - } - }, { - key: "exitCalc", - value: function exitCalc() { - this.calcStack.pop(); - - if (!this.calcStack) { +contexts.Eval = /** @class */ (function () { + function Eval(options, frames) { + copyFromOriginal(options, this, evalCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } + this.frames = frames || []; + this.importantScope = this.importantScope || []; this.inCalc = false; - } - } - }, { - key: "inParenthesis", - value: function inParenthesis() { - if (!this.parensStack) { - this.parensStack = []; - } - - this.parensStack.push(true); - } - }, { - key: "outOfParenthesis", - value: function outOfParenthesis() { - this.parensStack.pop(); + this.mathOn = true; } - }, { - key: "isMathOn", - value: function isMathOn(op) { - if (!this.mathOn) { - return false; - } - - if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { - return false; - } - - if (this.math > Math$1.PARENS_DIVISION) { - return this.parensStack && this.parensStack.length; - } - - return true; - } - }, { - key: "pathRequiresRewrite", - value: function pathRequiresRewrite(path) { - var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; - return isRelative(path); - } - }, { - key: "rewritePath", - value: function rewritePath(path, rootpath) { - var newPath; - rootpath = rootpath || ''; - newPath = this.normalizePath(rootpath + path); // If a path was explicit relative and the rootpath was not an absolute path - // we must ensure that the new path is also explicit relative. - - if (isPathLocalRelative(path) && isPathRelative(rootpath) && isPathLocalRelative(newPath) === false) { - newPath = `./${newPath}`; - } - - return newPath; - } - }, { - key: "normalizePath", - value: function normalizePath(path) { - var segments = path.split('/').reverse(); - var segment; - path = []; - - while (segments.length !== 0) { - segment = segments.pop(); - - switch (segment) { - case '.': - break; - - case '..': - if (path.length === 0 || path[path.length - 1] === '..') { - path.push(segment); - } else { - path.pop(); + Eval.prototype.enterCalc = function () { + if (!this.calcStack) { + this.calcStack = []; + } + this.calcStack.push(true); + this.inCalc = true; + }; + Eval.prototype.exitCalc = function () { + this.calcStack.pop(); + if (!this.calcStack) { + this.inCalc = false; + } + }; + Eval.prototype.inParenthesis = function () { + if (!this.parensStack) { + this.parensStack = []; + } + this.parensStack.push(true); + }; + Eval.prototype.outOfParenthesis = function () { + this.parensStack.pop(); + }; + Eval.prototype.isMathOn = function (op) { + if (!this.mathOn) { + return false; + } + if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { + return false; + } + if (this.math > Math$1.PARENS_DIVISION) { + return this.parensStack && this.parensStack.length; + } + return true; + }; + Eval.prototype.pathRequiresRewrite = function (path) { + var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; + return isRelative(path); + }; + Eval.prototype.rewritePath = function (path, rootpath) { + var newPath; + rootpath = rootpath || ''; + newPath = this.normalizePath(rootpath + path); + // If a path was explicit relative and the rootpath was not an absolute path + // we must ensure that the new path is also explicit relative. + if (isPathLocalRelative(path) && + isPathRelative(rootpath) && + isPathLocalRelative(newPath) === false) { + newPath = "./" + newPath; + } + return newPath; + }; + Eval.prototype.normalizePath = function (path) { + var segments = path.split('/').reverse(); + var segment; + path = []; + while (segments.length !== 0) { + segment = segments.pop(); + switch (segment) { + case '.': + break; + case '..': + if ((path.length === 0) || (path[path.length - 1] === '..')) { + path.push(segment); + } + else { + path.pop(); + } + break; + default: + path.push(segment); + break; } - - break; - - default: - path.push(segment); - break; } - } - - return path.join('/'); - } - }]); - - return _class; -}(); + return path.join('/'); + }; + return Eval; +}()); function makeRegistry(base) { - return { - _data: {}, - add: function add(name, func) { - // precautionary case conversion, as later querying of - // the registry by function-caller uses lower case as well. - name = name.toLowerCase(); - - if (this._data.hasOwnProperty(name)) ; - - this._data[name] = func; - }, - addMultiple: function addMultiple(functions) { - var _this = this; - - Object.keys(functions).forEach(function (name) { - _this.add(name, functions[name]); - }); - }, - get: function get(name) { - return this._data[name] || base && base.get(name); - }, - getLocalFunctions: function getLocalFunctions() { - return this._data; - }, - inherit: function inherit() { - return makeRegistry(this); - }, - create: function create(base) { - return makeRegistry(base); - } - }; + return { + _data: {}, + add: function (name, func) { + // precautionary case conversion, as later querying of + // the registry by function-caller uses lower case as well. + name = name.toLowerCase(); + if (this._data.hasOwnProperty(name)) ; + this._data[name] = func; + }, + addMultiple: function (functions) { + var _this = this; + Object.keys(functions).forEach(function (name) { + _this.add(name, functions[name]); + }); + }, + get: function (name) { + return this._data[name] || (base && base.get(name)); + }, + getLocalFunctions: function () { + return this._data; + }, + inherit: function () { + return makeRegistry(this); + }, + create: function (base) { + return makeRegistry(base); + } + }; } - var functionRegistry = makeRegistry(null); var defaultFunc = { - eval: function _eval() { - var v = this.value_; - var e = this.error_; - - if (e) { - throw e; + eval: function () { + var v = this.value_; + var e = this.error_; + if (e) { + throw e; + } + if (v != null) { + return v ? Keyword.True : Keyword.False; + } + }, + value: function (v) { + this.value_ = v; + }, + error: function (e) { + this.error_ = e; + }, + reset: function () { + this.value_ = this.error_ = null; } - - if (v != null) { - return v ? Keyword.True : Keyword.False; - } - }, - value: function value(v) { - this.value_ = v; - }, - error: function error(e) { - this.error_ = e; - }, - reset: function reset() { - this.value_ = this.error_ = null; - } }; -var Ruleset = -/*#__PURE__*/ -function (_Node) { - _inherits(Ruleset, _Node); - - function Ruleset(selectors, rules, strictImports, visibilityInfo) { - var _this; - - _classCallCheck(this, Ruleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Ruleset).call(this)); - _this.selectors = selectors; - _this.rules = rules; - _this._lookups = {}; - _this._variables = null; - _this._properties = null; - _this.strictImports = strictImports; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(_this.selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Ruleset, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.paths) { - this.paths = visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "eval", - value: function _eval(context) { - var selectors; - var selCnt; - var selector; - var i; - var hasVariable; - var hasOnePassingSelector = false; - - if (this.selectors && (selCnt = this.selectors.length)) { - selectors = new Array(selCnt); - defaultFunc.error({ - type: 'Syntax', - message: 'it is currently only allowed in parametric mixin guards,' - }); - - for (i = 0; i < selCnt; i++) { - selector = this.selectors[i].eval(context); - - for (var j = 0; j < selector.elements.length; j++) { - if (selector.elements[j].isVariable) { - hasVariable = true; - break; +var Ruleset = /** @class */ (function (_super) { + tslib.__extends(Ruleset, _super); + function Ruleset(selectors, rules, strictImports, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selectors = selectors; + _this.rules = rules; + _this._lookups = {}; + _this._variables = null; + _this._properties = null; + _this.strictImports = strictImports; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(_this.selectors, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Ruleset.prototype.isRulesetLike = function () { + return true; + }; + Ruleset.prototype.accept = function (visitor) { + if (this.paths) { + this.paths = visitor.visitArray(this.paths, true); + } + else if (this.selectors) { + this.selectors = visitor.visitArray(this.selectors); + } + if (this.rules && this.rules.length) { + this.rules = visitor.visitArray(this.rules); + } + }; + Ruleset.prototype.eval = function (context) { + var selectors; + var selCnt; + var selector; + var i; + var hasVariable; + var hasOnePassingSelector = false; + if (this.selectors && (selCnt = this.selectors.length)) { + selectors = new Array(selCnt); + defaultFunc.error({ + type: 'Syntax', + message: 'it is currently only allowed in parametric mixin guards,' + }); + for (i = 0; i < selCnt; i++) { + selector = this.selectors[i].eval(context); + for (var j = 0; j < selector.elements.length; j++) { + if (selector.elements[j].isVariable) { + hasVariable = true; + break; + } + } + selectors[i] = selector; + if (selector.evaldCondition) { + hasOnePassingSelector = true; + } } - } - - selectors[i] = selector; - - if (selector.evaldCondition) { + if (hasVariable) { + var toParseSelectors = new Array(selCnt); + for (i = 0; i < selCnt; i++) { + selector = selectors[i]; + toParseSelectors[i] = selector.toCSS(context); + } + this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { + if (result) { + selectors = flattenArray(result); + } + }); + } + defaultFunc.reset(); + } + else { hasOnePassingSelector = true; - } } - - if (hasVariable) { - var toParseSelectors = new Array(selCnt); - - for (i = 0; i < selCnt; i++) { - selector = selectors[i]; - toParseSelectors[i] = selector.toCSS(context); - } - - this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { - if (result) { - selectors = flattenArray(result); + var rules = this.rules ? copyArray(this.rules) : null; + var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); + var rule; + var subRule; + ruleset.originalRuleset = this; + ruleset.root = this.root; + ruleset.firstRoot = this.firstRoot; + ruleset.allowImports = this.allowImports; + if (this.debugInfo) { + ruleset.debugInfo = this.debugInfo; + } + if (!hasOnePassingSelector) { + rules.length = 0; + } + // inherit a function registry from the frames stack when possible; + // otherwise from the global registry + ruleset.functionRegistry = (function (frames) { + var i = 0; + var n = frames.length; + var found; + for (; i !== n; ++i) { + found = frames[i].functionRegistry; + if (found) { + return found; + } + } + return functionRegistry; + })(context.frames).inherit(); + // push the current ruleset to the frames stack + var ctxFrames = context.frames; + ctxFrames.unshift(ruleset); + // currrent selectors + var ctxSelectors = context.selectors; + if (!ctxSelectors) { + context.selectors = ctxSelectors = []; + } + ctxSelectors.unshift(this.selectors); + // Evaluate imports + if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { + ruleset.evalImports(context); + } + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + var rsRules = ruleset.rules; + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.evalFirst) { + rsRules[i] = rule.eval(context); } - }); } - - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? copyArray(this.rules) : null; - var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); - var rule; - var subRule; - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if (this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } // inherit a function registry from the frames stack when possible; - // otherwise from the global registry - - - ruleset.functionRegistry = function (frames) { - var i = 0; - var n = frames.length; - var found; - - for (; i !== n; ++i) { - found = frames[i].functionRegistry; - - if (found) { - return found; - } + var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0; + // Evaluate mixin calls. + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.type === 'MixinCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope if the variable is + // already there. consider returning false here + // but we need a way to "return" variable from mixins + return !(ruleset.variable(r.name)); + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } + else if (rule.type === 'VariableCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).rules.filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope at all + return false; + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } } - - return functionRegistry; - }(context.frames).inherit(); // push the current ruleset to the frames stack - - - var ctxFrames = context.frames; - ctxFrames.unshift(ruleset); // currrent selectors - - var ctxSelectors = context.selectors; - - if (!ctxSelectors) { - context.selectors = ctxSelectors = []; - } - - ctxSelectors.unshift(this.selectors); // Evaluate imports - - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(context); - } // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - - - var rsRules = ruleset.rules; - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.evalFirst) { - rsRules[i] = rule.eval(context); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + if (!rule.evalFirst) { + rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + } } - } - - var mediaBlockCount = context.mediaBlocks && context.mediaBlocks.length || 0; // Evaluate mixin calls. - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.type === 'MixinCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !ruleset.variable(r.name); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + // for rulesets, check if it is a css guard and can be removed + if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { + // check if it can be folded in (e.g. & where) + if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { + rsRules.splice(i--, 1); + for (var j = 0; (subRule = rule.rules[j]); j++) { + if (subRule instanceof Node) { + subRule.copyVisibilityInfo(rule.visibilityInfo()); + if (!(subRule instanceof Declaration) || !subRule.variable) { + rsRules.splice(++i, 0, subRule); + } + } + } + } } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); - } else if (rule.type === 'VariableCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).rules.filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope at all - return false; + } + // Pop the stack + ctxFrames.shift(); + ctxSelectors.shift(); + if (context.mediaBlocks) { + for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { + context.mediaBlocks[i].bubbleSelectors(selectors); } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - if (!rule.evalFirst) { - rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + return ruleset; + }; + Ruleset.prototype.evalImports = function (context) { + var rules = this.rules; + var i; + var importRules; + if (!rules) { + return; } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for (var j = 0; subRule = rule.rules[j]; j++) { - if (subRule instanceof Node) { - subRule.copyVisibilityInfo(rule.visibilityInfo()); - - if (!(subRule instanceof Declaration) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); + for (i = 0; i < rules.length; i++) { + if (rules[i].type === 'Import') { + importRules = rules[i].eval(context); + if (importRules && (importRules.length || importRules.length === 0)) { + rules.splice.apply(rules, [i, 1].concat(importRules)); + i += importRules.length - 1; } - } + else { + rules.splice(i, 1, importRules); + } + this.resetCache(); } - } - } - } // Pop the stack - - - ctxFrames.shift(); - ctxSelectors.shift(); - - if (context.mediaBlocks) { - for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { - context.mediaBlocks[i].bubbleSelectors(selectors); } - } - - return ruleset; - } - }, { - key: "evalImports", - value: function evalImports(context) { - var rules = this.rules; - var i; - var importRules; - - if (!rules) { - return; - } - - for (i = 0; i < rules.length; i++) { - if (rules[i].type === 'Import') { - importRules = rules[i].eval(context); - - if (importRules && (importRules.length || importRules.length === 0)) { - rules.splice.apply(rules, _toConsumableArray([i, 1].concat(importRules))); - i += importRules.length - 1; - } else { - rules.splice(i, 1, importRules); - } - - this.resetCache(); - } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - var result = new Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports, this.visibilityInfo()); - return result; - } - }, { - key: "matchArgs", - value: function matchArgs(args) { - return !args || args.length === 0; - } // lets you call a css selector with a guard - - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - var lastSelector = this.selectors[this.selectors.length - 1]; - - if (!lastSelector.evaldCondition) { - return false; - } - - if (lastSelector.condition && !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { - return false; - } - - return true; - } - }, { - key: "resetCache", - value: function resetCache() { - this._rulesets = null; - this._variables = null; - this._properties = null; - this._lookups = {}; - } - }, { - key: "variables", - value: function variables() { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable === true) { - hash[r.name] = r; - } // when evaluating variables in an import statement, imports have not been eval'd - // so we need to go inside import statements. - // guard against root being a string (in the case of inlined less) - - - if (r.type === 'Import' && r.root && r.root.variables) { - var vars = r.root.variables(); - - for (var name in vars) { - if (vars.hasOwnProperty(name)) { - hash[name] = r.root.variable(name); - } + }; + Ruleset.prototype.makeImportant = function () { + var result = new Ruleset(this.selectors, this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(); } - } - - return hash; - }, {}); - } - - return this._variables; - } - }, { - key: "properties", - value: function properties() { - if (!this._properties) { - this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable !== true) { - var name = r.name.length === 1 && r.name[0] instanceof Keyword ? r.name[0].value : r.name; // Properties don't overwrite as they can merge - - if (!hash[`$${name}`]) { - hash[`$${name}`] = [r]; - } else { - hash[`$${name}`].push(r); + else { + return r; } - } - - return hash; - }, {}); - } - - return this._properties; - } - }, { - key: "variable", - value: function variable(name) { - var decl = this.variables()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "property", - value: function property(name) { - var decl = this.properties()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "lastDeclaration", - value: function lastDeclaration() { - for (var i = this.rules.length; i > 0; i--) { - var decl = this.rules[i - 1]; - - if (decl instanceof Declaration) { - return this.parseValue(decl); - } - } - } - }, { - key: "parseValue", - value: function parseValue(toParse) { - var self = this; - - function transformDeclaration(decl) { - if (decl.value instanceof Anonymous && !decl.parsed) { - if (typeof decl.value.value === 'string') { - this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { - if (err) { - decl.parsed = true; - } - - if (result) { - decl.value = result[0]; - decl.important = result[1] || ''; - decl.parsed = true; - } - }); - } else { - decl.parsed = true; - } - - return decl; - } else { - return decl; + }), this.strictImports, this.visibilityInfo()); + return result; + }; + Ruleset.prototype.matchArgs = function (args) { + return !args || args.length === 0; + }; + // lets you call a css selector with a guard + Ruleset.prototype.matchCondition = function (args, context) { + var lastSelector = this.selectors[this.selectors.length - 1]; + if (!lastSelector.evaldCondition) { + return false; } - } - - if (!Array.isArray(toParse)) { - return transformDeclaration.call(self, toParse); - } else { - var nodes = []; - toParse.forEach(function (n) { - nodes.push(transformDeclaration.call(self, n)); - }); - return nodes; - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (!this.rules) { - return []; - } - - var filtRules = []; - var rules = this.rules; - var i; - var rule; - - for (i = 0; rule = rules[i]; i++) { - if (rule.isRuleset) { - filtRules.push(rule); + if (lastSelector.condition && + !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { + return false; } - } - - return filtRules; - } - }, { - key: "prependRule", - value: function prependRule(rule) { - var rules = this.rules; - - if (rules) { - rules.unshift(rule); - } else { - this.rules = [rule]; - } - - this.setParent(rule, this); - } - }, { - key: "find", - value: function find(selector) { - var self = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this; - var filter = arguments.length > 2 ? arguments[2] : undefined; - var rules = []; - var match; - var foundMixins; - var key = selector.toCSS(); - - if (key in this._lookups) { - return this._lookups[key]; - } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - - if (match) { - if (selector.elements.length > match) { - if (!filter || filter(rule)) { - foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); - - for (var i = 0; i < foundMixins.length; ++i) { - foundMixins[i].path.push(rule); - } - - Array.prototype.push.apply(rules, foundMixins); + return true; + }; + Ruleset.prototype.resetCache = function () { + this._rulesets = null; + this._variables = null; + this._properties = null; + this._lookups = {}; + }; + Ruleset.prototype.variables = function () { + if (!this._variables) { + this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable === true) { + hash[r.name] = r; } - } else { - rules.push({ - rule, - path: [] - }); - } - - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var j; - var charsetRuleNodes = []; - var ruleNodes = []; - var // Line number debugging - debugInfo$1; - var rule; - var path; - context.tabLevel = context.tabLevel || 0; - - if (!this.root) { - context.tabLevel++; - } - - var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); - var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); - var sep; - var charsetNodeIndex = 0; - var importNodeIndex = 0; - - for (i = 0; rule = this.rules[i]; i++) { - if (rule instanceof Comment) { - if (importNodeIndex === i) { - importNodeIndex++; - } - - ruleNodes.push(rule); - } else if (rule.isCharset && rule.isCharset()) { - ruleNodes.splice(charsetNodeIndex, 0, rule); - charsetNodeIndex++; - importNodeIndex++; - } else if (rule.type === 'Import') { - ruleNodes.splice(importNodeIndex, 0, rule); - importNodeIndex++; - } else { - ruleNodes.push(rule); - } - } - - ruleNodes = charsetRuleNodes.concat(ruleNodes); // If this is the root node, we don't render - // a selector, or {}. - - if (!this.root) { - debugInfo$1 = debugInfo(context, this, tabSetStr); - - if (debugInfo$1) { - output.add(debugInfo$1); - output.add(tabSetStr); - } - - var paths = this.paths; - var pathCnt = paths.length; - var pathSubCnt; - sep = context.compress ? ',' : `,\n${tabSetStr}`; - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - - if (!(pathSubCnt = path.length)) { - continue; - } - - if (i > 0) { - output.add(sep); - } - - context.firstSelector = true; - path[0].genCSS(context, output); - context.firstSelector = false; - - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(context, output); - } + // when evaluating variables in an import statement, imports have not been eval'd + // so we need to go inside import statements. + // guard against root being a string (in the case of inlined less) + if (r.type === 'Import' && r.root && r.root.variables) { + var vars = r.root.variables(); + for (var name_1 in vars) { + if (vars.hasOwnProperty(name_1)) { + hash[name_1] = r.root.variable(name_1); + } + } + } + return hash; + }, {}); } - - output.add((context.compress ? '{' : ' {\n') + tabRuleStr); - } // Compile rules and rulesets - - - for (i = 0; rule = ruleNodes[i]; i++) { - if (i + 1 === ruleNodes.length) { - context.lastRule = true; + return this._variables; + }; + Ruleset.prototype.properties = function () { + if (!this._properties) { + this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable !== true) { + var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ? + r.name[0].value : r.name; + // Properties don't overwrite as they can merge + if (!hash["$" + name_2]) { + hash["$" + name_2] = [r]; + } + else { + hash["$" + name_2].push(r); + } + } + return hash; + }, {}); } - - var currentLastRule = context.lastRule; - - if (rule.isRulesetLike(rule)) { - context.lastRule = false; + return this._properties; + }; + Ruleset.prototype.variable = function (name) { + var decl = this.variables()[name]; + if (decl) { + return this.parseValue(decl); } - - if (rule.genCSS) { - rule.genCSS(context, output); - } else if (rule.value) { - output.add(rule.value.toString()); + }; + Ruleset.prototype.property = function (name) { + var decl = this.properties()[name]; + if (decl) { + return this.parseValue(decl); } - - context.lastRule = currentLastRule; - - if (!context.lastRule && rule.isVisible()) { - output.add(context.compress ? '' : `\n${tabRuleStr}`); - } else { - context.lastRule = false; + }; + Ruleset.prototype.lastDeclaration = function () { + for (var i_1 = this.rules.length; i_1 > 0; i_1--) { + var decl = this.rules[i_1 - 1]; + if (decl instanceof Declaration) { + return this.parseValue(decl); + } } - } - - if (!this.root) { - output.add(context.compress ? '}' : `\n${tabSetStr}}`); - context.tabLevel--; - } - - if (!output.isEmpty() && !context.compress && this.firstRoot) { - output.add('\n'); - } - } - }, { - key: "joinSelectors", - value: function joinSelectors(paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - } - }, { - key: "joinSelector", - value: function joinSelector(paths, context, selector) { - function createParenthesis(elementsToPak, originalElement) { - var replacementParen; - var j; - - if (elementsToPak.length === 0) { - replacementParen = new Paren(elementsToPak[0]); - } else { - var insideParent = new Array(elementsToPak.length); - - for (j = 0; j < elementsToPak.length; j++) { - insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); - } - - replacementParen = new Paren(new Selector(insideParent)); + }; + Ruleset.prototype.parseValue = function (toParse) { + var self = this; + function transformDeclaration(decl) { + if (decl.value instanceof Anonymous && !decl.parsed) { + if (typeof decl.value.value === 'string') { + this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { + if (err) { + decl.parsed = true; + } + if (result) { + decl.value = result[0]; + decl.important = result[1] || ''; + decl.parsed = true; + } + }); + } + else { + decl.parsed = true; + } + return decl; + } + else { + return decl; + } } - - return replacementParen; - } - - function createSelector(containedElement, originalElement) { - var element; - var selector; - element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); - selector = new Selector([element]); - return selector; - } // joins selector path from `beginningPath` with selector path in `addPath` - // `replacedElement` contains element that is being replaced by `addPath` - // returns concatenated path - - - function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { - var newSelectorPath; - var lastSelector; - var newJoinedSelector; // our new selector path - - newSelectorPath = []; // construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - - if (beginningPath.length > 0) { - newSelectorPath = copyArray(beginningPath); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); - } else { - newJoinedSelector = originalSelector.createDerived([]); + if (!Array.isArray(toParse)) { + return transformDeclaration.call(self, toParse); } - - if (addPath.length > 0) { - // /deep/ is a CSS4 selector - (removed, so should deprecate) - // that is valid without anything in front of it - // so if the & does not have a combinator that is "" or " " then - // and there is a combinator on the parent, then grab that. - // this also allows + a { & .b { .a & { ... though not sure why you would want to do that - var combinator = replacedElement.combinator; - var parentEl = addPath[0].elements[0]; - - if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { - combinator = parentEl.combinator; - } // join the elements so far with the first part of the parent - - - newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); - } // now add the joined selector - but only if it is not empty - - - if (newJoinedSelector.elements.length !== 0) { - newSelectorPath.push(newJoinedSelector); - } // put together the parent selectors after the join (e.g. the rest of the parent) - - - if (addPath.length > 1) { - var restOfPath = addPath.slice(1); - restOfPath = restOfPath.map(function (selector) { - return selector.createDerived(selector.elements, []); - }); - newSelectorPath = newSelectorPath.concat(restOfPath); + else { + var nodes_1 = []; + toParse.forEach(function (n) { + nodes_1.push(transformDeclaration.call(self, n)); + }); + return nodes_1; } - - return newSelectorPath; - } // joins selector path from `beginningPath` with every selector path in `addPaths` array - // `replacedElement` contains element that is being replaced by `addPath` - // returns array with all concatenated paths - - - function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { - var j; - - for (j = 0; j < beginningPath.length; j++) { - var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); - result.push(newSelectorPath); + }; + Ruleset.prototype.rulesets = function () { + if (!this.rules) { + return []; } - - return result; - } - - function mergeElementsOnToSelectors(elements, selectors) { + var filtRules = []; + var rules = this.rules; var i; - var sel; - - if (elements.length === 0) { - return; + var rule; + for (i = 0; (rule = rules[i]); i++) { + if (rule.isRuleset) { + filtRules.push(rule); + } } - - if (selectors.length === 0) { - selectors.push([new Selector(elements)]); - return; + return filtRules; + }; + Ruleset.prototype.prependRule = function (rule) { + var rules = this.rules; + if (rules) { + rules.unshift(rule); } - - for (i = 0; sel = selectors[i]; i++) { - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } else { - sel.push(new Selector(elements)); - } - } - } // replace all parent selectors inside `inSelector` by content of `context` array - // resulting selectors are returned inside `paths` array - // returns true if `inSelector` contained at least one parent selector - - - function replaceParentSelector(paths, context, inSelector) { - // The paths are [[Selector]] - // The first list is a list of comma separated selectors - // The inner list is a list of inheritance separated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // + else { + this.rules = [rule]; + } + this.setParent(rule, this); + }; + Ruleset.prototype.find = function (selector, self, filter) { + if (self === void 0) { self = this; } + var rules = []; + var match; + var foundMixins; + var key = selector.toCSS(); + if (key in this._lookups) { + return this._lookups[key]; + } + this.rulesets().forEach(function (rule) { + if (rule !== self) { + for (var j = 0; j < rule.selectors.length; j++) { + match = selector.match(rule.selectors[j]); + if (match) { + if (selector.elements.length > match) { + if (!filter || filter(rule)) { + foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); + for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) { + foundMixins[i_2].path.push(rule); + } + Array.prototype.push.apply(rules, foundMixins); + } + } + else { + rules.push({ rule: rule, path: [] }); + } + break; + } + } + } + }); + this._lookups[key] = rules; + return rules; + }; + Ruleset.prototype.genCSS = function (context, output) { var i; var j; - var k; - var currentElements; - var newSelectors; - var selectorsMultiplied; - var sel; - var el; - var hadParentSelector = false; - var length; - var lastSelector; - - function findNestedSelector(element) { - var maybeSelector; - - if (!(element.value instanceof Paren)) { - return null; - } - - maybeSelector = element.value.value; - - if (!(maybeSelector instanceof Selector)) { - return null; - } - - return maybeSelector; - } // the elements from the current selector so far - - - currentElements = []; // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - - newSelectors = [[]]; - - for (i = 0; el = inSelector.elements[i]; i++) { - // non parent reference elements just get added - if (el.value !== '&') { - var nestedSelector = findNestedSelector(el); - - if (nestedSelector != null) { - // merge the current list of non parent selector elements - // on to the current list of selectors to add - mergeElementsOnToSelectors(currentElements, newSelectors); - var nestedPaths = []; - var replaced = void 0; - var replacedNewSelectors = []; - replaced = replaceParentSelector(nestedPaths, context, nestedSelector); - hadParentSelector = hadParentSelector || replaced; // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors - - for (k = 0; k < nestedPaths.length; k++) { - var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); - addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); - } - - newSelectors = replacedNewSelectors; - currentElements = []; - } else { - currentElements.push(el); + var charsetRuleNodes = []; + var ruleNodes = []; + var // Line number debugging + debugInfo$1; + var rule; + var path; + context.tabLevel = (context.tabLevel || 0); + if (!this.root) { + context.tabLevel++; + } + var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); + var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); + var sep; + var charsetNodeIndex = 0; + var importNodeIndex = 0; + for (i = 0; (rule = this.rules[i]); i++) { + if (rule instanceof Comment) { + if (importNodeIndex === i) { + importNodeIndex++; + } + ruleNodes.push(rule); } - } else { - hadParentSelector = true; // the new list of selectors to add - - selectorsMultiplied = []; // merge the current list of non parent selector elements - // on to the current list of selectors to add - - mergeElementsOnToSelectors(currentElements, newSelectors); // loop through our current selectors - - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + else if (rule.isCharset && rule.isCharset()) { + ruleNodes.splice(charsetNodeIndex, 0, rule); + charsetNodeIndex++; + importNodeIndex++; + } + else if (rule.type === 'Import') { + ruleNodes.splice(importNodeIndex, 0, rule); + importNodeIndex++; + } + else { + ruleNodes.push(rule); + } + } + ruleNodes = charsetRuleNodes.concat(ruleNodes); + // If this is the root node, we don't render + // a selector, or {}. + if (!this.root) { + debugInfo$1 = debugInfo(context, this, tabSetStr); + if (debugInfo$1) { + output.add(debugInfo$1); + output.add(tabSetStr); + } + var paths = this.paths; + var pathCnt = paths.length; + var pathSubCnt = void 0; + sep = context.compress ? ',' : (",\n" + tabSetStr); + for (i = 0; i < pathCnt; i++) { + path = paths[i]; + if (!(pathSubCnt = path.length)) { + continue; } - - selectorsMultiplied.push(sel); - } else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); // add that to our new set of selectors - - selectorsMultiplied.push(newSelectorPath); + if (i > 0) { + output.add(sep); } - } - } // our new selectors has been multiplied, so reset the state - - - newSelectors = selectorsMultiplied; + context.firstSelector = true; + path[0].genCSS(context, output); + context.firstSelector = false; + for (j = 1; j < pathSubCnt; j++) { + path[j].genCSS(context, output); + } + } + output.add((context.compress ? '{' : ' {\n') + tabRuleStr); + } + // Compile rules and rulesets + for (i = 0; (rule = ruleNodes[i]); i++) { + if (i + 1 === ruleNodes.length) { + context.lastRule = true; + } + var currentLastRule = context.lastRule; + if (rule.isRulesetLike(rule)) { + context.lastRule = false; + } + if (rule.genCSS) { + rule.genCSS(context, output); + } + else if (rule.value) { + output.add(rule.value.toString()); + } + context.lastRule = currentLastRule; + if (!context.lastRule && rule.isVisible()) { + output.add(context.compress ? '' : ("\n" + tabRuleStr)); + } + else { + context.lastRule = false; + } + } + if (!this.root) { + output.add((context.compress ? '}' : "\n" + tabSetStr + "}")); + context.tabLevel--; + } + if (!output.isEmpty() && !context.compress && this.firstRoot) { + output.add('\n'); + } + }; + Ruleset.prototype.joinSelectors = function (paths, context, selectors) { + for (var s = 0; s < selectors.length; s++) { + this.joinSelector(paths, context, selectors[s]); + } + }; + Ruleset.prototype.joinSelector = function (paths, context, selector) { + function createParenthesis(elementsToPak, originalElement) { + var replacementParen; + var j; + if (elementsToPak.length === 0) { + replacementParen = new Paren(elementsToPak[0]); + } + else { + var insideParent = new Array(elementsToPak.length); + for (j = 0; j < elementsToPak.length; j++) { + insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); + } + replacementParen = new Paren(new Selector(insideParent)); + } + return replacementParen; + } + function createSelector(containedElement, originalElement) { + var element; + var selector; + element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); + selector = new Selector([element]); + return selector; + } + // joins selector path from `beginningPath` with selector path in `addPath` + // `replacedElement` contains element that is being replaced by `addPath` + // returns concatenated path + function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { + var newSelectorPath; + var lastSelector; + var newJoinedSelector; + // our new selector path + newSelectorPath = []; + // construct the joined selector - if & is the first thing this will be empty, + // if not newJoinedSelector will be the last set of elements in the selector + if (beginningPath.length > 0) { + newSelectorPath = copyArray(beginningPath); + lastSelector = newSelectorPath.pop(); + newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); + } + else { + newJoinedSelector = originalSelector.createDerived([]); + } + if (addPath.length > 0) { + // /deep/ is a CSS4 selector - (removed, so should deprecate) + // that is valid without anything in front of it + // so if the & does not have a combinator that is "" or " " then + // and there is a combinator on the parent, then grab that. + // this also allows + a { & .b { .a & { ... though not sure why you would want to do that + var combinator = replacedElement.combinator; + var parentEl = addPath[0].elements[0]; + if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { + combinator = parentEl.combinator; + } + // join the elements so far with the first part of the parent + newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); + newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); + } + // now add the joined selector - but only if it is not empty + if (newJoinedSelector.elements.length !== 0) { + newSelectorPath.push(newJoinedSelector); + } + // put together the parent selectors after the join (e.g. the rest of the parent) + if (addPath.length > 1) { + var restOfPath = addPath.slice(1); + restOfPath = restOfPath.map(function (selector) { return selector.createDerived(selector.elements, []); }); + newSelectorPath = newSelectorPath.concat(restOfPath); + } + return newSelectorPath; + } + // joins selector path from `beginningPath` with every selector path in `addPaths` array + // `replacedElement` contains element that is being replaced by `addPath` + // returns array with all concatenated paths + function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { + var j; + for (j = 0; j < beginningPath.length; j++) { + var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); + result.push(newSelectorPath); + } + return result; + } + function mergeElementsOnToSelectors(elements, selectors) { + var i; + var sel; + if (elements.length === 0) { + return; + } + if (selectors.length === 0) { + selectors.push([new Selector(elements)]); + return; + } + for (i = 0; (sel = selectors[i]); i++) { + // if the previous thing in sel is a parent this needs to join on to it + if (sel.length > 0) { + sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); + } + else { + sel.push(new Selector(elements)); + } + } + } + // replace all parent selectors inside `inSelector` by content of `context` array + // resulting selectors are returned inside `paths` array + // returns true if `inSelector` contained at least one parent selector + function replaceParentSelector(paths, context, inSelector) { + // The paths are [[Selector]] + // The first list is a list of comma separated selectors + // The inner list is a list of inheritance separated selectors + // e.g. + // .a, .b { + // .c { + // } + // } + // == [[.a] [.c]] [[.b] [.c]] + // + var i; + var j; + var k; + var currentElements; + var newSelectors; + var selectorsMultiplied; + var sel; + var el; + var hadParentSelector = false; + var length; + var lastSelector; + function findNestedSelector(element) { + var maybeSelector; + if (!(element.value instanceof Paren)) { + return null; + } + maybeSelector = element.value.value; + if (!(maybeSelector instanceof Selector)) { + return null; + } + return maybeSelector; + } + // the elements from the current selector so far currentElements = []; - } - } // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - - - mergeElementsOnToSelectors(currentElements, newSelectors); - - for (i = 0; i < newSelectors.length; i++) { - length = newSelectors[i].length; - - if (length > 0) { - paths.push(newSelectors[i]); - lastSelector = newSelectors[i][length - 1]; - newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); - } + // the current list of new selectors to add to the path. + // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors + // by the parents + newSelectors = [ + [] + ]; + for (i = 0; (el = inSelector.elements[i]); i++) { + // non parent reference elements just get added + if (el.value !== '&') { + var nestedSelector = findNestedSelector(el); + if (nestedSelector != null) { + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + var nestedPaths = []; + var replaced = void 0; + var replacedNewSelectors = []; + replaced = replaceParentSelector(nestedPaths, context, nestedSelector); + hadParentSelector = hadParentSelector || replaced; + // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors + for (k = 0; k < nestedPaths.length; k++) { + var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); + addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); + } + newSelectors = replacedNewSelectors; + currentElements = []; + } + else { + currentElements.push(el); + } + } + else { + hadParentSelector = true; + // the new list of selectors to add + selectorsMultiplied = []; + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + // loop through our current selectors + for (j = 0; j < newSelectors.length; j++) { + sel = newSelectors[j]; + // if we don't have any parent paths, the & might be in a mixin so that it can be used + // whether there are parents or not + if (context.length === 0) { + // the combinator used on el should now be applied to the next element instead so that + // it is not lost + if (sel.length > 0) { + sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + } + selectorsMultiplied.push(sel); + } + else { + // and the parent selectors + for (k = 0; k < context.length; k++) { + // We need to put the current selectors + // then join the last selector's elements on to the parents selectors + var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); + // add that to our new set of selectors + selectorsMultiplied.push(newSelectorPath); + } + } + } + // our new selectors has been multiplied, so reset the state + newSelectors = selectorsMultiplied; + currentElements = []; + } + } + // if we have any elements left over (e.g. .a& .b == .b) + // add them on to all the current selectors + mergeElementsOnToSelectors(currentElements, newSelectors); + for (i = 0; i < newSelectors.length; i++) { + length = newSelectors[i].length; + if (length > 0) { + paths.push(newSelectors[i]); + lastSelector = newSelectors[i][length - 1]; + newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); + } + } + return hadParentSelector; } - - return hadParentSelector; - } - - function deriveSelector(visibilityInfo, deriveFrom) { - var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); - newSelector.copyVisibilityInfo(visibilityInfo); - return newSelector; - } // joinSelector code follows - - - var i; - var newPaths; - var hadParentSelector; - newPaths = []; - hadParentSelector = replaceParentSelector(newPaths, context, selector); - - if (!hadParentSelector) { - if (context.length > 0) { - newPaths = []; - - for (i = 0; i < context.length; i++) { - var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); - concatenated.push(selector); - newPaths.push(concatenated); - } - } else { - newPaths = [[selector]]; - } - } - - for (i = 0; i < newPaths.length; i++) { - paths.push(newPaths[i]); - } - } - }]); - - return Ruleset; -}(Node); - + function deriveSelector(visibilityInfo, deriveFrom) { + var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); + newSelector.copyVisibilityInfo(visibilityInfo); + return newSelector; + } + // joinSelector code follows + var i; + var newPaths; + var hadParentSelector; + newPaths = []; + hadParentSelector = replaceParentSelector(newPaths, context, selector); + if (!hadParentSelector) { + if (context.length > 0) { + newPaths = []; + for (i = 0; i < context.length; i++) { + var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); + concatenated.push(selector); + newPaths.push(concatenated); + } + } + else { + newPaths = [[selector]]; + } + } + for (i = 0; i < newPaths.length; i++) { + paths.push(newPaths[i]); + } + }; + return Ruleset; +}(Node)); Ruleset.prototype.type = 'Ruleset'; Ruleset.prototype.isRuleset = true; -var AtRule = -/*#__PURE__*/ -function (_Node) { - _inherits(AtRule, _Node); - - function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { - var _this; - - _classCallCheck(this, AtRule); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(AtRule).call(this)); - var i; - _this.name = name; - _this.value = value instanceof Node ? value : value ? new Anonymous(value) : value; - - if (rules) { - if (Array.isArray(rules)) { - _this.rules = rules; - } else { - _this.rules = [rules]; - _this.rules[0].selectors = new Selector([], null, null, index, currentFileInfo).createEmptySelectors(); - } - - for (i = 0; i < _this.rules.length; i++) { - _this.rules[i].allowImports = true; - } - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - } - - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.debugInfo = debugInfo; - _this.isRooted = isRooted || false; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(AtRule, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - var rules = this.rules; - - if (rules) { - this.rules = visitor.visitArray(rules); - } - - if (value) { - this.value = visitor.visit(value); - } - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rules || !this.isCharset(); - } - }, { - key: "isCharset", - value: function isCharset() { - return '@charset' === this.name; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var value = this.value; - var rules = this.rules; - output.add(this.name, this.fileInfo(), this.getIndex()); - - if (value) { - output.add(' '); - value.genCSS(context, output); - } - - if (rules) { - this.outputRuleset(context, output, rules); - } else { - output.add(';'); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mediaPathBackup; - var mediaBlocksBackup; - var value = this.value; - var rules = this.rules; // media stored inside other atrule should not bubble over it - // backpup media bubbling information - - mediaPathBackup = context.mediaPath; - mediaBlocksBackup = context.mediaBlocks; // deleted media bubbling information - - context.mediaPath = []; - context.mediaBlocks = []; - - if (value) { - value = value.eval(context); - } - - if (rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - rules = [rules[0].eval(context)]; - rules[0].root = true; - } // restore media bubbling information - - - context.mediaPath = mediaPathBackup; - context.mediaBlocks = mediaBlocksBackup; - return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); - } - }, { - key: "variable", - value: function variable(name) { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.variable.call(this.rules[0], name); - } - } - }, { - key: "find", - value: function find() { - if (this.rules) { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; +var AtRule = /** @class */ (function (_super) { + tslib.__extends(AtRule, _super); + function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { + var _this = _super.call(this) || this; + var i; + _this.name = name; + _this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value); + if (rules) { + if (Array.isArray(rules)) { + _this.rules = rules; + } + else { + _this.rules = [rules]; + _this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors(); + } + for (i = 0; i < _this.rules.length; i++) { + _this.rules[i].allowImports = true; + } + _this.setParent(_this.rules, _this); + } + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.debugInfo = debugInfo; + _this.isRooted = isRooted || false; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + AtRule.prototype.accept = function (visitor) { + var value = this.value; + var rules = this.rules; + if (rules) { + this.rules = visitor.visitArray(rules); } - - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.find.apply(this.rules[0], args); - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.rulesets.apply(this.rules[0]); - } - } - }, { - key: "outputRuleset", - value: function outputRuleset(context, output, rules) { - var ruleCnt = rules.length; - var i; - context.tabLevel = (context.tabLevel | 0) + 1; // Compressed - - if (context.compress) { - output.add('{'); - - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(context, output); + if (value) { + this.value = visitor.visit(value); } - - output.add('}'); - context.tabLevel--; - return; - } // Non-compressed - - - var tabSetStr = `\n${Array(context.tabLevel).join(' ')}`; - var tabRuleStr = `${tabSetStr} `; - - if (!ruleCnt) { - output.add(` {${tabSetStr}}`); - } else { - output.add(` {${tabRuleStr}`); - rules[0].genCSS(context, output); - - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(context, output); + }; + AtRule.prototype.isRulesetLike = function () { + return this.rules || !this.isCharset(); + }; + AtRule.prototype.isCharset = function () { + return '@charset' === this.name; + }; + AtRule.prototype.genCSS = function (context, output) { + var value = this.value; + var rules = this.rules; + output.add(this.name, this.fileInfo(), this.getIndex()); + if (value) { + output.add(' '); + value.genCSS(context, output); } - - output.add(`${tabSetStr}}`); - } - - context.tabLevel--; - } - }]); - - return AtRule; -}(Node); - + if (rules) { + this.outputRuleset(context, output, rules); + } + else { + output.add(';'); + } + }; + AtRule.prototype.eval = function (context) { + var mediaPathBackup; + var mediaBlocksBackup; + var value = this.value; + var rules = this.rules; + // media stored inside other atrule should not bubble over it + // backpup media bubbling information + mediaPathBackup = context.mediaPath; + mediaBlocksBackup = context.mediaBlocks; + // deleted media bubbling information + context.mediaPath = []; + context.mediaBlocks = []; + if (value) { + value = value.eval(context); + } + if (rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + rules = [rules[0].eval(context)]; + rules[0].root = true; + } + // restore media bubbling information + context.mediaPath = mediaPathBackup; + context.mediaBlocks = mediaBlocksBackup; + return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); + }; + AtRule.prototype.variable = function (name) { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.variable.call(this.rules[0], name); + } + }; + AtRule.prototype.find = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.find.apply(this.rules[0], args); + } + }; + AtRule.prototype.rulesets = function () { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.rulesets.apply(this.rules[0]); + } + }; + AtRule.prototype.outputRuleset = function (context, output, rules) { + var ruleCnt = rules.length; + var i; + context.tabLevel = (context.tabLevel | 0) + 1; + // Compressed + if (context.compress) { + output.add('{'); + for (i = 0; i < ruleCnt; i++) { + rules[i].genCSS(context, output); + } + output.add('}'); + context.tabLevel--; + return; + } + // Non-compressed + var tabSetStr = "\n" + Array(context.tabLevel).join(' '); + var tabRuleStr = tabSetStr + " "; + if (!ruleCnt) { + output.add(" {" + tabSetStr + "}"); + } + else { + output.add(" {" + tabRuleStr); + rules[0].genCSS(context, output); + for (i = 1; i < ruleCnt; i++) { + output.add(tabRuleStr); + rules[i].genCSS(context, output); + } + output.add(tabSetStr + "}"); + } + context.tabLevel--; + }; + return AtRule; +}(Node)); AtRule.prototype.type = 'AtRule'; -var DetachedRuleset = -/*#__PURE__*/ -function (_Node) { - _inherits(DetachedRuleset, _Node); - - function DetachedRuleset(ruleset, frames) { - var _this; - - _classCallCheck(this, DetachedRuleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(DetachedRuleset).call(this)); - _this.ruleset = ruleset; - _this.frames = frames; - - _this.setParent(_this.ruleset, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(DetachedRuleset, [{ - key: "accept", - value: function accept(visitor) { - this.ruleset = visitor.visit(this.ruleset); - } - }, { - key: "eval", - value: function _eval(context) { - var frames = this.frames || copyArray(context.frames); - return new DetachedRuleset(this.ruleset, frames); - } - }, { - key: "callEval", - value: function callEval(context) { - return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); - } - }]); - - return DetachedRuleset; -}(Node); - +var DetachedRuleset = /** @class */ (function (_super) { + tslib.__extends(DetachedRuleset, _super); + function DetachedRuleset(ruleset, frames) { + var _this = _super.call(this) || this; + _this.ruleset = ruleset; + _this.frames = frames; + _this.setParent(_this.ruleset, _this); + return _this; + } + DetachedRuleset.prototype.accept = function (visitor) { + this.ruleset = visitor.visit(this.ruleset); + }; + DetachedRuleset.prototype.eval = function (context) { + var frames = this.frames || copyArray(context.frames); + return new DetachedRuleset(this.ruleset, frames); + }; + DetachedRuleset.prototype.callEval = function (context) { + return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); + }; + return DetachedRuleset; +}(Node)); DetachedRuleset.prototype.type = 'DetachedRuleset'; DetachedRuleset.prototype.evalFirst = true; -var Unit = -/*#__PURE__*/ -function (_Node) { - _inherits(Unit, _Node); - - function Unit(numerator, denominator, backupUnit) { - var _this; - - _classCallCheck(this, Unit); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Unit).call(this)); - _this.numerator = numerator ? copyArray(numerator).sort() : []; - _this.denominator = denominator ? copyArray(denominator).sort() : []; - - if (backupUnit) { - _this.backupUnit = backupUnit; - } else if (numerator && numerator.length) { - _this.backupUnit = numerator[0]; +var Unit = /** @class */ (function (_super) { + tslib.__extends(Unit, _super); + function Unit(numerator, denominator, backupUnit) { + var _this = _super.call(this) || this; + _this.numerator = numerator ? copyArray(numerator).sort() : []; + _this.denominator = denominator ? copyArray(denominator).sort() : []; + if (backupUnit) { + _this.backupUnit = backupUnit; + } + else if (numerator && numerator.length) { + _this.backupUnit = numerator[0]; + } + return _this; } - - return _this; - } - - _createClass(Unit, [{ - key: "clone", - value: function clone() { - return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - // Dimension checks the unit is singular and throws an error if in strict math mode. - var strictUnits = context && context.strictUnits; - - if (this.numerator.length === 1) { - output.add(this.numerator[0]); // the ideal situation - } else if (!strictUnits && this.backupUnit) { - output.add(this.backupUnit); - } else if (!strictUnits && this.denominator.length) { - output.add(this.denominator[0]); - } - } - }, { - key: "toString", - value: function toString() { - var i; - var returnStr = this.numerator.join('*'); - - for (i = 0; i < this.denominator.length; i++) { - returnStr += `/${this.denominator[i]}`; - } - - return returnStr; - } - }, { - key: "compare", - value: function compare(other) { - return this.is(other.toString()) ? 0 : undefined; - } - }, { - key: "is", - value: function is(unitString) { - return this.toString().toUpperCase() === unitString.toUpperCase(); - } - }, { - key: "isLength", - value: function isLength() { - return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this.numerator.length === 0 && this.denominator.length === 0; - } - }, { - key: "isSingular", - value: function isSingular() { - return this.numerator.length <= 1 && this.denominator.length === 0; - } - }, { - key: "map", - value: function map(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - } - }, { - key: "usedUnits", - value: function usedUnits() { - var group; - var result = {}; - var mapUnit; - var groupName; - - mapUnit = function mapUnit(atomicUnit) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; + Unit.prototype.clone = function () { + return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); + }; + Unit.prototype.genCSS = function (context, output) { + // Dimension checks the unit is singular and throws an error if in strict math mode. + var strictUnits = context && context.strictUnits; + if (this.numerator.length === 1) { + output.add(this.numerator[0]); // the ideal situation } - - return atomicUnit; - }; - - for (groupName in unitConversions) { - if (unitConversions.hasOwnProperty(groupName)) { - group = unitConversions[groupName]; - this.map(mapUnit); + else if (!strictUnits && this.backupUnit) { + output.add(this.backupUnit); } - } - - return result; - } - }, { - key: "cancel", - value: function cancel() { - var counter = {}; - var atomicUnit; - var i; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); + else if (!strictUnits && this.denominator.length) { + output.add(this.denominator[0]); + } + }; + Unit.prototype.toString = function () { + var i; + var returnStr = this.numerator.join('*'); + for (i = 0; i < this.denominator.length; i++) { + returnStr += "/" + this.denominator[i]; + } + return returnStr; + }; + Unit.prototype.compare = function (other) { + return this.is(other.toString()) ? 0 : undefined; + }; + Unit.prototype.is = function (unitString) { + return this.toString().toUpperCase() === unitString.toUpperCase(); + }; + Unit.prototype.isLength = function () { + return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); + }; + Unit.prototype.isEmpty = function () { + return this.numerator.length === 0 && this.denominator.length === 0; + }; + Unit.prototype.isSingular = function () { + return this.numerator.length <= 1 && this.denominator.length === 0; + }; + Unit.prototype.map = function (callback) { + var i; + for (i = 0; i < this.numerator.length; i++) { + this.numerator[i] = callback(this.numerator[i], false); + } + for (i = 0; i < this.denominator.length; i++) { + this.denominator[i] = callback(this.denominator[i], true); + } + }; + Unit.prototype.usedUnits = function () { + var group; + var result = {}; + var mapUnit; + var groupName; + mapUnit = function (atomicUnit) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { + result[groupName] = atomicUnit; } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); + return atomicUnit; + }; + for (groupName in unitConversions) { + if (unitConversions.hasOwnProperty(groupName)) { + group = unitConversions[groupName]; + this.map(mapUnit); } - } } - } - - this.numerator.sort(); - this.denominator.sort(); - } - }]); - - return Unit; -}(Node); - + return result; + }; + Unit.prototype.cancel = function () { + var counter = {}; + var atomicUnit; + var i; + for (i = 0; i < this.numerator.length; i++) { + atomicUnit = this.numerator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; + } + for (i = 0; i < this.denominator.length; i++) { + atomicUnit = this.denominator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; + } + this.numerator = []; + this.denominator = []; + for (atomicUnit in counter) { + if (counter.hasOwnProperty(atomicUnit)) { + var count = counter[atomicUnit]; + if (count > 0) { + for (i = 0; i < count; i++) { + this.numerator.push(atomicUnit); + } + } + else if (count < 0) { + for (i = 0; i < -count; i++) { + this.denominator.push(atomicUnit); + } + } + } + } + this.numerator.sort(); + this.denominator.sort(); + }; + return Unit; +}(Node)); Unit.prototype.type = 'Unit'; +// // A number with a unit // - -var Dimension = -/*#__PURE__*/ -function (_Node) { - _inherits(Dimension, _Node); - - function Dimension(value, unit) { - var _this; - - _classCallCheck(this, Dimension); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Dimension).call(this)); - _this.value = parseFloat(value); - - if (isNaN(_this.value)) { - throw new Error('Dimension is not a number.'); - } - - _this.unit = unit && unit instanceof Unit ? unit : new Unit(unit ? [unit] : undefined); - - _this.setParent(_this.unit, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Dimension, [{ - key: "accept", - value: function accept(visitor) { - this.unit = visitor.visit(this.unit); - } - }, { - key: "eval", - value: function _eval(context) { - return this; - } - }, { - key: "toColor", - value: function toColor() { - return new Color([this.value, this.value, this.value]); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (context && context.strictUnits && !this.unit.isSingular()) { - throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`); - } - - var value = this.fround(context, this.value); - var strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ''); - } - - if (context && context.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } // Float values doesn't need a leading zero - - - if (value > 0 && value < 1) { - strValue = strValue.substr(1); +var Dimension = /** @class */ (function (_super) { + tslib.__extends(Dimension, _super); + function Dimension(value, unit) { + var _this = _super.call(this) || this; + _this.value = parseFloat(value); + if (isNaN(_this.value)) { + throw new Error('Dimension is not a number.'); + } + _this.unit = (unit && unit instanceof Unit) ? unit : + new Unit(unit ? [unit] : undefined); + _this.setParent(_this.unit, _this); + return _this; + } + Dimension.prototype.accept = function (visitor) { + this.unit = visitor.visit(this.unit); + }; + Dimension.prototype.eval = function (context) { + return this; + }; + Dimension.prototype.toColor = function () { + return new Color([this.value, this.value, this.value]); + }; + Dimension.prototype.genCSS = function (context, output) { + if ((context && context.strictUnits) && !this.unit.isSingular()) { + throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString()); + } + var value = this.fround(context, this.value); + var strValue = String(value); + if (value !== 0 && value < 0.000001 && value > -0.000001) { + // would be output 1e-6 etc. + strValue = value.toFixed(20).replace(/0+$/, ''); + } + if (context && context.compress) { + // Zero values doesn't need a unit + if (value === 0 && this.unit.isLength()) { + output.add(strValue); + return; + } + // Float values doesn't need a leading zero + if (value > 0 && value < 1) { + strValue = (strValue).substr(1); + } } - } - - output.add(strValue); - this.unit.genCSS(context, output); - } // In an operation between two Dimensions, + output.add(strValue); + this.unit.genCSS(context, output); + }; + // In an operation between two Dimensions, // we default to the first Dimension's unit, // so `1px + 2` will yield `3px`. - - }, { - key: "operate", - value: function operate(context, op, other) { - /* jshint noempty:false */ - var value = this._operate(context, op, this.value, other.value); - - var unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit = other.unit.clone(); - - if (this.unit.backupUnit) { - unit.backupUnit = this.unit.backupUnit; - } - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; else { - other = other.convertTo(this.unit.usedUnits()); - - if (context.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error(`Incompatible units. Change the units or use the unit function. ` + `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`); - } - - value = this._operate(context, op, this.value, other.value); + Dimension.prototype.operate = function (context, op, other) { + /* jshint noempty:false */ + var value = this._operate(context, op, this.value, other.value); + var unit = this.unit.clone(); + if (op === '+' || op === '-') { + if (unit.numerator.length === 0 && unit.denominator.length === 0) { + unit = other.unit.clone(); + if (this.unit.backupUnit) { + unit.backupUnit = this.unit.backupUnit; + } + } + else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; + else { + other = other.convertTo(this.unit.usedUnits()); + if (context.strictUnits && other.unit.toString() !== unit.toString()) { + throw new Error("Incompatible units. Change the units or use the unit function. " + + ("Bad units: '" + unit.toString() + "' and '" + other.unit.toString() + "'.")); + } + value = this._operate(context, op, this.value, other.value); + } } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - - return new Dimension(value, unit); - } - }, { - key: "compare", - value: function compare(other) { - var a; - var b; - - if (!(other instanceof Dimension)) { - return undefined; - } - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - - if (a.unit.compare(b.unit) !== 0) { - return undefined; + else if (op === '*') { + unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); + unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); + unit.cancel(); } - } - - return Node.numericCompare(a.value, b.value); - } - }, { - key: "unify", - value: function unify() { - return this.convertTo({ - length: 'px', - duration: 's', - angle: 'rad' - }); - } - }, { - key: "convertTo", - value: function convertTo(conversions) { - var value = this.value; - var unit = this.unit.clone(); - var i; - var groupName; - var group; - var targetUnit; - var derivedConversions = {}; - var applyUnit; - - if (typeof conversions === 'string') { - for (i in unitConversions) { - if (unitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } + else if (op === '/') { + unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); + unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); + unit.cancel(); } - - conversions = derivedConversions; - } - - applyUnit = function applyUnit(atomicUnit, denominator) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; + return new Dimension(value, unit); + }; + Dimension.prototype.compare = function (other) { + var a; + var b; + if (!(other instanceof Dimension)) { + return undefined; + } + if (this.unit.isEmpty() || other.unit.isEmpty()) { + a = this; + b = other; + } + else { + a = this.unify(); + b = other.unify(); + if (a.unit.compare(b.unit) !== 0) { + return undefined; + } } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = unitConversions[groupName]; - unit.map(applyUnit); + return Node.numericCompare(a.value, b.value); + }; + Dimension.prototype.unify = function () { + return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); + }; + Dimension.prototype.convertTo = function (conversions) { + var value = this.value; + var unit = this.unit.clone(); + var i; + var groupName; + var group; + var targetUnit; + var derivedConversions = {}; + var applyUnit; + if (typeof conversions === 'string') { + for (i in unitConversions) { + if (unitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; } - } - - unit.cancel(); - return new Dimension(value, unit); - } - }]); - - return Dimension; -}(Node); - + applyUnit = function (atomicUnit, denominator) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit)) { + if (denominator) { + value = value / (group[atomicUnit] / group[targetUnit]); + } + else { + value = value * (group[atomicUnit] / group[targetUnit]); + } + return targetUnit; + } + return atomicUnit; + }; + for (groupName in conversions) { + if (conversions.hasOwnProperty(groupName)) { + targetUnit = conversions[groupName]; + group = unitConversions[groupName]; + unit.map(applyUnit); + } + } + unit.cancel(); + return new Dimension(value, unit); + }; + return Dimension; +}(Node)); Dimension.prototype.type = 'Dimension'; var MATH$1 = Math$1; - -var Operation = -/*#__PURE__*/ -function (_Node) { - _inherits(Operation, _Node); - - function Operation(op, operands, isSpaced) { - var _this; - - _classCallCheck(this, Operation); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Operation).call(this)); - _this.op = op.trim(); - _this.operands = operands; - _this.isSpaced = isSpaced; - return _this; - } - - _createClass(Operation, [{ - key: "accept", - value: function accept(visitor) { - this.operands = visitor.visitArray(this.operands); - } - }, { - key: "eval", - value: function _eval(context) { - var a = this.operands[0].eval(context); - var b = this.operands[1].eval(context); - var op; - - if (context.isMathOn(this.op)) { - op = this.op === './' ? '/' : this.op; - - if (a instanceof Dimension && b instanceof Color) { - a = a.toColor(); - } - - if (b instanceof Dimension && a instanceof Color) { - b = b.toColor(); +var Operation = /** @class */ (function (_super) { + tslib.__extends(Operation, _super); + function Operation(op, operands, isSpaced) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.operands = operands; + _this.isSpaced = isSpaced; + return _this; + } + Operation.prototype.accept = function (visitor) { + this.operands = visitor.visitArray(this.operands); + }; + Operation.prototype.eval = function (context) { + var a = this.operands[0].eval(context); + var b = this.operands[1].eval(context); + var op; + if (context.isMathOn(this.op)) { + op = this.op === './' ? '/' : this.op; + if (a instanceof Dimension && b instanceof Color) { + a = a.toColor(); + } + if (b instanceof Dimension && a instanceof Color) { + b = b.toColor(); + } + if (!a.operate) { + if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + return new Operation(this.op, [a, b], this.isSpaced); + } + throw { type: 'Operation', + message: 'Operation on an invalid type' }; + } + return a.operate(context, op, b); } - - if (!a.operate) { - if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + else { return new Operation(this.op, [a, b], this.isSpaced); - } - - throw { - type: 'Operation', - message: 'Operation on an invalid type' - }; } - - return a.operate(context, op, b); - } else { - return new Operation(this.op, [a, b], this.isSpaced); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.operands[0].genCSS(context, output); - - if (this.isSpaced) { - output.add(' '); - } - - output.add(this.op); - - if (this.isSpaced) { - output.add(' '); - } - - this.operands[1].genCSS(context, output); - } - }]); - - return Operation; -}(Node); - + }; + Operation.prototype.genCSS = function (context, output) { + this.operands[0].genCSS(context, output); + if (this.isSpaced) { + output.add(' '); + } + output.add(this.op); + if (this.isSpaced) { + output.add(' '); + } + this.operands[1].genCSS(context, output); + }; + return Operation; +}(Node)); Operation.prototype.type = 'Operation'; var MATH$2 = Math$1; - -var Expression = -/*#__PURE__*/ -function (_Node) { - _inherits(Expression, _Node); - - function Expression(value, noSpacing) { - var _this; - - _classCallCheck(this, Expression); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Expression).call(this)); - _this.value = value; - _this.noSpacing = noSpacing; - - if (!value) { - throw new Error('Expression requires an array parameter'); - } - - return _this; - } - - _createClass(Expression, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visitArray(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - var returnValue; - var mathOn = context.isMathOn(); - var inParenthesis = this.parens && (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); - var doubleParen = false; - - if (inParenthesis) { - context.inParenthesis(); - } - - if (this.value.length > 1) { - returnValue = new Expression(this.value.map(function (e) { - if (!e.eval) { - return e; - } - - return e.eval(context); - }), this.noSpacing); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { - doubleParen = true; +var Expression = /** @class */ (function (_super) { + tslib.__extends(Expression, _super); + function Expression(value, noSpacing) { + var _this = _super.call(this) || this; + _this.value = value; + _this.noSpacing = noSpacing; + if (!value) { + throw new Error('Expression requires an array parameter'); } - - returnValue = this.value[0].eval(context); - } else { - returnValue = this; - } - - if (inParenthesis) { - context.outOfParenthesis(); - } - - if (this.parens && this.parensInOp && !mathOn && !doubleParen && !(returnValue instanceof Dimension)) { - returnValue = new Paren(returnValue); - } - - return returnValue; + return _this; } - }, { - key: "genCSS", - value: function genCSS(context, output) { - for (var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (!this.noSpacing && i + 1 < this.value.length) { - output.add(' '); + Expression.prototype.accept = function (visitor) { + this.value = visitor.visitArray(this.value); + }; + Expression.prototype.eval = function (context) { + var returnValue; + var mathOn = context.isMathOn(); + var inParenthesis = this.parens && + (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); + var doubleParen = false; + if (inParenthesis) { + context.inParenthesis(); + } + if (this.value.length > 1) { + returnValue = new Expression(this.value.map(function (e) { + if (!e.eval) { + return e; + } + return e.eval(context); + }), this.noSpacing); } - } - } - }, { - key: "throwAwayComments", - value: function throwAwayComments() { - this.value = this.value.filter(function (v) { - return !(v instanceof Comment); - }); - } - }]); - - return Expression; -}(Node); - -Expression.prototype.type = 'Expression'; - -var functionCaller = -/*#__PURE__*/ -function () { - function functionCaller(name, context, index, currentFileInfo) { - _classCallCheck(this, functionCaller); - - this.name = name.toLowerCase(); - this.index = index; - this.context = context; - this.currentFileInfo = currentFileInfo; - this.func = context.frames[0].functionRegistry.get(this.name); - } - - _createClass(functionCaller, [{ - key: "isValid", - value: function isValid() { - return Boolean(this.func); - } - }, { - key: "call", - value: function call(args) { - // This code is terrible and should be replaced as per this issue... - // https://github.com/less/less.js/issues/2477 - if (Array.isArray(args)) { - args = args.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }).map(function (item) { - if (item.type === 'Expression') { - var subNodes = item.value.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }); - - if (subNodes.length === 1) { - return subNodes[0]; - } else { - return new Expression(subNodes); + else if (this.value.length === 1) { + if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { + doubleParen = true; } - } - - return item; - }); - } + returnValue = this.value[0].eval(context); + } + else { + returnValue = this; + } + if (inParenthesis) { + context.outOfParenthesis(); + } + if (this.parens && this.parensInOp && !mathOn && !doubleParen + && (!(returnValue instanceof Dimension))) { + returnValue = new Paren(returnValue); + } + return returnValue; + }; + Expression.prototype.genCSS = function (context, output) { + for (var i_1 = 0; i_1 < this.value.length; i_1++) { + this.value[i_1].genCSS(context, output); + if (!this.noSpacing && i_1 + 1 < this.value.length) { + output.add(' '); + } + } + }; + Expression.prototype.throwAwayComments = function () { + this.value = this.value.filter(function (v) { return !(v instanceof Comment); }); + }; + return Expression; +}(Node)); +Expression.prototype.type = 'Expression'; - return this.func.apply(this, _toConsumableArray(args)); +var functionCaller = /** @class */ (function () { + function functionCaller(name, context, index, currentFileInfo) { + this.name = name.toLowerCase(); + this.index = index; + this.context = context; + this.currentFileInfo = currentFileInfo; + this.func = context.frames[0].functionRegistry.get(this.name); } - }]); - - return functionCaller; -}(); + functionCaller.prototype.isValid = function () { + return Boolean(this.func); + }; + functionCaller.prototype.call = function (args) { + // This code is terrible and should be replaced as per this issue... + // https://github.com/less/less.js/issues/2477 + if (Array.isArray(args)) { + args = args.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }) + .map(function (item) { + if (item.type === 'Expression') { + var subNodes = item.value.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }); + if (subNodes.length === 1) { + return subNodes[0]; + } + else { + return new Expression(subNodes); + } + } + return item; + }); + } + return this.func.apply(this, args); + }; + return functionCaller; +}()); +// // A function call node. // - -var Call = -/*#__PURE__*/ -function (_Node) { - _inherits(Call, _Node); - - function Call(name, args, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Call); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Call).call(this)); - _this.name = name; - _this.args = args; - _this.calc = name === 'calc'; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Call, [{ - key: "accept", - value: function accept(visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - } // +var Call = /** @class */ (function (_super) { + tslib.__extends(Call, _super); + function Call(name, args, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this.args = args; + _this.calc = name === 'calc'; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Call.prototype.accept = function (visitor) { + if (this.args) { + this.args = visitor.visitArray(this.args); + } + }; + // // When evaluating a function call, // we either find the function in the functionRegistry, // in which case we call it, passing the evaluated arguments, @@ -4349,645 +3262,466 @@ function (_Node) { // we try to pass a variable to a function, like: `saturate(@color)`. // The function should receive the value, not the variable. // - - }, { - key: "eval", - value: function _eval(context) { - /** - * Turn off math for calc(), and switch back on for evaluating nested functions - */ - var currentMathContext = context.mathOn; - context.mathOn = !this.calc; - - if (this.calc || context.inCalc) { - context.enterCalc(); - } - - var args = this.args.map(function (a) { - return a.eval(context); - }); - - if (this.calc || context.inCalc) { - context.exitCalc(); - } - - context.mathOn = currentMathContext; - var result; - var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); - - if (funcCaller.isValid()) { - try { - result = funcCaller.call(args); - } catch (e) { - throw { - type: e.type || 'Runtime', - message: `error evaluating function \`${this.name}\`${e.message ? `: ${e.message}` : ''}`, - index: this.getIndex(), - filename: this.fileInfo().filename, - line: e.lineNumber, - column: e.columnNumber - }; + Call.prototype.eval = function (context) { + /** + * Turn off math for calc(), and switch back on for evaluating nested functions + */ + var currentMathContext = context.mathOn; + context.mathOn = !this.calc; + if (this.calc || context.inCalc) { + context.enterCalc(); } - - if (result !== null && result !== undefined) { - // Results that that are not nodes are cast as Anonymous nodes - // Falsy values or booleans are returned as empty nodes - if (!(result instanceof Node)) { - if (!result || result === true) { - result = new Anonymous(null); - } else { - result = new Anonymous(result.toString()); - } - } - - result._index = this._index; - result._fileInfo = this._fileInfo; - return result; + var args = this.args.map(function (a) { return a.eval(context); }); + if (this.calc || context.inCalc) { + context.exitCalc(); } - } - - return new Call(this.name, args, this.getIndex(), this.fileInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(`${this.name}(`, this.fileInfo(), this.getIndex()); - - for (var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(context, output); - - if (i + 1 < this.args.length) { - output.add(', '); + context.mathOn = currentMathContext; + var result; + var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); + if (funcCaller.isValid()) { + try { + result = funcCaller.call(args); + } + catch (e) { + throw { + type: e.type || 'Runtime', + message: "error evaluating function `" + this.name + "`" + (e.message ? ": " + e.message : ''), + index: this.getIndex(), + filename: this.fileInfo().filename, + line: e.lineNumber, + column: e.columnNumber + }; + } + if (result !== null && result !== undefined) { + // Results that that are not nodes are cast as Anonymous nodes + // Falsy values or booleans are returned as empty nodes + if (!(result instanceof Node)) { + if (!result || result === true) { + result = new Anonymous(null); + } + else { + result = new Anonymous(result.toString()); + } + } + result._index = this._index; + result._fileInfo = this._fileInfo; + return result; + } } - } - - output.add(')'); - } - }]); - - return Call; -}(Node); - + return new Call(this.name, args, this.getIndex(), this.fileInfo()); + }; + Call.prototype.genCSS = function (context, output) { + output.add(this.name + "(", this.fileInfo(), this.getIndex()); + for (var i_1 = 0; i_1 < this.args.length; i_1++) { + this.args[i_1].genCSS(context, output); + if (i_1 + 1 < this.args.length) { + output.add(', '); + } + } + output.add(')'); + }; + return Call; +}(Node)); Call.prototype.type = 'Call'; -var Variable = -/*#__PURE__*/ -function (_Node) { - _inherits(Variable, _Node); - - function Variable(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Variable); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Variable).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Variable, [{ - key: "eval", - value: function _eval(context) { - var variable; - var name = this.name; - - if (name.indexOf('@@') === 0) { - name = `@${new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value}`; - } - - if (this.evaluating) { - throw { - type: 'Name', - message: `Recursive variable definition for ${name}`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - variable = this.find(context.frames, function (frame) { - var v = frame.variable(name); - - if (v) { - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } // If in calc, wrap vars in a function call to cascade evaluate args first - - - if (context.inCalc) { - return new Call('_SELF', [v.value]).eval(context); - } else { - return v.value.eval(context); - } +var Variable = /** @class */ (function (_super) { + tslib.__extends(Variable, _super); + function Variable(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Variable.prototype.eval = function (context) { + var variable; + var name = this.name; + if (name.indexOf('@@') === 0) { + name = "@" + new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value; + } + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive variable definition for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + variable = this.find(context.frames, function (frame) { + var v = frame.variable(name); + if (v) { + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + // If in calc, wrap vars in a function call to cascade evaluate args first + if (context.inCalc) { + return (new Call('_SELF', [v.value])).eval(context); + } + else { + return v.value.eval(context); + } + } + }); + if (variable) { + this.evaluating = false; + return variable; } - }); - - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { - type: 'Name', - message: `variable ${name} is undefined`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "variable " + name + " is undefined", + filename: this.fileInfo().filename, + index: this.getIndex() }; } - } - - return null; - } - }]); - - return Variable; -}(Node); - + }; + Variable.prototype.find = function (obj, fun) { + for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) { + r = fun.call(obj, obj[i_1]); + if (r) { + return r; + } + } + return null; + }; + return Variable; +}(Node)); Variable.prototype.type = 'Variable'; -var Property = -/*#__PURE__*/ -function (_Node) { - _inherits(Property, _Node); - - function Property(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Property); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Property).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Property, [{ - key: "eval", - value: function _eval(context) { - var property; - var name = this.name; // TODO: shorten this reference - - var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; - - if (this.evaluating) { - throw { - type: 'Name', - message: `Recursive property reference for ${name}`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - property = this.find(context.frames, function (frame) { - var v; - var vArr = frame.property(name); - - if (vArr) { - for (var i = 0; i < vArr.length; i++) { - v = vArr[i]; - vArr[i] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); - } - - mergeRules(vArr); - v = vArr[vArr.length - 1]; - - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } - - v = v.value.eval(context); - return v; +var Property = /** @class */ (function (_super) { + tslib.__extends(Property, _super); + function Property(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Property.prototype.eval = function (context) { + var property; + var name = this.name; + // TODO: shorten this reference + var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive property reference for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + property = this.find(context.frames, function (frame) { + var v; + var vArr = frame.property(name); + if (vArr) { + for (var i_1 = 0; i_1 < vArr.length; i_1++) { + v = vArr[i_1]; + vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); + } + mergeRules(vArr); + v = vArr[vArr.length - 1]; + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + v = v.value.eval(context); + return v; + } + }); + if (property) { + this.evaluating = false; + return property; } - }); - - if (property) { - this.evaluating = false; - return property; - } else { - throw { - type: 'Name', - message: `Property '${name}' is undefined`, - filename: this.currentFileInfo.filename, - index: this.index - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "Property '" + name + "' is undefined", + filename: this.currentFileInfo.filename, + index: this.index }; } - } - - return null; - } - }]); - - return Property; -}(Node); - + }; + Property.prototype.find = function (obj, fun) { + for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) { + r = fun.call(obj, obj[i_2]); + if (r) { + return r; + } + } + return null; + }; + return Property; +}(Node)); Property.prototype.type = 'Property'; -var Attribute = -/*#__PURE__*/ -function (_Node) { - _inherits(Attribute, _Node); - - function Attribute(key, op, value) { - var _this; - - _classCallCheck(this, Attribute); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Attribute).call(this)); - _this.key = key; - _this.op = op; - _this.value = value; - return _this; - } - - _createClass(Attribute, [{ - key: "eval", - value: function _eval(context) { - return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, this.value && this.value.eval ? this.value.eval(context) : this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context) { - var value = this.key.toCSS ? this.key.toCSS(context) : this.key; - - if (this.op) { - value += this.op; - value += this.value.toCSS ? this.value.toCSS(context) : this.value; - } - - return `[${value}]`; - } - }]); - - return Attribute; -}(Node); - +var Attribute = /** @class */ (function (_super) { + tslib.__extends(Attribute, _super); + function Attribute(key, op, value) { + var _this = _super.call(this) || this; + _this.key = key; + _this.op = op; + _this.value = value; + return _this; + } + Attribute.prototype.eval = function (context) { + return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value); + }; + Attribute.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Attribute.prototype.toCSS = function (context) { + var value = this.key.toCSS ? this.key.toCSS(context) : this.key; + if (this.op) { + value += this.op; + value += (this.value.toCSS ? this.value.toCSS(context) : this.value); + } + return "[" + value + "]"; + }; + return Attribute; +}(Node)); Attribute.prototype.type = 'Attribute'; -var Quoted = -/*#__PURE__*/ -function (_Node) { - _inherits(Quoted, _Node); - - function Quoted(str, content, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Quoted); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Quoted).call(this)); - _this.escaped = escaped == null ? true : escaped; - _this.value = content || ''; - _this.quote = str.charAt(0); - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.variableRegex = /@\{([\w-]+)\}/g; - _this.propRegex = /\$\{([\w-]+)\}/g; - _this.allowRoot = escaped; - return _this; - } - - _createClass(Quoted, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (!this.escaped) { - output.add(this.quote, this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - - if (!this.escaped) { - output.add(this.quote); - } - } - }, { - key: "containsVariables", - value: function containsVariables() { - return this.value.match(this.variableRegex); - } - }, { - key: "eval", - value: function _eval(context) { - var that = this; - var value = this.value; - - var variableReplacement = function variableReplacement(_, name) { - var v = new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - var propertyReplacement = function propertyReplacement(_, name) { - var v = new Property(`$${name}`, that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - function iterativeReplace(value, regexp, replacementFnc) { - var evaluatedValue = value; - - do { - value = evaluatedValue.toString(); - evaluatedValue = value.replace(regexp, replacementFnc); - } while (value !== evaluatedValue); - - return evaluatedValue; - } - - value = iterativeReplace(value, this.variableRegex, variableReplacement); - value = iterativeReplace(value, this.propRegex, propertyReplacement); - return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); - } - }, { - key: "compare", - value: function compare(other) { - // when comparing quoted strings allow the quote to differ - if (other.type === 'Quoted' && !this.escaped && !other.escaped) { - return Node.numericCompare(this.value, other.value); - } else { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - } - }]); - - return Quoted; -}(Node); - +var Quoted = /** @class */ (function (_super) { + tslib.__extends(Quoted, _super); + function Quoted(str, content, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = (escaped == null) ? true : escaped; + _this.value = content || ''; + _this.quote = str.charAt(0); + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.variableRegex = /@\{([\w-]+)\}/g; + _this.propRegex = /\$\{([\w-]+)\}/g; + _this.allowRoot = escaped; + return _this; + } + Quoted.prototype.genCSS = function (context, output) { + if (!this.escaped) { + output.add(this.quote, this.fileInfo(), this.getIndex()); + } + output.add(this.value); + if (!this.escaped) { + output.add(this.quote); + } + }; + Quoted.prototype.containsVariables = function () { + return this.value.match(this.variableRegex); + }; + Quoted.prototype.eval = function (context) { + var that = this; + var value = this.value; + var variableReplacement = function (_, name) { + var v = new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + var propertyReplacement = function (_, name) { + var v = new Property("$" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + function iterativeReplace(value, regexp, replacementFnc) { + var evaluatedValue = value; + do { + value = evaluatedValue.toString(); + evaluatedValue = value.replace(regexp, replacementFnc); + } while (value !== evaluatedValue); + return evaluatedValue; + } + value = iterativeReplace(value, this.variableRegex, variableReplacement); + value = iterativeReplace(value, this.propRegex, propertyReplacement); + return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); + }; + Quoted.prototype.compare = function (other) { + // when comparing quoted strings allow the quote to differ + if (other.type === 'Quoted' && !this.escaped && !other.escaped) { + return Node.numericCompare(this.value, other.value); + } + else { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + } + }; + return Quoted; +}(Node)); Quoted.prototype.type = 'Quoted'; -var URL = -/*#__PURE__*/ -function (_Node) { - _inherits(URL, _Node); - - function URL(val, index, currentFileInfo, isEvald) { - var _this; - - _classCallCheck(this, URL); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(URL).call(this)); - _this.value = val; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.isEvald = isEvald; - return _this; - } - - _createClass(URL, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('url('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - var val = this.value.eval(context); - var rootpath; - - if (!this.isEvald) { - // Add the rootpath if the URL requires a rewrite - rootpath = this.fileInfo() && this.fileInfo().rootpath; - - if (typeof rootpath === 'string' && typeof val.value === 'string' && context.pathRequiresRewrite(val.value)) { - if (!val.quote) { - rootpath = escapePath(rootpath); - } - - val.value = context.rewritePath(val.value, rootpath); - } else { - val.value = context.normalizePath(val.value); - } // Add url args if enabled - - - if (context.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + context.urlArgs; - - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', `${urlArgs}#`); - } else { - val.value += urlArgs; +var URL = /** @class */ (function (_super) { + tslib.__extends(URL, _super); + function URL(val, index, currentFileInfo, isEvald) { + var _this = _super.call(this) || this; + _this.value = val; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.isEvald = isEvald; + return _this; + } + URL.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + URL.prototype.genCSS = function (context, output) { + output.add('url('); + this.value.genCSS(context, output); + output.add(')'); + }; + URL.prototype.eval = function (context) { + var val = this.value.eval(context); + var rootpath; + if (!this.isEvald) { + // Add the rootpath if the URL requires a rewrite + rootpath = this.fileInfo() && this.fileInfo().rootpath; + if (typeof rootpath === 'string' && + typeof val.value === 'string' && + context.pathRequiresRewrite(val.value)) { + if (!val.quote) { + rootpath = escapePath(rootpath); + } + val.value = context.rewritePath(val.value, rootpath); + } + else { + val.value = context.normalizePath(val.value); + } + // Add url args if enabled + if (context.urlArgs) { + if (!val.value.match(/^\s*data:/)) { + var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; + var urlArgs = delimiter + context.urlArgs; + if (val.value.indexOf('#') !== -1) { + val.value = val.value.replace('#', urlArgs + "#"); + } + else { + val.value += urlArgs; + } + } } - } } - } - - return new URL(val, this.getIndex(), this.fileInfo(), true); - } - }]); - - return URL; -}(Node); - + return new URL(val, this.getIndex(), this.fileInfo(), true); + }; + return URL; +}(Node)); URL.prototype.type = 'Url'; - function escapePath(path) { - return path.replace(/[\(\)'"\s]/g, function (match) { - return `\\${match}`; - }); + return path.replace(/[\(\)'"\s]/g, function (match) { return "\\" + match; }); } -var Media = -/*#__PURE__*/ -function (_AtRule) { - _inherits(Media, _AtRule); - - function Media(value, features, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Media); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Media).call(this)); - _this._index = index; - _this._fileInfo = currentFileInfo; - var selectors = new Selector([], null, null, _this._index, _this._fileInfo).createEmptySelectors(); - _this.features = new Value(features); - _this.rules = [new Ruleset(selectors, value)]; - _this.rules[0].allowImports = true; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Media, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('@media ', this._fileInfo, this._index); - this.features.genCSS(context, output); - this.outputRuleset(context, output, this.rules); - } - }, { - key: "eval", - value: function _eval(context) { - if (!context.mediaBlocks) { - context.mediaBlocks = []; - context.mediaPath = []; - } - - var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); - - if (this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - - media.features = this.features.eval(context); - context.mediaPath.push(media); - context.mediaBlocks.push(media); - this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); - context.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(context)]; - context.frames.shift(); - context.mediaPath.pop(); - return context.mediaPath.length === 0 ? media.evalTop(context) : media.evalNested(context); - } - }, { - key: "evalTop", - value: function evalTop(context) { - var result = this; // Render all dependent Media blocks. - - if (context.mediaBlocks.length > 1) { - var selectors = new Selector([], null, null, this.getIndex(), this.fileInfo()).createEmptySelectors(); - result = new Ruleset(selectors, context.mediaBlocks); - result.multiMedia = true; - result.copyVisibilityInfo(this.visibilityInfo()); - this.setParent(result, this); - } - - delete context.mediaBlocks; - delete context.mediaPath; - return result; - } - }, { - key: "evalNested", - value: function evalNested(context) { - var i; - var value; - var path = context.mediaPath.concat([this]); // Extract the media-query conditions separated with `,` (OR). - - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof Value ? path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - - - this.features = new Value(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new Anonymous(fragment); - }); - - for (i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new Anonymous('and')); +var Media = /** @class */ (function (_super) { + tslib.__extends(Media, _super); + function Media(value, features, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this._index = index; + _this._fileInfo = currentFileInfo; + var selectors = (new Selector([], null, null, _this._index, _this._fileInfo)).createEmptySelectors(); + _this.features = new Value(features); + _this.rules = [new Ruleset(selectors, value)]; + _this.rules[0].allowImports = true; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(selectors, _this); + _this.setParent(_this.features, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Media.prototype.isRulesetLike = function () { + return true; + }; + Media.prototype.accept = function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); } - - return new Expression(path); - })); - this.setParent(this.features, this); // Fake a tree-node that doesn't output anything. - - return new Ruleset([], []); - } - }, { - key: "permute", - value: function permute(arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } + if (this.rules) { + this.rules = visitor.visitArray(this.rules); } - + }; + Media.prototype.genCSS = function (context, output) { + output.add('@media ', this._fileInfo, this._index); + this.features.genCSS(context, output); + this.outputRuleset(context, output, this.rules); + }; + Media.prototype.eval = function (context) { + if (!context.mediaBlocks) { + context.mediaBlocks = []; + context.mediaPath = []; + } + var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); + if (this.debugInfo) { + this.rules[0].debugInfo = this.debugInfo; + media.debugInfo = this.debugInfo; + } + media.features = this.features.eval(context); + context.mediaPath.push(media); + context.mediaBlocks.push(media); + this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); + context.frames.unshift(this.rules[0]); + media.rules = [this.rules[0].eval(context)]; + context.frames.shift(); + context.mediaPath.pop(); + return context.mediaPath.length === 0 ? media.evalTop(context) : + media.evalNested(context); + }; + Media.prototype.evalTop = function (context) { + var result = this; + // Render all dependent Media blocks. + if (context.mediaBlocks.length > 1) { + var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors(); + result = new Ruleset(selectors, context.mediaBlocks); + result.multiMedia = true; + result.copyVisibilityInfo(this.visibilityInfo()); + this.setParent(result, this); + } + delete context.mediaBlocks; + delete context.mediaPath; return result; - } - } - }, { - key: "bubbleSelectors", - value: function bubbleSelectors(selectors) { - if (!selectors) { - return; - } - - this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; - this.setParent(this.rules, this); - } - }]); - - return Media; -}(AtRule); - + }; + Media.prototype.evalNested = function (context) { + var i; + var value; + var path = context.mediaPath.concat([this]); + // Extract the media-query conditions separated with `,` (OR). + for (i = 0; i < path.length; i++) { + value = path[i].features instanceof Value ? + path[i].features.value : path[i].features; + path[i] = Array.isArray(value) ? value : [value]; + } + // Trace all permutations to generate the resulting media-query. + // + // (a, b and c) with nested (d, e) -> + // a and d + // a and e + // b and c and d + // b and c and e + this.features = new Value(this.permute(path).map(function (path) { + path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); }); + for (i = path.length - 1; i > 0; i--) { + path.splice(i, 0, new Anonymous('and')); + } + return new Expression(path); + })); + this.setParent(this.features, this); + // Fake a tree-node that doesn't output anything. + return new Ruleset([], []); + }; + Media.prototype.permute = function (arr) { + if (arr.length === 0) { + return []; + } + else if (arr.length === 1) { + return arr[0]; + } + else { + var result = []; + var rest = this.permute(arr.slice(1)); + for (var i_1 = 0; i_1 < rest.length; i_1++) { + for (var j = 0; j < arr[0].length; j++) { + result.push([arr[0][j]].concat(rest[i_1])); + } + } + return result; + } + }; + Media.prototype.bubbleSelectors = function (selectors) { + if (!selectors) { + return; + } + this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; + this.setParent(this.rules, this); + }; + return Media; +}(AtRule)); Media.prototype.type = 'Media'; +// // CSS @import node // // The general strategy here is that we don't want to wait @@ -4999,3738 +3733,2854 @@ Media.prototype.type = 'Media'; // `import,push`, we also pass it a callback, which it'll call once // the file has been fetched, and parsed. // - -var Import = -/*#__PURE__*/ -function (_Node) { - _inherits(Import, _Node); - - function Import(path, features, options, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Import); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Import).call(this)); - _this.options = options; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.path = path; - _this.features = features; - _this.allowRoot = true; - - if (_this.options.less !== undefined || _this.options.inline) { - _this.css = !_this.options.less || _this.options.inline; - } else { - var pathValue = _this.getPath(); - - if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { - _this.css = true; - } +var Import = /** @class */ (function (_super) { + tslib.__extends(Import, _super); + function Import(path, features, options, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.options = options; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.path = path; + _this.features = features; + _this.allowRoot = true; + if (_this.options.less !== undefined || _this.options.inline) { + _this.css = !_this.options.less || _this.options.inline; + } + else { + var pathValue = _this.getPath(); + if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { + _this.css = true; + } + } + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.features, _this); + _this.setParent(_this.path, _this); + return _this; } - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.path, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Import, [{ - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - this.path = visitor.visit(this.path); - - if (!this.options.isPlugin && !this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (this.css && this.path._fileInfo.reference === undefined) { - output.add('@import ', this._fileInfo, this._index); - this.path.genCSS(context, output); - + Import.prototype.accept = function (visitor) { if (this.features) { - output.add(' '); - this.features.genCSS(context, output); + this.features = visitor.visit(this.features); } - - output.add(';'); - } - } - }, { - key: "getPath", - value: function getPath() { - return this.path instanceof URL ? this.path.value.value : this.path.value; - } - }, { - key: "isVariableImport", - value: function isVariableImport() { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - if (path instanceof Quoted) { - return path.containsVariables(); - } - - return true; - } - }, { - key: "evalForImport", - value: function evalForImport(context) { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); - } - }, { - key: "evalPath", - value: function evalPath(context) { - var path = this.path.eval(context); - var fileInfo = this._fileInfo; - - if (!(path instanceof URL)) { - // Add the rootpath if the URL requires a rewrite - var pathValue = path.value; - - if (fileInfo && pathValue && context.pathRequiresRewrite(pathValue)) { - path.value = context.rewritePath(pathValue, fileInfo.rootpath); - } else { - path.value = context.normalizePath(path.value); + this.path = visitor.visit(this.path); + if (!this.options.isPlugin && !this.options.inline && this.root) { + this.root = visitor.visit(this.root); } - } - - return path; - } - }, { - key: "eval", - value: function _eval(context) { - var result = this.doEval(context); - - if (this.options.reference || this.blocksVisibility()) { - if (result.length || result.length === 0) { - result.forEach(function (node) { - node.addVisibilityBlock(); - }); - } else { - result.addVisibilityBlock(); - } - } - - return result; - } - }, { - key: "doEval", - value: function doEval(context) { - var ruleset; - var registry; - var features = this.features && this.features.eval(context); - - if (this.options.isPlugin) { - if (this.root && this.root.eval) { - try { - this.root.eval(context); - } catch (e) { - e.message = 'Plugin error during evaluation'; - throw new LessError(e, this.root.imports, this.root.filename); - } + }; + Import.prototype.genCSS = function (context, output) { + if (this.css && this.path._fileInfo.reference === undefined) { + output.add('@import ', this._fileInfo, this._index); + this.path.genCSS(context, output); + if (this.features) { + output.add(' '); + this.features.genCSS(context, output); + } + output.add(';'); } - - registry = context.frames[0] && context.frames[0].functionRegistry; - - if (registry && this.root && this.root.functions) { - registry.addMultiple(this.root.functions); + }; + Import.prototype.getPath = function () { + return (this.path instanceof URL) ? + this.path.value.value : this.path.value; + }; + Import.prototype.isVariableImport = function () { + var path = this.path; + if (path instanceof URL) { + path = path.value; } - - return []; - } - - if (this.skip) { - if (typeof this.skip === 'function') { - this.skip = this.skip(); + if (path instanceof Quoted) { + return path.containsVariables(); + } + return true; + }; + Import.prototype.evalForImport = function (context) { + var path = this.path; + if (path instanceof URL) { + path = path.value; + } + return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); + }; + Import.prototype.evalPath = function (context) { + var path = this.path.eval(context); + var fileInfo = this._fileInfo; + if (!(path instanceof URL)) { + // Add the rootpath if the URL requires a rewrite + var pathValue = path.value; + if (fileInfo && + pathValue && + context.pathRequiresRewrite(pathValue)) { + path.value = context.rewritePath(pathValue, fileInfo.rootpath); + } + else { + path.value = context.normalizePath(path.value); + } + } + return path; + }; + Import.prototype.eval = function (context) { + var result = this.doEval(context); + if (this.options.reference || this.blocksVisibility()) { + if (result.length || result.length === 0) { + result.forEach(function (node) { + node.addVisibilityBlock(); + }); + } + else { + result.addVisibilityBlock(); + } + } + return result; + }; + Import.prototype.doEval = function (context) { + var ruleset; + var registry; + var features = this.features && this.features.eval(context); + if (this.options.isPlugin) { + if (this.root && this.root.eval) { + try { + this.root.eval(context); + } + catch (e) { + e.message = 'Plugin error during evaluation'; + throw new LessError(e, this.root.imports, this.root.filename); + } + } + registry = context.frames[0] && context.frames[0].functionRegistry; + if (registry && this.root && this.root.functions) { + registry.addMultiple(this.root.functions); + } + return []; } - if (this.skip) { - return []; + if (typeof this.skip === 'function') { + this.skip = this.skip(); + } + if (this.skip) { + return []; + } } - } - - if (this.options.inline) { - var contents = new Anonymous(this.root, 0, { - filename: this.importedFilename, - reference: this.path._fileInfo && this.path._fileInfo.reference - }, true, true); - return this.features ? new Media([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new Import(this.evalPath(context), features, this.options, this._index); - - if (!newImport.css && this.error) { - throw this.error; + if (this.options.inline) { + var contents = new Anonymous(this.root, 0, { + filename: this.importedFilename, + reference: this.path._fileInfo && this.path._fileInfo.reference + }, true, true); + return this.features ? new Media([contents], this.features.value) : [contents]; + } + else if (this.css) { + var newImport = new Import(this.evalPath(context), features, this.options, this._index); + if (!newImport.css && this.error) { + throw this.error; + } + return newImport; } - - return newImport; - } else { - ruleset = new Ruleset(null, copyArray(this.root.rules)); - ruleset.evalImports(context); - return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; - } - } - }]); - - return Import; -}(Node); - + else { + ruleset = new Ruleset(null, copyArray(this.root.rules)); + ruleset.evalImports(context); + return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; + } + }; + return Import; +}(Node)); Import.prototype.type = 'Import'; -var JsEvalNode = -/*#__PURE__*/ -function (_Node) { - _inherits(JsEvalNode, _Node); - - function JsEvalNode() { - _classCallCheck(this, JsEvalNode); - - return _possibleConstructorReturn(this, _getPrototypeOf(JsEvalNode).apply(this, arguments)); - } - - _createClass(JsEvalNode, [{ - key: "evaluateJavaScript", - value: function evaluateJavaScript(expression, context) { - var result; - var that = this; - var evalContext = {}; - - if (!context.javascriptEnabled) { - throw { - message: 'Inline JavaScript is not enabled. Is it set in your options?', - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return that.jsify(new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context)); - }); - - try { - expression = new Function(`return (${expression})`); - } catch (e) { - throw { - message: `JavaScript evaluation error: ${e.message} from \`${expression}\``, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - var variables = context.frames[0].variables(); - - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /* jshint loopfunc:true */ - evalContext[k.slice(1)] = { - value: variables[k].value, - toJS: function toJS() { - return this.value.eval(context).toCSS(); +var JsEvalNode = /** @class */ (function (_super) { + tslib.__extends(JsEvalNode, _super); + function JsEvalNode() { + return _super !== null && _super.apply(this, arguments) || this; + } + JsEvalNode.prototype.evaluateJavaScript = function (expression, context) { + var result; + var that = this; + var evalContext = {}; + if (!context.javascriptEnabled) { + throw { message: 'Inline JavaScript is not enabled. Is it set in your options?', + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { return that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context)); }); + try { + expression = new Function("return (" + expression + ")"); + } + catch (e) { + throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + var variables = context.frames[0].variables(); + for (var k in variables) { + if (variables.hasOwnProperty(k)) { + /* jshint loopfunc:true */ + evalContext[k.slice(1)] = { + value: variables[k].value, + toJS: function () { + return this.value.eval(context).toCSS(); + } + }; } - }; } - } - - try { - result = expression.call(evalContext); - } catch (e) { - throw { - message: `JavaScript evaluation error: '${e.name}: ${e.message.replace(/["]/g, '\'')}'`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - return result; - } - }, { - key: "jsify", - value: function jsify(obj) { - if (Array.isArray(obj.value) && obj.value.length > 1) { - return `[${obj.value.map(function (v) { - return v.toCSS(); - }).join(', ')}]`; - } else { - return obj.toCSS(); - } - } - }]); - - return JsEvalNode; -}(Node); - -var JavaScript = -/*#__PURE__*/ -function (_JsEvalNode) { - _inherits(JavaScript, _JsEvalNode); - - function JavaScript(string, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, JavaScript); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(JavaScript).call(this)); - _this.escaped = escaped; - _this.expression = string; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(JavaScript, [{ - key: "eval", - value: function _eval(context) { - var result = this.evaluateJavaScript(this.expression, context); - var type = typeof result; - - if (type === 'number' && !isNaN(result)) { - return new Dimension(result); - } else if (type === 'string') { - return new Quoted(`"${result}"`, result, this.escaped, this._index); - } else if (Array.isArray(result)) { - return new Anonymous(result.join(', ')); - } else { - return new Anonymous(result); - } - } - }]); - - return JavaScript; -}(JsEvalNode); - + try { + result = expression.call(evalContext); + } + catch (e) { + throw { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + return result; + }; + JsEvalNode.prototype.jsify = function (obj) { + if (Array.isArray(obj.value) && (obj.value.length > 1)) { + return "[" + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + "]"; + } + else { + return obj.toCSS(); + } + }; + return JsEvalNode; +}(Node)); + +var JavaScript = /** @class */ (function (_super) { + tslib.__extends(JavaScript, _super); + function JavaScript(string, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = escaped; + _this.expression = string; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + JavaScript.prototype.eval = function (context) { + var result = this.evaluateJavaScript(this.expression, context); + var type = typeof result; + if (type === 'number' && !isNaN(result)) { + return new Dimension(result); + } + else if (type === 'string') { + return new Quoted("\"" + result + "\"", result, this.escaped, this._index); + } + else if (Array.isArray(result)) { + return new Anonymous(result.join(', ')); + } + else { + return new Anonymous(result); + } + }; + return JavaScript; +}(JsEvalNode)); JavaScript.prototype.type = 'JavaScript'; -var Assignment = -/*#__PURE__*/ -function (_Node) { - _inherits(Assignment, _Node); - - function Assignment(key, val) { - var _this; - - _classCallCheck(this, Assignment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Assignment).call(this)); - _this.key = key; - _this.value = val; - return _this; - } - - _createClass(Assignment, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.eval) { - return new Assignment(this.key, this.value.eval(context)); - } - - return this; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(`${this.key}=`); - - if (this.value.genCSS) { - this.value.genCSS(context, output); - } else { - output.add(this.value); - } +var Assignment = /** @class */ (function (_super) { + tslib.__extends(Assignment, _super); + function Assignment(key, val) { + var _this = _super.call(this) || this; + _this.key = key; + _this.value = val; + return _this; } - }]); - - return Assignment; -}(Node); - + Assignment.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Assignment.prototype.eval = function (context) { + if (this.value.eval) { + return new Assignment(this.key, this.value.eval(context)); + } + return this; + }; + Assignment.prototype.genCSS = function (context, output) { + output.add(this.key + "="); + if (this.value.genCSS) { + this.value.genCSS(context, output); + } + else { + output.add(this.value); + } + }; + return Assignment; +}(Node)); Assignment.prototype.type = 'Assignment'; -var Condition = -/*#__PURE__*/ -function (_Node) { - _inherits(Condition, _Node); - - function Condition(op, l, r, i, negate) { - var _this; - - _classCallCheck(this, Condition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Condition).call(this)); - _this.op = op.trim(); - _this.lvalue = l; - _this.rvalue = r; - _this._index = i; - _this.negate = negate; - return _this; - } - - _createClass(Condition, [{ - key: "accept", - value: function accept(visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - } - }, { - key: "eval", - value: function _eval(context) { - var result = function (op, a, b) { - switch (op) { - case 'and': - return a && b; - - case 'or': - return a || b; - - default: - switch (Node.compare(a, b)) { - case -1: - return op === '<' || op === '=<' || op === '<='; - - case 0: - return op === '=' || op === '>=' || op === '=<' || op === '<='; - - case 1: - return op === '>' || op === '>='; - - default: - return false; +var Condition = /** @class */ (function (_super) { + tslib.__extends(Condition, _super); + function Condition(op, l, r, i, negate) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.lvalue = l; + _this.rvalue = r; + _this._index = i; + _this.negate = negate; + return _this; + } + Condition.prototype.accept = function (visitor) { + this.lvalue = visitor.visit(this.lvalue); + this.rvalue = visitor.visit(this.rvalue); + }; + Condition.prototype.eval = function (context) { + var result = (function (op, a, b) { + switch (op) { + case 'and': return a && b; + case 'or': return a || b; + default: + switch (Node.compare(a, b)) { + case -1: + return op === '<' || op === '=<' || op === '<='; + case 0: + return op === '=' || op === '>=' || op === '=<' || op === '<='; + case 1: + return op === '>' || op === '>='; + default: + return false; + } } - - } - }(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); - - return this.negate ? !result : result; - } - }]); - - return Condition; -}(Node); - + })(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); + return this.negate ? !result : result; + }; + return Condition; +}(Node)); Condition.prototype.type = 'Condition'; -var UnicodeDescriptor = -/*#__PURE__*/ -function (_Node) { - _inherits(UnicodeDescriptor, _Node); - - function UnicodeDescriptor(value) { - var _this; - - _classCallCheck(this, UnicodeDescriptor); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(UnicodeDescriptor).call(this)); - _this.value = value; - return _this; - } - - return UnicodeDescriptor; -}(Node); - +var UnicodeDescriptor = /** @class */ (function (_super) { + tslib.__extends(UnicodeDescriptor, _super); + function UnicodeDescriptor(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; + } + return UnicodeDescriptor; +}(Node)); UnicodeDescriptor.prototype.type = 'UnicodeDescriptor'; -var Negative = -/*#__PURE__*/ -function (_Node) { - _inherits(Negative, _Node); - - function Negative(node) { - var _this; - - _classCallCheck(this, Negative); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Negative).call(this)); - _this.value = node; - return _this; - } - - _createClass(Negative, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('-'); - this.value.genCSS(context, output); - } - }, { - key: "eval", - value: function _eval(context) { - if (context.isMathOn()) { - return new Operation('*', [new Dimension(-1), this.value]).eval(context); - } - - return new Negative(this.value.eval(context)); +var Negative = /** @class */ (function (_super) { + tslib.__extends(Negative, _super); + function Negative(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; } - }]); - - return Negative; -}(Node); - + Negative.prototype.genCSS = function (context, output) { + output.add('-'); + this.value.genCSS(context, output); + }; + Negative.prototype.eval = function (context) { + if (context.isMathOn()) { + return (new Operation('*', [new Dimension(-1), this.value])).eval(context); + } + return new Negative(this.value.eval(context)); + }; + return Negative; +}(Node)); Negative.prototype.type = 'Negative'; -var Extend = -/*#__PURE__*/ -function (_Node) { - _inherits(Extend, _Node); - - function Extend(selector, option, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Extend); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Extend).call(this)); - _this.selector = selector; - _this.option = option; - _this.object_id = Extend.next_id++; - _this.parent_ids = [_this.object_id]; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - switch (option) { - case 'all': - _this.allowBefore = true; - _this.allowAfter = true; - break; - - default: - _this.allowBefore = false; - _this.allowAfter = false; - break; - } - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Extend, [{ - key: "accept", - value: function accept(visitor) { - this.selector = visitor.visit(this.selector); - } - }, { - key: "eval", - value: function _eval(context) { - return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone(context) { - return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } // it concatenates (joins) all selectors in selector array - - }, { - key: "findSelfSelectors", - value: function findSelfSelectors(selectors) { - var selfElements = []; - var i; - var selectorElements; - - for (i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { - selectorElements[0].combinator.value = ' '; +var Extend = /** @class */ (function (_super) { + tslib.__extends(Extend, _super); + function Extend(selector, option, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selector = selector; + _this.option = option; + _this.object_id = Extend.next_id++; + _this.parent_ids = [_this.object_id]; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + switch (option) { + case 'all': + _this.allowBefore = true; + _this.allowAfter = true; + break; + default: + _this.allowBefore = false; + _this.allowAfter = false; + break; } - - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [new Selector(selfElements)]; - this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + _this.setParent(_this.selector, _this); + return _this; } - }]); - - return Extend; -}(Node); - + Extend.prototype.accept = function (visitor) { + this.selector = visitor.visit(this.selector); + }; + Extend.prototype.eval = function (context) { + return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Extend.prototype.clone = function (context) { + return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + // it concatenates (joins) all selectors in selector array + Extend.prototype.findSelfSelectors = function (selectors) { + var selfElements = []; + var i; + var selectorElements; + for (i = 0; i < selectors.length; i++) { + selectorElements = selectors[i].elements; + // duplicate the logic in genCSS function inside the selector node. + // future TODO - move both logics into the selector joiner visitor + if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { + selectorElements[0].combinator.value = ' '; + } + selfElements = selfElements.concat(selectors[i].elements); + } + this.selfSelectors = [new Selector(selfElements)]; + this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + }; + return Extend; +}(Node)); Extend.next_id = 0; Extend.prototype.type = 'Extend'; -var VariableCall = -/*#__PURE__*/ -function (_Node) { - _inherits(VariableCall, _Node); - - function VariableCall(variable, index, currentFileInfo) { - var _this; - - _classCallCheck(this, VariableCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(VariableCall).call(this)); - _this.variable = variable; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(VariableCall, [{ - key: "eval", - value: function _eval(context) { - var rules; - var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); - var error = new LessError({ - message: `Could not evaluate variable call ${this.variable}` - }); - - if (!detachedRuleset.ruleset) { - if (detachedRuleset.rules) { - rules = detachedRuleset; - } else if (Array.isArray(detachedRuleset)) { - rules = new Ruleset('', detachedRuleset); - } else if (Array.isArray(detachedRuleset.value)) { - rules = new Ruleset('', detachedRuleset.value); - } else { - throw error; +var VariableCall = /** @class */ (function (_super) { + tslib.__extends(VariableCall, _super); + function VariableCall(variable, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.variable = variable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + VariableCall.prototype.eval = function (context) { + var rules; + var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); + var error = new LessError({ message: "Could not evaluate variable call " + this.variable }); + if (!detachedRuleset.ruleset) { + if (detachedRuleset.rules) { + rules = detachedRuleset; + } + else if (Array.isArray(detachedRuleset)) { + rules = new Ruleset('', detachedRuleset); + } + else if (Array.isArray(detachedRuleset.value)) { + rules = new Ruleset('', detachedRuleset.value); + } + else { + throw error; + } + detachedRuleset = new DetachedRuleset(rules); } - - detachedRuleset = new DetachedRuleset(rules); - } - - if (detachedRuleset.ruleset) { - return detachedRuleset.callEval(context); - } - - throw error; - } - }]); - - return VariableCall; -}(Node); - -VariableCall.prototype.type = 'VariableCall'; - -var NamespaceValue = -/*#__PURE__*/ -function (_Node) { - _inherits(NamespaceValue, _Node); - - function NamespaceValue(ruleCall, lookups, important, index, fileInfo) { - var _this; - - _classCallCheck(this, NamespaceValue); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(NamespaceValue).call(this)); - _this.value = ruleCall; - _this.lookups = lookups; - _this.important = important; - _this._index = index; - _this._fileInfo = fileInfo; - return _this; - } - - _createClass(NamespaceValue, [{ - key: "eval", - value: function _eval(context) { - var i; - var name; - var rules = this.value.eval(context); - - for (i = 0; i < this.lookups.length; i++) { - name = this.lookups[i]; - /** - * Eval'd DRs return rulesets. - * Eval'd mixins return rules, so let's make a ruleset if we need it. - * We need to do this because of late parsing of values - */ - - if (Array.isArray(rules)) { - rules = new Ruleset([new Selector()], rules); + if (detachedRuleset.ruleset) { + return detachedRuleset.callEval(context); } + throw error; + }; + return VariableCall; +}(Node)); +VariableCall.prototype.type = 'VariableCall'; - if (name === '') { - rules = rules.lastDeclaration(); - } else if (name.charAt(0) === '@') { - if (name.charAt(1) === '@') { - name = `@${new Variable(name.substr(1)).eval(context).value}`; - } - - if (rules.variables) { - rules = rules.variable(name); - } - - if (!rules) { - throw { - type: 'Name', - message: `variable ${name} not found`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } else { - if (name.substring(0, 2) === '$@') { - name = `$${new Variable(name.substr(1)).eval(context).value}`; - } else { - name = name.charAt(0) === '$' ? name : `$${name}`; - } - - if (rules.properties) { - rules = rules.property(name); - } - - if (!rules) { - throw { - type: 'Name', - message: `property "${name.substr(1)}" not found`, - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } // Properties are an array of values, since a ruleset can have multiple props. - // We pick the last one (the "cascaded" value) - - - rules = rules[rules.length - 1]; +var NamespaceValue = /** @class */ (function (_super) { + tslib.__extends(NamespaceValue, _super); + function NamespaceValue(ruleCall, lookups, index, fileInfo) { + var _this = _super.call(this) || this; + _this.value = ruleCall; + _this.lookups = lookups; + _this._index = index; + _this._fileInfo = fileInfo; + return _this; + } + NamespaceValue.prototype.eval = function (context) { + var i; + var name; + var rules = this.value.eval(context); + for (i = 0; i < this.lookups.length; i++) { + name = this.lookups[i]; + /** + * Eval'd DRs return rulesets. + * Eval'd mixins return rules, so let's make a ruleset if we need it. + * We need to do this because of late parsing of values + */ + if (Array.isArray(rules)) { + rules = new Ruleset([new Selector()], rules); + } + if (name === '') { + rules = rules.lastDeclaration(); + } + else if (name.charAt(0) === '@') { + if (name.charAt(1) === '@') { + name = "@" + new Variable(name.substr(1)).eval(context).value; + } + if (rules.variables) { + rules = rules.variable(name); + } + if (!rules) { + throw { type: 'Name', + message: "variable " + name + " not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + } + else { + if (name.substring(0, 2) === '$@') { + name = "$" + new Variable(name.substr(1)).eval(context).value; + } + else { + name = name.charAt(0) === '$' ? name : "$" + name; + } + if (rules.properties) { + rules = rules.property(name); + } + if (!rules) { + throw { type: 'Name', + message: "property \"" + name.substr(1) + "\" not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + // Properties are an array of values, since a ruleset can have multiple props. + // We pick the last one (the "cascaded" value) + rules = rules[rules.length - 1]; + } + if (rules.value) { + rules = rules.eval(context).value; + } + if (rules.ruleset) { + rules = rules.ruleset.eval(context); + } } + return rules; + }; + return NamespaceValue; +}(Node)); +NamespaceValue.prototype.type = 'NamespaceValue'; - if (rules.value) { - rules = rules.eval(context).value; +var Definition = /** @class */ (function (_super) { + tslib.__extends(Definition, _super); + function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { + var _this = _super.call(this) || this; + _this.name = name || 'anonymous mixin'; + _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; + _this.params = params; + _this.condition = condition; + _this.variadic = variadic; + _this.arity = params.length; + _this.rules = rules; + _this._lookups = {}; + var optionalParameters = []; + _this.required = params.reduce(function (count, p) { + if (!p.name || (p.name && !p.value)) { + return count + 1; + } + else { + optionalParameters.push(p.name); + return count; + } + }, 0); + _this.optionalParameters = optionalParameters; + _this.frames = frames; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + Definition.prototype.accept = function (visitor) { + if (this.params && this.params.length) { + this.params = visitor.visitArray(this.params); } - - if (rules.ruleset) { - rules = rules.ruleset.eval(context); + this.rules = visitor.visitArray(this.rules); + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } - - return rules; - } - }]); - - return NamespaceValue; -}(Node); - -NamespaceValue.prototype.type = 'NamespaceValue'; - -var Definition = -/*#__PURE__*/ -function (_Ruleset) { - _inherits(Definition, _Ruleset); - - function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { - var _this; - - _classCallCheck(this, Definition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Definition).call(this)); - _this.name = name || 'anonymous mixin'; - _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; - _this.params = params; - _this.condition = condition; - _this.variadic = variadic; - _this.arity = params.length; - _this.rules = rules; - _this._lookups = {}; - var optionalParameters = []; - _this.required = params.reduce(function (count, p) { - if (!p.name || p.name && !p.value) { - return count + 1; - } else { - optionalParameters.push(p.name); - return count; - } - }, 0); - _this.optionalParameters = optionalParameters; - _this.frames = frames; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(Definition, [{ - key: "accept", - value: function accept(visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - - this.rules = visitor.visitArray(this.rules); - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "evalParams", - value: function evalParams(context, mixinEnv, args, evaldArguments) { - /* jshint boss:true */ - var frame = new Ruleset(null, null); - var varargs; - var arg; - var params = copyArray(this.params); - var i; - var j; - var val; - var name; - var isNamedFound; - var argIndex; - var argsLength = 0; - - if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { - frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); - } - - mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = copyArray(args); - argsLength = args.length; - - for (i = 0; i < argsLength; i++) { - arg = args[i]; - - if (name = arg && arg.name) { - isNamedFound = false; - - for (j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(context); - frame.prependRule(new Declaration(name, arg.value.eval(context))); - isNamedFound = true; - break; - } + }; + Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) { + /* jshint boss:true */ + var frame = new Ruleset(null, null); + var varargs; + var arg; + var params = copyArray(this.params); + var i; + var j; + var val; + var name; + var isNamedFound; + var argIndex; + var argsLength = 0; + if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { + frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); + } + mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); + if (args) { + args = copyArray(args); + argsLength = args.length; + for (i = 0; i < argsLength; i++) { + arg = args[i]; + if (name = (arg && arg.name)) { + isNamedFound = false; + for (j = 0; j < params.length; j++) { + if (!evaldArguments[j] && name === params[j].name) { + evaldArguments[j] = arg.value.eval(context); + frame.prependRule(new Declaration(name, arg.value.eval(context))); + isNamedFound = true; + break; + } + } + if (isNamedFound) { + args.splice(i, 1); + i--; + continue; + } + else { + throw { type: 'Runtime', message: "Named argument for " + this.name + " " + args[i].name + " not found" }; + } + } } - - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { - type: 'Runtime', - message: `Named argument for ${this.name} ${args[i].name} not found` - }; - } - } - } - } - - argIndex = 0; - - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { - continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(context)); + argIndex = 0; + for (i = 0; i < params.length; i++) { + if (evaldArguments[i]) { + continue; } - - frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); - } else { - val = arg && arg.value; - - if (val) { - // This was a mixin call, pass in a detached ruleset of it's eval'd rules - if (Array.isArray(val)) { - val = new DetachedRuleset(new Ruleset('', val)); - } else { - val = val.eval(context); - } - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { - type: 'Runtime', - message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` - }; + arg = args && args[argIndex]; + if (name = params[i].name) { + if (params[i].variadic) { + varargs = []; + for (j = argIndex; j < argsLength; j++) { + varargs.push(args[j].value.eval(context)); + } + frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); + } + else { + val = arg && arg.value; + if (val) { + // This was a mixin call, pass in a detached ruleset of it's eval'd rules + if (Array.isArray(val)) { + val = new DetachedRuleset(new Ruleset('', val)); + } + else { + val = val.eval(context); + } + } + else if (params[i].value) { + val = params[i].value.eval(mixinEnv); + frame.resetCache(); + } + else { + throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + " (" + argsLength + " for " + this.arity + ")" }; + } + frame.prependRule(new Declaration(name, val)); + evaldArguments[i] = val; + } } - - frame.prependRule(new Declaration(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(context); - } + if (params[i].variadic && args) { + for (j = argIndex; j < argsLength; j++) { + evaldArguments[j] = args[j].value.eval(context); + } + } + argIndex++; } - - argIndex++; - } - - return frame; - } - }, { - key: "makeImportant", - value: function makeImportant() { - var rules = !this.rules ? this.rules : this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(true); - } else { - return r; - } - }); - var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); - return result; - } - }, { - key: "eval", - value: function _eval(context) { - return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); - } - }, { - key: "evalCall", - value: function evalCall(context, args, important) { - var _arguments = []; - var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; - var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); - var rules; - var ruleset; - frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); - rules = copyArray(this.rules); - ruleset = new Ruleset(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); - - if (important) { - ruleset = ruleset.makeImportant(); - } - - return ruleset; - } - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, - /* the parameter variables */ - new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])].concat(this.frames || []) // the parent namespace/mixin frames - .concat(context.frames)))) { - // the current environment frames - return false; - } - - return true; - } - }, { - key: "matchArgs", - value: function matchArgs(args, context) { - var allArgsCnt = args && args.length || 0; - var len; - var optionalParameters = this.optionalParameters; - var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { - if (optionalParameters.indexOf(p.name) < 0) { - return count + 1; - } else { - return count; - } - }, 0); - - if (!this.variadic) { - if (requiredArgsCnt < this.required) { - return false; + return frame; + }; + Definition.prototype.makeImportant = function () { + var rules = !this.rules ? this.rules : this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(true); + } + else { + return r; + } + }); + var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); + return result; + }; + Definition.prototype.eval = function (context) { + return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); + }; + Definition.prototype.evalCall = function (context, args, important) { + var _arguments = []; + var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; + var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); + var rules; + var ruleset; + frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); + rules = copyArray(this.rules); + ruleset = new Ruleset(null, rules); + ruleset.originalRuleset = this; + ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); + if (important) { + ruleset = ruleset.makeImportant(); + } + return ruleset; + }; + Definition.prototype.matchCondition = function (args, context) { + if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, /* the parameter variables */ new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])] + .concat(this.frames || []) // the parent namespace/mixin frames + .concat(context.frames)))) { // the current environment frames + return false; } - - if (allArgsCnt > this.params.length) { - return false; + return true; + }; + Definition.prototype.matchArgs = function (args, context) { + var allArgsCnt = (args && args.length) || 0; + var len; + var optionalParameters = this.optionalParameters; + var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { + if (optionalParameters.indexOf(p.name) < 0) { + return count + 1; + } + else { + return count; + } + }, 0); + if (!this.variadic) { + if (requiredArgsCnt < this.required) { + return false; + } + if (allArgsCnt > this.params.length) { + return false; + } } - } else { - if (requiredArgsCnt < this.required - 1) { - return false; + else { + if (requiredArgsCnt < (this.required - 1)) { + return false; + } } - } // check patterns - - - len = Math.min(requiredArgsCnt, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) { - return false; - } + // check patterns + len = Math.min(requiredArgsCnt, this.arity); + for (var i_1 = 0; i_1 < len; i_1++) { + if (!this.params[i_1].name && !this.params[i_1].variadic) { + if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) { + return false; + } + } } - } - - return true; - } - }]); - - return Definition; -}(Ruleset); - + return true; + }; + return Definition; +}(Ruleset)); Definition.prototype.type = 'MixinDefinition'; Definition.prototype.evalFirst = true; -var MixinCall = -/*#__PURE__*/ -function (_Node) { - _inherits(MixinCall, _Node); - - function MixinCall(elements, args, index, currentFileInfo, important) { - var _this; - - _classCallCheck(this, MixinCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(MixinCall).call(this)); - _this.selector = new Selector(elements); - _this.arguments = args || []; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.important = important; - _this.allowRoot = true; - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(MixinCall, [{ - key: "accept", - value: function accept(visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - - if (this.arguments.length) { - this.arguments = visitor.visitArray(this.arguments); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mixins; - var mixin; - var mixinPath; - var args = []; - var arg; - var argValue; - var rules = []; - var match = false; - var i; - var m; - var f; - var isRecursive; - var isOneFound; - var candidates = []; - var candidate; - var conditionResult = []; - var defaultResult; - var defFalseEitherCase = -1; - var defNone = 0; - var defTrue = 1; - var defFalse = 2; - var count; - var originalRuleset; - var noArgumentsFilter; - this.selector = this.selector.eval(context); - - function calcDefGroup(mixin, mixinPath) { +var MixinCall = /** @class */ (function (_super) { + tslib.__extends(MixinCall, _super); + function MixinCall(elements, args, index, currentFileInfo, important) { + var _this = _super.call(this) || this; + _this.selector = new Selector(elements); + _this.arguments = args || []; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.important = important; + _this.allowRoot = true; + _this.setParent(_this.selector, _this); + return _this; + } + MixinCall.prototype.accept = function (visitor) { + if (this.selector) { + this.selector = visitor.visit(this.selector); + } + if (this.arguments.length) { + this.arguments = visitor.visitArray(this.arguments); + } + }; + MixinCall.prototype.eval = function (context) { + var mixins; + var mixin; + var mixinPath; + var args = []; + var arg; + var argValue; + var rules = []; + var match = false; + var i; + var m; var f; - var p; - var namespace; - - for (f = 0; f < 2; f++) { - conditionResult[f] = true; - defaultFunc.value(f); - - for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { - namespace = mixinPath[p]; - - if (namespace.matchCondition) { - conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + var isRecursive; + var isOneFound; + var candidates = []; + var candidate; + var conditionResult = []; + var defaultResult; + var defFalseEitherCase = -1; + var defNone = 0; + var defTrue = 1; + var defFalse = 2; + var count; + var originalRuleset; + var noArgumentsFilter; + this.selector = this.selector.eval(context); + function calcDefGroup(mixin, mixinPath) { + var f; + var p; + var namespace; + for (f = 0; f < 2; f++) { + conditionResult[f] = true; + defaultFunc.value(f); + for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { + namespace = mixinPath[p]; + if (namespace.matchCondition) { + conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + } + } + if (mixin.matchCondition) { + conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); + } } - } - - if (mixin.matchCondition) { - conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); - } - } - - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - return conditionResult[1] ? defTrue : defFalse; - } - - return defNone; - } - - return defFalseEitherCase; - } - - for (i = 0; i < this.arguments.length; i++) { - arg = this.arguments[i]; - argValue = arg.value.eval(context); - - if (arg.expand && Array.isArray(argValue.value)) { - argValue = argValue.value; - - for (m = 0; m < argValue.length; m++) { - args.push({ - value: argValue[m] - }); - } - } else { - args.push({ - name: arg.name, - value: argValue - }); - } - } - - noArgumentsFilter = function noArgumentsFilter(rule) { - return rule.matchArgs(null, context); - }; - - for (i = 0; i < context.frames.length; i++) { - if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { - isOneFound = true; // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m].rule; - mixinPath = mixins[m].path; - isRecursive = false; - - for (f = 0; f < context.frames.length; f++) { - if (!(mixin instanceof Definition) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { - isRecursive = true; - break; - } + if (conditionResult[0] || conditionResult[1]) { + if (conditionResult[0] != conditionResult[1]) { + return conditionResult[1] ? + defTrue : defFalse; + } + return defNone; } - - if (isRecursive) { - continue; + return defFalseEitherCase; + } + for (i = 0; i < this.arguments.length; i++) { + arg = this.arguments[i]; + argValue = arg.value.eval(context); + if (arg.expand && Array.isArray(argValue.value)) { + argValue = argValue.value; + for (m = 0; m < argValue.length; m++) { + args.push({ value: argValue[m] }); + } } - - if (mixin.matchArgs(args, context)) { - candidate = { - mixin, - group: calcDefGroup(mixin, mixinPath) - }; - - if (candidate.group !== defFalseEitherCase) { - candidates.push(candidate); - } - - match = true; + else { + args.push({ name: arg.name, value: argValue }); } - } - - defaultFunc.reset(); - count = [0, 0, 0]; - - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - - if (count[defTrue] + count[defFalse] > 1) { - throw { - type: 'Runtime', - message: `Ambiguous use of \`default()\` found when matching for \`${this.format(args)}\``, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - - if (candidate === defNone || candidate === defaultResult) { - try { - mixin = candidates[m].mixin; - - if (!(mixin instanceof Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); - mixin.originalRuleset = originalRuleset; + } + noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); }; + for (i = 0; i < context.frames.length; i++) { + if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { + isOneFound = true; + // To make `default()` function independent of definition order we have two "subpasses" here. + // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), + // and build candidate list with corresponding flags. Then, when we know all possible matches, + // we make a final decision. + for (m = 0; m < mixins.length; m++) { + mixin = mixins[m].rule; + mixinPath = mixins[m].path; + isRecursive = false; + for (f = 0; f < context.frames.length; f++) { + if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { + isRecursive = true; + break; + } + } + if (isRecursive) { + continue; + } + if (mixin.matchArgs(args, context)) { + candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) }; + if (candidate.group !== defFalseEitherCase) { + candidates.push(candidate); + } + match = true; + } + } + defaultFunc.reset(); + count = [0, 0, 0]; + for (m = 0; m < candidates.length; m++) { + count[candidates[m].group]++; + } + if (count[defNone] > 0) { + defaultResult = defFalse; + } + else { + defaultResult = defTrue; + if ((count[defTrue] + count[defFalse]) > 1) { + throw { type: 'Runtime', + message: "Ambiguous use of `default()` found when matching for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; + } + } + for (m = 0; m < candidates.length; m++) { + candidate = candidates[m].group; + if ((candidate === defNone) || (candidate === defaultResult)) { + try { + mixin = candidates[m].mixin; + if (!(mixin instanceof Definition)) { + originalRuleset = mixin.originalRuleset || mixin; + mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); + mixin.originalRuleset = originalRuleset; + } + var newRules = mixin.evalCall(context, args, this.important).rules; + this._setVisibilityToReplacement(newRules); + Array.prototype.push.apply(rules, newRules); + } + catch (e) { + throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack }; + } + } + } + if (match) { + return rules; } - - var newRules = mixin.evalCall(context, args, this.important).rules; - - this._setVisibilityToReplacement(newRules); - - Array.prototype.push.apply(rules, newRules); - } catch (e) { - throw { - message: e.message, - index: this.getIndex(), - filename: this.fileInfo().filename, - stack: e.stack - }; - } } - } - - if (match) { - return rules; - } } - } - - if (isOneFound) { - throw { - type: 'Runtime', - message: `No matching definition was found for \`${this.format(args)}\``, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } else { - throw { - type: 'Name', - message: `${this.selector.toCSS().trim()} is undefined`, - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - }, { - key: "_setVisibilityToReplacement", - value: function _setVisibilityToReplacement(replacement) { - var i; - var rule; - - if (this.blocksVisibility()) { - for (i = 0; i < replacement.length; i++) { - rule = replacement[i]; - rule.addVisibilityBlock(); - } - } - } - }, { - key: "format", - value: function format(args) { - return `${this.selector.toCSS().trim()}(${args ? args.map(function (a) { - var argValue = ''; - - if (a.name) { - argValue += `${a.name}:`; + if (isOneFound) { + throw { type: 'Runtime', + message: "No matching definition was found for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; } - - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += '???'; + else { + throw { type: 'Name', + message: this.selector.toCSS().trim() + " is undefined", + index: this.getIndex(), filename: this.fileInfo().filename }; } + }; + MixinCall.prototype._setVisibilityToReplacement = function (replacement) { + var i; + var rule; + if (this.blocksVisibility()) { + for (i = 0; i < replacement.length; i++) { + rule = replacement[i]; + rule.addVisibilityBlock(); + } + } + }; + MixinCall.prototype.format = function (args) { + return this.selector.toCSS().trim() + "(" + (args ? args.map(function (a) { + var argValue = ''; + if (a.name) { + argValue += a.name + ":"; + } + if (a.value.toCSS) { + argValue += a.value.toCSS(); + } + else { + argValue += '???'; + } + return argValue; + }).join(', ') : '') + ")"; + }; + return MixinCall; +}(Node)); +MixinCall.prototype.type = 'MixinCall'; - return argValue; - }).join(', ') : ''})`; - } - }]); - - return MixinCall; -}(Node); - -MixinCall.prototype.type = 'MixinCall'; - -var tree = { - Node, - Color, - AtRule, - DetachedRuleset, - Operation, - Dimension, - Unit, - Keyword, - Variable, - Property, - Ruleset, - Element, - Attribute, - Combinator, - Selector, - Quoted, - Expression, - Declaration, - Call, - URL, - Import, - Comment, - Anonymous, - Value, - JavaScript, - Assignment, - Condition, - Paren, - Media, - UnicodeDescriptor, - Negative, - Extend, - VariableCall, - NamespaceValue, - mixin: { - Call: MixinCall, - Definition: Definition - } -}; - -var environment$1 = -/*#__PURE__*/ -function () { - function environment(externalEnvironment, fileManagers) { - _classCallCheck(this, environment); - - this.fileManagers = fileManagers || []; - externalEnvironment = externalEnvironment || {}; - var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; - var requiredFunctions = []; - var functions = requiredFunctions.concat(optionalFunctions); - - for (var i = 0; i < functions.length; i++) { - var propName = functions[i]; - var environmentFunc = externalEnvironment[propName]; - - if (environmentFunc) { - this[propName] = environmentFunc.bind(externalEnvironment); - } else if (i < requiredFunctions.length) { - this.warn(`missing required function in environment - ${propName}`); - } +var tree = { + Node: Node, Color: Color, AtRule: AtRule, DetachedRuleset: DetachedRuleset, Operation: Operation, + Dimension: Dimension, Unit: Unit, Keyword: Keyword, Variable: Variable, Property: Property, + Ruleset: Ruleset, Element: Element, Attribute: Attribute, Combinator: Combinator, Selector: Selector, + Quoted: Quoted, Expression: Expression, Declaration: Declaration, Call: Call, URL: URL, Import: Import, + Comment: Comment, Anonymous: Anonymous, Value: Value, JavaScript: JavaScript, Assignment: Assignment, + Condition: Condition, Paren: Paren, Media: Media, UnicodeDescriptor: UnicodeDescriptor, Negative: Negative, + Extend: Extend, VariableCall: VariableCall, NamespaceValue: NamespaceValue, + mixin: { + Call: MixinCall, + Definition: Definition } - } - - _createClass(environment, [{ - key: "getFileManager", - value: function getFileManager(filename, currentDirectory, options, environment, isSync) { - if (!filename) { - logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); - } - - if (currentDirectory == null) { - logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); - } - - var fileManagers = this.fileManagers; - - if (options.pluginManager) { - fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); - } - - for (var i = fileManagers.length - 1; i >= 0; i--) { - var fileManager = fileManagers[i]; +}; - if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { - return fileManager; +/** + * @todo Document why this abstraction exists, and the relationship between + * environment, file managers, and plugin manager + */ +var environment$1 = /** @class */ (function () { + function environment(externalEnvironment, fileManagers) { + this.fileManagers = fileManagers || []; + externalEnvironment = externalEnvironment || {}; + var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; + var requiredFunctions = []; + var functions = requiredFunctions.concat(optionalFunctions); + for (var i_1 = 0; i_1 < functions.length; i_1++) { + var propName = functions[i_1]; + var environmentFunc = externalEnvironment[propName]; + if (environmentFunc) { + this[propName] = environmentFunc.bind(externalEnvironment); + } + else if (i_1 < requiredFunctions.length) { + this.warn("missing required function in environment - " + propName); + } } - } - - return null; - } - }, { - key: "addFileManager", - value: function addFileManager(fileManager) { - this.fileManagers.push(fileManager); } - }, { - key: "clearFileManagers", - value: function clearFileManagers() { - this.fileManagers = []; - } - }]); - - return environment; -}(); - -var AbstractPluginLoader = -/*#__PURE__*/ -function () { - function AbstractPluginLoader() { - _classCallCheck(this, AbstractPluginLoader); - - // Implemented by Node.js plugin loader - this.require = function () { - return null; + environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) { + if (!filename) { + logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); + } + if (currentDirectory == null) { + logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); + } + var fileManagers = this.fileManagers; + if (options.pluginManager) { + fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); + } + for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) { + var fileManager = fileManagers[i_2]; + if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { + return fileManager; + } + } + return null; }; - } - - _createClass(AbstractPluginLoader, [{ - key: "evalPlugin", - value: function evalPlugin(contents, context, imports, pluginOptions, fileInfo) { - var loader; - var registry; - var pluginObj; - var localModule; - var pluginManager; - var filename; - var result; - pluginManager = context.pluginManager; - - if (fileInfo) { - if (typeof fileInfo === 'string') { - filename = fileInfo; - } else { - filename = fileInfo.filename; + environment.prototype.addFileManager = function (fileManager) { + this.fileManagers.push(fileManager); + }; + environment.prototype.clearFileManagers = function () { + this.fileManagers = []; + }; + return environment; +}()); + +var AbstractPluginLoader = /** @class */ (function () { + function AbstractPluginLoader() { + // Implemented by Node.js plugin loader + this.require = function () { return null; }; + } + AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) { + var loader; + var registry; + var pluginObj; + var localModule; + var pluginManager; + var filename; + var result; + pluginManager = context.pluginManager; + if (fileInfo) { + if (typeof fileInfo === 'string') { + filename = fileInfo; + } + else { + filename = fileInfo.filename; + } } - } - - var shortname = new this.less.FileManager().extractUrlParts(filename).filename; - - if (filename) { - pluginObj = pluginManager.get(filename); - - if (pluginObj) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - - try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); + var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename; + if (filename) { + pluginObj = pluginManager.get(filename); + if (pluginObj) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + return pluginObj; } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - - return pluginObj; } - } - - localModule = { - exports: {}, - pluginManager, - fileInfo - }; - registry = functionRegistry.create(); - - var registerPlugin = function registerPlugin(obj) { - pluginObj = obj; - }; - - try { - loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); - loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); - } catch (e) { - return new LessError(e, imports, filename); - } - - if (!pluginObj) { - pluginObj = localModule.exports; - } - - pluginObj = this.validatePlugin(pluginObj, filename, shortname); - - if (pluginObj instanceof LessError) { - return pluginObj; - } - - if (pluginObj) { - pluginObj.imports = imports; - pluginObj.filename = filename; // For < 3.x (or unspecified minVersion) - setOptions() before install() - - if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - } // Run on first load - - - pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); - pluginObj.functions = registry.getLocalFunctions(); // Need to call setOptions again because the pluginObj might have functions - - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } // Run every @plugin call - - + localModule = { + exports: {}, + pluginManager: pluginManager, + fileInfo: fileInfo + }; + registry = functionRegistry.create(); + var registerPlugin = function (obj) { + pluginObj = obj; + }; try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); - } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - } else { - return new LessError({ - message: 'Not a valid plugin' - }, imports, filename); - } - - return pluginObj; - } - }, { - key: "trySetOptions", - value: function trySetOptions(plugin, filename, name, options) { - if (options && !plugin.setOptions) { - return new LessError({ - message: `Options have been provided but the plugin ${name} does not support any options.` - }); - } - - try { - plugin.setOptions && plugin.setOptions(options); - } catch (e) { - return new LessError(e); - } - } - }, { - key: "validatePlugin", - value: function validatePlugin(plugin, filename, name) { - if (plugin) { - // support plugins being a function - // so that the plugin can be more usable programmatically - if (typeof plugin === 'function') { - plugin = new plugin(); + loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); + loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); } - - if (plugin.minVersion) { - if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + catch (e) { + return new LessError(e, imports, filename); + } + if (!pluginObj) { + pluginObj = localModule.exports; + } + pluginObj = this.validatePlugin(pluginObj, filename, shortname); + if (pluginObj instanceof LessError) { + return pluginObj; + } + if (pluginObj) { + pluginObj.imports = imports; + pluginObj.filename = filename; + // For < 3.x (or unspecified minVersion) - setOptions() before install() + if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + } + // Run on first load + pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); + pluginObj.functions = registry.getLocalFunctions(); + // Need to call setOptions again because the pluginObj might have functions + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + // Run every @plugin call + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + } + else { + return new LessError({ message: 'Not a valid plugin' }, imports, filename); + } + return pluginObj; + }; + AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) { + if (options && !plugin.setOptions) { return new LessError({ - message: `Plugin ${name} requires version ${this.versionToString(plugin.minVersion)}` + message: "Options have been provided but the plugin " + name + " does not support any options." }); - } } - - return plugin; - } - - return null; - } - }, { - key: "compareVersion", - value: function compareVersion(aVersion, bVersion) { - if (typeof aVersion === 'string') { - aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); - aVersion.shift(); - } - - for (var i = 0; i < aVersion.length; i++) { - if (aVersion[i] !== bVersion[i]) { - return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1; + try { + plugin.setOptions && plugin.setOptions(options); } - } - - return 0; - } - }, { - key: "versionToString", - value: function versionToString(version) { - var versionString = ''; - - for (var i = 0; i < version.length; i++) { - versionString += (versionString ? '.' : '') + version[i]; - } - - return versionString; - } - }, { - key: "printUsage", - value: function printUsage(plugins) { - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; - - if (plugin.printUsage) { - plugin.printUsage(); + catch (e) { + return new LessError(e); } - } - } - }]); - - return AbstractPluginLoader; -}(); + }; + AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) { + if (plugin) { + // support plugins being a function + // so that the plugin can be more usable programmatically + if (typeof plugin === 'function') { + plugin = new plugin(); + } + if (plugin.minVersion) { + if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + return new LessError({ + message: "Plugin " + name + " requires version " + this.versionToString(plugin.minVersion) + }); + } + } + return plugin; + } + return null; + }; + AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) { + if (typeof aVersion === 'string') { + aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); + aVersion.shift(); + } + for (var i_1 = 0; i_1 < aVersion.length; i_1++) { + if (aVersion[i_1] !== bVersion[i_1]) { + return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1; + } + } + return 0; + }; + AbstractPluginLoader.prototype.versionToString = function (version) { + var versionString = ''; + for (var i_2 = 0; i_2 < version.length; i_2++) { + versionString += (versionString ? '.' : '') + version[i_2]; + } + return versionString; + }; + AbstractPluginLoader.prototype.printUsage = function (plugins) { + for (var i_3 = 0; i_3 < plugins.length; i_3++) { + var plugin = plugins[i_3]; + if (plugin.printUsage) { + plugin.printUsage(); + } + } + }; + return AbstractPluginLoader; +}()); -var _visitArgs = { - visitDeeper: true -}; +var _visitArgs = { visitDeeper: true }; var _hasIndexed = false; - function _noop(node) { - return node; + return node; } - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key; - var child; - - for (key in parent) { - /* eslint guard-for-in: 0 */ - child = parent[key]; - - switch (typeof child) { - case 'function': - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; + // add .typeIndex to tree node types for lookup table + var key; + var child; + for (key in parent) { + /* eslint guard-for-in: 0 */ + child = parent[key]; + switch (typeof child) { + case 'function': + // ignore bound functions directly on tree which do not have a prototype + // or aren't nodes + if (child.prototype && child.prototype.type) { + child.prototype.typeIndex = ticker++; + } + break; + case 'object': + ticker = indexNodeTypes(child, ticker); + break; } - - break; - - case 'object': - ticker = indexNodeTypes(child, ticker); - break; } - } - - return ticker; + return ticker; } - -var Visitor = -/*#__PURE__*/ -function () { - function Visitor(implementation) { - _classCallCheck(this, Visitor); - - this._implementation = implementation; - this._visitInCache = {}; - this._visitOutCache = {}; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - } - - _createClass(Visitor, [{ - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - - if (!nodeTypeIndex) { - // MixinCall args aren't a node type? - if (node.value && node.value.typeIndex) { - this.visit(node.value); - } - - return node; - } - - var impl = this._implementation; - var func = this._visitInCache[nodeTypeIndex]; - var funcOut = this._visitOutCache[nodeTypeIndex]; - var visitArgs = _visitArgs; - var fnName; - visitArgs.visitDeeper = true; - - if (!func) { - fnName = `visit${node.type}`; - func = impl[fnName] || _noop; - funcOut = impl[`${fnName}Out`] || _noop; - this._visitInCache[nodeTypeIndex] = func; - this._visitOutCache[nodeTypeIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - - if (node && impl.isReplacing) { - node = newNode; +var Visitor = /** @class */ (function () { + function Visitor(implementation) { + this._implementation = implementation; + this._visitInCache = {}; + this._visitOutCache = {}; + if (!_hasIndexed) { + indexNodeTypes(tree, 1); + _hasIndexed = true; + } + } + Visitor.prototype.visit = function (node) { + if (!node) { + return node; + } + var nodeTypeIndex = node.typeIndex; + if (!nodeTypeIndex) { + // MixinCall args aren't a node type? + if (node.value && node.value.typeIndex) { + this.visit(node.value); + } + return node; + } + var impl = this._implementation; + var func = this._visitInCache[nodeTypeIndex]; + var funcOut = this._visitOutCache[nodeTypeIndex]; + var visitArgs = _visitArgs; + var fnName; + visitArgs.visitDeeper = true; + if (!func) { + fnName = "visit" + node.type; + func = impl[fnName] || _noop; + funcOut = impl[fnName + "Out"] || _noop; + this._visitInCache[nodeTypeIndex] = func; + this._visitOutCache[nodeTypeIndex] = funcOut; + } + if (func !== _noop) { + var newNode = func.call(impl, node, visitArgs); + if (node && impl.isReplacing) { + node = newNode; + } } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - } - }, { - key: "visitArray", - value: function visitArray(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; // Non-replacing - - if (nonReplacing || !this._implementation.isReplacing) { - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); + if (visitArgs.visitDeeper && node) { + if (node.length) { + for (var i = 0, cnt = node.length; i < cnt; i++) { + if (node[i].accept) { + node[i].accept(this); + } + } + } + else if (node.accept) { + node.accept(this); + } } - - return nodes; - } // Replacing - - - var out = []; - - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - - if (evald === undefined) { - continue; + if (funcOut != _noop) { + funcOut.call(impl, node); } - - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); + return node; + }; + Visitor.prototype.visitArray = function (nodes, nonReplacing) { + if (!nodes) { + return nodes; } - } - - return out; - } - }, { - key: "flatten", - value: function flatten(arr, out) { - if (!out) { - out = []; - } - - var cnt; - var i; - var item; - var nestedCnt; - var j; - var nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - - if (item === undefined) { - continue; + var cnt = nodes.length; + var i; + // Non-replacing + if (nonReplacing || !this._implementation.isReplacing) { + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); + } + return nodes; } - - if (!item.splice) { - out.push(item); - continue; + // Replacing + var out = []; + for (i = 0; i < cnt; i++) { + var evald = this.visit(nodes[i]); + if (evald === undefined) { + continue; + } + if (!evald.splice) { + out.push(evald); + } + else if (evald.length) { + this.flatten(evald, out); + } } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - - if (nestedItem === undefined) { - continue; - } - - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } + return out; + }; + Visitor.prototype.flatten = function (arr, out) { + if (!out) { + out = []; } - } - - return out; - } - }]); - - return Visitor; -}(); - -var ImportSequencer = -/*#__PURE__*/ -function () { - function ImportSequencer(onSequencerEmpty) { - _classCallCheck(this, ImportSequencer); - - this.imports = []; - this.variableImports = []; - this._onSequencerEmpty = onSequencerEmpty; - this._currentDepth = 0; - } - - _createClass(ImportSequencer, [{ - key: "addImport", - value: function addImport(callback) { - var importSequencer = this; - var importItem = { - callback, - args: null, - isReady: false - }; - this.imports.push(importItem); - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; + var cnt; + var i; + var item; + var nestedCnt; + var j; + var nestedItem; + for (i = 0, cnt = arr.length; i < cnt; i++) { + item = arr[i]; + if (item === undefined) { + continue; + } + if (!item.splice) { + out.push(item); + continue; + } + for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { + nestedItem = item[j]; + if (nestedItem === undefined) { + continue; + } + if (!nestedItem.splice) { + out.push(nestedItem); + } + else if (nestedItem.length) { + this.flatten(nestedItem, out); + } + } } - - importItem.args = Array.prototype.slice.call(args, 0); - importItem.isReady = true; - importSequencer.tryRun(); - }; - } - }, { - key: "addVariableImport", - value: function addVariableImport(callback) { - this.variableImports.push(callback); - } - }, { - key: "tryRun", - value: function tryRun() { - this._currentDepth++; - - try { - while (true) { - while (this.imports.length > 0) { - var importItem = this.imports[0]; - - if (!importItem.isReady) { - return; + return out; + }; + return Visitor; +}()); + +var ImportSequencer = /** @class */ (function () { + function ImportSequencer(onSequencerEmpty) { + this.imports = []; + this.variableImports = []; + this._onSequencerEmpty = onSequencerEmpty; + this._currentDepth = 0; + } + ImportSequencer.prototype.addImport = function (callback) { + var importSequencer = this; + var importItem = { + callback: callback, + args: null, + isReady: false + }; + this.imports.push(importItem); + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + importItem.args = Array.prototype.slice.call(args, 0); + importItem.isReady = true; + importSequencer.tryRun(); + }; + }; + ImportSequencer.prototype.addVariableImport = function (callback) { + this.variableImports.push(callback); + }; + ImportSequencer.prototype.tryRun = function () { + this._currentDepth++; + try { + while (true) { + while (this.imports.length > 0) { + var importItem = this.imports[0]; + if (!importItem.isReady) { + return; + } + this.imports = this.imports.slice(1); + importItem.callback.apply(null, importItem.args); + } + if (this.variableImports.length === 0) { + break; + } + var variableImport = this.variableImports[0]; + this.variableImports = this.variableImports.slice(1); + variableImport(); } - - this.imports = this.imports.slice(1); - importItem.callback.apply(null, importItem.args); - } - - if (this.variableImports.length === 0) { - break; - } - - var variableImport = this.variableImports[0]; - this.variableImports = this.variableImports.slice(1); - variableImport(); } - } finally { - this._currentDepth--; - } - - if (this._currentDepth === 0 && this._onSequencerEmpty) { - this._onSequencerEmpty(); - } - } - }]); - - return ImportSequencer; -}(); + finally { + this._currentDepth--; + } + if (this._currentDepth === 0 && this._onSequencerEmpty) { + this._onSequencerEmpty(); + } + }; + return ImportSequencer; +}()); -var ImportVisitor = function ImportVisitor(importer, finish) { - this._visitor = new Visitor(this); - this._importer = importer; - this._finish = finish; - this.context = new contexts.Eval(); - this.importCount = 0; - this.onceFileDetectionMap = {}; - this.recursionDetector = {}; - this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); +var ImportVisitor = function (importer, finish) { + this._visitor = new Visitor(this); + this._importer = importer; + this._finish = finish; + this.context = new contexts.Eval(); + this.importCount = 0; + this.onceFileDetectionMap = {}; + this.recursionDetector = {}; + this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); }; - ImportVisitor.prototype = { - isReplacing: false, - run: function run(root) { - try { - // process the contents - this._visitor.visit(root); - } catch (e) { - this.error = e; - } - - this.isFinished = true; - - this._sequencer.tryRun(); - }, - _onSequencerEmpty: function _onSequencerEmpty() { - if (!this.isFinished) { - return; - } - - this._finish(this.error); - }, - visitImport: function visitImport(importNode, visitArgs) { - var inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - var context = new contexts.Eval(this.context, copyArray(this.context.frames)); - var importParent = context.frames[0]; - this.importCount++; - - if (importNode.isVariableImport()) { - this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); - } else { - this.processImportNode(importNode, context, importParent); - } - } - - visitArgs.visitDeeper = false; - }, - processImportNode: function processImportNode(importNode, context, importParent) { - var evaldImportNode; - var inlineCSS = importNode.options.inline; - - try { - evaldImportNode = importNode.evalForImport(context); - } catch (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } // attempt to eval properly and treat as css - - - importNode.css = true; // if that fails, this error will be thrown - - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - if (evaldImportNode.options.multiple) { - context.importMultiple = true; - } // try appending if we haven't determined if it is css or not - - - var tryAppendLessExtension = evaldImportNode.css === undefined; - - for (var i = 0; i < importParent.rules.length; i++) { - if (importParent.rules[i] === importNode) { - importParent.rules[i] = evaldImportNode; - break; + isReplacing: false, + run: function (root) { + try { + // process the contents + this._visitor.visit(root); } - } - - var onImported = this.onImported.bind(this, evaldImportNode, context); - - var sequencedOnImported = this._sequencer.addImport(onImported); - - this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); - } else { - this.importCount--; - - if (this.isFinished) { + catch (e) { + this.error = e; + } + this.isFinished = true; this._sequencer.tryRun(); - } - } - }, - onImported: function onImported(importNode, context, e, root, importedAtRoot, fullPath) { - if (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } - - this.error = e; - } - - var importVisitor = this; - var inlineCSS = importNode.options.inline; - var isPlugin = importNode.options.isPlugin; - var isOptional = importNode.options.optional; - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - - if (!context.importMultiple) { - if (duplicateImport) { - importNode.skip = true; - } else { - importNode.skip = function () { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - if (!fullPath && isOptional) { - importNode.skip = true; - } - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - - if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - var oldContext = this.context; - this.context = context; - + }, + _onSequencerEmpty: function () { + if (!this.isFinished) { + return; + } + this._finish(this.error); + }, + visitImport: function (importNode, visitArgs) { + var inlineCSS = importNode.options.inline; + if (!importNode.css || inlineCSS) { + var context = new contexts.Eval(this.context, copyArray(this.context.frames)); + var importParent = context.frames[0]; + this.importCount++; + if (importNode.isVariableImport()) { + this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); + } + else { + this.processImportNode(importNode, context, importParent); + } + } + visitArgs.visitDeeper = false; + }, + processImportNode: function (importNode, context, importParent) { + var evaldImportNode; + var inlineCSS = importNode.options.inline; try { - this._visitor.visit(root); - } catch (e) { - this.error = e; + evaldImportNode = importNode.evalForImport(context); } - - this.context = oldContext; - } + catch (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + // attempt to eval properly and treat as css + importNode.css = true; + // if that fails, this error will be thrown + importNode.error = e; + } + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { + if (evaldImportNode.options.multiple) { + context.importMultiple = true; + } + // try appending if we haven't determined if it is css or not + var tryAppendLessExtension = evaldImportNode.css === undefined; + for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) { + if (importParent.rules[i_1] === importNode) { + importParent.rules[i_1] = evaldImportNode; + break; + } + } + var onImported = this.onImported.bind(this, evaldImportNode, context); + var sequencedOnImported = this._sequencer.addImport(onImported); + this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); + } + else { + this.importCount--; + if (this.isFinished) { + this._sequencer.tryRun(); + } + } + }, + onImported: function (importNode, context, e, root, importedAtRoot, fullPath) { + if (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + this.error = e; + } + var importVisitor = this; + var inlineCSS = importNode.options.inline; + var isPlugin = importNode.options.isPlugin; + var isOptional = importNode.options.optional; + var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; + if (!context.importMultiple) { + if (duplicateImport) { + importNode.skip = true; + } + else { + importNode.skip = function () { + if (fullPath in importVisitor.onceFileDetectionMap) { + return true; + } + importVisitor.onceFileDetectionMap[fullPath] = true; + return false; + }; + } + } + if (!fullPath && isOptional) { + importNode.skip = true; + } + if (root) { + importNode.root = root; + importNode.importedFilename = fullPath; + if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { + importVisitor.recursionDetector[fullPath] = true; + var oldContext = this.context; + this.context = context; + try { + this._visitor.visit(root); + } + catch (e) { + this.error = e; + } + this.context = oldContext; + } + } + importVisitor.importCount--; + if (importVisitor.isFinished) { + importVisitor._sequencer.tryRun(); + } + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.unshift(declNode); + } + else { + visitArgs.visitDeeper = false; + } + }, + visitDeclarationOut: function (declNode) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.shift(); + } + }, + visitAtRule: function (atRuleNode, visitArgs) { + this.context.frames.unshift(atRuleNode); + }, + visitAtRuleOut: function (atRuleNode) { + this.context.frames.shift(); + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + this.context.frames.unshift(mixinDefinitionNode); + }, + visitMixinDefinitionOut: function (mixinDefinitionNode) { + this.context.frames.shift(); + }, + visitRuleset: function (rulesetNode, visitArgs) { + this.context.frames.unshift(rulesetNode); + }, + visitRulesetOut: function (rulesetNode) { + this.context.frames.shift(); + }, + visitMedia: function (mediaNode, visitArgs) { + this.context.frames.unshift(mediaNode.rules[0]); + }, + visitMediaOut: function (mediaNode) { + this.context.frames.shift(); } - - importVisitor.importCount--; - - if (importVisitor.isFinished) { - importVisitor._sequencer.tryRun(); - } - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.unshift(declNode); - } else { - visitArgs.visitDeeper = false; - } - }, - visitDeclarationOut: function visitDeclarationOut(declNode) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.shift(); - } - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - this.context.frames.unshift(atRuleNode); - }, - visitAtRuleOut: function visitAtRuleOut(atRuleNode) { - this.context.frames.shift(); - }, - visitMixinDefinition: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - this.context.frames.unshift(mixinDefinitionNode); - }, - visitMixinDefinitionOut: function visitMixinDefinitionOut(mixinDefinitionNode) { - this.context.frames.shift(); - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - this.context.frames.unshift(rulesetNode); - }, - visitRulesetOut: function visitRulesetOut(rulesetNode) { - this.context.frames.shift(); - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - this.context.frames.unshift(mediaNode.rules[0]); - }, - visitMediaOut: function visitMediaOut(mediaNode) { - this.context.frames.shift(); - } }; -var SetTreeVisibilityVisitor = -/*#__PURE__*/ -function () { - function SetTreeVisibilityVisitor(visible) { - _classCallCheck(this, SetTreeVisibilityVisitor); - - this.visible = visible; - } - - _createClass(SetTreeVisibilityVisitor, [{ - key: "run", - value: function run(root) { - this.visit(root); - } - }, { - key: "visitArray", - value: function visitArray(nodes) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; - - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - - return nodes; - } - }, { - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - if (node.constructor === Array) { - return this.visitArray(node); - } - - if (!node.blocksVisibility || node.blocksVisibility()) { - return node; - } - - if (this.visible) { - node.ensureVisibility(); - } else { - node.ensureInvisibility(); - } - - node.accept(this); - return node; +var SetTreeVisibilityVisitor = /** @class */ (function () { + function SetTreeVisibilityVisitor(visible) { + this.visible = visible; } - }]); - - return SetTreeVisibilityVisitor; -}(); - -/* jshint loopfunc:true */ - -var ExtendFinderVisitor = -/*#__PURE__*/ -function () { - function ExtendFinderVisitor() { - _classCallCheck(this, ExtendFinderVisitor); - - this._visitor = new Visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - } - - _createClass(ExtendFinderVisitor, [{ - key: "run", - value: function run(root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i; - var j; - var extend; - var allSelectorsExtendList = []; - var extendList; // get &:extend(.a); rules which apply to all selectors in this ruleset - - var rules = rulesetNode.rules; - var ruleCnt = rules ? rules.length : 0; - - for (i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; + SetTreeVisibilityVisitor.prototype.run = function (root) { + this.visit(root); + }; + SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) { + if (!nodes) { + return nodes; } - } // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - - - var paths = rulesetNode.paths; - - for (i = 0; i < paths.length; i++) { - var selectorPath = paths[i]; - var selector = selectorPath[selectorPath.length - 1]; - var selExtendList = selector.extendList; - extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function (allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); + var cnt = nodes.length; + var i; + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); } - - for (j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - - if (j === 0) { - extend.firstExtendOnThisSelectorPath = true; - } - - this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); + return nodes; + }; + SetTreeVisibilityVisitor.prototype.visit = function (node) { + if (!node) { + return node; } - } - - this.contexts.push(rulesetNode.selectors); - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - atRuleNode.allExtends = []; - this.allExtendsStack.push(atRuleNode.allExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }]); - - return ExtendFinderVisitor; -}(); - -var ProcessExtendsVisitor = -/*#__PURE__*/ -function () { - function ProcessExtendsVisitor() { - _classCallCheck(this, ProcessExtendsVisitor); - - this._visitor = new Visitor(this); - } - - _createClass(ProcessExtendsVisitor, [{ - key: "run", - value: function run(root) { - var extendFinder = new ExtendFinderVisitor(); - this.extendIndices = {}; - extendFinder.run(root); - - if (!extendFinder.foundExtends) { - return root; - } - - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - - var newRoot = this._visitor.visit(root); - - this.checkExtendsForNonMatched(root.allExtends); - return newRoot; - } - }, { - key: "checkExtendsForNonMatched", - value: function checkExtendsForNonMatched(extendList) { - var indices = this.extendIndices; - extendList.filter(function (extend) { - return !extend.hasFoundMatches && extend.parent_ids.length == 1; - }).forEach(function (extend) { - var selector = '_unknown_'; - - try { - selector = extend.selector.toCSS({}); - } catch (_) {} - - if (!indices[`${extend.index} ${selector}`]) { - indices[`${extend.index} ${selector}`] = true; - logger.warn(`extend '${selector}' has no matches`); - } - }); - } - }, { - key: "doExtendChaining", - value: function doExtendChaining(extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering - // and pasting the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already - // processed if we look at each selector at a time, as is done in visitRuleset - var extendIndex; - var targetExtendIndex; - var matches; - var extendsToAdd = []; - var newSelector; - var extendVisitor = this; - var selectorPath; - var extend; - var targetExtend; - var newExtend; - iterationCount = iterationCount || 0; // loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the separation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - - for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { - for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; // look for circular references - - if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { - continue; - } // find a match in the target extends self selector (the bit before :extend) - - - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - extend.hasFoundMatches = true; // we found a match, so for each self selector.. - - extend.selfSelectors.forEach(function (selfSelector) { - var info = targetExtend.visibilityInfo(); // process the extend as usual - - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); // but now we create a new extend from it - - newExtend = new tree.Extend(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); - newExtend.selfSelectors = newSelector; // add the extend onto the list of extends for that selector - - newSelector[newSelector.length - 1].extendList = [newExtend]; // record that we need to add it. - - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; // remember its parents for circular references - - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } + if (node.constructor === Array) { + return this.visitArray(node); } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - - if (iterationCount > 100) { - var selectorOne = '{unable to calculate}'; - var selectorTwo = '{unable to calculate}'; - - try { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } catch (e) {} - - throw { - message: `extend circular reference detected. One of the circular extends is currently:${selectorOne}:extend(${selectorTwo})` - }; - } // now process the new extends on the existing rules so that we can handle a extending b extending c extending - // d extending e... - - - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); - } else { - return extendsToAdd; - } - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitSelector", - value: function visitSelector(selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var matches; - var pathIndex; - var extendIndex; - var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; - var selectorsToAdd = []; - var extendVisitor = this; - var selectorPath; // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; // extending extends happens initially, before the main pass - - if (rulesetNode.extendOnEveryPath) { - continue; - } - - var extendList = selectorPath[selectorPath.length - 1].extendList; - - if (extendList && extendList.length) { - continue; - } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - allExtends[extendIndex].hasFoundMatches = true; - allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { - var extendedSelectors; - extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); - selectorsToAdd.push(extendedSelectors); - }); - } + if (!node.blocksVisibility || node.blocksVisibility()) { + return node; } - } - - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - } - }, { - key: "findMatch", - value: function findMatch(extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex; - var hackstackSelector; - var hackstackElementIndex; - var haystackElement; - var targetCombinator; - var i; - var extendVisitor = this; - var needleElements = extend.selector.elements; - var potentialMatches = []; - var potentialMatch; - var matches = []; // loop through the haystack elements - - for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - haystackElement = hackstackSelector.elements[hackstackElementIndex]; // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - - if (extend.allowBefore || haystackSelectorIndex === 0 && hackstackElementIndex === 0) { - potentialMatches.push({ - pathIndex: haystackSelectorIndex, - index: hackstackElementIndex, - matched: 0, - initialCombinator: haystackElement.combinator - }); - } - - for (i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to - // work out what the resulting combinator will be - - targetCombinator = haystackElement.combinator.value; - - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } // if we don't match, null our match to indicate failure - - - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } // if we are still valid and have finished, test whether we have elements after and whether these are allowed - - - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - - if (potentialMatch.finished && !extend.allowAfter && (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length)) { - potentialMatch = null; - } - } // if null we remove, if not, we are still valid, so either push as a valid match or continue - - - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; - } - } + if (this.visible) { + node.ensureVisibility(); } - } - - return matches; - } - }, { - key: "isElementValuesEqual", - value: function isElementValuesEqual(elementValue1, elementValue2) { - if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { - return elementValue1 === elementValue2; - } - - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; + else { + node.ensureInvisibility(); } + node.accept(this); + return node; + }; + return SetTreeVisibilityVisitor; +}()); - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - - return true; +/* jshint loopfunc:true */ +var ExtendFinderVisitor = /** @class */ (function () { + function ExtendFinderVisitor() { + this._visitor = new Visitor(this); + this.contexts = []; + this.allExtendsStack = [[]]; + } + ExtendFinderVisitor.prototype.run = function (root) { + root = this._visitor.visit(root); + root.allExtends = this.allExtendsStack[0]; + return root; + }; + ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; + var i; + var j; + var extend; + var allSelectorsExtendList = []; + var extendList; + // get &:extend(.a); rules which apply to all selectors in this ruleset + var rules = rulesetNode.rules; + var ruleCnt = rules ? rules.length : 0; + for (i = 0; i < ruleCnt; i++) { + if (rulesetNode.rules[i] instanceof tree.Extend) { + allSelectorsExtendList.push(rules[i]); + rulesetNode.extendOnEveryPath = true; + } } - - for (var i = 0; i < elementValue1.elements.length; i++) { - if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) { - if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) { - return false; + // now find every selector and apply the extends that apply to all extends + // and the ones which apply to an individual extend + var paths = rulesetNode.paths; + for (i = 0; i < paths.length; i++) { + var selectorPath = paths[i]; + var selector = selectorPath[selectorPath.length - 1]; + var selExtendList = selector.extendList; + extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) + : allSelectorsExtendList; + if (extendList) { + extendList = extendList.map(function (allSelectorsExtend) { return allSelectorsExtend.clone(); }); + } + for (j = 0; j < extendList.length; j++) { + this.foundExtends = true; + extend = extendList[j]; + extend.findSelfSelectors(selectorPath); + extend.ruleset = rulesetNode; + if (j === 0) { + extend.firstExtendOnThisSelectorPath = true; + } + this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); } - } - - if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) { - return false; - } } - - return true; - } - - return false; - } - }, { - key: "extendSelector", - value: function extendSelector(matches, selectorPath, replacementSelector, isVisible) { - // for a set of matches, replace each match with the replacement selector - var currentSelectorPathIndex = 0; - var currentSelectorPathElementIndex = 0; - var path = []; - var matchIndex; - var selector; - var firstElement; - var match; - var newElements; - - for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { - match = matches[matchIndex]; - selector = selectorPath[match.pathIndex]; - firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); - - if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + this.contexts.push(rulesetNode.selectors); + }; + ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) { + if (!rulesetNode.root) { + this.contexts.length = this.contexts.length - 1; } - - newElements = selector.elements.slice(currentSelectorPathElementIndex, match.index).concat([firstElement]).concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - path.push(new tree.Selector(newElements)); + }; + ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + mediaNode.allExtends = []; + this.allExtendsStack.push(mediaNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + atRuleNode.allExtends = []; + this.allExtendsStack.push(atRuleNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + return ExtendFinderVisitor; +}()); +var ProcessExtendsVisitor = /** @class */ (function () { + function ProcessExtendsVisitor() { + this._visitor = new Visitor(this); + } + ProcessExtendsVisitor.prototype.run = function (root) { + var extendFinder = new ExtendFinderVisitor(); + this.extendIndices = {}; + extendFinder.run(root); + if (!extendFinder.foundExtends) { + return root; + } + root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); + this.allExtendsStack = [root.allExtends]; + var newRoot = this._visitor.visit(root); + this.checkExtendsForNonMatched(root.allExtends); + return newRoot; + }; + ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) { + var indices = this.extendIndices; + extendList.filter(function (extend) { return !extend.hasFoundMatches && extend.parent_ids.length == 1; }).forEach(function (extend) { + var selector = '_unknown_'; + try { + selector = extend.selector.toCSS({}); + } + catch (_) { } + if (!indices[extend.index + " " + selector]) { + indices[extend.index + " " + selector] = true; + logger.warn("extend '" + selector + "' has no matches"); + } + }); + }; + ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) { + // + // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering + // and pasting the selector we would do normally, but we are also adding an extend with the same target selector + // this means this new extend can then go and alter other extends + // + // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors + // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already + // processed if we look at each selector at a time, as is done in visitRuleset + var extendIndex; + var targetExtendIndex; + var matches; + var extendsToAdd = []; + var newSelector; + var extendVisitor = this; + var selectorPath; + var extend; + var targetExtend; + var newExtend; + iterationCount = iterationCount || 0; + // loop through comparing every extend with every target extend. + // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place + // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one + // and the second is the target. + // the separation into two lists allows us to process a subset of chains with a bigger set, as is the + // case when processing media queries + for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { + for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { + extend = extendsList[extendIndex]; + targetExtend = extendsListTarget[targetExtendIndex]; + // look for circular references + if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { + continue; + } + // find a match in the target extends self selector (the bit before :extend) + selectorPath = [targetExtend.selfSelectors[0]]; + matches = extendVisitor.findMatch(extend, selectorPath); + if (matches.length) { + extend.hasFoundMatches = true; + // we found a match, so for each self selector.. + extend.selfSelectors.forEach(function (selfSelector) { + var info = targetExtend.visibilityInfo(); + // process the extend as usual + newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); + // but now we create a new extend from it + newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); + newExtend.selfSelectors = newSelector; + // add the extend onto the list of extends for that selector + newSelector[newSelector.length - 1].extendList = [newExtend]; + // record that we need to add it. + extendsToAdd.push(newExtend); + newExtend.ruleset = targetExtend.ruleset; + // remember its parents for circular references + newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); + // only process the selector once.. if we have :extend(.a,.b) then multiple + // extends will look at the same selector path, so when extending + // we know that any others will be duplicates in terms of what is added to the css + if (targetExtend.firstExtendOnThisSelectorPath) { + newExtend.firstExtendOnThisSelectorPath = true; + targetExtend.ruleset.paths.push(newSelector); + } + }); + } + } } - - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + if (extendsToAdd.length) { + // try to detect circular references to stop a stack overflow. + // may no longer be needed. + this.extendChainCount++; + if (iterationCount > 100) { + var selectorOne = '{unable to calculate}'; + var selectorTwo = '{unable to calculate}'; + try { + selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); + selectorTwo = extendsToAdd[0].selector.toCSS(); + } + catch (e) { } + throw { message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")" }; + } + // now process the new extends on the existing rules so that we can handle a extending b extending c extending + // d extending e... + return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - path = path.map(function (currentValue) { - // we can re-use elements here, because the visibility property matters only for selectors - var derived = currentValue.createDerived(currentValue.elements); - - if (isVisible) { - derived.ensureVisibility(); - } else { - derived.ensureInvisibility(); + else { + return extendsToAdd; } - - return derived; - }); - return path; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }]); - - return ProcessExtendsVisitor; -}(); - -var JoinSelectorVisitor = -/*#__PURE__*/ -function () { - function JoinSelectorVisitor() { - _classCallCheck(this, JoinSelectorVisitor); - - this.contexts = [[]]; - this._visitor = new Visitor(this); - } - - _createClass(JoinSelectorVisitor, [{ - key: "run", - value: function run(root) { - return this._visitor.visit(root); - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - var paths = []; - var selectors; - this.contexts.push(paths); - - if (!rulesetNode.root) { - selectors = rulesetNode.selectors; - - if (selectors) { - selectors = selectors.filter(function (selector) { - return selector.getIsOutput(); - }); - rulesetNode.selectors = selectors.length ? selectors : selectors = null; - - if (selectors) { - rulesetNode.joinSelectors(paths, context, selectors); - } + }; + ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - if (!selectors) { - rulesetNode.rules = null; + var matches; + var pathIndex; + var extendIndex; + var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; + var selectorsToAdd = []; + var extendVisitor = this; + var selectorPath; + // look at each selector path in the ruleset, find any extend matches and then copy, find and replace + for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { + for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { + selectorPath = rulesetNode.paths[pathIndex]; + // extending extends happens initially, before the main pass + if (rulesetNode.extendOnEveryPath) { + continue; + } + var extendList = selectorPath[selectorPath.length - 1].extendList; + if (extendList && extendList.length) { + continue; + } + matches = this.findMatch(allExtends[extendIndex], selectorPath); + if (matches.length) { + allExtends[extendIndex].hasFoundMatches = true; + allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { + var extendedSelectors; + extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); + selectorsToAdd.push(extendedSelectors); + }); + } + } } - - rulesetNode.paths = paths; - } - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - this.contexts.length = this.contexts.length - 1; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = context.length === 0 || context[0].multiMedia; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - - if (atRuleNode.rules && atRuleNode.rules.length) { - atRuleNode.rules[0].root = atRuleNode.isRooted || context.length === 0 || null; - } - } - }]); - - return JoinSelectorVisitor; -}(); - -var CSSVisitorUtils = -/*#__PURE__*/ -function () { - function CSSVisitorUtils(context) { - _classCallCheck(this, CSSVisitorUtils); - - this._visitor = new Visitor(this); - this._context = context; - } - - _createClass(CSSVisitorUtils, [{ - key: "containsSilentNonBlockedChild", - value: function containsSilentNonBlockedChild(bodyRules) { - var rule; - - if (!bodyRules) { - return false; - } - - for (var r = 0; r < bodyRules.length; r++) { - rule = bodyRules[r]; - - if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { - // the atrule contains something that was referenced (likely by extend) - // therefore it needs to be shown in output too - return true; + rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); + }; + ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) { + // + // look through the haystack selector path to try and find the needle - extend.selector + // returns an array of selector matches that can then be replaced + // + var haystackSelectorIndex; + var hackstackSelector; + var hackstackElementIndex; + var haystackElement; + var targetCombinator; + var i; + var extendVisitor = this; + var needleElements = extend.selector.elements; + var potentialMatches = []; + var potentialMatch; + var matches = []; + // loop through the haystack elements + for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { + hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; + for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { + haystackElement = hackstackSelector.elements[hackstackElementIndex]; + // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. + if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { + potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, + initialCombinator: haystackElement.combinator }); + } + for (i = 0; i < potentialMatches.length; i++) { + potentialMatch = potentialMatches[i]; + // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't + // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to + // work out what the resulting combinator will be + targetCombinator = haystackElement.combinator.value; + if (targetCombinator === '' && hackstackElementIndex === 0) { + targetCombinator = ' '; + } + // if we don't match, null our match to indicate failure + if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || + (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { + potentialMatch = null; + } + else { + potentialMatch.matched++; + } + // if we are still valid and have finished, test whether we have elements after and whether these are allowed + if (potentialMatch) { + potentialMatch.finished = potentialMatch.matched === needleElements.length; + if (potentialMatch.finished && + (!extend.allowAfter && + (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) { + potentialMatch = null; + } + } + // if null we remove, if not, we are still valid, so either push as a valid match or continue + if (potentialMatch) { + if (potentialMatch.finished) { + potentialMatch.length = needleElements.length; + potentialMatch.endPathIndex = haystackSelectorIndex; + potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match + potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again + matches.push(potentialMatch); + } + } + else { + potentialMatches.splice(i, 1); + i--; + } + } + } } - } - - return false; - } - }, { - key: "keepOnlyVisibleChilds", - value: function keepOnlyVisibleChilds(owner) { - if (owner && owner.rules) { - owner.rules = owner.rules.filter(function (thing) { - return thing.isVisible(); - }); - } - } - }, { - key: "isEmpty", - value: function isEmpty(owner) { - return owner && owner.rules ? owner.rules.length === 0 : true; - } - }, { - key: "hasVisibleSelector", - value: function hasVisibleSelector(rulesetNode) { - return rulesetNode && rulesetNode.paths ? rulesetNode.paths.length > 0 : false; - } - }, { - key: "resolveVisibility", - value: function resolveVisibility(node, originalRules) { - if (!node.blocksVisibility()) { - if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { - return; + return matches; + }; + ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) { + if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { + return elementValue1 === elementValue2; + } + if (elementValue1 instanceof tree.Attribute) { + if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { + return false; + } + if (!elementValue1.value || !elementValue2.value) { + if (elementValue1.value || elementValue2.value) { + return false; + } + return true; + } + elementValue1 = elementValue1.value.value || elementValue1.value; + elementValue2 = elementValue2.value.value || elementValue2.value; + return elementValue1 === elementValue2; + } + elementValue1 = elementValue1.value; + elementValue2 = elementValue2.value; + if (elementValue1 instanceof tree.Selector) { + if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { + return false; + } + for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) { + if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) { + if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) { + return false; + } + } + if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) { + return false; + } + } + return true; } - - return node; - } - - var compiledRulesBody = node.rules[0]; - this.keepOnlyVisibleChilds(compiledRulesBody); - - if (this.isEmpty(compiledRulesBody)) { - return; - } - - node.ensureVisibility(); - node.removeVisibilityBlock(); - return node; - } - }, { - key: "isVisibleRuleset", - value: function isVisibleRuleset(rulesetNode) { - if (rulesetNode.firstRoot) { - return true; - } - - if (this.isEmpty(rulesetNode)) { - return false; - } - - if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { return false; - } - - return true; - } - }]); - - return CSSVisitorUtils; -}(); - -var ToCSSVisitor = function ToCSSVisitor(context) { - this._visitor = new Visitor(this); - this._context = context; - this.utils = new CSSVisitorUtils(context); -}; - -ToCSSVisitor.prototype = { - isReplacing: true, - run: function run(root) { - return this._visitor.visit(root); - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.blocksVisibility() || declNode.variable) { - return; - } - - return declNode; - }, - visitMixinDefinition: function visitMixinDefinition(mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - }, - visitExtend: function visitExtend(extendNode, visitArgs) {}, - visitComment: function visitComment(commentNode, visitArgs) { - if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { - return; - } - - return commentNode; - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - var originalRules = mediaNode.rules[0].rules; - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - return this.utils.resolveVisibility(mediaNode, originalRules); - }, - visitImport: function visitImport(importNode, visitArgs) { - if (importNode.blocksVisibility()) { - return; - } - - return importNode; - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - if (atRuleNode.rules && atRuleNode.rules.length) { - return this.visitAtRuleWithBody(atRuleNode, visitArgs); - } else { - return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); - } - }, - visitAnonymous: function visitAnonymous(anonymousNode, visitArgs) { - if (!anonymousNode.blocksVisibility()) { - anonymousNode.accept(this._visitor); - return anonymousNode; - } - }, - visitAtRuleWithBody: function visitAtRuleWithBody(atRuleNode, visitArgs) { - // if there is only one nested ruleset and that one has no path, then it is - // just fake ruleset - function hasFakeRuleset(atRuleNode) { - var bodyRules = atRuleNode.rules; - return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); - } - - function getBodyRules(atRuleNode) { - var nodeRules = atRuleNode.rules; - - if (hasFakeRuleset(atRuleNode)) { - return nodeRules[0].rules; - } - - return nodeRules; - } // it is still true that it is only one ruleset in array - // this is last such moment - // process childs - - - var originalRules = getBodyRules(atRuleNode); - atRuleNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!this.utils.isEmpty(atRuleNode)) { - this._mergeRules(atRuleNode.rules[0].rules); - } - - return this.utils.resolveVisibility(atRuleNode, originalRules); - }, - visitAtRuleWithoutBody: function visitAtRuleWithoutBody(atRuleNode, visitArgs) { - if (atRuleNode.blocksVisibility()) { - return; - } - - if (atRuleNode.name === '@charset') { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset atrule would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (atRuleNode.debugInfo) { - var comment = new tree.Comment(`/* ${atRuleNode.toCSS(this._context).replace(/\n/g, '')} */\n`); - comment.debugInfo = atRuleNode.debugInfo; - return this._visitor.visit(comment); + }; + ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) { + // for a set of matches, replace each match with the replacement selector + var currentSelectorPathIndex = 0; + var currentSelectorPathElementIndex = 0; + var path = []; + var matchIndex; + var selector; + var firstElement; + var match; + var newElements; + for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { + match = matches[matchIndex]; + selector = selectorPath[match.pathIndex]; + firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); + if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + newElements = selector.elements + .slice(currentSelectorPathElementIndex, match.index) + .concat([firstElement]) + .concat(replacementSelector.elements.slice(1)); + if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { + path[path.length - 1].elements = + path[path.length - 1].elements.concat(newElements); + } + else { + path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); + path.push(new tree.Selector(newElements)); + } + currentSelectorPathIndex = match.endPathIndex; + currentSelectorPathElementIndex = match.endPathElementIndex; + if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } } + if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathIndex++; + } + path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); + path = path.map(function (currentValue) { + // we can re-use elements here, because the visibility property matters only for selectors + var derived = currentValue.createDerived(currentValue.elements); + if (isVisible) { + derived.ensureVisibility(); + } + else { + derived.ensureInvisibility(); + } + return derived; + }); + return path; + }; + ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + return ProcessExtendsVisitor; +}()); - return; - } - - this.charset = true; - } - - return atRuleNode; - }, - checkValidNodes: function checkValidNodes(rules, isRoot) { - if (!rules) { - return; +var JoinSelectorVisitor = /** @class */ (function () { + function JoinSelectorVisitor() { + this.contexts = [[]]; + this._visitor = new Visitor(this); } - - for (var i = 0; i < rules.length; i++) { - var ruleNode = rules[i]; - - if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { - throw { - message: 'Properties must be inside selector blocks. They cannot be in the root', - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode instanceof tree.Call) { - throw { - message: `Function '${ruleNode.name}' is undefined`, - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode.type && !ruleNode.allowRoot) { - throw { - message: `${ruleNode.type} node returned by a function is not valid here`, - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - } - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - // at this point rulesets are nested into each other - var rule; - var rulesets = []; - this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); - - if (!rulesetNode.root) { - // remove invisible paths - this._compileRulesetPaths(rulesetNode); // remove rulesets from this ruleset body and compile them separately - - - var nodeRules = rulesetNode.rules; - var nodeRuleCnt = nodeRules ? nodeRules.length : 0; - - for (var i = 0; i < nodeRuleCnt;) { - rule = nodeRules[i]; - - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; + JoinSelectorVisitor.prototype.run = function (root) { + return this._visitor.visit(root); + }; + JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + var paths = []; + var selectors; + this.contexts.push(paths); + if (!rulesetNode.root) { + selectors = rulesetNode.selectors; + if (selectors) { + selectors = selectors.filter(function (selector) { return selector.getIsOutput(); }); + rulesetNode.selectors = selectors.length ? selectors : (selectors = null); + if (selectors) { + rulesetNode.joinSelectors(paths, context, selectors); + } + } + if (!selectors) { + rulesetNode.rules = null; + } + rulesetNode.paths = paths; } + }; + JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) { + this.contexts.length = this.contexts.length - 1; + }; + JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); + }; + JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + if (atRuleNode.rules && atRuleNode.rules.length) { + atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null); + } + }; + return JoinSelectorVisitor; +}()); - i++; - } // accept the visitor to remove rules and refactor itself - // then we can decide nogw whether we want it or not - // compile body - - - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - - visitArgs.visitDeeper = false; - } else { - // if (! rulesetNode.root) { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - } - - if (rulesetNode.rules) { - this._mergeRules(rulesetNode.rules); - - this._removeDuplicateRules(rulesetNode.rules); - } // now decide whether we keep the ruleset - - - if (this.utils.isVisibleRuleset(rulesetNode)) { - rulesetNode.ensureVisibility(); - rulesets.splice(0, 0, rulesetNode); - } - - if (rulesets.length === 1) { - return rulesets[0]; +var CSSVisitorUtils = /** @class */ (function () { + function CSSVisitorUtils(context) { + this._visitor = new Visitor(this); + this._context = context; } - - return rulesets; - }, - _compileRulesetPaths: function _compileRulesetPaths(rulesetNode) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths.filter(function (p) { - var i; - - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new tree.Combinator(''); + CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) { + var rule; + if (!bodyRules) { + return false; } - - for (i = 0; i < p.length; i++) { - if (p[i].isVisible() && p[i].getIsOutput()) { - return true; - } + for (var r = 0; r < bodyRules.length; r++) { + rule = bodyRules[r]; + if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { + // the atrule contains something that was referenced (likely by extend) + // therefore it needs to be shown in output too + return true; + } } - return false; - }); - } - }, - _removeDuplicateRules: function _removeDuplicateRules(rules) { - if (!rules) { - return; - } // remove duplicates - - - var ruleCache = {}; - var ruleList; - var rule; - var i; - - for (i = rules.length - 1; i >= 0; i--) { - rule = rules[i]; - - if (rule instanceof tree.Declaration) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - - if (ruleList instanceof tree.Declaration) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; - } - - var ruleCSS = rule.toCSS(this._context); - - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } + }; + CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) { + if (owner && owner.rules) { + owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); }); } - } - } - }, - _mergeRules: function _mergeRules(rules) { - if (!rules) { - return; - } - - var groups = {}; - var groupsArr = []; - - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - - if (rule.merge) { - var key = rule.name; - groups[key] ? rules.splice(i--, 1) : groupsArr.push(groups[key] = []); - groups[key].push(rule); - } - } - - groupsArr.forEach(function (group) { - if (group.length > 0) { - var result = group[0]; - var space = []; - var comma = [new tree.Expression(space)]; - group.forEach(function (rule) { - if (rule.merge === '+' && space.length > 0) { - comma.push(new tree.Expression(space = [])); - } - - space.push(rule.value); - result.important = result.important || rule.important; - }); - result.value = new tree.Value(comma); - } - }); - } -}; - -var visitors = { - Visitor, - ImportVisitor, - MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, - ExtendVisitor: ProcessExtendsVisitor, - JoinSelectorVisitor, - ToCSSVisitor + }; + CSSVisitorUtils.prototype.isEmpty = function (owner) { + return (owner && owner.rules) + ? (owner.rules.length === 0) : true; + }; + CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) { + return (rulesetNode && rulesetNode.paths) + ? (rulesetNode.paths.length > 0) : false; + }; + CSSVisitorUtils.prototype.resolveVisibility = function (node, originalRules) { + if (!node.blocksVisibility()) { + if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { + return; + } + return node; + } + var compiledRulesBody = node.rules[0]; + this.keepOnlyVisibleChilds(compiledRulesBody); + if (this.isEmpty(compiledRulesBody)) { + return; + } + node.ensureVisibility(); + node.removeVisibilityBlock(); + return node; + }; + CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) { + if (rulesetNode.firstRoot) { + return true; + } + if (this.isEmpty(rulesetNode)) { + return false; + } + if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { + return false; + } + return true; + }; + return CSSVisitorUtils; +}()); +var ToCSSVisitor = function (context) { + this._visitor = new Visitor(this); + this._context = context; + this.utils = new CSSVisitorUtils(context); }; - -// Split the input into chunks. -var chunker = (function (input, fail) { - var len = input.length; - var level = 0; - var parenLevel = 0; - var lastOpening; - var lastOpeningParen; - var lastMultiComment; - var lastMultiCommentEndBrace; - var chunks = []; - var emitFrom = 0; - var chunkerCurrentIndex; - var currentChunkStartIndex; - var cc; - var cc2; - var matched; - - function emitChunk(force) { - var len = chunkerCurrentIndex - emitFrom; - - if (len < 512 && !force || !len) { - return; - } - - chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); - emitFrom = chunkerCurrentIndex + 1; - } - - for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc = input.charCodeAt(chunkerCurrentIndex); - - if (cc >= 97 && cc <= 122 || cc < 34) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: - // ( - parenLevel++; - lastOpeningParen = chunkerCurrentIndex; - continue; - - case 41: - // ) - if (--parenLevel < 0) { - return fail('missing opening `(`', chunkerCurrentIndex); +ToCSSVisitor.prototype = { + isReplacing: true, + run: function (root) { + return this._visitor.visit(root); + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.blocksVisibility() || declNode.variable) { + return; } - - continue; - - case 59: - // ; - if (!parenLevel) { - emitChunk(); + return declNode; + }, + visitMixinDefinition: function (mixinNode, visitArgs) { + // mixin definitions do not get eval'd - this means they keep state + // so we have to clear that state here so it isn't used if toCSS is called twice + mixinNode.frames = []; + }, + visitExtend: function (extendNode, visitArgs) { + }, + visitComment: function (commentNode, visitArgs) { + if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { + return; } - - continue; - - case 123: - // { - level++; - lastOpening = chunkerCurrentIndex; - continue; - - case 125: - // } - if (--level < 0) { - return fail('missing opening `{`', chunkerCurrentIndex); + return commentNode; + }, + visitMedia: function (mediaNode, visitArgs) { + var originalRules = mediaNode.rules[0].rules; + mediaNode.accept(this._visitor); + visitArgs.visitDeeper = false; + return this.utils.resolveVisibility(mediaNode, originalRules); + }, + visitImport: function (importNode, visitArgs) { + if (importNode.blocksVisibility()) { + return; } - - if (!level && !parenLevel) { - emitChunk(); + return importNode; + }, + visitAtRule: function (atRuleNode, visitArgs) { + if (atRuleNode.rules && atRuleNode.rules.length) { + return this.visitAtRuleWithBody(atRuleNode, visitArgs); } - - continue; - - case 92: - // \ - if (chunkerCurrentIndex < len - 1) { - chunkerCurrentIndex++; - continue; + else { + return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); } - - return fail('unescaped `\\`', chunkerCurrentIndex); - - case 34: - case 39: - case 96: - // ", ' and ` - matched = 0; - currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 > 96) { - continue; - } - - if (cc2 == cc) { - matched = 1; - break; - } - - if (cc2 == 92) { - // \ - if (chunkerCurrentIndex == len - 1) { - return fail('unescaped `\\`', chunkerCurrentIndex); + }, + visitAnonymous: function (anonymousNode, visitArgs) { + if (!anonymousNode.blocksVisibility()) { + anonymousNode.accept(this._visitor); + return anonymousNode; + } + }, + visitAtRuleWithBody: function (atRuleNode, visitArgs) { + // if there is only one nested ruleset and that one has no path, then it is + // just fake ruleset + function hasFakeRuleset(atRuleNode) { + var bodyRules = atRuleNode.rules; + return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); + } + function getBodyRules(atRuleNode) { + var nodeRules = atRuleNode.rules; + if (hasFakeRuleset(atRuleNode)) { + return nodeRules[0].rules; } - - chunkerCurrentIndex++; - } + return nodeRules; + } + // it is still true that it is only one ruleset in array + // this is last such moment + // process childs + var originalRules = getBodyRules(atRuleNode); + atRuleNode.accept(this._visitor); + visitArgs.visitDeeper = false; + if (!this.utils.isEmpty(atRuleNode)) { + this._mergeRules(atRuleNode.rules[0].rules); + } + return this.utils.resolveVisibility(atRuleNode, originalRules); + }, + visitAtRuleWithoutBody: function (atRuleNode, visitArgs) { + if (atRuleNode.blocksVisibility()) { + return; } - - if (matched) { - continue; + if (atRuleNode.name === '@charset') { + // Only output the debug info together with subsequent @charset definitions + // a comment (or @media statement) before the actual @charset atrule would + // be considered illegal css as it has to be on the first line + if (this.charset) { + if (atRuleNode.debugInfo) { + var comment = new tree.Comment("/* " + atRuleNode.toCSS(this._context).replace(/\n/g, '') + " */\n"); + comment.debugInfo = atRuleNode.debugInfo; + return this._visitor.visit(comment); + } + return; + } + this.charset = true; } - - return fail(`unmatched \`${String.fromCharCode(cc)}\``, currentChunkStartIndex); - - case 47: - // /, check for comment - if (parenLevel || chunkerCurrentIndex == len - 1) { - continue; + return atRuleNode; + }, + checkValidNodes: function (rules, isRoot) { + if (!rules) { + return; } - - cc2 = input.charCodeAt(chunkerCurrentIndex + 1); - - if (cc2 == 47) { - // //, find lnfeed - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 <= 13 && (cc2 == 10 || cc2 == 13)) { - break; + for (var i_1 = 0; i_1 < rules.length; i_1++) { + var ruleNode = rules[i_1]; + if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { + throw { message: 'Properties must be inside selector blocks. They cannot be in the root', + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 == 125) { - lastMultiCommentEndBrace = chunkerCurrentIndex; + if (ruleNode instanceof tree.Call) { + throw { message: "Function '" + ruleNode.name + "' is undefined", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - - if (cc2 != 42) { - continue; + if (ruleNode.type && !ruleNode.allowRoot) { + throw { message: ruleNode.type + " node returned by a function is not valid here", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; } - - if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - break; + } + }, + visitRuleset: function (rulesetNode, visitArgs) { + // at this point rulesets are nested into each other + var rule; + var rulesets = []; + this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); + if (!rulesetNode.root) { + // remove invisible paths + this._compileRulesetPaths(rulesetNode); + // remove rulesets from this ruleset body and compile them separately + var nodeRules = rulesetNode.rules; + var nodeRuleCnt = nodeRules ? nodeRules.length : 0; + for (var i_2 = 0; i_2 < nodeRuleCnt;) { + rule = nodeRules[i_2]; + if (rule && rule.rules) { + // visit because we are moving them out from being a child + rulesets.push(this._visitor.visit(rule)); + nodeRules.splice(i_2, 1); + nodeRuleCnt--; + continue; + } + i_2++; } - } - - if (chunkerCurrentIndex == len - 1) { - return fail('missing closing `*/`', currentChunkStartIndex); - } - - chunkerCurrentIndex++; + // accept the visitor to remove rules and refactor itself + // then we can decide nogw whether we want it or not + // compile body + if (nodeRuleCnt > 0) { + rulesetNode.accept(this._visitor); + } + else { + rulesetNode.rules = null; + } + visitArgs.visitDeeper = false; } - - continue; - - case 42: - // *, check for unmatched */ - if (chunkerCurrentIndex < len - 1 && input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - return fail('unmatched `/*`', chunkerCurrentIndex); + else { // if (! rulesetNode.root) { + rulesetNode.accept(this._visitor); + visitArgs.visitDeeper = false; } - - continue; - } - } - - if (level !== 0) { - if (lastMultiComment > lastOpening && lastMultiCommentEndBrace > lastMultiComment) { - return fail('missing closing `}` or `*/`', lastOpening); - } else { - return fail('missing closing `}`', lastOpening); - } - } else if (parenLevel !== 0) { - return fail('missing closing `)`', lastOpeningParen); - } - - emitChunk(true); - return chunks; -}); - -var getParserInput = (function () { - var // Less input string - input; - var // current chunk - j; - var // holds state for backtracking - saveStack = []; - var // furthest index the parser has gone to - furthest; - var // if this is furthest we got to, this is the probably cause - furthestPossibleErrorMessage; - var // chunkified input - chunks; - var // current chunk - current; - var // index of current chunk, in `input` - currentPos; - var parserInput = {}; - var CHARCODE_SPACE = 32; - var CHARCODE_TAB = 9; - var CHARCODE_LF = 10; - var CHARCODE_CR = 13; - var CHARCODE_PLUS = 43; - var CHARCODE_COMMA = 44; - var CHARCODE_FORWARD_SLASH = 47; - var CHARCODE_9 = 57; - - function skipWhitespace(length) { - var oldi = parserInput.i; - var oldj = j; - var curr = parserInput.i - currentPos; - var endIndex = parserInput.i + current.length - curr; - var mem = parserInput.i += length; - var inp = input; - var c; - var nextChar; - var comment; - - for (; parserInput.i < endIndex; parserInput.i++) { - c = inp.charCodeAt(parserInput.i); - - if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { - nextChar = inp.charAt(parserInput.i + 1); - - if (nextChar === '/') { - comment = { - index: parserInput.i, - isLineComment: true - }; - var nextNewLine = inp.indexOf('\n', parserInput.i + 2); - - if (nextNewLine < 0) { - nextNewLine = endIndex; - } - - parserInput.i = nextNewLine; - comment.text = inp.substr(comment.index, parserInput.i - comment.index); - parserInput.commentStore.push(comment); - continue; - } else if (nextChar === '*') { - var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); - - if (nextStarSlash >= 0) { - comment = { - index: parserInput.i, - text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), - isLineComment: false - }; - parserInput.i += comment.text.length - 1; - parserInput.commentStore.push(comment); - continue; - } + if (rulesetNode.rules) { + this._mergeRules(rulesetNode.rules); + this._removeDuplicateRules(rulesetNode.rules); } - - break; - } - - if (c !== CHARCODE_SPACE && c !== CHARCODE_LF && c !== CHARCODE_TAB && c !== CHARCODE_CR) { - break; - } - } - - current = current.slice(length + parserInput.i - mem + curr); - currentPos = parserInput.i; - - if (!current.length) { - if (j < chunks.length - 1) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - - return true; // things changed - } - - parserInput.finished = true; + // now decide whether we keep the ruleset + if (this.utils.isVisibleRuleset(rulesetNode)) { + rulesetNode.ensureVisibility(); + rulesets.splice(0, 0, rulesetNode); + } + if (rulesets.length === 1) { + return rulesets[0]; + } + return rulesets; + }, + _compileRulesetPaths: function (rulesetNode) { + if (rulesetNode.paths) { + rulesetNode.paths = rulesetNode.paths + .filter(function (p) { + var i; + if (p[0].elements[0].combinator.value === ' ') { + p[0].elements[0].combinator = new (tree.Combinator)(''); + } + for (i = 0; i < p.length; i++) { + if (p[i].isVisible() && p[i].getIsOutput()) { + return true; + } + } + return false; + }); + } + }, + _removeDuplicateRules: function (rules) { + if (!rules) { + return; + } + // remove duplicates + var ruleCache = {}; + var ruleList; + var rule; + var i; + for (i = rules.length - 1; i >= 0; i--) { + rule = rules[i]; + if (rule instanceof tree.Declaration) { + if (!ruleCache[rule.name]) { + ruleCache[rule.name] = rule; + } + else { + ruleList = ruleCache[rule.name]; + if (ruleList instanceof tree.Declaration) { + ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; + } + var ruleCSS = rule.toCSS(this._context); + if (ruleList.indexOf(ruleCSS) !== -1) { + rules.splice(i, 1); + } + else { + ruleList.push(ruleCSS); + } + } + } + } + }, + _mergeRules: function (rules) { + if (!rules) { + return; + } + var groups = {}; + var groupsArr = []; + for (var i_3 = 0; i_3 < rules.length; i_3++) { + var rule = rules[i_3]; + if (rule.merge) { + var key = rule.name; + groups[key] ? rules.splice(i_3--, 1) : + groupsArr.push(groups[key] = []); + groups[key].push(rule); + } + } + groupsArr.forEach(function (group) { + if (group.length > 0) { + var result_1 = group[0]; + var space_1 = []; + var comma_1 = [new tree.Expression(space_1)]; + group.forEach(function (rule) { + if ((rule.merge === '+') && (space_1.length > 0)) { + comma_1.push(new tree.Expression(space_1 = [])); + } + space_1.push(rule.value); + result_1.important = result_1.important || rule.important; + }); + result_1.value = new tree.Value(comma_1); + } + }); } +}; - return oldi !== parserInput.i || oldj !== j; - } - - parserInput.save = function () { - currentPos = parserInput.i; - saveStack.push({ - current, - i: parserInput.i, - j - }); - }; +var visitors = { + Visitor: Visitor, + ImportVisitor: ImportVisitor, + MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, + ExtendVisitor: ProcessExtendsVisitor, + JoinSelectorVisitor: JoinSelectorVisitor, + ToCSSVisitor: ToCSSVisitor +}; - parserInput.restore = function (possibleErrorMessage) { - if (parserInput.i > furthest || parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage) { - furthest = parserInput.i; - furthestPossibleErrorMessage = possibleErrorMessage; +// Split the input into chunks. +var chunker = (function (input, fail) { + var len = input.length; + var level = 0; + var parenLevel = 0; + var lastOpening; + var lastOpeningParen; + var lastMultiComment; + var lastMultiCommentEndBrace; + var chunks = []; + var emitFrom = 0; + var chunkerCurrentIndex; + var currentChunkStartIndex; + var cc; + var cc2; + var matched; + function emitChunk(force) { + var len = chunkerCurrentIndex - emitFrom; + if (((len < 512) && !force) || !len) { + return; + } + chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); + emitFrom = chunkerCurrentIndex + 1; } - - var state = saveStack.pop(); - current = state.current; - currentPos = parserInput.i = state.i; - j = state.j; - }; - - parserInput.forget = function () { - saveStack.pop(); - }; - - parserInput.isWhitespace = function (offset) { - var pos = parserInput.i + (offset || 0); - var code = input.charCodeAt(pos); - return code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF; - }; // Specialization of $(tok) - - - parserInput.$re = function (tok) { - if (parserInput.i > currentPos) { - current = current.slice(parserInput.i - currentPos); - currentPos = parserInput.i; + for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc = input.charCodeAt(chunkerCurrentIndex); + if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { + // a-z or whitespace + continue; + } + switch (cc) { + case 40: // ( + parenLevel++; + lastOpeningParen = chunkerCurrentIndex; + continue; + case 41: // ) + if (--parenLevel < 0) { + return fail('missing opening `(`', chunkerCurrentIndex); + } + continue; + case 59: // ; + if (!parenLevel) { + emitChunk(); + } + continue; + case 123: // { + level++; + lastOpening = chunkerCurrentIndex; + continue; + case 125: // } + if (--level < 0) { + return fail('missing opening `{`', chunkerCurrentIndex); + } + if (!level && !parenLevel) { + emitChunk(); + } + continue; + case 92: // \ + if (chunkerCurrentIndex < len - 1) { + chunkerCurrentIndex++; + continue; + } + return fail('unescaped `\\`', chunkerCurrentIndex); + case 34: + case 39: + case 96: // ", ' and ` + matched = 0; + currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 > 96) { + continue; + } + if (cc2 == cc) { + matched = 1; + break; + } + if (cc2 == 92) { // \ + if (chunkerCurrentIndex == len - 1) { + return fail('unescaped `\\`', chunkerCurrentIndex); + } + chunkerCurrentIndex++; + } + } + if (matched) { + continue; + } + return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); + case 47: // /, check for comment + if (parenLevel || (chunkerCurrentIndex == len - 1)) { + continue; + } + cc2 = input.charCodeAt(chunkerCurrentIndex + 1); + if (cc2 == 47) { + // //, find lnfeed + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { + break; + } + } + } + else if (cc2 == 42) { + // /*, find */ + lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 == 125) { + lastMultiCommentEndBrace = chunkerCurrentIndex; + } + if (cc2 != 42) { + continue; + } + if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { + break; + } + } + if (chunkerCurrentIndex == len - 1) { + return fail('missing closing `*/`', currentChunkStartIndex); + } + chunkerCurrentIndex++; + } + continue; + case 42: // *, check for unmatched */ + if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) { + return fail('unmatched `/*`', chunkerCurrentIndex); + } + continue; + } } - - var m = tok.exec(current); - - if (!m) { - return null; + if (level !== 0) { + if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { + return fail('missing closing `}` or `*/`', lastOpening); + } + else { + return fail('missing closing `}`', lastOpening); + } } - - skipWhitespace(m[0].length); - - if (typeof m === 'string') { - return m; + else if (parenLevel !== 0) { + return fail('missing closing `)`', lastOpeningParen); } + emitChunk(true); + return chunks; +}); - return m.length === 1 ? m[0] : m; - }; - - parserInput.$char = function (tok) { - if (input.charAt(parserInput.i) !== tok) { - return null; +var getParserInput = (function () { + var // Less input string + input; + var // current chunk + j; + var // holds state for backtracking + saveStack = []; + var // furthest index the parser has gone to + furthest; + var // if this is furthest we got to, this is the probably cause + furthestPossibleErrorMessage; + var // chunkified input + chunks; + var // current chunk + current; + var // index of current chunk, in `input` + currentPos; + var parserInput = {}; + var CHARCODE_SPACE = 32; + var CHARCODE_TAB = 9; + var CHARCODE_LF = 10; + var CHARCODE_CR = 13; + var CHARCODE_PLUS = 43; + var CHARCODE_COMMA = 44; + var CHARCODE_FORWARD_SLASH = 47; + var CHARCODE_9 = 57; + function skipWhitespace(length) { + var oldi = parserInput.i; + var oldj = j; + var curr = parserInput.i - currentPos; + var endIndex = parserInput.i + current.length - curr; + var mem = (parserInput.i += length); + var inp = input; + var c; + var nextChar; + var comment; + for (; parserInput.i < endIndex; parserInput.i++) { + c = inp.charCodeAt(parserInput.i); + if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { + nextChar = inp.charAt(parserInput.i + 1); + if (nextChar === '/') { + comment = { index: parserInput.i, isLineComment: true }; + var nextNewLine = inp.indexOf('\n', parserInput.i + 2); + if (nextNewLine < 0) { + nextNewLine = endIndex; + } + parserInput.i = nextNewLine; + comment.text = inp.substr(comment.index, parserInput.i - comment.index); + parserInput.commentStore.push(comment); + continue; + } + else if (nextChar === '*') { + var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); + if (nextStarSlash >= 0) { + comment = { + index: parserInput.i, + text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), + isLineComment: false + }; + parserInput.i += comment.text.length - 1; + parserInput.commentStore.push(comment); + continue; + } + } + break; + } + if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) { + break; + } + } + current = current.slice(length + parserInput.i - mem + curr); + currentPos = parserInput.i; + if (!current.length) { + if (j < chunks.length - 1) { + current = chunks[++j]; + skipWhitespace(0); // skip space at the beginning of a chunk + return true; // things changed + } + parserInput.finished = true; + } + return oldi !== parserInput.i || oldj !== j; } - - skipWhitespace(1); - return tok; - }; - - parserInput.$str = function (tok) { - var tokLength = tok.length; // https://jsperf.com/string-startswith/21 - - for (var i = 0; i < tokLength; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { + parserInput.save = function () { + currentPos = parserInput.i; + saveStack.push({ current: current, i: parserInput.i, j: j }); + }; + parserInput.restore = function (possibleErrorMessage) { + if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) { + furthest = parserInput.i; + furthestPossibleErrorMessage = possibleErrorMessage; + } + var state = saveStack.pop(); + current = state.current; + currentPos = parserInput.i = state.i; + j = state.j; + }; + parserInput.forget = function () { + saveStack.pop(); + }; + parserInput.isWhitespace = function (offset) { + var pos = parserInput.i + (offset || 0); + var code = input.charCodeAt(pos); + return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF); + }; + // Specialization of $(tok) + parserInput.$re = function (tok) { + if (parserInput.i > currentPos) { + current = current.slice(parserInput.i - currentPos); + currentPos = parserInput.i; + } + var m = tok.exec(current); + if (!m) { + return null; + } + skipWhitespace(m[0].length); + if (typeof m === 'string') { + return m; + } + return m.length === 1 ? m[0] : m; + }; + parserInput.$char = function (tok) { + if (input.charAt(parserInput.i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + }; + parserInput.$str = function (tok) { + var tokLength = tok.length; + // https://jsperf.com/string-startswith/21 + for (var i_1 = 0; i_1 < tokLength; i_1++) { + if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) { + return null; + } + } + skipWhitespace(tokLength); + return tok; + }; + parserInput.$quoted = function (loc) { + var pos = loc || parserInput.i; + var startChar = input.charAt(pos); + if (startChar !== '\'' && startChar !== '"') { + return; + } + var length = input.length; + var currentPosition = pos; + for (var i_2 = 1; i_2 + currentPosition < length; i_2++) { + var nextChar = input.charAt(i_2 + currentPosition); + switch (nextChar) { + case '\\': + i_2++; + continue; + case '\r': + case '\n': + break; + case startChar: + var str = input.substr(currentPosition, i_2 + 1); + if (!loc && loc !== 0) { + skipWhitespace(i_2 + 1); + return str; + } + return [startChar, str]; + } + } return null; - } - } - - skipWhitespace(tokLength); - return tok; - }; - - parserInput.$quoted = function (loc) { - var pos = loc || parserInput.i; - var startChar = input.charAt(pos); - - if (startChar !== '\'' && startChar !== '"') { - return; - } - - var length = input.length; - var currentPosition = pos; - - for (var i = 1; i + currentPosition < length; i++) { - var nextChar = input.charAt(i + currentPosition); - - switch (nextChar) { - case '\\': - i++; - continue; - - case '\r': - case '\n': - break; - - case startChar: - var str = input.substr(currentPosition, i + 1); - - if (!loc && loc !== 0) { - skipWhitespace(i + 1); - return str; - } - - return [startChar, str]; - - default: - } - } - - return null; - }; - /** - * Permissive parsing. Ignores everything except matching {} [] () and quotes - * until matching token (outside of blocks) - */ - - - parserInput.$parseUntil = function (tok) { - var quote = ''; - var returnVal = null; - var inComment = false; - var blockDepth = 0; - var blockStack = []; - var parseGroups = []; - var length = input.length; - var startPos = parserInput.i; - var lastPos = parserInput.i; - var i = parserInput.i; - var loop = true; - var testChar; - - if (typeof tok === 'string') { - testChar = function testChar(char) { - return char === tok; - }; - } else { - testChar = function testChar(char) { - return tok.test(char); - }; - } - - do { - var nextChar = input.charAt(i); - - if (blockDepth === 0 && testChar(nextChar)) { - returnVal = input.substr(lastPos, i - lastPos); - - if (returnVal) { - parseGroups.push(returnVal); - } else { - parseGroups.push(' '); + }; + /** + * Permissive parsing. Ignores everything except matching {} [] () and quotes + * until matching token (outside of blocks) + */ + parserInput.$parseUntil = function (tok) { + var quote = ''; + var returnVal = null; + var inComment = false; + var blockDepth = 0; + var blockStack = []; + var parseGroups = []; + var length = input.length; + var startPos = parserInput.i; + var lastPos = parserInput.i; + var i = parserInput.i; + var loop = true; + var testChar; + if (typeof tok === 'string') { + testChar = function (char) { return char === tok; }; } - - returnVal = parseGroups; - skipWhitespace(i - startPos); - loop = false; - } else { - if (inComment) { - if (nextChar === '*' && input.charAt(i + 1) === '/') { - i++; - blockDepth--; - inComment = false; - } - - i++; - continue; + else { + testChar = function (char) { return tok.test(char); }; } - - switch (nextChar) { - case '\\': - i++; - nextChar = input.charAt(i); - parseGroups.push(input.substr(lastPos, i - lastPos + 1)); - lastPos = i + 1; - break; - - case '/': - if (input.charAt(i + 1) === '*') { - i++; - inComment = true; - blockDepth++; + do { + var nextChar = input.charAt(i); + if (blockDepth === 0 && testChar(nextChar)) { + returnVal = input.substr(lastPos, i - lastPos); + if (returnVal) { + parseGroups.push(returnVal); + } + else { + parseGroups.push(' '); + } + returnVal = parseGroups; + skipWhitespace(i - startPos); + loop = false; } - - break; - - case '\'': - case '"': - quote = parserInput.$quoted(i); - - if (quote) { - parseGroups.push(input.substr(lastPos, i - lastPos), quote); - i += quote[1].length - 1; - lastPos = i + 1; - } else { - skipWhitespace(i - startPos); - returnVal = nextChar; - loop = false; + else { + if (inComment) { + if (nextChar === '*' && + input.charAt(i + 1) === '/') { + i++; + blockDepth--; + inComment = false; + } + i++; + continue; + } + switch (nextChar) { + case '\\': + i++; + nextChar = input.charAt(i); + parseGroups.push(input.substr(lastPos, i - lastPos + 1)); + lastPos = i + 1; + break; + case '/': + if (input.charAt(i + 1) === '*') { + i++; + inComment = true; + blockDepth++; + } + break; + case '\'': + case '"': + quote = parserInput.$quoted(i); + if (quote) { + parseGroups.push(input.substr(lastPos, i - lastPos), quote); + i += quote[1].length - 1; + lastPos = i + 1; + } + else { + skipWhitespace(i - startPos); + returnVal = nextChar; + loop = false; + } + break; + case '{': + blockStack.push('}'); + blockDepth++; + break; + case '(': + blockStack.push(')'); + blockDepth++; + break; + case '[': + blockStack.push(']'); + blockDepth++; + break; + case '}': + case ')': + case ']': + var expected = blockStack.pop(); + if (nextChar === expected) { + blockDepth--; + } + else { + // move the parser to the error and return expected + skipWhitespace(i - startPos); + returnVal = expected; + loop = false; + } + } + i++; + if (i > length) { + loop = false; + } } - - break; - - case '{': - blockStack.push('}'); - blockDepth++; - break; - - case '(': - blockStack.push(')'); - blockDepth++; - break; - - case '[': - blockStack.push(']'); - blockDepth++; - break; - - case '}': - case ')': - case ']': - var expected = blockStack.pop(); - - if (nextChar === expected) { - blockDepth--; - } else { - // move the parser to the error and return expected - skipWhitespace(i - startPos); - returnVal = expected; - loop = false; + } while (loop); + return returnVal ? returnVal : null; + }; + parserInput.autoCommentAbsorb = true; + parserInput.commentStore = []; + parserInput.finished = false; + // Same as $(), but don't change the state of the parser, + // just return the match. + parserInput.peek = function (tok) { + if (typeof tok === 'string') { + // https://jsperf.com/string-startswith/21 + for (var i_3 = 0; i_3 < tok.length; i_3++) { + if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) { + return false; + } } - + return true; } - - i++; - - if (i > length) { - loop = false; + else { + return tok.test(current); } - } - } while (loop); - - return returnVal ? returnVal : null; - }; - - parserInput.autoCommentAbsorb = true; - parserInput.commentStore = []; - parserInput.finished = false; // Same as $(), but don't change the state of the parser, - // just return the match. - - parserInput.peek = function (tok) { - if (typeof tok === 'string') { - // https://jsperf.com/string-startswith/21 - for (var i = 0; i < tok.length; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { - return false; - } - } - - return true; - } else { - return tok.test(current); - } - }; // Specialization of peek() - // TODO remove or change some currentChar calls to peekChar - - - parserInput.peekChar = function (tok) { - return input.charAt(parserInput.i) === tok; - }; - - parserInput.currentChar = function () { - return input.charAt(parserInput.i); - }; - - parserInput.prevChar = function () { - return input.charAt(parserInput.i - 1); - }; - - parserInput.getInput = function () { - return input; - }; - - parserInput.peekNotNumeric = function () { - var c = input.charCodeAt(parserInput.i); // Is the first char of the dimension 0-9, '.', '+' or '-' - - return c > CHARCODE_9 || c < CHARCODE_PLUS || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; - }; - - parserInput.start = function (str, chunkInput, failFunction) { - input = str; - parserInput.i = j = currentPos = furthest = 0; // chunking apparently makes things quicker (but my tests indicate - // it might actually make things slower in node at least) - // and it is a non-perfect parse - it can't recognise - // unquoted urls, meaning it can't distinguish comments - // meaning comments with quotes or {}() in them get 'counted' - // and then lead to parse errors. - // In addition if the chunking chunks in the wrong place we might - // not be able to parse a parser statement in one go - // this is officially deprecated but can be switched on via an option - // in the case it causes too much performance issues. - - if (chunkInput) { - chunks = chunker(str, failFunction); - } else { - chunks = [str]; - } - - current = chunks[0]; - skipWhitespace(0); - }; - - parserInput.end = function () { - var message; - var isFinished = parserInput.i >= input.length; - - if (parserInput.i < furthest) { - message = furthestPossibleErrorMessage; - parserInput.i = furthest; - } - - return { - isFinished, - furthest: parserInput.i, - furthestPossibleErrorMessage: message, - furthestReachedEnd: parserInput.i >= input.length - 1, - furthestChar: input[parserInput.i] }; - }; - - return parserInput; + // Specialization of peek() + // TODO remove or change some currentChar calls to peekChar + parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; }; + parserInput.currentChar = function () { return input.charAt(parserInput.i); }; + parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); }; + parserInput.getInput = function () { return input; }; + parserInput.peekNotNumeric = function () { + var c = input.charCodeAt(parserInput.i); + // Is the first char of the dimension 0-9, '.', '+' or '-' + return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; + }; + parserInput.start = function (str, chunkInput, failFunction) { + input = str; + parserInput.i = j = currentPos = furthest = 0; + // chunking apparently makes things quicker (but my tests indicate + // it might actually make things slower in node at least) + // and it is a non-perfect parse - it can't recognise + // unquoted urls, meaning it can't distinguish comments + // meaning comments with quotes or {}() in them get 'counted' + // and then lead to parse errors. + // In addition if the chunking chunks in the wrong place we might + // not be able to parse a parser statement in one go + // this is officially deprecated but can be switched on via an option + // in the case it causes too much performance issues. + if (chunkInput) { + chunks = chunker(str, failFunction); + } + else { + chunks = [str]; + } + current = chunks[0]; + skipWhitespace(0); + }; + parserInput.end = function () { + var message; + var isFinished = parserInput.i >= input.length; + if (parserInput.i < furthest) { + message = furthestPossibleErrorMessage; + parserInput.i = furthest; + } + return { + isFinished: isFinished, + furthest: parserInput.i, + furthestPossibleErrorMessage: message, + furthestReachedEnd: parserInput.i >= input.length - 1, + furthestChar: input[parserInput.i] + }; + }; + return parserInput; }); +// // less.js - parser // // A relatively straight-forward predictive parser. @@ -8762,4660 +6612,4002 @@ var getParserInput = (function () { // a terminal string or regexp, or a non-terminal function to call. // It also takes care of moving all the indices forwards. // - var Parser = function Parser(context, imports, fileInfo) { - var parsers; - var parserInput = getParserInput(); - - function error(msg, type) { - throw new LessError({ - index: parserInput.i, - filename: fileInfo.filename, - type: type || 'Syntax', - message: msg - }, imports); - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = arg instanceof Function ? arg.call(parsers) : parserInput.$re(arg); - - if (result) { - return result; - } - - error(msg || (typeof arg === 'string' ? `expected '${arg}' got '${parserInput.currentChar()}'` : 'unexpected token')); - } // Specialization of expect() - - - function expectChar(arg, msg) { - if (parserInput.$char(arg)) { - return arg; + var parsers; + var parserInput = getParserInput(); + function error(msg, type) { + throw new LessError({ + index: parserInput.i, + filename: fileInfo.filename, + type: type || 'Syntax', + message: msg + }, imports); } - - error(msg || `expected '${arg}' got '${parserInput.currentChar()}'`); - } - - function getDebugInfo(index) { - var filename = fileInfo.filename; - return { - lineNumber: getLocation(index, parserInput.getInput()).line + 1, - fileName: filename - }; - } - /** - * Used after initial parsing to create nodes on the fly - * - * @param {String} str - string to parse - * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] - * @param {Number} currentIndex - start number to begin indexing - * @param {Object} fileInfo - fileInfo to attach to created nodes - */ - - - function parseNode(str, parseList, currentIndex, fileInfo, callback) { - var result; - var returnNodes = []; - var parser = parserInput; - - try { - parser.start(str, false, function fail(msg, index) { - callback({ - message: msg, - index: index + currentIndex - }); - }); - - for (var x = 0, p, i; p = parseList[x]; x++) { - i = parser.i; - result = parsers[p](); - + function expect(arg, msg) { + // some older browsers return typeof 'function' for RegExp + var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg); if (result) { - try { - result._index = i + currentIndex; - result._fileInfo = fileInfo; - } catch (e) {} - - returnNodes.push(result); - } else { - returnNodes.push(null); + return result; } - } - - var endInfo = parser.end(); - - if (endInfo.isFinished) { - callback(null, returnNodes); - } else { - callback(true, null); - } - } catch (e) { - throw new LessError({ - index: e.index + currentIndex, - message: e.message - }, imports, fileInfo.filename); - } - } // - // The Parser - // - - - return { - parserInput, - imports, - fileInfo, - parseNode, + error(msg || (typeof arg === 'string' + ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'" + : 'unexpected token')); + } + // Specialization of expect() + function expectChar(arg, msg) { + if (parserInput.$char(arg)) { + return arg; + } + error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'"); + } + function getDebugInfo(index) { + var filename = fileInfo.filename; + return { + lineNumber: getLocation(index, parserInput.getInput()).line + 1, + fileName: filename + }; + } + /** + * Used after initial parsing to create nodes on the fly + * + * @param {String} str - string to parse + * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] + * @param {Number} currentIndex - start number to begin indexing + * @param {Object} fileInfo - fileInfo to attach to created nodes + */ + function parseNode(str, parseList, currentIndex, fileInfo, callback) { + var result; + var returnNodes = []; + var parser = parserInput; + try { + parser.start(str, false, function fail(msg, index) { + callback({ + message: msg, + index: index + currentIndex + }); + }); + for (var x = 0, p = void 0, i_1; (p = parseList[x]); x++) { + i_1 = parser.i; + result = parsers[p](); + if (result) { + try { + result._index = i_1 + currentIndex; + result._fileInfo = fileInfo; + } + catch (e) { } + returnNodes.push(result); + } + else { + returnNodes.push(null); + } + } + var endInfo = parser.end(); + if (endInfo.isFinished) { + callback(null, returnNodes); + } + else { + callback(true, null); + } + } + catch (e) { + throw new LessError({ + index: e.index + currentIndex, + message: e.message + }, imports, fileInfo.filename); + } + } // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply + // The Parser // - parse: function parse(str, callback, additionalData) { - var root; - var error = null; - var globalVars; - var modifyVars; - var ignored; - var preText = ''; - globalVars = additionalData && additionalData.globalVars ? `${Parser.serializeVars(additionalData.globalVars)}\n` : ''; - modifyVars = additionalData && additionalData.modifyVars ? `\n${Parser.serializeVars(additionalData.modifyVars)}` : ''; - - if (context.pluginManager) { - var preProcessors = context.pluginManager.getPreProcessors(); - - for (var i = 0; i < preProcessors.length; i++) { - str = preProcessors[i].process(str, { - context, - imports, - fileInfo - }); - } - } - - if (globalVars || additionalData && additionalData.banner) { - preText = (additionalData && additionalData.banner ? additionalData.banner : '') + globalVars; - ignored = imports.contentsIgnoredChars; - ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; - ignored[fileInfo.filename] += preText.length; - } - - str = str.replace(/\r\n?/g, '\n'); // Remove potential UTF Byte Order Mark - - str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - imports.contents[fileInfo.filename] = str; // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - - try { - parserInput.start(str, context.chunkInput, function fail(msg, index) { - throw new LessError({ - index, - type: 'Parse', - message: msg, - filename: fileInfo.filename - }, imports); - }); - tree.Node.prototype.parse = this; - root = new tree.Ruleset(null, this.parsers.primary()); - tree.Node.prototype.rootNode = root; - root.root = true; - root.firstRoot = true; - root.functionRegistry = functionRegistry.inherit(); - } catch (e) { - return callback(new LessError(e, imports, fileInfo.filename)); - } // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occurred. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - - - var endInfo = parserInput.end(); - - if (!endInfo.isFinished) { - var message = endInfo.furthestPossibleErrorMessage; - - if (!message) { - message = 'Unrecognised input'; - - if (endInfo.furthestChar === '}') { - message += '. Possibly missing opening \'{\''; - } else if (endInfo.furthestChar === ')') { - message += '. Possibly missing opening \'(\''; - } else if (endInfo.furthestReachedEnd) { - message += '. Possibly missing something'; - } - } - - error = new LessError({ - type: 'Parse', - message, - index: endInfo.furthest, - filename: fileInfo.filename - }, imports); - } - - var finish = function finish(e) { - e = error || e || imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new LessError(e, imports, fileInfo.filename); - } - - return callback(e); - } else { - return callback(null, root); - } - }; - - if (context.processImports !== false) { - new visitors.ImportVisitor(imports, finish).run(root); - } else { - return finish(); - } - }, - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Declaration -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Declaration ("color", Value ([Expression [Color #fff]])) - // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$re()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | declaration)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function primary() { - var mixin = this.mixin; - var root = []; - var node; - - while (true) { - while (true) { - node = this.comment(); - - if (!node) { - break; - } - - root.push(node); - } // always process comments before deciding if finished - - - if (parserInput.finished) { - break; - } - - if (parserInput.peek('}')) { - break; - } - - node = this.extendRule(); - - if (node) { - root = root.concat(node); - continue; - } - - node = mixin.definition() || this.declaration() || this.ruleset() || mixin.call(false, false) || this.variableCall() || this.entities.call() || this.atrule(); - - if (node) { - root.push(node); - } else { - var foundSemiColon = false; - - while (parserInput.$char(';')) { - foundSemiColon = true; - } - - if (!foundSemiColon) { - break; - } - } - } - - return root; - }, - // comments are collected by the main parsing mechanism and then assigned to nodes - // where the current structure allows it - comment: function comment() { - if (parserInput.commentStore.length) { - var comment = parserInput.commentStore.shift(); - return new tree.Comment(comment.text, comment.isLineComment, comment.index, fileInfo); - } - }, - // - // Entities are tokens which can be found inside an Expression - // - entities: { - mixinLookup: function mixinLookup() { - return parsers.mixin.call(true, true); - }, - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function quoted(forceEscaped) { - var str; - var index = parserInput.i; - var isEscaped = false; - parserInput.save(); - - if (parserInput.$char('~')) { - isEscaped = true; - } else if (forceEscaped) { - parserInput.restore(); - return; - } - - str = parserInput.$quoted(); - - if (!str) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return new tree.Quoted(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); - }, - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function keyword() { - var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); - - if (k) { - return tree.Color.fromKeyword(k) || new tree.Keyword(k); - } - }, - // - // A function call - // - // rgb(255, 0, 255) + return { + parserInput: parserInput, + imports: imports, + fileInfo: fileInfo, + parseNode: parseNode, // - // The arguments are parsed with the `entities.arguments` parser. + // Parse an input string into an abstract syntax tree, + // @param str A string containing 'less' markup + // @param callback call `callback` when done. + // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply // - call: function call() { - var name; - var args; - var func; - var index = parserInput.i; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (parserInput.peek(/^url\(/i)) { - return; - } - - parserInput.save(); - name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); - - if (!name) { - parserInput.forget(); - return; - } - - name = name[1]; - func = this.customFuncCall(name); - - if (func) { - args = func.parse(); - - if (args && func.stop) { - parserInput.forget(); - return args; + parse: function (str, callback, additionalData) { + var root; + var error = null; + var globalVars; + var modifyVars; + var ignored; + var preText = ''; + globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : ''; + modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : ''; + if (context.pluginManager) { + var preProcessors = context.pluginManager.getPreProcessors(); + for (var i_2 = 0; i_2 < preProcessors.length; i_2++) { + str = preProcessors[i_2].process(str, { context: context, imports: imports, fileInfo: fileInfo }); + } } - } - - args = this.arguments(args); - - if (!parserInput.$char(')')) { - parserInput.restore('Could not parse call arguments or missing \')\''); - return; - } - - parserInput.forget(); - return new tree.Call(name, args, index, fileInfo); - }, - // - // Parsing rules for functions with non-standard args, e.g.: - // - // boolean(not(2 > 1)) - // - // This is a quick prototype, to be modified/improved when - // more custom-parsed funcs come (e.g. `selector(...)`) - // - customFuncCall: function customFuncCall(name) { - /* Ideally the table is to be moved out of here for faster perf., - but it's quite tricky since it relies on all these `parsers` - and `expect` available only here */ - return { - alpha: f(parsers.ieAlpha, true), - boolean: f(condition), - 'if': f(condition) - }[name.toLowerCase()]; - - function f(parse, stop) { - return { - parse, - // parsing function - stop // when true - stop after parse() and return its result, - // otherwise continue for plain args - - }; - } - - function condition() { - return [expect(parsers.condition, 'expected condition')]; - } - }, - arguments: function _arguments(prevArgs) { - var argsComma = prevArgs || []; - var argsSemiColon = []; - var isSemiColonSeparated; - var value; - parserInput.save(); - - while (true) { - if (prevArgs) { - prevArgs = false; - } else { - value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); - - if (!value) { - break; - } - - if (value.value && value.value.length == 1) { - value = value.value[0]; - } - - argsComma.push(value); + if (globalVars || (additionalData && additionalData.banner)) { + preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars; + ignored = imports.contentsIgnoredChars; + ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; + ignored[fileInfo.filename] += preText.length; } - - if (parserInput.$char(',')) { - continue; + str = str.replace(/\r\n?/g, '\n'); + // Remove potential UTF Byte Order Mark + str = preText + str.replace(/^\uFEFF/, '') + modifyVars; + imports.contents[fileInfo.filename] = str; + // Start with the primary rule. + // The whole syntax tree is held under a Ruleset node, + // with the `root` property set to true, so no `{}` are + // output. The callback is called when the input is parsed. + try { + parserInput.start(str, context.chunkInput, function fail(msg, index) { + throw new LessError({ + index: index, + type: 'Parse', + message: msg, + filename: fileInfo.filename + }, imports); + }); + tree.Node.prototype.parse = this; + root = new tree.Ruleset(null, this.parsers.primary()); + tree.Node.prototype.rootNode = root; + root.root = true; + root.firstRoot = true; + root.functionRegistry = functionRegistry.inherit(); } - - if (parserInput.$char(';') || isSemiColonSeparated) { - isSemiColonSeparated = true; - value = argsComma.length < 1 ? argsComma[0] : new tree.Value(argsComma); - argsSemiColon.push(value); - argsComma = []; + catch (e) { + return callback(new LessError(e, imports, fileInfo.filename)); } - } - - parserInput.forget(); - return isSemiColonSeparated ? argsSemiColon : argsComma; - }, - literal: function literal() { - return this.dimension() || this.color() || this.quoted() || this.unicodeDescriptor(); - }, - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - assignment: function assignment() { - var key; - var value; - parserInput.save(); - key = parserInput.$re(/^\w+(?=\s?=)/i); - - if (!key) { - parserInput.restore(); - return; - } - - if (!parserInput.$char('=')) { - parserInput.restore(); - return; - } - - value = parsers.entity(); - - if (value) { - parserInput.forget(); - return new tree.Assignment(key, value); - } else { - parserInput.restore(); - } - }, - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function url() { - var value; - var index = parserInput.i; - parserInput.autoCommentAbsorb = false; - - if (!parserInput.$str('url(')) { - parserInput.autoCommentAbsorb = true; - return; - } - - value = this.quoted() || this.variable() || this.property() || parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; - parserInput.autoCommentAbsorb = true; - expectChar(')'); - return new tree.URL(value.value != null || value instanceof tree.Variable || value instanceof tree.Property ? value : new tree.Anonymous(value, index), index, fileInfo); - }, - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function variable() { - var ch; - var name; - var index = parserInput.i; - parserInput.save(); - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { - ch = parserInput.currentChar(); - - if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { - // this may be a VariableCall lookup - var result = parsers.variableCall(name); - - if (result) { - parserInput.forget(); - return result; - } + // If `i` is smaller than the `input.length - 1`, + // it means the parser wasn't able to parse the whole + // string, so we've got a parsing error. + // + // We try to extract a \n delimited string, + // showing the line where the parse error occurred. + // We split it up into two parts (the part which parsed, + // and the part which didn't), so we can color them differently. + var endInfo = parserInput.end(); + if (!endInfo.isFinished) { + var message = endInfo.furthestPossibleErrorMessage; + if (!message) { + message = 'Unrecognised input'; + if (endInfo.furthestChar === '}') { + message += '. Possibly missing opening \'{\''; + } + else if (endInfo.furthestChar === ')') { + message += '. Possibly missing opening \'(\''; + } + else if (endInfo.furthestReachedEnd) { + message += '. Possibly missing something'; + } + } + error = new LessError({ + type: 'Parse', + message: message, + index: endInfo.furthest, + filename: fileInfo.filename + }, imports); } - - parserInput.forget(); - return new tree.Variable(name, index, fileInfo); - } - - parserInput.restore(); - }, - // A variable entity using the protective {} e.g. @{var} - variableCurly: function variableCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { - return new tree.Variable(`@${curly[1]}`, index, fileInfo); - } - }, - // - // A Property accessor, such as `$color`, in - // - // background-color: $color - // - property: function property() { - var name; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { - return new tree.Property(name, index, fileInfo); - } - }, - // A property entity useing the protective {} e.g. ${prop} - propertyCurly: function propertyCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { - return new tree.Property(`$${curly[1]}`, index, fileInfo); - } - }, - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function color() { - var rgb; - parserInput.save(); - - if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { - if (!rgb[2]) { - parserInput.forget(); - return new tree.Color(rgb[1], undefined, rgb[0]); + var finish = function (e) { + e = error || e || imports.error; + if (e) { + if (!(e instanceof LessError)) { + e = new LessError(e, imports, fileInfo.filename); + } + return callback(e); + } + else { + return callback(null, root); + } + }; + if (context.processImports !== false) { + new visitors.ImportVisitor(imports, finish) + .run(root); + } + else { + return finish(); } - } - - parserInput.restore(); - }, - colorKeyword: function colorKeyword() { - parserInput.save(); - var autoCommentAbsorb = parserInput.autoCommentAbsorb; - parserInput.autoCommentAbsorb = false; - var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); - parserInput.autoCommentAbsorb = autoCommentAbsorb; - - if (!k) { - parserInput.forget(); - return; - } - - parserInput.restore(); - var color = tree.Color.fromKeyword(k); - - if (color) { - parserInput.$str(k); - return color; - } - }, - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function dimension() { - if (parserInput.peekNotNumeric()) { - return; - } - - var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); - - if (value) { - return new tree.Dimension(value[1], value[2]); - } - }, - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function unicodeDescriptor() { - var ud; - ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - - if (ud) { - return new tree.UnicodeDescriptor(ud[0]); - } }, // - // JavaScript code to be evaluated + // Here in, the parsing rules/functions // - // `window.location.href` + // The basic structure of the syntax tree generated is as follows: // - javascript: function javascript() { - var js; - var index = parserInput.i; - parserInput.save(); - var escape = parserInput.$char('~'); - var jsQuote = parserInput.$char('`'); - - if (!jsQuote) { - parserInput.restore(); - return; - } - - js = parserInput.$re(/^[^`]*`/); - - if (js) { - parserInput.forget(); - return new tree.JavaScript(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); - } - - parserInput.restore('invalid javascript definition'); - } - }, - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function variable() { - var name; - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { - return name[1]; - } - }, - // - // Call a variable value to retrieve a detached ruleset - // or a value from a detached ruleset's rules. - // - // @fink(); - // @fink; - // color: @fink[@color]; - // - variableCall: function variableCall(parsedName) { - var lookups; - var important; - var i = parserInput.i; - var inValue = !!parsedName; - var name = parsedName; - parserInput.save(); - - if (name || parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/))) { - lookups = this.mixin.ruleLookups(); - - if (!lookups && (inValue && parserInput.$str('()') !== '()' || name[2] !== '()')) { - parserInput.restore('Missing \'[...]\' lookup in variable call'); - return; - } - - if (!inValue) { - name = name[1]; - } - - if (lookups && parsers.important()) { - important = true; - } - - var call = new tree.VariableCall(name, i, fileInfo); - - if (!inValue && parsers.end()) { - parserInput.forget(); - return call; - } else { - parserInput.forget(); - return new tree.NamespaceValue(call, lookups, important, i, fileInfo); - } - } - - parserInput.restore(); - }, - // - // extend syntax - used to extend selectors - // - extend: function extend(isRule) { - var elements; - var e; - var index = parserInput.i; - var option; - var extendList; - var extend; - - if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { - return; - } - - do { - option = null; - elements = null; - - while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - - if (!e) { - break; - } - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - } - - option = option && option[1]; - - if (!elements) { - error('Missing target selector for :extend().'); - } - - extend = new tree.Extend(new tree.Selector(elements), option, index, fileInfo); - - if (extendList) { - extendList.push(extend); - } else { - extendList = [extend]; - } - } while (parserInput.$char(',')); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function extendRule() { - return this.extend(true); - }, - // - // Mixins - // - mixin: { + // Ruleset -> Declaration -> Value -> Expression -> Entity // - // A Mixin call, with an optional argument list + // Here's some Less code: // - // #mixins > .square(#fff); - // #mixins.square(#fff); - // .rounded(4px, black); - // .button; + // .class { + // color: #fff; + // border: 1px solid #000; + // width: @w + 4px; + // > .child {...} + // } // - // We can lookup / return a value using the lookup syntax: + // And here's what the parse tree might look like: // - // color: #mixin.square(#fff)[@color]; + // Ruleset (Selector '.class', [ + // Declaration ("color", Value ([Expression [Color #fff]])) + // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) + // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) + // Ruleset (Selector [Element '>', '.child'], [...]) + // ]) // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. + // In general, most rules will try to parse a token with the `$re()` function, and if the return + // value is truly, will return a new node, of the relevant type. Sometimes, we need to check + // first, before parsing, that's when we use `peek()`. // - call: function call(inValue, getLookup) { - var s = parserInput.currentChar(); - var important = false; - var lookups; - var index = parserInput.i; - var elements; - var args; - var hasParens; - - if (s !== '.' && s !== '#') { - return; - } - - parserInput.save(); // stop us absorbing part of an invalid selector - - elements = this.elements(); - - if (elements) { - if (parserInput.$char('(')) { - args = this.args(true).args; - expectChar(')'); - hasParens = true; - } - - if (getLookup !== false) { - lookups = this.ruleLookups(); - } - - if (getLookup === true && !lookups) { - parserInput.restore(); - return; - } - - if (inValue && !lookups && !hasParens) { - // This isn't a valid in-value mixin call - parserInput.restore(); - return; - } - - if (!inValue && parsers.important()) { - important = true; - } - - if (inValue || parsers.end()) { - parserInput.forget(); - var mixin = new tree.mixin.Call(elements, args, index, fileInfo, !lookups && important); - - if (lookups) { - return new tree.NamespaceValue(mixin, lookups, important); - } else { - return mixin; - } - } - } - - parserInput.restore(); - }, - - /** - * Matching elements for mixins - * (Start with . or # and can have > ) - */ - elements: function elements() { - var elements; - var e; - var c; - var elem; - var elemIndex; - var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; - - while (true) { - elemIndex = parserInput.i; - e = parserInput.$re(re); - - if (!e) { - break; - } - - elem = new tree.Element(c, e, false, elemIndex, fileInfo); - - if (elements) { - elements.push(elem); - } else { - elements = [elem]; - } - - c = parserInput.$char('>'); - } - - return elements; - }, - args: function args(isCall) { - var entities = parsers.entities; - var returner = { - args: null, - variadic: false - }; - var expressions = []; - var argsSemiColon = []; - var argsComma = []; - var isSemiColonSeparated; - var expressionContainsNamed; - var name; - var nameLoop; - var value; - var arg; - var expand; - var hasSep = true; - parserInput.save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parserInput.commentStore.length = 0; - - if (parserInput.$str('...')) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; + parsers: parsers = { + // + // The `primary` rule is the *entry* and *exit* point of the parser. + // The rules here can appear at any level of the parse tree. + // + // The recursive nature of the grammar is an interplay between the `block` + // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, + // as represented by this simplified grammar: + // + // primary → (ruleset | declaration)+ + // ruleset → selector+ block + // block → '{' primary '}' + // + // Only at one point is the primary rule not called from the + // block rule: at the root level. + // + primary: function () { + var mixin = this.mixin; + var root = []; + var node; + while (true) { + while (true) { + node = this.comment(); + if (!node) { + break; + } + root.push(node); + } + // always process comments before deciding if finished + if (parserInput.finished) { + break; + } + if (parserInput.peek('}')) { + break; + } + node = this.extendRule(); + if (node) { + root = root.concat(node); + continue; + } + node = mixin.definition() || this.declaration() || mixin.call(false, false) || + this.ruleset() || this.variableCall() || this.entities.call() || this.atrule(); + if (node) { + root.push(node); + } + else { + var foundSemiColon = false; + while (parserInput.$char(';')) { + foundSemiColon = true; + } + if (!foundSemiColon) { + break; + } + } } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - variadic: true - }); - break; - } - - arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); - } - - if (!arg || !hasSep) { - break; - } - - nameLoop = null; - - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { - if (parserInput.$char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeparated) { - error('Cannot mix ; and , as delimiter types'); - } - - expressionContainsNamed = true; + return root; + }, + // comments are collected by the main parsing mechanism and then assigned to nodes + // where the current structure allows it + comment: function () { + if (parserInput.commentStore.length) { + var comment = parserInput.commentStore.shift(); + return new (tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo); } - - value = parsers.detachedRuleset() || parsers.expression(); - - if (!value) { - if (isCall) { - error('could not understand value for named argument'); - } else { + }, + // + // Entities are tokens which can be found inside an Expression + // + entities: { + mixinLookup: function () { + return parsers.mixin.call(true, true); + }, + // + // A string, which supports escaping " and ' + // + // "milky way" 'he\'s the one!' + // + quoted: function (forceEscaped) { + var str; + var index = parserInput.i; + var isEscaped = false; + parserInput.save(); + if (parserInput.$char('~')) { + isEscaped = true; + } + else if (forceEscaped) { + parserInput.restore(); + return; + } + str = parserInput.$quoted(); + if (!str) { + parserInput.restore(); + return; + } + parserInput.forget(); + return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); + }, + // + // A catch-all word, such as: + // + // black border-collapse + // + keyword: function () { + var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); + if (k) { + return tree.Color.fromKeyword(k) || new (tree.Keyword)(k); + } + }, + // + // A function call + // + // rgb(255, 0, 255) + // + // The arguments are parsed with the `entities.arguments` parser. + // + call: function () { + var name; + var args; + var func; + var index = parserInput.i; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (parserInput.peek(/^url\(/i)) { + return; + } + parserInput.save(); + name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); + if (!name) { + parserInput.forget(); + return; + } + name = name[1]; + func = this.customFuncCall(name); + if (func) { + args = func.parse(); + if (args && func.stop) { + parserInput.forget(); + return args; + } + } + args = this.arguments(args); + if (!parserInput.$char(')')) { + parserInput.restore('Could not parse call arguments or missing \')\''); + return; + } + parserInput.forget(); + return new (tree.Call)(name, args, index, fileInfo); + }, + // + // Parsing rules for functions with non-standard args, e.g.: + // + // boolean(not(2 > 1)) + // + // This is a quick prototype, to be modified/improved when + // more custom-parsed funcs come (e.g. `selector(...)`) + // + customFuncCall: function (name) { + /* Ideally the table is to be moved out of here for faster perf., + but it's quite tricky since it relies on all these `parsers` + and `expect` available only here */ + return { + alpha: f(parsers.ieAlpha, true), + boolean: f(condition), + 'if': f(condition) + }[name.toLowerCase()]; + function f(parse, stop) { + return { + parse: parse, + stop: stop // when true - stop after parse() and return its result, + // otherwise continue for plain args + }; + } + function condition() { + return [expect(parsers.condition, 'expected condition')]; + } + }, + arguments: function (prevArgs) { + var argsComma = prevArgs || []; + var argsSemiColon = []; + var isSemiColonSeparated; + var value; + parserInput.save(); + while (true) { + if (prevArgs) { + prevArgs = false; + } + else { + value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); + if (!value) { + break; + } + if (value.value && value.value.length == 1) { + value = value.value[0]; + } + argsComma.push(value); + } + if (parserInput.$char(',')) { + continue; + } + if (parserInput.$char(';') || isSemiColonSeparated) { + isSemiColonSeparated = true; + value = (argsComma.length < 1) ? argsComma[0] + : new tree.Value(argsComma); + argsSemiColon.push(value); + argsComma = []; + } + } + parserInput.forget(); + return isSemiColonSeparated ? argsSemiColon : argsComma; + }, + literal: function () { + return this.dimension() || + this.color() || + this.quoted() || + this.unicodeDescriptor(); + }, + // Assignments are argument entities for calls. + // They are present in ie filter properties as shown below. + // + // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) + // + assignment: function () { + var key; + var value; + parserInput.save(); + key = parserInput.$re(/^\w+(?=\s?=)/i); + if (!key) { + parserInput.restore(); + return; + } + if (!parserInput.$char('=')) { + parserInput.restore(); + return; + } + value = parsers.entity(); + if (value) { + parserInput.forget(); + return new (tree.Assignment)(key, value); + } + else { + parserInput.restore(); + } + }, + // + // Parse url() tokens + // + // We use a specific rule for urls, because they don't really behave like + // standard function calls. The difference is that the argument doesn't have + // to be enclosed within a string, so it can't be parsed as an Expression. + // + url: function () { + var value; + var index = parserInput.i; + parserInput.autoCommentAbsorb = false; + if (!parserInput.$str('url(')) { + parserInput.autoCommentAbsorb = true; + return; + } + value = this.quoted() || this.variable() || this.property() || + parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; + parserInput.autoCommentAbsorb = true; + expectChar(')'); + return new (tree.URL)((value.value != null || + value instanceof tree.Variable || + value instanceof tree.Property) ? + value : new (tree.Anonymous)(value, index), index, fileInfo); + }, + // + // A Variable entity, such as `@fink`, in + // + // width: @fink + 2px + // + // We use a different parser for variable definitions, + // see `parsers.variable`. + // + variable: function () { + var ch; + var name; + var index = parserInput.i; + parserInput.save(); + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { + ch = parserInput.currentChar(); + if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { + // this may be a VariableCall lookup + var result = parsers.variableCall(name); + if (result) { + parserInput.forget(); + return result; + } + } + parserInput.forget(); + return new (tree.Variable)(name, index, fileInfo); + } + parserInput.restore(); + }, + // A variable entity using the protective {} e.g. @{var} + variableCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { + return new (tree.Variable)("@" + curly[1], index, fileInfo); + } + }, + // + // A Property accessor, such as `$color`, in + // + // background-color: $color + // + property: function () { + var name; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { + return new (tree.Property)(name, index, fileInfo); + } + }, + // A property entity useing the protective {} e.g. ${prop} + propertyCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { + return new (tree.Property)("$" + curly[1], index, fileInfo); + } + }, + // + // A Hexadecimal color + // + // #4F3C2F + // + // `rgb` and `hsl` colors are parsed through the `entities.call` parser. + // + color: function () { + var rgb; + parserInput.save(); + if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { + if (!rgb[2]) { + parserInput.forget(); + return new (tree.Color)(rgb[1], undefined, rgb[0]); + } + } + parserInput.restore(); + }, + colorKeyword: function () { + parserInput.save(); + var autoCommentAbsorb = parserInput.autoCommentAbsorb; + parserInput.autoCommentAbsorb = false; + var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); + parserInput.autoCommentAbsorb = autoCommentAbsorb; + if (!k) { + parserInput.forget(); + return; + } + parserInput.restore(); + var color = tree.Color.fromKeyword(k); + if (color) { + parserInput.$str(k); + return color; + } + }, + // + // A Dimension, that is, a number and a unit + // + // 0.5em 95% + // + dimension: function () { + if (parserInput.peekNotNumeric()) { + return; + } + var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); + if (value) { + return new (tree.Dimension)(value[1], value[2]); + } + }, + // + // A unicode descriptor, as is used in unicode-range + // + // U+0?? or U+00A1-00A9 + // + unicodeDescriptor: function () { + var ud; + ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + if (ud) { + return new (tree.UnicodeDescriptor)(ud[0]); + } + }, + // + // JavaScript code to be evaluated + // + // `window.location.href` + // + javascript: function () { + var js; + var index = parserInput.i; + parserInput.save(); + var escape = parserInput.$char('~'); + var jsQuote = parserInput.$char('`'); + if (!jsQuote) { + parserInput.restore(); + return; + } + js = parserInput.$re(/^[^`]*`/); + if (js) { + parserInput.forget(); + return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); + } + parserInput.restore('invalid javascript definition'); + } + }, + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink: + // + variable: function () { + var name; + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { + return name[1]; + } + }, + // + // Call a variable value to retrieve a detached ruleset + // or a value from a detached ruleset's rules. + // + // @fink(); + // @fink; + // color: @fink[@color]; + // + variableCall: function (parsedName) { + var lookups; + var i = parserInput.i; + var inValue = !!parsedName; + var name = parsedName; + parserInput.save(); + if (name || (parserInput.currentChar() === '@' + && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) { + lookups = this.mixin.ruleLookups(); + if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) { + parserInput.restore('Missing \'[...]\' lookup in variable call'); + return; + } + if (!inValue) { + name = name[1]; + } + var call = new tree.VariableCall(name, i, fileInfo); + if (!inValue && parsers.end()) { + parserInput.forget(); + return call; + } + else { + parserInput.forget(); + return new tree.NamespaceValue(call, lookups, i, fileInfo); + } + } + parserInput.restore(); + }, + // + // extend syntax - used to extend selectors + // + extend: function (isRule) { + var elements; + var e; + var index = parserInput.i; + var option; + var extendList; + var extend; + if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { + return; + } + do { + option = null; + elements = null; + while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { + e = this.element(); + if (!e) { + break; + } + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + } + option = option && option[1]; + if (!elements) { + error('Missing target selector for :extend().'); + } + extend = new (tree.Extend)(new (tree.Selector)(elements), option, index, fileInfo); + if (extendList) { + extendList.push(extend); + } + else { + extendList = [extend]; + } + } while (parserInput.$char(',')); + expect(/^\)/); + if (isRule) { + expect(/^;/); + } + return extendList; + }, + // + // extendRule - used in a rule to extend all the parent selectors + // + extendRule: function () { + return this.extend(true); + }, + // + // Mixins + // + mixin: { + // + // A Mixin call, with an optional argument list + // + // #mixins > .square(#fff); + // #mixins.square(#fff); + // .rounded(4px, black); + // .button; + // + // We can lookup / return a value using the lookup syntax: + // + // color: #mixin.square(#fff)[@color]; + // + // The `while` loop is there because mixins can be + // namespaced, but we only support the child and descendant + // selector for now. + // + call: function (inValue, getLookup) { + var s = parserInput.currentChar(); + var important = false; + var lookups; + var index = parserInput.i; + var elements; + var args; + var hasParens; + if (s !== '.' && s !== '#') { + return; + } + parserInput.save(); // stop us absorbing part of an invalid selector + elements = this.elements(); + if (elements) { + if (parserInput.$char('(')) { + args = this.args(true).args; + expectChar(')'); + hasParens = true; + } + if (getLookup !== false) { + lookups = this.ruleLookups(); + } + if (getLookup === true && !lookups) { + parserInput.restore(); + return; + } + if (inValue && !lookups && !hasParens) { + // This isn't a valid in-value mixin call + parserInput.restore(); + return; + } + if (!inValue && parsers.important()) { + important = true; + } + if (inValue || parsers.end()) { + parserInput.forget(); + var mixin = new (tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important); + if (lookups) { + return new tree.NamespaceValue(mixin, lookups); + } + else { + return mixin; + } + } + } parserInput.restore(); - returner.args = []; + }, + /** + * Matching elements for mixins + * (Start with . or # and can have > ) + */ + elements: function () { + var elements; + var e; + var c; + var elem; + var elemIndex; + var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; + while (true) { + elemIndex = parserInput.i; + e = parserInput.$re(re); + if (!e) { + break; + } + elem = new (tree.Element)(c, e, false, elemIndex, fileInfo); + if (elements) { + elements.push(elem); + } + else { + elements = [elem]; + } + c = parserInput.$char('>'); + } + return elements; + }, + args: function (isCall) { + var entities = parsers.entities; + var returner = { args: null, variadic: false }; + var expressions = []; + var argsSemiColon = []; + var argsComma = []; + var isSemiColonSeparated; + var expressionContainsNamed; + var name; + var nameLoop; + var value; + var arg; + var expand; + var hasSep = true; + parserInput.save(); + while (true) { + if (isCall) { + arg = parsers.detachedRuleset() || parsers.expression(); + } + else { + parserInput.commentStore.length = 0; + if (parserInput.$str('...')) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ variadic: true }); + break; + } + arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); + } + if (!arg || !hasSep) { + break; + } + nameLoop = null; + if (arg.throwAwayComments) { + arg.throwAwayComments(); + } + value = arg; + var val = null; + if (isCall) { + // Variable + if (arg.value && arg.value.length == 1) { + val = arg.value[0]; + } + } + else { + val = arg; + } + if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { + if (parserInput.$char(':')) { + if (expressions.length > 0) { + if (isSemiColonSeparated) { + error('Cannot mix ; and , as delimiter types'); + } + expressionContainsNamed = true; + } + value = parsers.detachedRuleset() || parsers.expression(); + if (!value) { + if (isCall) { + error('could not understand value for named argument'); + } + else { + parserInput.restore(); + returner.args = []; + return returner; + } + } + nameLoop = (name = val.name); + } + else if (parserInput.$str('...')) { + if (!isCall) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ name: arg.name, variadic: true }); + break; + } + else { + expand = true; + } + } + else if (!isCall) { + name = nameLoop = val.name; + value = null; + } + } + if (value) { + expressions.push(value); + } + argsComma.push({ name: nameLoop, value: value, expand: expand }); + if (parserInput.$char(',')) { + hasSep = true; + continue; + } + hasSep = parserInput.$char(';') === ';'; + if (hasSep || isSemiColonSeparated) { + if (expressionContainsNamed) { + error('Cannot mix ; and , as delimiter types'); + } + isSemiColonSeparated = true; + if (expressions.length > 1) { + value = new (tree.Value)(expressions); + } + argsSemiColon.push({ name: name, value: value, expand: expand }); + name = null; + expressions = []; + expressionContainsNamed = false; + } + } + parserInput.forget(); + returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; return returner; - } + }, + // + // A Mixin definition, with a list of parameters + // + // .rounded (@radius: 2px, @color) { + // ... + // } + // + // Until we have a finer grained state-machine, we have to + // do a look-ahead, to make sure we don't have a mixin call. + // See the `rule` function for more information. + // + // We start by matching `.rounded (`, and then proceed on to + // the argument list, which has optional default values. + // We store the parameters in `params`, with a `value` key, + // if there is a value, such as in the case of `@radius`. + // + // Once we've got our params list, and a closing `)`, we parse + // the `{...}` block. + // + definition: function () { + var name; + var params = []; + var match; + var ruleset; + var cond; + var variadic = false; + if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') || + parserInput.peek(/^[^{]*\}/)) { + return; + } + parserInput.save(); + match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); + if (match) { + name = match[1]; + var argInfo = this.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + // .mixincall("@{a}"); + // looks a bit like a mixin definition.. + // also + // .mixincall(@a: {rule: set;}); + // so we have to be nice and restore + if (!parserInput.$char(')')) { + parserInput.restore('Missing closing \')\''); + return; + } + parserInput.commentStore.length = 0; + if (parserInput.$str('when')) { // Guard + cond = expect(parsers.conditions, 'expected condition'); + } + ruleset = parsers.block(); + if (ruleset) { + parserInput.forget(); + return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + ruleLookups: function () { + var rule; + var lookups = []; + if (parserInput.currentChar() !== '[') { + return; + } + while (true) { + parserInput.save(); + rule = this.lookupValue(); + if (!rule && rule !== '') { + parserInput.restore(); + break; + } + lookups.push(rule); + parserInput.forget(); + } + if (lookups.length > 0) { + return lookups; + } + }, + lookupValue: function () { + parserInput.save(); + if (!parserInput.$char('[')) { + parserInput.restore(); + return; + } + var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); + if (!parserInput.$char(']')) { + parserInput.restore(); + return; + } + if (name || name === '') { + parserInput.forget(); + return name; + } + parserInput.restore(); } - - nameLoop = name = val.name; - } else if (parserInput.$str('...')) { - if (!isCall) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; - } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - name: arg.name, - variadic: true - }); - break; - } else { - expand = true; - } - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } + }, + // + // Entities are the smallest recognized token, + // and can be found inside a rule's value. + // + entity: function () { + var entities = this.entities; + return this.comment() || entities.literal() || entities.variable() || entities.url() || + entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || + entities.javascript(); + }, + // + // A Declaration terminator. Note that we use `peek()` to check for '}', + // because the `block` rule will be expecting it, but we still need to make sure + // it's there, if ';' was omitted. + // + end: function () { + return parserInput.$char(';') || parserInput.peek('}'); + }, + // + // IE's alpha function + // + // alpha(opacity=88) + // + ieAlpha: function () { + var value; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (!parserInput.$re(/^opacity=/i)) { + return; + } + value = parserInput.$re(/^\d+/); + if (!value) { + value = expect(parsers.entities.variable, 'Could not parse alpha'); + value = "@{" + value.name.slice(1) + "}"; + } + expectChar(')'); + return new tree.Quoted('', "alpha(opacity=" + value + ")"); + }, + // + // A Selector Element + // + // div + // + h1 + // #socks + // input[type="text"] + // + // Elements are the building blocks for Selectors, + // they are made out of a `Combinator` (see combinator rule), + // and an element name, such as a tag a class, or `*`. + // + element: function () { + var e; + var c; + var v; + var index = parserInput.i; + c = this.combinator(); + e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || + parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || + parserInput.$char('*') || parserInput.$char('&') || this.attribute() || + parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || + this.entities.variableCurly(); + if (!e) { + parserInput.save(); + if (parserInput.$char('(')) { + if ((v = this.selector(false)) && parserInput.$char(')')) { + e = new (tree.Paren)(v); + parserInput.forget(); + } + else { + parserInput.restore('Missing closing \')\''); + } + } + else { + parserInput.forget(); + } + } + if (e) { + return new (tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo); + } + }, + // + // Combinators combine elements together, in a Selector. + // + // Because our parser isn't white-space sensitive, special care + // has to be taken, when parsing the descendant combinator, ` `, + // as it's an empty space. We have to check the previous character + // in the input, to see if it's a ` ` character. More info on how + // we deal with this in *combinator.js*. + // + combinator: function () { + var c = parserInput.currentChar(); + if (c === '/') { + parserInput.save(); + var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); + if (slashedCombinator) { + parserInput.forget(); + return new (tree.Combinator)(slashedCombinator); + } + parserInput.restore(); + } + if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { + parserInput.i++; + if (c === '^' && parserInput.currentChar() === '^') { + c = '^^'; + parserInput.i++; + } + while (parserInput.isWhitespace()) { + parserInput.i++; + } + return new (tree.Combinator)(c); + } + else if (parserInput.isWhitespace(-1)) { + return new (tree.Combinator)(' '); + } + else { + return new (tree.Combinator)(null); + } + }, + // + // A CSS Selector + // with less extensions e.g. the ability to extend and guard + // + // .class > div + h1 + // li a:hover + // + // Selectors are made out of one or more Elements, see above. + // + selector: function (isLess) { + var index = parserInput.i; + var elements; + var extendList; + var c; + var e; + var allExtends; + var when; + var condition; + isLess = isLess !== false; + while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) { + if (when) { + condition = expect(this.conditions, 'expected condition'); + } + else if (condition) { + error('CSS guard can only be used at the end of selector'); + } + else if (extendList) { + if (allExtends) { + allExtends = allExtends.concat(extendList); + } + else { + allExtends = extendList; + } + } + else { + if (allExtends) { + error('Extend can only be used at the end of selector'); + } + c = parserInput.currentChar(); + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + e = null; + } + if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { + break; + } + } + if (elements) { + return new (tree.Selector)(elements, allExtends, condition, index, fileInfo); + } + if (allExtends) { + error('Extend must be used to extend a selector, it cannot be used on its own'); + } + }, + selectors: function () { + var s; + var selectors; + while (true) { + s = this.selector(); + if (!s) { + break; + } + if (selectors) { + selectors.push(s); + } + else { + selectors = [s]; + } + parserInput.commentStore.length = 0; + if (s.condition && selectors.length > 1) { + error("Guards are only currently allowed on a single selector."); + } + if (!parserInput.$char(',')) { + break; + } + if (s.condition) { + error("Guards are only currently allowed on a single selector."); + } + parserInput.commentStore.length = 0; + } + return selectors; + }, + attribute: function () { + if (!parserInput.$char('[')) { + return; + } + var entities = this.entities; + var key; + var val; + var op; + if (!(key = entities.variableCurly())) { + key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + } + op = parserInput.$re(/^[|~*$^]?=/); + if (op) { + val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); + } + expectChar(']'); + return new (tree.Attribute)(key, op, val); + }, + // + // The `block` rule is used by `ruleset` and `mixin.definition`. + // It's a wrapper around the `primary` rule, with added `{}`. + // + block: function () { + var content; + if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { + return content; + } + }, + blockRuleset: function () { + var block = this.block(); + if (block) { + block = new tree.Ruleset(null, block); + } + return block; + }, + detachedRuleset: function () { + var argInfo; + var params; + var variadic; + parserInput.save(); + if (parserInput.$re(/^[.#]\(/)) { + /** + * DR args currently only implemented for each() function, and not + * yet settable as `@dr: #(@arg) {}` + * This should be done when DRs are merged with mixins. + * See: https://github.com/less/less-meta/issues/16 + */ + argInfo = this.mixin.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + } + var blockRuleset = this.blockRuleset(); + if (blockRuleset) { + parserInput.forget(); + if (params) { + return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); + } + return new tree.DetachedRuleset(blockRuleset); + } + parserInput.restore(); + }, + // + // div, .class, body > p {...} + // + ruleset: function () { + var selectors; + var rules; + var debugInfo; + parserInput.save(); + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(parserInput.i); + } + selectors = this.selectors(); + if (selectors && (rules = this.block())) { + parserInput.forget(); + var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports); + if (context.dumpLineNumbers) { + ruleset.debugInfo = debugInfo; + } + return ruleset; + } + else { + parserInput.restore(); + } + }, + declaration: function () { + var name; + var value; + var index = parserInput.i; + var hasDR; + var c = parserInput.currentChar(); + var important; + var merge; + var isVariable; + if (c === '.' || c === '#' || c === '&' || c === ':') { + return; + } + parserInput.save(); + name = this.variable() || this.ruleProperty(); + if (name) { + isVariable = typeof name === 'string'; + if (isVariable) { + value = this.detachedRuleset(); + if (value) { + hasDR = true; + } + } + parserInput.commentStore.length = 0; + if (!value) { + // a name returned by this.ruleProperty() is always an array of the form: + // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] + // where each item is a tree.Keyword or tree.Variable + merge = !isVariable && name.length > 1 && name.pop().value; + // Custom property values get permissive parsing + if (name[0].value && name[0].value.slice(0, 2) === '--') { + value = this.permissiveValue(); + } + // Try to store values as anonymous + // If we need the value later we'll re-parse it in ruleset.parseValue + else { + value = this.anonymousValue(); + } + if (value) { + parserInput.forget(); + // anonymous values absorb the end ';' which is required for them to work + return new (tree.Declaration)(name, value, false, merge, index, fileInfo); + } + if (!value) { + value = this.value(); + } + if (value) { + important = this.important(); + } + else if (isVariable) { + // As a last resort, try permissiveValue + value = this.permissiveValue(); + } + } + if (value && (this.end() || hasDR)) { + parserInput.forget(); + return new (tree.Declaration)(name, value, important, merge, index, fileInfo); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + anonymousValue: function () { + var index = parserInput.i; + var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); + if (match) { + return new (tree.Anonymous)(match[1], index); + } + }, + /** + * Used for custom properties, at-rules, and variables (as fallback) + * Parses almost anything inside of {} [] () "" blocks + * until it reaches outer-most tokens. + * + * First, it will try to parse comments and entities to reach + * the end. This is mostly like the Expression parser except no + * math is allowed. + */ + permissiveValue: function (untilTokens) { + var i; + var e; + var done; + var value; + var tok = untilTokens || ';'; + var index = parserInput.i; + var result = []; + function testCurrentChar() { + var char = parserInput.currentChar(); + if (typeof tok === 'string') { + return char === tok; + } + else { + return tok.test(char); + } + } + if (testCurrentChar()) { + return; + } + value = []; + do { + e = this.comment(); + if (e) { + value.push(e); + continue; + } + e = this.entity(); + if (e) { + value.push(e); + } + } while (e); + done = testCurrentChar(); + if (value.length > 0) { + value = new (tree.Expression)(value); + if (done) { + return value; + } + else { + result.push(value); + } + // Preserve space before $parseUntil as it will not + if (parserInput.prevChar() === ' ') { + result.push(new tree.Anonymous(' ', index)); + } + } + parserInput.save(); + value = parserInput.$parseUntil(tok); + if (value) { + if (typeof value === 'string') { + error("Expected '" + value + "'", 'Parse'); + } + if (value.length === 1 && value[0] === ' ') { + parserInput.forget(); + return new tree.Anonymous('', index); + } + var item = void 0; + for (i = 0; i < value.length; i++) { + item = value[i]; + if (Array.isArray(item)) { + // Treat actual quotes as normal quoted values + result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); + } + else { + if (i === value.length - 1) { + item = item.trim(); + } + // Treat like quoted values, but replace vars like unquoted expressions + var quote = new tree.Quoted('\'', item, true, index, fileInfo); + quote.variableRegex = /@([\w-]+)/g; + quote.propRegex = /\$([\w-]+)/g; + result.push(quote); + } + } + parserInput.forget(); + return new tree.Expression(result, true); + } + parserInput.restore(); + }, + // + // An @import atrule + // + // @import "lib"; + // + // Depending on our environment, importing is done differently: + // In the browser, it's an XHR request, in Node, it would be a + // file-system operation. The function used for importing is + // stored in `import`, which we pass to the Import constructor. + // + 'import': function () { + var path; + var features; + var index = parserInput.i; + var dir = parserInput.$re(/^@import?\s+/); + if (dir) { + var options_1 = (dir ? this.importOptions() : null) || {}; + if ((path = this.entities.quoted() || this.entities.url())) { + features = this.mediaFeatures(); + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon or unrecognised media features on import'); + } + features = features && new (tree.Value)(features); + return new (tree.Import)(path, features, options_1, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed import statement'); + } + } + }, + importOptions: function () { + var o; + var options = {}; + var optionName; + var value; + // list of options, surrounded by parens + if (!parserInput.$char('(')) { + return null; + } + do { + o = this.importOption(); + if (o) { + optionName = o; + value = true; + switch (optionName) { + case 'css': + optionName = 'less'; + value = false; + break; + case 'once': + optionName = 'multiple'; + value = false; + break; + } + options[optionName] = value; + if (!parserInput.$char(',')) { + break; + } + } + } while (o); + expectChar(')'); + return options; + }, + importOption: function () { + var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); + if (opt) { + return opt[1]; + } + }, + mediaFeature: function () { + var entities = this.entities; + var nodes = []; + var e; + var p; + parserInput.save(); + do { + e = entities.keyword() || entities.variable() || entities.mixinLookup(); + if (e) { + nodes.push(e); + } + else if (parserInput.$char('(')) { + p = this.property(); + e = this.value(); + if (parserInput.$char(')')) { + if (p && e) { + nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true))); + } + else if (e) { + nodes.push(new (tree.Paren)(e)); + } + else { + error('badly formed media feature definition'); + } + } + else { + error('Missing closing \')\'', 'Parse'); + } + } + } while (e); + parserInput.forget(); + if (nodes.length > 0) { + return new (tree.Expression)(nodes); + } + }, + mediaFeatures: function () { + var entities = this.entities; + var features = []; + var e; + do { + e = this.mediaFeature(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + else { + e = entities.variable() || entities.mixinLookup(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } + } while (e); + return features.length > 0 ? features : null; + }, + media: function () { + var features; + var rules; + var media; + var debugInfo; + var index = parserInput.i; + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(index); + } + parserInput.save(); + if (parserInput.$str('@media')) { + features = this.mediaFeatures(); + rules = this.block(); + if (!rules) { + error('media definitions require block statements after any features'); + } + parserInput.forget(); + media = new (tree.Media)(rules, features, index, fileInfo); + if (context.dumpLineNumbers) { + media.debugInfo = debugInfo; + } + return media; + } + parserInput.restore(); + }, + // + // A @plugin directive, used to import plugins dynamically. + // + // @plugin (args) "lib"; + // + plugin: function () { + var path; + var args; + var options; + var index = parserInput.i; + var dir = parserInput.$re(/^@plugin?\s+/); + if (dir) { + args = this.pluginArgs(); + if (args) { + options = { + pluginArgs: args, + isPlugin: true + }; + } + else { + options = { isPlugin: true }; + } + if ((path = this.entities.quoted() || this.entities.url())) { + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon on @plugin'); + } + return new (tree.Import)(path, null, options, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed @plugin statement'); + } + } + }, + pluginArgs: function () { + // list of options, surrounded by parens + parserInput.save(); + if (!parserInput.$char('(')) { + parserInput.restore(); + return null; + } + var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); + if (args[1]) { + parserInput.forget(); + return args[1].trim(); + } + else { + parserInput.restore(); + return null; + } + }, + // + // A CSS AtRule + // + // @charset "utf-8"; + // + atrule: function () { + var index = parserInput.i; + var name; + var value; + var rules; + var nonVendorSpecificName; + var hasIdentifier; + var hasExpression; + var hasUnknown; + var hasBlock = true; + var isRooted = true; + if (parserInput.currentChar() !== '@') { + return; + } + value = this['import']() || this.plugin() || this.media(); + if (value) { + return value; + } + parserInput.save(); + name = parserInput.$re(/^@[a-z-]+/); + if (!name) { + return; + } + nonVendorSpecificName = name; + if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { + nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); + } + switch (nonVendorSpecificName) { + case '@charset': + hasIdentifier = true; + hasBlock = false; + break; + case '@namespace': + hasExpression = true; + hasBlock = false; + break; + case '@keyframes': + case '@counter-style': + hasIdentifier = true; + break; + case '@document': + case '@supports': + hasUnknown = true; + isRooted = false; + break; + default: + hasUnknown = true; + break; + } + parserInput.commentStore.length = 0; + if (hasIdentifier) { + value = this.entity(); + if (!value) { + error("expected " + name + " identifier"); + } + } + else if (hasExpression) { + value = this.expression(); + if (!value) { + error("expected " + name + " expression"); + } + } + else if (hasUnknown) { + value = this.permissiveValue(/^[{;]/); + hasBlock = (parserInput.currentChar() === '{'); + if (!value) { + if (!hasBlock && parserInput.currentChar() !== ';') { + error(name + " rule is missing block or ending semi-colon"); + } + } + else if (!value.value) { + value = null; + } + } + if (hasBlock) { + rules = this.blockRuleset(); + } + if (rules || (!hasBlock && value && parserInput.$char(';'))) { + parserInput.forget(); + return new (tree.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); + } + parserInput.restore('at-rule options not recognised'); + }, + // + // A Value is a comma-delimited list of Expressions + // + // font-family: Baskerville, Georgia, serif; + // + // In a Rule, a Value represents everything after the `:`, + // and before the `;`. + // + value: function () { + var e; + var expressions = []; + var index = parserInput.i; + do { + e = this.expression(); + if (e) { + expressions.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } while (e); + if (expressions.length > 0) { + return new (tree.Value)(expressions, index); + } + }, + important: function () { + if (parserInput.currentChar() === '!') { + return parserInput.$re(/^! *important/); + } + }, + sub: function () { + var a; + var e; + parserInput.save(); + if (parserInput.$char('(')) { + a = this.addition(); + if (a && parserInput.$char(')')) { + parserInput.forget(); + e = new (tree.Expression)([a]); + e.parens = true; + return e; + } + parserInput.restore('Expected \')\''); + return; + } + parserInput.restore(); + }, + multiplication: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.operand(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + if (parserInput.peek(/^\/[*\/]/)) { + break; + } + parserInput.save(); + op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); + if (!op) { + parserInput.forget(); + break; + } + a = this.operand(); + if (!a) { + parserInput.restore(); + break; + } + parserInput.forget(); + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + addition: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.multiplication(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-'))); + if (!op) { + break; + } + a = this.multiplication(); + if (!a) { + break; + } + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + conditions: function () { + var a; + var b; + var index = parserInput.i; + var condition; + a = this.condition(true); + if (a) { + while (true) { + if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { + break; + } + b = this.condition(true); + if (!b) { + break; + } + condition = new (tree.Condition)('or', condition || a, b, index); + } + return condition || a; + } + }, + condition: function (needsParens) { + var result; + var logical; + var next; + function or() { + return parserInput.$str('or'); + } + result = this.conditionAnd(needsParens); + if (!result) { + return; + } + logical = or(); + if (logical) { + next = this.condition(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + conditionAnd: function (needsParens) { + var result; + var logical; + var next; + var self = this; + function insideCondition() { + var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); + if (!cond && !needsParens) { + return self.atomicCondition(needsParens); + } + return cond; + } + function and() { + return parserInput.$str('and'); + } + result = insideCondition(); + if (!result) { + return; + } + logical = and(); + if (logical) { + next = this.conditionAnd(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + negatedCondition: function (needsParens) { + if (parserInput.$str('not')) { + var result = this.parenthesisCondition(needsParens); + if (result) { + result.negate = !result.negate; + } + return result; + } + }, + parenthesisCondition: function (needsParens) { + function tryConditionFollowedByParenthesis(me) { + var body; + parserInput.save(); + body = me.condition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + parserInput.forget(); + return body; + } + var body; + parserInput.save(); + if (!parserInput.$str('(')) { + parserInput.restore(); + return; + } + body = tryConditionFollowedByParenthesis(this); + if (body) { + parserInput.forget(); + return body; + } + body = this.atomicCondition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'"); + return; + } + parserInput.forget(); + return body; + }, + atomicCondition: function (needsParens) { + var entities = this.entities; + var index = parserInput.i; + var a; + var b; + var c; + var op; + function cond() { + return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); + } + cond = cond.bind(this); + a = cond(); + if (a) { + if (parserInput.$char('>')) { + if (parserInput.$char('=')) { + op = '>='; + } + else { + op = '>'; + } + } + else if (parserInput.$char('<')) { + if (parserInput.$char('=')) { + op = '<='; + } + else { + op = '<'; + } + } + else if (parserInput.$char('=')) { + if (parserInput.$char('>')) { + op = '=>'; + } + else if (parserInput.$char('<')) { + op = '=<'; + } + else { + op = '='; + } + } + if (op) { + b = cond(); + if (b) { + c = new (tree.Condition)(op, a, b, index, false); + } + else { + error('expected expression'); + } + } + else { + c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, false); + } + return c; + } + }, + // + // An operand is anything that can be part of an operation, + // such as a Color, or a Variable + // + operand: function () { + var entities = this.entities; + var negate; + if (parserInput.peek(/^-[@\$\(]/)) { + negate = parserInput.$char('-'); + } + var o = this.sub() || entities.dimension() || + entities.color() || entities.variable() || + entities.property() || entities.call() || + entities.quoted(true) || entities.colorKeyword() || + entities.mixinLookup(); + if (negate) { + o.parensInOp = true; + o = new (tree.Negative)(o); + } + return o; + }, + // + // Expressions either represent mathematical operations, + // or white-space delimited Entities. + // + // 1px solid black + // @var * 2 + // + expression: function () { + var entities = []; + var e; + var delim; + var index = parserInput.i; + do { + e = this.comment(); + if (e) { + entities.push(e); + continue; + } + e = this.addition() || this.entity(); + if (e) { + entities.push(e); + // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here + if (!parserInput.peek(/^\/[\/*]/)) { + delim = parserInput.$char('/'); + if (delim) { + entities.push(new (tree.Anonymous)(delim, index)); + } + } + } + } while (e); + if (entities.length > 0) { + return new (tree.Expression)(entities); + } + }, + property: function () { + var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); + if (name) { + return name[1]; + } + }, + ruleProperty: function () { + var name = []; + var index = []; + var s; + var k; + parserInput.save(); + var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); + if (simpleProperty) { + name = [new (tree.Keyword)(simpleProperty[1])]; + parserInput.forget(); + return name; + } + function match(re) { + var i = parserInput.i; + var chunk = parserInput.$re(re); + if (chunk) { + index.push(i); + return name.push(chunk[1]); + } + } + match(/^(\*?)/); + while (true) { + if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { + break; + } + } + if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) { + parserInput.forget(); + // at last, we have the complete match now. move forward, + // convert name particles to tree objects and return: + if (name[0] === '') { + name.shift(); + index.shift(); + } + for (k = 0; k < name.length; k++) { + s = name[k]; + name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ? + new (tree.Keyword)(s) : + (s.charAt(0) === '@' ? + new (tree.Variable)("@" + s.slice(2, -1), index[k], fileInfo) : + new (tree.Property)("$" + s.slice(2, -1), index[k], fileInfo)); + } + return name; + } + parserInput.restore(); } - - if (value) { - expressions.push(value); - } - - argsComma.push({ - name: nameLoop, - value, - expand - }); - - if (parserInput.$char(',')) { - hasSep = true; - continue; - } - - hasSep = parserInput.$char(';') === ';'; - - if (hasSep || isSemiColonSeparated) { - if (expressionContainsNamed) { - error('Cannot mix ; and , as delimiter types'); - } - - isSemiColonSeparated = true; - - if (expressions.length > 1) { - value = new tree.Value(expressions); - } - - argsSemiColon.push({ - name, - value, - expand - }); - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - parserInput.forget(); - returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function definition() { - var name; - var params = []; - var match; - var ruleset; - var cond; - var variadic = false; - - if (parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#' || parserInput.peek(/^[^{]*\}/)) { - return; - } - - parserInput.save(); - match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - - if (match) { - name = match[1]; - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - - if (!parserInput.$char(')')) { - parserInput.restore('Missing closing \')\''); - return; - } - - parserInput.commentStore.length = 0; - - if (parserInput.$str('when')) { - // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - parserInput.forget(); - return new tree.mixin.Definition(name, params, ruleset, cond, variadic); - } else { - parserInput.restore(); - } - } else { - parserInput.forget(); - } - }, - ruleLookups: function ruleLookups() { - var rule; - var lookups = []; - - if (parserInput.currentChar() !== '[') { - return; - } - - while (true) { - parserInput.save(); - rule = this.lookupValue(); - - if (!rule && rule !== '') { - parserInput.restore(); - break; - } - - lookups.push(rule); - parserInput.forget(); - } - - if (lookups.length > 0) { - return lookups; - } - }, - lookupValue: function lookupValue() { - parserInput.save(); - - if (!parserInput.$char('[')) { - parserInput.restore(); - return; - } - - var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); - - if (!parserInput.$char(']')) { - parserInput.restore(); - return; - } - - if (name || name === '') { - parserInput.forget(); - return name; - } - - parserInput.restore(); - } - }, - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function entity() { - var entities = this.entities; - return this.comment() || entities.literal() || entities.variable() || entities.url() || entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || entities.javascript(); - }, - // - // A Declaration terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was omitted. - // - end: function end() { - return parserInput.$char(';') || parserInput.peek('}'); - }, - // - // IE's alpha function - // - // alpha(opacity=88) - // - ieAlpha: function ieAlpha() { - var value; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (!parserInput.$re(/^opacity=/i)) { - return; - } - - value = parserInput.$re(/^\d+/); - - if (!value) { - value = expect(parsers.entities.variable, 'Could not parse alpha'); - value = `@{${value.name.slice(1)}}`; - } - - expectChar(')'); - return new tree.Quoted('', `alpha(opacity=${value})`); - }, - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function element() { - var e; - var c; - var v; - var index = parserInput.i; - c = this.combinator(); - e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || this.entities.variableCurly(); - - if (!e) { - parserInput.save(); - - if (parserInput.$char('(')) { - if ((v = this.selector(false)) && parserInput.$char(')')) { - e = new tree.Paren(v); - parserInput.forget(); - } else { - parserInput.restore('Missing closing \')\''); - } - } else { - parserInput.forget(); - } - } - - if (e) { - return new tree.Element(c, e, e instanceof tree.Variable, index, fileInfo); - } - }, - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function combinator() { - var c = parserInput.currentChar(); - - if (c === '/') { - parserInput.save(); - var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); - - if (slashedCombinator) { - parserInput.forget(); - return new tree.Combinator(slashedCombinator); - } - - parserInput.restore(); - } - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - parserInput.i++; - - if (c === '^' && parserInput.currentChar() === '^') { - c = '^^'; - parserInput.i++; - } - - while (parserInput.isWhitespace()) { - parserInput.i++; - } - - return new tree.Combinator(c); - } else if (parserInput.isWhitespace(-1)) { - return new tree.Combinator(' '); - } else { - return new tree.Combinator(null); - } - }, - // - // A CSS Selector - // with less extensions e.g. the ability to extend and guard - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function selector(isLess) { - var index = parserInput.i; - var elements; - var extendList; - var c; - var e; - var allExtends; - var when; - var condition; - isLess = isLess !== false; - - while (isLess && (extendList = this.extend()) || isLess && (when = parserInput.$str('when')) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error('CSS guard can only be used at the end of selector'); - } else if (extendList) { - if (allExtends) { - allExtends = allExtends.concat(extendList); - } else { - allExtends = extendList; - } - } else { - if (allExtends) { - error('Extend can only be used at the end of selector'); - } - - c = parserInput.currentChar(); - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - - e = null; - } - - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { - return new tree.Selector(elements, allExtends, condition, index, fileInfo); - } - - if (allExtends) { - error('Extend must be used to extend a selector, it cannot be used on its own'); - } - }, - selectors: function selectors() { - var s; - var selectors; - - while (true) { - s = this.selector(); - - if (!s) { - break; - } - - if (selectors) { - selectors.push(s); - } else { - selectors = [s]; - } - - parserInput.commentStore.length = 0; - - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - - if (!parserInput.$char(',')) { - break; - } - - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - - parserInput.commentStore.length = 0; - } - - return selectors; - }, - attribute: function attribute() { - if (!parserInput.$char('[')) { - return; - } - - var entities = this.entities; - var key; - var val; - var op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = parserInput.$re(/^[|~*$^]?=/); - - if (op) { - val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - return new tree.Attribute(key, op, val); - }, - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function block() { - var content; - - if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { - return content; - } - }, - blockRuleset: function blockRuleset() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - - return block; - }, - detachedRuleset: function detachedRuleset() { - var argInfo; - var params; - var variadic; - parserInput.save(); - - if (parserInput.$re(/^[.#]\(/)) { - /** - * DR args currently only implemented for each() function, and not - * yet settable as `@dr: #(@arg) {}` - * This should be done when DRs are merged with mixins. - * See: https://github.com/less/less-meta/issues/16 - */ - argInfo = this.mixin.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - } - - var blockRuleset = this.blockRuleset(); - - if (blockRuleset) { - parserInput.forget(); - - if (params) { - return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); - } - - return new tree.DetachedRuleset(blockRuleset); - } - - parserInput.restore(); - }, - // - // div, .class, body > p {...} - // - ruleset: function ruleset() { - var selectors; - var rules; - var debugInfo; - parserInput.save(); - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(parserInput.i); - } - - selectors = this.selectors(); - - if (selectors && (rules = this.block())) { - parserInput.forget(); - var ruleset = new tree.Ruleset(selectors, rules, context.strictImports); - - if (context.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - - return ruleset; - } else { - parserInput.restore(); - } - }, - declaration: function declaration() { - var name; - var value; - var index = parserInput.i; - var hasDR; - var c = parserInput.currentChar(); - var important; - var merge; - var isVariable; - - if (c === '.' || c === '#' || c === '&' || c === ':') { - return; - } - - parserInput.save(); - name = this.variable() || this.ruleProperty(); - - if (name) { - isVariable = typeof name === 'string'; - - if (isVariable) { - value = this.detachedRuleset(); - - if (value) { - hasDR = true; - } - } - - parserInput.commentStore.length = 0; - - if (!value) { - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.length > 1 && name.pop().value; // Custom property values get permissive parsing - - if (name[0].value && name[0].value.slice(0, 2) === '--') { - value = this.permissiveValue(); - } // Try to store values as anonymous - // If we need the value later we'll re-parse it in ruleset.parseValue - else { - value = this.anonymousValue(); - } - - if (value) { - parserInput.forget(); // anonymous values absorb the end ';' which is required for them to work - - return new tree.Declaration(name, value, false, merge, index, fileInfo); - } - - if (!value) { - value = this.value(); - } - - if (value) { - important = this.important(); - } else if (isVariable) { - // As a last resort, try permissiveValue - value = this.permissiveValue(); - } - } - - if (value && (this.end() || hasDR)) { - parserInput.forget(); - return new tree.Declaration(name, value, important, merge, index, fileInfo); - } else { - parserInput.restore(); - } - } else { - parserInput.restore(); - } - }, - anonymousValue: function anonymousValue() { - var index = parserInput.i; - var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); - - if (match) { - return new tree.Anonymous(match[1], index); - } - }, - - /** - * Used for custom properties, at-rules, and variables (as fallback) - * Parses almost anything inside of {} [] () "" blocks - * until it reaches outer-most tokens. - * - * First, it will try to parse comments and entities to reach - * the end. This is mostly like the Expression parser except no - * math is allowed. - */ - permissiveValue: function permissiveValue(untilTokens) { - var i; - var e; - var done; - var value; - var tok = untilTokens || ';'; - var index = parserInput.i; - var result = []; - - function testCurrentChar() { - var char = parserInput.currentChar(); - - if (typeof tok === 'string') { - return char === tok; - } else { - return tok.test(char); - } - } - - if (testCurrentChar()) { - return; - } - - value = []; - - do { - e = this.comment(); - - if (e) { - value.push(e); - continue; - } - - e = this.entity(); - - if (e) { - value.push(e); - } - } while (e); - - done = testCurrentChar(); - - if (value.length > 0) { - value = new tree.Expression(value); - - if (done) { - return value; - } else { - result.push(value); - } // Preserve space before $parseUntil as it will not - - - if (parserInput.prevChar() === ' ') { - result.push(new tree.Anonymous(' ', index)); - } - } - - parserInput.save(); - value = parserInput.$parseUntil(tok); - - if (value) { - if (typeof value === 'string') { - error(`Expected '${value}'`, 'Parse'); - } - - if (value.length === 1 && value[0] === ' ') { - parserInput.forget(); - return new tree.Anonymous('', index); - } - - var item; - - for (i = 0; i < value.length; i++) { - item = value[i]; - - if (Array.isArray(item)) { - // Treat actual quotes as normal quoted values - result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); - } else { - if (i === value.length - 1) { - item = item.trim(); - } // Treat like quoted values, but replace vars like unquoted expressions - - - var quote = new tree.Quoted('\'', item, true, index, fileInfo); - quote.variableRegex = /@([\w-]+)/g; - quote.propRegex = /\$([\w-]+)/g; - result.push(quote); - } - } - - parserInput.forget(); - return new tree.Expression(result, true); - } - - parserInput.restore(); - }, - // - // An @import atrule - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - 'import': function _import() { - var path; - var features; - var index = parserInput.i; - var dir = parserInput.$re(/^@import?\s+/); - - if (dir) { - var options = (dir ? this.importOptions() : null) || {}; - - if (path = this.entities.quoted() || this.entities.url()) { - features = this.mediaFeatures(); - - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon or unrecognised media features on import'); - } - - features = features && new tree.Value(features); - return new tree.Import(path, features, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed import statement'); - } - } - }, - importOptions: function importOptions() { - var o; - var options = {}; - var optionName; - var value; // list of options, surrounded by parens - - if (!parserInput.$char('(')) { - return null; - } - - do { - o = this.importOption(); - - if (o) { - optionName = o; - value = true; - - switch (optionName) { - case 'css': - optionName = 'less'; - value = false; - break; - - case 'once': - optionName = 'multiple'; - value = false; - break; - } - - options[optionName] = value; - - if (!parserInput.$char(',')) { - break; - } - } - } while (o); - - expectChar(')'); - return options; - }, - importOption: function importOption() { - var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); - - if (opt) { - return opt[1]; - } - }, - mediaFeature: function mediaFeature() { - var entities = this.entities; - var nodes = []; - var e; - var p; - parserInput.save(); - - do { - e = entities.keyword() || entities.variable() || entities.mixinLookup(); - - if (e) { - nodes.push(e); - } else if (parserInput.$char('(')) { - p = this.property(); - e = this.value(); - - if (parserInput.$char(')')) { - if (p && e) { - nodes.push(new tree.Paren(new tree.Declaration(p, e, null, null, parserInput.i, fileInfo, true))); - } else if (e) { - nodes.push(new tree.Paren(e)); - } else { - error('badly formed media feature definition'); - } - } else { - error('Missing closing \')\'', 'Parse'); - } - } - } while (e); - - parserInput.forget(); - - if (nodes.length > 0) { - return new tree.Expression(nodes); - } - }, - mediaFeatures: function mediaFeatures() { - var entities = this.entities; - var features = []; - var e; - - do { - e = this.mediaFeature(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } else { - e = entities.variable() || entities.mixinLookup(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - media: function media() { - var features; - var rules; - var media; - var debugInfo; - var index = parserInput.i; - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(index); - } - - parserInput.save(); - - if (parserInput.$str('@media')) { - features = this.mediaFeatures(); - rules = this.block(); - - if (!rules) { - error('media definitions require block statements after any features'); - } - - parserInput.forget(); - media = new tree.Media(rules, features, index, fileInfo); - - if (context.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - - return media; - } - - parserInput.restore(); - }, - // - // A @plugin directive, used to import plugins dynamically. - // - // @plugin (args) "lib"; - // - plugin: function plugin() { - var path; - var args; - var options; - var index = parserInput.i; - var dir = parserInput.$re(/^@plugin?\s+/); - - if (dir) { - args = this.pluginArgs(); - - if (args) { - options = { - pluginArgs: args, - isPlugin: true - }; - } else { - options = { - isPlugin: true - }; - } - - if (path = this.entities.quoted() || this.entities.url()) { - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon on @plugin'); - } - - return new tree.Import(path, null, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed @plugin statement'); - } - } - }, - pluginArgs: function pluginArgs() { - // list of options, surrounded by parens - parserInput.save(); - - if (!parserInput.$char('(')) { - parserInput.restore(); - return null; - } - - var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); - - if (args[1]) { - parserInput.forget(); - return args[1].trim(); - } else { - parserInput.restore(); - return null; - } - }, - // - // A CSS AtRule - // - // @charset "utf-8"; - // - atrule: function atrule() { - var index = parserInput.i; - var name; - var value; - var rules; - var nonVendorSpecificName; - var hasIdentifier; - var hasExpression; - var hasUnknown; - var hasBlock = true; - var isRooted = true; - - if (parserInput.currentChar() !== '@') { - return; - } - - value = this['import']() || this.plugin() || this.media(); - - if (value) { - return value; - } - - parserInput.save(); - name = parserInput.$re(/^@[a-z-]+/); - - if (!name) { - return; - } - - nonVendorSpecificName = name; - - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = `@${name.slice(name.indexOf('-', 2) + 1)}`; - } - - switch (nonVendorSpecificName) { - case '@charset': - hasIdentifier = true; - hasBlock = false; - break; - - case '@namespace': - hasExpression = true; - hasBlock = false; - break; - - case '@keyframes': - case '@counter-style': - hasIdentifier = true; - break; - - case '@document': - case '@supports': - hasUnknown = true; - isRooted = false; - break; - - default: - hasUnknown = true; - break; - } - - parserInput.commentStore.length = 0; - - if (hasIdentifier) { - value = this.entity(); - - if (!value) { - error(`expected ${name} identifier`); - } - } else if (hasExpression) { - value = this.expression(); - - if (!value) { - error(`expected ${name} expression`); - } - } else if (hasUnknown) { - value = this.permissiveValue(/^[{;]/); - hasBlock = parserInput.currentChar() === '{'; - - if (!value) { - if (!hasBlock && parserInput.currentChar() !== ';') { - error(`${name} rule is missing block or ending semi-colon`); - } - } else if (!value.value) { - value = null; - } - } - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || !hasBlock && value && parserInput.$char(';')) { - parserInput.forget(); - return new tree.AtRule(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); - } - - parserInput.restore('at-rule options not recognised'); - }, - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function value() { - var e; - var expressions = []; - var index = parserInput.i; - - do { - e = this.expression(); - - if (e) { - expressions.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } while (e); - - if (expressions.length > 0) { - return new tree.Value(expressions, index); - } - }, - important: function important() { - if (parserInput.currentChar() === '!') { - return parserInput.$re(/^! *important/); - } - }, - sub: function sub() { - var a; - var e; - parserInput.save(); - - if (parserInput.$char('(')) { - a = this.addition(); - - if (a && parserInput.$char(')')) { - parserInput.forget(); - e = new tree.Expression([a]); - e.parens = true; - return e; - } - - parserInput.restore('Expected \')\''); - return; - } - - parserInput.restore(); - }, - multiplication: function multiplication() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.operand(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - if (parserInput.peek(/^\/[*\/]/)) { - break; - } - - parserInput.save(); - op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); - - if (!op) { - parserInput.forget(); - break; - } - - a = this.operand(); - - if (!a) { - parserInput.restore(); - break; - } - - parserInput.forget(); - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - addition: function addition() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.multiplication(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - op = parserInput.$re(/^[-+]\s+/) || !isSpaced && (parserInput.$char('+') || parserInput.$char('-')); - - if (!op) { - break; - } - - a = this.multiplication(); - - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - conditions: function conditions() { - var a; - var b; - var index = parserInput.i; - var condition; - a = this.condition(true); - - if (a) { - while (true) { - if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { - break; - } - - b = this.condition(true); - - if (!b) { - break; - } - - condition = new tree.Condition('or', condition || a, b, index); - } - - return condition || a; - } - }, - condition: function condition(needsParens) { - var result; - var logical; - var next; - - function or() { - return parserInput.$str('or'); - } - - result = this.conditionAnd(needsParens); - - if (!result) { - return; - } - - logical = or(); - - if (logical) { - next = this.condition(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - conditionAnd: function conditionAnd(needsParens) { - var result; - var logical; - var next; - var self = this; - - function insideCondition() { - var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); - - if (!cond && !needsParens) { - return self.atomicCondition(needsParens); - } - - return cond; - } - - function and() { - return parserInput.$str('and'); - } - - result = insideCondition(); - - if (!result) { - return; - } - - logical = and(); - - if (logical) { - next = this.conditionAnd(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - negatedCondition: function negatedCondition(needsParens) { - if (parserInput.$str('not')) { - var result = this.parenthesisCondition(needsParens); - - if (result) { - result.negate = !result.negate; - } - - return result; - } - }, - parenthesisCondition: function parenthesisCondition(needsParens) { - function tryConditionFollowedByParenthesis(me) { - var body; - parserInput.save(); - body = me.condition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return body; - } - - var body; - parserInput.save(); - - if (!parserInput.$str('(')) { - parserInput.restore(); - return; - } - - body = tryConditionFollowedByParenthesis(this); - - if (body) { - parserInput.forget(); - return body; - } - - body = this.atomicCondition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore(`expected ')' got '${parserInput.currentChar()}'`); - return; - } - - parserInput.forget(); - return body; - }, - atomicCondition: function atomicCondition(needsParens) { - var entities = this.entities; - var index = parserInput.i; - var a; - var b; - var c; - var op; - - function cond() { - return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); - } - - cond = cond.bind(this); - a = cond(); - - if (a) { - if (parserInput.$char('>')) { - if (parserInput.$char('=')) { - op = '>='; - } else { - op = '>'; - } - } else if (parserInput.$char('<')) { - if (parserInput.$char('=')) { - op = '<='; - } else { - op = '<'; - } - } else if (parserInput.$char('=')) { - if (parserInput.$char('>')) { - op = '=>'; - } else if (parserInput.$char('<')) { - op = '=<'; - } else { - op = '='; - } - } - - if (op) { - b = cond(); - - if (b) { - c = new tree.Condition(op, a, b, index, false); - } else { - error('expected expression'); - } - } else { - c = new tree.Condition('=', a, new tree.Keyword('true'), index, false); - } - - return c; - } - }, - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function operand() { - var entities = this.entities; - var negate; - - if (parserInput.peek(/^-[@\$\(]/)) { - negate = parserInput.$char('-'); - } - - var o = this.sub() || entities.dimension() || entities.color() || entities.variable() || entities.property() || entities.call() || entities.quoted(true) || entities.colorKeyword() || entities.mixinLookup(); - - if (negate) { - o.parensInOp = true; - o = new tree.Negative(o); - } - - return o; - }, - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function expression() { - var entities = []; - var e; - var delim; - var index = parserInput.i; - - do { - e = this.comment(); - - if (e) { - entities.push(e); - continue; - } - - e = this.addition() || this.entity(); - - if (e) { - entities.push(e); // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - - if (!parserInput.peek(/^\/[\/*]/)) { - delim = parserInput.$char('/'); - - if (delim) { - entities.push(new tree.Anonymous(delim, index)); - } - } - } - } while (e); - - if (entities.length > 0) { - return new tree.Expression(entities); - } - }, - property: function property() { - var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - - if (name) { - return name[1]; - } - }, - ruleProperty: function ruleProperty() { - var name = []; - var index = []; - var s; - var k; - parserInput.save(); - var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); - - if (simpleProperty) { - name = [new tree.Keyword(simpleProperty[1])]; - parserInput.forget(); - return name; - } - - function match(re) { - var i = parserInput.i; - var chunk = parserInput.$re(re); - - if (chunk) { - index.push(i); - return name.push(chunk[1]); - } - } - - match(/^(\*?)/); - - while (true) { - if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { - break; - } - } - - if (name.length > 1 && match(/^((?:\+_|\+)?)\s*:/)) { - parserInput.forget(); // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - - if (name[0] === '') { - name.shift(); - index.shift(); - } - - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = s.charAt(0) !== '@' && s.charAt(0) !== '$' ? new tree.Keyword(s) : s.charAt(0) === '@' ? new tree.Variable(`@${s.slice(2, -1)}`, index[k], fileInfo) : new tree.Property(`$${s.slice(2, -1)}`, index[k], fileInfo); - } - - return name; - } - - parserInput.restore(); - } - } - }; -}; - -Parser.serializeVars = function (vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += `${(name[0] === '@' ? '' : '@') + name}: ${value}${String(value).slice(-1) === ';' ? '' : ';'}`; - } - } - - return s; -}; - -function boolean(condition) { - return condition ? Keyword.True : Keyword.False; -} - -function If(condition, trueValue, falseValue) { - return condition ? trueValue : falseValue || new Anonymous(); -} - -var boolean$1 = { - boolean, - 'if': If -}; - -var colorFunctions; - -function clamp$1(val) { - return Math.min(1, Math.max(0, val)); -} - -function hsla(origColor, hsl) { - var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); - - if (color) { - if (origColor.value && /^(rgb|hsl)/.test(origColor.value)) { - color.value = origColor.value; - } else { - color.value = 'rgb'; - } - - return color; - } -} - -function toHSL(color) { - if (color.toHSL) { - return color.toHSL(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } -} - -function toHSV(color) { - if (color.toHSV) { - return color.toHSV(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } -} - -function number(n) { - if (n instanceof Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof n === 'number') { - return n; - } else { - throw { - type: 'Argument', - message: 'color functions take numbers as parameters' - }; - } -} - -function scaled(n, size) { - if (n instanceof Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } -} - -colorFunctions = { - rgb: function rgb(r, g, b) { - var color = colorFunctions.rgba(r, g, b, 1.0); - - if (color) { - color.value = 'rgb'; - return color; - } - }, - rgba: function rgba(r, g, b, a) { - try { - if (r instanceof Color) { - if (g) { - a = number(g); - } else { - a = r.alpha; - } - - return new Color(r.rgb, a, 'rgba'); - } - - var rgb = [r, g, b].map(function (c) { - return scaled(c, 255); - }); - a = number(a); - return new Color(rgb, a, 'rgba'); - } catch (e) {} - }, - hsl: function hsl(h, s, l) { - var color = colorFunctions.hsla(h, s, l, 1.0); - - if (color) { - color.value = 'hsl'; - return color; - } - }, - hsla: function hsla(h, s, l, a) { - try { - if (h instanceof Color) { - if (s) { - a = number(s); - } else { - a = h.alpha; } - - return new Color(h.rgb, a, 'hsla'); - } - - var m1; - var m2; - - function hue(h) { - h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; - - if (h * 6 < 1) { - return m1 + (m2 - m1) * h * 6; - } else if (h * 2 < 1) { - return m2; - } else if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - } else { - return m1; - } - } - - h = number(h) % 360 / 360; - s = clamp$1(number(s)); - l = clamp$1(number(l)); - a = clamp$1(number(a)); - m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - var rgb = [hue(h + 1 / 3) * 255, hue(h) * 255, hue(h - 1 / 3) * 255]; - a = number(a); - return new Color(rgb, a, 'hsla'); - } catch (e) {} - }, - hsv: function hsv(h, s, v) { - return colorFunctions.hsva(h, s, v, 1.0); - }, - hsva: function hsva(h, s, v, a) { - h = number(h) % 360 / 360 * 360; - s = number(s); - v = number(v); - a = number(a); - var i; - var f; - i = Math.floor(h / 60 % 6); - f = h / 60 - i; - var vs = [v, v * (1 - s), v * (1 - f * s), v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], [2, 0, 1], [1, 0, 3], [1, 2, 0], [3, 1, 0], [0, 1, 2]]; - return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); - }, - hue: function hue(color) { - return new Dimension(toHSL(color).h); - }, - saturation: function saturation(color) { - return new Dimension(toHSL(color).s * 100, '%'); - }, - lightness: function lightness(color) { - return new Dimension(toHSL(color).l * 100, '%'); - }, - hsvhue: function hsvhue(color) { - return new Dimension(toHSV(color).h); - }, - hsvsaturation: function hsvsaturation(color) { - return new Dimension(toHSV(color).s * 100, '%'); - }, - hsvvalue: function hsvvalue(color) { - return new Dimension(toHSV(color).v * 100, '%'); - }, - red: function red(color) { - return new Dimension(color.rgb[0]); - }, - green: function green(color) { - return new Dimension(color.rgb[1]); - }, - blue: function blue(color) { - return new Dimension(color.rgb[2]); - }, - alpha: function alpha(color) { - return new Dimension(toHSL(color).a); - }, - luma: function luma(color) { - return new Dimension(color.luma() * color.alpha * 100, '%'); - }, - luminance: function luminance(color) { - var luminance = 0.2126 * color.rgb[0] / 255 + 0.7152 * color.rgb[1] / 255 + 0.0722 * color.rgb[2] / 255; - return new Dimension(luminance * color.alpha * 100, '%'); - }, - saturate: function saturate(color, amount, method) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s += hsl.s * amount.value / 100; - } else { - hsl.s += amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - desaturate: function desaturate(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s -= hsl.s * amount.value / 100; - } else { - hsl.s -= amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - lighten: function lighten(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l += hsl.l * amount.value / 100; - } else { - hsl.l += amount.value / 100; - } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - darken: function darken(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l -= hsl.l * amount.value / 100; - } else { - hsl.l -= amount.value / 100; - } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - fadein: function fadein(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a += hsl.a * amount.value / 100; - } else { - hsl.a += amount.value / 100; - } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fadeout: function fadeout(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a -= hsl.a * amount.value / 100; - } else { - hsl.a -= amount.value / 100; - } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fade: function fade(color, amount) { - var hsl = toHSL(color); - hsl.a = amount.value / 100; - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - spin: function spin(color, amount) { - var hsl = toHSL(color); - var hue = (hsl.h + amount.value) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return hsla(color, hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function mix(color1, color2, weight) { - if (!weight) { - weight = new Dimension(50); - } - - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = toHSL(color1).a - toHSL(color2).a; - var w1 = ((w * a == -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, color1.rgb[1] * w1 + color2.rgb[1] * w2, color1.rgb[2] * w1 + color2.rgb[2] * w2]; - var alpha = color1.alpha * p + color2.alpha * (1 - p); - return new Color(rgb, alpha); - }, - greyscale: function greyscale(color) { - return colorFunctions.desaturate(color, new Dimension(100)); - }, - contrast: function contrast(color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - - if (typeof light === 'undefined') { - light = colorFunctions.rgba(255, 255, 255, 1.0); - } - - if (typeof dark === 'undefined') { - dark = colorFunctions.rgba(0, 0, 0, 1.0); - } // Figure out which is actually light and dark: - - - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; - } - - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); - } - - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - // Changes made in 2.7.0 - Reverted in 3.0.0 - // contrast: function (color, color1, color2, threshold) { - // // Return which of `color1` and `color2` has the greatest contrast with `color` - // // according to the standard WCAG contrast ratio calculation. - // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - // // The threshold param is no longer used, in line with SASS. - // // filter: contrast(3.2); - // // should be kept as is, so check for color - // if (!color.rgb) { - // return null; - // } - // if (typeof color1 === 'undefined') { - // color1 = colorFunctions.rgba(0, 0, 0, 1.0); - // } - // if (typeof color2 === 'undefined') { - // color2 = colorFunctions.rgba(255, 255, 255, 1.0); - // } - // var contrast1, contrast2; - // var luma = color.luma(); - // var luma1 = color1.luma(); - // var luma2 = color2.luma(); - // // Calculate contrast ratios for each color - // if (luma > luma1) { - // contrast1 = (luma + 0.05) / (luma1 + 0.05); - // } else { - // contrast1 = (luma1 + 0.05) / (luma + 0.05); - // } - // if (luma > luma2) { - // contrast2 = (luma + 0.05) / (luma2 + 0.05); - // } else { - // contrast2 = (luma2 + 0.05) / (luma + 0.05); - // } - // if (contrast1 > contrast2) { - // return color1; - // } else { - // return color2; - // } - // }, - argb: function argb(color) { - return new Anonymous(color.toARGB()); - }, - color: function color(c) { - if (c instanceof Quoted && /^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value)) { - var val = c.value.slice(1); - return new Color(val, undefined, `#${val}`); - } - - if (c instanceof Color || (c = Color.fromKeyword(c.value))) { - c.value = undefined; - return c; - } - - throw { - type: 'Argument', - message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' - }; - }, - tint: function tint(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); - }, - shade: function shade(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); - } -}; -var color = colorFunctions; - -// ref: http://www.w3.org/TR/compositing-1 - -function colorBlend(mode, color1, color2) { - var ab = color1.alpha; // result - - var // backdrop - cb; - var as = color2.alpha; - var // source - cs; - var ar; - var cr; - var r = []; - ar = as + ab * (1 - as); - - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - - if (ar) { - cr = (as * cs + ab * (cb - as * (cb + cs - cr))) / ar; - } - - r[i] = cr * 255; - } - - return new Color(r, ar); -} - -var colorBlendModeFunctions = { - multiply: function multiply(cb, cs) { - return cb * cs; - }, - screen: function screen(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function overlay(cb, cs) { - cb *= 2; - return cb <= 1 ? colorBlendModeFunctions.multiply(cb, cs) : colorBlendModeFunctions.screen(cb - 1, cs); - }, - softlight: function softlight(cb, cs) { - var d = 1; - var e = cb; - - if (cs > 0.5) { - e = 1; - d = cb > 0.25 ? Math.sqrt(cb) : ((16 * cb - 12) * cb + 4) * cb; - } - - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function hardlight(cb, cs) { - return colorBlendModeFunctions.overlay(cs, cb); - }, - difference: function difference(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function exclusion(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - // non-w3c functions: - average: function average(cb, cs) { - return (cb + cs) / 2; - }, - negation: function negation(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } + }; }; - -for (var f in colorBlendModeFunctions) { - if (colorBlendModeFunctions.hasOwnProperty(f)) { - colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); - } -} - -var dataUri = (function (environment) { - var fallback = function fallback(functionThis, node) { - return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); - }; - - return { - 'data-uri': function dataUri(mimetypeNode, filePathNode) { - if (!filePathNode) { - filePathNode = mimetypeNode; - mimetypeNode = null; - } - - var mimetype = mimetypeNode && mimetypeNode.value; - var filePath = filePathNode.value; - var currentFileInfo = this.currentFileInfo; - var currentDirectory = currentFileInfo.rewriteUrls ? currentFileInfo.currentDirectory : currentFileInfo.entryPath; - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - var context = clone(this.context); - context.rawBuffer = true; - var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); - - if (!fileManager) { - return fallback(this, filePathNode); - } - - var useBase64 = false; // detect the mimetype if not given - - if (!mimetypeNode) { - mimetype = environment.mimeLookup(filePath); - - if (mimetype === 'image/svg+xml') { - useBase64 = false; - } else { - // use base 64 unless it's an ASCII or UTF-8 format - var charset = environment.charsetLookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - } - - if (useBase64) { - mimetype += ';base64'; - } - } else { - useBase64 = /;base64$/.test(mimetype); - } - - var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); - - if (!fileSync.contents) { - logger.warn(`Skipped data-uri embedding of ${filePath} because file not found`); - return fallback(this, filePathNode || mimetypeNode); - } - - var buf = fileSync.contents; - - if (useBase64 && !environment.encodeBase64) { - return fallback(this, filePathNode); - } - - buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); - var uri = `data:${mimetype},${buf}${fragment}`; - return new URL(new Quoted(`"${uri}"`, uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); +Parser.serializeVars = function (vars) { + var s = ''; + for (var name_1 in vars) { + if (Object.hasOwnProperty.call(vars, name_1)) { + var value = vars[name_1]; + s += ((name_1[0] === '@') ? '' : '@') + name_1 + ": " + value + ((String(value).slice(-1) === ';') ? '' : ';'); + } } - }; -}); - -var getItemsFromNode = function getItemsFromNode(node) { - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - var items = Array.isArray(node.value) ? node.value : Array(node); - return items; + return s; }; -var list = { - _SELF: function _SELF(n) { - return n; - }, - extract: function extract(values, index) { - // (1-based index) - index = index.value - 1; - return getItemsFromNode(values)[index]; - }, - length: function length(values) { - return new Dimension(getItemsFromNode(values).length); - }, - - /** - * Creates a Less list of incremental values. - * Modeled after Lodash's range function, also exists natively in PHP - * - * @param {Dimension} [start=1] - * @param {Dimension} end - e.g. 10 or 10px - unit is added to output - * @param {Dimension} [step=1] - */ - range: function range(start, end, step) { - var from; - var to; - var stepValue = 1; - var list = []; - - if (end) { - to = end; - from = start.value; +function boolean(condition) { + return condition ? Keyword.True : Keyword.False; +} +function If(condition, trueValue, falseValue) { + return condition ? trueValue + : (falseValue || new Anonymous); +} +var boolean$1 = { boolean: boolean, 'if': If }; - if (step) { - stepValue = step.value; - } - } else { - from = 1; - to = start; +var colorFunctions; +function clamp$1(val) { + return Math.min(1, Math.max(0, val)); +} +function hsla(origColor, hsl) { + var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); + if (color) { + if (origColor.value && + /^(rgb|hsl)/.test(origColor.value)) { + color.value = origColor.value; + } + else { + color.value = 'rgb'; + } + return color; } - - for (var i = from; i <= to.value; i += stepValue) { - list.push(new Dimension(i, to.unit)); +} +function toHSL(color) { + if (color.toHSL) { + return color.toHSL(); } - - return new Expression(list); - }, - each: function each(list, rs) { - var rules = []; - var newRules; - var iterator; - - if (list.value && !(list instanceof Quoted)) { - if (Array.isArray(list.value)) { - iterator = list.value; - } else { - iterator = [list.value]; - } - } else if (list.ruleset) { - iterator = list.ruleset.rules; - } else if (list.rules) { - iterator = list.rules; - } else if (Array.isArray(list)) { - iterator = list; - } else { - iterator = [list]; + else { + throw new Error('Argument cannot be evaluated to a color'); } - - var valueName = '@value'; - var keyName = '@key'; - var indexName = '@index'; - - if (rs.params) { - valueName = rs.params[0] && rs.params[0].name; - keyName = rs.params[1] && rs.params[1].name; - indexName = rs.params[2] && rs.params[2].name; - rs = rs.rules; - } else { - rs = rs.ruleset; +} +function toHSV(color) { + if (color.toHSV) { + return color.toHSV(); } - - for (var i = 0; i < iterator.length; i++) { - var key = void 0; - var value = void 0; - var item = iterator[i]; - - if (item instanceof Declaration) { - key = typeof item.name === 'string' ? item.name : item.name[0].value; - value = item.value; - } else { - key = new Dimension(i + 1); - value = item; - } - - if (item instanceof Comment) { - continue; - } - - newRules = rs.rules.slice(0); - - if (valueName) { - newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); - } - - if (indexName) { - newRules.push(new Declaration(indexName, new Dimension(i + 1), false, false, this.index, this.currentFileInfo)); - } - - if (keyName) { - newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); - } - - rules.push(new Ruleset([new Selector([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); + else { + throw new Error('Argument cannot be evaluated to a color'); } - - return new Ruleset([new Selector([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); - } -}; - -var MathHelper = function MathHelper(fn, unit, n) { - if (!(n instanceof Dimension)) { - throw { - type: 'Argument', - message: 'argument must be a number' - }; - } - - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - - return new Dimension(fn(parseFloat(n.value)), unit); -}; - -var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: '', - sin: '', - cos: '', - atan: 'rad', - asin: 'rad', - acos: 'rad' -}; - -for (var f$1 in mathFunctions) { - if (mathFunctions.hasOwnProperty(f$1)) { - mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); - } } - -mathFunctions.round = function (n, f) { - var fraction = typeof f === 'undefined' ? 0 : f.value; - return MathHelper(function (num) { - return num.toFixed(fraction); - }, null, n); -}; - -var minMax = function minMax(isMin, args) { - args = Array.prototype.slice.call(args); - - switch (args.length) { - case 0: - throw { - type: 'Argument', - message: 'one or more arguments required' - }; - } - - var i; // key is the unit.toString() for unified Dimension values, - - var j; - var current; - var currentUnified; - var referenceUnified; - var unit; - var unitStatic; - var unitClone; - var // elems only contains original argument values. - order = []; - var values = {}; // value is the index into the order array. - - for (i = 0; i < args.length; i++) { - current = args[i]; - - if (!(current instanceof Dimension)) { - if (Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - - continue; +function number(n) { + if (n instanceof Dimension) { + return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); } - - currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; - unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; - - if (j === undefined) { - if (unitStatic !== undefined && unit !== unitStatic) { + else if (typeof n === 'number') { + return n; + } + else { throw { - type: 'Argument', - message: 'incompatible types' + type: 'Argument', + message: 'color functions take numbers as parameters' }; - } - - values[unit] = order.length; - order.push(current); - continue; - } - - referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); - - if (isMin && currentUnified.value < referenceUnified.value || !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; - } - } - - if (order.length == 1) { - return order[0]; - } - - args = order.map(function (a) { - return a.toCSS(this.context); - }).join(this.context.compress ? ',' : ', '); - return new Anonymous(`${isMin ? 'min' : 'max'}(${args})`); -}; - -var number$1 = { - min: function min() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; } - - return minMax(true, args); - }, - max: function max() { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - return minMax(false, args); - }, - convert: function convert(val, unit) { - return val.convertTo(unit.value); - }, - pi: function pi() { - return new Dimension(Math.PI); - }, - mod: function mod(a, b) { - return new Dimension(a.value % b.value, a.unit); - }, - pow: function pow(x, y) { - if (typeof x === 'number' && typeof y === 'number') { - x = new Dimension(x); - y = new Dimension(y); - } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { - throw { - type: 'Argument', - message: 'arguments must be numbers' - }; +} +function scaled(n, size) { + if (n instanceof Dimension && n.unit.is('%')) { + return parseFloat(n.value * size / 100); } - - return new Dimension(Math.pow(x.value, y.value), x.unit); - }, - percentage: function percentage(n) { - var result = MathHelper(function (num) { - return num * 100; - }, '%', n); - return result; - } -}; - -var string = { - e: function e(str) { - return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); - }, - escape: function escape(str) { - return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B').replace(/\(/g, '%28').replace(/\)/g, '%29')); - }, - replace: function replace(string, pattern, replacement, flags) { - var result = string.value; - replacement = replacement.type === 'Quoted' ? replacement.value : replacement.toCSS(); - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); - return new Quoted(string.quote || '', result, string.escaped); - }, - '%': function _(string - /* arg, arg, ... */ - ) { - var args = Array.prototype.slice.call(arguments, 1); - var result = string.value; - - var _loop = function _loop(i) { - /* jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function (token) { - var value = args[i].type === 'Quoted' && token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - }; - - for (var i = 0; i < args.length; i++) { - _loop(i); + else { + return number(n); } - - result = result.replace(/%%/g, '%'); - return new Quoted(string.quote || '', result, string.escaped); - } -}; - -var svg = (function (environment) { - return { - 'svg-gradient': function svgGradient(direction) { - var stops; - var gradientDirectionSvg; - var gradientType = 'linear'; - var rectangleDimension = 'x="0" y="0" width="1" height="1"'; - var renderEnv = { - compress: false - }; - var returner; - var directionValue = direction.toCSS(renderEnv); - var i; - var color; - var position; - var positionValue; - var alpha; - - function throwArgumentDescriptor() { - throw { - type: 'Argument', - message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + ' end_color [end_position] or direction, color list' - }; - } - - if (arguments.length == 2) { - if (arguments[1].value.length < 2) { - throwArgumentDescriptor(); +} +colorFunctions = { + rgb: function (r, g, b) { + var color = colorFunctions.rgba(r, g, b, 1.0); + if (color) { + color.value = 'rgb'; + return color; } - - stops = arguments[1].value; - } else if (arguments.length < 3) { - throwArgumentDescriptor(); - } else { - stops = Array.prototype.slice.call(arguments, 1); - } - - switch (directionValue) { - case 'to bottom': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - - case 'to right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - - case 'to bottom right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - - case 'to top right': - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - - case 'ellipse': - case 'ellipse at center': - gradientType = 'radial'; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - - default: - throw { - type: 'Argument', - message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' - }; - } - - returner = `<${gradientType}Gradient id="g" ${gradientDirectionSvg}>`; - - for (i = 0; i < stops.length; i += 1) { - if (stops[i] instanceof Expression) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; + }, + rgba: function (r, g, b, a) { + try { + if (r instanceof Color) { + if (g) { + a = number(g); + } + else { + a = r.alpha; + } + return new Color(r.rgb, a, 'rgba'); + } + var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); + a = number(a); + return new Color(rgb, a, 'rgba'); } - - if (!(color instanceof Color) || !((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension)) { - throwArgumentDescriptor(); + catch (e) { } + }, + hsl: function (h, s, l) { + var color = colorFunctions.hsla(h, s, l, 1.0); + if (color) { + color.value = 'hsl'; + return color; } - - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; - alpha = color.alpha; - returner += ``; - } - - returner += ``; - returner = encodeURIComponent(returner); - returner = `data:image/svg+xml,${returner}`; - return new URL(new Quoted(`'${returner}'`, returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + }, + hsla: function (h, s, l, a) { + try { + if (h instanceof Color) { + if (s) { + a = number(s); + } + else { + a = h.alpha; + } + return new Color(h.rgb, a, 'hsla'); + } + var m1_1; + var m2_1; + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { + return m1_1 + (m2_1 - m1_1) * h * 6; + } + else if (h * 2 < 1) { + return m2_1; + } + else if (h * 3 < 2) { + return m1_1 + (m2_1 - m1_1) * (2 / 3 - h) * 6; + } + else { + return m1_1; + } + } + h = (number(h) % 360) / 360; + s = clamp$1(number(s)); + l = clamp$1(number(l)); + a = clamp$1(number(a)); + m2_1 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + m1_1 = l * 2 - m2_1; + var rgb = [ + hue(h + 1 / 3) * 255, + hue(h) * 255, + hue(h - 1 / 3) * 255 + ]; + a = number(a); + return new Color(rgb, a, 'hsla'); + } + catch (e) { } + }, + hsv: function (h, s, v) { + return colorFunctions.hsva(h, s, v, 1.0); + }, + hsva: function (h, s, v, a) { + h = ((number(h) % 360) / 360) * 360; + s = number(s); + v = number(v); + a = number(a); + var i; + var f; + i = Math.floor((h / 60) % 6); + f = (h / 60) - i; + var vs = [v, + v * (1 - s), + v * (1 - f * s), + v * (1 - (1 - f) * s)]; + var perm = [[0, 3, 1], + [2, 0, 1], + [1, 0, 3], + [1, 2, 0], + [3, 1, 0], + [0, 1, 2]]; + return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); + }, + hue: function (color) { + return new Dimension(toHSL(color).h); + }, + saturation: function (color) { + return new Dimension(toHSL(color).s * 100, '%'); + }, + lightness: function (color) { + return new Dimension(toHSL(color).l * 100, '%'); + }, + hsvhue: function (color) { + return new Dimension(toHSV(color).h); + }, + hsvsaturation: function (color) { + return new Dimension(toHSV(color).s * 100, '%'); + }, + hsvvalue: function (color) { + return new Dimension(toHSV(color).v * 100, '%'); + }, + red: function (color) { + return new Dimension(color.rgb[0]); + }, + green: function (color) { + return new Dimension(color.rgb[1]); + }, + blue: function (color) { + return new Dimension(color.rgb[2]); + }, + alpha: function (color) { + return new Dimension(toHSL(color).a); + }, + luma: function (color) { + return new Dimension(color.luma() * color.alpha * 100, '%'); + }, + luminance: function (color) { + var luminance = (0.2126 * color.rgb[0] / 255) + + (0.7152 * color.rgb[1] / 255) + + (0.0722 * color.rgb[2] / 255); + return new Dimension(luminance * color.alpha * 100, '%'); + }, + saturate: function (color, amount, method) { + // filter: saturate(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s += hsl.s * amount.value / 100; + } + else { + hsl.s += amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + desaturate: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s -= hsl.s * amount.value / 100; + } + else { + hsl.s -= amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + lighten: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l += hsl.l * amount.value / 100; + } + else { + hsl.l += amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + darken: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l -= hsl.l * amount.value / 100; + } + else { + hsl.l -= amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + fadein: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a += hsl.a * amount.value / 100; + } + else { + hsl.a += amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fadeout: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a -= hsl.a * amount.value / 100; + } + else { + hsl.a -= amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fade: function (color, amount) { + var hsl = toHSL(color); + hsl.a = amount.value / 100; + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + spin: function (color, amount) { + var hsl = toHSL(color); + var hue = (hsl.h + amount.value) % 360; + hsl.h = hue < 0 ? 360 + hue : hue; + return hsla(color, hsl); + }, + // + // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein + // http://sass-lang.com + // + mix: function (color1, color2, weight) { + if (!weight) { + weight = new Dimension(50); + } + var p = weight.value / 100.0; + var w = p * 2 - 1; + var a = toHSL(color1).a - toHSL(color2).a; + var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, + color1.rgb[1] * w1 + color2.rgb[1] * w2, + color1.rgb[2] * w1 + color2.rgb[2] * w2]; + var alpha = color1.alpha * p + color2.alpha * (1 - p); + return new Color(rgb, alpha); + }, + greyscale: function (color) { + return colorFunctions.desaturate(color, new Dimension(100)); + }, + contrast: function (color, dark, light, threshold) { + // filter: contrast(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + if (typeof light === 'undefined') { + light = colorFunctions.rgba(255, 255, 255, 1.0); + } + if (typeof dark === 'undefined') { + dark = colorFunctions.rgba(0, 0, 0, 1.0); + } + // Figure out which is actually light and dark: + if (dark.luma() > light.luma()) { + var t = light; + light = dark; + dark = t; + } + if (typeof threshold === 'undefined') { + threshold = 0.43; + } + else { + threshold = number(threshold); + } + if (color.luma() < threshold) { + return light; + } + else { + return dark; + } + }, + // Changes made in 2.7.0 - Reverted in 3.0.0 + // contrast: function (color, color1, color2, threshold) { + // // Return which of `color1` and `color2` has the greatest contrast with `color` + // // according to the standard WCAG contrast ratio calculation. + // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + // // The threshold param is no longer used, in line with SASS. + // // filter: contrast(3.2); + // // should be kept as is, so check for color + // if (!color.rgb) { + // return null; + // } + // if (typeof color1 === 'undefined') { + // color1 = colorFunctions.rgba(0, 0, 0, 1.0); + // } + // if (typeof color2 === 'undefined') { + // color2 = colorFunctions.rgba(255, 255, 255, 1.0); + // } + // var contrast1, contrast2; + // var luma = color.luma(); + // var luma1 = color1.luma(); + // var luma2 = color2.luma(); + // // Calculate contrast ratios for each color + // if (luma > luma1) { + // contrast1 = (luma + 0.05) / (luma1 + 0.05); + // } else { + // contrast1 = (luma1 + 0.05) / (luma + 0.05); + // } + // if (luma > luma2) { + // contrast2 = (luma + 0.05) / (luma2 + 0.05); + // } else { + // contrast2 = (luma2 + 0.05) / (luma + 0.05); + // } + // if (contrast1 > contrast2) { + // return color1; + // } else { + // return color2; + // } + // }, + argb: function (color) { + return new Anonymous(color.toARGB()); + }, + color: function (c) { + if ((c instanceof Quoted) && + (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) { + var val = c.value.slice(1); + return new Color(val, undefined, "#" + val); + } + if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) { + c.value = undefined; + return c; + } + throw { + type: 'Argument', + message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' + }; + }, + tint: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); + }, + shade: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); } - }; -}); - -var isa = function isa(n, Type) { - return n instanceof Type ? Keyword.True : Keyword.False; -}; - -var isunit = function isunit(n, unit) { - if (unit === undefined) { - throw { - type: 'Argument', - message: 'missing the required second argument to isunit.' - }; - } - - unit = typeof unit.value === 'string' ? unit.value : unit; - - if (typeof unit !== 'string') { - throw { - type: 'Argument', - message: 'Second argument to isunit should be a unit or a string.' - }; - } - - return n instanceof Dimension && n.unit.is(unit) ? Keyword.True : Keyword.False; }; +var color = colorFunctions; -var types = { - isruleset: function isruleset(n) { - return isa(n, DetachedRuleset); - }, - iscolor: function iscolor(n) { - return isa(n, Color); - }, - isnumber: function isnumber(n) { - return isa(n, Dimension); - }, - isstring: function isstring(n) { - return isa(n, Quoted); - }, - iskeyword: function iskeyword(n) { - return isa(n, Keyword); - }, - isurl: function isurl(n) { - return isa(n, URL); - }, - ispixel: function ispixel(n) { - return isunit(n, 'px'); - }, - ispercentage: function ispercentage(n) { - return isunit(n, '%'); - }, - isem: function isem(n) { - return isunit(n, 'em'); - }, - isunit, - unit: function unit(val, _unit) { - if (!(val instanceof Dimension)) { - throw { - type: 'Argument', - message: `the first argument to unit must be a number${val instanceof Operation ? '. Have you forgotten parenthesis?' : ''}` - }; - } - - if (_unit) { - if (_unit instanceof Keyword) { - _unit = _unit.value; - } else { - _unit = _unit.toCSS(); - } - } else { - _unit = ''; +// Color Blending +// ref: http://www.w3.org/TR/compositing-1 +function colorBlend(mode, color1, color2) { + var ab = color1.alpha; // result + var // backdrop + cb; + var as = color2.alpha; + var // source + cs; + var ar; + var cr; + var r = []; + ar = as + ab * (1 - as); + for (var i_1 = 0; i_1 < 3; i_1++) { + cb = color1.rgb[i_1] / 255; + cs = color2.rgb[i_1] / 255; + cr = mode(cb, cs); + if (ar) { + cr = (as * cs + ab * (cb - + as * (cb + cs - cr))) / ar; + } + r[i_1] = cr * 255; + } + return new Color(r, ar); +} +var colorBlendModeFunctions = { + multiply: function (cb, cs) { + return cb * cs; + }, + screen: function (cb, cs) { + return cb + cs - cb * cs; + }, + overlay: function (cb, cs) { + cb *= 2; + return (cb <= 1) ? + colorBlendModeFunctions.multiply(cb, cs) : + colorBlendModeFunctions.screen(cb - 1, cs); + }, + softlight: function (cb, cs) { + var d = 1; + var e = cb; + if (cs > 0.5) { + e = 1; + d = (cb > 0.25) ? Math.sqrt(cb) + : ((16 * cb - 12) * cb + 4) * cb; + } + return cb - (1 - 2 * cs) * e * (d - cb); + }, + hardlight: function (cb, cs) { + return colorBlendModeFunctions.overlay(cs, cb); + }, + difference: function (cb, cs) { + return Math.abs(cb - cs); + }, + exclusion: function (cb, cs) { + return cb + cs - 2 * cb * cs; + }, + // non-w3c functions: + average: function (cb, cs) { + return (cb + cs) / 2; + }, + negation: function (cb, cs) { + return 1 - Math.abs(cb + cs - 1); } - - return new Dimension(val.value, _unit); - }, - 'get-unit': function getUnit(n) { - return new Anonymous(n.unit); - } }; - -var Functions = (function (environment) { - var functions = { - functionRegistry, - functionCaller - }; // register functions - - functionRegistry.addMultiple(boolean$1); - functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); - functionRegistry.addMultiple(color); - functionRegistry.addMultiple(colorBlend); - functionRegistry.addMultiple(dataUri(environment)); - functionRegistry.addMultiple(list); - functionRegistry.addMultiple(mathFunctions); - functionRegistry.addMultiple(number$1); - functionRegistry.addMultiple(string); - functionRegistry.addMultiple(svg()); - functionRegistry.addMultiple(types); - return functions; -}); - -var sourceMapOutput = (function (environment) { - var SourceMapOutput = - /*#__PURE__*/ - function () { - function SourceMapOutput(options) { - _classCallCheck(this, SourceMapOutput); - - this._css = []; - this._rootNode = options.rootNode; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - - if (options.sourceMapFilename) { - this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); - } - - this._outputFilename = options.outputFilename; - this.sourceMapURL = options.sourceMapURL; - - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - - if (options.sourceMapRootpath) { - this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); - - if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { - this._sourceMapRootpath += '/'; - } - } else { - this._sourceMapRootpath = ''; - } - - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); - this._lineNumber = 0; - this._column = 0; +for (var f in colorBlendModeFunctions) { + if (colorBlendModeFunctions.hasOwnProperty(f)) { + colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); } +} - _createClass(SourceMapOutput, [{ - key: "removeBasepath", - value: function removeBasepath(path) { - if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { - path = path.substring(this._sourceMapBasepath.length); - - if (path.charAt(0) === '\\' || path.charAt(0) === '/') { - path = path.substring(1); - } - } - - return path; - } - }, { - key: "normalizeFilename", - value: function normalizeFilename(filename) { - filename = filename.replace(/\\/g, '/'); - filename = this.removeBasepath(filename); - return (this._sourceMapRootpath || '') + filename; - } - }, { - key: "add", - value: function add(chunk, fileInfo, index, mapLines) { - // ignore adding empty strings - if (!chunk) { - return; - } - - var lines; - var sourceLines; - var columns; - var sourceColumns; - var i; - - if (fileInfo && fileInfo.filename) { - var inputSource = this._contentsMap[fileInfo.filename]; // remove vars/banner added to the top of the file - - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - - if (index < 0) { - index = 0; - } // adjust the source - - - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } // ignore empty content - - - if (inputSource === undefined) { - return; - } +var dataUri = (function (environment) { + var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); }; + return { 'data-uri': function (mimetypeNode, filePathNode) { + if (!filePathNode) { + filePathNode = mimetypeNode; + mimetypeNode = null; + } + var mimetype = mimetypeNode && mimetypeNode.value; + var filePath = filePathNode.value; + var currentFileInfo = this.currentFileInfo; + var currentDirectory = currentFileInfo.rewriteUrls ? + currentFileInfo.currentDirectory : currentFileInfo.entryPath; + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart !== -1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + var context = clone(this.context); + context.rawBuffer = true; + var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); + if (!fileManager) { + return fallback(this, filePathNode); + } + var useBase64 = false; + // detect the mimetype if not given + if (!mimetypeNode) { + mimetype = environment.mimeLookup(filePath); + if (mimetype === 'image/svg+xml') { + useBase64 = false; + } + else { + // use base 64 unless it's an ASCII or UTF-8 format + var charset = environment.charsetLookup(mimetype); + useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; + } + if (useBase64) { + mimetype += ';base64'; + } + } + else { + useBase64 = /;base64$/.test(mimetype); + } + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); + if (!fileSync.contents) { + logger.warn("Skipped data-uri embedding of " + filePath + " because file not found"); + return fallback(this, filePathNode || mimetypeNode); + } + var buf = fileSync.contents; + if (useBase64 && !environment.encodeBase64) { + return fallback(this, filePathNode); + } + buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); + var uri = "data:" + mimetype + "," + buf + fragment; + return new URL(new Quoted("\"" + uri + "\"", uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; +}); - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split('\n'); - sourceColumns = sourceLines[sourceLines.length - 1]; +var getItemsFromNode = function (node) { + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + var items = Array.isArray(node.value) ? + node.value : Array(node); + return items; +}; +var list = { + _SELF: function (n) { + return n; + }, + extract: function (values, index) { + // (1-based index) + index = index.value - 1; + return getItemsFromNode(values)[index]; + }, + length: function (values) { + return new Dimension(getItemsFromNode(values).length); + }, + /** + * Creates a Less list of incremental values. + * Modeled after Lodash's range function, also exists natively in PHP + * + * @param {Dimension} [start=1] + * @param {Dimension} end - e.g. 10 or 10px - unit is added to output + * @param {Dimension} [step=1] + */ + range: function (start, end, step) { + var from; + var to; + var stepValue = 1; + var list = []; + if (end) { + to = end; + from = start.value; + if (step) { + stepValue = step.value; + } } - - lines = chunk.split('\n'); - columns = lines[lines.length - 1]; - - if (fileInfo && fileInfo.filename) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + 1, - column: this._column - }, - original: { - line: sourceLines.length, - column: sourceColumns.length - }, - source: this.normalizeFilename(fileInfo.filename) - }); - } else { - for (i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + i + 1, - column: i === 0 ? this._column : 0 - }, - original: { - line: sourceLines.length + i, - column: i === 0 ? sourceColumns.length : 0 - }, - source: this.normalizeFilename(fileInfo.filename) - }); + else { + from = 1; + to = start; + } + for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) { + list.push(new Dimension(i_1, to.unit)); + } + return new Expression(list); + }, + each: function (list, rs) { + var rules = []; + var newRules; + var iterator; + if (list.value && !(list instanceof Quoted)) { + if (Array.isArray(list.value)) { + iterator = list.value; + } + else { + iterator = [list.value]; } - } } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; + else if (list.ruleset) { + iterator = list.ruleset.rules; + } + else if (list.rules) { + iterator = list.rules; + } + else if (Array.isArray(list)) { + iterator = list; + } + else { + iterator = [list]; + } + var valueName = '@value'; + var keyName = '@key'; + var indexName = '@index'; + if (rs.params) { + valueName = rs.params[0] && rs.params[0].name; + keyName = rs.params[1] && rs.params[1].name; + indexName = rs.params[2] && rs.params[2].name; + rs = rs.rules; + } + else { + rs = rs.ruleset; + } + for (var i_2 = 0; i_2 < iterator.length; i_2++) { + var key = void 0; + var value = void 0; + var item = iterator[i_2]; + if (item instanceof Declaration) { + key = typeof item.name === 'string' ? item.name : item.name[0].value; + value = item.value; + } + else { + key = new Dimension(i_2 + 1); + value = item; + } + if (item instanceof Comment) { + continue; + } + newRules = rs.rules.slice(0); + if (valueName) { + newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); + } + if (indexName) { + newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo)); + } + if (keyName) { + newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); + } + rules.push(new Ruleset([new (Selector)([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); } + return new Ruleset([new (Selector)([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); + } +}; - this._css.push(chunk); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this._css.length === 0; - } - }, { - key: "toCSS", - value: function toCSS(context) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ - file: this._outputFilename, - sourceRoot: null - }); - - if (this._outputSourceFiles) { - for (var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) { - var source = this._contentsMap[filename]; +var MathHelper = function (fn, unit, n) { + if (!(n instanceof Dimension)) { + throw { type: 'Argument', message: 'argument must be a number' }; + } + if (unit == null) { + unit = n.unit; + } + else { + n = n.unify(); + } + return new Dimension(fn(parseFloat(n.value)), unit); +}; - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } +var mathFunctions = { + // name, unit + ceil: null, + floor: null, + sqrt: null, + abs: null, + tan: '', + sin: '', + cos: '', + atan: 'rad', + asin: 'rad', + acos: 'rad' +}; +for (var f$1 in mathFunctions) { + if (mathFunctions.hasOwnProperty(f$1)) { + mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); + } +} +mathFunctions.round = function (n, f) { + var fraction = typeof f === 'undefined' ? 0 : f.value; + return MathHelper(function (num) { return num.toFixed(fraction); }, null, n); +}; - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); +var minMax = function (isMin, args) { + args = Array.prototype.slice.call(args); + switch (args.length) { + case 0: throw { type: 'Argument', message: 'one or more arguments required' }; + } + var i; // key is the unit.toString() for unified Dimension values, + var j; + var current; + var currentUnified; + var referenceUnified; + var unit; + var unitStatic; + var unitClone; + var // elems only contains original argument values. + order = []; + var values = {}; + // value is the index into the order array. + for (i = 0; i < args.length; i++) { + current = args[i]; + if (!(current instanceof Dimension)) { + if (Array.isArray(args[i].value)) { + Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); } - } + continue; } - - this._rootNode.genCSS(context, this); - - if (this._css.length > 0) { - var sourceMapURL; - var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this.sourceMapURL) { - sourceMapURL = this.sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this._sourceMapFilename; - } - - this.sourceMapURL = sourceMapURL; - this.sourceMap = sourceMapContent; + currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); + unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); + unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; + unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; + j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; + if (j === undefined) { + if (unitStatic !== undefined && unit !== unitStatic) { + throw { type: 'Argument', message: 'incompatible types' }; + } + values[unit] = order.length; + order.push(current); + continue; + } + referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); + if (isMin && currentUnified.value < referenceUnified.value || + !isMin && currentUnified.value > referenceUnified.value) { + order[j] = current; } - - return this._css.join(''); - } - }]); - - return SourceMapOutput; - }(); - - return SourceMapOutput; -}); - -var sourceMapBuilder = (function (SourceMapOutput, environment) { - var SourceMapBuilder = - /*#__PURE__*/ - function () { - function SourceMapBuilder(options) { - _classCallCheck(this, SourceMapBuilder); - - this.options = options; } - - _createClass(SourceMapBuilder, [{ - key: "toCSS", - value: function toCSS(rootNode, options, imports) { - var sourceMapOutput = new SourceMapOutput({ - contentsIgnoredCharsMap: imports.contentsIgnoredChars, - rootNode, - contentsMap: imports.contents, - sourceMapFilename: this.options.sourceMapFilename, - sourceMapURL: this.options.sourceMapURL, - outputFilename: this.options.sourceMapOutputFilename, - sourceMapBasepath: this.options.sourceMapBasepath, - sourceMapRootpath: this.options.sourceMapRootpath, - outputSourceFiles: this.options.outputSourceFiles, - sourceMapGenerator: this.options.sourceMapGenerator, - sourceMapFileInline: this.options.sourceMapFileInline - }); - var css = sourceMapOutput.toCSS(options); - this.sourceMap = sourceMapOutput.sourceMap; - this.sourceMapURL = sourceMapOutput.sourceMapURL; - - if (this.options.sourceMapInputFilename) { - this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + if (order.length == 1) { + return order[0]; + } + args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', '); + return new Anonymous((isMin ? 'min' : 'max') + "(" + args + ")"); +}; +var number$1 = { + min: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; } - - if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { - this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); + return minMax(true, args); + }, + max: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; } - - return css + this.getCSSAppendage(); - } - }, { - key: "getCSSAppendage", - value: function getCSSAppendage() { - var sourceMapURL = this.sourceMapURL; - - if (this.options.sourceMapFileInline) { - if (this.sourceMap === undefined) { - return ''; - } - - sourceMapURL = `data:application/json;base64,${environment.encodeBase64(this.sourceMap)}`; + return minMax(false, args); + }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, + pi: function () { + return new Dimension(Math.PI); + }, + mod: function (a, b) { + return new Dimension(a.value % b.value, a.unit); + }, + pow: function (x, y) { + if (typeof x === 'number' && typeof y === 'number') { + x = new Dimension(x); + y = new Dimension(y); } - - if (sourceMapURL) { - return `/*# sourceMappingURL=${sourceMapURL} */`; + else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { + throw { type: 'Argument', message: 'arguments must be numbers' }; } + return new Dimension(Math.pow(x.value, y.value), x.unit); + }, + percentage: function (n) { + var result = MathHelper(function (num) { return num * 100; }, '%', n); + return result; + } +}; - return ''; - } - }, { - key: "getExternalSourceMap", - value: function getExternalSourceMap() { - return this.sourceMap; - } - }, { - key: "setExternalSourceMap", - value: function setExternalSourceMap(sourceMap) { - this.sourceMap = sourceMap; - } - }, { - key: "isInline", - value: function isInline() { - return this.options.sourceMapFileInline; - } - }, { - key: "getSourceMapURL", - value: function getSourceMapURL() { - return this.sourceMapURL; - } - }, { - key: "getOutputFilename", - value: function getOutputFilename() { - return this.options.sourceMapOutputFilename; - } - }, { - key: "getInputFilename", - value: function getInputFilename() { - return this.sourceMapInputFilename; - } - }]); - - return SourceMapBuilder; - }(); - - return SourceMapBuilder; -}); - -var transformTree = (function (root) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var evaldRoot; - var variables = options.variables; - var evalEnv = new contexts.Eval(options); // - // Allows setting variables with a hash, so: - // - // `{ color: new tree.Color('#f01') }` will become: - // - // new tree.Declaration('@color', - // new tree.Value([ - // new tree.Expression([ - // new tree.Color('#f01') - // ]) - // ]) - // ) - // - - if (typeof variables === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (!(value instanceof tree.Value)) { - if (!(value instanceof tree.Expression)) { - value = new tree.Expression([value]); +var string = { + e: function (str) { + return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); + }, + escape: function (str) { + return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B') + .replace(/\(/g, '%28').replace(/\)/g, '%29')); + }, + replace: function (string, pattern, replacement, flags) { + var result = string.value; + replacement = (replacement.type === 'Quoted') ? + replacement.value : replacement.toCSS(); + result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); + return new Quoted(string.quote || '', result, string.escaped); + }, + '%': function (string /* arg, arg, ... */) { + var args = Array.prototype.slice.call(arguments, 1); + var result = string.value; + var _loop_1 = function (i_1) { + /* jshint loopfunc:true */ + result = result.replace(/%[sda]/i, function (token) { + var value = ((args[i_1].type === 'Quoted') && + token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS(); + return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; + }); + }; + for (var i_1 = 0; i_1 < args.length; i_1++) { + _loop_1(i_1); } - - value = new tree.Value([value]); - } - - return new tree.Declaration(`@${k}`, value, false, null, 0); - }); - evalEnv.frames = [new tree.Ruleset(null, variables)]; - } - - var visitors$1 = [new visitors.JoinSelectorVisitor(), new visitors.MarkVisibleSelectorsVisitor(true), new visitors.ExtendVisitor(), new visitors.ToCSSVisitor({ - compress: Boolean(options.compress) - })]; - var preEvalVisitors = []; - var v; - var visitorIterator; - /** - * first() / get() allows visitors to be added while visiting - * - * @todo Add scoping for visitors just like functions for @plugin; right now they're global - */ - - if (options.pluginManager) { - visitorIterator = options.pluginManager.visitor(); - - for (var i = 0; i < 2; i++) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (v.isPreEvalVisitor) { - if (i === 0 || preEvalVisitors.indexOf(v) === -1) { - preEvalVisitors.push(v); - v.run(root); - } - } else { - if (i === 0 || visitors$1.indexOf(v) === -1) { - if (v.isPreVisitor) { - visitors$1.unshift(v); - } else { - visitors$1.push(v); - } - } - } - } - } - } - - evaldRoot = root.eval(evalEnv); - - for (var i = 0; i < visitors$1.length; i++) { - visitors$1[i].run(evaldRoot); - } // Run any remaining visitors added after eval pass - - - if (options.pluginManager) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { - v.run(evaldRoot); - } + result = result.replace(/%%/g, '%'); + return new Quoted(string.quote || '', result, string.escaped); } - } +}; - return evaldRoot; +var svg = (function (environment) { + return { 'svg-gradient': function (direction) { + var stops; + var gradientDirectionSvg; + var gradientType = 'linear'; + var rectangleDimension = 'x="0" y="0" width="1" height="1"'; + var renderEnv = { compress: false }; + var returner; + var directionValue = direction.toCSS(renderEnv); + var i; + var color; + var position; + var positionValue; + var alpha; + function throwArgumentDescriptor() { + throw { type: 'Argument', + message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + + ' end_color [end_position] or direction, color list' }; + } + if (arguments.length == 2) { + if (arguments[1].value.length < 2) { + throwArgumentDescriptor(); + } + stops = arguments[1].value; + } + else if (arguments.length < 3) { + throwArgumentDescriptor(); + } + else { + stops = Array.prototype.slice.call(arguments, 1); + } + switch (directionValue) { + case 'to bottom': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; + break; + case 'to right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; + break; + case 'to bottom right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; + break; + case 'to top right': + gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; + break; + case 'ellipse': + case 'ellipse at center': + gradientType = 'radial'; + gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; + rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; + break; + default: + throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' }; + } + returner = "<" + gradientType + "Gradient id=\"g\" " + gradientDirectionSvg + ">"; + for (i = 0; i < stops.length; i += 1) { + if (stops[i] instanceof Expression) { + color = stops[i].value[0]; + position = stops[i].value[1]; + } + else { + color = stops[i]; + position = undefined; + } + if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) { + throwArgumentDescriptor(); + } + positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; + alpha = color.alpha; + returner += ""; + } + returner += ""; + returner = encodeURIComponent(returner); + returner = "data:image/svg+xml," + returner; + return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; }); -var parseTree = (function (SourceMapBuilder) { - var ParseTree = - /*#__PURE__*/ - function () { - function ParseTree(root, imports) { - _classCallCheck(this, ParseTree); - - this.root = root; - this.imports = imports; +var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; }; +var isunit = function (n, unit) { + if (unit === undefined) { + throw { type: 'Argument', message: 'missing the required second argument to isunit.' }; } - - _createClass(ParseTree, [{ - key: "toCSS", - value: function toCSS(options) { - var evaldRoot; - var result = {}; - var sourceMapBuilder; - - try { - evaldRoot = transformTree(this.root, options); - } catch (e) { - throw new LessError(e, this.imports); - } - - try { - var compress = Boolean(options.compress); - - if (compress) { - logger.warn('The compress option has been deprecated. ' + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); - } - - var toCSSOptions = { - compress, - dumpLineNumbers: options.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8 - }; - - if (options.sourceMap) { - sourceMapBuilder = new SourceMapBuilder(options.sourceMap); - result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); - } else { - result.css = evaldRoot.toCSS(toCSSOptions); - } - } catch (e) { - throw new LessError(e, this.imports); - } - - if (options.pluginManager) { - var postProcessors = options.pluginManager.getPostProcessors(); - - for (var i = 0; i < postProcessors.length; i++) { - result.css = postProcessors[i].process(result.css, { - sourceMap: sourceMapBuilder, - options, - imports: this.imports - }); - } - } - - if (options.sourceMap) { - result.map = sourceMapBuilder.getExternalSourceMap(); + unit = typeof unit.value === 'string' ? unit.value : unit; + if (typeof unit !== 'string') { + throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' }; + } + return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False; +}; +var types = { + isruleset: function (n) { + return isa(n, DetachedRuleset); + }, + iscolor: function (n) { + return isa(n, Color); + }, + isnumber: function (n) { + return isa(n, Dimension); + }, + isstring: function (n) { + return isa(n, Quoted); + }, + iskeyword: function (n) { + return isa(n, Keyword); + }, + isurl: function (n) { + return isa(n, URL); + }, + ispixel: function (n) { + return isunit(n, 'px'); + }, + ispercentage: function (n) { + return isunit(n, '%'); + }, + isem: function (n) { + return isunit(n, 'em'); + }, + isunit: isunit, + unit: function (val, unit) { + if (!(val instanceof Dimension)) { + throw { type: 'Argument', + message: "the first argument to unit must be a number" + (val instanceof Operation ? '. Have you forgotten parenthesis?' : '') }; + } + if (unit) { + if (unit instanceof Keyword) { + unit = unit.value; + } + else { + unit = unit.toCSS(); + } } - - result.imports = []; - - for (var file in this.imports.files) { - if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) { - result.imports.push(file); - } + else { + unit = ''; } + return new Dimension(val.value, unit); + }, + 'get-unit': function (n) { + return new Anonymous(n.unit); + } +}; - return result; - } - }]); - - return ParseTree; - }(); - - return ParseTree; +var Functions = (function (environment) { + var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller }; + // register functions + functionRegistry.addMultiple(boolean$1); + functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); + functionRegistry.addMultiple(color); + functionRegistry.addMultiple(colorBlend); + functionRegistry.addMultiple(dataUri(environment)); + functionRegistry.addMultiple(list); + functionRegistry.addMultiple(mathFunctions); + functionRegistry.addMultiple(number$1); + functionRegistry.addMultiple(string); + functionRegistry.addMultiple(svg()); + functionRegistry.addMultiple(types); + return functions; }); -var importManager = (function (environment) { - // FileInfo = { - // 'rewriteUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - var ImportManager = - /*#__PURE__*/ - function () { - function ImportManager(less, context, rootFileInfo) { - _classCallCheck(this, ImportManager); - - this.less = less; - this.rootFilename = rootFileInfo.filename; - this.paths = context.paths || []; // Search paths, when importing - - this.contents = {}; // map - filename to contents of all the files - - this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore - - this.mime = context.mime; - this.error = null; - this.context = context; // Deprecated? Unused outside of here, could be useful. +var sourceMapOutput = (function (environment) { + var SourceMapOutput = /** @class */ (function () { + function SourceMapOutput(options) { + this._css = []; + this._rootNode = options.rootNode; + this._contentsMap = options.contentsMap; + this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; + if (options.sourceMapFilename) { + this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); + } + this._outputFilename = options.outputFilename; + this.sourceMapURL = options.sourceMapURL; + if (options.sourceMapBasepath) { + this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); + } + if (options.sourceMapRootpath) { + this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); + if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { + this._sourceMapRootpath += '/'; + } + } + else { + this._sourceMapRootpath = ''; + } + this._outputSourceFiles = options.outputSourceFiles; + this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); + this._lineNumber = 0; + this._column = 0; + } + SourceMapOutput.prototype.removeBasepath = function (path) { + if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { + path = path.substring(this._sourceMapBasepath.length); + if (path.charAt(0) === '\\' || path.charAt(0) === '/') { + path = path.substring(1); + } + } + return path; + }; + SourceMapOutput.prototype.normalizeFilename = function (filename) { + filename = filename.replace(/\\/g, '/'); + filename = this.removeBasepath(filename); + return (this._sourceMapRootpath || '') + filename; + }; + SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) { + // ignore adding empty strings + if (!chunk) { + return; + } + var lines; + var sourceLines; + var columns; + var sourceColumns; + var i; + if (fileInfo && fileInfo.filename) { + var inputSource = this._contentsMap[fileInfo.filename]; + // remove vars/banner added to the top of the file + if (this._contentsIgnoredCharsMap[fileInfo.filename]) { + // adjust the index + index -= this._contentsIgnoredCharsMap[fileInfo.filename]; + if (index < 0) { + index = 0; + } + // adjust the source + inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); + } + // ignore empty content + if (inputSource === undefined) { + return; + } + inputSource = inputSource.substring(0, index); + sourceLines = inputSource.split('\n'); + sourceColumns = sourceLines[sourceLines.length - 1]; + } + lines = chunk.split('\n'); + columns = lines[lines.length - 1]; + if (fileInfo && fileInfo.filename) { + if (!mapLines) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column }, + original: { line: sourceLines.length, column: sourceColumns.length }, + source: this.normalizeFilename(fileInfo.filename) }); + } + else { + for (i = 0; i < lines.length; i++) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 }, + original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 }, + source: this.normalizeFilename(fileInfo.filename) }); + } + } + } + if (lines.length === 1) { + this._column += columns.length; + } + else { + this._lineNumber += lines.length - 1; + this._column = columns.length; + } + this._css.push(chunk); + }; + SourceMapOutput.prototype.isEmpty = function () { + return this._css.length === 0; + }; + SourceMapOutput.prototype.toCSS = function (context) { + this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); + if (this._outputSourceFiles) { + for (var filename in this._contentsMap) { + if (this._contentsMap.hasOwnProperty(filename)) { + var source = this._contentsMap[filename]; + if (this._contentsIgnoredCharsMap[filename]) { + source = source.slice(this._contentsIgnoredCharsMap[filename]); + } + this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + } + } + } + this._rootNode.genCSS(context, this); + if (this._css.length > 0) { + var sourceMapURL = void 0; + var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); + if (this.sourceMapURL) { + sourceMapURL = this.sourceMapURL; + } + else if (this._sourceMapFilename) { + sourceMapURL = this._sourceMapFilename; + } + this.sourceMapURL = sourceMapURL; + this.sourceMap = sourceMapContent; + } + return this._css.join(''); + }; + return SourceMapOutput; + }()); + return SourceMapOutput; +}); - this.queue = []; // Files which haven't been imported yet +var sourceMapBuilder = (function (SourceMapOutput, environment) { + var SourceMapBuilder = /** @class */ (function () { + function SourceMapBuilder(options) { + this.options = options; + } + SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) { + var sourceMapOutput = new SourceMapOutput({ + contentsIgnoredCharsMap: imports.contentsIgnoredChars, + rootNode: rootNode, + contentsMap: imports.contents, + sourceMapFilename: this.options.sourceMapFilename, + sourceMapURL: this.options.sourceMapURL, + outputFilename: this.options.sourceMapOutputFilename, + sourceMapBasepath: this.options.sourceMapBasepath, + sourceMapRootpath: this.options.sourceMapRootpath, + outputSourceFiles: this.options.outputSourceFiles, + sourceMapGenerator: this.options.sourceMapGenerator, + sourceMapFileInline: this.options.sourceMapFileInline + }); + var css = sourceMapOutput.toCSS(options); + this.sourceMap = sourceMapOutput.sourceMap; + this.sourceMapURL = sourceMapOutput.sourceMapURL; + if (this.options.sourceMapInputFilename) { + this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + } + if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { + this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); + } + return css + this.getCSSAppendage(); + }; + SourceMapBuilder.prototype.getCSSAppendage = function () { + var sourceMapURL = this.sourceMapURL; + if (this.options.sourceMapFileInline) { + if (this.sourceMap === undefined) { + return ''; + } + sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap); + } + if (sourceMapURL) { + return "/*# sourceMappingURL=" + sourceMapURL + " */"; + } + return ''; + }; + SourceMapBuilder.prototype.getExternalSourceMap = function () { + return this.sourceMap; + }; + SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) { + this.sourceMap = sourceMap; + }; + SourceMapBuilder.prototype.isInline = function () { + return this.options.sourceMapFileInline; + }; + SourceMapBuilder.prototype.getSourceMapURL = function () { + return this.sourceMapURL; + }; + SourceMapBuilder.prototype.getOutputFilename = function () { + return this.options.sourceMapOutputFilename; + }; + SourceMapBuilder.prototype.getInputFilename = function () { + return this.sourceMapInputFilename; + }; + return SourceMapBuilder; + }()); + return SourceMapBuilder; +}); - this.files = {}; // Holds the imported parse trees. - } +var transformTree = (function (root, options) { + if (options === void 0) { options = {}; } + var evaldRoot; + var variables = options.variables; + var evalEnv = new contexts.Eval(options); + // + // Allows setting variables with a hash, so: + // + // `{ color: new tree.Color('#f01') }` will become: + // + // new tree.Declaration('@color', + // new tree.Value([ + // new tree.Expression([ + // new tree.Color('#f01') + // ]) + // ]) + // ) + // + if (typeof variables === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables).map(function (k) { + var value = variables[k]; + if (!(value instanceof tree.Value)) { + if (!(value instanceof tree.Expression)) { + value = new tree.Expression([value]); + } + value = new tree.Value([value]); + } + return new tree.Declaration("@" + k, value, false, null, 0); + }); + evalEnv.frames = [new tree.Ruleset(null, variables)]; + } + var visitors$1 = [ + new visitors.JoinSelectorVisitor(), + new visitors.MarkVisibleSelectorsVisitor(true), + new visitors.ExtendVisitor(), + new visitors.ToCSSVisitor({ compress: Boolean(options.compress) }) + ]; + var preEvalVisitors = []; + var v; + var visitorIterator; /** - * Add an import to be imported - * @param path - the raw path - * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) - * @param currentFileInfo - the current file info (used for instance to work out relative paths) - * @param importOptions - import options - * @param callback - callback for when it is imported + * first() / get() allows visitors to be added while visiting + * + * @todo Add scoping for visitors just like functions for @plugin; right now they're global */ - - - _createClass(ImportManager, [{ - key: "push", - value: function push(path, tryAppendExtension, currentFileInfo, importOptions, callback) { - var importManager = this; - var pluginLoader = this.context.pluginManager.Loader; - this.queue.push(path); - - var fileParsedFunc = function fileParsedFunc(e, root, fullPath) { - importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue - - var importedEqualsRoot = fullPath === importManager.rootFilename; - - if (importOptions.optional && e) { - callback(null, { - rules: [] - }, false, null); - logger.info(`The file ${fullPath} was skipped because it was not found and the import was marked optional.`); - } else { - // Inline imports aren't cached here. - // If we start to cache them, please make sure they won't conflict with non-inline imports of the - // same name as they used to do before this comment and the condition below have been added. - if (!importManager.files[fullPath] && !importOptions.inline) { - importManager.files[fullPath] = { - root, - options: importOptions - }; + if (options.pluginManager) { + visitorIterator = options.pluginManager.visitor(); + for (var i = 0; i < 2; i++) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (v.isPreEvalVisitor) { + if (i === 0 || preEvalVisitors.indexOf(v) === -1) { + preEvalVisitors.push(v); + v.run(root); + } + } + else { + if (i === 0 || visitors$1.indexOf(v) === -1) { + if (v.isPreVisitor) { + visitors$1.unshift(v); + } + else { + visitors$1.push(v); + } + } + } + } + } + } + evaldRoot = root.eval(evalEnv); + for (var i = 0; i < visitors$1.length; i++) { + visitors$1[i].run(evaldRoot); + } + // Run any remaining visitors added after eval pass + if (options.pluginManager) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { + v.run(evaldRoot); } + } + } + return evaldRoot; +}); - if (e && !importManager.error) { - importManager.error = e; +var parseTree = (function (SourceMapBuilder) { + var ParseTree = /** @class */ (function () { + function ParseTree(root, imports) { + this.root = root; + this.imports = imports; + } + ParseTree.prototype.toCSS = function (options) { + var evaldRoot; + var result = {}; + var sourceMapBuilder; + try { + evaldRoot = transformTree(this.root, options); + } + catch (e) { + throw new LessError(e, this.imports); + } + try { + var compress = Boolean(options.compress); + if (compress) { + logger.warn('The compress option has been deprecated. ' + + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); + } + var toCSSOptions = { + compress: compress, + dumpLineNumbers: options.dumpLineNumbers, + strictUnits: Boolean(options.strictUnits), + numPrecision: 8 + }; + if (options.sourceMap) { + sourceMapBuilder = new SourceMapBuilder(options.sourceMap); + result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); + } + else { + result.css = evaldRoot.toCSS(toCSSOptions); + } + } + catch (e) { + throw new LessError(e, this.imports); + } + if (options.pluginManager) { + var postProcessors = options.pluginManager.getPostProcessors(); + for (var i_1 = 0; i_1 < postProcessors.length; i_1++) { + result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports }); + } + } + if (options.sourceMap) { + result.map = sourceMapBuilder.getExternalSourceMap(); + } + result.imports = []; + for (var file_1 in this.imports.files) { + if (this.imports.files.hasOwnProperty(file_1) && file_1 !== this.imports.rootFilename) { + result.imports.push(file_1); + } } - - callback(e, root, importedEqualsRoot, fullPath); - } - }; - - var newFileInfo = { - rewriteUrls: this.context.rewriteUrls, - entryPath: currentFileInfo.entryPath, - rootpath: currentFileInfo.rootpath, - rootFilename: currentFileInfo.rootFilename + return result; }; - var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + return ParseTree; + }()); + return ParseTree; +}); - if (!fileManager) { - fileParsedFunc({ - message: `Could not find a file-manager for ${path}` - }); - return; +var importManager = (function (environment) { + // FileInfo = { + // 'rewriteUrls' - option - whether to adjust URL's to be relative + // 'filename' - full resolved filename of current file + // 'rootpath' - path to append to normal URLs for this node + // 'currentDirectory' - path to the current file, absolute + // 'rootFilename' - filename of the base file + // 'entryPath' - absolute path to the entry file + // 'reference' - whether the file should not be output and only output parts that are referenced + var ImportManager = /** @class */ (function () { + function ImportManager(less, context, rootFileInfo) { + this.less = less; + this.rootFilename = rootFileInfo.filename; + this.paths = context.paths || []; // Search paths, when importing + this.contents = {}; // map - filename to contents of all the files + this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore + this.mime = context.mime; + this.error = null; + this.context = context; + // Deprecated? Unused outside of here, could be useful. + this.queue = []; // Files which haven't been imported yet + this.files = {}; // Holds the imported parse trees. } - - var loadFileCallback = function loadFileCallback(loadedFile) { - var plugin; - var resolvedFilename = loadedFile.filename; - var contents = loadedFile.contents.replace(/^\uFEFF/, ''); // Pass on an updated rootpath if path of imported file is relative and file - // is in a (sub|sup) directory - // - // Examples: - // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', - // then rootpath should become 'less/module/nav/' - // - If path of imported file is '../mixins.less' and rootpath is 'less/', - // then rootpath should become 'less/../' - - newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); - - if (newFileInfo.rewriteUrls) { - newFileInfo.rootpath = fileManager.join(importManager.context.rootpath || '', fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); - - if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { - newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + /** + * Add an import to be imported + * @param path - the raw path + * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) + * @param currentFileInfo - the current file info (used for instance to work out relative paths) + * @param importOptions - import options + * @param callback - callback for when it is imported + */ + ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) { + var importManager = this; + var pluginLoader = this.context.pluginManager.Loader; + this.queue.push(path); + var fileParsedFunc = function (e, root, fullPath) { + importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue + var importedEqualsRoot = fullPath === importManager.rootFilename; + if (importOptions.optional && e) { + callback(null, { rules: [] }, false, null); + logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional."); + } + else { + // Inline imports aren't cached here. + // If we start to cache them, please make sure they won't conflict with non-inline imports of the + // same name as they used to do before this comment and the condition below have been added. + if (!importManager.files[fullPath] && !importOptions.inline) { + importManager.files[fullPath] = { root: root, options: importOptions }; + } + if (e && !importManager.error) { + importManager.error = e; + } + callback(e, root, importedEqualsRoot, fullPath); + } + }; + var newFileInfo = { + rewriteUrls: this.context.rewriteUrls, + entryPath: currentFileInfo.entryPath, + rootpath: currentFileInfo.rootpath, + rootFilename: currentFileInfo.rootFilename + }; + var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + if (!fileManager) { + fileParsedFunc({ message: "Could not find a file-manager for " + path }); + return; + } + var loadFileCallback = function (loadedFile) { + var plugin; + var resolvedFilename = loadedFile.filename; + var contents = loadedFile.contents.replace(/^\uFEFF/, ''); + // Pass on an updated rootpath if path of imported file is relative and file + // is in a (sub|sup) directory + // + // Examples: + // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', + // then rootpath should become 'less/module/nav/' + // - If path of imported file is '../mixins.less' and rootpath is 'less/', + // then rootpath should become 'less/../' + newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); + if (newFileInfo.rewriteUrls) { + newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); + if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { + newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + } + } + newFileInfo.filename = resolvedFilename; + var newEnv = new contexts.Parse(importManager.context); + newEnv.processImports = false; + importManager.contents[resolvedFilename] = contents; + if (currentFileInfo.reference || importOptions.reference) { + newFileInfo.reference = true; + } + if (importOptions.isPlugin) { + plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); + if (plugin instanceof LessError) { + fileParsedFunc(plugin, null, resolvedFilename); + } + else { + fileParsedFunc(null, plugin, resolvedFilename); + } + } + else if (importOptions.inline) { + fileParsedFunc(null, contents, resolvedFilename); + } + else { + // import (multiple) parse trees apparently get altered and can't be cached. + // TODO: investigate why this is + if (importManager.files[resolvedFilename] + && !importManager.files[resolvedFilename].options.multiple + && !importOptions.multiple) { + fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); + } + else { + new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { + fileParsedFunc(e, root, resolvedFilename); + }); + } + } + }; + var promise; + var context = clone(this.context); + if (tryAppendExtension) { + context.ext = importOptions.isPlugin ? '.js' : '.less'; + } + if (importOptions.isPlugin) { + context.mime = 'application/javascript'; + promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); + } + else { + promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { + if (err) { + fileParsedFunc(err); + } + else { + loadFileCallback(loadedFile); + } + }); + } + if (promise) { + promise.then(loadFileCallback, fileParsedFunc); } - } - - newFileInfo.filename = resolvedFilename; - var newEnv = new contexts.Parse(importManager.context); - newEnv.processImports = false; - importManager.contents[resolvedFilename] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.isPlugin) { - plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); - - if (plugin instanceof LessError) { - fileParsedFunc(plugin, null, resolvedFilename); - } else { - fileParsedFunc(null, plugin, resolvedFilename); - } - } else if (importOptions.inline) { - fileParsedFunc(null, contents, resolvedFilename); - } else { - // import (multiple) parse trees apparently get altered and can't be cached. - // TODO: investigate why this is - if (importManager.files[resolvedFilename] && !importManager.files[resolvedFilename].options.multiple && !importOptions.multiple) { - fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); - } else { - new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { - fileParsedFunc(e, root, resolvedFilename); - }); - } - } }; - - var promise; - var context = clone(this.context); - - if (tryAppendExtension) { - context.ext = importOptions.isPlugin ? '.js' : '.less'; - } - - if (importOptions.isPlugin) { - context.mime = 'application/javascript'; - promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); - } else { - promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { - if (err) { - fileParsedFunc(err); - } else { - loadFileCallback(loadedFile); - } - }); - } - - if (promise) { - promise.then(loadFileCallback, fileParsedFunc); - } - } - }]); - + return ImportManager; + }()); return ImportManager; - }(); - - return ImportManager; }); var Render = (function (environment, ParseTree, ImportManager) { - var render = function render(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - render.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - this.parse(input, options, function (err, root, imports, options) { - if (err) { - return callback(err); + var render = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + render.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - - var result; - - try { - var parseTree = new ParseTree(root, imports); - result = parseTree.toCSS(options); - } catch (err) { - return callback(err); + else { + this.parse(input, options, function (err, root, imports, options) { + if (err) { + return callback(err); + } + var result; + try { + var parseTree = new ParseTree(root, imports); + result = parseTree.toCSS(options); + } + catch (err) { + return callback(err); + } + callback(null, result); + }); } - - callback(null, result); - }); - } - }; - - return render; + }; + return render; }); /** * Plugin Manager */ -var PluginManager = -/*#__PURE__*/ -function () { - function PluginManager(less) { - _classCallCheck(this, PluginManager); - - this.less = less; - this.visitors = []; - this.preProcessors = []; - this.postProcessors = []; - this.installedPlugins = []; - this.fileManagers = []; - this.iterator = -1; - this.pluginCache = {}; - this.Loader = new less.PluginLoader(less); - } - /** - * Adds all the plugins in the array - * @param {Array} plugins - */ - - - _createClass(PluginManager, [{ - key: "addPlugins", - value: function addPlugins(plugins) { - if (plugins) { - for (var i = 0; i < plugins.length; i++) { - this.addPlugin(plugins[i]); - } - } +var PluginManager = /** @class */ (function () { + function PluginManager(less) { + this.less = less; + this.visitors = []; + this.preProcessors = []; + this.postProcessors = []; + this.installedPlugins = []; + this.fileManagers = []; + this.iterator = -1; + this.pluginCache = {}; + this.Loader = new less.PluginLoader(less); } + /** + * Adds all the plugins in the array + * @param {Array} plugins + */ + PluginManager.prototype.addPlugins = function (plugins) { + if (plugins) { + for (var i_1 = 0; i_1 < plugins.length; i_1++) { + this.addPlugin(plugins[i_1]); + } + } + }; /** * * @param plugin * @param {String} filename */ - - }, { - key: "addPlugin", - value: function addPlugin(plugin, filename, functionRegistry) { - this.installedPlugins.push(plugin); - - if (filename) { - this.pluginCache[filename] = plugin; - } - - if (plugin.install) { - plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); - } - } + PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) { + this.installedPlugins.push(plugin); + if (filename) { + this.pluginCache[filename] = plugin; + } + if (plugin.install) { + plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); + } + }; /** * * @param filename */ - - }, { - key: "get", - value: function get(filename) { - return this.pluginCache[filename]; - } + PluginManager.prototype.get = function (filename) { + return this.pluginCache[filename]; + }; /** * Adds a visitor. The visitor object has options on itself to determine * when it should run. * @param visitor */ - - }, { - key: "addVisitor", - value: function addVisitor(visitor) { - this.visitors.push(visitor); - } + PluginManager.prototype.addVisitor = function (visitor) { + this.visitors.push(visitor); + }; /** * Adds a pre processor object * @param {object} preProcessor * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import */ - - }, { - key: "addPreProcessor", - value: function addPreProcessor(preProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { - if (this.preProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPreProcessor = function (preProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { + if (this.preProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.preProcessors.splice(indexToInsertAt, 0, { - preProcessor, - priority - }); - } + this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority }); + }; /** * Adds a post processor object * @param {object} postProcessor * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression */ - - }, { - key: "addPostProcessor", - value: function addPostProcessor(postProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { - if (this.postProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPostProcessor = function (postProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { + if (this.postProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.postProcessors.splice(indexToInsertAt, 0, { - postProcessor, - priority - }); - } + this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority }); + }; /** * * @param manager */ - - }, { - key: "addFileManager", - value: function addFileManager(manager) { - this.fileManagers.push(manager); - } + PluginManager.prototype.addFileManager = function (manager) { + this.fileManagers.push(manager); + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPreProcessors", - value: function getPreProcessors() { - var preProcessors = []; - - for (var i = 0; i < this.preProcessors.length; i++) { - preProcessors.push(this.preProcessors[i].preProcessor); - } - - return preProcessors; - } + PluginManager.prototype.getPreProcessors = function () { + var preProcessors = []; + for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) { + preProcessors.push(this.preProcessors[i_2].preProcessor); + } + return preProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPostProcessors", - value: function getPostProcessors() { - var postProcessors = []; - - for (var i = 0; i < this.postProcessors.length; i++) { - postProcessors.push(this.postProcessors[i].postProcessor); - } - - return postProcessors; - } + PluginManager.prototype.getPostProcessors = function () { + var postProcessors = []; + for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) { + postProcessors.push(this.postProcessors[i_3].postProcessor); + } + return postProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getVisitors", - value: function getVisitors() { - return this.visitors; - } - }, { - key: "visitor", - value: function visitor() { - var self = this; - return { - first: function first() { - self.iterator = -1; - return self.visitors[self.iterator]; - }, - get: function get() { - self.iterator += 1; - return self.visitors[self.iterator]; - } - }; - } + PluginManager.prototype.getVisitors = function () { + return this.visitors; + }; + PluginManager.prototype.visitor = function () { + var self = this; + return { + first: function () { + self.iterator = -1; + return self.visitors[self.iterator]; + }, + get: function () { + self.iterator += 1; + return self.visitors[self.iterator]; + } + }; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getFileManagers", - value: function getFileManagers() { - return this.fileManagers; - } - }]); - - return PluginManager; -}(); - + PluginManager.prototype.getFileManagers = function () { + return this.fileManagers; + }; + return PluginManager; +}()); var pm; - function PluginManagerFactory(less, newFactory) { - if (newFactory || !pm) { - pm = new PluginManager(less); - } - - return pm; + if (newFactory || !pm) { + pm = new PluginManager(less); + } + return pm; } var Parse = (function (environment, ParseTree, ImportManager) { - var parse = function parse(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - parse.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - var context; - var rootFileInfo; - var pluginManager = new PluginManagerFactory(this, !options.reUsePluginManager); - options.pluginManager = pluginManager; - context = new contexts.Parse(options); - - if (options.rootFileInfo) { - rootFileInfo = options.rootFileInfo; - } else { - var filename = options.filename || 'input'; - var entryPath = filename.replace(/[^\/\\]*$/, ''); - rootFileInfo = { - filename, - rewriteUrls: context.rewriteUrls, - rootpath: context.rootpath || '', - currentDirectory: entryPath, - entryPath, - rootFilename: filename - }; // add in a missing trailing slash - - if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { - rootFileInfo.rootpath += '/'; + var parse = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + parse.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - } - - var imports = new ImportManager(this, context, rootFileInfo); - this.importManager = imports; // TODO: allow the plugins to be just a list of paths or names - // Do an async plugin queue like lessc - - if (options.plugins) { - options.plugins.forEach(function (plugin) { - var evalResult; - var contents; - - if (plugin.fileContent) { - contents = plugin.fileContent.replace(/^\uFEFF/, ''); - evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename); - - if (evalResult instanceof LessError) { - return callback(evalResult); + else { + var context_1; + var rootFileInfo = void 0; + var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager); + options.pluginManager = pluginManager_1; + context_1 = new contexts.Parse(options); + if (options.rootFileInfo) { + rootFileInfo = options.rootFileInfo; } - } else { - pluginManager.addPlugin(plugin); - } - }); - } - - new Parser(context, imports, rootFileInfo).parse(input, function (e, root) { - if (e) { - return callback(e); + else { + var filename = options.filename || 'input'; + var entryPath = filename.replace(/[^\/\\]*$/, ''); + rootFileInfo = { + filename: filename, + rewriteUrls: context_1.rewriteUrls, + rootpath: context_1.rootpath || '', + currentDirectory: entryPath, + entryPath: entryPath, + rootFilename: filename + }; + // add in a missing trailing slash + if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { + rootFileInfo.rootpath += '/'; + } + } + var imports_1 = new ImportManager(this, context_1, rootFileInfo); + this.importManager = imports_1; + // TODO: allow the plugins to be just a list of paths or names + // Do an async plugin queue like lessc + if (options.plugins) { + options.plugins.forEach(function (plugin) { + var evalResult; + var contents; + if (plugin.fileContent) { + contents = plugin.fileContent.replace(/^\uFEFF/, ''); + evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename); + if (evalResult instanceof LessError) { + return callback(evalResult); + } + } + else { + pluginManager_1.addPlugin(plugin); + } + }); + } + new Parser(context_1, imports_1, rootFileInfo) + .parse(input, function (e, root) { + if (e) { + return callback(e); + } + callback(null, root, imports_1, options); + }, options); } - - callback(null, root, imports, options); - }, options); - } - }; - - return parse; + }; + return parse; }); var createFromEnvironment = (function (environment, fileManagers) { - /** - * @todo - * This original code could be improved quite a bit. - * Many classes / modules currently add side-effects / mutations to passed in objects, - * which makes it hard to refactor and reason about. - */ - environment = new environment$1(environment, fileManagers); - var SourceMapOutput = sourceMapOutput(environment); - var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment); - var ParseTree = parseTree(SourceMapBuilder); - var ImportManager = importManager(environment); - var render = Render(environment, ParseTree); - var parse = Parse(environment, ParseTree, ImportManager); - var functions = Functions(environment); - /** - * @todo - * This root properties / methods need to be organized. - * It's not clear what should / must be public and why. - */ - - var initial = { - version: [3, 10, 3], - data, - tree, - Environment: environment$1, - AbstractFileManager, - AbstractPluginLoader, - environment, - visitors, - Parser, - functions, - contexts, - SourceMapOutput, - SourceMapBuilder, - ParseTree, - ImportManager, - render, - parse, - LessError, - transformTree, - utils, - PluginManager: PluginManagerFactory, - logger - }; // Create a public API - - var ctor = function ctor(t) { - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return _construct(t, args); + /** + * @todo + * This original code could be improved quite a bit. + * Many classes / modules currently add side-effects / mutations to passed in objects, + * which makes it hard to refactor and reason about. + */ + environment = new environment$1(environment, fileManagers); + var SourceMapOutput = sourceMapOutput(environment); + var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment); + var ParseTree = parseTree(SourceMapBuilder); + var ImportManager = importManager(environment); + var render = Render(environment, ParseTree); + var parse = Parse(environment, ParseTree, ImportManager); + var functions = Functions(environment); + /** + * @todo + * This root properties / methods need to be organized. + * It's not clear what should / must be public and why. + */ + var initial = { + version: [3, 11, 0], + data: data, + tree: tree, + Environment: environment$1, + AbstractFileManager: AbstractFileManager, + AbstractPluginLoader: AbstractPluginLoader, + environment: environment, + visitors: visitors, + Parser: Parser, + functions: functions, + contexts: contexts, + SourceMapOutput: SourceMapOutput, + SourceMapBuilder: SourceMapBuilder, + ParseTree: ParseTree, + ImportManager: ImportManager, + render: render, + parse: parse, + LessError: LessError, + transformTree: transformTree, + utils: utils, + PluginManager: PluginManagerFactory, + logger: logger }; - }; - - var t; - var api = Object.create(initial); - - for (var n in initial.tree) { - /* eslint guard-for-in: 0 */ - t = initial.tree[n]; - - if (typeof t === 'function') { - api[n.toLowerCase()] = ctor(t); - } else { - api[n] = Object.create(null); - - for (var o in t) { + // Create a public API + var ctor = function (t) { return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new (t.bind.apply(t, tslib.__spreadArrays([void 0], args)))(); + }; }; + var t; + var api = Object.create(initial); + for (var n in initial.tree) { /* eslint guard-for-in: 0 */ - api[n][o.toLowerCase()] = ctor(t[o]); - } + t = initial.tree[n]; + if (typeof t === 'function') { + api[n.toLowerCase()] = ctor(t); + } + else { + api[n] = Object.create(null); + for (var o in t) { + /* eslint guard-for-in: 0 */ + api[n][o.toLowerCase()] = ctor(t[o]); + } + } } - } - - return api; + return api; }); function createCommonjsModule(fn, module) { @@ -13423,294 +10615,255 @@ function createCommonjsModule(fn, module) { } var lesscHelper = createCommonjsModule(function (module, exports) { - // lessc_helper.js - // - // helper functions for lessc - var lessc_helper = { - // Stylize a string - stylize: function stylize(str, style) { - var styles = { - 'reset': [0, 0], - 'bold': [1, 22], - 'inverse': [7, 27], - 'underline': [4, 24], - 'yellow': [33, 39], - 'green': [32, 39], - 'red': [31, 39], - 'grey': [90, 39] - }; - return `\x1b[${styles[style][0]}m${str}\x1b[${styles[style][1]}m`; - }, - // Print command line options - printUsage: function printUsage() { - console.log('usage: lessc [option option=parameter ...] [destination]'); - console.log(''); - console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.'); - console.log(''); - console.log('options:'); - console.log(' -h, --help Prints help (this message) and exit.'); - console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.'); - console.log(' -M, --depends Outputs a makefile import dependency list to stdout.'); - console.log(' --no-color Disables colorized output.'); - console.log(' --ie-compat Enables IE8 compatibility checks.'); - console.log(' --js Enables inline JavaScript in less files'); - console.log(' -l, --lint Syntax check only (lint).'); - console.log(' -s, --silent Suppresses output of error messages.'); - console.log(' --strict-imports Forces evaluation of imports.'); - console.log(' --insecure Allows imports from insecure https hosts.'); - console.log(' -v, --version Prints version number and exit.'); - console.log(' --verbose Be verbose.'); - console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).'); - console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.'); - console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.'); - console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.'); - console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.'); - console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment'); - console.log(' in generated CSS file.'); - console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls'); - console.log(' Works with or without the relative-urls option.'); - console.log(' -ru=, --rewrite-urls= Rewrites URLs to make them relative to the base less file.'); - console.log(' all|local|off \'all\' rewrites all URLs, \'local\' just those starting with a \'.\''); - console.log(''); - console.log(' -m=, --math='); - console.log(' always Less will eagerly perform math operations always.'); - console.log(' parens-division Math performed except for division (/) operator'); - console.log(' parens | strict Math only performed inside parentheses'); - console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)'); - console.log(''); - console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units'); - console.log(' --strict-units=on|off that cannot be represented.'); - console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.'); - console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.'); - console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')'); - console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins'); - console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css'); - console.log(' once installed (npm install less-plugin-clean-css), use either with'); - console.log(' --plugin=less-plugin-clean-css or just --clean-css'); - console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"'); - console.log(' or --clean-css="advanced"'); - console.log(''); - console.log('-------------------------- Deprecated ----------------'); - console.log(' -sm=on|off Legacy parens-only math. Use --math'); - console.log(' --strict-math=on|off '); - console.log(''); - console.log(' --line-numbers=TYPE Outputs filename and line numbers.'); - console.log(' TYPE can be either \'comments\', which will output'); - console.log(' the debug info within comments, \'mediaquery\''); - console.log(' that will output the information within a fake'); - console.log(' media query which is compatible with the SASS'); - console.log(' format, and \'all\' which will do both.'); - console.log(' -x, --compress Compresses output by removing some whitespaces.'); - console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css'); - console.log(''); - console.log('Report bugs to: http://github.com/less/less.js/issues'); - console.log('Home page: '); - } - }; // Exports helper functions - - for (var h in lessc_helper) { - if (lessc_helper.hasOwnProperty(h)) { - exports[h] = lessc_helper[h]; + // lessc_helper.js + // + // helper functions for lessc + var lessc_helper = { + // Stylize a string + stylize: function (str, style) { + var styles = { + 'reset': [0, 0], + 'bold': [1, 22], + 'inverse': [7, 27], + 'underline': [4, 24], + 'yellow': [33, 39], + 'green': [32, 39], + 'red': [31, 39], + 'grey': [90, 39] + }; + return "\u001B[" + styles[style][0] + "m" + str + "\u001B[" + styles[style][1] + "m"; + }, + // Print command line options + printUsage: function () { + console.log('usage: lessc [option option=parameter ...] [destination]'); + console.log(''); + console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.'); + console.log(''); + console.log('options:'); + console.log(' -h, --help Prints help (this message) and exit.'); + console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.'); + console.log(' -M, --depends Outputs a makefile import dependency list to stdout.'); + console.log(' --no-color Disables colorized output.'); + console.log(' --ie-compat Enables IE8 compatibility checks.'); + console.log(' --js Enables inline JavaScript in less files'); + console.log(' -l, --lint Syntax check only (lint).'); + console.log(' -s, --silent Suppresses output of error messages.'); + console.log(' --strict-imports Forces evaluation of imports.'); + console.log(' --insecure Allows imports from insecure https hosts.'); + console.log(' -v, --version Prints version number and exit.'); + console.log(' --verbose Be verbose.'); + console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).'); + console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.'); + console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.'); + console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.'); + console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.'); + console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment'); + console.log(' in generated CSS file.'); + console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls'); + console.log(' Works with or without the relative-urls option.'); + console.log(' -ru=, --rewrite-urls= Rewrites URLs to make them relative to the base less file.'); + console.log(' all|local|off \'all\' rewrites all URLs, \'local\' just those starting with a \'.\''); + console.log(''); + console.log(' -m=, --math='); + console.log(' always Less will eagerly perform math operations always.'); + console.log(' parens-division Math performed except for division (/) operator'); + console.log(' parens | strict Math only performed inside parentheses'); + console.log(' strict-legacy Parens required in very strict terms (legacy --strict-math)'); + console.log(''); + console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units'); + console.log(' --strict-units=on|off that cannot be represented.'); + console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.'); + console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.'); + console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')'); + console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins'); + console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css'); + console.log(' once installed (npm install less-plugin-clean-css), use either with'); + console.log(' --plugin=less-plugin-clean-css or just --clean-css'); + console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"'); + console.log(' or --clean-css="advanced"'); + console.log(''); + console.log('-------------------------- Deprecated ----------------'); + console.log(' -sm=on|off Legacy parens-only math. Use --math'); + console.log(' --strict-math=on|off '); + console.log(''); + console.log(' --line-numbers=TYPE Outputs filename and line numbers.'); + console.log(' TYPE can be either \'comments\', which will output'); + console.log(' the debug info within comments, \'mediaquery\''); + console.log(' that will output the information within a fake'); + console.log(' media query which is compatible with the SASS'); + console.log(' format, and \'all\' which will do both.'); + console.log(' -x, --compress Compresses output by removing some whitespaces.'); + console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css'); + console.log(''); + console.log('Report bugs to: http://github.com/less/less.js/issues'); + console.log('Home page: '); + } + }; + // Exports helper functions + for (var h in lessc_helper) { + if (lessc_helper.hasOwnProperty(h)) { + exports[h] = lessc_helper[h]; + } } - } }); /** * Node Plugin Loader */ - -var PluginLoader = -/*#__PURE__*/ -function (_AbstractPluginLoader) { - _inherits(PluginLoader, _AbstractPluginLoader); - - function PluginLoader(less) { - var _this; - - _classCallCheck(this, PluginLoader); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(PluginLoader).call(this)); - _this.less = less; - - _this.require = function (prefix) { - prefix = path.dirname(prefix); - return function (id) { - var str = id.substr(0, 2); - - if (str === '..' || str === './') { - return require(path.join(prefix, id)); - } else { - return require(id); - } - }; - }; - - return _this; - } - - _createClass(PluginLoader, [{ - key: "loadPlugin", - value: function loadPlugin(filename, basePath, context, environment, fileManager) { - var prefix = filename.slice(0, 1); - var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js'; - - if (!explicit) { - context.prefixes = ['less-plugin-', '']; - } - - return new Promise(function (fulfill, reject) { - fileManager.loadFile(filename, basePath, context, environment).then(function (data) { - try { - fulfill(data); - } catch (e) { - console.log(e); - reject(e); - } - }).catch(function (err) { - reject(err); +var PluginLoader = /** @class */ (function (_super) { + tslib.__extends(PluginLoader, _super); + function PluginLoader(less) { + var _this = _super.call(this) || this; + _this.less = less; + _this.require = function (prefix) { + prefix = path.dirname(prefix); + return function (id) { + var str = id.substr(0, 2); + if (str === '..' || str === './') { + return require(path.join(prefix, id)); + } + else { + return require(id); + } + }; + }; + return _this; + } + PluginLoader.prototype.loadPlugin = function (filename, basePath, context, environment, fileManager) { + var prefix = filename.slice(0, 1); + var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js'; + if (!explicit) { + context.prefixes = ['less-plugin-', '']; + } + return new Promise(function (fulfill, reject) { + fileManager.loadFile(filename, basePath, context, environment).then(function (data) { + try { + fulfill(data); + } + catch (e) { + console.log(e); + reject(e); + } + }).catch(function (err) { + reject(err); + }); }); - }); - } - }]); - - return PluginLoader; -}(AbstractPluginLoader); + }; + return PluginLoader; +}(AbstractPluginLoader)); // Export a new default each time -var defaultOptions = (function () { - return { +var defaultOptions = (function () { return ({ /* Inline Javascript - @plugin still allowed */ javascriptEnabled: false, - /* Outputs a makefile import dependency list to stdout. */ depends: false, - - /* (DEPRECATED) Compress using less built-in compression. - * This does an okay job but does not utilise all the tricks of - * dedicated css compression. */ + /* (DEPRECATED) Compress using less built-in compression. + * This does an okay job but does not utilise all the tricks of + * dedicated css compression. */ compress: false, - /* Runs the less parser and just reports errors without any output. */ lint: false, - /* Sets available include paths. - * If the file in an @import rule does not exist at that exact location, - * less will look for it at the location(s) passed to this option. - * You might use this for instance to specify a path to a library which - * you want to be referenced simply and relatively in the less files. */ + * If the file in an @import rule does not exist at that exact location, + * less will look for it at the location(s) passed to this option. + * You might use this for instance to specify a path to a library which + * you want to be referenced simply and relatively in the less files. */ paths: [], - /* color output in the terminal */ color: true, - - /* The strictImports controls whether the compiler will allow an @import inside of either - * @media blocks or (a later addition) other selector blocks. - * See: https://github.com/less/less.js/issues/656 */ + /* The strictImports controls whether the compiler will allow an @import inside of either + * @media blocks or (a later addition) other selector blocks. + * See: https://github.com/less/less.js/issues/656 */ strictImports: false, - /* Allow Imports from Insecure HTTPS Hosts */ insecure: false, - - /* Allows you to add a path to every generated import and url in your css. - * This does not affect less import statements that are processed, just ones - * that are left in the output css. */ + /* Allows you to add a path to every generated import and url in your css. + * This does not affect less import statements that are processed, just ones + * that are left in the output css. */ rootpath: '', - - /* By default URLs are kept as-is, so if you import a file in a sub-directory - * that references an image, exactly the same URL will be output in the css. - * This option allows you to re-write URL's in imported files so that the - * URL is always relative to the base imported file */ + /* By default URLs are kept as-is, so if you import a file in a sub-directory + * that references an image, exactly the same URL will be output in the css. + * This option allows you to re-write URL's in imported files so that the + * URL is always relative to the base imported file */ rewriteUrls: false, - - /* How to process math - * 0 always - eagerly try to solve all operations - * 1 parens-division - require parens for division "/" - * 2 parens | strict - require parens for all operations - * 3 strict-legacy - legacy strict behavior (super-strict) - */ + /* How to process math + * 0 always - eagerly try to solve all operations + * 1 parens-division - require parens for division "/" + * 2 parens | strict - require parens for all operations + * 3 strict-legacy - legacy strict behavior (super-strict) + */ math: 0, - /* Without this option, less attempts to guess at the output unit when it does maths. */ strictUnits: false, - - /* Effectively the declaration is put at the top of your base Less file, - * meaning it can be used but it also can be overridden if this variable - * is defined in the file. */ + /* Effectively the declaration is put at the top of your base Less file, + * meaning it can be used but it also can be overridden if this variable + * is defined in the file. */ globalVars: null, - /* As opposed to the global variable option, this puts the declaration at the - * end of your base file, meaning it will override anything defined in your Less file. */ + * end of your base file, meaning it will override anything defined in your Less file. */ modifyVars: null, - /* This option allows you to specify a argument to go on to every URL. */ urlArgs: '' - }; -}); +}); }); var imageSize = (function (environment) { - function _imageSize(functionContext, filePathNode) { - var filePath = filePathNode.value; - var currentFileInfo = functionContext.currentFileInfo; - var currentDirectory = currentFileInfo.rewriteUrls ? currentFileInfo.currentDirectory : currentFileInfo.entryPath; - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - var fileManager = environment.getFileManager(filePath, currentDirectory, functionContext.context, environment, true); - - if (!fileManager) { - throw { - type: 'File', - message: `Can not set up FileManager for ${filePathNode}` - }; - } - - var fileSync = fileManager.loadFileSync(filePath, currentDirectory, functionContext.context, environment); - - if (fileSync.error) { - throw fileSync.error; - } - - var sizeOf = require('image-size'); - - return sizeOf(fileSync.filename); - } - - var imageFunctions = { - 'image-size': function imageSize(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Expression([new Dimension(size.width, 'px'), new Dimension(size.height, 'px')]); - }, - 'image-width': function imageWidth(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Dimension(size.width, 'px'); - }, - 'image-height': function imageHeight(filePathNode) { - var size = _imageSize(this, filePathNode); - - return new Dimension(size.height, 'px'); + function imageSize(functionContext, filePathNode) { + var filePath = filePathNode.value; + var currentFileInfo = functionContext.currentFileInfo; + var currentDirectory = currentFileInfo.rewriteUrls ? + currentFileInfo.currentDirectory : currentFileInfo.entryPath; + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart !== -1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + var fileManager = environment.getFileManager(filePath, currentDirectory, functionContext.context, environment, true); + if (!fileManager) { + throw { + type: 'File', + message: "Can not set up FileManager for " + filePathNode + }; + } + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, functionContext.context, environment); + if (fileSync.error) { + throw fileSync.error; + } + var sizeOf = require('image-size'); + return sizeOf(fileSync.filename); } - }; - functionRegistry.addMultiple(imageFunctions); + var imageFunctions = { + 'image-size': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Expression([ + new Dimension(size.width, 'px'), + new Dimension(size.height, 'px') + ]); + }, + 'image-width': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Dimension(size.width, 'px'); + }, + 'image-height': function (filePathNode) { + var size = imageSize(this, filePathNode); + return new Dimension(size.height, 'px'); + } + }; + functionRegistry.addMultiple(imageFunctions); }); -var less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]); // allow people to create less with their own environment - +var less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]); +// allow people to create less with their own environment less.createFromEnvironment = createFromEnvironment; less.lesscHelper = lesscHelper; less.PluginLoader = PluginLoader; less.fs = fs$1; less.FileManager = FileManager; -less.UrlFileManager = UrlFileManager; // Set up options - -less.options = defaultOptions(); // provide image-size functionality - +less.UrlFileManager = UrlFileManager; +// Set up options +less.options = defaultOptions(); +// provide image-size functionality imageSize(less.environment); module.exports = less; diff --git a/dist/less.js b/dist/less.js index 8219629d3..3a60d61a7 100644 --- a/dist/less.js +++ b/dist/less.js @@ -1,8 +1,8 @@ /** - * Less - Leaner CSS v3.10.3 + * Less - Leaner CSS v3.11.0 * http://lesscss.org * - * Copyright (c) 2009-2019, Alexis Sellier + * Copyright (c) 2009-2020, Alexis Sellier * Licensed under the Apache-2.0 License. * * @license Apache-2.0 @@ -12,1198 +12,908 @@ typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global = global || self, global.less = factory()); -}(this, function () { 'use strict'; +}(this, (function () { 'use strict'; // Export a new default each time - var defaultOptions = (function () { - return { + var defaultOptions = (function () { return ({ /* Inline Javascript - @plugin still allowed */ javascriptEnabled: false, - /* Outputs a makefile import dependency list to stdout. */ depends: false, - - /* (DEPRECATED) Compress using less built-in compression. - * This does an okay job but does not utilise all the tricks of - * dedicated css compression. */ + /* (DEPRECATED) Compress using less built-in compression. + * This does an okay job but does not utilise all the tricks of + * dedicated css compression. */ compress: false, - /* Runs the less parser and just reports errors without any output. */ lint: false, - /* Sets available include paths. - * If the file in an @import rule does not exist at that exact location, - * less will look for it at the location(s) passed to this option. - * You might use this for instance to specify a path to a library which - * you want to be referenced simply and relatively in the less files. */ + * If the file in an @import rule does not exist at that exact location, + * less will look for it at the location(s) passed to this option. + * You might use this for instance to specify a path to a library which + * you want to be referenced simply and relatively in the less files. */ paths: [], - /* color output in the terminal */ color: true, - - /* The strictImports controls whether the compiler will allow an @import inside of either - * @media blocks or (a later addition) other selector blocks. - * See: https://github.com/less/less.js/issues/656 */ + /* The strictImports controls whether the compiler will allow an @import inside of either + * @media blocks or (a later addition) other selector blocks. + * See: https://github.com/less/less.js/issues/656 */ strictImports: false, - /* Allow Imports from Insecure HTTPS Hosts */ insecure: false, - - /* Allows you to add a path to every generated import and url in your css. - * This does not affect less import statements that are processed, just ones - * that are left in the output css. */ + /* Allows you to add a path to every generated import and url in your css. + * This does not affect less import statements that are processed, just ones + * that are left in the output css. */ rootpath: '', - - /* By default URLs are kept as-is, so if you import a file in a sub-directory - * that references an image, exactly the same URL will be output in the css. - * This option allows you to re-write URL's in imported files so that the - * URL is always relative to the base imported file */ + /* By default URLs are kept as-is, so if you import a file in a sub-directory + * that references an image, exactly the same URL will be output in the css. + * This option allows you to re-write URL's in imported files so that the + * URL is always relative to the base imported file */ rewriteUrls: false, - - /* How to process math - * 0 always - eagerly try to solve all operations - * 1 parens-division - require parens for division "/" - * 2 parens | strict - require parens for all operations - * 3 strict-legacy - legacy strict behavior (super-strict) - */ + /* How to process math + * 0 always - eagerly try to solve all operations + * 1 parens-division - require parens for division "/" + * 2 parens | strict - require parens for all operations + * 3 strict-legacy - legacy strict behavior (super-strict) + */ math: 0, - /* Without this option, less attempts to guess at the output unit when it does maths. */ strictUnits: false, - - /* Effectively the declaration is put at the top of your base Less file, - * meaning it can be used but it also can be overridden if this variable - * is defined in the file. */ + /* Effectively the declaration is put at the top of your base Less file, + * meaning it can be used but it also can be overridden if this variable + * is defined in the file. */ globalVars: null, - /* As opposed to the global variable option, this puts the declaration at the - * end of your base file, meaning it will override anything defined in your Less file. */ + * end of your base file, meaning it will override anything defined in your Less file. */ modifyVars: null, - /* This option allows you to specify a argument to go on to every URL. */ urlArgs: '' - }; - }); + }); }); function extractId(href) { - return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain - .replace(/[\?\&]livereload=\w+/, '') // Remove LiveReload cachebuster - .replace(/^\//, '') // Remove root / - .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension - .replace(/[^\.\w-]+/g, '-') // Replace illegal characters - .replace(/\./g, ':'); // Replace dots with colons(for valid id) + return href.replace(/^[a-z-]+:\/+?[^\/]+/, '') // Remove protocol & domain + .replace(/[\?\&]livereload=\w+/, '') // Remove LiveReload cachebuster + .replace(/^\//, '') // Remove root / + .replace(/\.[a-zA-Z]+$/, '') // Remove simple extension + .replace(/[^\.\w-]+/g, '-') // Replace illegal characters + .replace(/\./g, ':'); // Replace dots with colons(for valid id) } function addDataAttr(options, tag) { - for (var opt in tag.dataset) { - if (tag.dataset.hasOwnProperty(opt)) { - if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') { - options[opt] = tag.dataset[opt]; - } else { - try { - options[opt] = JSON.parse(tag.dataset[opt]); - } catch (_) {} - } + for (var opt in tag.dataset) { + if (tag.dataset.hasOwnProperty(opt)) { + if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') { + options[opt] = tag.dataset[opt]; + } + else { + try { + options[opt] = JSON.parse(tag.dataset[opt]); + } + catch (_) { } + } + } } - } } var browser = { - createCSS: function createCSS(document, styles, sheet) { - // Strip the query-string - var href = sheet.href || ''; // If there is no title set, use the filename, minus the extension - - var id = "less:".concat(sheet.title || extractId(href)); // If this has already been inserted into the DOM, we may need to replace it - - var oldStyleNode = document.getElementById(id); - var keepOldStyleNode = false; // Create a new stylesheet node for insertion or (if necessary) replacement - - var styleNode = document.createElement('style'); - styleNode.setAttribute('type', 'text/css'); - - if (sheet.media) { - styleNode.setAttribute('media', sheet.media); - } - - styleNode.id = id; - - if (!styleNode.styleSheet) { - styleNode.appendChild(document.createTextNode(styles)); // If new contents match contents of oldStyleNode, don't replace oldStyleNode - - keepOldStyleNode = oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 && oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue; - } - - var head = document.getElementsByTagName('head')[0]; // If there is no oldStyleNode, just append; otherwise, only append if we need - // to replace oldStyleNode with an updated stylesheet - - if (oldStyleNode === null || keepOldStyleNode === false) { - var nextEl = sheet && sheet.nextSibling || null; - - if (nextEl) { - nextEl.parentNode.insertBefore(styleNode, nextEl); - } else { - head.appendChild(styleNode); - } + createCSS: function (document, styles, sheet) { + // Strip the query-string + var href = sheet.href || ''; + // If there is no title set, use the filename, minus the extension + var id = "less:" + (sheet.title || extractId(href)); + // If this has already been inserted into the DOM, we may need to replace it + var oldStyleNode = document.getElementById(id); + var keepOldStyleNode = false; + // Create a new stylesheet node for insertion or (if necessary) replacement + var styleNode = document.createElement('style'); + styleNode.setAttribute('type', 'text/css'); + if (sheet.media) { + styleNode.setAttribute('media', sheet.media); + } + styleNode.id = id; + if (!styleNode.styleSheet) { + styleNode.appendChild(document.createTextNode(styles)); + // If new contents match contents of oldStyleNode, don't replace oldStyleNode + keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 && + oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue); + } + var head = document.getElementsByTagName('head')[0]; + // If there is no oldStyleNode, just append; otherwise, only append if we need + // to replace oldStyleNode with an updated stylesheet + if (oldStyleNode === null || keepOldStyleNode === false) { + var nextEl = sheet && sheet.nextSibling || null; + if (nextEl) { + nextEl.parentNode.insertBefore(styleNode, nextEl); + } + else { + head.appendChild(styleNode); + } + } + if (oldStyleNode && keepOldStyleNode === false) { + oldStyleNode.parentNode.removeChild(oldStyleNode); + } + // For IE. + // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash. + // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head + if (styleNode.styleSheet) { + try { + styleNode.styleSheet.cssText = styles; + } + catch (e) { + throw new Error('Couldn\'t reassign styleSheet.cssText.'); + } + } + }, + currentScript: function (window) { + var document = window.document; + return document.currentScript || (function () { + var scripts = document.getElementsByTagName('script'); + return scripts[scripts.length - 1]; + })(); } - - if (oldStyleNode && keepOldStyleNode === false) { - oldStyleNode.parentNode.removeChild(oldStyleNode); - } // For IE. - // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash. - // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head - - - if (styleNode.styleSheet) { - try { - styleNode.styleSheet.cssText = styles; - } catch (e) { - throw new Error('Couldn\'t reassign styleSheet.cssText.'); - } - } - }, - currentScript: function currentScript(window) { - var document = window.document; - return document.currentScript || function () { - var scripts = document.getElementsByTagName('script'); - return scripts[scripts.length - 1]; - }(); - } }; var addDefaultOptions = (function (window, options) { - // use options from the current script tag data attribues - addDataAttr(options, browser.currentScript(window)); - - if (options.isFileProtocol === undefined) { - options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol); - } // Load styles asynchronously (default: false) - // - // This is set to `false` by default, so that the body - // doesn't start loading before the stylesheets are parsed. - // Setting this to `true` can result in flickering. - // - - - options.async = options.async || false; - options.fileAsync = options.fileAsync || false; // Interval between watch polls - - options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500); - options.env = options.env || (window.location.hostname == '127.0.0.1' || window.location.hostname == '0.0.0.0' || window.location.hostname == 'localhost' || window.location.port && window.location.port.length > 0 || options.isFileProtocol ? 'development' : 'production'); - var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash); - - if (dumpLineNumbers) { - options.dumpLineNumbers = dumpLineNumbers[1]; - } - - if (options.useFileCache === undefined) { - options.useFileCache = true; - } - - if (options.onReady === undefined) { - options.onReady = true; - } - - if (options.relativeUrls) { - options.rewriteUrls = 'all'; - } + // use options from the current script tag data attribues + addDataAttr(options, browser.currentScript(window)); + if (options.isFileProtocol === undefined) { + options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol); + } + // Load styles asynchronously (default: false) + // + // This is set to `false` by default, so that the body + // doesn't start loading before the stylesheets are parsed. + // Setting this to `true` can result in flickering. + // + options.async = options.async || false; + options.fileAsync = options.fileAsync || false; + // Interval between watch polls + options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500); + options.env = options.env || (window.location.hostname == '127.0.0.1' || + window.location.hostname == '0.0.0.0' || + window.location.hostname == 'localhost' || + (window.location.port && + window.location.port.length > 0) || + options.isFileProtocol ? 'development' + : 'production'); + var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash); + if (dumpLineNumbers) { + options.dumpLineNumbers = dumpLineNumbers[1]; + } + if (options.useFileCache === undefined) { + options.useFileCache = true; + } + if (options.onReady === undefined) { + options.onReady = true; + } + if (options.relativeUrls) { + options.rewriteUrls = 'all'; + } }); - function _typeof(obj) { - if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { - _typeof = function (obj) { - return typeof obj; - }; - } else { - _typeof = function (obj) { - return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }; - } - - return _typeof(obj); - } - - function _classCallCheck(instance, Constructor) { - if (!(instance instanceof Constructor)) { - throw new TypeError("Cannot call a class as a function"); - } - } - - function _defineProperties(target, props) { - for (var i = 0; i < props.length; i++) { - var descriptor = props[i]; - descriptor.enumerable = descriptor.enumerable || false; - descriptor.configurable = true; - if ("value" in descriptor) descriptor.writable = true; - Object.defineProperty(target, descriptor.key, descriptor); - } - } - - function _createClass(Constructor, protoProps, staticProps) { - if (protoProps) _defineProperties(Constructor.prototype, protoProps); - if (staticProps) _defineProperties(Constructor, staticProps); - return Constructor; - } - - function _inherits(subClass, superClass) { - if (typeof superClass !== "function" && superClass !== null) { - throw new TypeError("Super expression must either be null or a function"); - } - - subClass.prototype = Object.create(superClass && superClass.prototype, { - constructor: { - value: subClass, - writable: true, - configurable: true - } - }); - if (superClass) _setPrototypeOf(subClass, superClass); - } - - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } - - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); - } - - function isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); - return true; - } catch (e) { - return false; - } - } - - function _construct(Parent, args, Class) { - if (isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); - } - - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; - } - - function _possibleConstructorReturn(self, call) { - if (call && (typeof call === "object" || typeof call === "function")) { - return call; - } - - return _assertThisInitialized(self); - } - - function _toConsumableArray(arr) { - return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); - } - - function _arrayWithoutHoles(arr) { - if (Array.isArray(arr)) { - for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; - - return arr2; - } - } + /*! ***************************************************************************** + Copyright (c) Microsoft Corporation. All rights reserved. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use + this file except in compliance with the License. You may obtain a copy of the + License at http://www.apache.org/licenses/LICENSE-2.0 + + THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED + WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, + MERCHANTABLITY OR NON-INFRINGEMENT. + + See the Apache Version 2.0 License for specific language governing permissions + and limitations under the License. + ***************************************************************************** */ + /* global Reflect, Promise */ + + var extendStatics = function(d, b) { + extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + return extendStatics(d, b); + }; - function _iterableToArray(iter) { - if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); + function __extends(d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); } - function _nonIterableSpread() { - throw new TypeError("Invalid attempt to spread non-iterable instance"); + function __spreadArrays() { + for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length; + for (var r = Array(s), k = 0, i = 0; i < il; i++) + for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) + r[k] = a[j]; + return r; } var colors = { - 'aliceblue': '#f0f8ff', - 'antiquewhite': '#faebd7', - 'aqua': '#00ffff', - 'aquamarine': '#7fffd4', - 'azure': '#f0ffff', - 'beige': '#f5f5dc', - 'bisque': '#ffe4c4', - 'black': '#000000', - 'blanchedalmond': '#ffebcd', - 'blue': '#0000ff', - 'blueviolet': '#8a2be2', - 'brown': '#a52a2a', - 'burlywood': '#deb887', - 'cadetblue': '#5f9ea0', - 'chartreuse': '#7fff00', - 'chocolate': '#d2691e', - 'coral': '#ff7f50', - 'cornflowerblue': '#6495ed', - 'cornsilk': '#fff8dc', - 'crimson': '#dc143c', - 'cyan': '#00ffff', - 'darkblue': '#00008b', - 'darkcyan': '#008b8b', - 'darkgoldenrod': '#b8860b', - 'darkgray': '#a9a9a9', - 'darkgrey': '#a9a9a9', - 'darkgreen': '#006400', - 'darkkhaki': '#bdb76b', - 'darkmagenta': '#8b008b', - 'darkolivegreen': '#556b2f', - 'darkorange': '#ff8c00', - 'darkorchid': '#9932cc', - 'darkred': '#8b0000', - 'darksalmon': '#e9967a', - 'darkseagreen': '#8fbc8f', - 'darkslateblue': '#483d8b', - 'darkslategray': '#2f4f4f', - 'darkslategrey': '#2f4f4f', - 'darkturquoise': '#00ced1', - 'darkviolet': '#9400d3', - 'deeppink': '#ff1493', - 'deepskyblue': '#00bfff', - 'dimgray': '#696969', - 'dimgrey': '#696969', - 'dodgerblue': '#1e90ff', - 'firebrick': '#b22222', - 'floralwhite': '#fffaf0', - 'forestgreen': '#228b22', - 'fuchsia': '#ff00ff', - 'gainsboro': '#dcdcdc', - 'ghostwhite': '#f8f8ff', - 'gold': '#ffd700', - 'goldenrod': '#daa520', - 'gray': '#808080', - 'grey': '#808080', - 'green': '#008000', - 'greenyellow': '#adff2f', - 'honeydew': '#f0fff0', - 'hotpink': '#ff69b4', - 'indianred': '#cd5c5c', - 'indigo': '#4b0082', - 'ivory': '#fffff0', - 'khaki': '#f0e68c', - 'lavender': '#e6e6fa', - 'lavenderblush': '#fff0f5', - 'lawngreen': '#7cfc00', - 'lemonchiffon': '#fffacd', - 'lightblue': '#add8e6', - 'lightcoral': '#f08080', - 'lightcyan': '#e0ffff', - 'lightgoldenrodyellow': '#fafad2', - 'lightgray': '#d3d3d3', - 'lightgrey': '#d3d3d3', - 'lightgreen': '#90ee90', - 'lightpink': '#ffb6c1', - 'lightsalmon': '#ffa07a', - 'lightseagreen': '#20b2aa', - 'lightskyblue': '#87cefa', - 'lightslategray': '#778899', - 'lightslategrey': '#778899', - 'lightsteelblue': '#b0c4de', - 'lightyellow': '#ffffe0', - 'lime': '#00ff00', - 'limegreen': '#32cd32', - 'linen': '#faf0e6', - 'magenta': '#ff00ff', - 'maroon': '#800000', - 'mediumaquamarine': '#66cdaa', - 'mediumblue': '#0000cd', - 'mediumorchid': '#ba55d3', - 'mediumpurple': '#9370d8', - 'mediumseagreen': '#3cb371', - 'mediumslateblue': '#7b68ee', - 'mediumspringgreen': '#00fa9a', - 'mediumturquoise': '#48d1cc', - 'mediumvioletred': '#c71585', - 'midnightblue': '#191970', - 'mintcream': '#f5fffa', - 'mistyrose': '#ffe4e1', - 'moccasin': '#ffe4b5', - 'navajowhite': '#ffdead', - 'navy': '#000080', - 'oldlace': '#fdf5e6', - 'olive': '#808000', - 'olivedrab': '#6b8e23', - 'orange': '#ffa500', - 'orangered': '#ff4500', - 'orchid': '#da70d6', - 'palegoldenrod': '#eee8aa', - 'palegreen': '#98fb98', - 'paleturquoise': '#afeeee', - 'palevioletred': '#d87093', - 'papayawhip': '#ffefd5', - 'peachpuff': '#ffdab9', - 'peru': '#cd853f', - 'pink': '#ffc0cb', - 'plum': '#dda0dd', - 'powderblue': '#b0e0e6', - 'purple': '#800080', - 'rebeccapurple': '#663399', - 'red': '#ff0000', - 'rosybrown': '#bc8f8f', - 'royalblue': '#4169e1', - 'saddlebrown': '#8b4513', - 'salmon': '#fa8072', - 'sandybrown': '#f4a460', - 'seagreen': '#2e8b57', - 'seashell': '#fff5ee', - 'sienna': '#a0522d', - 'silver': '#c0c0c0', - 'skyblue': '#87ceeb', - 'slateblue': '#6a5acd', - 'slategray': '#708090', - 'slategrey': '#708090', - 'snow': '#fffafa', - 'springgreen': '#00ff7f', - 'steelblue': '#4682b4', - 'tan': '#d2b48c', - 'teal': '#008080', - 'thistle': '#d8bfd8', - 'tomato': '#ff6347', - 'turquoise': '#40e0d0', - 'violet': '#ee82ee', - 'wheat': '#f5deb3', - 'white': '#ffffff', - 'whitesmoke': '#f5f5f5', - 'yellow': '#ffff00', - 'yellowgreen': '#9acd32' + 'aliceblue': '#f0f8ff', + 'antiquewhite': '#faebd7', + 'aqua': '#00ffff', + 'aquamarine': '#7fffd4', + 'azure': '#f0ffff', + 'beige': '#f5f5dc', + 'bisque': '#ffe4c4', + 'black': '#000000', + 'blanchedalmond': '#ffebcd', + 'blue': '#0000ff', + 'blueviolet': '#8a2be2', + 'brown': '#a52a2a', + 'burlywood': '#deb887', + 'cadetblue': '#5f9ea0', + 'chartreuse': '#7fff00', + 'chocolate': '#d2691e', + 'coral': '#ff7f50', + 'cornflowerblue': '#6495ed', + 'cornsilk': '#fff8dc', + 'crimson': '#dc143c', + 'cyan': '#00ffff', + 'darkblue': '#00008b', + 'darkcyan': '#008b8b', + 'darkgoldenrod': '#b8860b', + 'darkgray': '#a9a9a9', + 'darkgrey': '#a9a9a9', + 'darkgreen': '#006400', + 'darkkhaki': '#bdb76b', + 'darkmagenta': '#8b008b', + 'darkolivegreen': '#556b2f', + 'darkorange': '#ff8c00', + 'darkorchid': '#9932cc', + 'darkred': '#8b0000', + 'darksalmon': '#e9967a', + 'darkseagreen': '#8fbc8f', + 'darkslateblue': '#483d8b', + 'darkslategray': '#2f4f4f', + 'darkslategrey': '#2f4f4f', + 'darkturquoise': '#00ced1', + 'darkviolet': '#9400d3', + 'deeppink': '#ff1493', + 'deepskyblue': '#00bfff', + 'dimgray': '#696969', + 'dimgrey': '#696969', + 'dodgerblue': '#1e90ff', + 'firebrick': '#b22222', + 'floralwhite': '#fffaf0', + 'forestgreen': '#228b22', + 'fuchsia': '#ff00ff', + 'gainsboro': '#dcdcdc', + 'ghostwhite': '#f8f8ff', + 'gold': '#ffd700', + 'goldenrod': '#daa520', + 'gray': '#808080', + 'grey': '#808080', + 'green': '#008000', + 'greenyellow': '#adff2f', + 'honeydew': '#f0fff0', + 'hotpink': '#ff69b4', + 'indianred': '#cd5c5c', + 'indigo': '#4b0082', + 'ivory': '#fffff0', + 'khaki': '#f0e68c', + 'lavender': '#e6e6fa', + 'lavenderblush': '#fff0f5', + 'lawngreen': '#7cfc00', + 'lemonchiffon': '#fffacd', + 'lightblue': '#add8e6', + 'lightcoral': '#f08080', + 'lightcyan': '#e0ffff', + 'lightgoldenrodyellow': '#fafad2', + 'lightgray': '#d3d3d3', + 'lightgrey': '#d3d3d3', + 'lightgreen': '#90ee90', + 'lightpink': '#ffb6c1', + 'lightsalmon': '#ffa07a', + 'lightseagreen': '#20b2aa', + 'lightskyblue': '#87cefa', + 'lightslategray': '#778899', + 'lightslategrey': '#778899', + 'lightsteelblue': '#b0c4de', + 'lightyellow': '#ffffe0', + 'lime': '#00ff00', + 'limegreen': '#32cd32', + 'linen': '#faf0e6', + 'magenta': '#ff00ff', + 'maroon': '#800000', + 'mediumaquamarine': '#66cdaa', + 'mediumblue': '#0000cd', + 'mediumorchid': '#ba55d3', + 'mediumpurple': '#9370d8', + 'mediumseagreen': '#3cb371', + 'mediumslateblue': '#7b68ee', + 'mediumspringgreen': '#00fa9a', + 'mediumturquoise': '#48d1cc', + 'mediumvioletred': '#c71585', + 'midnightblue': '#191970', + 'mintcream': '#f5fffa', + 'mistyrose': '#ffe4e1', + 'moccasin': '#ffe4b5', + 'navajowhite': '#ffdead', + 'navy': '#000080', + 'oldlace': '#fdf5e6', + 'olive': '#808000', + 'olivedrab': '#6b8e23', + 'orange': '#ffa500', + 'orangered': '#ff4500', + 'orchid': '#da70d6', + 'palegoldenrod': '#eee8aa', + 'palegreen': '#98fb98', + 'paleturquoise': '#afeeee', + 'palevioletred': '#d87093', + 'papayawhip': '#ffefd5', + 'peachpuff': '#ffdab9', + 'peru': '#cd853f', + 'pink': '#ffc0cb', + 'plum': '#dda0dd', + 'powderblue': '#b0e0e6', + 'purple': '#800080', + 'rebeccapurple': '#663399', + 'red': '#ff0000', + 'rosybrown': '#bc8f8f', + 'royalblue': '#4169e1', + 'saddlebrown': '#8b4513', + 'salmon': '#fa8072', + 'sandybrown': '#f4a460', + 'seagreen': '#2e8b57', + 'seashell': '#fff5ee', + 'sienna': '#a0522d', + 'silver': '#c0c0c0', + 'skyblue': '#87ceeb', + 'slateblue': '#6a5acd', + 'slategray': '#708090', + 'slategrey': '#708090', + 'snow': '#fffafa', + 'springgreen': '#00ff7f', + 'steelblue': '#4682b4', + 'tan': '#d2b48c', + 'teal': '#008080', + 'thistle': '#d8bfd8', + 'tomato': '#ff6347', + 'turquoise': '#40e0d0', + 'violet': '#ee82ee', + 'wheat': '#f5deb3', + 'white': '#ffffff', + 'whitesmoke': '#f5f5f5', + 'yellow': '#ffff00', + 'yellowgreen': '#9acd32' }; var unitConversions = { - length: { - 'm': 1, - 'cm': 0.01, - 'mm': 0.001, - 'in': 0.0254, - 'px': 0.0254 / 96, - 'pt': 0.0254 / 72, - 'pc': 0.0254 / 72 * 12 - }, - duration: { - 's': 1, - 'ms': 0.001 - }, - angle: { - 'rad': 1 / (2 * Math.PI), - 'deg': 1 / 360, - 'grad': 1 / 400, - 'turn': 1 - } - }; - - var data = { - colors: colors, - unitConversions: unitConversions + length: { + 'm': 1, + 'cm': 0.01, + 'mm': 0.001, + 'in': 0.0254, + 'px': 0.0254 / 96, + 'pt': 0.0254 / 72, + 'pc': 0.0254 / 72 * 12 + }, + duration: { + 's': 1, + 'ms': 0.001 + }, + angle: { + 'rad': 1 / (2 * Math.PI), + 'deg': 1 / 360, + 'grad': 1 / 400, + 'turn': 1 + } }; - var Node = - /*#__PURE__*/ - function () { - function Node() { - _classCallCheck(this, Node); - - this.parent = null; - this.visibilityBlocks = undefined; - this.nodeVisible = undefined; - this.rootNode = null; - this.parsed = null; - var self = this; - Object.defineProperty(this, 'currentFileInfo', { - get: function get() { - return self.fileInfo(); - } - }); - Object.defineProperty(this, 'index', { - get: function get() { - return self.getIndex(); - } - }); - } - - _createClass(Node, [{ - key: "setParent", - value: function setParent(nodes, parent) { - function set(node) { - if (node && node instanceof Node) { - node.parent = parent; - } - } - - if (Array.isArray(nodes)) { - nodes.forEach(set); - } else { - set(nodes); - } - } - }, { - key: "getIndex", - value: function getIndex() { - return this._index || this.parent && this.parent.getIndex() || 0; - } - }, { - key: "fileInfo", - value: function fileInfo() { - return this._fileInfo || this.parent && this.parent.fileInfo() || {}; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return false; - } - }, { - key: "toCSS", - value: function toCSS(context) { - var strs = []; - this.genCSS(context, { - add: function add(chunk, fileInfo, index) { - strs.push(chunk); - }, - isEmpty: function isEmpty() { - return strs.length === 0; - } - }); - return strs.join(''); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.value); - } - }, { - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval() { - return this; - } - }, { - key: "_operate", - value: function _operate(context, op, a, b) { - switch (op) { - case '+': - return a + b; - - case '-': - return a - b; - - case '*': - return a * b; - - case '/': - return a / b; - } - } - }, { - key: "fround", - value: function fround(context, value) { - var precision = context && context.numPrecision; // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: - - return precision ? Number((value + 2e-16).toFixed(precision)) : value; - } // Returns true if this node represents root of ast imported by reference + var data = { colors: colors, unitConversions: unitConversions }; - }, { - key: "blocksVisibility", - value: function blocksVisibility() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - return this.visibilityBlocks !== 0; - } - }, { - key: "addVisibilityBlock", - value: function addVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - this.visibilityBlocks = this.visibilityBlocks + 1; - } - }, { - key: "removeVisibilityBlock", - value: function removeVisibilityBlock() { - if (this.visibilityBlocks == null) { - this.visibilityBlocks = 0; - } - - this.visibilityBlocks = this.visibilityBlocks - 1; - } // Turns on node visibility - if called node will be shown in output regardless + var Node = /** @class */ (function () { + function Node() { + this.parent = null; + this.visibilityBlocks = undefined; + this.nodeVisible = undefined; + this.rootNode = null; + this.parsed = null; + var self = this; + Object.defineProperty(this, 'currentFileInfo', { + get: function () { return self.fileInfo(); } + }); + Object.defineProperty(this, 'index', { + get: function () { return self.getIndex(); } + }); + } + Node.prototype.setParent = function (nodes, parent) { + function set(node) { + if (node && node instanceof Node) { + node.parent = parent; + } + } + if (Array.isArray(nodes)) { + nodes.forEach(set); + } + else { + set(nodes); + } + }; + Node.prototype.getIndex = function () { + return this._index || (this.parent && this.parent.getIndex()) || 0; + }; + Node.prototype.fileInfo = function () { + return this._fileInfo || (this.parent && this.parent.fileInfo()) || {}; + }; + Node.prototype.isRulesetLike = function () { + return false; + }; + Node.prototype.toCSS = function (context) { + var strs = []; + this.genCSS(context, { + add: function (chunk, fileInfo, index) { + strs.push(chunk); + }, + isEmpty: function () { + return strs.length === 0; + } + }); + return strs.join(''); + }; + Node.prototype.genCSS = function (context, output) { + output.add(this.value); + }; + Node.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Node.prototype.eval = function () { return this; }; + Node.prototype._operate = function (context, op, a, b) { + switch (op) { + case '+': return a + b; + case '-': return a - b; + case '*': return a * b; + case '/': return a / b; + } + }; + Node.prototype.fround = function (context, value) { + var precision = context && context.numPrecision; + // add "epsilon" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded: + return (precision) ? Number((value + 2e-16).toFixed(precision)) : value; + }; + // Returns true if this node represents root of ast imported by reference + Node.prototype.blocksVisibility = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + return this.visibilityBlocks !== 0; + }; + Node.prototype.addVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks + 1; + }; + Node.prototype.removeVisibilityBlock = function () { + if (this.visibilityBlocks == null) { + this.visibilityBlocks = 0; + } + this.visibilityBlocks = this.visibilityBlocks - 1; + }; + // Turns on node visibility - if called node will be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureVisibility", - value: function ensureVisibility() { - this.nodeVisible = true; - } // Turns off node visibility - if called node will NOT be shown in output regardless + Node.prototype.ensureVisibility = function () { + this.nodeVisible = true; + }; + // Turns off node visibility - if called node will NOT be shown in output regardless // of whether it comes from import by reference or not - - }, { - key: "ensureInvisibility", - value: function ensureInvisibility() { - this.nodeVisible = false; - } // return values: + Node.prototype.ensureInvisibility = function () { + this.nodeVisible = false; + }; + // return values: // false - the node must not be visible // true - the node must be visible // undefined or null - the node has the same visibility as its parent - - }, { - key: "isVisible", - value: function isVisible() { - return this.nodeVisible; - } - }, { - key: "visibilityInfo", - value: function visibilityInfo() { - return { - visibilityBlocks: this.visibilityBlocks, - nodeVisible: this.nodeVisible - }; - } - }, { - key: "copyVisibilityInfo", - value: function copyVisibilityInfo(info) { - if (!info) { - return; - } - - this.visibilityBlocks = info.visibilityBlocks; - this.nodeVisible = info.nodeVisible; - } - }]); - - return Node; - }(); - + Node.prototype.isVisible = function () { + return this.nodeVisible; + }; + Node.prototype.visibilityInfo = function () { + return { + visibilityBlocks: this.visibilityBlocks, + nodeVisible: this.nodeVisible + }; + }; + Node.prototype.copyVisibilityInfo = function (info) { + if (!info) { + return; + } + this.visibilityBlocks = info.visibilityBlocks; + this.nodeVisible = info.nodeVisible; + }; + return Node; + }()); Node.compare = function (a, b) { - /* returns: - -1: a < b - 0: a = b - 1: a > b - and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ - if (a.compare && // for "symmetric results" force toCSS-based comparison - // of Quoted or Anonymous if either value is one of those - !(b.type === 'Quoted' || b.type === 'Anonymous')) { - return a.compare(b); - } else if (b.compare) { - return -b.compare(a); - } else if (a.type !== b.type) { - return undefined; - } - - a = a.value; - b = b.value; - - if (!Array.isArray(a)) { - return a === b ? 0 : undefined; - } - - if (a.length !== b.length) { - return undefined; - } - - for (var i = 0; i < a.length; i++) { - if (Node.compare(a[i], b[i]) !== 0) { - return undefined; + /* returns: + -1: a < b + 0: a = b + 1: a > b + and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */ + if ((a.compare) && + // for "symmetric results" force toCSS-based comparison + // of Quoted or Anonymous if either value is one of those + !(b.type === 'Quoted' || b.type === 'Anonymous')) { + return a.compare(b); + } + else if (b.compare) { + return -b.compare(a); + } + else if (a.type !== b.type) { + return undefined; } - } - - return 0; - }; - - Node.numericCompare = function (a, b) { - return a < b ? -1 : a === b ? 0 : a > b ? 1 : undefined; + a = a.value; + b = b.value; + if (!Array.isArray(a)) { + return a === b ? 0 : undefined; + } + if (a.length !== b.length) { + return undefined; + } + for (var i_1 = 0; i_1 < a.length; i_1++) { + if (Node.compare(a[i_1], b[i_1]) !== 0) { + return undefined; + } + } + return 0; }; + Node.numericCompare = function (a, b) { return a < b ? -1 + : a === b ? 0 + : a > b ? 1 : undefined; }; + // // RGB Colors - #ff0014, #eee // - - var Color = - /*#__PURE__*/ - function (_Node) { - _inherits(Color, _Node); - - function Color(rgb, a, originalForm) { - var _this; - - _classCallCheck(this, Color); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Color).call(this)); - - var self = _assertThisInitialized(_this); // - // The end goal here, is to parse the arguments - // into an integer triplet, such as `128, 255, 0` - // - // This facilitates operations and conversions. - // - - - if (Array.isArray(rgb)) { - _this.rgb = rgb; - } else if (rgb.length >= 6) { - _this.rgb = []; - rgb.match(/.{2}/g).map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c, 16)); - } else { - self.alpha = parseInt(c, 16) / 255; - } - }); - } else { - _this.rgb = []; - rgb.split('').map(function (c, i) { - if (i < 3) { - self.rgb.push(parseInt(c + c, 16)); - } else { - self.alpha = parseInt(c + c, 16) / 255; - } - }); - } - - _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); - - if (typeof originalForm !== 'undefined') { - _this.value = originalForm; + var Color = /** @class */ (function (_super) { + __extends(Color, _super); + function Color(rgb, a, originalForm) { + var _this = _super.call(this) || this; + var self = _this; + // + // The end goal here, is to parse the arguments + // into an integer triplet, such as `128, 255, 0` + // + // This facilitates operations and conversions. + // + if (Array.isArray(rgb)) { + _this.rgb = rgb; + } + else if (rgb.length >= 6) { + _this.rgb = []; + rgb.match(/.{2}/g).map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c, 16)); + } + else { + self.alpha = (parseInt(c, 16)) / 255; + } + }); + } + else { + _this.rgb = []; + rgb.split('').map(function (c, i) { + if (i < 3) { + self.rgb.push(parseInt(c + c, 16)); + } + else { + self.alpha = (parseInt(c + c, 16)) / 255; + } + }); + } + _this.alpha = _this.alpha || (typeof a === 'number' ? a : 1); + if (typeof originalForm !== 'undefined') { + _this.value = originalForm; + } + return _this; } - - return _this; - } - - _createClass(Color, [{ - key: "luma", - value: function luma() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - r = r <= 0.03928 ? r / 12.92 : Math.pow((r + 0.055) / 1.055, 2.4); - g = g <= 0.03928 ? g / 12.92 : Math.pow((g + 0.055) / 1.055, 2.4); - b = b <= 0.03928 ? b / 12.92 : Math.pow((b + 0.055) / 1.055, 2.4); - return 0.2126 * r + 0.7152 * g + 0.0722 * b; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context, doNotCompress) { - var compress = context && context.compress && !doNotCompress; - var color; - var alpha; - var colorFunction; - var args = []; // `value` is set if this color was originally - // converted from a named color string so we need - // to respect this and try to output named color too. - - alpha = this.fround(context, this.alpha); - - if (this.value) { - if (this.value.indexOf('rgb') === 0) { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } else if (this.value.indexOf('hsl') === 0) { - if (alpha < 1) { - colorFunction = 'hsla'; - } else { - colorFunction = 'hsl'; - } - } else { - return this.value; - } - } else { - if (alpha < 1) { - colorFunction = 'rgba'; - } - } - - switch (colorFunction) { - case 'rgba': - args = this.rgb.map(function (c) { - return clamp(Math.round(c), 255); - }).concat(clamp(alpha, 1)); - break; - - case 'hsla': - args.push(clamp(alpha, 1)); - - case 'hsl': - color = this.toHSL(); - args = [this.fround(context, color.h), "".concat(this.fround(context, color.s * 100), "%"), "".concat(this.fround(context, color.l * 100), "%")].concat(args); - } - - if (colorFunction) { - // Values are capped between `0` and `255`, rounded and zero-padded. - return "".concat(colorFunction, "(").concat(args.join(",".concat(compress ? '' : ' ')), ")"); - } - - color = this.toRGB(); - - if (compress) { - var splitcolor = color.split(''); // Convert color to short format - - if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { - color = "#".concat(splitcolor[1]).concat(splitcolor[3]).concat(splitcolor[5]); + Color.prototype.luma = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4); + g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4); + b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4); + return 0.2126 * r + 0.7152 * g + 0.0722 * b; + }; + Color.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Color.prototype.toCSS = function (context, doNotCompress) { + var compress = context && context.compress && !doNotCompress; + var color; + var alpha; + var colorFunction; + var args = []; + // `value` is set if this color was originally + // converted from a named color string so we need + // to respect this and try to output named color too. + alpha = this.fround(context, this.alpha); + if (this.value) { + if (this.value.indexOf('rgb') === 0) { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + else if (this.value.indexOf('hsl') === 0) { + if (alpha < 1) { + colorFunction = 'hsla'; + } + else { + colorFunction = 'hsl'; + } + } + else { + return this.value; + } } - } - - return color; - } // + else { + if (alpha < 1) { + colorFunction = 'rgba'; + } + } + switch (colorFunction) { + case 'rgba': + args = this.rgb.map(function (c) { return clamp(Math.round(c), 255); }).concat(clamp(alpha, 1)); + break; + case 'hsla': + args.push(clamp(alpha, 1)); + case 'hsl': + color = this.toHSL(); + args = [ + this.fround(context, color.h), + this.fround(context, color.s * 100) + "%", + this.fround(context, color.l * 100) + "%" + ].concat(args); + } + if (colorFunction) { + // Values are capped between `0` and `255`, rounded and zero-padded. + return colorFunction + "(" + args.join("," + (compress ? '' : ' ')) + ")"; + } + color = this.toRGB(); + if (compress) { + var splitcolor = color.split(''); + // Convert color to short format + if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) { + color = "#" + splitcolor[1] + splitcolor[3] + splitcolor[5]; + } + } + return color; + }; + // // Operations have to be done per-channel, if not, // channels will spill onto each other. Once we have // our result, in the form of an integer triplet, // we create a new Color node to hold the result. // - - }, { - key: "operate", - value: function operate(context, op, other) { - var rgb = new Array(3); - var alpha = this.alpha * (1 - other.alpha) + other.alpha; - - for (var c = 0; c < 3; c++) { - rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); - } - - return new Color(rgb, alpha); - } - }, { - key: "toRGB", - value: function toRGB() { - return toHex(this.rgb); - } - }, { - key: "toHSL", - value: function toHSL() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var l = (max + min) / 2; - var d = max - min; - - if (max === min) { - h = s = 0; - } else { - s = l > 0.5 ? d / (2 - max - min) : d / (max + min); - - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + Color.prototype.operate = function (context, op, other) { + var rgb = new Array(3); + var alpha = this.alpha * (1 - other.alpha) + other.alpha; + for (var c = 0; c < 3; c++) { + rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]); } - - h /= 6; - } - - return { - h: h * 360, - s: s, - l: l, - a: a - }; - } // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript - - }, { - key: "toHSV", - value: function toHSV() { - var r = this.rgb[0] / 255; - var g = this.rgb[1] / 255; - var b = this.rgb[2] / 255; - var a = this.alpha; - var max = Math.max(r, g, b); - var min = Math.min(r, g, b); - var h; - var s; - var v = max; - var d = max - min; - - if (max === 0) { - s = 0; - } else { - s = d / max; - } - - if (max === min) { - h = 0; - } else { - switch (max) { - case r: - h = (g - b) / d + (g < b ? 6 : 0); - break; - - case g: - h = (b - r) / d + 2; - break; - - case b: - h = (r - g) / d + 4; - break; + return new Color(rgb, alpha); + }; + Color.prototype.toRGB = function () { + return toHex(this.rgb); + }; + Color.prototype.toHSL = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var l = (max + min) / 2; + var d = max - min; + if (max === min) { + h = s = 0; + } + else { + s = l > 0.5 ? d / (2 - max - min) : d / (max + min); + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; } - - h /= 6; - } - - return { - h: h * 360, - s: s, - v: v, - a: a - }; - } - }, { - key: "toARGB", - value: function toARGB() { - return toHex([this.alpha * 255].concat(this.rgb)); - } - }, { - key: "compare", - value: function compare(x) { - return x.rgb && x.rgb[0] === this.rgb[0] && x.rgb[1] === this.rgb[1] && x.rgb[2] === this.rgb[2] && x.alpha === this.alpha ? 0 : undefined; - } - }]); - - return Color; - }(Node); - + return { h: h * 360, s: s, l: l, a: a }; + }; + // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript + Color.prototype.toHSV = function () { + var r = this.rgb[0] / 255; + var g = this.rgb[1] / 255; + var b = this.rgb[2] / 255; + var a = this.alpha; + var max = Math.max(r, g, b); + var min = Math.min(r, g, b); + var h; + var s; + var v = max; + var d = max - min; + if (max === 0) { + s = 0; + } + else { + s = d / max; + } + if (max === min) { + h = 0; + } + else { + switch (max) { + case r: + h = (g - b) / d + (g < b ? 6 : 0); + break; + case g: + h = (b - r) / d + 2; + break; + case b: + h = (r - g) / d + 4; + break; + } + h /= 6; + } + return { h: h * 360, s: s, v: v, a: a }; + }; + Color.prototype.toARGB = function () { + return toHex([this.alpha * 255].concat(this.rgb)); + }; + Color.prototype.compare = function (x) { + return (x.rgb && + x.rgb[0] === this.rgb[0] && + x.rgb[1] === this.rgb[1] && + x.rgb[2] === this.rgb[2] && + x.alpha === this.alpha) ? 0 : undefined; + }; + return Color; + }(Node)); Color.prototype.type = 'Color'; - function clamp(v, max) { - return Math.min(Math.max(v, 0), max); + return Math.min(Math.max(v, 0), max); } - function toHex(v) { - return "#".concat(v.map(function (c) { - c = clamp(Math.round(c), 255); - return (c < 16 ? '0' : '') + c.toString(16); - }).join('')); + return "#" + v.map(function (c) { + c = clamp(Math.round(c), 255); + return (c < 16 ? '0' : '') + c.toString(16); + }).join(''); } - Color.fromKeyword = function (keyword) { - var c; - var key = keyword.toLowerCase(); - - if (colors.hasOwnProperty(key)) { - c = new Color(colors[key].slice(1)); - } else if (key === 'transparent') { - c = new Color([0, 0, 0], 0); - } - - if (c) { - c.value = keyword; - return c; - } + var c; + var key = keyword.toLowerCase(); + if (colors.hasOwnProperty(key)) { + c = new Color(colors[key].slice(1)); + } + else if (key === 'transparent') { + c = new Color([0, 0, 0], 0); + } + if (c) { + c.value = keyword; + return c; + } }; - var Paren = - /*#__PURE__*/ - function (_Node) { - _inherits(Paren, _Node); - - function Paren(node) { - var _this; - - _classCallCheck(this, Paren); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Paren).call(this)); - _this.value = node; - return _this; - } - - _createClass(Paren, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - return new Paren(this.value.eval(context)); - } - }]); - - return Paren; - }(Node); - + var Paren = /** @class */ (function (_super) { + __extends(Paren, _super); + function Paren(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; + } + Paren.prototype.genCSS = function (context, output) { + output.add('('); + this.value.genCSS(context, output); + output.add(')'); + }; + Paren.prototype.eval = function (context) { + return new Paren(this.value.eval(context)); + }; + return Paren; + }(Node)); Paren.prototype.type = 'Paren'; var _noSpaceCombinators = { - '': true, - ' ': true, - '|': true + '': true, + ' ': true, + '|': true }; - - var Combinator = - /*#__PURE__*/ - function (_Node) { - _inherits(Combinator, _Node); - - function Combinator(value) { - var _this; - - _classCallCheck(this, Combinator); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Combinator).call(this)); - - if (value === ' ') { - _this.value = ' '; - _this.emptyOrWhitespace = true; - } else { - _this.value = value ? value.trim() : ''; - _this.emptyOrWhitespace = _this.value === ''; - } - - return _this; - } - - _createClass(Combinator, [{ - key: "genCSS", - value: function genCSS(context, output) { - var spaceOrEmpty = context.compress || _noSpaceCombinators[this.value] ? '' : ' '; - output.add(spaceOrEmpty + this.value + spaceOrEmpty); - } - }]); - - return Combinator; - }(Node); - + var Combinator = /** @class */ (function (_super) { + __extends(Combinator, _super); + function Combinator(value) { + var _this = _super.call(this) || this; + if (value === ' ') { + _this.value = ' '; + _this.emptyOrWhitespace = true; + } + else { + _this.value = value ? value.trim() : ''; + _this.emptyOrWhitespace = _this.value === ''; + } + return _this; + } + Combinator.prototype.genCSS = function (context, output) { + var spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' '; + output.add(spaceOrEmpty + this.value + spaceOrEmpty); + }; + return Combinator; + }(Node)); Combinator.prototype.type = 'Combinator'; - var Element = - /*#__PURE__*/ - function (_Node) { - _inherits(Element, _Node); - - function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Element); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Element).call(this)); - _this.combinator = combinator instanceof Combinator ? combinator : new Combinator(combinator); - - if (typeof value === 'string') { - _this.value = value.trim(); - } else if (value) { - _this.value = value; - } else { - _this.value = ''; - } - - _this.isVariable = isVariable; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.combinator, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Element, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - this.combinator = visitor.visit(this.combinator); - - if (_typeof(value) === 'object') { - this.value = visitor.visit(value); - } - } - }, { - key: "eval", - value: function _eval(context) { - return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone() { - return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); - } - }, { - key: "toCSS", - value: function toCSS() { - var context = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var value = this.value; - var firstSelector = context.firstSelector; - - if (value instanceof Paren) { - // selector in parens should not be affected by outer selector - // flags (breaks only interpolated selectors - see #1973) - context.firstSelector = true; - } - - value = value.toCSS ? value.toCSS(context) : value; - context.firstSelector = firstSelector; - - if (value === '' && this.combinator.value.charAt(0) === '&') { - return ''; - } else { - return this.combinator.toCSS(context) + value; - } - } - }]); - - return Element; - }(Node); - + var Element = /** @class */ (function (_super) { + __extends(Element, _super); + function Element(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.combinator = combinator instanceof Combinator ? + combinator : new Combinator(combinator); + if (typeof value === 'string') { + _this.value = value.trim(); + } + else if (value) { + _this.value = value; + } + else { + _this.value = ''; + } + _this.isVariable = isVariable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.combinator, _this); + return _this; + } + Element.prototype.accept = function (visitor) { + var value = this.value; + this.combinator = visitor.visit(this.combinator); + if (typeof value === 'object') { + this.value = visitor.visit(value); + } + }; + Element.prototype.eval = function (context) { + return new Element(this.combinator, this.value.eval ? this.value.eval(context) : this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.clone = function () { + return new Element(this.combinator, this.value, this.isVariable, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Element.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context), this.fileInfo(), this.getIndex()); + }; + Element.prototype.toCSS = function (context) { + if (context === void 0) { context = {}; } + var value = this.value; + var firstSelector = context.firstSelector; + if (value instanceof Paren) { + // selector in parens should not be affected by outer selector + // flags (breaks only interpolated selectors - see #1973) + context.firstSelector = true; + } + value = value.toCSS ? value.toCSS(context) : value; + context.firstSelector = firstSelector; + if (value === '' && this.combinator.value.charAt(0) === '&') { + return ''; + } + else { + return this.combinator.toCSS(context) + value; + } + }; + return Element; + }(Node)); Element.prototype.type = 'Element'; var Math$1 = { - ALWAYS: 0, - PARENS_DIVISION: 1, - PARENS: 2, - STRICT_LEGACY: 3 + ALWAYS: 0, + PARENS_DIVISION: 1, + PARENS: 2, + STRICT_LEGACY: 3 }; var RewriteUrls = { - OFF: 0, - LOCAL: 1, - ALL: 2 + OFF: 0, + LOCAL: 1, + ALL: 2 }; function createCommonjsModule(fn, module) { @@ -1211,402 +921,363 @@ } var clone_1 = createCommonjsModule(function (module) { - var clone = (function() { - - function _instanceof(obj, type) { - return type != null && obj instanceof type; - } - - var nativeMap; - try { - nativeMap = Map; - } catch(_) { - // maybe a reference error because no `Map`. Give it a dummy value that no - // value will ever be an instanceof. - nativeMap = function() {}; - } - - var nativeSet; - try { - nativeSet = Set; - } catch(_) { - nativeSet = function() {}; - } - - var nativePromise; - try { - nativePromise = Promise; - } catch(_) { - nativePromise = function() {}; - } - - /** - * Clones (copies) an Object using deep copying. - * - * This function supports circular references by default, but if you are certain - * there are no circular references in your object, you can save some CPU time - * by calling clone(obj, false). - * - * Caution: if `circular` is false and `parent` contains circular references, - * your program may enter an infinite loop and crash. - * - * @param `parent` - the object to be cloned - * @param `circular` - set to true if the object to be cloned may contain - * circular references. (optional - true by default) - * @param `depth` - set to a number if the object is only to be cloned to - * a particular depth. (optional - defaults to Infinity) - * @param `prototype` - sets the prototype to be used when cloning an object. - * (optional - defaults to parent prototype). - * @param `includeNonEnumerable` - set to true if the non-enumerable properties - * should be cloned as well. Non-enumerable properties on the prototype - * chain will be ignored. (optional - false by default) - */ - function clone(parent, circular, depth, prototype, includeNonEnumerable) { - if (typeof circular === 'object') { - depth = circular.depth; - prototype = circular.prototype; - includeNonEnumerable = circular.includeNonEnumerable; - circular = circular.circular; - } - // maintain two arrays for circular references, where corresponding parents - // and children have the same index - var allParents = []; - var allChildren = []; - - var useBuffer = typeof Buffer != 'undefined'; - - if (typeof circular == 'undefined') - circular = true; - - if (typeof depth == 'undefined') - depth = Infinity; - - // recurse this function so we don't reset allParents and allChildren - function _clone(parent, depth) { - // cloning null always returns null - if (parent === null) - return null; - - if (depth === 0) - return parent; - - var child; - var proto; - if (typeof parent != 'object') { - return parent; - } - - if (_instanceof(parent, nativeMap)) { - child = new nativeMap(); - } else if (_instanceof(parent, nativeSet)) { - child = new nativeSet(); - } else if (_instanceof(parent, nativePromise)) { - child = new nativePromise(function (resolve, reject) { - parent.then(function(value) { - resolve(_clone(value, depth - 1)); - }, function(err) { - reject(_clone(err, depth - 1)); - }); - }); - } else if (clone.__isArray(parent)) { - child = []; - } else if (clone.__isRegExp(parent)) { - child = new RegExp(parent.source, __getRegExpFlags(parent)); - if (parent.lastIndex) child.lastIndex = parent.lastIndex; - } else if (clone.__isDate(parent)) { - child = new Date(parent.getTime()); - } else if (useBuffer && Buffer.isBuffer(parent)) { - if (Buffer.allocUnsafe) { - // Node.js >= 4.5.0 - child = Buffer.allocUnsafe(parent.length); - } else { - // Older Node.js versions - child = new Buffer(parent.length); - } - parent.copy(child); - return child; - } else if (_instanceof(parent, Error)) { - child = Object.create(parent); - } else { - if (typeof prototype == 'undefined') { - proto = Object.getPrototypeOf(parent); - child = Object.create(proto); - } - else { - child = Object.create(prototype); - proto = prototype; - } - } - - if (circular) { - var index = allParents.indexOf(parent); - - if (index != -1) { - return allChildren[index]; - } - allParents.push(parent); - allChildren.push(child); - } - - if (_instanceof(parent, nativeMap)) { - parent.forEach(function(value, key) { - var keyChild = _clone(key, depth - 1); - var valueChild = _clone(value, depth - 1); - child.set(keyChild, valueChild); - }); - } - if (_instanceof(parent, nativeSet)) { - parent.forEach(function(value) { - var entryChild = _clone(value, depth - 1); - child.add(entryChild); - }); - } - - for (var i in parent) { - var attrs; - if (proto) { - attrs = Object.getOwnPropertyDescriptor(proto, i); - } - - if (attrs && attrs.set == null) { - continue; - } - child[i] = _clone(parent[i], depth - 1); - } - - if (Object.getOwnPropertySymbols) { - var symbols = Object.getOwnPropertySymbols(parent); - for (var i = 0; i < symbols.length; i++) { - // Don't need to worry about cloning a symbol because it is a primitive, - // like a number or string. - var symbol = symbols[i]; - var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); - if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { - continue; - } - child[symbol] = _clone(parent[symbol], depth - 1); - if (!descriptor.enumerable) { - Object.defineProperty(child, symbol, { - enumerable: false - }); - } - } - } - - if (includeNonEnumerable) { - var allPropertyNames = Object.getOwnPropertyNames(parent); - for (var i = 0; i < allPropertyNames.length; i++) { - var propertyName = allPropertyNames[i]; - var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); - if (descriptor && descriptor.enumerable) { - continue; - } - child[propertyName] = _clone(parent[propertyName], depth - 1); - Object.defineProperty(child, propertyName, { - enumerable: false - }); - } + var clone = (function () { + function _instanceof(obj, type) { + return type != null && obj instanceof type; + } + var nativeMap; + try { + nativeMap = Map; + } + catch (_) { + // maybe a reference error because no `Map`. Give it a dummy value that no + // value will ever be an instanceof. + nativeMap = function () { }; + } + var nativeSet; + try { + nativeSet = Set; + } + catch (_) { + nativeSet = function () { }; + } + var nativePromise; + try { + nativePromise = Promise; + } + catch (_) { + nativePromise = function () { }; + } + /** + * Clones (copies) an Object using deep copying. + * + * This function supports circular references by default, but if you are certain + * there are no circular references in your object, you can save some CPU time + * by calling clone(obj, false). + * + * Caution: if `circular` is false and `parent` contains circular references, + * your program may enter an infinite loop and crash. + * + * @param `parent` - the object to be cloned + * @param `circular` - set to true if the object to be cloned may contain + * circular references. (optional - true by default) + * @param `depth` - set to a number if the object is only to be cloned to + * a particular depth. (optional - defaults to Infinity) + * @param `prototype` - sets the prototype to be used when cloning an object. + * (optional - defaults to parent prototype). + * @param `includeNonEnumerable` - set to true if the non-enumerable properties + * should be cloned as well. Non-enumerable properties on the prototype + * chain will be ignored. (optional - false by default) + */ + function clone(parent, circular, depth, prototype, includeNonEnumerable) { + if (typeof circular === 'object') { + depth = circular.depth; + prototype = circular.prototype; + includeNonEnumerable = circular.includeNonEnumerable; + circular = circular.circular; + } + // maintain two arrays for circular references, where corresponding parents + // and children have the same index + var allParents = []; + var allChildren = []; + var useBuffer = typeof Buffer != 'undefined'; + if (typeof circular == 'undefined') + circular = true; + if (typeof depth == 'undefined') + depth = Infinity; + // recurse this function so we don't reset allParents and allChildren + function _clone(parent, depth) { + // cloning null always returns null + if (parent === null) + return null; + if (depth === 0) + return parent; + var child; + var proto; + if (typeof parent != 'object') { + return parent; + } + if (_instanceof(parent, nativeMap)) { + child = new nativeMap(); + } + else if (_instanceof(parent, nativeSet)) { + child = new nativeSet(); + } + else if (_instanceof(parent, nativePromise)) { + child = new nativePromise(function (resolve, reject) { + parent.then(function (value) { + resolve(_clone(value, depth - 1)); + }, function (err) { + reject(_clone(err, depth - 1)); + }); + }); + } + else if (clone.__isArray(parent)) { + child = []; + } + else if (clone.__isRegExp(parent)) { + child = new RegExp(parent.source, __getRegExpFlags(parent)); + if (parent.lastIndex) + child.lastIndex = parent.lastIndex; + } + else if (clone.__isDate(parent)) { + child = new Date(parent.getTime()); + } + else if (useBuffer && Buffer.isBuffer(parent)) { + if (Buffer.allocUnsafe) { + // Node.js >= 4.5.0 + child = Buffer.allocUnsafe(parent.length); + } + else { + // Older Node.js versions + child = new Buffer(parent.length); + } + parent.copy(child); + return child; + } + else if (_instanceof(parent, Error)) { + child = Object.create(parent); + } + else { + if (typeof prototype == 'undefined') { + proto = Object.getPrototypeOf(parent); + child = Object.create(proto); + } + else { + child = Object.create(prototype); + proto = prototype; + } + } + if (circular) { + var index = allParents.indexOf(parent); + if (index != -1) { + return allChildren[index]; + } + allParents.push(parent); + allChildren.push(child); + } + if (_instanceof(parent, nativeMap)) { + parent.forEach(function (value, key) { + var keyChild = _clone(key, depth - 1); + var valueChild = _clone(value, depth - 1); + child.set(keyChild, valueChild); + }); + } + if (_instanceof(parent, nativeSet)) { + parent.forEach(function (value) { + var entryChild = _clone(value, depth - 1); + child.add(entryChild); + }); + } + for (var i in parent) { + var attrs; + if (proto) { + attrs = Object.getOwnPropertyDescriptor(proto, i); + } + if (attrs && attrs.set == null) { + continue; + } + child[i] = _clone(parent[i], depth - 1); + } + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(parent); + for (var i = 0; i < symbols.length; i++) { + // Don't need to worry about cloning a symbol because it is a primitive, + // like a number or string. + var symbol = symbols[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, symbol); + if (descriptor && !descriptor.enumerable && !includeNonEnumerable) { + continue; + } + child[symbol] = _clone(parent[symbol], depth - 1); + if (!descriptor.enumerable) { + Object.defineProperty(child, symbol, { + enumerable: false + }); + } + } + } + if (includeNonEnumerable) { + var allPropertyNames = Object.getOwnPropertyNames(parent); + for (var i = 0; i < allPropertyNames.length; i++) { + var propertyName = allPropertyNames[i]; + var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName); + if (descriptor && descriptor.enumerable) { + continue; + } + child[propertyName] = _clone(parent[propertyName], depth - 1); + Object.defineProperty(child, propertyName, { + enumerable: false + }); + } + } + return child; + } + return _clone(parent, depth); + } + /** + * Simple flat clone using prototype, accepts only objects, usefull for property + * override on FLAT configuration object (no nested props). + * + * USE WITH CAUTION! This may not behave as you wish if you do not know how this + * works. + */ + clone.clonePrototype = function clonePrototype(parent) { + if (parent === null) + return null; + var c = function () { }; + c.prototype = parent; + return new c(); + }; + // private utility functions + function __objToStr(o) { + return Object.prototype.toString.call(o); + } + clone.__objToStr = __objToStr; + function __isDate(o) { + return typeof o === 'object' && __objToStr(o) === '[object Date]'; + } + clone.__isDate = __isDate; + function __isArray(o) { + return typeof o === 'object' && __objToStr(o) === '[object Array]'; + } + clone.__isArray = __isArray; + function __isRegExp(o) { + return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; + } + clone.__isRegExp = __isRegExp; + function __getRegExpFlags(re) { + var flags = ''; + if (re.global) + flags += 'g'; + if (re.ignoreCase) + flags += 'i'; + if (re.multiline) + flags += 'm'; + return flags; + } + clone.__getRegExpFlags = __getRegExpFlags; + return clone; + })(); + if ( module.exports) { + module.exports = clone; } - - return child; - } - - return _clone(parent, depth); - } - - /** - * Simple flat clone using prototype, accepts only objects, usefull for property - * override on FLAT configuration object (no nested props). - * - * USE WITH CAUTION! This may not behave as you wish if you do not know how this - * works. - */ - clone.clonePrototype = function clonePrototype(parent) { - if (parent === null) - return null; - - var c = function () {}; - c.prototype = parent; - return new c(); - }; - - // private utility functions - - function __objToStr(o) { - return Object.prototype.toString.call(o); - } - clone.__objToStr = __objToStr; - - function __isDate(o) { - return typeof o === 'object' && __objToStr(o) === '[object Date]'; - } - clone.__isDate = __isDate; - - function __isArray(o) { - return typeof o === 'object' && __objToStr(o) === '[object Array]'; - } - clone.__isArray = __isArray; - - function __isRegExp(o) { - return typeof o === 'object' && __objToStr(o) === '[object RegExp]'; - } - clone.__isRegExp = __isRegExp; - - function __getRegExpFlags(re) { - var flags = ''; - if (re.global) flags += 'g'; - if (re.ignoreCase) flags += 'i'; - if (re.multiline) flags += 'm'; - return flags; - } - clone.__getRegExpFlags = __getRegExpFlags; - - return clone; - })(); - - if ( module.exports) { - module.exports = clone; - } }); /* jshint proto: true */ function getLocation(index, inputStream) { - var n = index + 1; - var line = null; - var column = -1; - - while (--n >= 0 && inputStream.charAt(n) !== '\n') { - column++; - } - - if (typeof index === 'number') { - line = (inputStream.slice(0, index).match(/\n/g) || '').length; - } - - return { - line: line, - column: column - }; + var n = index + 1; + var line = null; + var column = -1; + while (--n >= 0 && inputStream.charAt(n) !== '\n') { + column++; + } + if (typeof index === 'number') { + line = (inputStream.slice(0, index).match(/\n/g) || '').length; + } + return { + line: line, + column: column + }; } function copyArray(arr) { - var i; - var length = arr.length; - var copy = new Array(length); - - for (i = 0; i < length; i++) { - copy[i] = arr[i]; - } - - return copy; + var i; + var length = arr.length; + var copy = new Array(length); + for (i = 0; i < length; i++) { + copy[i] = arr[i]; + } + return copy; } function clone(obj) { - var cloned = {}; - - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - cloned[prop] = obj[prop]; + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; + } } - } - - return cloned; + return cloned; } function defaults(obj1, obj2) { - var newObj = obj2 || {}; - - if (!obj2._defaults) { - newObj = {}; - - var _defaults = clone_1(obj1); - - newObj._defaults = _defaults; - var cloned = obj2 ? clone_1(obj2) : {}; - Object.assign(newObj, _defaults, cloned); - } - - return newObj; + var newObj = obj2 || {}; + if (!obj2._defaults) { + newObj = {}; + var defaults_1 = clone_1(obj1); + newObj._defaults = defaults_1; + var cloned = obj2 ? clone_1(obj2) : {}; + Object.assign(newObj, defaults_1, cloned); + } + return newObj; } function copyOptions(obj1, obj2) { - if (obj2 && obj2._defaults) { - return obj2; - } - - var opts = defaults(obj1, obj2); - - if (opts.strictMath) { - opts.math = Math$1.STRICT_LEGACY; - } // Back compat with changed relativeUrls option - - - if (opts.relativeUrls) { - opts.rewriteUrls = RewriteUrls.ALL; - } - - if (typeof opts.math === 'string') { - switch (opts.math.toLowerCase()) { - case 'always': - opts.math = Math$1.ALWAYS; - break; - - case 'parens-division': - opts.math = Math$1.PARENS_DIVISION; - break; - - case 'strict': - case 'parens': - opts.math = Math$1.PARENS; - break; - - case 'strict-legacy': + if (obj2 && obj2._defaults) { + return obj2; + } + var opts = defaults(obj1, obj2); + if (opts.strictMath) { opts.math = Math$1.STRICT_LEGACY; } - } - - if (typeof opts.rewriteUrls === 'string') { - switch (opts.rewriteUrls.toLowerCase()) { - case 'off': - opts.rewriteUrls = RewriteUrls.OFF; - break; - - case 'local': - opts.rewriteUrls = RewriteUrls.LOCAL; - break; - - case 'all': + // Back compat with changed relativeUrls option + if (opts.relativeUrls) { opts.rewriteUrls = RewriteUrls.ALL; - break; } - } - - return opts; + if (typeof opts.math === 'string') { + switch (opts.math.toLowerCase()) { + case 'always': + opts.math = Math$1.ALWAYS; + break; + case 'parens-division': + opts.math = Math$1.PARENS_DIVISION; + break; + case 'strict': + case 'parens': + opts.math = Math$1.PARENS; + break; + case 'strict-legacy': + opts.math = Math$1.STRICT_LEGACY; + } + } + if (typeof opts.rewriteUrls === 'string') { + switch (opts.rewriteUrls.toLowerCase()) { + case 'off': + opts.rewriteUrls = RewriteUrls.OFF; + break; + case 'local': + opts.rewriteUrls = RewriteUrls.LOCAL; + break; + case 'all': + opts.rewriteUrls = RewriteUrls.ALL; + break; + } + } + return opts; } function merge(obj1, obj2) { - for (var prop in obj2) { - if (obj2.hasOwnProperty(prop)) { - obj1[prop] = obj2[prop]; + for (var prop in obj2) { + if (obj2.hasOwnProperty(prop)) { + obj1[prop] = obj2[prop]; + } } - } - - return obj1; + return obj1; } - function flattenArray(arr) { - var result = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : []; - - for (var i = 0, length = arr.length; i < length; i++) { - var value = arr[i]; - - if (Array.isArray(value)) { - flattenArray(value, result); - } else { - if (value !== undefined) { - result.push(value); - } - } - } - - return result; + function flattenArray(arr, result) { + if (result === void 0) { result = []; } + for (var i_1 = 0, length_1 = arr.length; i_1 < length_1; i_1++) { + var value = arr[i_1]; + if (Array.isArray(value)) { + flattenArray(value, result); + } + else { + if (value !== undefined) { + result.push(value); + } + } + } + return result; } var utils = /*#__PURE__*/Object.freeze({ + __proto__: null, getLocation: getLocation, copyArray: copyArray, clone: clone, @@ -1616,6 +1287,7 @@ flattenArray: flattenArray }); + var anonymousFunc = /(|Function):(\d+):(\d+)/; /** * This is a centralized class of any error that could be thrown internally (mostly by the parser). * Besides standard .message it keeps some additional data like a path to the file where the error @@ -1638,55 +1310,68 @@ * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager? * @param {string} [currentFilename] */ - var LessError = function LessError(e, fileContentMap, currentFilename) { - Error.call(this); - var filename = e.filename || currentFilename; - this.message = e.message; - this.stack = e.stack; - - if (fileContentMap && filename) { - var input = fileContentMap.contents[filename]; - var loc = getLocation(e.index, input); - var line = loc.line; - var col = loc.column; - var callLine = e.call && getLocation(e.call, input).line; - var lines = input ? input.split('\n') : ''; - this.type = e.type || 'Syntax'; - this.filename = filename; - this.index = e.index; - this.line = typeof line === 'number' ? line + 1 : null; - this.column = col; - - if (!this.line && this.stack) { - var found = this.stack.match(/(|Function):(\d+):(\d+)/); - - if (found) { - if (found[2]) { - this.line = parseInt(found[2]) - 2; - } - - if (found[3]) { - this.column = parseInt(found[3]); + Error.call(this); + var filename = e.filename || currentFilename; + this.message = e.message; + this.stack = e.stack; + if (fileContentMap && filename) { + var input = fileContentMap.contents[filename]; + var loc = getLocation(e.index, input); + var line = loc.line; + var col = loc.column; + var callLine = e.call && getLocation(e.call, input).line; + var lines = input ? input.split('\n') : ''; + this.type = e.type || 'Syntax'; + this.filename = filename; + this.index = e.index; + this.line = typeof line === 'number' ? line + 1 : null; + this.column = col; + if (!this.line && this.stack) { + var found = this.stack.match(anonymousFunc); + /** + * We have to figure out how this environment stringifies anonymous functions + * so we can correctly map plugin errors. + * + * Note, in Node 8, the output of anonymous funcs varied based on parameters + * being present or not, so we inject dummy params. + */ + var func = new Function('a', 'throw new Error()'); + var lineAdjust = 0; + try { + func(); + } + catch (e) { + var match = e.stack.match(anonymousFunc); + var line_1 = parseInt(match[2]); + lineAdjust = 1 - line_1; + } + if (found) { + if (found[2]) { + this.line = parseInt(found[2]) + lineAdjust; + } + if (found[3]) { + this.column = parseInt(found[3]); + } + } } - } + this.callLine = callLine + 1; + this.callExtract = lines[callLine]; + this.extract = [ + lines[this.line - 2], + lines[this.line - 1], + lines[this.line] + ]; } - - this.callLine = callLine + 1; - this.callExtract = lines[callLine]; - this.extract = [lines[this.line - 2], lines[this.line - 1], lines[this.line]]; - } }; - if (typeof Object.create === 'undefined') { - var F = function F() {}; - - F.prototype = Error.prototype; - LessError.prototype = new F(); - } else { - LessError.prototype = Object.create(Error.prototype); + var F = function () { }; + F.prototype = Error.prototype; + LessError.prototype = new F(); + } + else { + LessError.prototype = Object.create(Error.prototype); } - LessError.prototype.constructor = LessError; /** * An overridden version of the default Object.prototype.toString @@ -1695,2619 +1380,1984 @@ * @param {Object} options * @returns {string} */ - - LessError.prototype.toString = function () { - var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; - var message = ''; - var extract = this.extract || []; - var error = []; - - var stylize = function stylize(str) { - return str; - }; - - if (options.stylize) { - var type = _typeof(options.stylize); - - if (type !== 'function') { - throw Error("options.stylize should be a function, got a ".concat(type, "!")); + LessError.prototype.toString = function (options) { + if (options === void 0) { options = {}; } + var message = ''; + var extract = this.extract || []; + var error = []; + var stylize = function (str) { return str; }; + if (options.stylize) { + var type = typeof options.stylize; + if (type !== 'function') { + throw Error("options.stylize should be a function, got a " + type + "!"); + } + stylize = options.stylize; + } + if (this.line !== null) { + if (typeof extract[0] === 'string') { + error.push(stylize(this.line - 1 + " " + extract[0], 'grey')); + } + if (typeof extract[1] === 'string') { + var errorTxt = this.line + " "; + if (extract[1]) { + errorTxt += extract[1].slice(0, this.column) + + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + + extract[1].slice(this.column + 1), 'red'), 'inverse'); + } + error.push(errorTxt); + } + if (typeof extract[2] === 'string') { + error.push(stylize(this.line + 1 + " " + extract[2], 'grey')); + } + error = error.join('\n') + stylize('', 'reset') + "\n"; } - - stylize = options.stylize; - } - - if (this.line !== null) { - if (typeof extract[0] === 'string') { - error.push(stylize("".concat(this.line - 1, " ").concat(extract[0]), 'grey')); + message += stylize(this.type + "Error: " + this.message, 'red'); + if (this.filename) { + message += stylize(' in ', 'red') + this.filename; } - - if (typeof extract[1] === 'string') { - var errorTxt = "".concat(this.line, " "); - - if (extract[1]) { - errorTxt += extract[1].slice(0, this.column) + stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') + extract[1].slice(this.column + 1), 'red'), 'inverse'); - } - - error.push(errorTxt); + if (this.line) { + message += stylize(" on line " + this.line + ", column " + (this.column + 1) + ":", 'grey'); } - - if (typeof extract[2] === 'string') { - error.push(stylize("".concat(this.line + 1, " ").concat(extract[2]), 'grey')); + message += "\n" + error; + if (this.callLine) { + message += stylize('from ', 'red') + (this.filename || '') + "/n"; + message += stylize(this.callLine, 'grey') + " " + this.callExtract + "/n"; } - - error = "".concat(error.join('\n') + stylize('', 'reset'), "\n"); - } - - message += stylize("".concat(this.type, "Error: ").concat(this.message), 'red'); - - if (this.filename) { - message += stylize(' in ', 'red') + this.filename; - } - - if (this.line) { - message += stylize(" on line ".concat(this.line, ", column ").concat(this.column + 1, ":"), 'grey'); - } - - message += "\n".concat(error); - - if (this.callLine) { - message += "".concat(stylize('from ', 'red') + (this.filename || ''), "/n"); - message += "".concat(stylize(this.callLine, 'grey'), " ").concat(this.callExtract, "/n"); - } - - return message; + return message; }; - var Selector = - /*#__PURE__*/ - function (_Node) { - _inherits(Selector, _Node); - - function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Selector); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Selector).call(this)); - _this.extendList = extendList; - _this.condition = condition; - _this.evaldCondition = !condition; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.elements = _this.getElements(elements); - _this.mixinElements_ = undefined; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.elements, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Selector, [{ - key: "accept", - value: function accept(visitor) { - if (this.elements) { - this.elements = visitor.visitArray(this.elements); - } - - if (this.extendList) { - this.extendList = visitor.visitArray(this.extendList); - } - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "createDerived", - value: function createDerived(elements, extendList, evaldCondition) { - elements = this.getElements(elements); - var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - newSelector.evaldCondition = evaldCondition != null ? evaldCondition : this.evaldCondition; - newSelector.mediaEmpty = this.mediaEmpty; - return newSelector; - } - }, { - key: "getElements", - value: function getElements(els) { - if (!els) { - return [new Element('', '&', false, this._index, this._fileInfo)]; - } - - if (typeof els === 'string') { - this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { - if (err) { - throw new LessError({ - index: err.index, - message: err.message - }, this.parse.imports, this._fileInfo.filename); - } - - els = result[0].elements; - }); - } - - return els; - } - }, { - key: "createEmptySelectors", - value: function createEmptySelectors() { - var el = new Element('', '&', false, this._index, this._fileInfo); - var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; - sels[0].mediaEmpty = true; - return sels; - } - }, { - key: "match", - value: function match(other) { - var elements = this.elements; - var len = elements.length; - var olen; - var i; - other = other.mixinElements(); - olen = other.length; - - if (olen === 0 || len < olen) { - return 0; - } else { - for (i = 0; i < olen; i++) { - if (elements[i].value !== other[i]) { - return 0; - } - } - } - - return olen; // return number of matched elements - } - }, { - key: "mixinElements", - value: function mixinElements() { - if (this.mixinElements_) { - return this.mixinElements_; - } - - var elements = this.elements.map(function (v) { - return v.combinator.value + (v.value.value || v.value); - }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); - - if (elements) { - if (elements[0] === '&') { - elements.shift(); + var Selector = /** @class */ (function (_super) { + __extends(Selector, _super); + function Selector(elements, extendList, condition, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.extendList = extendList; + _this.condition = condition; + _this.evaldCondition = !condition; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.elements = _this.getElements(elements); + _this.mixinElements_ = undefined; + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.elements, _this); + return _this; + } + Selector.prototype.accept = function (visitor) { + if (this.elements) { + this.elements = visitor.visitArray(this.elements); + } + if (this.extendList) { + this.extendList = visitor.visitArray(this.extendList); + } + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } else { - elements = []; - } - - return this.mixinElements_ = elements; - } - }, { - key: "isJustParentSelector", - value: function isJustParentSelector() { - return !this.mediaEmpty && this.elements.length === 1 && this.elements[0].value === '&' && (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); - } - }, { - key: "eval", - value: function _eval(context) { - var evaldCondition = this.condition && this.condition.eval(context); - var elements = this.elements; - var extendList = this.extendList; - elements = elements && elements.map(function (e) { - return e.eval(context); - }); - extendList = extendList && extendList.map(function (extend) { - return extend.eval(context); - }); - return this.createDerived(elements, extendList, evaldCondition); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var element; - - if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { - output.add(' ', this.fileInfo(), this.getIndex()); - } - - for (i = 0; i < this.elements.length; i++) { - element = this.elements[i]; - element.genCSS(context, output); - } - } - }, { - key: "getIsOutput", - value: function getIsOutput() { - return this.evaldCondition; - } - }]); - - return Selector; - }(Node); - + }; + Selector.prototype.createDerived = function (elements, extendList, evaldCondition) { + elements = this.getElements(elements); + var newSelector = new Selector(elements, extendList || this.extendList, null, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition; + newSelector.mediaEmpty = this.mediaEmpty; + return newSelector; + }; + Selector.prototype.getElements = function (els) { + if (!els) { + return [new Element('', '&', false, this._index, this._fileInfo)]; + } + if (typeof els === 'string') { + this.parse.parseNode(els, ['selector'], this._index, this._fileInfo, function (err, result) { + if (err) { + throw new LessError({ + index: err.index, + message: err.message + }, this.parse.imports, this._fileInfo.filename); + } + els = result[0].elements; + }); + } + return els; + }; + Selector.prototype.createEmptySelectors = function () { + var el = new Element('', '&', false, this._index, this._fileInfo); + var sels = [new Selector([el], null, null, this._index, this._fileInfo)]; + sels[0].mediaEmpty = true; + return sels; + }; + Selector.prototype.match = function (other) { + var elements = this.elements; + var len = elements.length; + var olen; + var i; + other = other.mixinElements(); + olen = other.length; + if (olen === 0 || len < olen) { + return 0; + } + else { + for (i = 0; i < olen; i++) { + if (elements[i].value !== other[i]) { + return 0; + } + } + } + return olen; // return number of matched elements + }; + Selector.prototype.mixinElements = function () { + if (this.mixinElements_) { + return this.mixinElements_; + } + var elements = this.elements.map(function (v) { return v.combinator.value + (v.value.value || v.value); }).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g); + if (elements) { + if (elements[0] === '&') { + elements.shift(); + } + } + else { + elements = []; + } + return (this.mixinElements_ = elements); + }; + Selector.prototype.isJustParentSelector = function () { + return !this.mediaEmpty && + this.elements.length === 1 && + this.elements[0].value === '&' && + (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === ''); + }; + Selector.prototype.eval = function (context) { + var evaldCondition = this.condition && this.condition.eval(context); + var elements = this.elements; + var extendList = this.extendList; + elements = elements && elements.map(function (e) { return e.eval(context); }); + extendList = extendList && extendList.map(function (extend) { return extend.eval(context); }); + return this.createDerived(elements, extendList, evaldCondition); + }; + Selector.prototype.genCSS = function (context, output) { + var i; + var element; + if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') { + output.add(' ', this.fileInfo(), this.getIndex()); + } + for (i = 0; i < this.elements.length; i++) { + element = this.elements[i]; + element.genCSS(context, output); + } + }; + Selector.prototype.getIsOutput = function () { + return this.evaldCondition; + }; + return Selector; + }(Node)); Selector.prototype.type = 'Selector'; - var Value = - /*#__PURE__*/ - function (_Node) { - _inherits(Value, _Node); - - function Value(value) { - var _this; - - _classCallCheck(this, Value); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Value).call(this)); - - if (!value) { - throw new Error('Value requires an array argument'); - } - - if (!Array.isArray(value)) { - _this.value = [value]; - } else { - _this.value = value; - } - - return _this; - } - - _createClass(Value, [{ - key: "accept", - value: function accept(visitor) { - if (this.value) { - this.value = visitor.visitArray(this.value); - } - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.length === 1) { - return this.value[0].eval(context); - } else { - return new Value(this.value.map(function (v) { - return v.eval(context); - })); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - - for (i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (i + 1 < this.value.length) { - output.add(context && context.compress ? ',' : ', '); + var Value = /** @class */ (function (_super) { + __extends(Value, _super); + function Value(value) { + var _this = _super.call(this) || this; + if (!value) { + throw new Error('Value requires an array argument'); + } + if (!Array.isArray(value)) { + _this.value = [value]; } - } + else { + _this.value = value; + } + return _this; } - }]); - - return Value; - }(Node); - + Value.prototype.accept = function (visitor) { + if (this.value) { + this.value = visitor.visitArray(this.value); + } + }; + Value.prototype.eval = function (context) { + if (this.value.length === 1) { + return this.value[0].eval(context); + } + else { + return new Value(this.value.map(function (v) { return v.eval(context); })); + } + }; + Value.prototype.genCSS = function (context, output) { + var i; + for (i = 0; i < this.value.length; i++) { + this.value[i].genCSS(context, output); + if (i + 1 < this.value.length) { + output.add((context && context.compress) ? ',' : ', '); + } + } + }; + return Value; + }(Node)); Value.prototype.type = 'Value'; - var Keyword = - /*#__PURE__*/ - function (_Node) { - _inherits(Keyword, _Node); - - function Keyword(value) { - var _this; - - _classCallCheck(this, Keyword); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Keyword).call(this)); - _this.value = value; - return _this; - } - - _createClass(Keyword, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.value === '%') { - throw { - type: 'Syntax', - message: 'Invalid % without number' - }; - } - - output.add(this.value); + var Keyword = /** @class */ (function (_super) { + __extends(Keyword, _super); + function Keyword(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; } - }]); - - return Keyword; - }(Node); - + Keyword.prototype.genCSS = function (context, output) { + if (this.value === '%') { + throw { type: 'Syntax', message: 'Invalid % without number' }; + } + output.add(this.value); + }; + return Keyword; + }(Node)); Keyword.prototype.type = 'Keyword'; Keyword.True = new Keyword('true'); Keyword.False = new Keyword('false'); - var Anonymous = - /*#__PURE__*/ - function (_Node) { - _inherits(Anonymous, _Node); - - function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { - var _this; - - _classCallCheck(this, Anonymous); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Anonymous).call(this)); - _this.value = value; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.mapLines = mapLines; - _this.rulesetLike = typeof rulesetLike === 'undefined' ? false : rulesetLike; - _this.allowRoot = true; - - _this.copyVisibilityInfo(visibilityInfo); - - return _this; - } - - _createClass(Anonymous, [{ - key: "eval", - value: function _eval() { - return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); - } - }, { - key: "compare", - value: function compare(other) { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rulesetLike; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.nodeVisible = Boolean(this.value); - - if (this.nodeVisible) { - output.add(this.value, this._fileInfo, this._index, this.mapLines); - } - } - }]); - - return Anonymous; - }(Node); - + var Anonymous = /** @class */ (function (_super) { + __extends(Anonymous, _super); + function Anonymous(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.mapLines = mapLines; + _this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike; + _this.allowRoot = true; + _this.copyVisibilityInfo(visibilityInfo); + return _this; + } + Anonymous.prototype.eval = function () { + return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo()); + }; + Anonymous.prototype.compare = function (other) { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + }; + Anonymous.prototype.isRulesetLike = function () { + return this.rulesetLike; + }; + Anonymous.prototype.genCSS = function (context, output) { + this.nodeVisible = Boolean(this.value); + if (this.nodeVisible) { + output.add(this.value, this._fileInfo, this._index, this.mapLines); + } + }; + return Anonymous; + }(Node)); Anonymous.prototype.type = 'Anonymous'; var MATH = Math$1; - - var Declaration = - /*#__PURE__*/ - function (_Node) { - _inherits(Declaration, _Node); - - function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { - var _this; - - _classCallCheck(this, Declaration); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Declaration).call(this)); - _this.name = name; - _this.value = value instanceof Node ? value : new Value([value ? new Anonymous(value) : null]); - _this.important = important ? " ".concat(important.trim()) : ''; - _this.merge = merge; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.inline = inline || false; - _this.variable = variable !== undefined ? variable : name.charAt && name.charAt(0) === '@'; - _this.allowRoot = true; - - _this.setParent(_this.value, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Declaration, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); - - try { - this.value.genCSS(context, output); - } catch (e) { - e.index = this._index; - e.filename = this._fileInfo.filename; - throw e; - } - - output.add(this.important + (this.inline || context.lastRule && context.compress ? '' : ';'), this._fileInfo, this._index); - } - }, { - key: "eval", - value: function _eval(context) { - var mathBypass = false; - var prevMath; - var name = this.name; - var evaldValue; - var variable = this.variable; - - if (typeof name !== 'string') { - // expand 'primitive' name directly to get - // things faster (~10% for benchmark.less): - name = name.length === 1 && name[0] instanceof Keyword ? name[0].value : evalName(context, name); - variable = false; // never treat expanded interpolation as new variable name - } // @todo remove when parens-division is default - - - if (name === 'font' && context.math === MATH.ALWAYS) { - mathBypass = true; - prevMath = context.math; - context.math = MATH.PARENS_DIVISION; - } - - try { - context.importantScope.push({}); - evaldValue = this.value.eval(context); - - if (!this.variable && evaldValue.type === 'DetachedRuleset') { - throw { - message: 'Rulesets cannot be evaluated on a property.', - index: this.getIndex(), - filename: this.fileInfo().filename - }; + var Declaration = /** @class */ (function (_super) { + __extends(Declaration, _super); + function Declaration(name, value, important, merge, index, currentFileInfo, inline, variable) { + var _this = _super.call(this) || this; + _this.name = name; + _this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]); + _this.important = important ? " " + important.trim() : ''; + _this.merge = merge; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.inline = inline || false; + _this.variable = (variable !== undefined) ? variable + : (name.charAt && (name.charAt(0) === '@')); + _this.allowRoot = true; + _this.setParent(_this.value, _this); + return _this; + } + Declaration.prototype.genCSS = function (context, output) { + output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex()); + try { + this.value.genCSS(context, output); } - - var important = this.important; - var importantResult = context.importantScope.pop(); - - if (!important && importantResult.important) { - important = importantResult.important; + catch (e) { + e.index = this._index; + e.filename = this._fileInfo.filename; + throw e; } - - return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); - } catch (e) { - if (typeof e.index !== 'number') { - e.index = this.getIndex(); - e.filename = this.fileInfo().filename; + output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index); + }; + Declaration.prototype.eval = function (context) { + var mathBypass = false; + var prevMath; + var name = this.name; + var evaldValue; + var variable = this.variable; + if (typeof name !== 'string') { + // expand 'primitive' name directly to get + // things faster (~10% for benchmark.less): + name = (name.length === 1) && (name[0] instanceof Keyword) ? + name[0].value : evalName(context, name); + variable = false; // never treat expanded interpolation as new variable name + } + // @todo remove when parens-division is default + if (name === 'font' && context.math === MATH.ALWAYS) { + mathBypass = true; + prevMath = context.math; + context.math = MATH.PARENS_DIVISION; } - - throw e; - } finally { - if (mathBypass) { - context.math = prevMath; + try { + context.importantScope.push({}); + evaldValue = this.value.eval(context); + if (!this.variable && evaldValue.type === 'DetachedRuleset') { + throw { message: 'Rulesets cannot be evaluated on a property.', + index: this.getIndex(), filename: this.fileInfo().filename }; + } + var important = this.important; + var importantResult = context.importantScope.pop(); + if (!important && importantResult.important) { + important = importantResult.important; + } + return new Declaration(name, evaldValue, important, this.merge, this.getIndex(), this.fileInfo(), this.inline, variable); } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); - } - }]); - - return Declaration; - }(Node); - + catch (e) { + if (typeof e.index !== 'number') { + e.index = this.getIndex(); + e.filename = this.fileInfo().filename; + } + throw e; + } + finally { + if (mathBypass) { + context.math = prevMath; + } + } + }; + Declaration.prototype.makeImportant = function () { + return new Declaration(this.name, this.value, '!important', this.merge, this.getIndex(), this.fileInfo(), this.inline); + }; + return Declaration; + }(Node)); function evalName(context, name) { - var value = ''; - var i; - var n = name.length; - var output = { - add: function add(s) { - value += s; - } - }; - - for (i = 0; i < n; i++) { - name[i].eval(context).genCSS(context, output); - } - - return value; + var value = ''; + var i; + var n = name.length; + var output = { add: function (s) { value += s; } }; + for (i = 0; i < n; i++) { + name[i].eval(context).genCSS(context, output); + } + return value; } - Declaration.prototype.type = 'Declaration'; - var debugInfo = function debugInfo(context, ctx, lineSeparator) { - var result = ''; - - if (context.dumpLineNumbers && !context.compress) { - switch (context.dumpLineNumbers) { - case 'comments': - result = debugInfo.asComment(ctx); - break; - - case 'mediaquery': - result = debugInfo.asMediaQuery(ctx); - break; - - case 'all': - result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); - break; + var debugInfo = function (context, ctx, lineSeparator) { + var result = ''; + if (context.dumpLineNumbers && !context.compress) { + switch (context.dumpLineNumbers) { + case 'comments': + result = debugInfo.asComment(ctx); + break; + case 'mediaquery': + result = debugInfo.asMediaQuery(ctx); + break; + case 'all': + result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx); + break; + } } - } - - return result; - }; - - debugInfo.asComment = function (ctx) { - return "/* line ".concat(ctx.debugInfo.lineNumber, ", ").concat(ctx.debugInfo.fileName, " */\n"); + return result; }; - + debugInfo.asComment = function (ctx) { return "/* line " + ctx.debugInfo.lineNumber + ", " + ctx.debugInfo.fileName + " */\n"; }; debugInfo.asMediaQuery = function (ctx) { - var filenameWithProtocol = ctx.debugInfo.fileName; - - if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { - filenameWithProtocol = "file://".concat(filenameWithProtocol); - } - - return "@media -sass-debug-info{filename{font-family:".concat(filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { - if (a == '\\') { - a = '\/'; + var filenameWithProtocol = ctx.debugInfo.fileName; + if (!/^[a-z]+:\/\//i.test(filenameWithProtocol)) { + filenameWithProtocol = "file://" + filenameWithProtocol; } - - return "\\".concat(a); - }), "}line{font-family:\\00003").concat(ctx.debugInfo.lineNumber, "}}\n"); + return "@media -sass-debug-info{filename{font-family:" + filenameWithProtocol.replace(/([.:\/\\])/g, function (a) { + if (a == '\\') { + a = '\/'; + } + return "\\" + a; + }) + "}line{font-family:\\00003" + ctx.debugInfo.lineNumber + "}}\n"; }; - var Comment = - /*#__PURE__*/ - function (_Node) { - _inherits(Comment, _Node); - - function Comment(value, isLineComment, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Comment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Comment).call(this)); - _this.value = value; - _this.isLineComment = isLineComment; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(Comment, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (this.debugInfo) { - output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - } - }, { - key: "isSilent", - value: function isSilent(context) { - var isCompressed = context.compress && this.value[2] !== '!'; - return this.isLineComment || isCompressed; - } - }]); - - return Comment; - }(Node); - + var Comment = /** @class */ (function (_super) { + __extends(Comment, _super); + function Comment(value, isLineComment, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.value = value; + _this.isLineComment = isLineComment; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + Comment.prototype.genCSS = function (context, output) { + if (this.debugInfo) { + output.add(debugInfo(context, this), this.fileInfo(), this.getIndex()); + } + output.add(this.value); + }; + Comment.prototype.isSilent = function (context) { + var isCompressed = context.compress && this.value[2] !== '!'; + return this.isLineComment || isCompressed; + }; + return Comment; + }(Node)); Comment.prototype.type = 'Comment'; var contexts = {}; - var copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) { - if (!original) { - return; - } - - for (var i = 0; i < propertiesToCopy.length; i++) { - if (original.hasOwnProperty(propertiesToCopy[i])) { - destination[propertiesToCopy[i]] = original[propertiesToCopy[i]]; + if (!original) { + return; + } + for (var i_1 = 0; i_1 < propertiesToCopy.length; i_1++) { + if (original.hasOwnProperty(propertiesToCopy[i_1])) { + destination[propertiesToCopy[i_1]] = original[propertiesToCopy[i_1]]; + } } - } }; /* parse is used whilst parsing */ - - - var parseCopyProperties = [// options - 'paths', // option - unmodified - paths to search for imports on - 'rewriteUrls', // option - whether to adjust URL's to be relative - 'rootpath', // option - rootpath to append to URL's - 'strictImports', // option - - 'insecure', // option - whether to allow imports from insecure ssl hosts - 'dumpLineNumbers', // option - whether to dump line numbers - 'compress', // option - whether to compress - 'syncImport', // option - whether to import synchronously - 'chunkInput', // option - whether to chunk input. more performant but causes parse issues. - 'mime', // browser only - mime type for sheet import - 'useFileCache', // browser only - whether to use the per file session cache - // context - 'processImports', // option & context - whether to process imports. if false then imports will not be imported. - // Used by the import manager to stop multiple import visitors being created. - 'pluginManager' // Used as the plugin manager for the session + var parseCopyProperties = [ + // options + 'paths', + 'rewriteUrls', + 'rootpath', + 'strictImports', + 'insecure', + 'dumpLineNumbers', + 'compress', + 'syncImport', + 'chunkInput', + 'mime', + 'useFileCache', + // context + 'processImports', + // Used by the import manager to stop multiple import visitors being created. + 'pluginManager' // Used as the plugin manager for the session ]; - contexts.Parse = function (options) { - copyFromOriginal(options, this, parseCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } + copyFromOriginal(options, this, parseCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } }; - - var evalCopyProperties = ['paths', // additional include paths - 'compress', // whether to compress - 'math', // whether math has to be within parenthesis - 'strictUnits', // whether units need to evaluate correctly - 'sourceMap', // whether to output a source map - 'importMultiple', // whether we are currently importing multiple copies - 'urlArgs', // whether to add args into url tokens - 'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false - 'pluginManager', // Used as the plugin manager for the session - 'importantScope', // used to bubble up !important statements - 'rewriteUrls' // option - whether to adjust URL's to be relative + var evalCopyProperties = [ + 'paths', + 'compress', + 'math', + 'strictUnits', + 'sourceMap', + 'importMultiple', + 'urlArgs', + 'javascriptEnabled', + 'pluginManager', + 'importantScope', + 'rewriteUrls' // option - whether to adjust URL's to be relative ]; - function isPathRelative(path) { - return !/^(?:[a-z-]+:|\/|#)/i.test(path); + return !/^(?:[a-z-]+:|\/|#)/i.test(path); } - function isPathLocalRelative(path) { - return path.charAt(0) === '.'; + return path.charAt(0) === '.'; } - - contexts.Eval = - /*#__PURE__*/ - function () { - function _class(options, frames) { - _classCallCheck(this, _class); - - copyFromOriginal(options, this, evalCopyProperties); - - if (typeof this.paths === 'string') { - this.paths = [this.paths]; - } - - this.frames = frames || []; - this.importantScope = this.importantScope || []; - this.inCalc = false; - this.mathOn = true; - } - - _createClass(_class, [{ - key: "enterCalc", - value: function enterCalc() { - if (!this.calcStack) { - this.calcStack = []; - } - - this.calcStack.push(true); - this.inCalc = true; - } - }, { - key: "exitCalc", - value: function exitCalc() { - this.calcStack.pop(); - - if (!this.calcStack) { + contexts.Eval = /** @class */ (function () { + function Eval(options, frames) { + copyFromOriginal(options, this, evalCopyProperties); + if (typeof this.paths === 'string') { + this.paths = [this.paths]; + } + this.frames = frames || []; + this.importantScope = this.importantScope || []; this.inCalc = false; - } - } - }, { - key: "inParenthesis", - value: function inParenthesis() { - if (!this.parensStack) { - this.parensStack = []; - } - - this.parensStack.push(true); - } - }, { - key: "outOfParenthesis", - value: function outOfParenthesis() { - this.parensStack.pop(); + this.mathOn = true; } - }, { - key: "isMathOn", - value: function isMathOn(op) { - if (!this.mathOn) { - return false; - } - - if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { - return false; - } - - if (this.math > Math$1.PARENS_DIVISION) { - return this.parensStack && this.parensStack.length; - } - - return true; - } - }, { - key: "pathRequiresRewrite", - value: function pathRequiresRewrite(path) { - var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; - return isRelative(path); - } - }, { - key: "rewritePath", - value: function rewritePath(path, rootpath) { - var newPath; - rootpath = rootpath || ''; - newPath = this.normalizePath(rootpath + path); // If a path was explicit relative and the rootpath was not an absolute path - // we must ensure that the new path is also explicit relative. - - if (isPathLocalRelative(path) && isPathRelative(rootpath) && isPathLocalRelative(newPath) === false) { - newPath = "./".concat(newPath); - } - - return newPath; - } - }, { - key: "normalizePath", - value: function normalizePath(path) { - var segments = path.split('/').reverse(); - var segment; - path = []; - - while (segments.length !== 0) { - segment = segments.pop(); - - switch (segment) { - case '.': - break; - - case '..': - if (path.length === 0 || path[path.length - 1] === '..') { - path.push(segment); - } else { - path.pop(); + Eval.prototype.enterCalc = function () { + if (!this.calcStack) { + this.calcStack = []; + } + this.calcStack.push(true); + this.inCalc = true; + }; + Eval.prototype.exitCalc = function () { + this.calcStack.pop(); + if (!this.calcStack) { + this.inCalc = false; + } + }; + Eval.prototype.inParenthesis = function () { + if (!this.parensStack) { + this.parensStack = []; + } + this.parensStack.push(true); + }; + Eval.prototype.outOfParenthesis = function () { + this.parensStack.pop(); + }; + Eval.prototype.isMathOn = function (op) { + if (!this.mathOn) { + return false; + } + if (op === '/' && this.math !== Math$1.ALWAYS && (!this.parensStack || !this.parensStack.length)) { + return false; + } + if (this.math > Math$1.PARENS_DIVISION) { + return this.parensStack && this.parensStack.length; + } + return true; + }; + Eval.prototype.pathRequiresRewrite = function (path) { + var isRelative = this.rewriteUrls === RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative; + return isRelative(path); + }; + Eval.prototype.rewritePath = function (path, rootpath) { + var newPath; + rootpath = rootpath || ''; + newPath = this.normalizePath(rootpath + path); + // If a path was explicit relative and the rootpath was not an absolute path + // we must ensure that the new path is also explicit relative. + if (isPathLocalRelative(path) && + isPathRelative(rootpath) && + isPathLocalRelative(newPath) === false) { + newPath = "./" + newPath; + } + return newPath; + }; + Eval.prototype.normalizePath = function (path) { + var segments = path.split('/').reverse(); + var segment; + path = []; + while (segments.length !== 0) { + segment = segments.pop(); + switch (segment) { + case '.': + break; + case '..': + if ((path.length === 0) || (path[path.length - 1] === '..')) { + path.push(segment); + } + else { + path.pop(); + } + break; + default: + path.push(segment); + break; } - - break; - - default: - path.push(segment); - break; } - } - - return path.join('/'); - } - }]); - - return _class; - }(); + return path.join('/'); + }; + return Eval; + }()); function makeRegistry(base) { - return { - _data: {}, - add: function add(name, func) { - // precautionary case conversion, as later querying of - // the registry by function-caller uses lower case as well. - name = name.toLowerCase(); - - if (this._data.hasOwnProperty(name)) ; - - this._data[name] = func; - }, - addMultiple: function addMultiple(functions) { - var _this = this; - - Object.keys(functions).forEach(function (name) { - _this.add(name, functions[name]); - }); - }, - get: function get(name) { - return this._data[name] || base && base.get(name); - }, - getLocalFunctions: function getLocalFunctions() { - return this._data; - }, - inherit: function inherit() { - return makeRegistry(this); - }, - create: function create(base) { - return makeRegistry(base); - } - }; + return { + _data: {}, + add: function (name, func) { + // precautionary case conversion, as later querying of + // the registry by function-caller uses lower case as well. + name = name.toLowerCase(); + if (this._data.hasOwnProperty(name)) ; + this._data[name] = func; + }, + addMultiple: function (functions) { + var _this = this; + Object.keys(functions).forEach(function (name) { + _this.add(name, functions[name]); + }); + }, + get: function (name) { + return this._data[name] || (base && base.get(name)); + }, + getLocalFunctions: function () { + return this._data; + }, + inherit: function () { + return makeRegistry(this); + }, + create: function (base) { + return makeRegistry(base); + } + }; } - var functionRegistry = makeRegistry(null); var defaultFunc = { - eval: function _eval() { - var v = this.value_; - var e = this.error_; - - if (e) { - throw e; + eval: function () { + var v = this.value_; + var e = this.error_; + if (e) { + throw e; + } + if (v != null) { + return v ? Keyword.True : Keyword.False; + } + }, + value: function (v) { + this.value_ = v; + }, + error: function (e) { + this.error_ = e; + }, + reset: function () { + this.value_ = this.error_ = null; } - - if (v != null) { - return v ? Keyword.True : Keyword.False; - } - }, - value: function value(v) { - this.value_ = v; - }, - error: function error(e) { - this.error_ = e; - }, - reset: function reset() { - this.value_ = this.error_ = null; - } }; - var Ruleset = - /*#__PURE__*/ - function (_Node) { - _inherits(Ruleset, _Node); - - function Ruleset(selectors, rules, strictImports, visibilityInfo) { - var _this; - - _classCallCheck(this, Ruleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Ruleset).call(this)); - _this.selectors = selectors; - _this.rules = rules; - _this._lookups = {}; - _this._variables = null; - _this._properties = null; - _this.strictImports = strictImports; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(_this.selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Ruleset, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.paths) { - this.paths = visitor.visitArray(this.paths, true); - } else if (this.selectors) { - this.selectors = visitor.visitArray(this.selectors); - } - - if (this.rules && this.rules.length) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "eval", - value: function _eval(context) { - var selectors; - var selCnt; - var selector; - var i; - var hasVariable; - var hasOnePassingSelector = false; - - if (this.selectors && (selCnt = this.selectors.length)) { - selectors = new Array(selCnt); - defaultFunc.error({ - type: 'Syntax', - message: 'it is currently only allowed in parametric mixin guards,' - }); - - for (i = 0; i < selCnt; i++) { - selector = this.selectors[i].eval(context); - - for (var j = 0; j < selector.elements.length; j++) { - if (selector.elements[j].isVariable) { - hasVariable = true; - break; + var Ruleset = /** @class */ (function (_super) { + __extends(Ruleset, _super); + function Ruleset(selectors, rules, strictImports, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selectors = selectors; + _this.rules = rules; + _this._lookups = {}; + _this._variables = null; + _this._properties = null; + _this.strictImports = strictImports; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(_this.selectors, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Ruleset.prototype.isRulesetLike = function () { + return true; + }; + Ruleset.prototype.accept = function (visitor) { + if (this.paths) { + this.paths = visitor.visitArray(this.paths, true); + } + else if (this.selectors) { + this.selectors = visitor.visitArray(this.selectors); + } + if (this.rules && this.rules.length) { + this.rules = visitor.visitArray(this.rules); + } + }; + Ruleset.prototype.eval = function (context) { + var selectors; + var selCnt; + var selector; + var i; + var hasVariable; + var hasOnePassingSelector = false; + if (this.selectors && (selCnt = this.selectors.length)) { + selectors = new Array(selCnt); + defaultFunc.error({ + type: 'Syntax', + message: 'it is currently only allowed in parametric mixin guards,' + }); + for (i = 0; i < selCnt; i++) { + selector = this.selectors[i].eval(context); + for (var j = 0; j < selector.elements.length; j++) { + if (selector.elements[j].isVariable) { + hasVariable = true; + break; + } + } + selectors[i] = selector; + if (selector.evaldCondition) { + hasOnePassingSelector = true; + } } - } - - selectors[i] = selector; - - if (selector.evaldCondition) { + if (hasVariable) { + var toParseSelectors = new Array(selCnt); + for (i = 0; i < selCnt; i++) { + selector = selectors[i]; + toParseSelectors[i] = selector.toCSS(context); + } + this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { + if (result) { + selectors = flattenArray(result); + } + }); + } + defaultFunc.reset(); + } + else { hasOnePassingSelector = true; - } } - - if (hasVariable) { - var toParseSelectors = new Array(selCnt); - - for (i = 0; i < selCnt; i++) { - selector = selectors[i]; - toParseSelectors[i] = selector.toCSS(context); - } - - this.parse.parseNode(toParseSelectors.join(','), ["selectors"], selectors[0].getIndex(), selectors[0].fileInfo(), function (err, result) { - if (result) { - selectors = flattenArray(result); + var rules = this.rules ? copyArray(this.rules) : null; + var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); + var rule; + var subRule; + ruleset.originalRuleset = this; + ruleset.root = this.root; + ruleset.firstRoot = this.firstRoot; + ruleset.allowImports = this.allowImports; + if (this.debugInfo) { + ruleset.debugInfo = this.debugInfo; + } + if (!hasOnePassingSelector) { + rules.length = 0; + } + // inherit a function registry from the frames stack when possible; + // otherwise from the global registry + ruleset.functionRegistry = (function (frames) { + var i = 0; + var n = frames.length; + var found; + for (; i !== n; ++i) { + found = frames[i].functionRegistry; + if (found) { + return found; + } + } + return functionRegistry; + })(context.frames).inherit(); + // push the current ruleset to the frames stack + var ctxFrames = context.frames; + ctxFrames.unshift(ruleset); + // currrent selectors + var ctxSelectors = context.selectors; + if (!ctxSelectors) { + context.selectors = ctxSelectors = []; + } + ctxSelectors.unshift(this.selectors); + // Evaluate imports + if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { + ruleset.evalImports(context); + } + // Store the frames around mixin definitions, + // so they can be evaluated like closures when the time comes. + var rsRules = ruleset.rules; + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.evalFirst) { + rsRules[i] = rule.eval(context); } - }); } - - defaultFunc.reset(); - } else { - hasOnePassingSelector = true; - } - - var rules = this.rules ? copyArray(this.rules) : null; - var ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo()); - var rule; - var subRule; - ruleset.originalRuleset = this; - ruleset.root = this.root; - ruleset.firstRoot = this.firstRoot; - ruleset.allowImports = this.allowImports; - - if (this.debugInfo) { - ruleset.debugInfo = this.debugInfo; - } - - if (!hasOnePassingSelector) { - rules.length = 0; - } // inherit a function registry from the frames stack when possible; - // otherwise from the global registry - - - ruleset.functionRegistry = function (frames) { - var i = 0; - var n = frames.length; - var found; - - for (; i !== n; ++i) { - found = frames[i].functionRegistry; - - if (found) { - return found; - } + var mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0; + // Evaluate mixin calls. + for (i = 0; (rule = rsRules[i]); i++) { + if (rule.type === 'MixinCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope if the variable is + // already there. consider returning false here + // but we need a way to "return" variable from mixins + return !(ruleset.variable(r.name)); + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } + else if (rule.type === 'VariableCall') { + /* jshint loopfunc:true */ + rules = rule.eval(context).rules.filter(function (r) { + if ((r instanceof Declaration) && r.variable) { + // do not pollute the scope at all + return false; + } + return true; + }); + rsRules.splice.apply(rsRules, [i, 1].concat(rules)); + i += rules.length - 1; + ruleset.resetCache(); + } } - - return functionRegistry; - }(context.frames).inherit(); // push the current ruleset to the frames stack - - - var ctxFrames = context.frames; - ctxFrames.unshift(ruleset); // currrent selectors - - var ctxSelectors = context.selectors; - - if (!ctxSelectors) { - context.selectors = ctxSelectors = []; - } - - ctxSelectors.unshift(this.selectors); // Evaluate imports - - if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) { - ruleset.evalImports(context); - } // Store the frames around mixin definitions, - // so they can be evaluated like closures when the time comes. - - - var rsRules = ruleset.rules; - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.evalFirst) { - rsRules[i] = rule.eval(context); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + if (!rule.evalFirst) { + rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + } } - } - - var mediaBlockCount = context.mediaBlocks && context.mediaBlocks.length || 0; // Evaluate mixin calls. - - for (i = 0; rule = rsRules[i]; i++) { - if (rule.type === 'MixinCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope if the variable is - // already there. consider returning false here - // but we need a way to "return" variable from mixins - return !ruleset.variable(r.name); + // Evaluate everything else + for (i = 0; (rule = rsRules[i]); i++) { + // for rulesets, check if it is a css guard and can be removed + if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { + // check if it can be folded in (e.g. & where) + if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { + rsRules.splice(i--, 1); + for (var j = 0; (subRule = rule.rules[j]); j++) { + if (subRule instanceof Node) { + subRule.copyVisibilityInfo(rule.visibilityInfo()); + if (!(subRule instanceof Declaration) || !subRule.variable) { + rsRules.splice(++i, 0, subRule); + } + } + } + } } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); - } else if (rule.type === 'VariableCall') { - /* jshint loopfunc:true */ - rules = rule.eval(context).rules.filter(function (r) { - if (r instanceof Declaration && r.variable) { - // do not pollute the scope at all - return false; + } + // Pop the stack + ctxFrames.shift(); + ctxSelectors.shift(); + if (context.mediaBlocks) { + for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { + context.mediaBlocks[i].bubbleSelectors(selectors); } - - return true; - }); - rsRules.splice.apply(rsRules, _toConsumableArray([i, 1].concat(rules))); - i += rules.length - 1; - ruleset.resetCache(); } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - if (!rule.evalFirst) { - rsRules[i] = rule = rule.eval ? rule.eval(context) : rule; + return ruleset; + }; + Ruleset.prototype.evalImports = function (context) { + var rules = this.rules; + var i; + var importRules; + if (!rules) { + return; } - } // Evaluate everything else - - - for (i = 0; rule = rsRules[i]; i++) { - // for rulesets, check if it is a css guard and can be removed - if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) { - // check if it can be folded in (e.g. & where) - if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) { - rsRules.splice(i--, 1); - - for (var j = 0; subRule = rule.rules[j]; j++) { - if (subRule instanceof Node) { - subRule.copyVisibilityInfo(rule.visibilityInfo()); - - if (!(subRule instanceof Declaration) || !subRule.variable) { - rsRules.splice(++i, 0, subRule); + for (i = 0; i < rules.length; i++) { + if (rules[i].type === 'Import') { + importRules = rules[i].eval(context); + if (importRules && (importRules.length || importRules.length === 0)) { + rules.splice.apply(rules, [i, 1].concat(importRules)); + i += importRules.length - 1; + } + else { + rules.splice(i, 1, importRules); } - } + this.resetCache(); } - } - } - } // Pop the stack - - - ctxFrames.shift(); - ctxSelectors.shift(); - - if (context.mediaBlocks) { - for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) { - context.mediaBlocks[i].bubbleSelectors(selectors); } - } - - return ruleset; - } - }, { - key: "evalImports", - value: function evalImports(context) { - var rules = this.rules; - var i; - var importRules; - - if (!rules) { - return; - } - - for (i = 0; i < rules.length; i++) { - if (rules[i].type === 'Import') { - importRules = rules[i].eval(context); - - if (importRules && (importRules.length || importRules.length === 0)) { - rules.splice.apply(rules, _toConsumableArray([i, 1].concat(importRules))); - i += importRules.length - 1; - } else { - rules.splice(i, 1, importRules); - } - - this.resetCache(); - } - } - } - }, { - key: "makeImportant", - value: function makeImportant() { - var result = new Ruleset(this.selectors, this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(); - } else { - return r; - } - }), this.strictImports, this.visibilityInfo()); - return result; - } - }, { - key: "matchArgs", - value: function matchArgs(args) { - return !args || args.length === 0; - } // lets you call a css selector with a guard - - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - var lastSelector = this.selectors[this.selectors.length - 1]; - - if (!lastSelector.evaldCondition) { - return false; - } - - if (lastSelector.condition && !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { - return false; - } - - return true; - } - }, { - key: "resetCache", - value: function resetCache() { - this._rulesets = null; - this._variables = null; - this._properties = null; - this._lookups = {}; - } - }, { - key: "variables", - value: function variables() { - if (!this._variables) { - this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable === true) { - hash[r.name] = r; - } // when evaluating variables in an import statement, imports have not been eval'd - // so we need to go inside import statements. - // guard against root being a string (in the case of inlined less) - - - if (r.type === 'Import' && r.root && r.root.variables) { - var vars = r.root.variables(); - - for (var name in vars) { - if (vars.hasOwnProperty(name)) { - hash[name] = r.root.variable(name); - } + }; + Ruleset.prototype.makeImportant = function () { + var result = new Ruleset(this.selectors, this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(); } - } - - return hash; - }, {}); - } - - return this._variables; - } - }, { - key: "properties", - value: function properties() { - if (!this._properties) { - this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { - if (r instanceof Declaration && r.variable !== true) { - var name = r.name.length === 1 && r.name[0] instanceof Keyword ? r.name[0].value : r.name; // Properties don't overwrite as they can merge - - if (!hash["$".concat(name)]) { - hash["$".concat(name)] = [r]; - } else { - hash["$".concat(name)].push(r); + else { + return r; } - } - - return hash; - }, {}); - } - - return this._properties; - } - }, { - key: "variable", - value: function variable(name) { - var decl = this.variables()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "property", - value: function property(name) { - var decl = this.properties()[name]; - - if (decl) { - return this.parseValue(decl); - } - } - }, { - key: "lastDeclaration", - value: function lastDeclaration() { - for (var i = this.rules.length; i > 0; i--) { - var decl = this.rules[i - 1]; - - if (decl instanceof Declaration) { - return this.parseValue(decl); - } - } - } - }, { - key: "parseValue", - value: function parseValue(toParse) { - var self = this; - - function transformDeclaration(decl) { - if (decl.value instanceof Anonymous && !decl.parsed) { - if (typeof decl.value.value === 'string') { - this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { - if (err) { - decl.parsed = true; - } - - if (result) { - decl.value = result[0]; - decl.important = result[1] || ''; - decl.parsed = true; - } - }); - } else { - decl.parsed = true; - } - - return decl; - } else { - return decl; + }), this.strictImports, this.visibilityInfo()); + return result; + }; + Ruleset.prototype.matchArgs = function (args) { + return !args || args.length === 0; + }; + // lets you call a css selector with a guard + Ruleset.prototype.matchCondition = function (args, context) { + var lastSelector = this.selectors[this.selectors.length - 1]; + if (!lastSelector.evaldCondition) { + return false; } - } - - if (!Array.isArray(toParse)) { - return transformDeclaration.call(self, toParse); - } else { - var nodes = []; - toParse.forEach(function (n) { - nodes.push(transformDeclaration.call(self, n)); - }); - return nodes; - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (!this.rules) { - return []; - } - - var filtRules = []; - var rules = this.rules; - var i; - var rule; - - for (i = 0; rule = rules[i]; i++) { - if (rule.isRuleset) { - filtRules.push(rule); + if (lastSelector.condition && + !lastSelector.condition.eval(new contexts.Eval(context, context.frames))) { + return false; } - } - - return filtRules; - } - }, { - key: "prependRule", - value: function prependRule(rule) { - var rules = this.rules; - - if (rules) { - rules.unshift(rule); - } else { - this.rules = [rule]; - } - - this.setParent(rule, this); - } - }, { - key: "find", - value: function find(selector) { - var self = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this; - var filter = arguments.length > 2 ? arguments[2] : undefined; - var rules = []; - var match; - var foundMixins; - var key = selector.toCSS(); - - if (key in this._lookups) { - return this._lookups[key]; - } - - this.rulesets().forEach(function (rule) { - if (rule !== self) { - for (var j = 0; j < rule.selectors.length; j++) { - match = selector.match(rule.selectors[j]); - - if (match) { - if (selector.elements.length > match) { - if (!filter || filter(rule)) { - foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); - - for (var i = 0; i < foundMixins.length; ++i) { - foundMixins[i].path.push(rule); - } - - Array.prototype.push.apply(rules, foundMixins); + return true; + }; + Ruleset.prototype.resetCache = function () { + this._rulesets = null; + this._variables = null; + this._properties = null; + this._lookups = {}; + }; + Ruleset.prototype.variables = function () { + if (!this._variables) { + this._variables = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable === true) { + hash[r.name] = r; } - } else { - rules.push({ - rule: rule, - path: [] - }); - } - - break; - } - } - } - }); - this._lookups[key] = rules; - return rules; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var i; - var j; - var charsetRuleNodes = []; - var ruleNodes = []; - var // Line number debugging - debugInfo$1; - var rule; - var path; - context.tabLevel = context.tabLevel || 0; - - if (!this.root) { - context.tabLevel++; - } - - var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); - var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); - var sep; - var charsetNodeIndex = 0; - var importNodeIndex = 0; - - for (i = 0; rule = this.rules[i]; i++) { - if (rule instanceof Comment) { - if (importNodeIndex === i) { - importNodeIndex++; - } - - ruleNodes.push(rule); - } else if (rule.isCharset && rule.isCharset()) { - ruleNodes.splice(charsetNodeIndex, 0, rule); - charsetNodeIndex++; - importNodeIndex++; - } else if (rule.type === 'Import') { - ruleNodes.splice(importNodeIndex, 0, rule); - importNodeIndex++; - } else { - ruleNodes.push(rule); - } - } - - ruleNodes = charsetRuleNodes.concat(ruleNodes); // If this is the root node, we don't render - // a selector, or {}. - - if (!this.root) { - debugInfo$1 = debugInfo(context, this, tabSetStr); - - if (debugInfo$1) { - output.add(debugInfo$1); - output.add(tabSetStr); - } - - var paths = this.paths; - var pathCnt = paths.length; - var pathSubCnt; - sep = context.compress ? ',' : ",\n".concat(tabSetStr); - - for (i = 0; i < pathCnt; i++) { - path = paths[i]; - - if (!(pathSubCnt = path.length)) { - continue; - } - - if (i > 0) { - output.add(sep); - } - - context.firstSelector = true; - path[0].genCSS(context, output); - context.firstSelector = false; - - for (j = 1; j < pathSubCnt; j++) { - path[j].genCSS(context, output); - } + // when evaluating variables in an import statement, imports have not been eval'd + // so we need to go inside import statements. + // guard against root being a string (in the case of inlined less) + if (r.type === 'Import' && r.root && r.root.variables) { + var vars = r.root.variables(); + for (var name_1 in vars) { + if (vars.hasOwnProperty(name_1)) { + hash[name_1] = r.root.variable(name_1); + } + } + } + return hash; + }, {}); } - - output.add((context.compress ? '{' : ' {\n') + tabRuleStr); - } // Compile rules and rulesets - - - for (i = 0; rule = ruleNodes[i]; i++) { - if (i + 1 === ruleNodes.length) { - context.lastRule = true; + return this._variables; + }; + Ruleset.prototype.properties = function () { + if (!this._properties) { + this._properties = !this.rules ? {} : this.rules.reduce(function (hash, r) { + if (r instanceof Declaration && r.variable !== true) { + var name_2 = (r.name.length === 1) && (r.name[0] instanceof Keyword) ? + r.name[0].value : r.name; + // Properties don't overwrite as they can merge + if (!hash["$" + name_2]) { + hash["$" + name_2] = [r]; + } + else { + hash["$" + name_2].push(r); + } + } + return hash; + }, {}); } - - var currentLastRule = context.lastRule; - - if (rule.isRulesetLike(rule)) { - context.lastRule = false; + return this._properties; + }; + Ruleset.prototype.variable = function (name) { + var decl = this.variables()[name]; + if (decl) { + return this.parseValue(decl); } - - if (rule.genCSS) { - rule.genCSS(context, output); - } else if (rule.value) { - output.add(rule.value.toString()); + }; + Ruleset.prototype.property = function (name) { + var decl = this.properties()[name]; + if (decl) { + return this.parseValue(decl); } - - context.lastRule = currentLastRule; - - if (!context.lastRule && rule.isVisible()) { - output.add(context.compress ? '' : "\n".concat(tabRuleStr)); - } else { - context.lastRule = false; + }; + Ruleset.prototype.lastDeclaration = function () { + for (var i_1 = this.rules.length; i_1 > 0; i_1--) { + var decl = this.rules[i_1 - 1]; + if (decl instanceof Declaration) { + return this.parseValue(decl); + } } - } - - if (!this.root) { - output.add(context.compress ? '}' : "\n".concat(tabSetStr, "}")); - context.tabLevel--; - } - - if (!output.isEmpty() && !context.compress && this.firstRoot) { - output.add('\n'); - } - } - }, { - key: "joinSelectors", - value: function joinSelectors(paths, context, selectors) { - for (var s = 0; s < selectors.length; s++) { - this.joinSelector(paths, context, selectors[s]); - } - } - }, { - key: "joinSelector", - value: function joinSelector(paths, context, selector) { - function createParenthesis(elementsToPak, originalElement) { - var replacementParen; - var j; - - if (elementsToPak.length === 0) { - replacementParen = new Paren(elementsToPak[0]); - } else { - var insideParent = new Array(elementsToPak.length); - - for (j = 0; j < elementsToPak.length; j++) { - insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); - } - - replacementParen = new Paren(new Selector(insideParent)); + }; + Ruleset.prototype.parseValue = function (toParse) { + var self = this; + function transformDeclaration(decl) { + if (decl.value instanceof Anonymous && !decl.parsed) { + if (typeof decl.value.value === 'string') { + this.parse.parseNode(decl.value.value, ['value', 'important'], decl.value.getIndex(), decl.fileInfo(), function (err, result) { + if (err) { + decl.parsed = true; + } + if (result) { + decl.value = result[0]; + decl.important = result[1] || ''; + decl.parsed = true; + } + }); + } + else { + decl.parsed = true; + } + return decl; + } + else { + return decl; + } } - - return replacementParen; - } - - function createSelector(containedElement, originalElement) { - var element; - var selector; - element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); - selector = new Selector([element]); - return selector; - } // joins selector path from `beginningPath` with selector path in `addPath` - // `replacedElement` contains element that is being replaced by `addPath` - // returns concatenated path - - - function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { - var newSelectorPath; - var lastSelector; - var newJoinedSelector; // our new selector path - - newSelectorPath = []; // construct the joined selector - if & is the first thing this will be empty, - // if not newJoinedSelector will be the last set of elements in the selector - - if (beginningPath.length > 0) { - newSelectorPath = copyArray(beginningPath); - lastSelector = newSelectorPath.pop(); - newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); - } else { - newJoinedSelector = originalSelector.createDerived([]); + if (!Array.isArray(toParse)) { + return transformDeclaration.call(self, toParse); } - - if (addPath.length > 0) { - // /deep/ is a CSS4 selector - (removed, so should deprecate) - // that is valid without anything in front of it - // so if the & does not have a combinator that is "" or " " then - // and there is a combinator on the parent, then grab that. - // this also allows + a { & .b { .a & { ... though not sure why you would want to do that - var combinator = replacedElement.combinator; - var parentEl = addPath[0].elements[0]; - - if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { - combinator = parentEl.combinator; - } // join the elements so far with the first part of the parent - - - newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); - newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); - } // now add the joined selector - but only if it is not empty - - - if (newJoinedSelector.elements.length !== 0) { - newSelectorPath.push(newJoinedSelector); - } // put together the parent selectors after the join (e.g. the rest of the parent) - - - if (addPath.length > 1) { - var restOfPath = addPath.slice(1); - restOfPath = restOfPath.map(function (selector) { - return selector.createDerived(selector.elements, []); - }); - newSelectorPath = newSelectorPath.concat(restOfPath); + else { + var nodes_1 = []; + toParse.forEach(function (n) { + nodes_1.push(transformDeclaration.call(self, n)); + }); + return nodes_1; } - - return newSelectorPath; - } // joins selector path from `beginningPath` with every selector path in `addPaths` array - // `replacedElement` contains element that is being replaced by `addPath` - // returns array with all concatenated paths - - - function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { - var j; - - for (j = 0; j < beginningPath.length; j++) { - var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); - result.push(newSelectorPath); + }; + Ruleset.prototype.rulesets = function () { + if (!this.rules) { + return []; } - - return result; - } - - function mergeElementsOnToSelectors(elements, selectors) { + var filtRules = []; + var rules = this.rules; var i; - var sel; - - if (elements.length === 0) { - return; + var rule; + for (i = 0; (rule = rules[i]); i++) { + if (rule.isRuleset) { + filtRules.push(rule); + } } - - if (selectors.length === 0) { - selectors.push([new Selector(elements)]); - return; + return filtRules; + }; + Ruleset.prototype.prependRule = function (rule) { + var rules = this.rules; + if (rules) { + rules.unshift(rule); } - - for (i = 0; sel = selectors[i]; i++) { - // if the previous thing in sel is a parent this needs to join on to it - if (sel.length > 0) { - sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); - } else { - sel.push(new Selector(elements)); - } - } - } // replace all parent selectors inside `inSelector` by content of `context` array - // resulting selectors are returned inside `paths` array - // returns true if `inSelector` contained at least one parent selector - - - function replaceParentSelector(paths, context, inSelector) { - // The paths are [[Selector]] - // The first list is a list of comma separated selectors - // The inner list is a list of inheritance separated selectors - // e.g. - // .a, .b { - // .c { - // } - // } - // == [[.a] [.c]] [[.b] [.c]] - // + else { + this.rules = [rule]; + } + this.setParent(rule, this); + }; + Ruleset.prototype.find = function (selector, self, filter) { + if (self === void 0) { self = this; } + var rules = []; + var match; + var foundMixins; + var key = selector.toCSS(); + if (key in this._lookups) { + return this._lookups[key]; + } + this.rulesets().forEach(function (rule) { + if (rule !== self) { + for (var j = 0; j < rule.selectors.length; j++) { + match = selector.match(rule.selectors[j]); + if (match) { + if (selector.elements.length > match) { + if (!filter || filter(rule)) { + foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter); + for (var i_2 = 0; i_2 < foundMixins.length; ++i_2) { + foundMixins[i_2].path.push(rule); + } + Array.prototype.push.apply(rules, foundMixins); + } + } + else { + rules.push({ rule: rule, path: [] }); + } + break; + } + } + } + }); + this._lookups[key] = rules; + return rules; + }; + Ruleset.prototype.genCSS = function (context, output) { var i; var j; - var k; - var currentElements; - var newSelectors; - var selectorsMultiplied; - var sel; - var el; - var hadParentSelector = false; - var length; - var lastSelector; - - function findNestedSelector(element) { - var maybeSelector; - - if (!(element.value instanceof Paren)) { - return null; - } - - maybeSelector = element.value.value; - - if (!(maybeSelector instanceof Selector)) { - return null; - } - - return maybeSelector; - } // the elements from the current selector so far - - - currentElements = []; // the current list of new selectors to add to the path. - // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors - // by the parents - - newSelectors = [[]]; - - for (i = 0; el = inSelector.elements[i]; i++) { - // non parent reference elements just get added - if (el.value !== '&') { - var nestedSelector = findNestedSelector(el); - - if (nestedSelector != null) { - // merge the current list of non parent selector elements - // on to the current list of selectors to add - mergeElementsOnToSelectors(currentElements, newSelectors); - var nestedPaths = []; - var replaced = void 0; - var replacedNewSelectors = []; - replaced = replaceParentSelector(nestedPaths, context, nestedSelector); - hadParentSelector = hadParentSelector || replaced; // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors - - for (k = 0; k < nestedPaths.length; k++) { - var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); - addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); - } - - newSelectors = replacedNewSelectors; - currentElements = []; - } else { - currentElements.push(el); + var charsetRuleNodes = []; + var ruleNodes = []; + var // Line number debugging + debugInfo$1; + var rule; + var path; + context.tabLevel = (context.tabLevel || 0); + if (!this.root) { + context.tabLevel++; + } + var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '); + var tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '); + var sep; + var charsetNodeIndex = 0; + var importNodeIndex = 0; + for (i = 0; (rule = this.rules[i]); i++) { + if (rule instanceof Comment) { + if (importNodeIndex === i) { + importNodeIndex++; + } + ruleNodes.push(rule); } - } else { - hadParentSelector = true; // the new list of selectors to add - - selectorsMultiplied = []; // merge the current list of non parent selector elements - // on to the current list of selectors to add - - mergeElementsOnToSelectors(currentElements, newSelectors); // loop through our current selectors - - for (j = 0; j < newSelectors.length; j++) { - sel = newSelectors[j]; // if we don't have any parent paths, the & might be in a mixin so that it can be used - // whether there are parents or not - - if (context.length === 0) { - // the combinator used on el should now be applied to the next element instead so that - // it is not lost - if (sel.length > 0) { - sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + else if (rule.isCharset && rule.isCharset()) { + ruleNodes.splice(charsetNodeIndex, 0, rule); + charsetNodeIndex++; + importNodeIndex++; + } + else if (rule.type === 'Import') { + ruleNodes.splice(importNodeIndex, 0, rule); + importNodeIndex++; + } + else { + ruleNodes.push(rule); + } + } + ruleNodes = charsetRuleNodes.concat(ruleNodes); + // If this is the root node, we don't render + // a selector, or {}. + if (!this.root) { + debugInfo$1 = debugInfo(context, this, tabSetStr); + if (debugInfo$1) { + output.add(debugInfo$1); + output.add(tabSetStr); + } + var paths = this.paths; + var pathCnt = paths.length; + var pathSubCnt = void 0; + sep = context.compress ? ',' : (",\n" + tabSetStr); + for (i = 0; i < pathCnt; i++) { + path = paths[i]; + if (!(pathSubCnt = path.length)) { + continue; } - - selectorsMultiplied.push(sel); - } else { - // and the parent selectors - for (k = 0; k < context.length; k++) { - // We need to put the current selectors - // then join the last selector's elements on to the parents selectors - var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); // add that to our new set of selectors - - selectorsMultiplied.push(newSelectorPath); + if (i > 0) { + output.add(sep); } - } - } // our new selectors has been multiplied, so reset the state - - - newSelectors = selectorsMultiplied; - currentElements = []; - } - } // if we have any elements left over (e.g. .a& .b == .b) - // add them on to all the current selectors - - - mergeElementsOnToSelectors(currentElements, newSelectors); - - for (i = 0; i < newSelectors.length; i++) { - length = newSelectors[i].length; - - if (length > 0) { - paths.push(newSelectors[i]); - lastSelector = newSelectors[i][length - 1]; - newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); - } + context.firstSelector = true; + path[0].genCSS(context, output); + context.firstSelector = false; + for (j = 1; j < pathSubCnt; j++) { + path[j].genCSS(context, output); + } + } + output.add((context.compress ? '{' : ' {\n') + tabRuleStr); } - - return hadParentSelector; - } - - function deriveSelector(visibilityInfo, deriveFrom) { - var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); - newSelector.copyVisibilityInfo(visibilityInfo); - return newSelector; - } // joinSelector code follows - - - var i; - var newPaths; - var hadParentSelector; - newPaths = []; - hadParentSelector = replaceParentSelector(newPaths, context, selector); - - if (!hadParentSelector) { - if (context.length > 0) { - newPaths = []; - - for (i = 0; i < context.length; i++) { - var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); - concatenated.push(selector); - newPaths.push(concatenated); - } - } else { - newPaths = [[selector]]; - } - } - - for (i = 0; i < newPaths.length; i++) { - paths.push(newPaths[i]); - } - } - }]); - - return Ruleset; - }(Node); - + // Compile rules and rulesets + for (i = 0; (rule = ruleNodes[i]); i++) { + if (i + 1 === ruleNodes.length) { + context.lastRule = true; + } + var currentLastRule = context.lastRule; + if (rule.isRulesetLike(rule)) { + context.lastRule = false; + } + if (rule.genCSS) { + rule.genCSS(context, output); + } + else if (rule.value) { + output.add(rule.value.toString()); + } + context.lastRule = currentLastRule; + if (!context.lastRule && rule.isVisible()) { + output.add(context.compress ? '' : ("\n" + tabRuleStr)); + } + else { + context.lastRule = false; + } + } + if (!this.root) { + output.add((context.compress ? '}' : "\n" + tabSetStr + "}")); + context.tabLevel--; + } + if (!output.isEmpty() && !context.compress && this.firstRoot) { + output.add('\n'); + } + }; + Ruleset.prototype.joinSelectors = function (paths, context, selectors) { + for (var s = 0; s < selectors.length; s++) { + this.joinSelector(paths, context, selectors[s]); + } + }; + Ruleset.prototype.joinSelector = function (paths, context, selector) { + function createParenthesis(elementsToPak, originalElement) { + var replacementParen; + var j; + if (elementsToPak.length === 0) { + replacementParen = new Paren(elementsToPak[0]); + } + else { + var insideParent = new Array(elementsToPak.length); + for (j = 0; j < elementsToPak.length; j++) { + insideParent[j] = new Element(null, elementsToPak[j], originalElement.isVariable, originalElement._index, originalElement._fileInfo); + } + replacementParen = new Paren(new Selector(insideParent)); + } + return replacementParen; + } + function createSelector(containedElement, originalElement) { + var element; + var selector; + element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo); + selector = new Selector([element]); + return selector; + } + // joins selector path from `beginningPath` with selector path in `addPath` + // `replacedElement` contains element that is being replaced by `addPath` + // returns concatenated path + function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) { + var newSelectorPath; + var lastSelector; + var newJoinedSelector; + // our new selector path + newSelectorPath = []; + // construct the joined selector - if & is the first thing this will be empty, + // if not newJoinedSelector will be the last set of elements in the selector + if (beginningPath.length > 0) { + newSelectorPath = copyArray(beginningPath); + lastSelector = newSelectorPath.pop(); + newJoinedSelector = originalSelector.createDerived(copyArray(lastSelector.elements)); + } + else { + newJoinedSelector = originalSelector.createDerived([]); + } + if (addPath.length > 0) { + // /deep/ is a CSS4 selector - (removed, so should deprecate) + // that is valid without anything in front of it + // so if the & does not have a combinator that is "" or " " then + // and there is a combinator on the parent, then grab that. + // this also allows + a { & .b { .a & { ... though not sure why you would want to do that + var combinator = replacedElement.combinator; + var parentEl = addPath[0].elements[0]; + if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) { + combinator = parentEl.combinator; + } + // join the elements so far with the first part of the parent + newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement.isVariable, replacedElement._index, replacedElement._fileInfo)); + newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1)); + } + // now add the joined selector - but only if it is not empty + if (newJoinedSelector.elements.length !== 0) { + newSelectorPath.push(newJoinedSelector); + } + // put together the parent selectors after the join (e.g. the rest of the parent) + if (addPath.length > 1) { + var restOfPath = addPath.slice(1); + restOfPath = restOfPath.map(function (selector) { return selector.createDerived(selector.elements, []); }); + newSelectorPath = newSelectorPath.concat(restOfPath); + } + return newSelectorPath; + } + // joins selector path from `beginningPath` with every selector path in `addPaths` array + // `replacedElement` contains element that is being replaced by `addPath` + // returns array with all concatenated paths + function addAllReplacementsIntoPath(beginningPath, addPaths, replacedElement, originalSelector, result) { + var j; + for (j = 0; j < beginningPath.length; j++) { + var newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector); + result.push(newSelectorPath); + } + return result; + } + function mergeElementsOnToSelectors(elements, selectors) { + var i; + var sel; + if (elements.length === 0) { + return; + } + if (selectors.length === 0) { + selectors.push([new Selector(elements)]); + return; + } + for (i = 0; (sel = selectors[i]); i++) { + // if the previous thing in sel is a parent this needs to join on to it + if (sel.length > 0) { + sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements)); + } + else { + sel.push(new Selector(elements)); + } + } + } + // replace all parent selectors inside `inSelector` by content of `context` array + // resulting selectors are returned inside `paths` array + // returns true if `inSelector` contained at least one parent selector + function replaceParentSelector(paths, context, inSelector) { + // The paths are [[Selector]] + // The first list is a list of comma separated selectors + // The inner list is a list of inheritance separated selectors + // e.g. + // .a, .b { + // .c { + // } + // } + // == [[.a] [.c]] [[.b] [.c]] + // + var i; + var j; + var k; + var currentElements; + var newSelectors; + var selectorsMultiplied; + var sel; + var el; + var hadParentSelector = false; + var length; + var lastSelector; + function findNestedSelector(element) { + var maybeSelector; + if (!(element.value instanceof Paren)) { + return null; + } + maybeSelector = element.value.value; + if (!(maybeSelector instanceof Selector)) { + return null; + } + return maybeSelector; + } + // the elements from the current selector so far + currentElements = []; + // the current list of new selectors to add to the path. + // We will build it up. We initiate it with one empty selector as we "multiply" the new selectors + // by the parents + newSelectors = [ + [] + ]; + for (i = 0; (el = inSelector.elements[i]); i++) { + // non parent reference elements just get added + if (el.value !== '&') { + var nestedSelector = findNestedSelector(el); + if (nestedSelector != null) { + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + var nestedPaths = []; + var replaced = void 0; + var replacedNewSelectors = []; + replaced = replaceParentSelector(nestedPaths, context, nestedSelector); + hadParentSelector = hadParentSelector || replaced; + // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors + for (k = 0; k < nestedPaths.length; k++) { + var replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el); + addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors); + } + newSelectors = replacedNewSelectors; + currentElements = []; + } + else { + currentElements.push(el); + } + } + else { + hadParentSelector = true; + // the new list of selectors to add + selectorsMultiplied = []; + // merge the current list of non parent selector elements + // on to the current list of selectors to add + mergeElementsOnToSelectors(currentElements, newSelectors); + // loop through our current selectors + for (j = 0; j < newSelectors.length; j++) { + sel = newSelectors[j]; + // if we don't have any parent paths, the & might be in a mixin so that it can be used + // whether there are parents or not + if (context.length === 0) { + // the combinator used on el should now be applied to the next element instead so that + // it is not lost + if (sel.length > 0) { + sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo)); + } + selectorsMultiplied.push(sel); + } + else { + // and the parent selectors + for (k = 0; k < context.length; k++) { + // We need to put the current selectors + // then join the last selector's elements on to the parents selectors + var newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector); + // add that to our new set of selectors + selectorsMultiplied.push(newSelectorPath); + } + } + } + // our new selectors has been multiplied, so reset the state + newSelectors = selectorsMultiplied; + currentElements = []; + } + } + // if we have any elements left over (e.g. .a& .b == .b) + // add them on to all the current selectors + mergeElementsOnToSelectors(currentElements, newSelectors); + for (i = 0; i < newSelectors.length; i++) { + length = newSelectors[i].length; + if (length > 0) { + paths.push(newSelectors[i]); + lastSelector = newSelectors[i][length - 1]; + newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList); + } + } + return hadParentSelector; + } + function deriveSelector(visibilityInfo, deriveFrom) { + var newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition); + newSelector.copyVisibilityInfo(visibilityInfo); + return newSelector; + } + // joinSelector code follows + var i; + var newPaths; + var hadParentSelector; + newPaths = []; + hadParentSelector = replaceParentSelector(newPaths, context, selector); + if (!hadParentSelector) { + if (context.length > 0) { + newPaths = []; + for (i = 0; i < context.length; i++) { + var concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo())); + concatenated.push(selector); + newPaths.push(concatenated); + } + } + else { + newPaths = [[selector]]; + } + } + for (i = 0; i < newPaths.length; i++) { + paths.push(newPaths[i]); + } + }; + return Ruleset; + }(Node)); Ruleset.prototype.type = 'Ruleset'; Ruleset.prototype.isRuleset = true; - var AtRule = - /*#__PURE__*/ - function (_Node) { - _inherits(AtRule, _Node); - - function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { - var _this; - - _classCallCheck(this, AtRule); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(AtRule).call(this)); - var i; - _this.name = name; - _this.value = value instanceof Node ? value : value ? new Anonymous(value) : value; - - if (rules) { - if (Array.isArray(rules)) { - _this.rules = rules; - } else { - _this.rules = [rules]; - _this.rules[0].selectors = new Selector([], null, null, index, currentFileInfo).createEmptySelectors(); - } - - for (i = 0; i < _this.rules.length; i++) { - _this.rules[i].allowImports = true; - } - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - } - - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.debugInfo = debugInfo; - _this.isRooted = isRooted || false; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(AtRule, [{ - key: "accept", - value: function accept(visitor) { - var value = this.value; - var rules = this.rules; - - if (rules) { - this.rules = visitor.visitArray(rules); - } - - if (value) { - this.value = visitor.visit(value); - } - } - }, { - key: "isRulesetLike", - value: function isRulesetLike() { - return this.rules || !this.isCharset(); - } - }, { - key: "isCharset", - value: function isCharset() { - return '@charset' === this.name; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - var value = this.value; - var rules = this.rules; - output.add(this.name, this.fileInfo(), this.getIndex()); - - if (value) { - output.add(' '); - value.genCSS(context, output); - } - - if (rules) { - this.outputRuleset(context, output, rules); - } else { - output.add(';'); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mediaPathBackup; - var mediaBlocksBackup; - var value = this.value; - var rules = this.rules; // media stored inside other atrule should not bubble over it - // backpup media bubbling information - - mediaPathBackup = context.mediaPath; - mediaBlocksBackup = context.mediaBlocks; // deleted media bubbling information - - context.mediaPath = []; - context.mediaBlocks = []; - - if (value) { - value = value.eval(context); - } - - if (rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - rules = [rules[0].eval(context)]; - rules[0].root = true; - } // restore media bubbling information - - - context.mediaPath = mediaPathBackup; - context.mediaBlocks = mediaBlocksBackup; - return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); - } - }, { - key: "variable", - value: function variable(name) { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.variable.call(this.rules[0], name); - } - } - }, { - key: "find", - value: function find() { - if (this.rules) { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; + var AtRule = /** @class */ (function (_super) { + __extends(AtRule, _super); + function AtRule(name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) { + var _this = _super.call(this) || this; + var i; + _this.name = name; + _this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value); + if (rules) { + if (Array.isArray(rules)) { + _this.rules = rules; + } + else { + _this.rules = [rules]; + _this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors(); + } + for (i = 0; i < _this.rules.length; i++) { + _this.rules[i].allowImports = true; + } + _this.setParent(_this.rules, _this); + } + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.debugInfo = debugInfo; + _this.isRooted = isRooted || false; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + AtRule.prototype.accept = function (visitor) { + var value = this.value; + var rules = this.rules; + if (rules) { + this.rules = visitor.visitArray(rules); } - - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.find.apply(this.rules[0], args); - } - } - }, { - key: "rulesets", - value: function rulesets() { - if (this.rules) { - // assuming that there is only one rule at this point - that is how parser constructs the rule - return Ruleset.prototype.rulesets.apply(this.rules[0]); - } - } - }, { - key: "outputRuleset", - value: function outputRuleset(context, output, rules) { - var ruleCnt = rules.length; - var i; - context.tabLevel = (context.tabLevel | 0) + 1; // Compressed - - if (context.compress) { - output.add('{'); - - for (i = 0; i < ruleCnt; i++) { - rules[i].genCSS(context, output); + if (value) { + this.value = visitor.visit(value); } - - output.add('}'); - context.tabLevel--; - return; - } // Non-compressed - - - var tabSetStr = "\n".concat(Array(context.tabLevel).join(' ')); - var tabRuleStr = "".concat(tabSetStr, " "); - - if (!ruleCnt) { - output.add(" {".concat(tabSetStr, "}")); - } else { - output.add(" {".concat(tabRuleStr)); - rules[0].genCSS(context, output); - - for (i = 1; i < ruleCnt; i++) { - output.add(tabRuleStr); - rules[i].genCSS(context, output); + }; + AtRule.prototype.isRulesetLike = function () { + return this.rules || !this.isCharset(); + }; + AtRule.prototype.isCharset = function () { + return '@charset' === this.name; + }; + AtRule.prototype.genCSS = function (context, output) { + var value = this.value; + var rules = this.rules; + output.add(this.name, this.fileInfo(), this.getIndex()); + if (value) { + output.add(' '); + value.genCSS(context, output); } - - output.add("".concat(tabSetStr, "}")); - } - - context.tabLevel--; - } - }]); - - return AtRule; - }(Node); - + if (rules) { + this.outputRuleset(context, output, rules); + } + else { + output.add(';'); + } + }; + AtRule.prototype.eval = function (context) { + var mediaPathBackup; + var mediaBlocksBackup; + var value = this.value; + var rules = this.rules; + // media stored inside other atrule should not bubble over it + // backpup media bubbling information + mediaPathBackup = context.mediaPath; + mediaBlocksBackup = context.mediaBlocks; + // deleted media bubbling information + context.mediaPath = []; + context.mediaBlocks = []; + if (value) { + value = value.eval(context); + } + if (rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + rules = [rules[0].eval(context)]; + rules[0].root = true; + } + // restore media bubbling information + context.mediaPath = mediaPathBackup; + context.mediaBlocks = mediaBlocksBackup; + return new AtRule(this.name, value, rules, this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo()); + }; + AtRule.prototype.variable = function (name) { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.variable.call(this.rules[0], name); + } + }; + AtRule.prototype.find = function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.find.apply(this.rules[0], args); + } + }; + AtRule.prototype.rulesets = function () { + if (this.rules) { + // assuming that there is only one rule at this point - that is how parser constructs the rule + return Ruleset.prototype.rulesets.apply(this.rules[0]); + } + }; + AtRule.prototype.outputRuleset = function (context, output, rules) { + var ruleCnt = rules.length; + var i; + context.tabLevel = (context.tabLevel | 0) + 1; + // Compressed + if (context.compress) { + output.add('{'); + for (i = 0; i < ruleCnt; i++) { + rules[i].genCSS(context, output); + } + output.add('}'); + context.tabLevel--; + return; + } + // Non-compressed + var tabSetStr = "\n" + Array(context.tabLevel).join(' '); + var tabRuleStr = tabSetStr + " "; + if (!ruleCnt) { + output.add(" {" + tabSetStr + "}"); + } + else { + output.add(" {" + tabRuleStr); + rules[0].genCSS(context, output); + for (i = 1; i < ruleCnt; i++) { + output.add(tabRuleStr); + rules[i].genCSS(context, output); + } + output.add(tabSetStr + "}"); + } + context.tabLevel--; + }; + return AtRule; + }(Node)); AtRule.prototype.type = 'AtRule'; - var DetachedRuleset = - /*#__PURE__*/ - function (_Node) { - _inherits(DetachedRuleset, _Node); - - function DetachedRuleset(ruleset, frames) { - var _this; - - _classCallCheck(this, DetachedRuleset); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(DetachedRuleset).call(this)); - _this.ruleset = ruleset; - _this.frames = frames; - - _this.setParent(_this.ruleset, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(DetachedRuleset, [{ - key: "accept", - value: function accept(visitor) { - this.ruleset = visitor.visit(this.ruleset); - } - }, { - key: "eval", - value: function _eval(context) { - var frames = this.frames || copyArray(context.frames); - return new DetachedRuleset(this.ruleset, frames); - } - }, { - key: "callEval", - value: function callEval(context) { - return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); - } - }]); - - return DetachedRuleset; - }(Node); - + var DetachedRuleset = /** @class */ (function (_super) { + __extends(DetachedRuleset, _super); + function DetachedRuleset(ruleset, frames) { + var _this = _super.call(this) || this; + _this.ruleset = ruleset; + _this.frames = frames; + _this.setParent(_this.ruleset, _this); + return _this; + } + DetachedRuleset.prototype.accept = function (visitor) { + this.ruleset = visitor.visit(this.ruleset); + }; + DetachedRuleset.prototype.eval = function (context) { + var frames = this.frames || copyArray(context.frames); + return new DetachedRuleset(this.ruleset, frames); + }; + DetachedRuleset.prototype.callEval = function (context) { + return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context); + }; + return DetachedRuleset; + }(Node)); DetachedRuleset.prototype.type = 'DetachedRuleset'; DetachedRuleset.prototype.evalFirst = true; - var Unit = - /*#__PURE__*/ - function (_Node) { - _inherits(Unit, _Node); - - function Unit(numerator, denominator, backupUnit) { - var _this; - - _classCallCheck(this, Unit); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Unit).call(this)); - _this.numerator = numerator ? copyArray(numerator).sort() : []; - _this.denominator = denominator ? copyArray(denominator).sort() : []; - - if (backupUnit) { - _this.backupUnit = backupUnit; - } else if (numerator && numerator.length) { - _this.backupUnit = numerator[0]; + var Unit = /** @class */ (function (_super) { + __extends(Unit, _super); + function Unit(numerator, denominator, backupUnit) { + var _this = _super.call(this) || this; + _this.numerator = numerator ? copyArray(numerator).sort() : []; + _this.denominator = denominator ? copyArray(denominator).sort() : []; + if (backupUnit) { + _this.backupUnit = backupUnit; + } + else if (numerator && numerator.length) { + _this.backupUnit = numerator[0]; + } + return _this; } - - return _this; - } - - _createClass(Unit, [{ - key: "clone", - value: function clone() { - return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - // Dimension checks the unit is singular and throws an error if in strict math mode. - var strictUnits = context && context.strictUnits; - - if (this.numerator.length === 1) { - output.add(this.numerator[0]); // the ideal situation - } else if (!strictUnits && this.backupUnit) { - output.add(this.backupUnit); - } else if (!strictUnits && this.denominator.length) { - output.add(this.denominator[0]); - } - } - }, { - key: "toString", - value: function toString() { - var i; - var returnStr = this.numerator.join('*'); - - for (i = 0; i < this.denominator.length; i++) { - returnStr += "/".concat(this.denominator[i]); - } - - return returnStr; - } - }, { - key: "compare", - value: function compare(other) { - return this.is(other.toString()) ? 0 : undefined; - } - }, { - key: "is", - value: function is(unitString) { - return this.toString().toUpperCase() === unitString.toUpperCase(); - } - }, { - key: "isLength", - value: function isLength() { - return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this.numerator.length === 0 && this.denominator.length === 0; - } - }, { - key: "isSingular", - value: function isSingular() { - return this.numerator.length <= 1 && this.denominator.length === 0; - } - }, { - key: "map", - value: function map(callback) { - var i; - - for (i = 0; i < this.numerator.length; i++) { - this.numerator[i] = callback(this.numerator[i], false); - } - - for (i = 0; i < this.denominator.length; i++) { - this.denominator[i] = callback(this.denominator[i], true); - } - } - }, { - key: "usedUnits", - value: function usedUnits() { - var group; - var result = {}; - var mapUnit; - var groupName; - - mapUnit = function mapUnit(atomicUnit) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { - result[groupName] = atomicUnit; + Unit.prototype.clone = function () { + return new Unit(copyArray(this.numerator), copyArray(this.denominator), this.backupUnit); + }; + Unit.prototype.genCSS = function (context, output) { + // Dimension checks the unit is singular and throws an error if in strict math mode. + var strictUnits = context && context.strictUnits; + if (this.numerator.length === 1) { + output.add(this.numerator[0]); // the ideal situation } - - return atomicUnit; - }; - - for (groupName in unitConversions) { - if (unitConversions.hasOwnProperty(groupName)) { - group = unitConversions[groupName]; - this.map(mapUnit); + else if (!strictUnits && this.backupUnit) { + output.add(this.backupUnit); } - } - - return result; - } - }, { - key: "cancel", - value: function cancel() { - var counter = {}; - var atomicUnit; - var i; - - for (i = 0; i < this.numerator.length; i++) { - atomicUnit = this.numerator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; - } - - for (i = 0; i < this.denominator.length; i++) { - atomicUnit = this.denominator[i]; - counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; - } - - this.numerator = []; - this.denominator = []; - - for (atomicUnit in counter) { - if (counter.hasOwnProperty(atomicUnit)) { - var count = counter[atomicUnit]; - - if (count > 0) { - for (i = 0; i < count; i++) { - this.numerator.push(atomicUnit); + else if (!strictUnits && this.denominator.length) { + output.add(this.denominator[0]); + } + }; + Unit.prototype.toString = function () { + var i; + var returnStr = this.numerator.join('*'); + for (i = 0; i < this.denominator.length; i++) { + returnStr += "/" + this.denominator[i]; + } + return returnStr; + }; + Unit.prototype.compare = function (other) { + return this.is(other.toString()) ? 0 : undefined; + }; + Unit.prototype.is = function (unitString) { + return this.toString().toUpperCase() === unitString.toUpperCase(); + }; + Unit.prototype.isLength = function () { + return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS()); + }; + Unit.prototype.isEmpty = function () { + return this.numerator.length === 0 && this.denominator.length === 0; + }; + Unit.prototype.isSingular = function () { + return this.numerator.length <= 1 && this.denominator.length === 0; + }; + Unit.prototype.map = function (callback) { + var i; + for (i = 0; i < this.numerator.length; i++) { + this.numerator[i] = callback(this.numerator[i], false); + } + for (i = 0; i < this.denominator.length; i++) { + this.denominator[i] = callback(this.denominator[i], true); + } + }; + Unit.prototype.usedUnits = function () { + var group; + var result = {}; + var mapUnit; + var groupName; + mapUnit = function (atomicUnit) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit) && !result[groupName]) { + result[groupName] = atomicUnit; } - } else if (count < 0) { - for (i = 0; i < -count; i++) { - this.denominator.push(atomicUnit); + return atomicUnit; + }; + for (groupName in unitConversions) { + if (unitConversions.hasOwnProperty(groupName)) { + group = unitConversions[groupName]; + this.map(mapUnit); } - } } - } - - this.numerator.sort(); - this.denominator.sort(); - } - }]); - - return Unit; - }(Node); - + return result; + }; + Unit.prototype.cancel = function () { + var counter = {}; + var atomicUnit; + var i; + for (i = 0; i < this.numerator.length; i++) { + atomicUnit = this.numerator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) + 1; + } + for (i = 0; i < this.denominator.length; i++) { + atomicUnit = this.denominator[i]; + counter[atomicUnit] = (counter[atomicUnit] || 0) - 1; + } + this.numerator = []; + this.denominator = []; + for (atomicUnit in counter) { + if (counter.hasOwnProperty(atomicUnit)) { + var count = counter[atomicUnit]; + if (count > 0) { + for (i = 0; i < count; i++) { + this.numerator.push(atomicUnit); + } + } + else if (count < 0) { + for (i = 0; i < -count; i++) { + this.denominator.push(atomicUnit); + } + } + } + } + this.numerator.sort(); + this.denominator.sort(); + }; + return Unit; + }(Node)); Unit.prototype.type = 'Unit'; + // // A number with a unit // - - var Dimension = - /*#__PURE__*/ - function (_Node) { - _inherits(Dimension, _Node); - - function Dimension(value, unit) { - var _this; - - _classCallCheck(this, Dimension); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Dimension).call(this)); - _this.value = parseFloat(value); - - if (isNaN(_this.value)) { - throw new Error('Dimension is not a number.'); - } - - _this.unit = unit && unit instanceof Unit ? unit : new Unit(unit ? [unit] : undefined); - - _this.setParent(_this.unit, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Dimension, [{ - key: "accept", - value: function accept(visitor) { - this.unit = visitor.visit(this.unit); - } - }, { - key: "eval", - value: function _eval(context) { - return this; - } - }, { - key: "toColor", - value: function toColor() { - return new Color([this.value, this.value, this.value]); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (context && context.strictUnits && !this.unit.isSingular()) { - throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: ".concat(this.unit.toString())); - } - - var value = this.fround(context, this.value); - var strValue = String(value); - - if (value !== 0 && value < 0.000001 && value > -0.000001) { - // would be output 1e-6 etc. - strValue = value.toFixed(20).replace(/0+$/, ''); - } - - if (context && context.compress) { - // Zero values doesn't need a unit - if (value === 0 && this.unit.isLength()) { - output.add(strValue); - return; - } // Float values doesn't need a leading zero - - - if (value > 0 && value < 1) { - strValue = strValue.substr(1); + var Dimension = /** @class */ (function (_super) { + __extends(Dimension, _super); + function Dimension(value, unit) { + var _this = _super.call(this) || this; + _this.value = parseFloat(value); + if (isNaN(_this.value)) { + throw new Error('Dimension is not a number.'); + } + _this.unit = (unit && unit instanceof Unit) ? unit : + new Unit(unit ? [unit] : undefined); + _this.setParent(_this.unit, _this); + return _this; + } + Dimension.prototype.accept = function (visitor) { + this.unit = visitor.visit(this.unit); + }; + Dimension.prototype.eval = function (context) { + return this; + }; + Dimension.prototype.toColor = function () { + return new Color([this.value, this.value, this.value]); + }; + Dimension.prototype.genCSS = function (context, output) { + if ((context && context.strictUnits) && !this.unit.isSingular()) { + throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString()); + } + var value = this.fround(context, this.value); + var strValue = String(value); + if (value !== 0 && value < 0.000001 && value > -0.000001) { + // would be output 1e-6 etc. + strValue = value.toFixed(20).replace(/0+$/, ''); + } + if (context && context.compress) { + // Zero values doesn't need a unit + if (value === 0 && this.unit.isLength()) { + output.add(strValue); + return; + } + // Float values doesn't need a leading zero + if (value > 0 && value < 1) { + strValue = (strValue).substr(1); + } } - } - - output.add(strValue); - this.unit.genCSS(context, output); - } // In an operation between two Dimensions, + output.add(strValue); + this.unit.genCSS(context, output); + }; + // In an operation between two Dimensions, // we default to the first Dimension's unit, // so `1px + 2` will yield `3px`. - - }, { - key: "operate", - value: function operate(context, op, other) { - /* jshint noempty:false */ - var value = this._operate(context, op, this.value, other.value); - - var unit = this.unit.clone(); - - if (op === '+' || op === '-') { - if (unit.numerator.length === 0 && unit.denominator.length === 0) { - unit = other.unit.clone(); - - if (this.unit.backupUnit) { - unit.backupUnit = this.unit.backupUnit; - } - } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; else { - other = other.convertTo(this.unit.usedUnits()); - - if (context.strictUnits && other.unit.toString() !== unit.toString()) { - throw new Error("Incompatible units. Change the units or use the unit function. " + "Bad units: '".concat(unit.toString(), "' and '").concat(other.unit.toString(), "'.")); - } - - value = this._operate(context, op, this.value, other.value); + Dimension.prototype.operate = function (context, op, other) { + /* jshint noempty:false */ + var value = this._operate(context, op, this.value, other.value); + var unit = this.unit.clone(); + if (op === '+' || op === '-') { + if (unit.numerator.length === 0 && unit.denominator.length === 0) { + unit = other.unit.clone(); + if (this.unit.backupUnit) { + unit.backupUnit = this.unit.backupUnit; + } + } + else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) ; + else { + other = other.convertTo(this.unit.usedUnits()); + if (context.strictUnits && other.unit.toString() !== unit.toString()) { + throw new Error("Incompatible units. Change the units or use the unit function. " + + ("Bad units: '" + unit.toString() + "' and '" + other.unit.toString() + "'.")); + } + value = this._operate(context, op, this.value, other.value); + } } - } else if (op === '*') { - unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); - unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); - unit.cancel(); - } else if (op === '/') { - unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); - unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); - unit.cancel(); - } - - return new Dimension(value, unit); - } - }, { - key: "compare", - value: function compare(other) { - var a; - var b; - - if (!(other instanceof Dimension)) { - return undefined; - } - - if (this.unit.isEmpty() || other.unit.isEmpty()) { - a = this; - b = other; - } else { - a = this.unify(); - b = other.unify(); - - if (a.unit.compare(b.unit) !== 0) { - return undefined; + else if (op === '*') { + unit.numerator = unit.numerator.concat(other.unit.numerator).sort(); + unit.denominator = unit.denominator.concat(other.unit.denominator).sort(); + unit.cancel(); } - } - - return Node.numericCompare(a.value, b.value); - } - }, { - key: "unify", - value: function unify() { - return this.convertTo({ - length: 'px', - duration: 's', - angle: 'rad' - }); - } - }, { - key: "convertTo", - value: function convertTo(conversions) { - var value = this.value; - var unit = this.unit.clone(); - var i; - var groupName; - var group; - var targetUnit; - var derivedConversions = {}; - var applyUnit; - - if (typeof conversions === 'string') { - for (i in unitConversions) { - if (unitConversions[i].hasOwnProperty(conversions)) { - derivedConversions = {}; - derivedConversions[i] = conversions; - } + else if (op === '/') { + unit.numerator = unit.numerator.concat(other.unit.denominator).sort(); + unit.denominator = unit.denominator.concat(other.unit.numerator).sort(); + unit.cancel(); } - - conversions = derivedConversions; - } - - applyUnit = function applyUnit(atomicUnit, denominator) { - /* jshint loopfunc:true */ - if (group.hasOwnProperty(atomicUnit)) { - if (denominator) { - value = value / (group[atomicUnit] / group[targetUnit]); - } else { - value = value * (group[atomicUnit] / group[targetUnit]); - } - - return targetUnit; + return new Dimension(value, unit); + }; + Dimension.prototype.compare = function (other) { + var a; + var b; + if (!(other instanceof Dimension)) { + return undefined; + } + if (this.unit.isEmpty() || other.unit.isEmpty()) { + a = this; + b = other; + } + else { + a = this.unify(); + b = other.unify(); + if (a.unit.compare(b.unit) !== 0) { + return undefined; + } } - - return atomicUnit; - }; - - for (groupName in conversions) { - if (conversions.hasOwnProperty(groupName)) { - targetUnit = conversions[groupName]; - group = unitConversions[groupName]; - unit.map(applyUnit); + return Node.numericCompare(a.value, b.value); + }; + Dimension.prototype.unify = function () { + return this.convertTo({ length: 'px', duration: 's', angle: 'rad' }); + }; + Dimension.prototype.convertTo = function (conversions) { + var value = this.value; + var unit = this.unit.clone(); + var i; + var groupName; + var group; + var targetUnit; + var derivedConversions = {}; + var applyUnit; + if (typeof conversions === 'string') { + for (i in unitConversions) { + if (unitConversions[i].hasOwnProperty(conversions)) { + derivedConversions = {}; + derivedConversions[i] = conversions; + } + } + conversions = derivedConversions; } - } - - unit.cancel(); - return new Dimension(value, unit); - } - }]); - - return Dimension; - }(Node); - - Dimension.prototype.type = 'Dimension'; - - var MATH$1 = Math$1; - - var Operation = - /*#__PURE__*/ - function (_Node) { - _inherits(Operation, _Node); - - function Operation(op, operands, isSpaced) { - var _this; - - _classCallCheck(this, Operation); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Operation).call(this)); - _this.op = op.trim(); - _this.operands = operands; - _this.isSpaced = isSpaced; - return _this; - } - - _createClass(Operation, [{ - key: "accept", - value: function accept(visitor) { - this.operands = visitor.visitArray(this.operands); - } - }, { - key: "eval", - value: function _eval(context) { - var a = this.operands[0].eval(context); - var b = this.operands[1].eval(context); - var op; - - if (context.isMathOn(this.op)) { - op = this.op === './' ? '/' : this.op; - - if (a instanceof Dimension && b instanceof Color) { - a = a.toColor(); + applyUnit = function (atomicUnit, denominator) { + /* jshint loopfunc:true */ + if (group.hasOwnProperty(atomicUnit)) { + if (denominator) { + value = value / (group[atomicUnit] / group[targetUnit]); + } + else { + value = value * (group[atomicUnit] / group[targetUnit]); + } + return targetUnit; + } + return atomicUnit; + }; + for (groupName in conversions) { + if (conversions.hasOwnProperty(groupName)) { + targetUnit = conversions[groupName]; + group = unitConversions[groupName]; + unit.map(applyUnit); + } } + unit.cancel(); + return new Dimension(value, unit); + }; + return Dimension; + }(Node)); + Dimension.prototype.type = 'Dimension'; - if (b instanceof Dimension && a instanceof Color) { - b = b.toColor(); + var MATH$1 = Math$1; + var Operation = /** @class */ (function (_super) { + __extends(Operation, _super); + function Operation(op, operands, isSpaced) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.operands = operands; + _this.isSpaced = isSpaced; + return _this; + } + Operation.prototype.accept = function (visitor) { + this.operands = visitor.visitArray(this.operands); + }; + Operation.prototype.eval = function (context) { + var a = this.operands[0].eval(context); + var b = this.operands[1].eval(context); + var op; + if (context.isMathOn(this.op)) { + op = this.op === './' ? '/' : this.op; + if (a instanceof Dimension && b instanceof Color) { + a = a.toColor(); + } + if (b instanceof Dimension && a instanceof Color) { + b = b.toColor(); + } + if (!a.operate) { + if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + return new Operation(this.op, [a, b], this.isSpaced); + } + throw { type: 'Operation', + message: 'Operation on an invalid type' }; + } + return a.operate(context, op, b); } - - if (!a.operate) { - if (a instanceof Operation && a.op === '/' && context.math === MATH$1.PARENS_DIVISION) { + else { return new Operation(this.op, [a, b], this.isSpaced); - } - - throw { - type: 'Operation', - message: 'Operation on an invalid type' - }; } - - return a.operate(context, op, b); - } else { - return new Operation(this.op, [a, b], this.isSpaced); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - this.operands[0].genCSS(context, output); - - if (this.isSpaced) { - output.add(' '); - } - - output.add(this.op); - - if (this.isSpaced) { - output.add(' '); - } - - this.operands[1].genCSS(context, output); - } - }]); - - return Operation; - }(Node); - + }; + Operation.prototype.genCSS = function (context, output) { + this.operands[0].genCSS(context, output); + if (this.isSpaced) { + output.add(' '); + } + output.add(this.op); + if (this.isSpaced) { + output.add(' '); + } + this.operands[1].genCSS(context, output); + }; + return Operation; + }(Node)); Operation.prototype.type = 'Operation'; var MATH$2 = Math$1; - - var Expression = - /*#__PURE__*/ - function (_Node) { - _inherits(Expression, _Node); - - function Expression(value, noSpacing) { - var _this; - - _classCallCheck(this, Expression); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Expression).call(this)); - _this.value = value; - _this.noSpacing = noSpacing; - - if (!value) { - throw new Error('Expression requires an array parameter'); - } - - return _this; - } - - _createClass(Expression, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visitArray(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - var returnValue; - var mathOn = context.isMathOn(); - var inParenthesis = this.parens && (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); - var doubleParen = false; - - if (inParenthesis) { - context.inParenthesis(); - } - - if (this.value.length > 1) { - returnValue = new Expression(this.value.map(function (e) { - if (!e.eval) { - return e; - } - - return e.eval(context); - }), this.noSpacing); - } else if (this.value.length === 1) { - if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { - doubleParen = true; + var Expression = /** @class */ (function (_super) { + __extends(Expression, _super); + function Expression(value, noSpacing) { + var _this = _super.call(this) || this; + _this.value = value; + _this.noSpacing = noSpacing; + if (!value) { + throw new Error('Expression requires an array parameter'); } - - returnValue = this.value[0].eval(context); - } else { - returnValue = this; - } - - if (inParenthesis) { - context.outOfParenthesis(); - } - - if (this.parens && this.parensInOp && !mathOn && !doubleParen && !(returnValue instanceof Dimension)) { - returnValue = new Paren(returnValue); - } - - return returnValue; + return _this; } - }, { - key: "genCSS", - value: function genCSS(context, output) { - for (var i = 0; i < this.value.length; i++) { - this.value[i].genCSS(context, output); - - if (!this.noSpacing && i + 1 < this.value.length) { - output.add(' '); + Expression.prototype.accept = function (visitor) { + this.value = visitor.visitArray(this.value); + }; + Expression.prototype.eval = function (context) { + var returnValue; + var mathOn = context.isMathOn(); + var inParenthesis = this.parens && + (context.math !== MATH$2.STRICT_LEGACY || !this.parensInOp); + var doubleParen = false; + if (inParenthesis) { + context.inParenthesis(); + } + if (this.value.length > 1) { + returnValue = new Expression(this.value.map(function (e) { + if (!e.eval) { + return e; + } + return e.eval(context); + }), this.noSpacing); } - } - } - }, { - key: "throwAwayComments", - value: function throwAwayComments() { - this.value = this.value.filter(function (v) { - return !(v instanceof Comment); - }); - } - }]); - - return Expression; - }(Node); - - Expression.prototype.type = 'Expression'; - - var functionCaller = - /*#__PURE__*/ - function () { - function functionCaller(name, context, index, currentFileInfo) { - _classCallCheck(this, functionCaller); - - this.name = name.toLowerCase(); - this.index = index; - this.context = context; - this.currentFileInfo = currentFileInfo; - this.func = context.frames[0].functionRegistry.get(this.name); - } - - _createClass(functionCaller, [{ - key: "isValid", - value: function isValid() { - return Boolean(this.func); - } - }, { - key: "call", - value: function call(args) { - // This code is terrible and should be replaced as per this issue... - // https://github.com/less/less.js/issues/2477 - if (Array.isArray(args)) { - args = args.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }).map(function (item) { - if (item.type === 'Expression') { - var subNodes = item.value.filter(function (item) { - if (item.type === 'Comment') { - return false; - } - - return true; - }); - - if (subNodes.length === 1) { - return subNodes[0]; - } else { - return new Expression(subNodes); + else if (this.value.length === 1) { + if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) { + doubleParen = true; } - } - - return item; - }); - } + returnValue = this.value[0].eval(context); + } + else { + returnValue = this; + } + if (inParenthesis) { + context.outOfParenthesis(); + } + if (this.parens && this.parensInOp && !mathOn && !doubleParen + && (!(returnValue instanceof Dimension))) { + returnValue = new Paren(returnValue); + } + return returnValue; + }; + Expression.prototype.genCSS = function (context, output) { + for (var i_1 = 0; i_1 < this.value.length; i_1++) { + this.value[i_1].genCSS(context, output); + if (!this.noSpacing && i_1 + 1 < this.value.length) { + output.add(' '); + } + } + }; + Expression.prototype.throwAwayComments = function () { + this.value = this.value.filter(function (v) { return !(v instanceof Comment); }); + }; + return Expression; + }(Node)); + Expression.prototype.type = 'Expression'; - return this.func.apply(this, _toConsumableArray(args)); + var functionCaller = /** @class */ (function () { + function functionCaller(name, context, index, currentFileInfo) { + this.name = name.toLowerCase(); + this.index = index; + this.context = context; + this.currentFileInfo = currentFileInfo; + this.func = context.frames[0].functionRegistry.get(this.name); } - }]); - - return functionCaller; - }(); + functionCaller.prototype.isValid = function () { + return Boolean(this.func); + }; + functionCaller.prototype.call = function (args) { + // This code is terrible and should be replaced as per this issue... + // https://github.com/less/less.js/issues/2477 + if (Array.isArray(args)) { + args = args.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }) + .map(function (item) { + if (item.type === 'Expression') { + var subNodes = item.value.filter(function (item) { + if (item.type === 'Comment') { + return false; + } + return true; + }); + if (subNodes.length === 1) { + return subNodes[0]; + } + else { + return new Expression(subNodes); + } + } + return item; + }); + } + return this.func.apply(this, args); + }; + return functionCaller; + }()); + // // A function call node. // - - var Call = - /*#__PURE__*/ - function (_Node) { - _inherits(Call, _Node); - - function Call(name, args, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Call); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Call).call(this)); - _this.name = name; - _this.args = args; - _this.calc = name === 'calc'; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Call, [{ - key: "accept", - value: function accept(visitor) { - if (this.args) { - this.args = visitor.visitArray(this.args); - } - } // + var Call = /** @class */ (function (_super) { + __extends(Call, _super); + function Call(name, args, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this.args = args; + _this.calc = name === 'calc'; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Call.prototype.accept = function (visitor) { + if (this.args) { + this.args = visitor.visitArray(this.args); + } + }; + // // When evaluating a function call, // we either find the function in the functionRegistry, // in which case we call it, passing the evaluated arguments, @@ -4318,645 +3368,466 @@ // we try to pass a variable to a function, like: `saturate(@color)`. // The function should receive the value, not the variable. // - - }, { - key: "eval", - value: function _eval(context) { - /** - * Turn off math for calc(), and switch back on for evaluating nested functions - */ - var currentMathContext = context.mathOn; - context.mathOn = !this.calc; - - if (this.calc || context.inCalc) { - context.enterCalc(); - } - - var args = this.args.map(function (a) { - return a.eval(context); - }); - - if (this.calc || context.inCalc) { - context.exitCalc(); - } - - context.mathOn = currentMathContext; - var result; - var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); - - if (funcCaller.isValid()) { - try { - result = funcCaller.call(args); - } catch (e) { - throw { - type: e.type || 'Runtime', - message: "error evaluating function `".concat(this.name, "`").concat(e.message ? ": ".concat(e.message) : ''), - index: this.getIndex(), - filename: this.fileInfo().filename, - line: e.lineNumber, - column: e.columnNumber - }; + Call.prototype.eval = function (context) { + /** + * Turn off math for calc(), and switch back on for evaluating nested functions + */ + var currentMathContext = context.mathOn; + context.mathOn = !this.calc; + if (this.calc || context.inCalc) { + context.enterCalc(); } - - if (result !== null && result !== undefined) { - // Results that that are not nodes are cast as Anonymous nodes - // Falsy values or booleans are returned as empty nodes - if (!(result instanceof Node)) { - if (!result || result === true) { - result = new Anonymous(null); - } else { - result = new Anonymous(result.toString()); - } - } - - result._index = this._index; - result._fileInfo = this._fileInfo; - return result; + var args = this.args.map(function (a) { return a.eval(context); }); + if (this.calc || context.inCalc) { + context.exitCalc(); } - } - - return new Call(this.name, args, this.getIndex(), this.fileInfo()); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add("".concat(this.name, "("), this.fileInfo(), this.getIndex()); - - for (var i = 0; i < this.args.length; i++) { - this.args[i].genCSS(context, output); - - if (i + 1 < this.args.length) { - output.add(', '); + context.mathOn = currentMathContext; + var result; + var funcCaller = new functionCaller(this.name, context, this.getIndex(), this.fileInfo()); + if (funcCaller.isValid()) { + try { + result = funcCaller.call(args); + } + catch (e) { + throw { + type: e.type || 'Runtime', + message: "error evaluating function `" + this.name + "`" + (e.message ? ": " + e.message : ''), + index: this.getIndex(), + filename: this.fileInfo().filename, + line: e.lineNumber, + column: e.columnNumber + }; + } + if (result !== null && result !== undefined) { + // Results that that are not nodes are cast as Anonymous nodes + // Falsy values or booleans are returned as empty nodes + if (!(result instanceof Node)) { + if (!result || result === true) { + result = new Anonymous(null); + } + else { + result = new Anonymous(result.toString()); + } + } + result._index = this._index; + result._fileInfo = this._fileInfo; + return result; + } } - } - - output.add(')'); - } - }]); - - return Call; - }(Node); - + return new Call(this.name, args, this.getIndex(), this.fileInfo()); + }; + Call.prototype.genCSS = function (context, output) { + output.add(this.name + "(", this.fileInfo(), this.getIndex()); + for (var i_1 = 0; i_1 < this.args.length; i_1++) { + this.args[i_1].genCSS(context, output); + if (i_1 + 1 < this.args.length) { + output.add(', '); + } + } + output.add(')'); + }; + return Call; + }(Node)); Call.prototype.type = 'Call'; - var Variable = - /*#__PURE__*/ - function (_Node) { - _inherits(Variable, _Node); - - function Variable(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Variable); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Variable).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Variable, [{ - key: "eval", - value: function _eval(context) { - var variable; - var name = this.name; - - if (name.indexOf('@@') === 0) { - name = "@".concat(new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value); - } - - if (this.evaluating) { - throw { - type: 'Name', - message: "Recursive variable definition for ".concat(name), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - variable = this.find(context.frames, function (frame) { - var v = frame.variable(name); - - if (v) { - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } // If in calc, wrap vars in a function call to cascade evaluate args first - - - if (context.inCalc) { - return new Call('_SELF', [v.value]).eval(context); - } else { - return v.value.eval(context); - } + var Variable = /** @class */ (function (_super) { + __extends(Variable, _super); + function Variable(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Variable.prototype.eval = function (context) { + var variable; + var name = this.name; + if (name.indexOf('@@') === 0) { + name = "@" + new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value; + } + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive variable definition for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + variable = this.find(context.frames, function (frame) { + var v = frame.variable(name); + if (v) { + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + // If in calc, wrap vars in a function call to cascade evaluate args first + if (context.inCalc) { + return (new Call('_SELF', [v.value])).eval(context); + } + else { + return v.value.eval(context); + } + } + }); + if (variable) { + this.evaluating = false; + return variable; } - }); - - if (variable) { - this.evaluating = false; - return variable; - } else { - throw { - type: 'Name', - message: "variable ".concat(name, " is undefined"), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "variable " + name + " is undefined", + filename: this.fileInfo().filename, + index: this.getIndex() }; } - } - - return null; - } - }]); - - return Variable; - }(Node); - + }; + Variable.prototype.find = function (obj, fun) { + for (var i_1 = 0, r = void 0; i_1 < obj.length; i_1++) { + r = fun.call(obj, obj[i_1]); + if (r) { + return r; + } + } + return null; + }; + return Variable; + }(Node)); Variable.prototype.type = 'Variable'; - var Property = - /*#__PURE__*/ - function (_Node) { - _inherits(Property, _Node); - - function Property(name, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Property); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Property).call(this)); - _this.name = name; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(Property, [{ - key: "eval", - value: function _eval(context) { - var property; - var name = this.name; // TODO: shorten this reference - - var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; - - if (this.evaluating) { - throw { - type: 'Name', - message: "Recursive property reference for ".concat(name), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - this.evaluating = true; - property = this.find(context.frames, function (frame) { - var v; - var vArr = frame.property(name); - - if (vArr) { - for (var i = 0; i < vArr.length; i++) { - v = vArr[i]; - vArr[i] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); - } - - mergeRules(vArr); - v = vArr[vArr.length - 1]; - - if (v.important) { - var importantScope = context.importantScope[context.importantScope.length - 1]; - importantScope.important = v.important; - } - - v = v.value.eval(context); - return v; + var Property = /** @class */ (function (_super) { + __extends(Property, _super); + function Property(name, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.name = name; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + Property.prototype.eval = function (context) { + var property; + var name = this.name; + // TODO: shorten this reference + var mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules; + if (this.evaluating) { + throw { type: 'Name', + message: "Recursive property reference for " + name, + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + this.evaluating = true; + property = this.find(context.frames, function (frame) { + var v; + var vArr = frame.property(name); + if (vArr) { + for (var i_1 = 0; i_1 < vArr.length; i_1++) { + v = vArr[i_1]; + vArr[i_1] = new Declaration(v.name, v.value, v.important, v.merge, v.index, v.currentFileInfo, v.inline, v.variable); + } + mergeRules(vArr); + v = vArr[vArr.length - 1]; + if (v.important) { + var importantScope = context.importantScope[context.importantScope.length - 1]; + importantScope.important = v.important; + } + v = v.value.eval(context); + return v; + } + }); + if (property) { + this.evaluating = false; + return property; } - }); - - if (property) { - this.evaluating = false; - return property; - } else { - throw { - type: 'Name', - message: "Property '".concat(name, "' is undefined"), - filename: this.currentFileInfo.filename, - index: this.index - }; - } - } - }, { - key: "find", - value: function find(obj, fun) { - for (var i = 0, r; i < obj.length; i++) { - r = fun.call(obj, obj[i]); - - if (r) { - return r; + else { + throw { type: 'Name', + message: "Property '" + name + "' is undefined", + filename: this.currentFileInfo.filename, + index: this.index }; } - } - - return null; - } - }]); - - return Property; - }(Node); - + }; + Property.prototype.find = function (obj, fun) { + for (var i_2 = 0, r = void 0; i_2 < obj.length; i_2++) { + r = fun.call(obj, obj[i_2]); + if (r) { + return r; + } + } + return null; + }; + return Property; + }(Node)); Property.prototype.type = 'Property'; - var Attribute = - /*#__PURE__*/ - function (_Node) { - _inherits(Attribute, _Node); - - function Attribute(key, op, value) { - var _this; - - _classCallCheck(this, Attribute); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Attribute).call(this)); - _this.key = key; - _this.op = op; - _this.value = value; - return _this; - } - - _createClass(Attribute, [{ - key: "eval", - value: function _eval(context) { - return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, this.value && this.value.eval ? this.value.eval(context) : this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add(this.toCSS(context)); - } - }, { - key: "toCSS", - value: function toCSS(context) { - var value = this.key.toCSS ? this.key.toCSS(context) : this.key; - - if (this.op) { - value += this.op; - value += this.value.toCSS ? this.value.toCSS(context) : this.value; - } - - return "[".concat(value, "]"); - } - }]); - - return Attribute; - }(Node); - + var Attribute = /** @class */ (function (_super) { + __extends(Attribute, _super); + function Attribute(key, op, value) { + var _this = _super.call(this) || this; + _this.key = key; + _this.op = op; + _this.value = value; + return _this; + } + Attribute.prototype.eval = function (context) { + return new Attribute(this.key.eval ? this.key.eval(context) : this.key, this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value); + }; + Attribute.prototype.genCSS = function (context, output) { + output.add(this.toCSS(context)); + }; + Attribute.prototype.toCSS = function (context) { + var value = this.key.toCSS ? this.key.toCSS(context) : this.key; + if (this.op) { + value += this.op; + value += (this.value.toCSS ? this.value.toCSS(context) : this.value); + } + return "[" + value + "]"; + }; + return Attribute; + }(Node)); Attribute.prototype.type = 'Attribute'; - var Quoted = - /*#__PURE__*/ - function (_Node) { - _inherits(Quoted, _Node); - - function Quoted(str, content, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, Quoted); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Quoted).call(this)); - _this.escaped = escaped == null ? true : escaped; - _this.value = content || ''; - _this.quote = str.charAt(0); - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.variableRegex = /@\{([\w-]+)\}/g; - _this.propRegex = /\$\{([\w-]+)\}/g; - _this.allowRoot = escaped; - return _this; - } - - _createClass(Quoted, [{ - key: "genCSS", - value: function genCSS(context, output) { - if (!this.escaped) { - output.add(this.quote, this.fileInfo(), this.getIndex()); - } - - output.add(this.value); - - if (!this.escaped) { - output.add(this.quote); - } - } - }, { - key: "containsVariables", - value: function containsVariables() { - return this.value.match(this.variableRegex); - } - }, { - key: "eval", - value: function _eval(context) { - var that = this; - var value = this.value; - - var variableReplacement = function variableReplacement(_, name) { - var v = new Variable("@".concat(name), that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - var propertyReplacement = function propertyReplacement(_, name) { - var v = new Property("$".concat(name), that.getIndex(), that.fileInfo()).eval(context, true); - return v instanceof Quoted ? v.value : v.toCSS(); - }; - - function iterativeReplace(value, regexp, replacementFnc) { - var evaluatedValue = value; - - do { - value = evaluatedValue.toString(); - evaluatedValue = value.replace(regexp, replacementFnc); - } while (value !== evaluatedValue); - - return evaluatedValue; - } - - value = iterativeReplace(value, this.variableRegex, variableReplacement); - value = iterativeReplace(value, this.propRegex, propertyReplacement); - return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); - } - }, { - key: "compare", - value: function compare(other) { - // when comparing quoted strings allow the quote to differ - if (other.type === 'Quoted' && !this.escaped && !other.escaped) { - return Node.numericCompare(this.value, other.value); - } else { - return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; - } - } - }]); - - return Quoted; - }(Node); - + var Quoted = /** @class */ (function (_super) { + __extends(Quoted, _super); + function Quoted(str, content, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = (escaped == null) ? true : escaped; + _this.value = content || ''; + _this.quote = str.charAt(0); + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.variableRegex = /@\{([\w-]+)\}/g; + _this.propRegex = /\$\{([\w-]+)\}/g; + _this.allowRoot = escaped; + return _this; + } + Quoted.prototype.genCSS = function (context, output) { + if (!this.escaped) { + output.add(this.quote, this.fileInfo(), this.getIndex()); + } + output.add(this.value); + if (!this.escaped) { + output.add(this.quote); + } + }; + Quoted.prototype.containsVariables = function () { + return this.value.match(this.variableRegex); + }; + Quoted.prototype.eval = function (context) { + var that = this; + var value = this.value; + var variableReplacement = function (_, name) { + var v = new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + var propertyReplacement = function (_, name) { + var v = new Property("$" + name, that.getIndex(), that.fileInfo()).eval(context, true); + return (v instanceof Quoted) ? v.value : v.toCSS(); + }; + function iterativeReplace(value, regexp, replacementFnc) { + var evaluatedValue = value; + do { + value = evaluatedValue.toString(); + evaluatedValue = value.replace(regexp, replacementFnc); + } while (value !== evaluatedValue); + return evaluatedValue; + } + value = iterativeReplace(value, this.variableRegex, variableReplacement); + value = iterativeReplace(value, this.propRegex, propertyReplacement); + return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo()); + }; + Quoted.prototype.compare = function (other) { + // when comparing quoted strings allow the quote to differ + if (other.type === 'Quoted' && !this.escaped && !other.escaped) { + return Node.numericCompare(this.value, other.value); + } + else { + return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined; + } + }; + return Quoted; + }(Node)); Quoted.prototype.type = 'Quoted'; - var URL = - /*#__PURE__*/ - function (_Node) { - _inherits(URL, _Node); - - function URL(val, index, currentFileInfo, isEvald) { - var _this; - - _classCallCheck(this, URL); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(URL).call(this)); - _this.value = val; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.isEvald = isEvald; - return _this; - } - - _createClass(URL, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('url('); - this.value.genCSS(context, output); - output.add(')'); - } - }, { - key: "eval", - value: function _eval(context) { - var val = this.value.eval(context); - var rootpath; - - if (!this.isEvald) { - // Add the rootpath if the URL requires a rewrite - rootpath = this.fileInfo() && this.fileInfo().rootpath; - - if (typeof rootpath === 'string' && typeof val.value === 'string' && context.pathRequiresRewrite(val.value)) { - if (!val.quote) { - rootpath = escapePath(rootpath); - } - - val.value = context.rewritePath(val.value, rootpath); - } else { - val.value = context.normalizePath(val.value); - } // Add url args if enabled - - - if (context.urlArgs) { - if (!val.value.match(/^\s*data:/)) { - var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; - var urlArgs = delimiter + context.urlArgs; - - if (val.value.indexOf('#') !== -1) { - val.value = val.value.replace('#', "".concat(urlArgs, "#")); - } else { - val.value += urlArgs; + var URL = /** @class */ (function (_super) { + __extends(URL, _super); + function URL(val, index, currentFileInfo, isEvald) { + var _this = _super.call(this) || this; + _this.value = val; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.isEvald = isEvald; + return _this; + } + URL.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + URL.prototype.genCSS = function (context, output) { + output.add('url('); + this.value.genCSS(context, output); + output.add(')'); + }; + URL.prototype.eval = function (context) { + var val = this.value.eval(context); + var rootpath; + if (!this.isEvald) { + // Add the rootpath if the URL requires a rewrite + rootpath = this.fileInfo() && this.fileInfo().rootpath; + if (typeof rootpath === 'string' && + typeof val.value === 'string' && + context.pathRequiresRewrite(val.value)) { + if (!val.quote) { + rootpath = escapePath(rootpath); + } + val.value = context.rewritePath(val.value, rootpath); + } + else { + val.value = context.normalizePath(val.value); + } + // Add url args if enabled + if (context.urlArgs) { + if (!val.value.match(/^\s*data:/)) { + var delimiter = val.value.indexOf('?') === -1 ? '?' : '&'; + var urlArgs = delimiter + context.urlArgs; + if (val.value.indexOf('#') !== -1) { + val.value = val.value.replace('#', urlArgs + "#"); + } + else { + val.value += urlArgs; + } + } } - } } - } - - return new URL(val, this.getIndex(), this.fileInfo(), true); - } - }]); - - return URL; - }(Node); - + return new URL(val, this.getIndex(), this.fileInfo(), true); + }; + return URL; + }(Node)); URL.prototype.type = 'Url'; - function escapePath(path) { - return path.replace(/[\(\)'"\s]/g, function (match) { - return "\\".concat(match); - }); + return path.replace(/[\(\)'"\s]/g, function (match) { return "\\" + match; }); } - var Media = - /*#__PURE__*/ - function (_AtRule) { - _inherits(Media, _AtRule); - - function Media(value, features, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Media); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Media).call(this)); - _this._index = index; - _this._fileInfo = currentFileInfo; - var selectors = new Selector([], null, null, _this._index, _this._fileInfo).createEmptySelectors(); - _this.features = new Value(features); - _this.rules = [new Ruleset(selectors, value)]; - _this.rules[0].allowImports = true; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - _this.setParent(selectors, _assertThisInitialized(_this)); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.rules, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Media, [{ - key: "isRulesetLike", - value: function isRulesetLike() { - return true; - } - }, { - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - if (this.rules) { - this.rules = visitor.visitArray(this.rules); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add('@media ', this._fileInfo, this._index); - this.features.genCSS(context, output); - this.outputRuleset(context, output, this.rules); - } - }, { - key: "eval", - value: function _eval(context) { - if (!context.mediaBlocks) { - context.mediaBlocks = []; - context.mediaPath = []; - } - - var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); - - if (this.debugInfo) { - this.rules[0].debugInfo = this.debugInfo; - media.debugInfo = this.debugInfo; - } - - media.features = this.features.eval(context); - context.mediaPath.push(media); - context.mediaBlocks.push(media); - this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); - context.frames.unshift(this.rules[0]); - media.rules = [this.rules[0].eval(context)]; - context.frames.shift(); - context.mediaPath.pop(); - return context.mediaPath.length === 0 ? media.evalTop(context) : media.evalNested(context); - } - }, { - key: "evalTop", - value: function evalTop(context) { - var result = this; // Render all dependent Media blocks. - - if (context.mediaBlocks.length > 1) { - var selectors = new Selector([], null, null, this.getIndex(), this.fileInfo()).createEmptySelectors(); - result = new Ruleset(selectors, context.mediaBlocks); - result.multiMedia = true; - result.copyVisibilityInfo(this.visibilityInfo()); - this.setParent(result, this); - } - - delete context.mediaBlocks; - delete context.mediaPath; - return result; - } - }, { - key: "evalNested", - value: function evalNested(context) { - var i; - var value; - var path = context.mediaPath.concat([this]); // Extract the media-query conditions separated with `,` (OR). - - for (i = 0; i < path.length; i++) { - value = path[i].features instanceof Value ? path[i].features.value : path[i].features; - path[i] = Array.isArray(value) ? value : [value]; - } // Trace all permutations to generate the resulting media-query. - // - // (a, b and c) with nested (d, e) -> - // a and d - // a and e - // b and c and d - // b and c and e - - - this.features = new Value(this.permute(path).map(function (path) { - path = path.map(function (fragment) { - return fragment.toCSS ? fragment : new Anonymous(fragment); - }); - - for (i = path.length - 1; i > 0; i--) { - path.splice(i, 0, new Anonymous('and')); + var Media = /** @class */ (function (_super) { + __extends(Media, _super); + function Media(value, features, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this._index = index; + _this._fileInfo = currentFileInfo; + var selectors = (new Selector([], null, null, _this._index, _this._fileInfo)).createEmptySelectors(); + _this.features = new Value(features); + _this.rules = [new Ruleset(selectors, value)]; + _this.rules[0].allowImports = true; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + _this.setParent(selectors, _this); + _this.setParent(_this.features, _this); + _this.setParent(_this.rules, _this); + return _this; + } + Media.prototype.isRulesetLike = function () { + return true; + }; + Media.prototype.accept = function (visitor) { + if (this.features) { + this.features = visitor.visit(this.features); } - - return new Expression(path); - })); - this.setParent(this.features, this); // Fake a tree-node that doesn't output anything. - - return new Ruleset([], []); - } - }, { - key: "permute", - value: function permute(arr) { - if (arr.length === 0) { - return []; - } else if (arr.length === 1) { - return arr[0]; - } else { - var result = []; - var rest = this.permute(arr.slice(1)); - - for (var i = 0; i < rest.length; i++) { - for (var j = 0; j < arr[0].length; j++) { - result.push([arr[0][j]].concat(rest[i])); - } + if (this.rules) { + this.rules = visitor.visitArray(this.rules); } - + }; + Media.prototype.genCSS = function (context, output) { + output.add('@media ', this._fileInfo, this._index); + this.features.genCSS(context, output); + this.outputRuleset(context, output, this.rules); + }; + Media.prototype.eval = function (context) { + if (!context.mediaBlocks) { + context.mediaBlocks = []; + context.mediaPath = []; + } + var media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo()); + if (this.debugInfo) { + this.rules[0].debugInfo = this.debugInfo; + media.debugInfo = this.debugInfo; + } + media.features = this.features.eval(context); + context.mediaPath.push(media); + context.mediaBlocks.push(media); + this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit(); + context.frames.unshift(this.rules[0]); + media.rules = [this.rules[0].eval(context)]; + context.frames.shift(); + context.mediaPath.pop(); + return context.mediaPath.length === 0 ? media.evalTop(context) : + media.evalNested(context); + }; + Media.prototype.evalTop = function (context) { + var result = this; + // Render all dependent Media blocks. + if (context.mediaBlocks.length > 1) { + var selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors(); + result = new Ruleset(selectors, context.mediaBlocks); + result.multiMedia = true; + result.copyVisibilityInfo(this.visibilityInfo()); + this.setParent(result, this); + } + delete context.mediaBlocks; + delete context.mediaPath; return result; - } - } - }, { - key: "bubbleSelectors", - value: function bubbleSelectors(selectors) { - if (!selectors) { - return; - } - - this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; - this.setParent(this.rules, this); - } - }]); - - return Media; - }(AtRule); - + }; + Media.prototype.evalNested = function (context) { + var i; + var value; + var path = context.mediaPath.concat([this]); + // Extract the media-query conditions separated with `,` (OR). + for (i = 0; i < path.length; i++) { + value = path[i].features instanceof Value ? + path[i].features.value : path[i].features; + path[i] = Array.isArray(value) ? value : [value]; + } + // Trace all permutations to generate the resulting media-query. + // + // (a, b and c) with nested (d, e) -> + // a and d + // a and e + // b and c and d + // b and c and e + this.features = new Value(this.permute(path).map(function (path) { + path = path.map(function (fragment) { return fragment.toCSS ? fragment : new Anonymous(fragment); }); + for (i = path.length - 1; i > 0; i--) { + path.splice(i, 0, new Anonymous('and')); + } + return new Expression(path); + })); + this.setParent(this.features, this); + // Fake a tree-node that doesn't output anything. + return new Ruleset([], []); + }; + Media.prototype.permute = function (arr) { + if (arr.length === 0) { + return []; + } + else if (arr.length === 1) { + return arr[0]; + } + else { + var result = []; + var rest = this.permute(arr.slice(1)); + for (var i_1 = 0; i_1 < rest.length; i_1++) { + for (var j = 0; j < arr[0].length; j++) { + result.push([arr[0][j]].concat(rest[i_1])); + } + } + return result; + } + }; + Media.prototype.bubbleSelectors = function (selectors) { + if (!selectors) { + return; + } + this.rules = [new Ruleset(copyArray(selectors), [this.rules[0]])]; + this.setParent(this.rules, this); + }; + return Media; + }(AtRule)); Media.prototype.type = 'Media'; + // // CSS @import node // // The general strategy here is that we don't want to wait @@ -4968,3938 +3839,3011 @@ // `import,push`, we also pass it a callback, which it'll call once // the file has been fetched, and parsed. // - - var Import = - /*#__PURE__*/ - function (_Node) { - _inherits(Import, _Node); - - function Import(path, features, options, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Import); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Import).call(this)); - _this.options = options; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.path = path; - _this.features = features; - _this.allowRoot = true; - - if (_this.options.less !== undefined || _this.options.inline) { - _this.css = !_this.options.less || _this.options.inline; - } else { - var pathValue = _this.getPath(); - - if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { - _this.css = true; - } + var Import = /** @class */ (function (_super) { + __extends(Import, _super); + function Import(path, features, options, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.options = options; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.path = path; + _this.features = features; + _this.allowRoot = true; + if (_this.options.less !== undefined || _this.options.inline) { + _this.css = !_this.options.less || _this.options.inline; + } + else { + var pathValue = _this.getPath(); + if (pathValue && /[#\.\&\?]css([\?;].*)?$/.test(pathValue)) { + _this.css = true; + } + } + _this.copyVisibilityInfo(visibilityInfo); + _this.setParent(_this.features, _this); + _this.setParent(_this.path, _this); + return _this; } - - _this.copyVisibilityInfo(visibilityInfo); - - _this.setParent(_this.features, _assertThisInitialized(_this)); - - _this.setParent(_this.path, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Import, [{ - key: "accept", - value: function accept(visitor) { - if (this.features) { - this.features = visitor.visit(this.features); - } - - this.path = visitor.visit(this.path); - - if (!this.options.isPlugin && !this.options.inline && this.root) { - this.root = visitor.visit(this.root); - } - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - if (this.css && this.path._fileInfo.reference === undefined) { - output.add('@import ', this._fileInfo, this._index); - this.path.genCSS(context, output); - + Import.prototype.accept = function (visitor) { if (this.features) { - output.add(' '); - this.features.genCSS(context, output); + this.features = visitor.visit(this.features); } - - output.add(';'); - } - } - }, { - key: "getPath", - value: function getPath() { - return this.path instanceof URL ? this.path.value.value : this.path.value; - } - }, { - key: "isVariableImport", - value: function isVariableImport() { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - if (path instanceof Quoted) { - return path.containsVariables(); - } - - return true; - } - }, { - key: "evalForImport", - value: function evalForImport(context) { - var path = this.path; - - if (path instanceof URL) { - path = path.value; - } - - return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); - } - }, { - key: "evalPath", - value: function evalPath(context) { - var path = this.path.eval(context); - var fileInfo = this._fileInfo; - - if (!(path instanceof URL)) { - // Add the rootpath if the URL requires a rewrite - var pathValue = path.value; - - if (fileInfo && pathValue && context.pathRequiresRewrite(pathValue)) { - path.value = context.rewritePath(pathValue, fileInfo.rootpath); - } else { - path.value = context.normalizePath(path.value); + this.path = visitor.visit(this.path); + if (!this.options.isPlugin && !this.options.inline && this.root) { + this.root = visitor.visit(this.root); } - } - - return path; - } - }, { - key: "eval", - value: function _eval(context) { - var result = this.doEval(context); - - if (this.options.reference || this.blocksVisibility()) { - if (result.length || result.length === 0) { - result.forEach(function (node) { - node.addVisibilityBlock(); - }); - } else { - result.addVisibilityBlock(); - } - } - - return result; - } - }, { - key: "doEval", - value: function doEval(context) { - var ruleset; - var registry; - var features = this.features && this.features.eval(context); - - if (this.options.isPlugin) { - if (this.root && this.root.eval) { - try { - this.root.eval(context); - } catch (e) { - e.message = 'Plugin error during evaluation'; - throw new LessError(e, this.root.imports, this.root.filename); - } + }; + Import.prototype.genCSS = function (context, output) { + if (this.css && this.path._fileInfo.reference === undefined) { + output.add('@import ', this._fileInfo, this._index); + this.path.genCSS(context, output); + if (this.features) { + output.add(' '); + this.features.genCSS(context, output); + } + output.add(';'); } - - registry = context.frames[0] && context.frames[0].functionRegistry; - - if (registry && this.root && this.root.functions) { - registry.addMultiple(this.root.functions); + }; + Import.prototype.getPath = function () { + return (this.path instanceof URL) ? + this.path.value.value : this.path.value; + }; + Import.prototype.isVariableImport = function () { + var path = this.path; + if (path instanceof URL) { + path = path.value; } - - return []; - } - - if (this.skip) { - if (typeof this.skip === 'function') { - this.skip = this.skip(); + if (path instanceof Quoted) { + return path.containsVariables(); + } + return true; + }; + Import.prototype.evalForImport = function (context) { + var path = this.path; + if (path instanceof URL) { + path = path.value; + } + return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo()); + }; + Import.prototype.evalPath = function (context) { + var path = this.path.eval(context); + var fileInfo = this._fileInfo; + if (!(path instanceof URL)) { + // Add the rootpath if the URL requires a rewrite + var pathValue = path.value; + if (fileInfo && + pathValue && + context.pathRequiresRewrite(pathValue)) { + path.value = context.rewritePath(pathValue, fileInfo.rootpath); + } + else { + path.value = context.normalizePath(path.value); + } + } + return path; + }; + Import.prototype.eval = function (context) { + var result = this.doEval(context); + if (this.options.reference || this.blocksVisibility()) { + if (result.length || result.length === 0) { + result.forEach(function (node) { + node.addVisibilityBlock(); + }); + } + else { + result.addVisibilityBlock(); + } + } + return result; + }; + Import.prototype.doEval = function (context) { + var ruleset; + var registry; + var features = this.features && this.features.eval(context); + if (this.options.isPlugin) { + if (this.root && this.root.eval) { + try { + this.root.eval(context); + } + catch (e) { + e.message = 'Plugin error during evaluation'; + throw new LessError(e, this.root.imports, this.root.filename); + } + } + registry = context.frames[0] && context.frames[0].functionRegistry; + if (registry && this.root && this.root.functions) { + registry.addMultiple(this.root.functions); + } + return []; } - if (this.skip) { - return []; + if (typeof this.skip === 'function') { + this.skip = this.skip(); + } + if (this.skip) { + return []; + } } - } - - if (this.options.inline) { - var contents = new Anonymous(this.root, 0, { - filename: this.importedFilename, - reference: this.path._fileInfo && this.path._fileInfo.reference - }, true, true); - return this.features ? new Media([contents], this.features.value) : [contents]; - } else if (this.css) { - var newImport = new Import(this.evalPath(context), features, this.options, this._index); - - if (!newImport.css && this.error) { - throw this.error; + if (this.options.inline) { + var contents = new Anonymous(this.root, 0, { + filename: this.importedFilename, + reference: this.path._fileInfo && this.path._fileInfo.reference + }, true, true); + return this.features ? new Media([contents], this.features.value) : [contents]; + } + else if (this.css) { + var newImport = new Import(this.evalPath(context), features, this.options, this._index); + if (!newImport.css && this.error) { + throw this.error; + } + return newImport; } - - return newImport; - } else { - ruleset = new Ruleset(null, copyArray(this.root.rules)); - ruleset.evalImports(context); - return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; - } - } - }]); - - return Import; - }(Node); - + else { + ruleset = new Ruleset(null, copyArray(this.root.rules)); + ruleset.evalImports(context); + return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules; + } + }; + return Import; + }(Node)); Import.prototype.type = 'Import'; - var JsEvalNode = - /*#__PURE__*/ - function (_Node) { - _inherits(JsEvalNode, _Node); - - function JsEvalNode() { - _classCallCheck(this, JsEvalNode); - - return _possibleConstructorReturn(this, _getPrototypeOf(JsEvalNode).apply(this, arguments)); - } - - _createClass(JsEvalNode, [{ - key: "evaluateJavaScript", - value: function evaluateJavaScript(expression, context) { - var result; - var that = this; - var evalContext = {}; - - if (!context.javascriptEnabled) { - throw { - message: 'Inline JavaScript is not enabled. Is it set in your options?', - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { - return that.jsify(new Variable("@".concat(name), that.getIndex(), that.fileInfo()).eval(context)); - }); - - try { - expression = new Function("return (".concat(expression, ")")); - } catch (e) { - throw { - message: "JavaScript evaluation error: ".concat(e.message, " from `").concat(expression, "`"), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - var variables = context.frames[0].variables(); - - for (var k in variables) { - if (variables.hasOwnProperty(k)) { - /* jshint loopfunc:true */ - evalContext[k.slice(1)] = { - value: variables[k].value, - toJS: function toJS() { - return this.value.eval(context).toCSS(); + var JsEvalNode = /** @class */ (function (_super) { + __extends(JsEvalNode, _super); + function JsEvalNode() { + return _super !== null && _super.apply(this, arguments) || this; + } + JsEvalNode.prototype.evaluateJavaScript = function (expression, context) { + var result; + var that = this; + var evalContext = {}; + if (!context.javascriptEnabled) { + throw { message: 'Inline JavaScript is not enabled. Is it set in your options?', + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + expression = expression.replace(/@\{([\w-]+)\}/g, function (_, name) { return that.jsify(new Variable("@" + name, that.getIndex(), that.fileInfo()).eval(context)); }); + try { + expression = new Function("return (" + expression + ")"); + } + catch (e) { + throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + var variables = context.frames[0].variables(); + for (var k in variables) { + if (variables.hasOwnProperty(k)) { + /* jshint loopfunc:true */ + evalContext[k.slice(1)] = { + value: variables[k].value, + toJS: function () { + return this.value.eval(context).toCSS(); + } + }; } - }; } - } - - try { - result = expression.call(evalContext); - } catch (e) { - throw { - message: "JavaScript evaluation error: '".concat(e.name, ": ").concat(e.message.replace(/["]/g, '\''), "'"), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - - return result; - } - }, { - key: "jsify", - value: function jsify(obj) { - if (Array.isArray(obj.value) && obj.value.length > 1) { - return "[".concat(obj.value.map(function (v) { - return v.toCSS(); - }).join(', '), "]"); - } else { - return obj.toCSS(); - } - } - }]); - - return JsEvalNode; - }(Node); - - var JavaScript = - /*#__PURE__*/ - function (_JsEvalNode) { - _inherits(JavaScript, _JsEvalNode); - - function JavaScript(string, escaped, index, currentFileInfo) { - var _this; - - _classCallCheck(this, JavaScript); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(JavaScript).call(this)); - _this.escaped = escaped; - _this.expression = string; - _this._index = index; - _this._fileInfo = currentFileInfo; - return _this; - } - - _createClass(JavaScript, [{ - key: "eval", - value: function _eval(context) { - var result = this.evaluateJavaScript(this.expression, context); - - var type = _typeof(result); - - if (type === 'number' && !isNaN(result)) { - return new Dimension(result); - } else if (type === 'string') { - return new Quoted("\"".concat(result, "\""), result, this.escaped, this._index); - } else if (Array.isArray(result)) { - return new Anonymous(result.join(', ')); - } else { - return new Anonymous(result); - } - } - }]); - - return JavaScript; - }(JsEvalNode); - + try { + result = expression.call(evalContext); + } + catch (e) { + throw { message: "JavaScript evaluation error: '" + e.name + ": " + e.message.replace(/["]/g, '\'') + "'", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + return result; + }; + JsEvalNode.prototype.jsify = function (obj) { + if (Array.isArray(obj.value) && (obj.value.length > 1)) { + return "[" + obj.value.map(function (v) { return v.toCSS(); }).join(', ') + "]"; + } + else { + return obj.toCSS(); + } + }; + return JsEvalNode; + }(Node)); + + var JavaScript = /** @class */ (function (_super) { + __extends(JavaScript, _super); + function JavaScript(string, escaped, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.escaped = escaped; + _this.expression = string; + _this._index = index; + _this._fileInfo = currentFileInfo; + return _this; + } + JavaScript.prototype.eval = function (context) { + var result = this.evaluateJavaScript(this.expression, context); + var type = typeof result; + if (type === 'number' && !isNaN(result)) { + return new Dimension(result); + } + else if (type === 'string') { + return new Quoted("\"" + result + "\"", result, this.escaped, this._index); + } + else if (Array.isArray(result)) { + return new Anonymous(result.join(', ')); + } + else { + return new Anonymous(result); + } + }; + return JavaScript; + }(JsEvalNode)); JavaScript.prototype.type = 'JavaScript'; - var Assignment = - /*#__PURE__*/ - function (_Node) { - _inherits(Assignment, _Node); - - function Assignment(key, val) { - var _this; - - _classCallCheck(this, Assignment); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Assignment).call(this)); - _this.key = key; - _this.value = val; - return _this; - } - - _createClass(Assignment, [{ - key: "accept", - value: function accept(visitor) { - this.value = visitor.visit(this.value); - } - }, { - key: "eval", - value: function _eval(context) { - if (this.value.eval) { - return new Assignment(this.key, this.value.eval(context)); - } - - return this; - } - }, { - key: "genCSS", - value: function genCSS(context, output) { - output.add("".concat(this.key, "=")); - - if (this.value.genCSS) { - this.value.genCSS(context, output); - } else { - output.add(this.value); - } + var Assignment = /** @class */ (function (_super) { + __extends(Assignment, _super); + function Assignment(key, val) { + var _this = _super.call(this) || this; + _this.key = key; + _this.value = val; + return _this; } - }]); - - return Assignment; - }(Node); - + Assignment.prototype.accept = function (visitor) { + this.value = visitor.visit(this.value); + }; + Assignment.prototype.eval = function (context) { + if (this.value.eval) { + return new Assignment(this.key, this.value.eval(context)); + } + return this; + }; + Assignment.prototype.genCSS = function (context, output) { + output.add(this.key + "="); + if (this.value.genCSS) { + this.value.genCSS(context, output); + } + else { + output.add(this.value); + } + }; + return Assignment; + }(Node)); Assignment.prototype.type = 'Assignment'; - var Condition = - /*#__PURE__*/ - function (_Node) { - _inherits(Condition, _Node); - - function Condition(op, l, r, i, negate) { - var _this; - - _classCallCheck(this, Condition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Condition).call(this)); - _this.op = op.trim(); - _this.lvalue = l; - _this.rvalue = r; - _this._index = i; - _this.negate = negate; - return _this; - } - - _createClass(Condition, [{ - key: "accept", - value: function accept(visitor) { - this.lvalue = visitor.visit(this.lvalue); - this.rvalue = visitor.visit(this.rvalue); - } - }, { - key: "eval", - value: function _eval(context) { - var result = function (op, a, b) { - switch (op) { - case 'and': - return a && b; - - case 'or': - return a || b; - - default: - switch (Node.compare(a, b)) { - case -1: - return op === '<' || op === '=<' || op === '<='; - - case 0: - return op === '=' || op === '>=' || op === '=<' || op === '<='; - - case 1: - return op === '>' || op === '>='; - - default: - return false; + var Condition = /** @class */ (function (_super) { + __extends(Condition, _super); + function Condition(op, l, r, i, negate) { + var _this = _super.call(this) || this; + _this.op = op.trim(); + _this.lvalue = l; + _this.rvalue = r; + _this._index = i; + _this.negate = negate; + return _this; + } + Condition.prototype.accept = function (visitor) { + this.lvalue = visitor.visit(this.lvalue); + this.rvalue = visitor.visit(this.rvalue); + }; + Condition.prototype.eval = function (context) { + var result = (function (op, a, b) { + switch (op) { + case 'and': return a && b; + case 'or': return a || b; + default: + switch (Node.compare(a, b)) { + case -1: + return op === '<' || op === '=<' || op === '<='; + case 0: + return op === '=' || op === '>=' || op === '=<' || op === '<='; + case 1: + return op === '>' || op === '>='; + default: + return false; + } } - - } - }(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); - - return this.negate ? !result : result; - } - }]); - - return Condition; - }(Node); - + })(this.op, this.lvalue.eval(context), this.rvalue.eval(context)); + return this.negate ? !result : result; + }; + return Condition; + }(Node)); Condition.prototype.type = 'Condition'; - var UnicodeDescriptor = - /*#__PURE__*/ - function (_Node) { - _inherits(UnicodeDescriptor, _Node); - - function UnicodeDescriptor(value) { - var _this; - - _classCallCheck(this, UnicodeDescriptor); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(UnicodeDescriptor).call(this)); - _this.value = value; - return _this; - } - - return UnicodeDescriptor; - }(Node); - + var UnicodeDescriptor = /** @class */ (function (_super) { + __extends(UnicodeDescriptor, _super); + function UnicodeDescriptor(value) { + var _this = _super.call(this) || this; + _this.value = value; + return _this; + } + return UnicodeDescriptor; + }(Node)); UnicodeDescriptor.prototype.type = 'UnicodeDescriptor'; - var Negative = - /*#__PURE__*/ - function (_Node) { - _inherits(Negative, _Node); - - function Negative(node) { - var _this; - - _classCallCheck(this, Negative); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Negative).call(this)); - _this.value = node; - return _this; - } - - _createClass(Negative, [{ - key: "genCSS", - value: function genCSS(context, output) { - output.add('-'); - this.value.genCSS(context, output); - } - }, { - key: "eval", - value: function _eval(context) { - if (context.isMathOn()) { - return new Operation('*', [new Dimension(-1), this.value]).eval(context); - } - - return new Negative(this.value.eval(context)); + var Negative = /** @class */ (function (_super) { + __extends(Negative, _super); + function Negative(node) { + var _this = _super.call(this) || this; + _this.value = node; + return _this; } - }]); - - return Negative; - }(Node); - + Negative.prototype.genCSS = function (context, output) { + output.add('-'); + this.value.genCSS(context, output); + }; + Negative.prototype.eval = function (context) { + if (context.isMathOn()) { + return (new Operation('*', [new Dimension(-1), this.value])).eval(context); + } + return new Negative(this.value.eval(context)); + }; + return Negative; + }(Node)); Negative.prototype.type = 'Negative'; - var Extend = - /*#__PURE__*/ - function (_Node) { - _inherits(Extend, _Node); - - function Extend(selector, option, index, currentFileInfo, visibilityInfo) { - var _this; - - _classCallCheck(this, Extend); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Extend).call(this)); - _this.selector = selector; - _this.option = option; - _this.object_id = Extend.next_id++; - _this.parent_ids = [_this.object_id]; - _this._index = index; - _this._fileInfo = currentFileInfo; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - - switch (option) { - case 'all': - _this.allowBefore = true; - _this.allowAfter = true; - break; - - default: - _this.allowBefore = false; - _this.allowAfter = false; - break; - } - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(Extend, [{ - key: "accept", - value: function accept(visitor) { - this.selector = visitor.visit(this.selector); - } - }, { - key: "eval", - value: function _eval(context) { - return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } - }, { - key: "clone", - value: function clone(context) { - return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); - } // it concatenates (joins) all selectors in selector array - - }, { - key: "findSelfSelectors", - value: function findSelfSelectors(selectors) { - var selfElements = []; - var i; - var selectorElements; - - for (i = 0; i < selectors.length; i++) { - selectorElements = selectors[i].elements; // duplicate the logic in genCSS function inside the selector node. - // future TODO - move both logics into the selector joiner visitor - - if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { - selectorElements[0].combinator.value = ' '; + var Extend = /** @class */ (function (_super) { + __extends(Extend, _super); + function Extend(selector, option, index, currentFileInfo, visibilityInfo) { + var _this = _super.call(this) || this; + _this.selector = selector; + _this.option = option; + _this.object_id = Extend.next_id++; + _this.parent_ids = [_this.object_id]; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + switch (option) { + case 'all': + _this.allowBefore = true; + _this.allowAfter = true; + break; + default: + _this.allowBefore = false; + _this.allowAfter = false; + break; } - - selfElements = selfElements.concat(selectors[i].elements); - } - - this.selfSelectors = [new Selector(selfElements)]; - this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + _this.setParent(_this.selector, _this); + return _this; } - }]); - - return Extend; - }(Node); - + Extend.prototype.accept = function (visitor) { + this.selector = visitor.visit(this.selector); + }; + Extend.prototype.eval = function (context) { + return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + Extend.prototype.clone = function (context) { + return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo()); + }; + // it concatenates (joins) all selectors in selector array + Extend.prototype.findSelfSelectors = function (selectors) { + var selfElements = []; + var i; + var selectorElements; + for (i = 0; i < selectors.length; i++) { + selectorElements = selectors[i].elements; + // duplicate the logic in genCSS function inside the selector node. + // future TODO - move both logics into the selector joiner visitor + if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') { + selectorElements[0].combinator.value = ' '; + } + selfElements = selfElements.concat(selectors[i].elements); + } + this.selfSelectors = [new Selector(selfElements)]; + this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo()); + }; + return Extend; + }(Node)); Extend.next_id = 0; Extend.prototype.type = 'Extend'; - var VariableCall = - /*#__PURE__*/ - function (_Node) { - _inherits(VariableCall, _Node); - - function VariableCall(variable, index, currentFileInfo) { - var _this; - - _classCallCheck(this, VariableCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(VariableCall).call(this)); - _this.variable = variable; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.allowRoot = true; - return _this; - } - - _createClass(VariableCall, [{ - key: "eval", - value: function _eval(context) { - var rules; - var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); - var error = new LessError({ - message: "Could not evaluate variable call ".concat(this.variable) - }); - - if (!detachedRuleset.ruleset) { - if (detachedRuleset.rules) { - rules = detachedRuleset; - } else if (Array.isArray(detachedRuleset)) { - rules = new Ruleset('', detachedRuleset); - } else if (Array.isArray(detachedRuleset.value)) { - rules = new Ruleset('', detachedRuleset.value); - } else { - throw error; + var VariableCall = /** @class */ (function (_super) { + __extends(VariableCall, _super); + function VariableCall(variable, index, currentFileInfo) { + var _this = _super.call(this) || this; + _this.variable = variable; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.allowRoot = true; + return _this; + } + VariableCall.prototype.eval = function (context) { + var rules; + var detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context); + var error = new LessError({ message: "Could not evaluate variable call " + this.variable }); + if (!detachedRuleset.ruleset) { + if (detachedRuleset.rules) { + rules = detachedRuleset; + } + else if (Array.isArray(detachedRuleset)) { + rules = new Ruleset('', detachedRuleset); + } + else if (Array.isArray(detachedRuleset.value)) { + rules = new Ruleset('', detachedRuleset.value); + } + else { + throw error; + } + detachedRuleset = new DetachedRuleset(rules); } - - detachedRuleset = new DetachedRuleset(rules); - } - - if (detachedRuleset.ruleset) { - return detachedRuleset.callEval(context); - } - - throw error; - } - }]); - - return VariableCall; - }(Node); - - VariableCall.prototype.type = 'VariableCall'; - - var NamespaceValue = - /*#__PURE__*/ - function (_Node) { - _inherits(NamespaceValue, _Node); - - function NamespaceValue(ruleCall, lookups, important, index, fileInfo) { - var _this; - - _classCallCheck(this, NamespaceValue); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(NamespaceValue).call(this)); - _this.value = ruleCall; - _this.lookups = lookups; - _this.important = important; - _this._index = index; - _this._fileInfo = fileInfo; - return _this; - } - - _createClass(NamespaceValue, [{ - key: "eval", - value: function _eval(context) { - var i; - var name; - var rules = this.value.eval(context); - - for (i = 0; i < this.lookups.length; i++) { - name = this.lookups[i]; - /** - * Eval'd DRs return rulesets. - * Eval'd mixins return rules, so let's make a ruleset if we need it. - * We need to do this because of late parsing of values - */ - - if (Array.isArray(rules)) { - rules = new Ruleset([new Selector()], rules); + if (detachedRuleset.ruleset) { + return detachedRuleset.callEval(context); } + throw error; + }; + return VariableCall; + }(Node)); + VariableCall.prototype.type = 'VariableCall'; - if (name === '') { - rules = rules.lastDeclaration(); - } else if (name.charAt(0) === '@') { - if (name.charAt(1) === '@') { - name = "@".concat(new Variable(name.substr(1)).eval(context).value); - } - - if (rules.variables) { - rules = rules.variable(name); - } - - if (!rules) { - throw { - type: 'Name', - message: "variable ".concat(name, " not found"), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } - } else { - if (name.substring(0, 2) === '$@') { - name = "$".concat(new Variable(name.substr(1)).eval(context).value); - } else { - name = name.charAt(0) === '$' ? name : "$".concat(name); - } - - if (rules.properties) { - rules = rules.property(name); - } - - if (!rules) { - throw { - type: 'Name', - message: "property \"".concat(name.substr(1), "\" not found"), - filename: this.fileInfo().filename, - index: this.getIndex() - }; - } // Properties are an array of values, since a ruleset can have multiple props. - // We pick the last one (the "cascaded" value) - - - rules = rules[rules.length - 1]; + var NamespaceValue = /** @class */ (function (_super) { + __extends(NamespaceValue, _super); + function NamespaceValue(ruleCall, lookups, index, fileInfo) { + var _this = _super.call(this) || this; + _this.value = ruleCall; + _this.lookups = lookups; + _this._index = index; + _this._fileInfo = fileInfo; + return _this; + } + NamespaceValue.prototype.eval = function (context) { + var i; + var name; + var rules = this.value.eval(context); + for (i = 0; i < this.lookups.length; i++) { + name = this.lookups[i]; + /** + * Eval'd DRs return rulesets. + * Eval'd mixins return rules, so let's make a ruleset if we need it. + * We need to do this because of late parsing of values + */ + if (Array.isArray(rules)) { + rules = new Ruleset([new Selector()], rules); + } + if (name === '') { + rules = rules.lastDeclaration(); + } + else if (name.charAt(0) === '@') { + if (name.charAt(1) === '@') { + name = "@" + new Variable(name.substr(1)).eval(context).value; + } + if (rules.variables) { + rules = rules.variable(name); + } + if (!rules) { + throw { type: 'Name', + message: "variable " + name + " not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + } + else { + if (name.substring(0, 2) === '$@') { + name = "$" + new Variable(name.substr(1)).eval(context).value; + } + else { + name = name.charAt(0) === '$' ? name : "$" + name; + } + if (rules.properties) { + rules = rules.property(name); + } + if (!rules) { + throw { type: 'Name', + message: "property \"" + name.substr(1) + "\" not found", + filename: this.fileInfo().filename, + index: this.getIndex() }; + } + // Properties are an array of values, since a ruleset can have multiple props. + // We pick the last one (the "cascaded" value) + rules = rules[rules.length - 1]; + } + if (rules.value) { + rules = rules.eval(context).value; + } + if (rules.ruleset) { + rules = rules.ruleset.eval(context); + } } + return rules; + }; + return NamespaceValue; + }(Node)); + NamespaceValue.prototype.type = 'NamespaceValue'; - if (rules.value) { - rules = rules.eval(context).value; + var Definition = /** @class */ (function (_super) { + __extends(Definition, _super); + function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { + var _this = _super.call(this) || this; + _this.name = name || 'anonymous mixin'; + _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; + _this.params = params; + _this.condition = condition; + _this.variadic = variadic; + _this.arity = params.length; + _this.rules = rules; + _this._lookups = {}; + var optionalParameters = []; + _this.required = params.reduce(function (count, p) { + if (!p.name || (p.name && !p.value)) { + return count + 1; + } + else { + optionalParameters.push(p.name); + return count; + } + }, 0); + _this.optionalParameters = optionalParameters; + _this.frames = frames; + _this.copyVisibilityInfo(visibilityInfo); + _this.allowRoot = true; + return _this; + } + Definition.prototype.accept = function (visitor) { + if (this.params && this.params.length) { + this.params = visitor.visitArray(this.params); } - - if (rules.ruleset) { - rules = rules.ruleset.eval(context); + this.rules = visitor.visitArray(this.rules); + if (this.condition) { + this.condition = visitor.visit(this.condition); } - } - - return rules; - } - }]); - - return NamespaceValue; - }(Node); - - NamespaceValue.prototype.type = 'NamespaceValue'; - - var Definition = - /*#__PURE__*/ - function (_Ruleset) { - _inherits(Definition, _Ruleset); - - function Definition(name, params, rules, condition, variadic, frames, visibilityInfo) { - var _this; - - _classCallCheck(this, Definition); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(Definition).call(this)); - _this.name = name || 'anonymous mixin'; - _this.selectors = [new Selector([new Element(null, name, false, _this._index, _this._fileInfo)])]; - _this.params = params; - _this.condition = condition; - _this.variadic = variadic; - _this.arity = params.length; - _this.rules = rules; - _this._lookups = {}; - var optionalParameters = []; - _this.required = params.reduce(function (count, p) { - if (!p.name || p.name && !p.value) { - return count + 1; - } else { - optionalParameters.push(p.name); - return count; - } - }, 0); - _this.optionalParameters = optionalParameters; - _this.frames = frames; - - _this.copyVisibilityInfo(visibilityInfo); - - _this.allowRoot = true; - return _this; - } - - _createClass(Definition, [{ - key: "accept", - value: function accept(visitor) { - if (this.params && this.params.length) { - this.params = visitor.visitArray(this.params); - } - - this.rules = visitor.visitArray(this.rules); - - if (this.condition) { - this.condition = visitor.visit(this.condition); - } - } - }, { - key: "evalParams", - value: function evalParams(context, mixinEnv, args, evaldArguments) { - /* jshint boss:true */ - var frame = new Ruleset(null, null); - var varargs; - var arg; - var params = copyArray(this.params); - var i; - var j; - var val; - var name; - var isNamedFound; - var argIndex; - var argsLength = 0; - - if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { - frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); - } - - mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); - - if (args) { - args = copyArray(args); - argsLength = args.length; - - for (i = 0; i < argsLength; i++) { - arg = args[i]; - - if (name = arg && arg.name) { - isNamedFound = false; - - for (j = 0; j < params.length; j++) { - if (!evaldArguments[j] && name === params[j].name) { - evaldArguments[j] = arg.value.eval(context); - frame.prependRule(new Declaration(name, arg.value.eval(context))); - isNamedFound = true; - break; - } + }; + Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArguments) { + /* jshint boss:true */ + var frame = new Ruleset(null, null); + var varargs; + var arg; + var params = copyArray(this.params); + var i; + var j; + var val; + var name; + var isNamedFound; + var argIndex; + var argsLength = 0; + if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) { + frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit(); + } + mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames)); + if (args) { + args = copyArray(args); + argsLength = args.length; + for (i = 0; i < argsLength; i++) { + arg = args[i]; + if (name = (arg && arg.name)) { + isNamedFound = false; + for (j = 0; j < params.length; j++) { + if (!evaldArguments[j] && name === params[j].name) { + evaldArguments[j] = arg.value.eval(context); + frame.prependRule(new Declaration(name, arg.value.eval(context))); + isNamedFound = true; + break; + } + } + if (isNamedFound) { + args.splice(i, 1); + i--; + continue; + } + else { + throw { type: 'Runtime', message: "Named argument for " + this.name + " " + args[i].name + " not found" }; + } + } } - - if (isNamedFound) { - args.splice(i, 1); - i--; - continue; - } else { - throw { - type: 'Runtime', - message: "Named argument for ".concat(this.name, " ").concat(args[i].name, " not found") - }; - } - } - } - } - - argIndex = 0; - - for (i = 0; i < params.length; i++) { - if (evaldArguments[i]) { - continue; } - - arg = args && args[argIndex]; - - if (name = params[i].name) { - if (params[i].variadic) { - varargs = []; - - for (j = argIndex; j < argsLength; j++) { - varargs.push(args[j].value.eval(context)); + argIndex = 0; + for (i = 0; i < params.length; i++) { + if (evaldArguments[i]) { + continue; } - - frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); - } else { - val = arg && arg.value; - - if (val) { - // This was a mixin call, pass in a detached ruleset of it's eval'd rules - if (Array.isArray(val)) { - val = new DetachedRuleset(new Ruleset('', val)); - } else { - val = val.eval(context); - } - } else if (params[i].value) { - val = params[i].value.eval(mixinEnv); - frame.resetCache(); - } else { - throw { - type: 'Runtime', - message: "wrong number of arguments for ".concat(this.name, " (").concat(argsLength, " for ").concat(this.arity, ")") - }; + arg = args && args[argIndex]; + if (name = params[i].name) { + if (params[i].variadic) { + varargs = []; + for (j = argIndex; j < argsLength; j++) { + varargs.push(args[j].value.eval(context)); + } + frame.prependRule(new Declaration(name, new Expression(varargs).eval(context))); + } + else { + val = arg && arg.value; + if (val) { + // This was a mixin call, pass in a detached ruleset of it's eval'd rules + if (Array.isArray(val)) { + val = new DetachedRuleset(new Ruleset('', val)); + } + else { + val = val.eval(context); + } + } + else if (params[i].value) { + val = params[i].value.eval(mixinEnv); + frame.resetCache(); + } + else { + throw { type: 'Runtime', message: "wrong number of arguments for " + this.name + " (" + argsLength + " for " + this.arity + ")" }; + } + frame.prependRule(new Declaration(name, val)); + evaldArguments[i] = val; + } } - - frame.prependRule(new Declaration(name, val)); - evaldArguments[i] = val; - } - } - - if (params[i].variadic && args) { - for (j = argIndex; j < argsLength; j++) { - evaldArguments[j] = args[j].value.eval(context); - } + if (params[i].variadic && args) { + for (j = argIndex; j < argsLength; j++) { + evaldArguments[j] = args[j].value.eval(context); + } + } + argIndex++; } - - argIndex++; - } - - return frame; - } - }, { - key: "makeImportant", - value: function makeImportant() { - var rules = !this.rules ? this.rules : this.rules.map(function (r) { - if (r.makeImportant) { - return r.makeImportant(true); - } else { - return r; - } - }); - var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); - return result; - } - }, { - key: "eval", - value: function _eval(context) { - return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); - } - }, { - key: "evalCall", - value: function evalCall(context, args, important) { - var _arguments = []; - var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; - var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); - var rules; - var ruleset; - frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); - rules = copyArray(this.rules); - ruleset = new Ruleset(null, rules); - ruleset.originalRuleset = this; - ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); - - if (important) { - ruleset = ruleset.makeImportant(); - } - - return ruleset; - } - }, { - key: "matchCondition", - value: function matchCondition(args, context) { - if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, - /* the parameter variables */ - new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])].concat(this.frames || []) // the parent namespace/mixin frames - .concat(context.frames)))) { - // the current environment frames - return false; - } - - return true; - } - }, { - key: "matchArgs", - value: function matchArgs(args, context) { - var allArgsCnt = args && args.length || 0; - var len; - var optionalParameters = this.optionalParameters; - var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { - if (optionalParameters.indexOf(p.name) < 0) { - return count + 1; - } else { - return count; - } - }, 0); - - if (!this.variadic) { - if (requiredArgsCnt < this.required) { - return false; + return frame; + }; + Definition.prototype.makeImportant = function () { + var rules = !this.rules ? this.rules : this.rules.map(function (r) { + if (r.makeImportant) { + return r.makeImportant(true); + } + else { + return r; + } + }); + var result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames); + return result; + }; + Definition.prototype.eval = function (context) { + return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || copyArray(context.frames)); + }; + Definition.prototype.evalCall = function (context, args, important) { + var _arguments = []; + var mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames; + var frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments); + var rules; + var ruleset; + frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context))); + rules = copyArray(this.rules); + ruleset = new Ruleset(null, rules); + ruleset.originalRuleset = this; + ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames))); + if (important) { + ruleset = ruleset.makeImportant(); + } + return ruleset; + }; + Definition.prototype.matchCondition = function (args, context) { + if (this.condition && !this.condition.eval(new contexts.Eval(context, [this.evalParams(context, /* the parameter variables */ new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])] + .concat(this.frames || []) // the parent namespace/mixin frames + .concat(context.frames)))) { // the current environment frames + return false; } - - if (allArgsCnt > this.params.length) { - return false; + return true; + }; + Definition.prototype.matchArgs = function (args, context) { + var allArgsCnt = (args && args.length) || 0; + var len; + var optionalParameters = this.optionalParameters; + var requiredArgsCnt = !args ? 0 : args.reduce(function (count, p) { + if (optionalParameters.indexOf(p.name) < 0) { + return count + 1; + } + else { + return count; + } + }, 0); + if (!this.variadic) { + if (requiredArgsCnt < this.required) { + return false; + } + if (allArgsCnt > this.params.length) { + return false; + } } - } else { - if (requiredArgsCnt < this.required - 1) { - return false; + else { + if (requiredArgsCnt < (this.required - 1)) { + return false; + } } - } // check patterns - - - len = Math.min(requiredArgsCnt, this.arity); - - for (var i = 0; i < len; i++) { - if (!this.params[i].name && !this.params[i].variadic) { - if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) { - return false; - } + // check patterns + len = Math.min(requiredArgsCnt, this.arity); + for (var i_1 = 0; i_1 < len; i_1++) { + if (!this.params[i_1].name && !this.params[i_1].variadic) { + if (args[i_1].value.eval(context).toCSS() != this.params[i_1].value.eval(context).toCSS()) { + return false; + } + } } - } - - return true; - } - }]); - - return Definition; - }(Ruleset); - + return true; + }; + return Definition; + }(Ruleset)); Definition.prototype.type = 'MixinDefinition'; Definition.prototype.evalFirst = true; - var MixinCall = - /*#__PURE__*/ - function (_Node) { - _inherits(MixinCall, _Node); - - function MixinCall(elements, args, index, currentFileInfo, important) { - var _this; - - _classCallCheck(this, MixinCall); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(MixinCall).call(this)); - _this.selector = new Selector(elements); - _this.arguments = args || []; - _this._index = index; - _this._fileInfo = currentFileInfo; - _this.important = important; - _this.allowRoot = true; - - _this.setParent(_this.selector, _assertThisInitialized(_this)); - - return _this; - } - - _createClass(MixinCall, [{ - key: "accept", - value: function accept(visitor) { - if (this.selector) { - this.selector = visitor.visit(this.selector); - } - - if (this.arguments.length) { - this.arguments = visitor.visitArray(this.arguments); - } - } - }, { - key: "eval", - value: function _eval(context) { - var mixins; - var mixin; - var mixinPath; - var args = []; - var arg; - var argValue; - var rules = []; - var match = false; - var i; - var m; - var f; - var isRecursive; - var isOneFound; - var candidates = []; - var candidate; - var conditionResult = []; - var defaultResult; - var defFalseEitherCase = -1; - var defNone = 0; - var defTrue = 1; - var defFalse = 2; - var count; - var originalRuleset; - var noArgumentsFilter; - this.selector = this.selector.eval(context); - - function calcDefGroup(mixin, mixinPath) { + var MixinCall = /** @class */ (function (_super) { + __extends(MixinCall, _super); + function MixinCall(elements, args, index, currentFileInfo, important) { + var _this = _super.call(this) || this; + _this.selector = new Selector(elements); + _this.arguments = args || []; + _this._index = index; + _this._fileInfo = currentFileInfo; + _this.important = important; + _this.allowRoot = true; + _this.setParent(_this.selector, _this); + return _this; + } + MixinCall.prototype.accept = function (visitor) { + if (this.selector) { + this.selector = visitor.visit(this.selector); + } + if (this.arguments.length) { + this.arguments = visitor.visitArray(this.arguments); + } + }; + MixinCall.prototype.eval = function (context) { + var mixins; + var mixin; + var mixinPath; + var args = []; + var arg; + var argValue; + var rules = []; + var match = false; + var i; + var m; var f; - var p; - var namespace; - - for (f = 0; f < 2; f++) { - conditionResult[f] = true; - defaultFunc.value(f); - - for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { - namespace = mixinPath[p]; - - if (namespace.matchCondition) { - conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + var isRecursive; + var isOneFound; + var candidates = []; + var candidate; + var conditionResult = []; + var defaultResult; + var defFalseEitherCase = -1; + var defNone = 0; + var defTrue = 1; + var defFalse = 2; + var count; + var originalRuleset; + var noArgumentsFilter; + this.selector = this.selector.eval(context); + function calcDefGroup(mixin, mixinPath) { + var f; + var p; + var namespace; + for (f = 0; f < 2; f++) { + conditionResult[f] = true; + defaultFunc.value(f); + for (p = 0; p < mixinPath.length && conditionResult[f]; p++) { + namespace = mixinPath[p]; + if (namespace.matchCondition) { + conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context); + } + } + if (mixin.matchCondition) { + conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); + } } - } - - if (mixin.matchCondition) { - conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context); - } - } - - if (conditionResult[0] || conditionResult[1]) { - if (conditionResult[0] != conditionResult[1]) { - return conditionResult[1] ? defTrue : defFalse; - } - - return defNone; - } - - return defFalseEitherCase; - } - - for (i = 0; i < this.arguments.length; i++) { - arg = this.arguments[i]; - argValue = arg.value.eval(context); - - if (arg.expand && Array.isArray(argValue.value)) { - argValue = argValue.value; - - for (m = 0; m < argValue.length; m++) { - args.push({ - value: argValue[m] - }); - } - } else { - args.push({ - name: arg.name, - value: argValue - }); - } - } - - noArgumentsFilter = function noArgumentsFilter(rule) { - return rule.matchArgs(null, context); - }; - - for (i = 0; i < context.frames.length; i++) { - if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { - isOneFound = true; // To make `default()` function independent of definition order we have two "subpasses" here. - // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), - // and build candidate list with corresponding flags. Then, when we know all possible matches, - // we make a final decision. - - for (m = 0; m < mixins.length; m++) { - mixin = mixins[m].rule; - mixinPath = mixins[m].path; - isRecursive = false; - - for (f = 0; f < context.frames.length; f++) { - if (!(mixin instanceof Definition) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { - isRecursive = true; - break; - } + if (conditionResult[0] || conditionResult[1]) { + if (conditionResult[0] != conditionResult[1]) { + return conditionResult[1] ? + defTrue : defFalse; + } + return defNone; } - - if (isRecursive) { - continue; + return defFalseEitherCase; + } + for (i = 0; i < this.arguments.length; i++) { + arg = this.arguments[i]; + argValue = arg.value.eval(context); + if (arg.expand && Array.isArray(argValue.value)) { + argValue = argValue.value; + for (m = 0; m < argValue.length; m++) { + args.push({ value: argValue[m] }); + } } - - if (mixin.matchArgs(args, context)) { - candidate = { - mixin: mixin, - group: calcDefGroup(mixin, mixinPath) - }; - - if (candidate.group !== defFalseEitherCase) { - candidates.push(candidate); - } - - match = true; + else { + args.push({ name: arg.name, value: argValue }); } - } - - defaultFunc.reset(); - count = [0, 0, 0]; - - for (m = 0; m < candidates.length; m++) { - count[candidates[m].group]++; - } - - if (count[defNone] > 0) { - defaultResult = defFalse; - } else { - defaultResult = defTrue; - - if (count[defTrue] + count[defFalse] > 1) { - throw { - type: 'Runtime', - message: "Ambiguous use of `default()` found when matching for `".concat(this.format(args), "`"), - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - - for (m = 0; m < candidates.length; m++) { - candidate = candidates[m].group; - - if (candidate === defNone || candidate === defaultResult) { - try { - mixin = candidates[m].mixin; - - if (!(mixin instanceof Definition)) { - originalRuleset = mixin.originalRuleset || mixin; - mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); - mixin.originalRuleset = originalRuleset; + } + noArgumentsFilter = function (rule) { return rule.matchArgs(null, context); }; + for (i = 0; i < context.frames.length; i++) { + if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) { + isOneFound = true; + // To make `default()` function independent of definition order we have two "subpasses" here. + // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`), + // and build candidate list with corresponding flags. Then, when we know all possible matches, + // we make a final decision. + for (m = 0; m < mixins.length; m++) { + mixin = mixins[m].rule; + mixinPath = mixins[m].path; + isRecursive = false; + for (f = 0; f < context.frames.length; f++) { + if ((!(mixin instanceof Definition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) { + isRecursive = true; + break; + } + } + if (isRecursive) { + continue; + } + if (mixin.matchArgs(args, context)) { + candidate = { mixin: mixin, group: calcDefGroup(mixin, mixinPath) }; + if (candidate.group !== defFalseEitherCase) { + candidates.push(candidate); + } + match = true; + } + } + defaultFunc.reset(); + count = [0, 0, 0]; + for (m = 0; m < candidates.length; m++) { + count[candidates[m].group]++; + } + if (count[defNone] > 0) { + defaultResult = defFalse; + } + else { + defaultResult = defTrue; + if ((count[defTrue] + count[defFalse]) > 1) { + throw { type: 'Runtime', + message: "Ambiguous use of `default()` found when matching for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; + } + } + for (m = 0; m < candidates.length; m++) { + candidate = candidates[m].group; + if ((candidate === defNone) || (candidate === defaultResult)) { + try { + mixin = candidates[m].mixin; + if (!(mixin instanceof Definition)) { + originalRuleset = mixin.originalRuleset || mixin; + mixin = new Definition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo()); + mixin.originalRuleset = originalRuleset; + } + var newRules = mixin.evalCall(context, args, this.important).rules; + this._setVisibilityToReplacement(newRules); + Array.prototype.push.apply(rules, newRules); + } + catch (e) { + throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack }; + } + } + } + if (match) { + return rules; } - - var newRules = mixin.evalCall(context, args, this.important).rules; - - this._setVisibilityToReplacement(newRules); - - Array.prototype.push.apply(rules, newRules); - } catch (e) { - throw { - message: e.message, - index: this.getIndex(), - filename: this.fileInfo().filename, - stack: e.stack - }; - } } - } - - if (match) { - return rules; - } } - } - - if (isOneFound) { - throw { - type: 'Runtime', - message: "No matching definition was found for `".concat(this.format(args), "`"), - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } else { - throw { - type: 'Name', - message: "".concat(this.selector.toCSS().trim(), " is undefined"), - index: this.getIndex(), - filename: this.fileInfo().filename - }; - } - } - }, { - key: "_setVisibilityToReplacement", - value: function _setVisibilityToReplacement(replacement) { - var i; - var rule; - - if (this.blocksVisibility()) { - for (i = 0; i < replacement.length; i++) { - rule = replacement[i]; - rule.addVisibilityBlock(); - } - } - } - }, { - key: "format", - value: function format(args) { - return "".concat(this.selector.toCSS().trim(), "(").concat(args ? args.map(function (a) { - var argValue = ''; - - if (a.name) { - argValue += "".concat(a.name, ":"); + if (isOneFound) { + throw { type: 'Runtime', + message: "No matching definition was found for `" + this.format(args) + "`", + index: this.getIndex(), filename: this.fileInfo().filename }; } - - if (a.value.toCSS) { - argValue += a.value.toCSS(); - } else { - argValue += '???'; + else { + throw { type: 'Name', + message: this.selector.toCSS().trim() + " is undefined", + index: this.getIndex(), filename: this.fileInfo().filename }; } - - return argValue; - }).join(', ') : '', ")"); - } - }]); - - return MixinCall; - }(Node); - + }; + MixinCall.prototype._setVisibilityToReplacement = function (replacement) { + var i; + var rule; + if (this.blocksVisibility()) { + for (i = 0; i < replacement.length; i++) { + rule = replacement[i]; + rule.addVisibilityBlock(); + } + } + }; + MixinCall.prototype.format = function (args) { + return this.selector.toCSS().trim() + "(" + (args ? args.map(function (a) { + var argValue = ''; + if (a.name) { + argValue += a.name + ":"; + } + if (a.value.toCSS) { + argValue += a.value.toCSS(); + } + else { + argValue += '???'; + } + return argValue; + }).join(', ') : '') + ")"; + }; + return MixinCall; + }(Node)); MixinCall.prototype.type = 'MixinCall'; var tree = { - Node: Node, - Color: Color, - AtRule: AtRule, - DetachedRuleset: DetachedRuleset, - Operation: Operation, - Dimension: Dimension, - Unit: Unit, - Keyword: Keyword, - Variable: Variable, - Property: Property, - Ruleset: Ruleset, - Element: Element, - Attribute: Attribute, - Combinator: Combinator, - Selector: Selector, - Quoted: Quoted, - Expression: Expression, - Declaration: Declaration, - Call: Call, - URL: URL, - Import: Import, - Comment: Comment, - Anonymous: Anonymous, - Value: Value, - JavaScript: JavaScript, - Assignment: Assignment, - Condition: Condition, - Paren: Paren, - Media: Media, - UnicodeDescriptor: UnicodeDescriptor, - Negative: Negative, - Extend: Extend, - VariableCall: VariableCall, - NamespaceValue: NamespaceValue, - mixin: { - Call: MixinCall, - Definition: Definition - } + Node: Node, Color: Color, AtRule: AtRule, DetachedRuleset: DetachedRuleset, Operation: Operation, + Dimension: Dimension, Unit: Unit, Keyword: Keyword, Variable: Variable, Property: Property, + Ruleset: Ruleset, Element: Element, Attribute: Attribute, Combinator: Combinator, Selector: Selector, + Quoted: Quoted, Expression: Expression, Declaration: Declaration, Call: Call, URL: URL, Import: Import, + Comment: Comment, Anonymous: Anonymous, Value: Value, JavaScript: JavaScript, Assignment: Assignment, + Condition: Condition, Paren: Paren, Media: Media, UnicodeDescriptor: UnicodeDescriptor, Negative: Negative, + Extend: Extend, VariableCall: VariableCall, NamespaceValue: NamespaceValue, + mixin: { + Call: MixinCall, + Definition: Definition + } }; var logger = { - error: function error(msg) { - this._fireEvent('error', msg); - }, - warn: function warn(msg) { - this._fireEvent('warn', msg); - }, - info: function info(msg) { - this._fireEvent('info', msg); - }, - debug: function debug(msg) { - this._fireEvent('debug', msg); - }, - addListener: function addListener(listener) { - this._listeners.push(listener); - }, - removeListener: function removeListener(listener) { - for (var i = 0; i < this._listeners.length; i++) { - if (this._listeners[i] === listener) { - this._listeners.splice(i, 1); - - return; - } - } - }, - _fireEvent: function _fireEvent(type, msg) { - for (var i = 0; i < this._listeners.length; i++) { - var logFunction = this._listeners[i][type]; - - if (logFunction) { - logFunction(msg); - } - } - }, - _listeners: [] + error: function (msg) { + this._fireEvent('error', msg); + }, + warn: function (msg) { + this._fireEvent('warn', msg); + }, + info: function (msg) { + this._fireEvent('info', msg); + }, + debug: function (msg) { + this._fireEvent('debug', msg); + }, + addListener: function (listener) { + this._listeners.push(listener); + }, + removeListener: function (listener) { + for (var i_1 = 0; i_1 < this._listeners.length; i_1++) { + if (this._listeners[i_1] === listener) { + this._listeners.splice(i_1, 1); + return; + } + } + }, + _fireEvent: function (type, msg) { + for (var i_2 = 0; i_2 < this._listeners.length; i_2++) { + var logFunction = this._listeners[i_2][type]; + if (logFunction) { + logFunction(msg); + } + } + }, + _listeners: [] }; - var environment = - /*#__PURE__*/ - function () { - function environment(externalEnvironment, fileManagers) { - _classCallCheck(this, environment); - - this.fileManagers = fileManagers || []; - externalEnvironment = externalEnvironment || {}; - var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; - var requiredFunctions = []; - var functions = requiredFunctions.concat(optionalFunctions); - - for (var i = 0; i < functions.length; i++) { - var propName = functions[i]; - var environmentFunc = externalEnvironment[propName]; - - if (environmentFunc) { - this[propName] = environmentFunc.bind(externalEnvironment); - } else if (i < requiredFunctions.length) { - this.warn("missing required function in environment - ".concat(propName)); - } + /** + * @todo Document why this abstraction exists, and the relationship between + * environment, file managers, and plugin manager + */ + var environment = /** @class */ (function () { + function environment(externalEnvironment, fileManagers) { + this.fileManagers = fileManagers || []; + externalEnvironment = externalEnvironment || {}; + var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator']; + var requiredFunctions = []; + var functions = requiredFunctions.concat(optionalFunctions); + for (var i_1 = 0; i_1 < functions.length; i_1++) { + var propName = functions[i_1]; + var environmentFunc = externalEnvironment[propName]; + if (environmentFunc) { + this[propName] = environmentFunc.bind(externalEnvironment); + } + else if (i_1 < requiredFunctions.length) { + this.warn("missing required function in environment - " + propName); + } + } } - } - - _createClass(environment, [{ - key: "getFileManager", - value: function getFileManager(filename, currentDirectory, options, environment, isSync) { - if (!filename) { - logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); - } - - if (currentDirectory == null) { - logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); - } - - var fileManagers = this.fileManagers; - - if (options.pluginManager) { - fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); - } - - for (var i = fileManagers.length - 1; i >= 0; i--) { - var fileManager = fileManagers[i]; - - if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { - return fileManager; + environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) { + if (!filename) { + logger.warn('getFileManager called with no filename.. Please report this issue. continuing.'); } - } - - return null; - } - }, { - key: "addFileManager", - value: function addFileManager(fileManager) { - this.fileManagers.push(fileManager); - } - }, { - key: "clearFileManagers", - value: function clearFileManagers() { - this.fileManagers = []; - } - }]); - - return environment; - }(); - - var AbstractFileManager = - /*#__PURE__*/ - function () { - function AbstractFileManager() { - _classCallCheck(this, AbstractFileManager); - } - - _createClass(AbstractFileManager, [{ - key: "getPath", - value: function getPath(filename) { - var j = filename.lastIndexOf('?'); - - if (j > 0) { - filename = filename.slice(0, j); - } - - j = filename.lastIndexOf('/'); - - if (j < 0) { - j = filename.lastIndexOf('\\'); - } - - if (j < 0) { - return ''; - } - - return filename.slice(0, j + 1); - } - }, { - key: "tryAppendExtension", - value: function tryAppendExtension(path, ext) { - return /(\.[a-z]*$)|([\?;].*)$/.test(path) ? path : path + ext; - } - }, { - key: "tryAppendLessExtension", - value: function tryAppendLessExtension(path) { - return this.tryAppendExtension(path, '.less'); - } - }, { - key: "supportsSync", - value: function supportsSync() { - return false; - } - }, { - key: "alwaysMakePathsAbsolute", - value: function alwaysMakePathsAbsolute() { - return false; - } - }, { - key: "isPathAbsolute", - value: function isPathAbsolute(filename) { - return /^(?:[a-z-]+:|\/|\\|#)/i.test(filename); - } // TODO: pull out / replace? - - }, { - key: "join", - value: function join(basePath, laterPath) { - if (!basePath) { - return laterPath; - } - - return basePath + laterPath; - } - }, { - key: "pathDiff", - value: function pathDiff(url, baseUrl) { - // diff between two paths to create a relative path - var urlParts = this.extractUrlParts(url); - var baseUrlParts = this.extractUrlParts(baseUrl); - var i; - var max; - var urlDirectories; - var baseUrlDirectories; - var diff = ''; - - if (urlParts.hostPart !== baseUrlParts.hostPart) { - return ''; - } - - max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); - - for (i = 0; i < max; i++) { - if (baseUrlParts.directories[i] !== urlParts.directories[i]) { - break; + if (currentDirectory == null) { + logger.warn('getFileManager called with null directory.. Please report this issue. continuing.'); } - } - - baseUrlDirectories = baseUrlParts.directories.slice(i); - urlDirectories = urlParts.directories.slice(i); - - for (i = 0; i < baseUrlDirectories.length - 1; i++) { - diff += '../'; - } - - for (i = 0; i < urlDirectories.length - 1; i++) { - diff += "".concat(urlDirectories[i], "/"); - } + var fileManagers = this.fileManagers; + if (options.pluginManager) { + fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers()); + } + for (var i_2 = fileManagers.length - 1; i_2 >= 0; i_2--) { + var fileManager = fileManagers[i_2]; + if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) { + return fileManager; + } + } + return null; + }; + environment.prototype.addFileManager = function (fileManager) { + this.fileManagers.push(fileManager); + }; + environment.prototype.clearFileManagers = function () { + this.fileManagers = []; + }; + return environment; + }()); - return diff; + var AbstractFileManager = /** @class */ (function () { + function AbstractFileManager() { } - }, { - key: "extractUrlParts", + AbstractFileManager.prototype.getPath = function (filename) { + var j = filename.lastIndexOf('?'); + if (j > 0) { + filename = filename.slice(0, j); + } + j = filename.lastIndexOf('/'); + if (j < 0) { + j = filename.lastIndexOf('\\'); + } + if (j < 0) { + return ''; + } + return filename.slice(0, j + 1); + }; + AbstractFileManager.prototype.isPathWithExtension = function (path, ext) { + var extPos = path.lastIndexOf(ext); + return extPos !== -1 && extPos === path.length - ext.length; + }; + AbstractFileManager.prototype.tryAppendExtension = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return path; + } + return path + ext; + }; + AbstractFileManager.prototype.tryAppendLessExtension = function (path) { + return this.tryAppendExtension(path, '.less'); + }; + AbstractFileManager.prototype.supportsSync = function () { return false; }; + AbstractFileManager.prototype.alwaysMakePathsAbsolute = function () { return false; }; + AbstractFileManager.prototype.isPathAbsolute = function (filename) { + return (/^(?:[a-z-]+:|\/|\\|#)/i).test(filename); + }; + // TODO: pull out / replace? + AbstractFileManager.prototype.join = function (basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return basePath + laterPath; + }; + AbstractFileManager.prototype.pathDiff = function (url, baseUrl) { + // diff between two paths to create a relative path + var urlParts = this.extractUrlParts(url); + var baseUrlParts = this.extractUrlParts(baseUrl); + var i; + var max; + var urlDirectories; + var baseUrlDirectories; + var diff = ''; + if (urlParts.hostPart !== baseUrlParts.hostPart) { + return ''; + } + max = Math.max(baseUrlParts.directories.length, urlParts.directories.length); + for (i = 0; i < max; i++) { + if (baseUrlParts.directories[i] !== urlParts.directories[i]) { + break; + } + } + baseUrlDirectories = baseUrlParts.directories.slice(i); + urlDirectories = urlParts.directories.slice(i); + for (i = 0; i < baseUrlDirectories.length - 1; i++) { + diff += '../'; + } + for (i = 0; i < urlDirectories.length - 1; i++) { + diff += urlDirectories[i] + "/"; + } + return diff; + }; // helper function, not part of API - value: function extractUrlParts(url, baseUrl) { - // urlParts[1] = protocol://hostname/ OR / - // urlParts[2] = / if path relative to host base - // urlParts[3] = directories - // urlParts[4] = filename - // urlParts[5] = parameters - var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; - var urlParts = url.match(urlPartsRegex); - var returner = {}; - var rawDirectories = []; - var directories = []; - var i; - var baseUrlParts; - - if (!urlParts) { - throw new Error("Could not parse sheet href - '".concat(url, "'")); - } // Stylesheets in IE don't always return the full path - - - if (baseUrl && (!urlParts[1] || urlParts[2])) { - baseUrlParts = baseUrl.match(urlPartsRegex); - - if (!baseUrlParts) { - throw new Error("Could not parse page url - '".concat(baseUrl, "'")); + AbstractFileManager.prototype.extractUrlParts = function (url, baseUrl) { + // urlParts[1] = protocol://hostname/ OR / + // urlParts[2] = / if path relative to host base + // urlParts[3] = directories + // urlParts[4] = filename + // urlParts[5] = parameters + var urlPartsRegex = /^((?:[a-z-]+:)?\/{2}(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i; + var urlParts = url.match(urlPartsRegex); + var returner = {}; + var rawDirectories = []; + var directories = []; + var i; + var baseUrlParts; + if (!urlParts) { + throw new Error("Could not parse sheet href - '" + url + "'"); + } + // Stylesheets in IE don't always return the full path + if (baseUrl && (!urlParts[1] || urlParts[2])) { + baseUrlParts = baseUrl.match(urlPartsRegex); + if (!baseUrlParts) { + throw new Error("Could not parse page url - '" + baseUrl + "'"); + } + urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; + if (!urlParts[2]) { + urlParts[3] = baseUrlParts[3] + urlParts[3]; + } } - - urlParts[1] = urlParts[1] || baseUrlParts[1] || ''; - - if (!urlParts[2]) { - urlParts[3] = baseUrlParts[3] + urlParts[3]; + if (urlParts[3]) { + rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); + // collapse '..' and skip '.' + for (i = 0; i < rawDirectories.length; i++) { + if (rawDirectories[i] === '..') { + directories.pop(); + } + else if (rawDirectories[i] !== '.') { + directories.push(rawDirectories[i]); + } + } } - } - - if (urlParts[3]) { - rawDirectories = urlParts[3].replace(/\\/g, '/').split('/'); // collapse '..' and skip '.' - - for (i = 0; i < rawDirectories.length; i++) { - if (rawDirectories[i] === '..') { - directories.pop(); - } else if (rawDirectories[i] !== '.') { - directories.push(rawDirectories[i]); - } - } - } - - returner.hostPart = urlParts[1]; - returner.directories = directories; - returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); - returner.path = (urlParts[1] || '') + directories.join('/'); - returner.filename = urlParts[4]; - returner.fileUrl = returner.path + (urlParts[4] || ''); - returner.url = returner.fileUrl + (urlParts[5] || ''); - return returner; - } - }]); - - return AbstractFileManager; - }(); - - var AbstractPluginLoader = - /*#__PURE__*/ - function () { - function AbstractPluginLoader() { - _classCallCheck(this, AbstractPluginLoader); - - // Implemented by Node.js plugin loader - this.require = function () { - return null; + returner.hostPart = urlParts[1]; + returner.directories = directories; + returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/'); + returner.path = (urlParts[1] || '') + directories.join('/'); + returner.filename = urlParts[4]; + returner.fileUrl = returner.path + (urlParts[4] || ''); + returner.url = returner.fileUrl + (urlParts[5] || ''); + return returner; }; - } - - _createClass(AbstractPluginLoader, [{ - key: "evalPlugin", - value: function evalPlugin(contents, context, imports, pluginOptions, fileInfo) { - var loader; - var registry; - var pluginObj; - var localModule; - var pluginManager; - var filename; - var result; - pluginManager = context.pluginManager; - - if (fileInfo) { - if (typeof fileInfo === 'string') { - filename = fileInfo; - } else { - filename = fileInfo.filename; + return AbstractFileManager; + }()); + + var AbstractPluginLoader = /** @class */ (function () { + function AbstractPluginLoader() { + // Implemented by Node.js plugin loader + this.require = function () { return null; }; + } + AbstractPluginLoader.prototype.evalPlugin = function (contents, context, imports, pluginOptions, fileInfo) { + var loader; + var registry; + var pluginObj; + var localModule; + var pluginManager; + var filename; + var result; + pluginManager = context.pluginManager; + if (fileInfo) { + if (typeof fileInfo === 'string') { + filename = fileInfo; + } + else { + filename = fileInfo.filename; + } } - } - - var shortname = new this.less.FileManager().extractUrlParts(filename).filename; - - if (filename) { - pluginObj = pluginManager.get(filename); - - if (pluginObj) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - - try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); + var shortname = (new this.less.FileManager()).extractUrlParts(filename).filename; + if (filename) { + pluginObj = pluginManager.get(filename); + if (pluginObj) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + return pluginObj; } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - - return pluginObj; } - } - - localModule = { - exports: {}, - pluginManager: pluginManager, - fileInfo: fileInfo - }; - registry = functionRegistry.create(); - - var registerPlugin = function registerPlugin(obj) { - pluginObj = obj; - }; - - try { - loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); - loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); - } catch (e) { - return new LessError(e, imports, filename); - } - - if (!pluginObj) { - pluginObj = localModule.exports; - } - - pluginObj = this.validatePlugin(pluginObj, filename, shortname); - - if (pluginObj instanceof LessError) { - return pluginObj; - } - - if (pluginObj) { - pluginObj.imports = imports; - pluginObj.filename = filename; // For < 3.x (or unspecified minVersion) - setOptions() before install() - - if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } - } // Run on first load - - - pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); - pluginObj.functions = registry.getLocalFunctions(); // Need to call setOptions again because the pluginObj might have functions - - result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); - - if (result) { - return result; - } // Run every @plugin call - - + localModule = { + exports: {}, + pluginManager: pluginManager, + fileInfo: fileInfo + }; + registry = functionRegistry.create(); + var registerPlugin = function (obj) { + pluginObj = obj; + }; try { - if (pluginObj.use) { - pluginObj.use.call(this.context, pluginObj); - } - } catch (e) { - e.message = e.message || 'Error during @plugin call'; - return new LessError(e, imports, filename); - } - } else { - return new LessError({ - message: 'Not a valid plugin' - }, imports, filename); - } - - return pluginObj; - } - }, { - key: "trySetOptions", - value: function trySetOptions(plugin, filename, name, options) { - if (options && !plugin.setOptions) { - return new LessError({ - message: "Options have been provided but the plugin ".concat(name, " does not support any options.") - }); - } - - try { - plugin.setOptions && plugin.setOptions(options); - } catch (e) { - return new LessError(e); - } - } - }, { - key: "validatePlugin", - value: function validatePlugin(plugin, filename, name) { - if (plugin) { - // support plugins being a function - // so that the plugin can be more usable programmatically - if (typeof plugin === 'function') { - plugin = new plugin(); + loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents); + loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo); } - - if (plugin.minVersion) { - if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + catch (e) { + return new LessError(e, imports, filename); + } + if (!pluginObj) { + pluginObj = localModule.exports; + } + pluginObj = this.validatePlugin(pluginObj, filename, shortname); + if (pluginObj instanceof LessError) { + return pluginObj; + } + if (pluginObj) { + pluginObj.imports = imports; + pluginObj.filename = filename; + // For < 3.x (or unspecified minVersion) - setOptions() before install() + if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) { + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + } + // Run on first load + pluginManager.addPlugin(pluginObj, fileInfo.filename, registry); + pluginObj.functions = registry.getLocalFunctions(); + // Need to call setOptions again because the pluginObj might have functions + result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions); + if (result) { + return result; + } + // Run every @plugin call + try { + if (pluginObj.use) { + pluginObj.use.call(this.context, pluginObj); + } + } + catch (e) { + e.message = e.message || 'Error during @plugin call'; + return new LessError(e, imports, filename); + } + } + else { + return new LessError({ message: 'Not a valid plugin' }, imports, filename); + } + return pluginObj; + }; + AbstractPluginLoader.prototype.trySetOptions = function (plugin, filename, name, options) { + if (options && !plugin.setOptions) { return new LessError({ - message: "Plugin ".concat(name, " requires version ").concat(this.versionToString(plugin.minVersion)) + message: "Options have been provided but the plugin " + name + " does not support any options." }); - } } - - return plugin; - } - - return null; - } - }, { - key: "compareVersion", - value: function compareVersion(aVersion, bVersion) { - if (typeof aVersion === 'string') { - aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); - aVersion.shift(); - } - - for (var i = 0; i < aVersion.length; i++) { - if (aVersion[i] !== bVersion[i]) { - return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1; + try { + plugin.setOptions && plugin.setOptions(options); } - } - - return 0; - } - }, { - key: "versionToString", - value: function versionToString(version) { - var versionString = ''; - - for (var i = 0; i < version.length; i++) { - versionString += (versionString ? '.' : '') + version[i]; - } - - return versionString; - } - }, { - key: "printUsage", - value: function printUsage(plugins) { - for (var i = 0; i < plugins.length; i++) { - var plugin = plugins[i]; - - if (plugin.printUsage) { - plugin.printUsage(); + catch (e) { + return new LessError(e); } - } - } - }]); - - return AbstractPluginLoader; - }(); + }; + AbstractPluginLoader.prototype.validatePlugin = function (plugin, filename, name) { + if (plugin) { + // support plugins being a function + // so that the plugin can be more usable programmatically + if (typeof plugin === 'function') { + plugin = new plugin(); + } + if (plugin.minVersion) { + if (this.compareVersion(plugin.minVersion, this.less.version) < 0) { + return new LessError({ + message: "Plugin " + name + " requires version " + this.versionToString(plugin.minVersion) + }); + } + } + return plugin; + } + return null; + }; + AbstractPluginLoader.prototype.compareVersion = function (aVersion, bVersion) { + if (typeof aVersion === 'string') { + aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/); + aVersion.shift(); + } + for (var i_1 = 0; i_1 < aVersion.length; i_1++) { + if (aVersion[i_1] !== bVersion[i_1]) { + return parseInt(aVersion[i_1]) > parseInt(bVersion[i_1]) ? -1 : 1; + } + } + return 0; + }; + AbstractPluginLoader.prototype.versionToString = function (version) { + var versionString = ''; + for (var i_2 = 0; i_2 < version.length; i_2++) { + versionString += (versionString ? '.' : '') + version[i_2]; + } + return versionString; + }; + AbstractPluginLoader.prototype.printUsage = function (plugins) { + for (var i_3 = 0; i_3 < plugins.length; i_3++) { + var plugin = plugins[i_3]; + if (plugin.printUsage) { + plugin.printUsage(); + } + } + }; + return AbstractPluginLoader; + }()); - var _visitArgs = { - visitDeeper: true - }; + var _visitArgs = { visitDeeper: true }; var _hasIndexed = false; - function _noop(node) { - return node; + return node; } - function indexNodeTypes(parent, ticker) { - // add .typeIndex to tree node types for lookup table - var key; - var child; - - for (key in parent) { - /* eslint guard-for-in: 0 */ - child = parent[key]; - - switch (_typeof(child)) { - case 'function': - // ignore bound functions directly on tree which do not have a prototype - // or aren't nodes - if (child.prototype && child.prototype.type) { - child.prototype.typeIndex = ticker++; + // add .typeIndex to tree node types for lookup table + var key; + var child; + for (key in parent) { + /* eslint guard-for-in: 0 */ + child = parent[key]; + switch (typeof child) { + case 'function': + // ignore bound functions directly on tree which do not have a prototype + // or aren't nodes + if (child.prototype && child.prototype.type) { + child.prototype.typeIndex = ticker++; + } + break; + case 'object': + ticker = indexNodeTypes(child, ticker); + break; } - - break; - - case 'object': - ticker = indexNodeTypes(child, ticker); - break; } - } - - return ticker; + return ticker; } - - var Visitor = - /*#__PURE__*/ - function () { - function Visitor(implementation) { - _classCallCheck(this, Visitor); - - this._implementation = implementation; - this._visitInCache = {}; - this._visitOutCache = {}; - - if (!_hasIndexed) { - indexNodeTypes(tree, 1); - _hasIndexed = true; - } - } - - _createClass(Visitor, [{ - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - var nodeTypeIndex = node.typeIndex; - - if (!nodeTypeIndex) { - // MixinCall args aren't a node type? - if (node.value && node.value.typeIndex) { - this.visit(node.value); + var Visitor = /** @class */ (function () { + function Visitor(implementation) { + this._implementation = implementation; + this._visitInCache = {}; + this._visitOutCache = {}; + if (!_hasIndexed) { + indexNodeTypes(tree, 1); + _hasIndexed = true; + } + } + Visitor.prototype.visit = function (node) { + if (!node) { + return node; + } + var nodeTypeIndex = node.typeIndex; + if (!nodeTypeIndex) { + // MixinCall args aren't a node type? + if (node.value && node.value.typeIndex) { + this.visit(node.value); + } + return node; + } + var impl = this._implementation; + var func = this._visitInCache[nodeTypeIndex]; + var funcOut = this._visitOutCache[nodeTypeIndex]; + var visitArgs = _visitArgs; + var fnName; + visitArgs.visitDeeper = true; + if (!func) { + fnName = "visit" + node.type; + func = impl[fnName] || _noop; + funcOut = impl[fnName + "Out"] || _noop; + this._visitInCache[nodeTypeIndex] = func; + this._visitOutCache[nodeTypeIndex] = funcOut; + } + if (func !== _noop) { + var newNode = func.call(impl, node, visitArgs); + if (node && impl.isReplacing) { + node = newNode; + } + } + if (visitArgs.visitDeeper && node) { + if (node.length) { + for (var i = 0, cnt = node.length; i < cnt; i++) { + if (node[i].accept) { + node[i].accept(this); + } + } + } + else if (node.accept) { + node.accept(this); + } + } + if (funcOut != _noop) { + funcOut.call(impl, node); } - return node; - } - - var impl = this._implementation; - var func = this._visitInCache[nodeTypeIndex]; - var funcOut = this._visitOutCache[nodeTypeIndex]; - var visitArgs = _visitArgs; - var fnName; - visitArgs.visitDeeper = true; - - if (!func) { - fnName = "visit".concat(node.type); - func = impl[fnName] || _noop; - funcOut = impl["".concat(fnName, "Out")] || _noop; - this._visitInCache[nodeTypeIndex] = func; - this._visitOutCache[nodeTypeIndex] = funcOut; - } - - if (func !== _noop) { - var newNode = func.call(impl, node, visitArgs); - - if (node && impl.isReplacing) { - node = newNode; + }; + Visitor.prototype.visitArray = function (nodes, nonReplacing) { + if (!nodes) { + return nodes; } - } - - if (visitArgs.visitDeeper && node && node.accept) { - node.accept(this); - } - - if (funcOut != _noop) { - funcOut.call(impl, node); - } - - return node; - } - }, { - key: "visitArray", - value: function visitArray(nodes, nonReplacing) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; // Non-replacing - - if (nonReplacing || !this._implementation.isReplacing) { + var cnt = nodes.length; + var i; + // Non-replacing + if (nonReplacing || !this._implementation.isReplacing) { + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); + } + return nodes; + } + // Replacing + var out = []; for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); + var evald = this.visit(nodes[i]); + if (evald === undefined) { + continue; + } + if (!evald.splice) { + out.push(evald); + } + else if (evald.length) { + this.flatten(evald, out); + } } - - return nodes; - } // Replacing - - - var out = []; - - for (i = 0; i < cnt; i++) { - var evald = this.visit(nodes[i]); - - if (evald === undefined) { - continue; + return out; + }; + Visitor.prototype.flatten = function (arr, out) { + if (!out) { + out = []; } - - if (!evald.splice) { - out.push(evald); - } else if (evald.length) { - this.flatten(evald, out); + var cnt; + var i; + var item; + var nestedCnt; + var j; + var nestedItem; + for (i = 0, cnt = arr.length; i < cnt; i++) { + item = arr[i]; + if (item === undefined) { + continue; + } + if (!item.splice) { + out.push(item); + continue; + } + for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { + nestedItem = item[j]; + if (nestedItem === undefined) { + continue; + } + if (!nestedItem.splice) { + out.push(nestedItem); + } + else if (nestedItem.length) { + this.flatten(nestedItem, out); + } + } } - } - - return out; - } - }, { - key: "flatten", - value: function flatten(arr, out) { - if (!out) { - out = []; - } - - var cnt; - var i; - var item; - var nestedCnt; - var j; - var nestedItem; - - for (i = 0, cnt = arr.length; i < cnt; i++) { - item = arr[i]; - - if (item === undefined) { - continue; + return out; + }; + return Visitor; + }()); + + var ImportSequencer = /** @class */ (function () { + function ImportSequencer(onSequencerEmpty) { + this.imports = []; + this.variableImports = []; + this._onSequencerEmpty = onSequencerEmpty; + this._currentDepth = 0; + } + ImportSequencer.prototype.addImport = function (callback) { + var importSequencer = this; + var importItem = { + callback: callback, + args: null, + isReady: false + }; + this.imports.push(importItem); + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + importItem.args = Array.prototype.slice.call(args, 0); + importItem.isReady = true; + importSequencer.tryRun(); + }; + }; + ImportSequencer.prototype.addVariableImport = function (callback) { + this.variableImports.push(callback); + }; + ImportSequencer.prototype.tryRun = function () { + this._currentDepth++; + try { + while (true) { + while (this.imports.length > 0) { + var importItem = this.imports[0]; + if (!importItem.isReady) { + return; + } + this.imports = this.imports.slice(1); + importItem.callback.apply(null, importItem.args); + } + if (this.variableImports.length === 0) { + break; + } + var variableImport = this.variableImports[0]; + this.variableImports = this.variableImports.slice(1); + variableImport(); + } } - - if (!item.splice) { - out.push(item); - continue; + finally { + this._currentDepth--; } - - for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) { - nestedItem = item[j]; - - if (nestedItem === undefined) { - continue; - } - - if (!nestedItem.splice) { - out.push(nestedItem); - } else if (nestedItem.length) { - this.flatten(nestedItem, out); - } + if (this._currentDepth === 0 && this._onSequencerEmpty) { + this._onSequencerEmpty(); } - } - - return out; - } - }]); - - return Visitor; - }(); - - var ImportSequencer = - /*#__PURE__*/ - function () { - function ImportSequencer(onSequencerEmpty) { - _classCallCheck(this, ImportSequencer); - - this.imports = []; - this.variableImports = []; - this._onSequencerEmpty = onSequencerEmpty; - this._currentDepth = 0; - } + }; + return ImportSequencer; + }()); - _createClass(ImportSequencer, [{ - key: "addImport", - value: function addImport(callback) { - var importSequencer = this; - var importItem = { - callback: callback, - args: null, - isReady: false - }; - this.imports.push(importItem); - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; + var ImportVisitor = function (importer, finish) { + this._visitor = new Visitor(this); + this._importer = importer; + this._finish = finish; + this.context = new contexts.Eval(); + this.importCount = 0; + this.onceFileDetectionMap = {}; + this.recursionDetector = {}; + this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); + }; + ImportVisitor.prototype = { + isReplacing: false, + run: function (root) { + try { + // process the contents + this._visitor.visit(root); } - - importItem.args = Array.prototype.slice.call(args, 0); - importItem.isReady = true; - importSequencer.tryRun(); - }; - } - }, { - key: "addVariableImport", - value: function addVariableImport(callback) { - this.variableImports.push(callback); - } - }, { - key: "tryRun", - value: function tryRun() { - this._currentDepth++; - - try { - while (true) { - while (this.imports.length > 0) { - var importItem = this.imports[0]; - - if (!importItem.isReady) { - return; - } - - this.imports = this.imports.slice(1); - importItem.callback.apply(null, importItem.args); - } - - if (this.variableImports.length === 0) { - break; - } - - var variableImport = this.variableImports[0]; - this.variableImports = this.variableImports.slice(1); - variableImport(); + catch (e) { + this.error = e; } - } finally { - this._currentDepth--; - } - - if (this._currentDepth === 0 && this._onSequencerEmpty) { - this._onSequencerEmpty(); - } - } - }]); - - return ImportSequencer; - }(); - - var ImportVisitor = function ImportVisitor(importer, finish) { - this._visitor = new Visitor(this); - this._importer = importer; - this._finish = finish; - this.context = new contexts.Eval(); - this.importCount = 0; - this.onceFileDetectionMap = {}; - this.recursionDetector = {}; - this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this)); - }; - - ImportVisitor.prototype = { - isReplacing: false, - run: function run(root) { - try { - // process the contents - this._visitor.visit(root); - } catch (e) { - this.error = e; - } - - this.isFinished = true; - - this._sequencer.tryRun(); - }, - _onSequencerEmpty: function _onSequencerEmpty() { - if (!this.isFinished) { - return; - } - - this._finish(this.error); - }, - visitImport: function visitImport(importNode, visitArgs) { - var inlineCSS = importNode.options.inline; - - if (!importNode.css || inlineCSS) { - var context = new contexts.Eval(this.context, copyArray(this.context.frames)); - var importParent = context.frames[0]; - this.importCount++; - - if (importNode.isVariableImport()) { - this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); - } else { - this.processImportNode(importNode, context, importParent); - } - } - - visitArgs.visitDeeper = false; - }, - processImportNode: function processImportNode(importNode, context, importParent) { - var evaldImportNode; - var inlineCSS = importNode.options.inline; - - try { - evaldImportNode = importNode.evalForImport(context); - } catch (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } // attempt to eval properly and treat as css - - - importNode.css = true; // if that fails, this error will be thrown - - importNode.error = e; - } - - if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { - if (evaldImportNode.options.multiple) { - context.importMultiple = true; - } // try appending if we haven't determined if it is css or not - - - var tryAppendLessExtension = evaldImportNode.css === undefined; - - for (var i = 0; i < importParent.rules.length; i++) { - if (importParent.rules[i] === importNode) { - importParent.rules[i] = evaldImportNode; - break; - } - } - - var onImported = this.onImported.bind(this, evaldImportNode, context); - - var sequencedOnImported = this._sequencer.addImport(onImported); - - this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); - } else { - this.importCount--; - - if (this.isFinished) { + this.isFinished = true; this._sequencer.tryRun(); - } - } - }, - onImported: function onImported(importNode, context, e, root, importedAtRoot, fullPath) { - if (e) { - if (!e.filename) { - e.index = importNode.getIndex(); - e.filename = importNode.fileInfo().filename; - } - - this.error = e; - } - - var importVisitor = this; - var inlineCSS = importNode.options.inline; - var isPlugin = importNode.options.isPlugin; - var isOptional = importNode.options.optional; - var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; - - if (!context.importMultiple) { - if (duplicateImport) { - importNode.skip = true; - } else { - importNode.skip = function () { - if (fullPath in importVisitor.onceFileDetectionMap) { - return true; - } - - importVisitor.onceFileDetectionMap[fullPath] = true; - return false; - }; - } - } - - if (!fullPath && isOptional) { - importNode.skip = true; - } - - if (root) { - importNode.root = root; - importNode.importedFilename = fullPath; - - if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { - importVisitor.recursionDetector[fullPath] = true; - var oldContext = this.context; - this.context = context; - - try { - this._visitor.visit(root); - } catch (e) { - this.error = e; - } - - this.context = oldContext; - } - } - - importVisitor.importCount--; - - if (importVisitor.isFinished) { - importVisitor._sequencer.tryRun(); - } - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.unshift(declNode); - } else { - visitArgs.visitDeeper = false; - } - }, - visitDeclarationOut: function visitDeclarationOut(declNode) { - if (declNode.value.type === 'DetachedRuleset') { - this.context.frames.shift(); - } - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - this.context.frames.unshift(atRuleNode); - }, - visitAtRuleOut: function visitAtRuleOut(atRuleNode) { - this.context.frames.shift(); - }, - visitMixinDefinition: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - this.context.frames.unshift(mixinDefinitionNode); - }, - visitMixinDefinitionOut: function visitMixinDefinitionOut(mixinDefinitionNode) { - this.context.frames.shift(); - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - this.context.frames.unshift(rulesetNode); - }, - visitRulesetOut: function visitRulesetOut(rulesetNode) { - this.context.frames.shift(); - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - this.context.frames.unshift(mediaNode.rules[0]); - }, - visitMediaOut: function visitMediaOut(mediaNode) { - this.context.frames.shift(); - } - }; - - var SetTreeVisibilityVisitor = - /*#__PURE__*/ - function () { - function SetTreeVisibilityVisitor(visible) { - _classCallCheck(this, SetTreeVisibilityVisitor); - - this.visible = visible; - } - - _createClass(SetTreeVisibilityVisitor, [{ - key: "run", - value: function run(root) { - this.visit(root); - } - }, { - key: "visitArray", - value: function visitArray(nodes) { - if (!nodes) { - return nodes; - } - - var cnt = nodes.length; - var i; - - for (i = 0; i < cnt; i++) { - this.visit(nodes[i]); - } - - return nodes; - } - }, { - key: "visit", - value: function visit(node) { - if (!node) { - return node; - } - - if (node.constructor === Array) { - return this.visitArray(node); - } - - if (!node.blocksVisibility || node.blocksVisibility()) { - return node; - } - - if (this.visible) { - node.ensureVisibility(); - } else { - node.ensureInvisibility(); - } - - node.accept(this); - return node; - } - }]); - - return SetTreeVisibilityVisitor; - }(); - - /* jshint loopfunc:true */ - - var ExtendFinderVisitor = - /*#__PURE__*/ - function () { - function ExtendFinderVisitor() { - _classCallCheck(this, ExtendFinderVisitor); - - this._visitor = new Visitor(this); - this.contexts = []; - this.allExtendsStack = [[]]; - } - - _createClass(ExtendFinderVisitor, [{ - key: "run", - value: function run(root) { - root = this._visitor.visit(root); - root.allExtends = this.allExtendsStack[0]; - return root; - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var i; - var j; - var extend; - var allSelectorsExtendList = []; - var extendList; // get &:extend(.a); rules which apply to all selectors in this ruleset - - var rules = rulesetNode.rules; - var ruleCnt = rules ? rules.length : 0; - - for (i = 0; i < ruleCnt; i++) { - if (rulesetNode.rules[i] instanceof tree.Extend) { - allSelectorsExtendList.push(rules[i]); - rulesetNode.extendOnEveryPath = true; - } - } // now find every selector and apply the extends that apply to all extends - // and the ones which apply to an individual extend - - - var paths = rulesetNode.paths; - - for (i = 0; i < paths.length; i++) { - var selectorPath = paths[i]; - var selector = selectorPath[selectorPath.length - 1]; - var selExtendList = selector.extendList; - extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) : allSelectorsExtendList; - - if (extendList) { - extendList = extendList.map(function (allSelectorsExtend) { - return allSelectorsExtend.clone(); - }); + }, + _onSequencerEmpty: function () { + if (!this.isFinished) { + return; } - - for (j = 0; j < extendList.length; j++) { - this.foundExtends = true; - extend = extendList[j]; - extend.findSelfSelectors(selectorPath); - extend.ruleset = rulesetNode; - - if (j === 0) { - extend.firstExtendOnThisSelectorPath = true; - } - - this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); + this._finish(this.error); + }, + visitImport: function (importNode, visitArgs) { + var inlineCSS = importNode.options.inline; + if (!importNode.css || inlineCSS) { + var context = new contexts.Eval(this.context, copyArray(this.context.frames)); + var importParent = context.frames[0]; + this.importCount++; + if (importNode.isVariableImport()) { + this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent)); + } + else { + this.processImportNode(importNode, context, importParent); + } } - } - - this.contexts.push(rulesetNode.selectors); - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - if (!rulesetNode.root) { - this.contexts.length = this.contexts.length - 1; - } - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - mediaNode.allExtends = []; - this.allExtendsStack.push(mediaNode.allExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - atRuleNode.allExtends = []; - this.allExtendsStack.push(atRuleNode.allExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - this.allExtendsStack.length = this.allExtendsStack.length - 1; - } - }]); - - return ExtendFinderVisitor; - }(); - - var ProcessExtendsVisitor = - /*#__PURE__*/ - function () { - function ProcessExtendsVisitor() { - _classCallCheck(this, ProcessExtendsVisitor); - - this._visitor = new Visitor(this); - } - - _createClass(ProcessExtendsVisitor, [{ - key: "run", - value: function run(root) { - var extendFinder = new ExtendFinderVisitor(); - this.extendIndices = {}; - extendFinder.run(root); - - if (!extendFinder.foundExtends) { - return root; - } - - root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); - this.allExtendsStack = [root.allExtends]; - - var newRoot = this._visitor.visit(root); - - this.checkExtendsForNonMatched(root.allExtends); - return newRoot; - } - }, { - key: "checkExtendsForNonMatched", - value: function checkExtendsForNonMatched(extendList) { - var indices = this.extendIndices; - extendList.filter(function (extend) { - return !extend.hasFoundMatches && extend.parent_ids.length == 1; - }).forEach(function (extend) { - var selector = '_unknown_'; - + visitArgs.visitDeeper = false; + }, + processImportNode: function (importNode, context, importParent) { + var evaldImportNode; + var inlineCSS = importNode.options.inline; try { - selector = extend.selector.toCSS({}); - } catch (_) {} - - if (!indices["".concat(extend.index, " ").concat(selector)]) { - indices["".concat(extend.index, " ").concat(selector)] = true; - logger.warn("extend '".concat(selector, "' has no matches")); - } - }); - } - }, { - key: "doExtendChaining", - value: function doExtendChaining(extendsList, extendsListTarget, iterationCount) { - // - // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering - // and pasting the selector we would do normally, but we are also adding an extend with the same target selector - // this means this new extend can then go and alter other extends - // - // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors - // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already - // processed if we look at each selector at a time, as is done in visitRuleset - var extendIndex; - var targetExtendIndex; - var matches; - var extendsToAdd = []; - var newSelector; - var extendVisitor = this; - var selectorPath; - var extend; - var targetExtend; - var newExtend; - iterationCount = iterationCount || 0; // loop through comparing every extend with every target extend. - // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place - // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one - // and the second is the target. - // the separation into two lists allows us to process a subset of chains with a bigger set, as is the - // case when processing media queries - - for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { - for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { - extend = extendsList[extendIndex]; - targetExtend = extendsListTarget[targetExtendIndex]; // look for circular references - - if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { - continue; - } // find a match in the target extends self selector (the bit before :extend) - - - selectorPath = [targetExtend.selfSelectors[0]]; - matches = extendVisitor.findMatch(extend, selectorPath); - - if (matches.length) { - extend.hasFoundMatches = true; // we found a match, so for each self selector.. - - extend.selfSelectors.forEach(function (selfSelector) { - var info = targetExtend.visibilityInfo(); // process the extend as usual - - newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); // but now we create a new extend from it - - newExtend = new tree.Extend(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); - newExtend.selfSelectors = newSelector; // add the extend onto the list of extends for that selector - - newSelector[newSelector.length - 1].extendList = [newExtend]; // record that we need to add it. - - extendsToAdd.push(newExtend); - newExtend.ruleset = targetExtend.ruleset; // remember its parents for circular references - - newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); // only process the selector once.. if we have :extend(.a,.b) then multiple - // extends will look at the same selector path, so when extending - // we know that any others will be duplicates in terms of what is added to the css - - if (targetExtend.firstExtendOnThisSelectorPath) { - newExtend.firstExtendOnThisSelectorPath = true; - targetExtend.ruleset.paths.push(newSelector); - } - }); - } + evaldImportNode = importNode.evalForImport(context); } - } - - if (extendsToAdd.length) { - // try to detect circular references to stop a stack overflow. - // may no longer be needed. - this.extendChainCount++; - - if (iterationCount > 100) { - var selectorOne = '{unable to calculate}'; - var selectorTwo = '{unable to calculate}'; - - try { - selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); - selectorTwo = extendsToAdd[0].selector.toCSS(); - } catch (e) {} - - throw { - message: "extend circular reference detected. One of the circular extends is currently:".concat(selectorOne, ":extend(").concat(selectorTwo, ")") - }; - } // now process the new extends on the existing rules so that we can handle a extending b extending c extending - // d extending e... - - - return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); - } else { - return extendsToAdd; - } - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(ruleNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitSelector", - value: function visitSelector(selectorNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - if (rulesetNode.root) { - return; - } - - var matches; - var pathIndex; - var extendIndex; - var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; - var selectorsToAdd = []; - var extendVisitor = this; - var selectorPath; // look at each selector path in the ruleset, find any extend matches and then copy, find and replace - - for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { - for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { - selectorPath = rulesetNode.paths[pathIndex]; // extending extends happens initially, before the main pass - - if (rulesetNode.extendOnEveryPath) { - continue; - } - - var extendList = selectorPath[selectorPath.length - 1].extendList; - - if (extendList && extendList.length) { - continue; - } - - matches = this.findMatch(allExtends[extendIndex], selectorPath); - - if (matches.length) { - allExtends[extendIndex].hasFoundMatches = true; - allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { - var extendedSelectors; - extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); - selectorsToAdd.push(extendedSelectors); - }); - } + catch (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + // attempt to eval properly and treat as css + importNode.css = true; + // if that fails, this error will be thrown + importNode.error = e; + } + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { + if (evaldImportNode.options.multiple) { + context.importMultiple = true; + } + // try appending if we haven't determined if it is css or not + var tryAppendLessExtension = evaldImportNode.css === undefined; + for (var i_1 = 0; i_1 < importParent.rules.length; i_1++) { + if (importParent.rules[i_1] === importNode) { + importParent.rules[i_1] = evaldImportNode; + break; + } + } + var onImported = this.onImported.bind(this, evaldImportNode, context); + var sequencedOnImported = this._sequencer.addImport(onImported); + this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(), evaldImportNode.options, sequencedOnImported); + } + else { + this.importCount--; + if (this.isFinished) { + this._sequencer.tryRun(); + } } - } - - rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); - } - }, { - key: "findMatch", - value: function findMatch(extend, haystackSelectorPath) { - // - // look through the haystack selector path to try and find the needle - extend.selector - // returns an array of selector matches that can then be replaced - // - var haystackSelectorIndex; - var hackstackSelector; - var hackstackElementIndex; - var haystackElement; - var targetCombinator; - var i; - var extendVisitor = this; - var needleElements = extend.selector.elements; - var potentialMatches = []; - var potentialMatch; - var matches = []; // loop through the haystack elements - - for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { - hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; - - for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { - haystackElement = hackstackSelector.elements[hackstackElementIndex]; // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. - - if (extend.allowBefore || haystackSelectorIndex === 0 && hackstackElementIndex === 0) { - potentialMatches.push({ - pathIndex: haystackSelectorIndex, - index: hackstackElementIndex, - matched: 0, - initialCombinator: haystackElement.combinator - }); - } - - for (i = 0; i < potentialMatches.length; i++) { - potentialMatch = potentialMatches[i]; // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't - // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to - // work out what the resulting combinator will be - - targetCombinator = haystackElement.combinator.value; - - if (targetCombinator === '' && hackstackElementIndex === 0) { - targetCombinator = ' '; - } // if we don't match, null our match to indicate failure - - - if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator) { - potentialMatch = null; - } else { - potentialMatch.matched++; - } // if we are still valid and have finished, test whether we have elements after and whether these are allowed - - - if (potentialMatch) { - potentialMatch.finished = potentialMatch.matched === needleElements.length; - - if (potentialMatch.finished && !extend.allowAfter && (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length)) { - potentialMatch = null; - } - } // if null we remove, if not, we are still valid, so either push as a valid match or continue - - - if (potentialMatch) { - if (potentialMatch.finished) { - potentialMatch.length = needleElements.length; - potentialMatch.endPathIndex = haystackSelectorIndex; - potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match - - potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again - - matches.push(potentialMatch); - } - } else { - potentialMatches.splice(i, 1); - i--; + }, + onImported: function (importNode, context, e, root, importedAtRoot, fullPath) { + if (e) { + if (!e.filename) { + e.index = importNode.getIndex(); + e.filename = importNode.fileInfo().filename; + } + this.error = e; + } + var importVisitor = this; + var inlineCSS = importNode.options.inline; + var isPlugin = importNode.options.isPlugin; + var isOptional = importNode.options.optional; + var duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector; + if (!context.importMultiple) { + if (duplicateImport) { + importNode.skip = true; + } + else { + importNode.skip = function () { + if (fullPath in importVisitor.onceFileDetectionMap) { + return true; + } + importVisitor.onceFileDetectionMap[fullPath] = true; + return false; + }; } - } } - } - - return matches; - } - }, { - key: "isElementValuesEqual", - value: function isElementValuesEqual(elementValue1, elementValue2) { - if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { - return elementValue1 === elementValue2; - } - - if (elementValue1 instanceof tree.Attribute) { - if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { - return false; + if (!fullPath && isOptional) { + importNode.skip = true; + } + if (root) { + importNode.root = root; + importNode.importedFilename = fullPath; + if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) { + importVisitor.recursionDetector[fullPath] = true; + var oldContext = this.context; + this.context = context; + try { + this._visitor.visit(root); + } + catch (e) { + this.error = e; + } + this.context = oldContext; + } } - - if (!elementValue1.value || !elementValue2.value) { - if (elementValue1.value || elementValue2.value) { - return false; - } - - return true; + importVisitor.importCount--; + if (importVisitor.isFinished) { + importVisitor._sequencer.tryRun(); } - - elementValue1 = elementValue1.value.value || elementValue1.value; - elementValue2 = elementValue2.value.value || elementValue2.value; - return elementValue1 === elementValue2; - } - - elementValue1 = elementValue1.value; - elementValue2 = elementValue2.value; - - if (elementValue1 instanceof tree.Selector) { - if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { - return false; + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.unshift(declNode); } - - for (var i = 0; i < elementValue1.elements.length; i++) { - if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) { - if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) { - return false; - } - } - - if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) { - return false; - } + else { + visitArgs.visitDeeper = false; } - - return true; - } - - return false; - } - }, { - key: "extendSelector", - value: function extendSelector(matches, selectorPath, replacementSelector, isVisible) { - // for a set of matches, replace each match with the replacement selector - var currentSelectorPathIndex = 0; - var currentSelectorPathElementIndex = 0; - var path = []; - var matchIndex; - var selector; - var firstElement; - var match; - var newElements; - - for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { - match = matches[matchIndex]; - selector = selectorPath[match.pathIndex]; - firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); - - if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + }, + visitDeclarationOut: function (declNode) { + if (declNode.value.type === 'DetachedRuleset') { + this.context.frames.shift(); } + }, + visitAtRule: function (atRuleNode, visitArgs) { + this.context.frames.unshift(atRuleNode); + }, + visitAtRuleOut: function (atRuleNode) { + this.context.frames.shift(); + }, + visitMixinDefinition: function (mixinDefinitionNode, visitArgs) { + this.context.frames.unshift(mixinDefinitionNode); + }, + visitMixinDefinitionOut: function (mixinDefinitionNode) { + this.context.frames.shift(); + }, + visitRuleset: function (rulesetNode, visitArgs) { + this.context.frames.unshift(rulesetNode); + }, + visitRulesetOut: function (rulesetNode) { + this.context.frames.shift(); + }, + visitMedia: function (mediaNode, visitArgs) { + this.context.frames.unshift(mediaNode.rules[0]); + }, + visitMediaOut: function (mediaNode) { + this.context.frames.shift(); + } + }; - newElements = selector.elements.slice(currentSelectorPathElementIndex, match.index).concat([firstElement]).concat(replacementSelector.elements.slice(1)); - - if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(newElements); - } else { - path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); - path.push(new tree.Selector(newElements)); + var SetTreeVisibilityVisitor = /** @class */ (function () { + function SetTreeVisibilityVisitor(visible) { + this.visible = visible; + } + SetTreeVisibilityVisitor.prototype.run = function (root) { + this.visit(root); + }; + SetTreeVisibilityVisitor.prototype.visitArray = function (nodes) { + if (!nodes) { + return nodes; } - - currentSelectorPathIndex = match.endPathIndex; - currentSelectorPathElementIndex = match.endPathElementIndex; - - if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { - currentSelectorPathElementIndex = 0; - currentSelectorPathIndex++; + var cnt = nodes.length; + var i; + for (i = 0; i < cnt; i++) { + this.visit(nodes[i]); } - } - - if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { - path[path.length - 1].elements = path[path.length - 1].elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); - currentSelectorPathIndex++; - } - - path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); - path = path.map(function (currentValue) { - // we can re-use elements here, because the visibility property matters only for selectors - var derived = currentValue.createDerived(currentValue.elements); - - if (isVisible) { - derived.ensureVisibility(); - } else { - derived.ensureInvisibility(); + return nodes; + }; + SetTreeVisibilityVisitor.prototype.visit = function (node) { + if (!node) { + return node; } - - return derived; - }); - return path; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitMediaOut", - value: function visitMediaOut(mediaNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); - newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); - this.allExtendsStack.push(newAllExtends); - } - }, { - key: "visitAtRuleOut", - value: function visitAtRuleOut(atRuleNode) { - var lastIndex = this.allExtendsStack.length - 1; - this.allExtendsStack.length = lastIndex; - } - }]); - - return ProcessExtendsVisitor; - }(); - - var JoinSelectorVisitor = - /*#__PURE__*/ - function () { - function JoinSelectorVisitor() { - _classCallCheck(this, JoinSelectorVisitor); - - this.contexts = [[]]; - this._visitor = new Visitor(this); - } - - _createClass(JoinSelectorVisitor, [{ - key: "run", - value: function run(root) { - return this._visitor.visit(root); - } - }, { - key: "visitDeclaration", - value: function visitDeclaration(declNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitMixinDefinition", - value: function visitMixinDefinition(mixinDefinitionNode, visitArgs) { - visitArgs.visitDeeper = false; - } - }, { - key: "visitRuleset", - value: function visitRuleset(rulesetNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - var paths = []; - var selectors; - this.contexts.push(paths); - - if (!rulesetNode.root) { - selectors = rulesetNode.selectors; - - if (selectors) { - selectors = selectors.filter(function (selector) { - return selector.getIsOutput(); - }); - rulesetNode.selectors = selectors.length ? selectors : selectors = null; - - if (selectors) { - rulesetNode.joinSelectors(paths, context, selectors); - } + if (node.constructor === Array) { + return this.visitArray(node); } - - if (!selectors) { - rulesetNode.rules = null; + if (!node.blocksVisibility || node.blocksVisibility()) { + return node; } - - rulesetNode.paths = paths; - } - } - }, { - key: "visitRulesetOut", - value: function visitRulesetOut(rulesetNode) { - this.contexts.length = this.contexts.length - 1; - } - }, { - key: "visitMedia", - value: function visitMedia(mediaNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - mediaNode.rules[0].root = context.length === 0 || context[0].multiMedia; - } - }, { - key: "visitAtRule", - value: function visitAtRule(atRuleNode, visitArgs) { - var context = this.contexts[this.contexts.length - 1]; - - if (atRuleNode.rules && atRuleNode.rules.length) { - atRuleNode.rules[0].root = atRuleNode.isRooted || context.length === 0 || null; - } - } - }]); - - return JoinSelectorVisitor; - }(); - - var CSSVisitorUtils = - /*#__PURE__*/ - function () { - function CSSVisitorUtils(context) { - _classCallCheck(this, CSSVisitorUtils); - - this._visitor = new Visitor(this); - this._context = context; - } - - _createClass(CSSVisitorUtils, [{ - key: "containsSilentNonBlockedChild", - value: function containsSilentNonBlockedChild(bodyRules) { - var rule; - - if (!bodyRules) { - return false; - } - - for (var r = 0; r < bodyRules.length; r++) { - rule = bodyRules[r]; - - if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { - // the atrule contains something that was referenced (likely by extend) - // therefore it needs to be shown in output too - return true; + if (this.visible) { + node.ensureVisibility(); } - } - - return false; - } - }, { - key: "keepOnlyVisibleChilds", - value: function keepOnlyVisibleChilds(owner) { - if (owner && owner.rules) { - owner.rules = owner.rules.filter(function (thing) { - return thing.isVisible(); - }); - } - } - }, { - key: "isEmpty", - value: function isEmpty(owner) { - return owner && owner.rules ? owner.rules.length === 0 : true; - } - }, { - key: "hasVisibleSelector", - value: function hasVisibleSelector(rulesetNode) { - return rulesetNode && rulesetNode.paths ? rulesetNode.paths.length > 0 : false; - } - }, { - key: "resolveVisibility", - value: function resolveVisibility(node, originalRules) { - if (!node.blocksVisibility()) { - if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { - return; + else { + node.ensureInvisibility(); } - + node.accept(this); return node; - } - - var compiledRulesBody = node.rules[0]; - this.keepOnlyVisibleChilds(compiledRulesBody); - - if (this.isEmpty(compiledRulesBody)) { - return; - } - - node.ensureVisibility(); - node.removeVisibilityBlock(); - return node; - } - }, { - key: "isVisibleRuleset", - value: function isVisibleRuleset(rulesetNode) { - if (rulesetNode.firstRoot) { - return true; - } - - if (this.isEmpty(rulesetNode)) { - return false; - } - - if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { - return false; - } - - return true; - } - }]); - - return CSSVisitorUtils; - }(); + }; + return SetTreeVisibilityVisitor; + }()); - var ToCSSVisitor = function ToCSSVisitor(context) { - this._visitor = new Visitor(this); - this._context = context; - this.utils = new CSSVisitorUtils(context); - }; - - ToCSSVisitor.prototype = { - isReplacing: true, - run: function run(root) { - return this._visitor.visit(root); - }, - visitDeclaration: function visitDeclaration(declNode, visitArgs) { - if (declNode.blocksVisibility() || declNode.variable) { - return; - } - - return declNode; - }, - visitMixinDefinition: function visitMixinDefinition(mixinNode, visitArgs) { - // mixin definitions do not get eval'd - this means they keep state - // so we have to clear that state here so it isn't used if toCSS is called twice - mixinNode.frames = []; - }, - visitExtend: function visitExtend(extendNode, visitArgs) {}, - visitComment: function visitComment(commentNode, visitArgs) { - if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { - return; - } - - return commentNode; - }, - visitMedia: function visitMedia(mediaNode, visitArgs) { - var originalRules = mediaNode.rules[0].rules; - mediaNode.accept(this._visitor); - visitArgs.visitDeeper = false; - return this.utils.resolveVisibility(mediaNode, originalRules); - }, - visitImport: function visitImport(importNode, visitArgs) { - if (importNode.blocksVisibility()) { - return; - } - - return importNode; - }, - visitAtRule: function visitAtRule(atRuleNode, visitArgs) { - if (atRuleNode.rules && atRuleNode.rules.length) { - return this.visitAtRuleWithBody(atRuleNode, visitArgs); - } else { - return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); - } - }, - visitAnonymous: function visitAnonymous(anonymousNode, visitArgs) { - if (!anonymousNode.blocksVisibility()) { - anonymousNode.accept(this._visitor); - return anonymousNode; - } - }, - visitAtRuleWithBody: function visitAtRuleWithBody(atRuleNode, visitArgs) { - // if there is only one nested ruleset and that one has no path, then it is - // just fake ruleset - function hasFakeRuleset(atRuleNode) { - var bodyRules = atRuleNode.rules; - return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); - } - - function getBodyRules(atRuleNode) { - var nodeRules = atRuleNode.rules; - - if (hasFakeRuleset(atRuleNode)) { - return nodeRules[0].rules; - } - - return nodeRules; - } // it is still true that it is only one ruleset in array - // this is last such moment - // process childs - - - var originalRules = getBodyRules(atRuleNode); - atRuleNode.accept(this._visitor); - visitArgs.visitDeeper = false; - - if (!this.utils.isEmpty(atRuleNode)) { - this._mergeRules(atRuleNode.rules[0].rules); - } - - return this.utils.resolveVisibility(atRuleNode, originalRules); - }, - visitAtRuleWithoutBody: function visitAtRuleWithoutBody(atRuleNode, visitArgs) { - if (atRuleNode.blocksVisibility()) { - return; - } - - if (atRuleNode.name === '@charset') { - // Only output the debug info together with subsequent @charset definitions - // a comment (or @media statement) before the actual @charset atrule would - // be considered illegal css as it has to be on the first line - if (this.charset) { - if (atRuleNode.debugInfo) { - var comment = new tree.Comment("/* ".concat(atRuleNode.toCSS(this._context).replace(/\n/g, ''), " */\n")); - comment.debugInfo = atRuleNode.debugInfo; - return this._visitor.visit(comment); - } - - return; - } - - this.charset = true; - } - - return atRuleNode; - }, - checkValidNodes: function checkValidNodes(rules, isRoot) { - if (!rules) { - return; - } - - for (var i = 0; i < rules.length; i++) { - var ruleNode = rules[i]; - - if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { - throw { - message: 'Properties must be inside selector blocks. They cannot be in the root', - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode instanceof tree.Call) { - throw { - message: "Function '".concat(ruleNode.name, "' is undefined"), - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - - if (ruleNode.type && !ruleNode.allowRoot) { - throw { - message: "".concat(ruleNode.type, " node returned by a function is not valid here"), - index: ruleNode.getIndex(), - filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename - }; - } - } - }, - visitRuleset: function visitRuleset(rulesetNode, visitArgs) { - // at this point rulesets are nested into each other - var rule; - var rulesets = []; - this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); - - if (!rulesetNode.root) { - // remove invisible paths - this._compileRulesetPaths(rulesetNode); // remove rulesets from this ruleset body and compile them separately - - - var nodeRules = rulesetNode.rules; - var nodeRuleCnt = nodeRules ? nodeRules.length : 0; - - for (var i = 0; i < nodeRuleCnt;) { - rule = nodeRules[i]; - - if (rule && rule.rules) { - // visit because we are moving them out from being a child - rulesets.push(this._visitor.visit(rule)); - nodeRules.splice(i, 1); - nodeRuleCnt--; - continue; + /* jshint loopfunc:true */ + var ExtendFinderVisitor = /** @class */ (function () { + function ExtendFinderVisitor() { + this._visitor = new Visitor(this); + this.contexts = []; + this.allExtendsStack = [[]]; + } + ExtendFinderVisitor.prototype.run = function (root) { + root = this._visitor.visit(root); + root.allExtends = this.allExtendsStack[0]; + return root; + }; + ExtendFinderVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ExtendFinderVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - i++; - } // accept the visitor to remove rules and refactor itself - // then we can decide nogw whether we want it or not - // compile body - - - if (nodeRuleCnt > 0) { - rulesetNode.accept(this._visitor); - } else { - rulesetNode.rules = null; - } - - visitArgs.visitDeeper = false; - } else { - // if (! rulesetNode.root) { - rulesetNode.accept(this._visitor); - visitArgs.visitDeeper = false; - } - - if (rulesetNode.rules) { - this._mergeRules(rulesetNode.rules); - - this._removeDuplicateRules(rulesetNode.rules); - } // now decide whether we keep the ruleset - - - if (this.utils.isVisibleRuleset(rulesetNode)) { - rulesetNode.ensureVisibility(); - rulesets.splice(0, 0, rulesetNode); - } - - if (rulesets.length === 1) { - return rulesets[0]; - } - - return rulesets; - }, - _compileRulesetPaths: function _compileRulesetPaths(rulesetNode) { - if (rulesetNode.paths) { - rulesetNode.paths = rulesetNode.paths.filter(function (p) { var i; - - if (p[0].elements[0].combinator.value === ' ') { - p[0].elements[0].combinator = new tree.Combinator(''); + var j; + var extend; + var allSelectorsExtendList = []; + var extendList; + // get &:extend(.a); rules which apply to all selectors in this ruleset + var rules = rulesetNode.rules; + var ruleCnt = rules ? rules.length : 0; + for (i = 0; i < ruleCnt; i++) { + if (rulesetNode.rules[i] instanceof tree.Extend) { + allSelectorsExtendList.push(rules[i]); + rulesetNode.extendOnEveryPath = true; + } } - - for (i = 0; i < p.length; i++) { - if (p[i].isVisible() && p[i].getIsOutput()) { - return true; - } + // now find every selector and apply the extends that apply to all extends + // and the ones which apply to an individual extend + var paths = rulesetNode.paths; + for (i = 0; i < paths.length; i++) { + var selectorPath = paths[i]; + var selector = selectorPath[selectorPath.length - 1]; + var selExtendList = selector.extendList; + extendList = selExtendList ? copyArray(selExtendList).concat(allSelectorsExtendList) + : allSelectorsExtendList; + if (extendList) { + extendList = extendList.map(function (allSelectorsExtend) { return allSelectorsExtend.clone(); }); + } + for (j = 0; j < extendList.length; j++) { + this.foundExtends = true; + extend = extendList[j]; + extend.findSelfSelectors(selectorPath); + extend.ruleset = rulesetNode; + if (j === 0) { + extend.firstExtendOnThisSelectorPath = true; + } + this.allExtendsStack[this.allExtendsStack.length - 1].push(extend); + } } - - return false; - }); - } - }, - _removeDuplicateRules: function _removeDuplicateRules(rules) { - if (!rules) { - return; - } // remove duplicates - - - var ruleCache = {}; - var ruleList; - var rule; - var i; - - for (i = rules.length - 1; i >= 0; i--) { - rule = rules[i]; - - if (rule instanceof tree.Declaration) { - if (!ruleCache[rule.name]) { - ruleCache[rule.name] = rule; - } else { - ruleList = ruleCache[rule.name]; - - if (ruleList instanceof tree.Declaration) { - ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; - } - - var ruleCSS = rule.toCSS(this._context); - - if (ruleList.indexOf(ruleCSS) !== -1) { - rules.splice(i, 1); - } else { - ruleList.push(ruleCSS); - } + this.contexts.push(rulesetNode.selectors); + }; + ExtendFinderVisitor.prototype.visitRulesetOut = function (rulesetNode) { + if (!rulesetNode.root) { + this.contexts.length = this.contexts.length - 1; } - } - } - }, - _mergeRules: function _mergeRules(rules) { - if (!rules) { - return; - } - - var groups = {}; - var groupsArr = []; - - for (var i = 0; i < rules.length; i++) { - var rule = rules[i]; - - if (rule.merge) { - var key = rule.name; - groups[key] ? rules.splice(i--, 1) : groupsArr.push(groups[key] = []); - groups[key].push(rule); - } - } - - groupsArr.forEach(function (group) { - if (group.length > 0) { - var result = group[0]; - var space = []; - var comma = [new tree.Expression(space)]; - group.forEach(function (rule) { - if (rule.merge === '+' && space.length > 0) { - comma.push(new tree.Expression(space = [])); - } - - space.push(rule.value); - result.important = result.important || rule.important; + }; + ExtendFinderVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + mediaNode.allExtends = []; + this.allExtendsStack.push(mediaNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitMediaOut = function (mediaNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + ExtendFinderVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + atRuleNode.allExtends = []; + this.allExtendsStack.push(atRuleNode.allExtends); + }; + ExtendFinderVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + this.allExtendsStack.length = this.allExtendsStack.length - 1; + }; + return ExtendFinderVisitor; + }()); + var ProcessExtendsVisitor = /** @class */ (function () { + function ProcessExtendsVisitor() { + this._visitor = new Visitor(this); + } + ProcessExtendsVisitor.prototype.run = function (root) { + var extendFinder = new ExtendFinderVisitor(); + this.extendIndices = {}; + extendFinder.run(root); + if (!extendFinder.foundExtends) { + return root; + } + root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends)); + this.allExtendsStack = [root.allExtends]; + var newRoot = this._visitor.visit(root); + this.checkExtendsForNonMatched(root.allExtends); + return newRoot; + }; + ProcessExtendsVisitor.prototype.checkExtendsForNonMatched = function (extendList) { + var indices = this.extendIndices; + extendList.filter(function (extend) { return !extend.hasFoundMatches && extend.parent_ids.length == 1; }).forEach(function (extend) { + var selector = '_unknown_'; + try { + selector = extend.selector.toCSS({}); + } + catch (_) { } + if (!indices[extend.index + " " + selector]) { + indices[extend.index + " " + selector] = true; + logger.warn("extend '" + selector + "' has no matches"); + } }); - result.value = new tree.Value(comma); - } - }); - } - }; - - var visitors = { - Visitor: Visitor, - ImportVisitor: ImportVisitor, - MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, - ExtendVisitor: ProcessExtendsVisitor, - JoinSelectorVisitor: JoinSelectorVisitor, - ToCSSVisitor: ToCSSVisitor - }; - - // Split the input into chunks. - var chunker = (function (input, fail) { - var len = input.length; - var level = 0; - var parenLevel = 0; - var lastOpening; - var lastOpeningParen; - var lastMultiComment; - var lastMultiCommentEndBrace; - var chunks = []; - var emitFrom = 0; - var chunkerCurrentIndex; - var currentChunkStartIndex; - var cc; - var cc2; - var matched; - - function emitChunk(force) { - var len = chunkerCurrentIndex - emitFrom; - - if (len < 512 && !force || !len) { - return; - } - - chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); - emitFrom = chunkerCurrentIndex + 1; - } - - for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc = input.charCodeAt(chunkerCurrentIndex); - - if (cc >= 97 && cc <= 122 || cc < 34) { - // a-z or whitespace - continue; - } - - switch (cc) { - case 40: - // ( - parenLevel++; - lastOpeningParen = chunkerCurrentIndex; - continue; - - case 41: - // ) - if (--parenLevel < 0) { - return fail('missing opening `(`', chunkerCurrentIndex); - } - - continue; - - case 59: - // ; - if (!parenLevel) { - emitChunk(); + }; + ProcessExtendsVisitor.prototype.doExtendChaining = function (extendsList, extendsListTarget, iterationCount) { + // + // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering + // and pasting the selector we would do normally, but we are also adding an extend with the same target selector + // this means this new extend can then go and alter other extends + // + // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors + // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already + // processed if we look at each selector at a time, as is done in visitRuleset + var extendIndex; + var targetExtendIndex; + var matches; + var extendsToAdd = []; + var newSelector; + var extendVisitor = this; + var selectorPath; + var extend; + var targetExtend; + var newExtend; + iterationCount = iterationCount || 0; + // loop through comparing every extend with every target extend. + // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place + // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one + // and the second is the target. + // the separation into two lists allows us to process a subset of chains with a bigger set, as is the + // case when processing media queries + for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) { + for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) { + extend = extendsList[extendIndex]; + targetExtend = extendsListTarget[targetExtendIndex]; + // look for circular references + if (extend.parent_ids.indexOf(targetExtend.object_id) >= 0) { + continue; + } + // find a match in the target extends self selector (the bit before :extend) + selectorPath = [targetExtend.selfSelectors[0]]; + matches = extendVisitor.findMatch(extend, selectorPath); + if (matches.length) { + extend.hasFoundMatches = true; + // we found a match, so for each self selector.. + extend.selfSelectors.forEach(function (selfSelector) { + var info = targetExtend.visibilityInfo(); + // process the extend as usual + newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible()); + // but now we create a new extend from it + newExtend = new (tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info); + newExtend.selfSelectors = newSelector; + // add the extend onto the list of extends for that selector + newSelector[newSelector.length - 1].extendList = [newExtend]; + // record that we need to add it. + extendsToAdd.push(newExtend); + newExtend.ruleset = targetExtend.ruleset; + // remember its parents for circular references + newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids); + // only process the selector once.. if we have :extend(.a,.b) then multiple + // extends will look at the same selector path, so when extending + // we know that any others will be duplicates in terms of what is added to the css + if (targetExtend.firstExtendOnThisSelectorPath) { + newExtend.firstExtendOnThisSelectorPath = true; + targetExtend.ruleset.paths.push(newSelector); + } + }); + } + } } - - continue; - - case 123: - // { - level++; - lastOpening = chunkerCurrentIndex; - continue; - - case 125: - // } - if (--level < 0) { - return fail('missing opening `{`', chunkerCurrentIndex); + if (extendsToAdd.length) { + // try to detect circular references to stop a stack overflow. + // may no longer be needed. + this.extendChainCount++; + if (iterationCount > 100) { + var selectorOne = '{unable to calculate}'; + var selectorTwo = '{unable to calculate}'; + try { + selectorOne = extendsToAdd[0].selfSelectors[0].toCSS(); + selectorTwo = extendsToAdd[0].selector.toCSS(); + } + catch (e) { } + throw { message: "extend circular reference detected. One of the circular extends is currently:" + selectorOne + ":extend(" + selectorTwo + ")" }; + } + // now process the new extends on the existing rules so that we can handle a extending b extending c extending + // d extending e... + return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1)); } - - if (!level && !parenLevel) { - emitChunk(); + else { + return extendsToAdd; } - - continue; - - case 92: - // \ - if (chunkerCurrentIndex < len - 1) { - chunkerCurrentIndex++; - continue; + }; + ProcessExtendsVisitor.prototype.visitDeclaration = function (ruleNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitSelector = function (selectorNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + ProcessExtendsVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + if (rulesetNode.root) { + return; } - - return fail('unescaped `\\`', chunkerCurrentIndex); - - case 34: - case 39: - case 96: - // ", ' and ` - matched = 0; - currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 > 96) { - continue; - } - - if (cc2 == cc) { - matched = 1; - break; - } - - if (cc2 == 92) { - // \ - if (chunkerCurrentIndex == len - 1) { - return fail('unescaped `\\`', chunkerCurrentIndex); + var matches; + var pathIndex; + var extendIndex; + var allExtends = this.allExtendsStack[this.allExtendsStack.length - 1]; + var selectorsToAdd = []; + var extendVisitor = this; + var selectorPath; + // look at each selector path in the ruleset, find any extend matches and then copy, find and replace + for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) { + for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) { + selectorPath = rulesetNode.paths[pathIndex]; + // extending extends happens initially, before the main pass + if (rulesetNode.extendOnEveryPath) { + continue; + } + var extendList = selectorPath[selectorPath.length - 1].extendList; + if (extendList && extendList.length) { + continue; + } + matches = this.findMatch(allExtends[extendIndex], selectorPath); + if (matches.length) { + allExtends[extendIndex].hasFoundMatches = true; + allExtends[extendIndex].selfSelectors.forEach(function (selfSelector) { + var extendedSelectors; + extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible()); + selectorsToAdd.push(extendedSelectors); + }); + } } - - chunkerCurrentIndex++; - } } - - if (matched) { - continue; + rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd); + }; + ProcessExtendsVisitor.prototype.findMatch = function (extend, haystackSelectorPath) { + // + // look through the haystack selector path to try and find the needle - extend.selector + // returns an array of selector matches that can then be replaced + // + var haystackSelectorIndex; + var hackstackSelector; + var hackstackElementIndex; + var haystackElement; + var targetCombinator; + var i; + var extendVisitor = this; + var needleElements = extend.selector.elements; + var potentialMatches = []; + var potentialMatch; + var matches = []; + // loop through the haystack elements + for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) { + hackstackSelector = haystackSelectorPath[haystackSelectorIndex]; + for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) { + haystackElement = hackstackSelector.elements[hackstackElementIndex]; + // if we allow elements before our match we can add a potential match every time. otherwise only at the first element. + if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) { + potentialMatches.push({ pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0, + initialCombinator: haystackElement.combinator }); + } + for (i = 0; i < potentialMatches.length; i++) { + potentialMatch = potentialMatches[i]; + // selectors add " " onto the first element. When we use & it joins the selectors together, but if we don't + // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to + // work out what the resulting combinator will be + targetCombinator = haystackElement.combinator.value; + if (targetCombinator === '' && hackstackElementIndex === 0) { + targetCombinator = ' '; + } + // if we don't match, null our match to indicate failure + if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) || + (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) { + potentialMatch = null; + } + else { + potentialMatch.matched++; + } + // if we are still valid and have finished, test whether we have elements after and whether these are allowed + if (potentialMatch) { + potentialMatch.finished = potentialMatch.matched === needleElements.length; + if (potentialMatch.finished && + (!extend.allowAfter && + (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) { + potentialMatch = null; + } + } + // if null we remove, if not, we are still valid, so either push as a valid match or continue + if (potentialMatch) { + if (potentialMatch.finished) { + potentialMatch.length = needleElements.length; + potentialMatch.endPathIndex = haystackSelectorIndex; + potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match + potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again + matches.push(potentialMatch); + } + } + else { + potentialMatches.splice(i, 1); + i--; + } + } + } } - - return fail("unmatched `".concat(String.fromCharCode(cc), "`"), currentChunkStartIndex); - - case 47: - // /, check for comment - if (parenLevel || chunkerCurrentIndex == len - 1) { - continue; + return matches; + }; + ProcessExtendsVisitor.prototype.isElementValuesEqual = function (elementValue1, elementValue2) { + if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') { + return elementValue1 === elementValue2; } - - cc2 = input.charCodeAt(chunkerCurrentIndex + 1); - - if (cc2 == 47) { - // //, find lnfeed - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 <= 13 && (cc2 == 10 || cc2 == 13)) { - break; + if (elementValue1 instanceof tree.Attribute) { + if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) { + return false; } - } - } else if (cc2 == 42) { - // /*, find */ - lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; - - for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { - cc2 = input.charCodeAt(chunkerCurrentIndex); - - if (cc2 == 125) { - lastMultiCommentEndBrace = chunkerCurrentIndex; + if (!elementValue1.value || !elementValue2.value) { + if (elementValue1.value || elementValue2.value) { + return false; + } + return true; } - - if (cc2 != 42) { - continue; + elementValue1 = elementValue1.value.value || elementValue1.value; + elementValue2 = elementValue2.value.value || elementValue2.value; + return elementValue1 === elementValue2; + } + elementValue1 = elementValue1.value; + elementValue2 = elementValue2.value; + if (elementValue1 instanceof tree.Selector) { + if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) { + return false; } - - if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - break; + for (var i_1 = 0; i_1 < elementValue1.elements.length; i_1++) { + if (elementValue1.elements[i_1].combinator.value !== elementValue2.elements[i_1].combinator.value) { + if (i_1 !== 0 || (elementValue1.elements[i_1].combinator.value || ' ') !== (elementValue2.elements[i_1].combinator.value || ' ')) { + return false; + } + } + if (!this.isElementValuesEqual(elementValue1.elements[i_1].value, elementValue2.elements[i_1].value)) { + return false; + } } - } - - if (chunkerCurrentIndex == len - 1) { - return fail('missing closing `*/`', currentChunkStartIndex); - } - - chunkerCurrentIndex++; + return true; } - - continue; - - case 42: - // *, check for unmatched */ - if (chunkerCurrentIndex < len - 1 && input.charCodeAt(chunkerCurrentIndex + 1) == 47) { - return fail('unmatched `/*`', chunkerCurrentIndex); + return false; + }; + ProcessExtendsVisitor.prototype.extendSelector = function (matches, selectorPath, replacementSelector, isVisible) { + // for a set of matches, replace each match with the replacement selector + var currentSelectorPathIndex = 0; + var currentSelectorPathElementIndex = 0; + var path = []; + var matchIndex; + var selector; + var firstElement; + var match; + var newElements; + for (matchIndex = 0; matchIndex < matches.length; matchIndex++) { + match = matches[matchIndex]; + selector = selectorPath[match.pathIndex]; + firstElement = new tree.Element(match.initialCombinator, replacementSelector.elements[0].value, replacementSelector.elements[0].isVariable, replacementSelector.elements[0].getIndex(), replacementSelector.elements[0].fileInfo()); + if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } + newElements = selector.elements + .slice(currentSelectorPathElementIndex, match.index) + .concat([firstElement]) + .concat(replacementSelector.elements.slice(1)); + if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) { + path[path.length - 1].elements = + path[path.length - 1].elements.concat(newElements); + } + else { + path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex)); + path.push(new tree.Selector(newElements)); + } + currentSelectorPathIndex = match.endPathIndex; + currentSelectorPathElementIndex = match.endPathElementIndex; + if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) { + currentSelectorPathElementIndex = 0; + currentSelectorPathIndex++; + } } + if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) { + path[path.length - 1].elements = path[path.length - 1] + .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex)); + currentSelectorPathIndex++; + } + path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length)); + path = path.map(function (currentValue) { + // we can re-use elements here, because the visibility property matters only for selectors + var derived = currentValue.createDerived(currentValue.elements); + if (isVisible) { + derived.ensureVisibility(); + } + else { + derived.ensureInvisibility(); + } + return derived; + }); + return path; + }; + ProcessExtendsVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitMediaOut = function (mediaNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + ProcessExtendsVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]); + newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends)); + this.allExtendsStack.push(newAllExtends); + }; + ProcessExtendsVisitor.prototype.visitAtRuleOut = function (atRuleNode) { + var lastIndex = this.allExtendsStack.length - 1; + this.allExtendsStack.length = lastIndex; + }; + return ProcessExtendsVisitor; + }()); - continue; + var JoinSelectorVisitor = /** @class */ (function () { + function JoinSelectorVisitor() { + this.contexts = [[]]; + this._visitor = new Visitor(this); } - } - - if (level !== 0) { - if (lastMultiComment > lastOpening && lastMultiCommentEndBrace > lastMultiComment) { - return fail('missing closing `}` or `*/`', lastOpening); - } else { - return fail('missing closing `}`', lastOpening); - } - } else if (parenLevel !== 0) { - return fail('missing closing `)`', lastOpeningParen); - } - - emitChunk(true); - return chunks; - }); - - var getParserInput = (function () { - var // Less input string - input; - var // current chunk - j; - var // holds state for backtracking - saveStack = []; - var // furthest index the parser has gone to - furthest; - var // if this is furthest we got to, this is the probably cause - furthestPossibleErrorMessage; - var // chunkified input - chunks; - var // current chunk - current; - var // index of current chunk, in `input` - currentPos; - var parserInput = {}; - var CHARCODE_SPACE = 32; - var CHARCODE_TAB = 9; - var CHARCODE_LF = 10; - var CHARCODE_CR = 13; - var CHARCODE_PLUS = 43; - var CHARCODE_COMMA = 44; - var CHARCODE_FORWARD_SLASH = 47; - var CHARCODE_9 = 57; - - function skipWhitespace(length) { - var oldi = parserInput.i; - var oldj = j; - var curr = parserInput.i - currentPos; - var endIndex = parserInput.i + current.length - curr; - var mem = parserInput.i += length; - var inp = input; - var c; - var nextChar; - var comment; - - for (; parserInput.i < endIndex; parserInput.i++) { - c = inp.charCodeAt(parserInput.i); - - if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { - nextChar = inp.charAt(parserInput.i + 1); - - if (nextChar === '/') { - comment = { - index: parserInput.i, - isLineComment: true - }; - var nextNewLine = inp.indexOf('\n', parserInput.i + 2); - - if (nextNewLine < 0) { - nextNewLine = endIndex; - } - - parserInput.i = nextNewLine; - comment.text = inp.substr(comment.index, parserInput.i - comment.index); - parserInput.commentStore.push(comment); - continue; - } else if (nextChar === '*') { - var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); - - if (nextStarSlash >= 0) { - comment = { - index: parserInput.i, - text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), - isLineComment: false - }; - parserInput.i += comment.text.length - 1; - parserInput.commentStore.push(comment); - continue; - } + JoinSelectorVisitor.prototype.run = function (root) { + return this._visitor.visit(root); + }; + JoinSelectorVisitor.prototype.visitDeclaration = function (declNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitMixinDefinition = function (mixinDefinitionNode, visitArgs) { + visitArgs.visitDeeper = false; + }; + JoinSelectorVisitor.prototype.visitRuleset = function (rulesetNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + var paths = []; + var selectors; + this.contexts.push(paths); + if (!rulesetNode.root) { + selectors = rulesetNode.selectors; + if (selectors) { + selectors = selectors.filter(function (selector) { return selector.getIsOutput(); }); + rulesetNode.selectors = selectors.length ? selectors : (selectors = null); + if (selectors) { + rulesetNode.joinSelectors(paths, context, selectors); + } + } + if (!selectors) { + rulesetNode.rules = null; + } + rulesetNode.paths = paths; } + }; + JoinSelectorVisitor.prototype.visitRulesetOut = function (rulesetNode) { + this.contexts.length = this.contexts.length - 1; + }; + JoinSelectorVisitor.prototype.visitMedia = function (mediaNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia); + }; + JoinSelectorVisitor.prototype.visitAtRule = function (atRuleNode, visitArgs) { + var context = this.contexts[this.contexts.length - 1]; + if (atRuleNode.rules && atRuleNode.rules.length) { + atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null); + } + }; + return JoinSelectorVisitor; + }()); - break; - } - - if (c !== CHARCODE_SPACE && c !== CHARCODE_LF && c !== CHARCODE_TAB && c !== CHARCODE_CR) { - break; - } - } - - current = current.slice(length + parserInput.i - mem + curr); - currentPos = parserInput.i; - - if (!current.length) { - if (j < chunks.length - 1) { - current = chunks[++j]; - skipWhitespace(0); // skip space at the beginning of a chunk - - return true; // things changed - } - - parserInput.finished = true; - } - - return oldi !== parserInput.i || oldj !== j; - } - - parserInput.save = function () { - currentPos = parserInput.i; - saveStack.push({ - current: current, - i: parserInput.i, - j: j - }); - }; - - parserInput.restore = function (possibleErrorMessage) { - if (parserInput.i > furthest || parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage) { - furthest = parserInput.i; - furthestPossibleErrorMessage = possibleErrorMessage; - } - - var state = saveStack.pop(); - current = state.current; - currentPos = parserInput.i = state.i; - j = state.j; - }; - - parserInput.forget = function () { - saveStack.pop(); - }; - - parserInput.isWhitespace = function (offset) { - var pos = parserInput.i + (offset || 0); - var code = input.charCodeAt(pos); - return code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF; - }; // Specialization of $(tok) - - - parserInput.$re = function (tok) { - if (parserInput.i > currentPos) { - current = current.slice(parserInput.i - currentPos); - currentPos = parserInput.i; - } - - var m = tok.exec(current); - - if (!m) { - return null; - } - - skipWhitespace(m[0].length); - - if (typeof m === 'string') { - return m; - } - - return m.length === 1 ? m[0] : m; - }; - - parserInput.$char = function (tok) { - if (input.charAt(parserInput.i) !== tok) { - return null; - } - - skipWhitespace(1); - return tok; - }; - - parserInput.$str = function (tok) { - var tokLength = tok.length; // https://jsperf.com/string-startswith/21 - - for (var i = 0; i < tokLength; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { - return null; - } + var CSSVisitorUtils = /** @class */ (function () { + function CSSVisitorUtils(context) { + this._visitor = new Visitor(this); + this._context = context; } - - skipWhitespace(tokLength); - return tok; - }; - - parserInput.$quoted = function (loc) { - var pos = loc || parserInput.i; - var startChar = input.charAt(pos); - - if (startChar !== '\'' && startChar !== '"') { - return; - } - - var length = input.length; - var currentPosition = pos; - - for (var i = 1; i + currentPosition < length; i++) { - var nextChar = input.charAt(i + currentPosition); - - switch (nextChar) { - case '\\': - i++; - continue; - - case '\r': - case '\n': - break; - - case startChar: - var str = input.substr(currentPosition, i + 1); - - if (!loc && loc !== 0) { - skipWhitespace(i + 1); - return str; - } - - return [startChar, str]; - - default: - } - } - - return null; - }; - /** - * Permissive parsing. Ignores everything except matching {} [] () and quotes - * until matching token (outside of blocks) - */ - - - parserInput.$parseUntil = function (tok) { - var quote = ''; - var returnVal = null; - var inComment = false; - var blockDepth = 0; - var blockStack = []; - var parseGroups = []; - var length = input.length; - var startPos = parserInput.i; - var lastPos = parserInput.i; - var i = parserInput.i; - var loop = true; - var testChar; - - if (typeof tok === 'string') { - testChar = function testChar(char) { - return char === tok; - }; - } else { - testChar = function testChar(char) { - return tok.test(char); - }; - } - - do { - var nextChar = input.charAt(i); - - if (blockDepth === 0 && testChar(nextChar)) { - returnVal = input.substr(lastPos, i - lastPos); - - if (returnVal) { - parseGroups.push(returnVal); - } else { - parseGroups.push(' '); + CSSVisitorUtils.prototype.containsSilentNonBlockedChild = function (bodyRules) { + var rule; + if (!bodyRules) { + return false; } - - returnVal = parseGroups; - skipWhitespace(i - startPos); - loop = false; - } else { - if (inComment) { - if (nextChar === '*' && input.charAt(i + 1) === '/') { - i++; - blockDepth--; - inComment = false; - } - - i++; - continue; + for (var r = 0; r < bodyRules.length; r++) { + rule = bodyRules[r]; + if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) { + // the atrule contains something that was referenced (likely by extend) + // therefore it needs to be shown in output too + return true; + } } - - switch (nextChar) { - case '\\': - i++; - nextChar = input.charAt(i); - parseGroups.push(input.substr(lastPos, i - lastPos + 1)); - lastPos = i + 1; - break; - - case '/': - if (input.charAt(i + 1) === '*') { - i++; - inComment = true; - blockDepth++; + return false; + }; + CSSVisitorUtils.prototype.keepOnlyVisibleChilds = function (owner) { + if (owner && owner.rules) { + owner.rules = owner.rules.filter(function (thing) { return thing.isVisible(); }); + } + }; + CSSVisitorUtils.prototype.isEmpty = function (owner) { + return (owner && owner.rules) + ? (owner.rules.length === 0) : true; + }; + CSSVisitorUtils.prototype.hasVisibleSelector = function (rulesetNode) { + return (rulesetNode && rulesetNode.paths) + ? (rulesetNode.paths.length > 0) : false; + }; + CSSVisitorUtils.prototype.resolveVisibility = function (node, originalRules) { + if (!node.blocksVisibility()) { + if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) { + return; } - - break; - - case '\'': - case '"': - quote = parserInput.$quoted(i); - - if (quote) { - parseGroups.push(input.substr(lastPos, i - lastPos), quote); - i += quote[1].length - 1; - lastPos = i + 1; - } else { - skipWhitespace(i - startPos); - returnVal = nextChar; - loop = false; + return node; + } + var compiledRulesBody = node.rules[0]; + this.keepOnlyVisibleChilds(compiledRulesBody); + if (this.isEmpty(compiledRulesBody)) { + return; + } + node.ensureVisibility(); + node.removeVisibilityBlock(); + return node; + }; + CSSVisitorUtils.prototype.isVisibleRuleset = function (rulesetNode) { + if (rulesetNode.firstRoot) { + return true; + } + if (this.isEmpty(rulesetNode)) { + return false; + } + if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) { + return false; + } + return true; + }; + return CSSVisitorUtils; + }()); + var ToCSSVisitor = function (context) { + this._visitor = new Visitor(this); + this._context = context; + this.utils = new CSSVisitorUtils(context); + }; + ToCSSVisitor.prototype = { + isReplacing: true, + run: function (root) { + return this._visitor.visit(root); + }, + visitDeclaration: function (declNode, visitArgs) { + if (declNode.blocksVisibility() || declNode.variable) { + return; + } + return declNode; + }, + visitMixinDefinition: function (mixinNode, visitArgs) { + // mixin definitions do not get eval'd - this means they keep state + // so we have to clear that state here so it isn't used if toCSS is called twice + mixinNode.frames = []; + }, + visitExtend: function (extendNode, visitArgs) { + }, + visitComment: function (commentNode, visitArgs) { + if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) { + return; + } + return commentNode; + }, + visitMedia: function (mediaNode, visitArgs) { + var originalRules = mediaNode.rules[0].rules; + mediaNode.accept(this._visitor); + visitArgs.visitDeeper = false; + return this.utils.resolveVisibility(mediaNode, originalRules); + }, + visitImport: function (importNode, visitArgs) { + if (importNode.blocksVisibility()) { + return; + } + return importNode; + }, + visitAtRule: function (atRuleNode, visitArgs) { + if (atRuleNode.rules && atRuleNode.rules.length) { + return this.visitAtRuleWithBody(atRuleNode, visitArgs); + } + else { + return this.visitAtRuleWithoutBody(atRuleNode, visitArgs); + } + }, + visitAnonymous: function (anonymousNode, visitArgs) { + if (!anonymousNode.blocksVisibility()) { + anonymousNode.accept(this._visitor); + return anonymousNode; + } + }, + visitAtRuleWithBody: function (atRuleNode, visitArgs) { + // if there is only one nested ruleset and that one has no path, then it is + // just fake ruleset + function hasFakeRuleset(atRuleNode) { + var bodyRules = atRuleNode.rules; + return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0); + } + function getBodyRules(atRuleNode) { + var nodeRules = atRuleNode.rules; + if (hasFakeRuleset(atRuleNode)) { + return nodeRules[0].rules; } - - break; - - case '{': - blockStack.push('}'); - blockDepth++; - break; - - case '(': - blockStack.push(')'); - blockDepth++; - break; - - case '[': - blockStack.push(']'); - blockDepth++; - break; - - case '}': - case ')': - case ']': - var expected = blockStack.pop(); - - if (nextChar === expected) { - blockDepth--; - } else { - // move the parser to the error and return expected - skipWhitespace(i - startPos); - returnVal = expected; - loop = false; + return nodeRules; + } + // it is still true that it is only one ruleset in array + // this is last such moment + // process childs + var originalRules = getBodyRules(atRuleNode); + atRuleNode.accept(this._visitor); + visitArgs.visitDeeper = false; + if (!this.utils.isEmpty(atRuleNode)) { + this._mergeRules(atRuleNode.rules[0].rules); + } + return this.utils.resolveVisibility(atRuleNode, originalRules); + }, + visitAtRuleWithoutBody: function (atRuleNode, visitArgs) { + if (atRuleNode.blocksVisibility()) { + return; + } + if (atRuleNode.name === '@charset') { + // Only output the debug info together with subsequent @charset definitions + // a comment (or @media statement) before the actual @charset atrule would + // be considered illegal css as it has to be on the first line + if (this.charset) { + if (atRuleNode.debugInfo) { + var comment = new tree.Comment("/* " + atRuleNode.toCSS(this._context).replace(/\n/g, '') + " */\n"); + comment.debugInfo = atRuleNode.debugInfo; + return this._visitor.visit(comment); + } + return; } - + this.charset = true; } - - i++; - - if (i > length) { - loop = false; + return atRuleNode; + }, + checkValidNodes: function (rules, isRoot) { + if (!rules) { + return; } - } - } while (loop); - - return returnVal ? returnVal : null; - }; - - parserInput.autoCommentAbsorb = true; - parserInput.commentStore = []; - parserInput.finished = false; // Same as $(), but don't change the state of the parser, - // just return the match. - - parserInput.peek = function (tok) { - if (typeof tok === 'string') { - // https://jsperf.com/string-startswith/21 - for (var i = 0; i < tok.length; i++) { - if (input.charAt(parserInput.i + i) !== tok.charAt(i)) { - return false; - } - } - - return true; - } else { - return tok.test(current); + for (var i_1 = 0; i_1 < rules.length; i_1++) { + var ruleNode = rules[i_1]; + if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) { + throw { message: 'Properties must be inside selector blocks. They cannot be in the root', + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; + } + if (ruleNode instanceof tree.Call) { + throw { message: "Function '" + ruleNode.name + "' is undefined", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; + } + if (ruleNode.type && !ruleNode.allowRoot) { + throw { message: ruleNode.type + " node returned by a function is not valid here", + index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename }; + } + } + }, + visitRuleset: function (rulesetNode, visitArgs) { + // at this point rulesets are nested into each other + var rule; + var rulesets = []; + this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); + if (!rulesetNode.root) { + // remove invisible paths + this._compileRulesetPaths(rulesetNode); + // remove rulesets from this ruleset body and compile them separately + var nodeRules = rulesetNode.rules; + var nodeRuleCnt = nodeRules ? nodeRules.length : 0; + for (var i_2 = 0; i_2 < nodeRuleCnt;) { + rule = nodeRules[i_2]; + if (rule && rule.rules) { + // visit because we are moving them out from being a child + rulesets.push(this._visitor.visit(rule)); + nodeRules.splice(i_2, 1); + nodeRuleCnt--; + continue; + } + i_2++; + } + // accept the visitor to remove rules and refactor itself + // then we can decide nogw whether we want it or not + // compile body + if (nodeRuleCnt > 0) { + rulesetNode.accept(this._visitor); + } + else { + rulesetNode.rules = null; + } + visitArgs.visitDeeper = false; + } + else { // if (! rulesetNode.root) { + rulesetNode.accept(this._visitor); + visitArgs.visitDeeper = false; + } + if (rulesetNode.rules) { + this._mergeRules(rulesetNode.rules); + this._removeDuplicateRules(rulesetNode.rules); + } + // now decide whether we keep the ruleset + if (this.utils.isVisibleRuleset(rulesetNode)) { + rulesetNode.ensureVisibility(); + rulesets.splice(0, 0, rulesetNode); + } + if (rulesets.length === 1) { + return rulesets[0]; + } + return rulesets; + }, + _compileRulesetPaths: function (rulesetNode) { + if (rulesetNode.paths) { + rulesetNode.paths = rulesetNode.paths + .filter(function (p) { + var i; + if (p[0].elements[0].combinator.value === ' ') { + p[0].elements[0].combinator = new (tree.Combinator)(''); + } + for (i = 0; i < p.length; i++) { + if (p[i].isVisible() && p[i].getIsOutput()) { + return true; + } + } + return false; + }); + } + }, + _removeDuplicateRules: function (rules) { + if (!rules) { + return; + } + // remove duplicates + var ruleCache = {}; + var ruleList; + var rule; + var i; + for (i = rules.length - 1; i >= 0; i--) { + rule = rules[i]; + if (rule instanceof tree.Declaration) { + if (!ruleCache[rule.name]) { + ruleCache[rule.name] = rule; + } + else { + ruleList = ruleCache[rule.name]; + if (ruleList instanceof tree.Declaration) { + ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)]; + } + var ruleCSS = rule.toCSS(this._context); + if (ruleList.indexOf(ruleCSS) !== -1) { + rules.splice(i, 1); + } + else { + ruleList.push(ruleCSS); + } + } + } + } + }, + _mergeRules: function (rules) { + if (!rules) { + return; + } + var groups = {}; + var groupsArr = []; + for (var i_3 = 0; i_3 < rules.length; i_3++) { + var rule = rules[i_3]; + if (rule.merge) { + var key = rule.name; + groups[key] ? rules.splice(i_3--, 1) : + groupsArr.push(groups[key] = []); + groups[key].push(rule); + } + } + groupsArr.forEach(function (group) { + if (group.length > 0) { + var result_1 = group[0]; + var space_1 = []; + var comma_1 = [new tree.Expression(space_1)]; + group.forEach(function (rule) { + if ((rule.merge === '+') && (space_1.length > 0)) { + comma_1.push(new tree.Expression(space_1 = [])); + } + space_1.push(rule.value); + result_1.important = result_1.important || rule.important; + }); + result_1.value = new tree.Value(comma_1); + } + }); } - }; // Specialization of peek() - // TODO remove or change some currentChar calls to peekChar - - - parserInput.peekChar = function (tok) { - return input.charAt(parserInput.i) === tok; - }; - - parserInput.currentChar = function () { - return input.charAt(parserInput.i); - }; - - parserInput.prevChar = function () { - return input.charAt(parserInput.i - 1); - }; - - parserInput.getInput = function () { - return input; - }; - - parserInput.peekNotNumeric = function () { - var c = input.charCodeAt(parserInput.i); // Is the first char of the dimension 0-9, '.', '+' or '-' - - return c > CHARCODE_9 || c < CHARCODE_PLUS || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; - }; + }; - parserInput.start = function (str, chunkInput, failFunction) { - input = str; - parserInput.i = j = currentPos = furthest = 0; // chunking apparently makes things quicker (but my tests indicate - // it might actually make things slower in node at least) - // and it is a non-perfect parse - it can't recognise - // unquoted urls, meaning it can't distinguish comments - // meaning comments with quotes or {}() in them get 'counted' - // and then lead to parse errors. - // In addition if the chunking chunks in the wrong place we might - // not be able to parse a parser statement in one go - // this is officially deprecated but can be switched on via an option - // in the case it causes too much performance issues. + var visitors = { + Visitor: Visitor, + ImportVisitor: ImportVisitor, + MarkVisibleSelectorsVisitor: SetTreeVisibilityVisitor, + ExtendVisitor: ProcessExtendsVisitor, + JoinSelectorVisitor: JoinSelectorVisitor, + ToCSSVisitor: ToCSSVisitor + }; - if (chunkInput) { - chunks = chunker(str, failFunction); - } else { - chunks = [str]; + // Split the input into chunks. + var chunker = (function (input, fail) { + var len = input.length; + var level = 0; + var parenLevel = 0; + var lastOpening; + var lastOpeningParen; + var lastMultiComment; + var lastMultiCommentEndBrace; + var chunks = []; + var emitFrom = 0; + var chunkerCurrentIndex; + var currentChunkStartIndex; + var cc; + var cc2; + var matched; + function emitChunk(force) { + var len = chunkerCurrentIndex - emitFrom; + if (((len < 512) && !force) || !len) { + return; + } + chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1)); + emitFrom = chunkerCurrentIndex + 1; } - - current = chunks[0]; - skipWhitespace(0); - }; - - parserInput.end = function () { - var message; - var isFinished = parserInput.i >= input.length; - - if (parserInput.i < furthest) { - message = furthestPossibleErrorMessage; - parserInput.i = furthest; + for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc = input.charCodeAt(chunkerCurrentIndex); + if (((cc >= 97) && (cc <= 122)) || (cc < 34)) { + // a-z or whitespace + continue; + } + switch (cc) { + case 40: // ( + parenLevel++; + lastOpeningParen = chunkerCurrentIndex; + continue; + case 41: // ) + if (--parenLevel < 0) { + return fail('missing opening `(`', chunkerCurrentIndex); + } + continue; + case 59: // ; + if (!parenLevel) { + emitChunk(); + } + continue; + case 123: // { + level++; + lastOpening = chunkerCurrentIndex; + continue; + case 125: // } + if (--level < 0) { + return fail('missing opening `{`', chunkerCurrentIndex); + } + if (!level && !parenLevel) { + emitChunk(); + } + continue; + case 92: // \ + if (chunkerCurrentIndex < len - 1) { + chunkerCurrentIndex++; + continue; + } + return fail('unescaped `\\`', chunkerCurrentIndex); + case 34: + case 39: + case 96: // ", ' and ` + matched = 0; + currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 > 96) { + continue; + } + if (cc2 == cc) { + matched = 1; + break; + } + if (cc2 == 92) { // \ + if (chunkerCurrentIndex == len - 1) { + return fail('unescaped `\\`', chunkerCurrentIndex); + } + chunkerCurrentIndex++; + } + } + if (matched) { + continue; + } + return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex); + case 47: // /, check for comment + if (parenLevel || (chunkerCurrentIndex == len - 1)) { + continue; + } + cc2 = input.charCodeAt(chunkerCurrentIndex + 1); + if (cc2 == 47) { + // //, find lnfeed + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { + break; + } + } + } + else if (cc2 == 42) { + // /*, find */ + lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex; + for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) { + cc2 = input.charCodeAt(chunkerCurrentIndex); + if (cc2 == 125) { + lastMultiCommentEndBrace = chunkerCurrentIndex; + } + if (cc2 != 42) { + continue; + } + if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { + break; + } + } + if (chunkerCurrentIndex == len - 1) { + return fail('missing closing `*/`', currentChunkStartIndex); + } + chunkerCurrentIndex++; + } + continue; + case 42: // *, check for unmatched */ + if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) { + return fail('unmatched `/*`', chunkerCurrentIndex); + } + continue; + } + } + if (level !== 0) { + if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) { + return fail('missing closing `}` or `*/`', lastOpening); + } + else { + return fail('missing closing `}`', lastOpening); + } } + else if (parenLevel !== 0) { + return fail('missing closing `)`', lastOpeningParen); + } + emitChunk(true); + return chunks; + }); - return { - isFinished: isFinished, - furthest: parserInput.i, - furthestPossibleErrorMessage: message, - furthestReachedEnd: parserInput.i >= input.length - 1, - furthestChar: input[parserInput.i] + var getParserInput = (function () { + var // Less input string + input; + var // current chunk + j; + var // holds state for backtracking + saveStack = []; + var // furthest index the parser has gone to + furthest; + var // if this is furthest we got to, this is the probably cause + furthestPossibleErrorMessage; + var // chunkified input + chunks; + var // current chunk + current; + var // index of current chunk, in `input` + currentPos; + var parserInput = {}; + var CHARCODE_SPACE = 32; + var CHARCODE_TAB = 9; + var CHARCODE_LF = 10; + var CHARCODE_CR = 13; + var CHARCODE_PLUS = 43; + var CHARCODE_COMMA = 44; + var CHARCODE_FORWARD_SLASH = 47; + var CHARCODE_9 = 57; + function skipWhitespace(length) { + var oldi = parserInput.i; + var oldj = j; + var curr = parserInput.i - currentPos; + var endIndex = parserInput.i + current.length - curr; + var mem = (parserInput.i += length); + var inp = input; + var c; + var nextChar; + var comment; + for (; parserInput.i < endIndex; parserInput.i++) { + c = inp.charCodeAt(parserInput.i); + if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) { + nextChar = inp.charAt(parserInput.i + 1); + if (nextChar === '/') { + comment = { index: parserInput.i, isLineComment: true }; + var nextNewLine = inp.indexOf('\n', parserInput.i + 2); + if (nextNewLine < 0) { + nextNewLine = endIndex; + } + parserInput.i = nextNewLine; + comment.text = inp.substr(comment.index, parserInput.i - comment.index); + parserInput.commentStore.push(comment); + continue; + } + else if (nextChar === '*') { + var nextStarSlash = inp.indexOf('*/', parserInput.i + 2); + if (nextStarSlash >= 0) { + comment = { + index: parserInput.i, + text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i), + isLineComment: false + }; + parserInput.i += comment.text.length - 1; + parserInput.commentStore.push(comment); + continue; + } + } + break; + } + if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) { + break; + } + } + current = current.slice(length + parserInput.i - mem + curr); + currentPos = parserInput.i; + if (!current.length) { + if (j < chunks.length - 1) { + current = chunks[++j]; + skipWhitespace(0); // skip space at the beginning of a chunk + return true; // things changed + } + parserInput.finished = true; + } + return oldi !== parserInput.i || oldj !== j; + } + parserInput.save = function () { + currentPos = parserInput.i; + saveStack.push({ current: current, i: parserInput.i, j: j }); }; - }; - - return parserInput; + parserInput.restore = function (possibleErrorMessage) { + if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) { + furthest = parserInput.i; + furthestPossibleErrorMessage = possibleErrorMessage; + } + var state = saveStack.pop(); + current = state.current; + currentPos = parserInput.i = state.i; + j = state.j; + }; + parserInput.forget = function () { + saveStack.pop(); + }; + parserInput.isWhitespace = function (offset) { + var pos = parserInput.i + (offset || 0); + var code = input.charCodeAt(pos); + return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF); + }; + // Specialization of $(tok) + parserInput.$re = function (tok) { + if (parserInput.i > currentPos) { + current = current.slice(parserInput.i - currentPos); + currentPos = parserInput.i; + } + var m = tok.exec(current); + if (!m) { + return null; + } + skipWhitespace(m[0].length); + if (typeof m === 'string') { + return m; + } + return m.length === 1 ? m[0] : m; + }; + parserInput.$char = function (tok) { + if (input.charAt(parserInput.i) !== tok) { + return null; + } + skipWhitespace(1); + return tok; + }; + parserInput.$str = function (tok) { + var tokLength = tok.length; + // https://jsperf.com/string-startswith/21 + for (var i_1 = 0; i_1 < tokLength; i_1++) { + if (input.charAt(parserInput.i + i_1) !== tok.charAt(i_1)) { + return null; + } + } + skipWhitespace(tokLength); + return tok; + }; + parserInput.$quoted = function (loc) { + var pos = loc || parserInput.i; + var startChar = input.charAt(pos); + if (startChar !== '\'' && startChar !== '"') { + return; + } + var length = input.length; + var currentPosition = pos; + for (var i_2 = 1; i_2 + currentPosition < length; i_2++) { + var nextChar = input.charAt(i_2 + currentPosition); + switch (nextChar) { + case '\\': + i_2++; + continue; + case '\r': + case '\n': + break; + case startChar: + var str = input.substr(currentPosition, i_2 + 1); + if (!loc && loc !== 0) { + skipWhitespace(i_2 + 1); + return str; + } + return [startChar, str]; + } + } + return null; + }; + /** + * Permissive parsing. Ignores everything except matching {} [] () and quotes + * until matching token (outside of blocks) + */ + parserInput.$parseUntil = function (tok) { + var quote = ''; + var returnVal = null; + var inComment = false; + var blockDepth = 0; + var blockStack = []; + var parseGroups = []; + var length = input.length; + var startPos = parserInput.i; + var lastPos = parserInput.i; + var i = parserInput.i; + var loop = true; + var testChar; + if (typeof tok === 'string') { + testChar = function (char) { return char === tok; }; + } + else { + testChar = function (char) { return tok.test(char); }; + } + do { + var nextChar = input.charAt(i); + if (blockDepth === 0 && testChar(nextChar)) { + returnVal = input.substr(lastPos, i - lastPos); + if (returnVal) { + parseGroups.push(returnVal); + } + else { + parseGroups.push(' '); + } + returnVal = parseGroups; + skipWhitespace(i - startPos); + loop = false; + } + else { + if (inComment) { + if (nextChar === '*' && + input.charAt(i + 1) === '/') { + i++; + blockDepth--; + inComment = false; + } + i++; + continue; + } + switch (nextChar) { + case '\\': + i++; + nextChar = input.charAt(i); + parseGroups.push(input.substr(lastPos, i - lastPos + 1)); + lastPos = i + 1; + break; + case '/': + if (input.charAt(i + 1) === '*') { + i++; + inComment = true; + blockDepth++; + } + break; + case '\'': + case '"': + quote = parserInput.$quoted(i); + if (quote) { + parseGroups.push(input.substr(lastPos, i - lastPos), quote); + i += quote[1].length - 1; + lastPos = i + 1; + } + else { + skipWhitespace(i - startPos); + returnVal = nextChar; + loop = false; + } + break; + case '{': + blockStack.push('}'); + blockDepth++; + break; + case '(': + blockStack.push(')'); + blockDepth++; + break; + case '[': + blockStack.push(']'); + blockDepth++; + break; + case '}': + case ')': + case ']': + var expected = blockStack.pop(); + if (nextChar === expected) { + blockDepth--; + } + else { + // move the parser to the error and return expected + skipWhitespace(i - startPos); + returnVal = expected; + loop = false; + } + } + i++; + if (i > length) { + loop = false; + } + } + } while (loop); + return returnVal ? returnVal : null; + }; + parserInput.autoCommentAbsorb = true; + parserInput.commentStore = []; + parserInput.finished = false; + // Same as $(), but don't change the state of the parser, + // just return the match. + parserInput.peek = function (tok) { + if (typeof tok === 'string') { + // https://jsperf.com/string-startswith/21 + for (var i_3 = 0; i_3 < tok.length; i_3++) { + if (input.charAt(parserInput.i + i_3) !== tok.charAt(i_3)) { + return false; + } + } + return true; + } + else { + return tok.test(current); + } + }; + // Specialization of peek() + // TODO remove or change some currentChar calls to peekChar + parserInput.peekChar = function (tok) { return input.charAt(parserInput.i) === tok; }; + parserInput.currentChar = function () { return input.charAt(parserInput.i); }; + parserInput.prevChar = function () { return input.charAt(parserInput.i - 1); }; + parserInput.getInput = function () { return input; }; + parserInput.peekNotNumeric = function () { + var c = input.charCodeAt(parserInput.i); + // Is the first char of the dimension 0-9, '.', '+' or '-' + return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA; + }; + parserInput.start = function (str, chunkInput, failFunction) { + input = str; + parserInput.i = j = currentPos = furthest = 0; + // chunking apparently makes things quicker (but my tests indicate + // it might actually make things slower in node at least) + // and it is a non-perfect parse - it can't recognise + // unquoted urls, meaning it can't distinguish comments + // meaning comments with quotes or {}() in them get 'counted' + // and then lead to parse errors. + // In addition if the chunking chunks in the wrong place we might + // not be able to parse a parser statement in one go + // this is officially deprecated but can be switched on via an option + // in the case it causes too much performance issues. + if (chunkInput) { + chunks = chunker(str, failFunction); + } + else { + chunks = [str]; + } + current = chunks[0]; + skipWhitespace(0); + }; + parserInput.end = function () { + var message; + var isFinished = parserInput.i >= input.length; + if (parserInput.i < furthest) { + message = furthestPossibleErrorMessage; + parserInput.i = furthest; + } + return { + isFinished: isFinished, + furthest: parserInput.i, + furthestPossibleErrorMessage: message, + furthestReachedEnd: parserInput.i >= input.length - 1, + furthestChar: input[parserInput.i] + }; + }; + return parserInput; }); + // // less.js - parser // // A relatively straight-forward predictive parser. @@ -8931,5336 +6875,4641 @@ // a terminal string or regexp, or a non-terminal function to call. // It also takes care of moving all the indices forwards. // - var Parser = function Parser(context, imports, fileInfo) { - var parsers; - var parserInput = getParserInput(); - - function error(msg, type) { - throw new LessError({ - index: parserInput.i, - filename: fileInfo.filename, - type: type || 'Syntax', - message: msg - }, imports); - } - - function expect(arg, msg) { - // some older browsers return typeof 'function' for RegExp - var result = arg instanceof Function ? arg.call(parsers) : parserInput.$re(arg); - - if (result) { - return result; - } - - error(msg || (typeof arg === 'string' ? "expected '".concat(arg, "' got '").concat(parserInput.currentChar(), "'") : 'unexpected token')); - } // Specialization of expect() - - - function expectChar(arg, msg) { - if (parserInput.$char(arg)) { - return arg; + var parsers; + var parserInput = getParserInput(); + function error(msg, type) { + throw new LessError({ + index: parserInput.i, + filename: fileInfo.filename, + type: type || 'Syntax', + message: msg + }, imports); } - - error(msg || "expected '".concat(arg, "' got '").concat(parserInput.currentChar(), "'")); - } - - function getDebugInfo(index) { - var filename = fileInfo.filename; - return { - lineNumber: getLocation(index, parserInput.getInput()).line + 1, - fileName: filename - }; - } - /** - * Used after initial parsing to create nodes on the fly - * - * @param {String} str - string to parse - * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] - * @param {Number} currentIndex - start number to begin indexing - * @param {Object} fileInfo - fileInfo to attach to created nodes - */ - - - function parseNode(str, parseList, currentIndex, fileInfo, callback) { - var result; - var returnNodes = []; - var parser = parserInput; - - try { - parser.start(str, false, function fail(msg, index) { - callback({ - message: msg, - index: index + currentIndex - }); - }); - - for (var x = 0, p, i; p = parseList[x]; x++) { - i = parser.i; - result = parsers[p](); - + function expect(arg, msg) { + // some older browsers return typeof 'function' for RegExp + var result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg); if (result) { - try { - result._index = i + currentIndex; - result._fileInfo = fileInfo; - } catch (e) {} - - returnNodes.push(result); - } else { - returnNodes.push(null); + return result; } - } - - var endInfo = parser.end(); - - if (endInfo.isFinished) { - callback(null, returnNodes); - } else { - callback(true, null); - } - } catch (e) { - throw new LessError({ - index: e.index + currentIndex, - message: e.message - }, imports, fileInfo.filename); - } - } // - // The Parser - // - - - return { - parserInput: parserInput, - imports: imports, - fileInfo: fileInfo, - parseNode: parseNode, - // - // Parse an input string into an abstract syntax tree, - // @param str A string containing 'less' markup - // @param callback call `callback` when done. - // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply - // - parse: function parse(str, callback, additionalData) { - var root; - var error = null; - var globalVars; - var modifyVars; - var ignored; - var preText = ''; - globalVars = additionalData && additionalData.globalVars ? "".concat(Parser.serializeVars(additionalData.globalVars), "\n") : ''; - modifyVars = additionalData && additionalData.modifyVars ? "\n".concat(Parser.serializeVars(additionalData.modifyVars)) : ''; - - if (context.pluginManager) { - var preProcessors = context.pluginManager.getPreProcessors(); - - for (var i = 0; i < preProcessors.length; i++) { - str = preProcessors[i].process(str, { - context: context, - imports: imports, - fileInfo: fileInfo - }); + error(msg || (typeof arg === 'string' + ? "expected '" + arg + "' got '" + parserInput.currentChar() + "'" + : 'unexpected token')); + } + // Specialization of expect() + function expectChar(arg, msg) { + if (parserInput.$char(arg)) { + return arg; } - } - - if (globalVars || additionalData && additionalData.banner) { - preText = (additionalData && additionalData.banner ? additionalData.banner : '') + globalVars; - ignored = imports.contentsIgnoredChars; - ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; - ignored[fileInfo.filename] += preText.length; - } - - str = str.replace(/\r\n?/g, '\n'); // Remove potential UTF Byte Order Mark - - str = preText + str.replace(/^\uFEFF/, '') + modifyVars; - imports.contents[fileInfo.filename] = str; // Start with the primary rule. - // The whole syntax tree is held under a Ruleset node, - // with the `root` property set to true, so no `{}` are - // output. The callback is called when the input is parsed. - - try { - parserInput.start(str, context.chunkInput, function fail(msg, index) { - throw new LessError({ - index: index, - type: 'Parse', - message: msg, - filename: fileInfo.filename - }, imports); - }); - tree.Node.prototype.parse = this; - root = new tree.Ruleset(null, this.parsers.primary()); - tree.Node.prototype.rootNode = root; - root.root = true; - root.firstRoot = true; - root.functionRegistry = functionRegistry.inherit(); - } catch (e) { - return callback(new LessError(e, imports, fileInfo.filename)); - } // If `i` is smaller than the `input.length - 1`, - // it means the parser wasn't able to parse the whole - // string, so we've got a parsing error. - // - // We try to extract a \n delimited string, - // showing the line where the parse error occurred. - // We split it up into two parts (the part which parsed, - // and the part which didn't), so we can color them differently. - - - var endInfo = parserInput.end(); - - if (!endInfo.isFinished) { - var message = endInfo.furthestPossibleErrorMessage; - - if (!message) { - message = 'Unrecognised input'; - - if (endInfo.furthestChar === '}') { - message += '. Possibly missing opening \'{\''; - } else if (endInfo.furthestChar === ')') { - message += '. Possibly missing opening \'(\''; - } else if (endInfo.furthestReachedEnd) { - message += '. Possibly missing something'; - } - } - - error = new LessError({ - type: 'Parse', - message: message, - index: endInfo.furthest, - filename: fileInfo.filename - }, imports); - } - - var finish = function finish(e) { - e = error || e || imports.error; - - if (e) { - if (!(e instanceof LessError)) { - e = new LessError(e, imports, fileInfo.filename); - } - - return callback(e); - } else { - return callback(null, root); - } - }; - - if (context.processImports !== false) { - new visitors.ImportVisitor(imports, finish).run(root); - } else { - return finish(); - } - }, - // - // Here in, the parsing rules/functions - // - // The basic structure of the syntax tree generated is as follows: - // - // Ruleset -> Declaration -> Value -> Expression -> Entity - // - // Here's some Less code: - // - // .class { - // color: #fff; - // border: 1px solid #000; - // width: @w + 4px; - // > .child {...} - // } - // - // And here's what the parse tree might look like: - // - // Ruleset (Selector '.class', [ - // Declaration ("color", Value ([Expression [Color #fff]])) - // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) - // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) - // Ruleset (Selector [Element '>', '.child'], [...]) - // ]) - // - // In general, most rules will try to parse a token with the `$re()` function, and if the return - // value is truly, will return a new node, of the relevant type. Sometimes, we need to check - // first, before parsing, that's when we use `peek()`. - // - parsers: parsers = { - // - // The `primary` rule is the *entry* and *exit* point of the parser. - // The rules here can appear at any level of the parse tree. - // - // The recursive nature of the grammar is an interplay between the `block` - // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, - // as represented by this simplified grammar: - // - // primary → (ruleset | declaration)+ - // ruleset → selector+ block - // block → '{' primary '}' - // - // Only at one point is the primary rule not called from the - // block rule: at the root level. - // - primary: function primary() { - var mixin = this.mixin; - var root = []; - var node; - - while (true) { - while (true) { - node = this.comment(); - - if (!node) { - break; + error(msg || "expected '" + arg + "' got '" + parserInput.currentChar() + "'"); + } + function getDebugInfo(index) { + var filename = fileInfo.filename; + return { + lineNumber: getLocation(index, parserInput.getInput()).line + 1, + fileName: filename + }; + } + /** + * Used after initial parsing to create nodes on the fly + * + * @param {String} str - string to parse + * @param {Array} parseList - array of parsers to run input through e.g. ["value", "important"] + * @param {Number} currentIndex - start number to begin indexing + * @param {Object} fileInfo - fileInfo to attach to created nodes + */ + function parseNode(str, parseList, currentIndex, fileInfo, callback) { + var result; + var returnNodes = []; + var parser = parserInput; + try { + parser.start(str, false, function fail(msg, index) { + callback({ + message: msg, + index: index + currentIndex + }); + }); + for (var x = 0, p = void 0, i_1; (p = parseList[x]); x++) { + i_1 = parser.i; + result = parsers[p](); + if (result) { + try { + result._index = i_1 + currentIndex; + result._fileInfo = fileInfo; + } + catch (e) { } + returnNodes.push(result); + } + else { + returnNodes.push(null); + } } - - root.push(node); - } // always process comments before deciding if finished - - - if (parserInput.finished) { - break; - } - - if (parserInput.peek('}')) { - break; - } - - node = this.extendRule(); - - if (node) { - root = root.concat(node); - continue; - } - - node = mixin.definition() || this.declaration() || this.ruleset() || mixin.call(false, false) || this.variableCall() || this.entities.call() || this.atrule(); - - if (node) { - root.push(node); - } else { - var foundSemiColon = false; - - while (parserInput.$char(';')) { - foundSemiColon = true; + var endInfo = parser.end(); + if (endInfo.isFinished) { + callback(null, returnNodes); } - - if (!foundSemiColon) { - break; + else { + callback(true, null); } - } } - - return root; - }, - // comments are collected by the main parsing mechanism and then assigned to nodes - // where the current structure allows it - comment: function comment() { - if (parserInput.commentStore.length) { - var comment = parserInput.commentStore.shift(); - return new tree.Comment(comment.text, comment.isLineComment, comment.index, fileInfo); - } - }, - // - // Entities are tokens which can be found inside an Expression - // - entities: { - mixinLookup: function mixinLookup() { - return parsers.mixin.call(true, true); - }, - // - // A string, which supports escaping " and ' - // - // "milky way" 'he\'s the one!' - // - quoted: function quoted(forceEscaped) { - var str; - var index = parserInput.i; - var isEscaped = false; - parserInput.save(); - - if (parserInput.$char('~')) { - isEscaped = true; - } else if (forceEscaped) { - parserInput.restore(); - return; - } - - str = parserInput.$quoted(); - - if (!str) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return new tree.Quoted(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); - }, - // - // A catch-all word, such as: - // - // black border-collapse - // - keyword: function keyword() { - var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); - - if (k) { - return tree.Color.fromKeyword(k) || new tree.Keyword(k); - } - }, - // - // A function call - // - // rgb(255, 0, 255) + catch (e) { + throw new LessError({ + index: e.index + currentIndex, + message: e.message + }, imports, fileInfo.filename); + } + } + // + // The Parser + // + return { + parserInput: parserInput, + imports: imports, + fileInfo: fileInfo, + parseNode: parseNode, // - // The arguments are parsed with the `entities.arguments` parser. + // Parse an input string into an abstract syntax tree, + // @param str A string containing 'less' markup + // @param callback call `callback` when done. + // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply // - call: function call() { - var name; - var args; - var func; - var index = parserInput.i; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (parserInput.peek(/^url\(/i)) { - return; - } - - parserInput.save(); - name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); - - if (!name) { - parserInput.forget(); - return; - } - - name = name[1]; - func = this.customFuncCall(name); - - if (func) { - args = func.parse(); - - if (args && func.stop) { - parserInput.forget(); - return args; + parse: function (str, callback, additionalData) { + var root; + var error = null; + var globalVars; + var modifyVars; + var ignored; + var preText = ''; + globalVars = (additionalData && additionalData.globalVars) ? Parser.serializeVars(additionalData.globalVars) + "\n" : ''; + modifyVars = (additionalData && additionalData.modifyVars) ? "\n" + Parser.serializeVars(additionalData.modifyVars) : ''; + if (context.pluginManager) { + var preProcessors = context.pluginManager.getPreProcessors(); + for (var i_2 = 0; i_2 < preProcessors.length; i_2++) { + str = preProcessors[i_2].process(str, { context: context, imports: imports, fileInfo: fileInfo }); + } } - } - - args = this.arguments(args); - - if (!parserInput.$char(')')) { - parserInput.restore('Could not parse call arguments or missing \')\''); - return; - } - - parserInput.forget(); - return new tree.Call(name, args, index, fileInfo); - }, - // - // Parsing rules for functions with non-standard args, e.g.: - // - // boolean(not(2 > 1)) - // - // This is a quick prototype, to be modified/improved when - // more custom-parsed funcs come (e.g. `selector(...)`) - // - customFuncCall: function customFuncCall(name) { - /* Ideally the table is to be moved out of here for faster perf., - but it's quite tricky since it relies on all these `parsers` - and `expect` available only here */ - return { - alpha: f(parsers.ieAlpha, true), - boolean: f(condition), - 'if': f(condition) - }[name.toLowerCase()]; - - function f(parse, stop) { - return { - parse: parse, - // parsing function - stop: stop // when true - stop after parse() and return its result, - // otherwise continue for plain args - - }; - } - - function condition() { - return [expect(parsers.condition, 'expected condition')]; - } - }, - arguments: function _arguments(prevArgs) { - var argsComma = prevArgs || []; - var argsSemiColon = []; - var isSemiColonSeparated; - var value; - parserInput.save(); - - while (true) { - if (prevArgs) { - prevArgs = false; - } else { - value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); - - if (!value) { - break; - } - - if (value.value && value.value.length == 1) { - value = value.value[0]; - } - - argsComma.push(value); + if (globalVars || (additionalData && additionalData.banner)) { + preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars; + ignored = imports.contentsIgnoredChars; + ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0; + ignored[fileInfo.filename] += preText.length; } - - if (parserInput.$char(',')) { - continue; + str = str.replace(/\r\n?/g, '\n'); + // Remove potential UTF Byte Order Mark + str = preText + str.replace(/^\uFEFF/, '') + modifyVars; + imports.contents[fileInfo.filename] = str; + // Start with the primary rule. + // The whole syntax tree is held under a Ruleset node, + // with the `root` property set to true, so no `{}` are + // output. The callback is called when the input is parsed. + try { + parserInput.start(str, context.chunkInput, function fail(msg, index) { + throw new LessError({ + index: index, + type: 'Parse', + message: msg, + filename: fileInfo.filename + }, imports); + }); + tree.Node.prototype.parse = this; + root = new tree.Ruleset(null, this.parsers.primary()); + tree.Node.prototype.rootNode = root; + root.root = true; + root.firstRoot = true; + root.functionRegistry = functionRegistry.inherit(); } - - if (parserInput.$char(';') || isSemiColonSeparated) { - isSemiColonSeparated = true; - value = argsComma.length < 1 ? argsComma[0] : new tree.Value(argsComma); - argsSemiColon.push(value); - argsComma = []; + catch (e) { + return callback(new LessError(e, imports, fileInfo.filename)); } - } - - parserInput.forget(); - return isSemiColonSeparated ? argsSemiColon : argsComma; - }, - literal: function literal() { - return this.dimension() || this.color() || this.quoted() || this.unicodeDescriptor(); - }, - // Assignments are argument entities for calls. - // They are present in ie filter properties as shown below. - // - // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) - // - assignment: function assignment() { - var key; - var value; - parserInput.save(); - key = parserInput.$re(/^\w+(?=\s?=)/i); - - if (!key) { - parserInput.restore(); - return; - } - - if (!parserInput.$char('=')) { - parserInput.restore(); - return; - } - - value = parsers.entity(); - - if (value) { - parserInput.forget(); - return new tree.Assignment(key, value); - } else { - parserInput.restore(); - } - }, - // - // Parse url() tokens - // - // We use a specific rule for urls, because they don't really behave like - // standard function calls. The difference is that the argument doesn't have - // to be enclosed within a string, so it can't be parsed as an Expression. - // - url: function url() { - var value; - var index = parserInput.i; - parserInput.autoCommentAbsorb = false; - - if (!parserInput.$str('url(')) { - parserInput.autoCommentAbsorb = true; - return; - } - - value = this.quoted() || this.variable() || this.property() || parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; - parserInput.autoCommentAbsorb = true; - expectChar(')'); - return new tree.URL(value.value != null || value instanceof tree.Variable || value instanceof tree.Property ? value : new tree.Anonymous(value, index), index, fileInfo); - }, - // - // A Variable entity, such as `@fink`, in - // - // width: @fink + 2px - // - // We use a different parser for variable definitions, - // see `parsers.variable`. - // - variable: function variable() { - var ch; - var name; - var index = parserInput.i; - parserInput.save(); - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { - ch = parserInput.currentChar(); - - if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { - // this may be a VariableCall lookup - var result = parsers.variableCall(name); - - if (result) { - parserInput.forget(); - return result; - } + // If `i` is smaller than the `input.length - 1`, + // it means the parser wasn't able to parse the whole + // string, so we've got a parsing error. + // + // We try to extract a \n delimited string, + // showing the line where the parse error occurred. + // We split it up into two parts (the part which parsed, + // and the part which didn't), so we can color them differently. + var endInfo = parserInput.end(); + if (!endInfo.isFinished) { + var message = endInfo.furthestPossibleErrorMessage; + if (!message) { + message = 'Unrecognised input'; + if (endInfo.furthestChar === '}') { + message += '. Possibly missing opening \'{\''; + } + else if (endInfo.furthestChar === ')') { + message += '. Possibly missing opening \'(\''; + } + else if (endInfo.furthestReachedEnd) { + message += '. Possibly missing something'; + } + } + error = new LessError({ + type: 'Parse', + message: message, + index: endInfo.furthest, + filename: fileInfo.filename + }, imports); } - - parserInput.forget(); - return new tree.Variable(name, index, fileInfo); - } - - parserInput.restore(); - }, - // A variable entity using the protective {} e.g. @{var} - variableCurly: function variableCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { - return new tree.Variable("@".concat(curly[1]), index, fileInfo); - } - }, - // - // A Property accessor, such as `$color`, in - // - // background-color: $color - // - property: function property() { - var name; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { - return new tree.Property(name, index, fileInfo); - } - }, - // A property entity useing the protective {} e.g. ${prop} - propertyCurly: function propertyCurly() { - var curly; - var index = parserInput.i; - - if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { - return new tree.Property("$".concat(curly[1]), index, fileInfo); - } - }, - // - // A Hexadecimal color - // - // #4F3C2F - // - // `rgb` and `hsl` colors are parsed through the `entities.call` parser. - // - color: function color() { - var rgb; - parserInput.save(); - - if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { - if (!rgb[2]) { - parserInput.forget(); - return new tree.Color(rgb[1], undefined, rgb[0]); + var finish = function (e) { + e = error || e || imports.error; + if (e) { + if (!(e instanceof LessError)) { + e = new LessError(e, imports, fileInfo.filename); + } + return callback(e); + } + else { + return callback(null, root); + } + }; + if (context.processImports !== false) { + new visitors.ImportVisitor(imports, finish) + .run(root); + } + else { + return finish(); } - } - - parserInput.restore(); - }, - colorKeyword: function colorKeyword() { - parserInput.save(); - var autoCommentAbsorb = parserInput.autoCommentAbsorb; - parserInput.autoCommentAbsorb = false; - var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); - parserInput.autoCommentAbsorb = autoCommentAbsorb; - - if (!k) { - parserInput.forget(); - return; - } - - parserInput.restore(); - var color = tree.Color.fromKeyword(k); - - if (color) { - parserInput.$str(k); - return color; - } - }, - // - // A Dimension, that is, a number and a unit - // - // 0.5em 95% - // - dimension: function dimension() { - if (parserInput.peekNotNumeric()) { - return; - } - - var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); - - if (value) { - return new tree.Dimension(value[1], value[2]); - } - }, - // - // A unicode descriptor, as is used in unicode-range - // - // U+0?? or U+00A1-00A9 - // - unicodeDescriptor: function unicodeDescriptor() { - var ud; - ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); - - if (ud) { - return new tree.UnicodeDescriptor(ud[0]); - } }, // - // JavaScript code to be evaluated + // Here in, the parsing rules/functions // - // `window.location.href` + // The basic structure of the syntax tree generated is as follows: // - javascript: function javascript() { - var js; - var index = parserInput.i; - parserInput.save(); - var escape = parserInput.$char('~'); - var jsQuote = parserInput.$char('`'); - - if (!jsQuote) { - parserInput.restore(); - return; - } - - js = parserInput.$re(/^[^`]*`/); - - if (js) { - parserInput.forget(); - return new tree.JavaScript(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); - } - - parserInput.restore('invalid javascript definition'); - } - }, - // - // The variable part of a variable definition. Used in the `rule` parser - // - // @fink: - // - variable: function variable() { - var name; - - if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { - return name[1]; - } - }, - // - // Call a variable value to retrieve a detached ruleset - // or a value from a detached ruleset's rules. - // - // @fink(); - // @fink; - // color: @fink[@color]; - // - variableCall: function variableCall(parsedName) { - var lookups; - var important; - var i = parserInput.i; - var inValue = !!parsedName; - var name = parsedName; - parserInput.save(); - - if (name || parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/))) { - lookups = this.mixin.ruleLookups(); - - if (!lookups && (inValue && parserInput.$str('()') !== '()' || name[2] !== '()')) { - parserInput.restore('Missing \'[...]\' lookup in variable call'); - return; - } - - if (!inValue) { - name = name[1]; - } - - if (lookups && parsers.important()) { - important = true; - } - - var call = new tree.VariableCall(name, i, fileInfo); - - if (!inValue && parsers.end()) { - parserInput.forget(); - return call; - } else { - parserInput.forget(); - return new tree.NamespaceValue(call, lookups, important, i, fileInfo); - } - } - - parserInput.restore(); - }, - // - // extend syntax - used to extend selectors - // - extend: function extend(isRule) { - var elements; - var e; - var index = parserInput.i; - var option; - var extendList; - var extend; - - if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { - return; - } - - do { - option = null; - elements = null; - - while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { - e = this.element(); - - if (!e) { - break; - } - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - } - - option = option && option[1]; - - if (!elements) { - error('Missing target selector for :extend().'); - } - - extend = new tree.Extend(new tree.Selector(elements), option, index, fileInfo); - - if (extendList) { - extendList.push(extend); - } else { - extendList = [extend]; - } - } while (parserInput.$char(',')); - - expect(/^\)/); - - if (isRule) { - expect(/^;/); - } - - return extendList; - }, - // - // extendRule - used in a rule to extend all the parent selectors - // - extendRule: function extendRule() { - return this.extend(true); - }, - // - // Mixins - // - mixin: { + // Ruleset -> Declaration -> Value -> Expression -> Entity // - // A Mixin call, with an optional argument list + // Here's some Less code: // - // #mixins > .square(#fff); - // #mixins.square(#fff); - // .rounded(4px, black); - // .button; + // .class { + // color: #fff; + // border: 1px solid #000; + // width: @w + 4px; + // > .child {...} + // } // - // We can lookup / return a value using the lookup syntax: + // And here's what the parse tree might look like: // - // color: #mixin.square(#fff)[@color]; + // Ruleset (Selector '.class', [ + // Declaration ("color", Value ([Expression [Color #fff]])) + // Declaration ("border", Value ([Expression [Dimension 1px][Keyword "solid"][Color #000]])) + // Declaration ("width", Value ([Expression [Operation " + " [Variable "@w"][Dimension 4px]]])) + // Ruleset (Selector [Element '>', '.child'], [...]) + // ]) // - // The `while` loop is there because mixins can be - // namespaced, but we only support the child and descendant - // selector for now. + // In general, most rules will try to parse a token with the `$re()` function, and if the return + // value is truly, will return a new node, of the relevant type. Sometimes, we need to check + // first, before parsing, that's when we use `peek()`. // - call: function call(inValue, getLookup) { - var s = parserInput.currentChar(); - var important = false; - var lookups; - var index = parserInput.i; - var elements; - var args; - var hasParens; - - if (s !== '.' && s !== '#') { - return; - } - - parserInput.save(); // stop us absorbing part of an invalid selector - - elements = this.elements(); - - if (elements) { - if (parserInput.$char('(')) { - args = this.args(true).args; - expectChar(')'); - hasParens = true; - } - - if (getLookup !== false) { - lookups = this.ruleLookups(); - } - - if (getLookup === true && !lookups) { - parserInput.restore(); - return; - } - - if (inValue && !lookups && !hasParens) { - // This isn't a valid in-value mixin call - parserInput.restore(); - return; - } - - if (!inValue && parsers.important()) { - important = true; - } - - if (inValue || parsers.end()) { - parserInput.forget(); - var mixin = new tree.mixin.Call(elements, args, index, fileInfo, !lookups && important); - - if (lookups) { - return new tree.NamespaceValue(mixin, lookups, important); - } else { - return mixin; - } - } - } - - parserInput.restore(); - }, - - /** - * Matching elements for mixins - * (Start with . or # and can have > ) - */ - elements: function elements() { - var elements; - var e; - var c; - var elem; - var elemIndex; - var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; - - while (true) { - elemIndex = parserInput.i; - e = parserInput.$re(re); - - if (!e) { - break; - } - - elem = new tree.Element(c, e, false, elemIndex, fileInfo); - - if (elements) { - elements.push(elem); - } else { - elements = [elem]; - } - - c = parserInput.$char('>'); - } - - return elements; - }, - args: function args(isCall) { - var entities = parsers.entities; - var returner = { - args: null, - variadic: false - }; - var expressions = []; - var argsSemiColon = []; - var argsComma = []; - var isSemiColonSeparated; - var expressionContainsNamed; - var name; - var nameLoop; - var value; - var arg; - var expand; - var hasSep = true; - parserInput.save(); - - while (true) { - if (isCall) { - arg = parsers.detachedRuleset() || parsers.expression(); - } else { - parserInput.commentStore.length = 0; - - if (parserInput.$str('...')) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; + parsers: parsers = { + // + // The `primary` rule is the *entry* and *exit* point of the parser. + // The rules here can appear at any level of the parse tree. + // + // The recursive nature of the grammar is an interplay between the `block` + // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule, + // as represented by this simplified grammar: + // + // primary → (ruleset | declaration)+ + // ruleset → selector+ block + // block → '{' primary '}' + // + // Only at one point is the primary rule not called from the + // block rule: at the root level. + // + primary: function () { + var mixin = this.mixin; + var root = []; + var node; + while (true) { + while (true) { + node = this.comment(); + if (!node) { + break; + } + root.push(node); + } + // always process comments before deciding if finished + if (parserInput.finished) { + break; + } + if (parserInput.peek('}')) { + break; + } + node = this.extendRule(); + if (node) { + root = root.concat(node); + continue; + } + node = mixin.definition() || this.declaration() || mixin.call(false, false) || + this.ruleset() || this.variableCall() || this.entities.call() || this.atrule(); + if (node) { + root.push(node); + } + else { + var foundSemiColon = false; + while (parserInput.$char(';')) { + foundSemiColon = true; + } + if (!foundSemiColon) { + break; + } + } } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - variadic: true - }); - break; - } - - arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); - } - - if (!arg || !hasSep) { - break; - } - - nameLoop = null; - - if (arg.throwAwayComments) { - arg.throwAwayComments(); - } - - value = arg; - var val = null; - - if (isCall) { - // Variable - if (arg.value && arg.value.length == 1) { - val = arg.value[0]; - } - } else { - val = arg; - } - - if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { - if (parserInput.$char(':')) { - if (expressions.length > 0) { - if (isSemiColonSeparated) { - error('Cannot mix ; and , as delimiter types'); - } - - expressionContainsNamed = true; + return root; + }, + // comments are collected by the main parsing mechanism and then assigned to nodes + // where the current structure allows it + comment: function () { + if (parserInput.commentStore.length) { + var comment = parserInput.commentStore.shift(); + return new (tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo); } - - value = parsers.detachedRuleset() || parsers.expression(); - - if (!value) { - if (isCall) { - error('could not understand value for named argument'); - } else { + }, + // + // Entities are tokens which can be found inside an Expression + // + entities: { + mixinLookup: function () { + return parsers.mixin.call(true, true); + }, + // + // A string, which supports escaping " and ' + // + // "milky way" 'he\'s the one!' + // + quoted: function (forceEscaped) { + var str; + var index = parserInput.i; + var isEscaped = false; + parserInput.save(); + if (parserInput.$char('~')) { + isEscaped = true; + } + else if (forceEscaped) { + parserInput.restore(); + return; + } + str = parserInput.$quoted(); + if (!str) { + parserInput.restore(); + return; + } + parserInput.forget(); + return new (tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo); + }, + // + // A catch-all word, such as: + // + // black border-collapse + // + keyword: function () { + var k = parserInput.$char('%') || parserInput.$re(/^\[?(?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\]?/); + if (k) { + return tree.Color.fromKeyword(k) || new (tree.Keyword)(k); + } + }, + // + // A function call + // + // rgb(255, 0, 255) + // + // The arguments are parsed with the `entities.arguments` parser. + // + call: function () { + var name; + var args; + var func; + var index = parserInput.i; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (parserInput.peek(/^url\(/i)) { + return; + } + parserInput.save(); + name = parserInput.$re(/^([\w-]+|%|progid:[\w\.]+)\(/); + if (!name) { + parserInput.forget(); + return; + } + name = name[1]; + func = this.customFuncCall(name); + if (func) { + args = func.parse(); + if (args && func.stop) { + parserInput.forget(); + return args; + } + } + args = this.arguments(args); + if (!parserInput.$char(')')) { + parserInput.restore('Could not parse call arguments or missing \')\''); + return; + } + parserInput.forget(); + return new (tree.Call)(name, args, index, fileInfo); + }, + // + // Parsing rules for functions with non-standard args, e.g.: + // + // boolean(not(2 > 1)) + // + // This is a quick prototype, to be modified/improved when + // more custom-parsed funcs come (e.g. `selector(...)`) + // + customFuncCall: function (name) { + /* Ideally the table is to be moved out of here for faster perf., + but it's quite tricky since it relies on all these `parsers` + and `expect` available only here */ + return { + alpha: f(parsers.ieAlpha, true), + boolean: f(condition), + 'if': f(condition) + }[name.toLowerCase()]; + function f(parse, stop) { + return { + parse: parse, + stop: stop // when true - stop after parse() and return its result, + // otherwise continue for plain args + }; + } + function condition() { + return [expect(parsers.condition, 'expected condition')]; + } + }, + arguments: function (prevArgs) { + var argsComma = prevArgs || []; + var argsSemiColon = []; + var isSemiColonSeparated; + var value; + parserInput.save(); + while (true) { + if (prevArgs) { + prevArgs = false; + } + else { + value = parsers.detachedRuleset() || this.assignment() || parsers.expression(); + if (!value) { + break; + } + if (value.value && value.value.length == 1) { + value = value.value[0]; + } + argsComma.push(value); + } + if (parserInput.$char(',')) { + continue; + } + if (parserInput.$char(';') || isSemiColonSeparated) { + isSemiColonSeparated = true; + value = (argsComma.length < 1) ? argsComma[0] + : new tree.Value(argsComma); + argsSemiColon.push(value); + argsComma = []; + } + } + parserInput.forget(); + return isSemiColonSeparated ? argsSemiColon : argsComma; + }, + literal: function () { + return this.dimension() || + this.color() || + this.quoted() || + this.unicodeDescriptor(); + }, + // Assignments are argument entities for calls. + // They are present in ie filter properties as shown below. + // + // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* ) + // + assignment: function () { + var key; + var value; + parserInput.save(); + key = parserInput.$re(/^\w+(?=\s?=)/i); + if (!key) { + parserInput.restore(); + return; + } + if (!parserInput.$char('=')) { + parserInput.restore(); + return; + } + value = parsers.entity(); + if (value) { + parserInput.forget(); + return new (tree.Assignment)(key, value); + } + else { + parserInput.restore(); + } + }, + // + // Parse url() tokens + // + // We use a specific rule for urls, because they don't really behave like + // standard function calls. The difference is that the argument doesn't have + // to be enclosed within a string, so it can't be parsed as an Expression. + // + url: function () { + var value; + var index = parserInput.i; + parserInput.autoCommentAbsorb = false; + if (!parserInput.$str('url(')) { + parserInput.autoCommentAbsorb = true; + return; + } + value = this.quoted() || this.variable() || this.property() || + parserInput.$re(/^(?:(?:\\[\(\)'"])|[^\(\)'"])+/) || ''; + parserInput.autoCommentAbsorb = true; + expectChar(')'); + return new (tree.URL)((value.value != null || + value instanceof tree.Variable || + value instanceof tree.Property) ? + value : new (tree.Anonymous)(value, index), index, fileInfo); + }, + // + // A Variable entity, such as `@fink`, in + // + // width: @fink + 2px + // + // We use a different parser for variable definitions, + // see `parsers.variable`. + // + variable: function () { + var ch; + var name; + var index = parserInput.i; + parserInput.save(); + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\w-]+/))) { + ch = parserInput.currentChar(); + if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\s/)) { + // this may be a VariableCall lookup + var result = parsers.variableCall(name); + if (result) { + parserInput.forget(); + return result; + } + } + parserInput.forget(); + return new (tree.Variable)(name, index, fileInfo); + } + parserInput.restore(); + }, + // A variable entity using the protective {} e.g. @{var} + variableCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\{([\w-]+)\}/))) { + return new (tree.Variable)("@" + curly[1], index, fileInfo); + } + }, + // + // A Property accessor, such as `$color`, in + // + // background-color: $color + // + property: function () { + var name; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\$[\w-]+/))) { + return new (tree.Property)(name, index, fileInfo); + } + }, + // A property entity useing the protective {} e.g. ${prop} + propertyCurly: function () { + var curly; + var index = parserInput.i; + if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\$\{([\w-]+)\}/))) { + return new (tree.Property)("$" + curly[1], index, fileInfo); + } + }, + // + // A Hexadecimal color + // + // #4F3C2F + // + // `rgb` and `hsl` colors are parsed through the `entities.call` parser. + // + color: function () { + var rgb; + parserInput.save(); + if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\w.#\[])?/))) { + if (!rgb[2]) { + parserInput.forget(); + return new (tree.Color)(rgb[1], undefined, rgb[0]); + } + } + parserInput.restore(); + }, + colorKeyword: function () { + parserInput.save(); + var autoCommentAbsorb = parserInput.autoCommentAbsorb; + parserInput.autoCommentAbsorb = false; + var k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/); + parserInput.autoCommentAbsorb = autoCommentAbsorb; + if (!k) { + parserInput.forget(); + return; + } + parserInput.restore(); + var color = tree.Color.fromKeyword(k); + if (color) { + parserInput.$str(k); + return color; + } + }, + // + // A Dimension, that is, a number and a unit + // + // 0.5em 95% + // + dimension: function () { + if (parserInput.peekNotNumeric()) { + return; + } + var value = parserInput.$re(/^([+-]?\d*\.?\d+)(%|[a-z_]+)?/i); + if (value) { + return new (tree.Dimension)(value[1], value[2]); + } + }, + // + // A unicode descriptor, as is used in unicode-range + // + // U+0?? or U+00A1-00A9 + // + unicodeDescriptor: function () { + var ud; + ud = parserInput.$re(/^U\+[0-9a-fA-F?]+(\-[0-9a-fA-F?]+)?/); + if (ud) { + return new (tree.UnicodeDescriptor)(ud[0]); + } + }, + // + // JavaScript code to be evaluated + // + // `window.location.href` + // + javascript: function () { + var js; + var index = parserInput.i; + parserInput.save(); + var escape = parserInput.$char('~'); + var jsQuote = parserInput.$char('`'); + if (!jsQuote) { + parserInput.restore(); + return; + } + js = parserInput.$re(/^[^`]*`/); + if (js) { + parserInput.forget(); + return new (tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo); + } + parserInput.restore('invalid javascript definition'); + } + }, + // + // The variable part of a variable definition. Used in the `rule` parser + // + // @fink: + // + variable: function () { + var name; + if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\w-]+)\s*:/))) { + return name[1]; + } + }, + // + // Call a variable value to retrieve a detached ruleset + // or a value from a detached ruleset's rules. + // + // @fink(); + // @fink; + // color: @fink[@color]; + // + variableCall: function (parsedName) { + var lookups; + var i = parserInput.i; + var inValue = !!parsedName; + var name = parsedName; + parserInput.save(); + if (name || (parserInput.currentChar() === '@' + && (name = parserInput.$re(/^(@[\w-]+)(\(\s*\))?/)))) { + lookups = this.mixin.ruleLookups(); + if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) { + parserInput.restore('Missing \'[...]\' lookup in variable call'); + return; + } + if (!inValue) { + name = name[1]; + } + var call = new tree.VariableCall(name, i, fileInfo); + if (!inValue && parsers.end()) { + parserInput.forget(); + return call; + } + else { + parserInput.forget(); + return new tree.NamespaceValue(call, lookups, i, fileInfo); + } + } + parserInput.restore(); + }, + // + // extend syntax - used to extend selectors + // + extend: function (isRule) { + var elements; + var e; + var index = parserInput.i; + var option; + var extendList; + var extend; + if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) { + return; + } + do { + option = null; + elements = null; + while (!(option = parserInput.$re(/^(all)(?=\s*(\)|,))/))) { + e = this.element(); + if (!e) { + break; + } + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + } + option = option && option[1]; + if (!elements) { + error('Missing target selector for :extend().'); + } + extend = new (tree.Extend)(new (tree.Selector)(elements), option, index, fileInfo); + if (extendList) { + extendList.push(extend); + } + else { + extendList = [extend]; + } + } while (parserInput.$char(',')); + expect(/^\)/); + if (isRule) { + expect(/^;/); + } + return extendList; + }, + // + // extendRule - used in a rule to extend all the parent selectors + // + extendRule: function () { + return this.extend(true); + }, + // + // Mixins + // + mixin: { + // + // A Mixin call, with an optional argument list + // + // #mixins > .square(#fff); + // #mixins.square(#fff); + // .rounded(4px, black); + // .button; + // + // We can lookup / return a value using the lookup syntax: + // + // color: #mixin.square(#fff)[@color]; + // + // The `while` loop is there because mixins can be + // namespaced, but we only support the child and descendant + // selector for now. + // + call: function (inValue, getLookup) { + var s = parserInput.currentChar(); + var important = false; + var lookups; + var index = parserInput.i; + var elements; + var args; + var hasParens; + if (s !== '.' && s !== '#') { + return; + } + parserInput.save(); // stop us absorbing part of an invalid selector + elements = this.elements(); + if (elements) { + if (parserInput.$char('(')) { + args = this.args(true).args; + expectChar(')'); + hasParens = true; + } + if (getLookup !== false) { + lookups = this.ruleLookups(); + } + if (getLookup === true && !lookups) { + parserInput.restore(); + return; + } + if (inValue && !lookups && !hasParens) { + // This isn't a valid in-value mixin call + parserInput.restore(); + return; + } + if (!inValue && parsers.important()) { + important = true; + } + if (inValue || parsers.end()) { + parserInput.forget(); + var mixin = new (tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important); + if (lookups) { + return new tree.NamespaceValue(mixin, lookups); + } + else { + return mixin; + } + } + } parserInput.restore(); - returner.args = []; + }, + /** + * Matching elements for mixins + * (Start with . or # and can have > ) + */ + elements: function () { + var elements; + var e; + var c; + var elem; + var elemIndex; + var re = /^[#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/; + while (true) { + elemIndex = parserInput.i; + e = parserInput.$re(re); + if (!e) { + break; + } + elem = new (tree.Element)(c, e, false, elemIndex, fileInfo); + if (elements) { + elements.push(elem); + } + else { + elements = [elem]; + } + c = parserInput.$char('>'); + } + return elements; + }, + args: function (isCall) { + var entities = parsers.entities; + var returner = { args: null, variadic: false }; + var expressions = []; + var argsSemiColon = []; + var argsComma = []; + var isSemiColonSeparated; + var expressionContainsNamed; + var name; + var nameLoop; + var value; + var arg; + var expand; + var hasSep = true; + parserInput.save(); + while (true) { + if (isCall) { + arg = parsers.detachedRuleset() || parsers.expression(); + } + else { + parserInput.commentStore.length = 0; + if (parserInput.$str('...')) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ variadic: true }); + break; + } + arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true); + } + if (!arg || !hasSep) { + break; + } + nameLoop = null; + if (arg.throwAwayComments) { + arg.throwAwayComments(); + } + value = arg; + var val = null; + if (isCall) { + // Variable + if (arg.value && arg.value.length == 1) { + val = arg.value[0]; + } + } + else { + val = arg; + } + if (val && (val instanceof tree.Variable || val instanceof tree.Property)) { + if (parserInput.$char(':')) { + if (expressions.length > 0) { + if (isSemiColonSeparated) { + error('Cannot mix ; and , as delimiter types'); + } + expressionContainsNamed = true; + } + value = parsers.detachedRuleset() || parsers.expression(); + if (!value) { + if (isCall) { + error('could not understand value for named argument'); + } + else { + parserInput.restore(); + returner.args = []; + return returner; + } + } + nameLoop = (name = val.name); + } + else if (parserInput.$str('...')) { + if (!isCall) { + returner.variadic = true; + if (parserInput.$char(';') && !isSemiColonSeparated) { + isSemiColonSeparated = true; + } + (isSemiColonSeparated ? argsSemiColon : argsComma) + .push({ name: arg.name, variadic: true }); + break; + } + else { + expand = true; + } + } + else if (!isCall) { + name = nameLoop = val.name; + value = null; + } + } + if (value) { + expressions.push(value); + } + argsComma.push({ name: nameLoop, value: value, expand: expand }); + if (parserInput.$char(',')) { + hasSep = true; + continue; + } + hasSep = parserInput.$char(';') === ';'; + if (hasSep || isSemiColonSeparated) { + if (expressionContainsNamed) { + error('Cannot mix ; and , as delimiter types'); + } + isSemiColonSeparated = true; + if (expressions.length > 1) { + value = new (tree.Value)(expressions); + } + argsSemiColon.push({ name: name, value: value, expand: expand }); + name = null; + expressions = []; + expressionContainsNamed = false; + } + } + parserInput.forget(); + returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; return returner; - } + }, + // + // A Mixin definition, with a list of parameters + // + // .rounded (@radius: 2px, @color) { + // ... + // } + // + // Until we have a finer grained state-machine, we have to + // do a look-ahead, to make sure we don't have a mixin call. + // See the `rule` function for more information. + // + // We start by matching `.rounded (`, and then proceed on to + // the argument list, which has optional default values. + // We store the parameters in `params`, with a `value` key, + // if there is a value, such as in the case of `@radius`. + // + // Once we've got our params list, and a closing `)`, we parse + // the `{...}` block. + // + definition: function () { + var name; + var params = []; + var match; + var ruleset; + var cond; + var variadic = false; + if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') || + parserInput.peek(/^[^{]*\}/)) { + return; + } + parserInput.save(); + match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); + if (match) { + name = match[1]; + var argInfo = this.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + // .mixincall("@{a}"); + // looks a bit like a mixin definition.. + // also + // .mixincall(@a: {rule: set;}); + // so we have to be nice and restore + if (!parserInput.$char(')')) { + parserInput.restore('Missing closing \')\''); + return; + } + parserInput.commentStore.length = 0; + if (parserInput.$str('when')) { // Guard + cond = expect(parsers.conditions, 'expected condition'); + } + ruleset = parsers.block(); + if (ruleset) { + parserInput.forget(); + return new (tree.mixin.Definition)(name, params, ruleset, cond, variadic); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + ruleLookups: function () { + var rule; + var lookups = []; + if (parserInput.currentChar() !== '[') { + return; + } + while (true) { + parserInput.save(); + rule = this.lookupValue(); + if (!rule && rule !== '') { + parserInput.restore(); + break; + } + lookups.push(rule); + parserInput.forget(); + } + if (lookups.length > 0) { + return lookups; + } + }, + lookupValue: function () { + parserInput.save(); + if (!parserInput.$char('[')) { + parserInput.restore(); + return; + } + var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); + if (!parserInput.$char(']')) { + parserInput.restore(); + return; + } + if (name || name === '') { + parserInput.forget(); + return name; + } + parserInput.restore(); } - - nameLoop = name = val.name; - } else if (parserInput.$str('...')) { - if (!isCall) { - returner.variadic = true; - - if (parserInput.$char(';') && !isSemiColonSeparated) { - isSemiColonSeparated = true; - } - - (isSemiColonSeparated ? argsSemiColon : argsComma).push({ - name: arg.name, - variadic: true - }); - break; - } else { - expand = true; - } - } else if (!isCall) { - name = nameLoop = val.name; - value = null; - } - } - - if (value) { - expressions.push(value); - } - - argsComma.push({ - name: nameLoop, - value: value, - expand: expand - }); - - if (parserInput.$char(',')) { - hasSep = true; - continue; - } - - hasSep = parserInput.$char(';') === ';'; - - if (hasSep || isSemiColonSeparated) { - if (expressionContainsNamed) { - error('Cannot mix ; and , as delimiter types'); - } - - isSemiColonSeparated = true; - - if (expressions.length > 1) { - value = new tree.Value(expressions); - } - - argsSemiColon.push({ - name: name, - value: value, - expand: expand - }); - name = null; - expressions = []; - expressionContainsNamed = false; - } - } - - parserInput.forget(); - returner.args = isSemiColonSeparated ? argsSemiColon : argsComma; - return returner; - }, - // - // A Mixin definition, with a list of parameters - // - // .rounded (@radius: 2px, @color) { - // ... - // } - // - // Until we have a finer grained state-machine, we have to - // do a look-ahead, to make sure we don't have a mixin call. - // See the `rule` function for more information. - // - // We start by matching `.rounded (`, and then proceed on to - // the argument list, which has optional default values. - // We store the parameters in `params`, with a `value` key, - // if there is a value, such as in the case of `@radius`. - // - // Once we've got our params list, and a closing `)`, we parse - // the `{...}` block. - // - definition: function definition() { - var name; - var params = []; - var match; - var ruleset; - var cond; - var variadic = false; - - if (parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#' || parserInput.peek(/^[^{]*\}/)) { - return; - } - - parserInput.save(); - match = parserInput.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/); - - if (match) { - name = match[1]; - var argInfo = this.args(false); - params = argInfo.args; - variadic = argInfo.variadic; // .mixincall("@{a}"); - // looks a bit like a mixin definition.. - // also - // .mixincall(@a: {rule: set;}); - // so we have to be nice and restore - - if (!parserInput.$char(')')) { - parserInput.restore('Missing closing \')\''); - return; - } - - parserInput.commentStore.length = 0; - - if (parserInput.$str('when')) { - // Guard - cond = expect(parsers.conditions, 'expected condition'); - } - - ruleset = parsers.block(); - - if (ruleset) { - parserInput.forget(); - return new tree.mixin.Definition(name, params, ruleset, cond, variadic); - } else { - parserInput.restore(); - } - } else { - parserInput.forget(); - } - }, - ruleLookups: function ruleLookups() { - var rule; - var lookups = []; - - if (parserInput.currentChar() !== '[') { - return; - } - - while (true) { - parserInput.save(); - rule = this.lookupValue(); - - if (!rule && rule !== '') { - parserInput.restore(); - break; - } - - lookups.push(rule); - parserInput.forget(); - } - - if (lookups.length > 0) { - return lookups; - } - }, - lookupValue: function lookupValue() { - parserInput.save(); - - if (!parserInput.$char('[')) { - parserInput.restore(); - return; - } - - var name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/); - - if (!parserInput.$char(']')) { - parserInput.restore(); - return; - } - - if (name || name === '') { - parserInput.forget(); - return name; - } - - parserInput.restore(); - } - }, - // - // Entities are the smallest recognized token, - // and can be found inside a rule's value. - // - entity: function entity() { - var entities = this.entities; - return this.comment() || entities.literal() || entities.variable() || entities.url() || entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || entities.javascript(); - }, - // - // A Declaration terminator. Note that we use `peek()` to check for '}', - // because the `block` rule will be expecting it, but we still need to make sure - // it's there, if ';' was omitted. - // - end: function end() { - return parserInput.$char(';') || parserInput.peek('}'); - }, - // - // IE's alpha function - // - // alpha(opacity=88) - // - ieAlpha: function ieAlpha() { - var value; // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 - - if (!parserInput.$re(/^opacity=/i)) { - return; - } - - value = parserInput.$re(/^\d+/); - - if (!value) { - value = expect(parsers.entities.variable, 'Could not parse alpha'); - value = "@{".concat(value.name.slice(1), "}"); - } - - expectChar(')'); - return new tree.Quoted('', "alpha(opacity=".concat(value, ")")); - }, - // - // A Selector Element - // - // div - // + h1 - // #socks - // input[type="text"] - // - // Elements are the building blocks for Selectors, - // they are made out of a `Combinator` (see combinator rule), - // and an element name, such as a tag a class, or `*`. - // - element: function element() { - var e; - var c; - var v; - var index = parserInput.i; - c = this.combinator(); - e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || parserInput.$char('*') || parserInput.$char('&') || this.attribute() || parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || this.entities.variableCurly(); - - if (!e) { - parserInput.save(); - - if (parserInput.$char('(')) { - if ((v = this.selector(false)) && parserInput.$char(')')) { - e = new tree.Paren(v); - parserInput.forget(); - } else { - parserInput.restore('Missing closing \')\''); - } - } else { - parserInput.forget(); - } - } - - if (e) { - return new tree.Element(c, e, e instanceof tree.Variable, index, fileInfo); - } - }, - // - // Combinators combine elements together, in a Selector. - // - // Because our parser isn't white-space sensitive, special care - // has to be taken, when parsing the descendant combinator, ` `, - // as it's an empty space. We have to check the previous character - // in the input, to see if it's a ` ` character. More info on how - // we deal with this in *combinator.js*. - // - combinator: function combinator() { - var c = parserInput.currentChar(); - - if (c === '/') { - parserInput.save(); - var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); - - if (slashedCombinator) { - parserInput.forget(); - return new tree.Combinator(slashedCombinator); - } - - parserInput.restore(); - } - - if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { - parserInput.i++; - - if (c === '^' && parserInput.currentChar() === '^') { - c = '^^'; - parserInput.i++; - } - - while (parserInput.isWhitespace()) { - parserInput.i++; - } - - return new tree.Combinator(c); - } else if (parserInput.isWhitespace(-1)) { - return new tree.Combinator(' '); - } else { - return new tree.Combinator(null); - } - }, - // - // A CSS Selector - // with less extensions e.g. the ability to extend and guard - // - // .class > div + h1 - // li a:hover - // - // Selectors are made out of one or more Elements, see above. - // - selector: function selector(isLess) { - var index = parserInput.i; - var elements; - var extendList; - var c; - var e; - var allExtends; - var when; - var condition; - isLess = isLess !== false; - - while (isLess && (extendList = this.extend()) || isLess && (when = parserInput.$str('when')) || (e = this.element())) { - if (when) { - condition = expect(this.conditions, 'expected condition'); - } else if (condition) { - error('CSS guard can only be used at the end of selector'); - } else if (extendList) { - if (allExtends) { - allExtends = allExtends.concat(extendList); - } else { - allExtends = extendList; - } - } else { - if (allExtends) { - error('Extend can only be used at the end of selector'); - } - - c = parserInput.currentChar(); - - if (elements) { - elements.push(e); - } else { - elements = [e]; - } - - e = null; - } - - if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { - break; - } - } - - if (elements) { - return new tree.Selector(elements, allExtends, condition, index, fileInfo); - } - - if (allExtends) { - error('Extend must be used to extend a selector, it cannot be used on its own'); - } - }, - selectors: function selectors() { - var s; - var selectors; - - while (true) { - s = this.selector(); - - if (!s) { - break; - } - - if (selectors) { - selectors.push(s); - } else { - selectors = [s]; - } - - parserInput.commentStore.length = 0; - - if (s.condition && selectors.length > 1) { - error("Guards are only currently allowed on a single selector."); - } - - if (!parserInput.$char(',')) { - break; - } - - if (s.condition) { - error("Guards are only currently allowed on a single selector."); - } - - parserInput.commentStore.length = 0; - } - - return selectors; - }, - attribute: function attribute() { - if (!parserInput.$char('[')) { - return; - } - - var entities = this.entities; - var key; - var val; - var op; - - if (!(key = entities.variableCurly())) { - key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); - } - - op = parserInput.$re(/^[|~*$^]?=/); - - if (op) { - val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); - } - - expectChar(']'); - return new tree.Attribute(key, op, val); - }, - // - // The `block` rule is used by `ruleset` and `mixin.definition`. - // It's a wrapper around the `primary` rule, with added `{}`. - // - block: function block() { - var content; - - if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { - return content; - } - }, - blockRuleset: function blockRuleset() { - var block = this.block(); - - if (block) { - block = new tree.Ruleset(null, block); - } - - return block; - }, - detachedRuleset: function detachedRuleset() { - var argInfo; - var params; - var variadic; - parserInput.save(); - - if (parserInput.$re(/^[.#]\(/)) { - /** - * DR args currently only implemented for each() function, and not - * yet settable as `@dr: #(@arg) {}` - * This should be done when DRs are merged with mixins. - * See: https://github.com/less/less-meta/issues/16 - */ - argInfo = this.mixin.args(false); - params = argInfo.args; - variadic = argInfo.variadic; - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - } - - var blockRuleset = this.blockRuleset(); - - if (blockRuleset) { - parserInput.forget(); - - if (params) { - return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); - } - - return new tree.DetachedRuleset(blockRuleset); - } - - parserInput.restore(); - }, - // - // div, .class, body > p {...} - // - ruleset: function ruleset() { - var selectors; - var rules; - var debugInfo; - parserInput.save(); - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(parserInput.i); - } - - selectors = this.selectors(); - - if (selectors && (rules = this.block())) { - parserInput.forget(); - var ruleset = new tree.Ruleset(selectors, rules, context.strictImports); - - if (context.dumpLineNumbers) { - ruleset.debugInfo = debugInfo; - } - - return ruleset; - } else { - parserInput.restore(); - } - }, - declaration: function declaration() { - var name; - var value; - var index = parserInput.i; - var hasDR; - var c = parserInput.currentChar(); - var important; - var merge; - var isVariable; - - if (c === '.' || c === '#' || c === '&' || c === ':') { - return; - } - - parserInput.save(); - name = this.variable() || this.ruleProperty(); - - if (name) { - isVariable = typeof name === 'string'; - - if (isVariable) { - value = this.detachedRuleset(); - - if (value) { - hasDR = true; - } - } - - parserInput.commentStore.length = 0; - - if (!value) { - // a name returned by this.ruleProperty() is always an array of the form: - // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] - // where each item is a tree.Keyword or tree.Variable - merge = !isVariable && name.length > 1 && name.pop().value; // Custom property values get permissive parsing - - if (name[0].value && name[0].value.slice(0, 2) === '--') { - value = this.permissiveValue(); - } // Try to store values as anonymous - // If we need the value later we'll re-parse it in ruleset.parseValue - else { - value = this.anonymousValue(); - } - - if (value) { - parserInput.forget(); // anonymous values absorb the end ';' which is required for them to work - - return new tree.Declaration(name, value, false, merge, index, fileInfo); - } - - if (!value) { - value = this.value(); - } - - if (value) { - important = this.important(); - } else if (isVariable) { - // As a last resort, try permissiveValue - value = this.permissiveValue(); - } - } - - if (value && (this.end() || hasDR)) { - parserInput.forget(); - return new tree.Declaration(name, value, important, merge, index, fileInfo); - } else { - parserInput.restore(); - } - } else { - parserInput.restore(); - } - }, - anonymousValue: function anonymousValue() { - var index = parserInput.i; - var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); - - if (match) { - return new tree.Anonymous(match[1], index); - } - }, - - /** - * Used for custom properties, at-rules, and variables (as fallback) - * Parses almost anything inside of {} [] () "" blocks - * until it reaches outer-most tokens. - * - * First, it will try to parse comments and entities to reach - * the end. This is mostly like the Expression parser except no - * math is allowed. - */ - permissiveValue: function permissiveValue(untilTokens) { - var i; - var e; - var done; - var value; - var tok = untilTokens || ';'; - var index = parserInput.i; - var result = []; - - function testCurrentChar() { - var char = parserInput.currentChar(); - - if (typeof tok === 'string') { - return char === tok; - } else { - return tok.test(char); - } - } - - if (testCurrentChar()) { - return; - } - - value = []; - - do { - e = this.comment(); - - if (e) { - value.push(e); - continue; - } - - e = this.entity(); - - if (e) { - value.push(e); - } - } while (e); - - done = testCurrentChar(); - - if (value.length > 0) { - value = new tree.Expression(value); - - if (done) { - return value; - } else { - result.push(value); - } // Preserve space before $parseUntil as it will not - - - if (parserInput.prevChar() === ' ') { - result.push(new tree.Anonymous(' ', index)); - } - } - - parserInput.save(); - value = parserInput.$parseUntil(tok); - - if (value) { - if (typeof value === 'string') { - error("Expected '".concat(value, "'"), 'Parse'); - } - - if (value.length === 1 && value[0] === ' ') { - parserInput.forget(); - return new tree.Anonymous('', index); - } - - var item; - - for (i = 0; i < value.length; i++) { - item = value[i]; - - if (Array.isArray(item)) { - // Treat actual quotes as normal quoted values - result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); - } else { - if (i === value.length - 1) { - item = item.trim(); - } // Treat like quoted values, but replace vars like unquoted expressions - - - var quote = new tree.Quoted('\'', item, true, index, fileInfo); - quote.variableRegex = /@([\w-]+)/g; - quote.propRegex = /\$([\w-]+)/g; - result.push(quote); - } - } - - parserInput.forget(); - return new tree.Expression(result, true); - } - - parserInput.restore(); - }, - // - // An @import atrule - // - // @import "lib"; - // - // Depending on our environment, importing is done differently: - // In the browser, it's an XHR request, in Node, it would be a - // file-system operation. The function used for importing is - // stored in `import`, which we pass to the Import constructor. - // - 'import': function _import() { - var path; - var features; - var index = parserInput.i; - var dir = parserInput.$re(/^@import?\s+/); - - if (dir) { - var options = (dir ? this.importOptions() : null) || {}; - - if (path = this.entities.quoted() || this.entities.url()) { - features = this.mediaFeatures(); - - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon or unrecognised media features on import'); - } - - features = features && new tree.Value(features); - return new tree.Import(path, features, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed import statement'); - } - } - }, - importOptions: function importOptions() { - var o; - var options = {}; - var optionName; - var value; // list of options, surrounded by parens - - if (!parserInput.$char('(')) { - return null; - } - - do { - o = this.importOption(); - - if (o) { - optionName = o; - value = true; - - switch (optionName) { - case 'css': - optionName = 'less'; - value = false; - break; - - case 'once': - optionName = 'multiple'; - value = false; - break; - } - - options[optionName] = value; - - if (!parserInput.$char(',')) { - break; - } - } - } while (o); - - expectChar(')'); - return options; - }, - importOption: function importOption() { - var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); - - if (opt) { - return opt[1]; - } - }, - mediaFeature: function mediaFeature() { - var entities = this.entities; - var nodes = []; - var e; - var p; - parserInput.save(); - - do { - e = entities.keyword() || entities.variable() || entities.mixinLookup(); - - if (e) { - nodes.push(e); - } else if (parserInput.$char('(')) { - p = this.property(); - e = this.value(); - - if (parserInput.$char(')')) { - if (p && e) { - nodes.push(new tree.Paren(new tree.Declaration(p, e, null, null, parserInput.i, fileInfo, true))); - } else if (e) { - nodes.push(new tree.Paren(e)); - } else { - error('badly formed media feature definition'); - } - } else { - error('Missing closing \')\'', 'Parse'); - } - } - } while (e); - - parserInput.forget(); - - if (nodes.length > 0) { - return new tree.Expression(nodes); - } - }, - mediaFeatures: function mediaFeatures() { - var entities = this.entities; - var features = []; - var e; - - do { - e = this.mediaFeature(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } else { - e = entities.variable() || entities.mixinLookup(); - - if (e) { - features.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } - } while (e); - - return features.length > 0 ? features : null; - }, - media: function media() { - var features; - var rules; - var media; - var debugInfo; - var index = parserInput.i; - - if (context.dumpLineNumbers) { - debugInfo = getDebugInfo(index); - } - - parserInput.save(); - - if (parserInput.$str('@media')) { - features = this.mediaFeatures(); - rules = this.block(); - - if (!rules) { - error('media definitions require block statements after any features'); - } - - parserInput.forget(); - media = new tree.Media(rules, features, index, fileInfo); - - if (context.dumpLineNumbers) { - media.debugInfo = debugInfo; - } - - return media; - } - - parserInput.restore(); - }, - // - // A @plugin directive, used to import plugins dynamically. - // - // @plugin (args) "lib"; - // - plugin: function plugin() { - var path; - var args; - var options; - var index = parserInput.i; - var dir = parserInput.$re(/^@plugin?\s+/); - - if (dir) { - args = this.pluginArgs(); - - if (args) { - options = { - pluginArgs: args, - isPlugin: true - }; - } else { - options = { - isPlugin: true - }; - } - - if (path = this.entities.quoted() || this.entities.url()) { - if (!parserInput.$char(';')) { - parserInput.i = index; - error('missing semi-colon on @plugin'); - } - - return new tree.Import(path, null, options, index, fileInfo); - } else { - parserInput.i = index; - error('malformed @plugin statement'); - } - } - }, - pluginArgs: function pluginArgs() { - // list of options, surrounded by parens - parserInput.save(); - - if (!parserInput.$char('(')) { - parserInput.restore(); - return null; - } - - var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); - - if (args[1]) { - parserInput.forget(); - return args[1].trim(); - } else { - parserInput.restore(); - return null; - } - }, - // - // A CSS AtRule - // - // @charset "utf-8"; - // - atrule: function atrule() { - var index = parserInput.i; - var name; - var value; - var rules; - var nonVendorSpecificName; - var hasIdentifier; - var hasExpression; - var hasUnknown; - var hasBlock = true; - var isRooted = true; - - if (parserInput.currentChar() !== '@') { - return; - } - - value = this['import']() || this.plugin() || this.media(); - - if (value) { - return value; - } - - parserInput.save(); - name = parserInput.$re(/^@[a-z-]+/); - - if (!name) { - return; - } - - nonVendorSpecificName = name; - - if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { - nonVendorSpecificName = "@".concat(name.slice(name.indexOf('-', 2) + 1)); - } - - switch (nonVendorSpecificName) { - case '@charset': - hasIdentifier = true; - hasBlock = false; - break; - - case '@namespace': - hasExpression = true; - hasBlock = false; - break; - - case '@keyframes': - case '@counter-style': - hasIdentifier = true; - break; - - case '@document': - case '@supports': - hasUnknown = true; - isRooted = false; - break; - - default: - hasUnknown = true; - break; - } - - parserInput.commentStore.length = 0; - - if (hasIdentifier) { - value = this.entity(); - - if (!value) { - error("expected ".concat(name, " identifier")); - } - } else if (hasExpression) { - value = this.expression(); - - if (!value) { - error("expected ".concat(name, " expression")); - } - } else if (hasUnknown) { - value = this.permissiveValue(/^[{;]/); - hasBlock = parserInput.currentChar() === '{'; - - if (!value) { - if (!hasBlock && parserInput.currentChar() !== ';') { - error("".concat(name, " rule is missing block or ending semi-colon")); - } - } else if (!value.value) { - value = null; - } - } - - if (hasBlock) { - rules = this.blockRuleset(); - } - - if (rules || !hasBlock && value && parserInput.$char(';')) { - parserInput.forget(); - return new tree.AtRule(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); - } - - parserInput.restore('at-rule options not recognised'); - }, - // - // A Value is a comma-delimited list of Expressions - // - // font-family: Baskerville, Georgia, serif; - // - // In a Rule, a Value represents everything after the `:`, - // and before the `;`. - // - value: function value() { - var e; - var expressions = []; - var index = parserInput.i; - - do { - e = this.expression(); - - if (e) { - expressions.push(e); - - if (!parserInput.$char(',')) { - break; - } - } - } while (e); - - if (expressions.length > 0) { - return new tree.Value(expressions, index); - } - }, - important: function important() { - if (parserInput.currentChar() === '!') { - return parserInput.$re(/^! *important/); - } - }, - sub: function sub() { - var a; - var e; - parserInput.save(); - - if (parserInput.$char('(')) { - a = this.addition(); - - if (a && parserInput.$char(')')) { - parserInput.forget(); - e = new tree.Expression([a]); - e.parens = true; - return e; - } - - parserInput.restore('Expected \')\''); - return; - } - - parserInput.restore(); - }, - multiplication: function multiplication() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.operand(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - if (parserInput.peek(/^\/[*\/]/)) { - break; - } - - parserInput.save(); - op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); - - if (!op) { - parserInput.forget(); - break; - } - - a = this.operand(); - - if (!a) { - parserInput.restore(); - break; - } - - parserInput.forget(); - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - addition: function addition() { - var m; - var a; - var op; - var operation; - var isSpaced; - m = this.multiplication(); - - if (m) { - isSpaced = parserInput.isWhitespace(-1); - - while (true) { - op = parserInput.$re(/^[-+]\s+/) || !isSpaced && (parserInput.$char('+') || parserInput.$char('-')); - - if (!op) { - break; - } - - a = this.multiplication(); - - if (!a) { - break; - } - - m.parensInOp = true; - a.parensInOp = true; - operation = new tree.Operation(op, [operation || m, a], isSpaced); - isSpaced = parserInput.isWhitespace(-1); - } - - return operation || m; - } - }, - conditions: function conditions() { - var a; - var b; - var index = parserInput.i; - var condition; - a = this.condition(true); - - if (a) { - while (true) { - if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { - break; - } - - b = this.condition(true); - - if (!b) { - break; - } - - condition = new tree.Condition('or', condition || a, b, index); - } - - return condition || a; - } - }, - condition: function condition(needsParens) { - var result; - var logical; - var next; - - function or() { - return parserInput.$str('or'); - } - - result = this.conditionAnd(needsParens); - - if (!result) { - return; - } - - logical = or(); - - if (logical) { - next = this.condition(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - conditionAnd: function conditionAnd(needsParens) { - var result; - var logical; - var next; - var self = this; - - function insideCondition() { - var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); - - if (!cond && !needsParens) { - return self.atomicCondition(needsParens); - } - - return cond; - } - - function and() { - return parserInput.$str('and'); - } - - result = insideCondition(); - - if (!result) { - return; - } - - logical = and(); - - if (logical) { - next = this.conditionAnd(needsParens); - - if (next) { - result = new tree.Condition(logical, result, next); - } else { - return; - } - } - - return result; - }, - negatedCondition: function negatedCondition(needsParens) { - if (parserInput.$str('not')) { - var result = this.parenthesisCondition(needsParens); - - if (result) { - result.negate = !result.negate; - } - - return result; - } - }, - parenthesisCondition: function parenthesisCondition(needsParens) { - function tryConditionFollowedByParenthesis(me) { - var body; - parserInput.save(); - body = me.condition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore(); - return; - } - - parserInput.forget(); - return body; - } - - var body; - parserInput.save(); - - if (!parserInput.$str('(')) { - parserInput.restore(); - return; - } - - body = tryConditionFollowedByParenthesis(this); - - if (body) { - parserInput.forget(); - return body; - } - - body = this.atomicCondition(needsParens); - - if (!body) { - parserInput.restore(); - return; - } - - if (!parserInput.$char(')')) { - parserInput.restore("expected ')' got '".concat(parserInput.currentChar(), "'")); - return; - } - - parserInput.forget(); - return body; - }, - atomicCondition: function atomicCondition(needsParens) { - var entities = this.entities; - var index = parserInput.i; - var a; - var b; - var c; - var op; - - function cond() { - return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); - } - - cond = cond.bind(this); - a = cond(); - - if (a) { - if (parserInput.$char('>')) { - if (parserInput.$char('=')) { - op = '>='; - } else { - op = '>'; - } - } else if (parserInput.$char('<')) { - if (parserInput.$char('=')) { - op = '<='; - } else { - op = '<'; - } - } else if (parserInput.$char('=')) { - if (parserInput.$char('>')) { - op = '=>'; - } else if (parserInput.$char('<')) { - op = '=<'; - } else { - op = '='; - } - } - - if (op) { - b = cond(); - - if (b) { - c = new tree.Condition(op, a, b, index, false); - } else { - error('expected expression'); - } - } else { - c = new tree.Condition('=', a, new tree.Keyword('true'), index, false); - } - - return c; - } - }, - // - // An operand is anything that can be part of an operation, - // such as a Color, or a Variable - // - operand: function operand() { - var entities = this.entities; - var negate; - - if (parserInput.peek(/^-[@\$\(]/)) { - negate = parserInput.$char('-'); - } - - var o = this.sub() || entities.dimension() || entities.color() || entities.variable() || entities.property() || entities.call() || entities.quoted(true) || entities.colorKeyword() || entities.mixinLookup(); - - if (negate) { - o.parensInOp = true; - o = new tree.Negative(o); - } - - return o; - }, - // - // Expressions either represent mathematical operations, - // or white-space delimited Entities. - // - // 1px solid black - // @var * 2 - // - expression: function expression() { - var entities = []; - var e; - var delim; - var index = parserInput.i; - - do { - e = this.comment(); - - if (e) { - entities.push(e); - continue; - } - - e = this.addition() || this.entity(); - - if (e) { - entities.push(e); // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here - - if (!parserInput.peek(/^\/[\/*]/)) { - delim = parserInput.$char('/'); - - if (delim) { - entities.push(new tree.Anonymous(delim, index)); - } + }, + // + // Entities are the smallest recognized token, + // and can be found inside a rule's value. + // + entity: function () { + var entities = this.entities; + return this.comment() || entities.literal() || entities.variable() || entities.url() || + entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) || + entities.javascript(); + }, + // + // A Declaration terminator. Note that we use `peek()` to check for '}', + // because the `block` rule will be expecting it, but we still need to make sure + // it's there, if ';' was omitted. + // + end: function () { + return parserInput.$char(';') || parserInput.peek('}'); + }, + // + // IE's alpha function + // + // alpha(opacity=88) + // + ieAlpha: function () { + var value; + // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18 + if (!parserInput.$re(/^opacity=/i)) { + return; + } + value = parserInput.$re(/^\d+/); + if (!value) { + value = expect(parsers.entities.variable, 'Could not parse alpha'); + value = "@{" + value.name.slice(1) + "}"; + } + expectChar(')'); + return new tree.Quoted('', "alpha(opacity=" + value + ")"); + }, + // + // A Selector Element + // + // div + // + h1 + // #socks + // input[type="text"] + // + // Elements are the building blocks for Selectors, + // they are made out of a `Combinator` (see combinator rule), + // and an element name, such as a tag a class, or `*`. + // + element: function () { + var e; + var c; + var v; + var index = parserInput.i; + c = this.combinator(); + e = parserInput.$re(/^(?:\d+\.\d+|\d+)%/) || + parserInput.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) || + parserInput.$char('*') || parserInput.$char('&') || this.attribute() || + parserInput.$re(/^\([^&()@]+\)/) || parserInput.$re(/^[\.#:](?=@)/) || + this.entities.variableCurly(); + if (!e) { + parserInput.save(); + if (parserInput.$char('(')) { + if ((v = this.selector(false)) && parserInput.$char(')')) { + e = new (tree.Paren)(v); + parserInput.forget(); + } + else { + parserInput.restore('Missing closing \')\''); + } + } + else { + parserInput.forget(); + } + } + if (e) { + return new (tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo); + } + }, + // + // Combinators combine elements together, in a Selector. + // + // Because our parser isn't white-space sensitive, special care + // has to be taken, when parsing the descendant combinator, ` `, + // as it's an empty space. We have to check the previous character + // in the input, to see if it's a ` ` character. More info on how + // we deal with this in *combinator.js*. + // + combinator: function () { + var c = parserInput.currentChar(); + if (c === '/') { + parserInput.save(); + var slashedCombinator = parserInput.$re(/^\/[a-z]+\//i); + if (slashedCombinator) { + parserInput.forget(); + return new (tree.Combinator)(slashedCombinator); + } + parserInput.restore(); + } + if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') { + parserInput.i++; + if (c === '^' && parserInput.currentChar() === '^') { + c = '^^'; + parserInput.i++; + } + while (parserInput.isWhitespace()) { + parserInput.i++; + } + return new (tree.Combinator)(c); + } + else if (parserInput.isWhitespace(-1)) { + return new (tree.Combinator)(' '); + } + else { + return new (tree.Combinator)(null); + } + }, + // + // A CSS Selector + // with less extensions e.g. the ability to extend and guard + // + // .class > div + h1 + // li a:hover + // + // Selectors are made out of one or more Elements, see above. + // + selector: function (isLess) { + var index = parserInput.i; + var elements; + var extendList; + var c; + var e; + var allExtends; + var when; + var condition; + isLess = isLess !== false; + while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) { + if (when) { + condition = expect(this.conditions, 'expected condition'); + } + else if (condition) { + error('CSS guard can only be used at the end of selector'); + } + else if (extendList) { + if (allExtends) { + allExtends = allExtends.concat(extendList); + } + else { + allExtends = extendList; + } + } + else { + if (allExtends) { + error('Extend can only be used at the end of selector'); + } + c = parserInput.currentChar(); + if (elements) { + elements.push(e); + } + else { + elements = [e]; + } + e = null; + } + if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') { + break; + } + } + if (elements) { + return new (tree.Selector)(elements, allExtends, condition, index, fileInfo); + } + if (allExtends) { + error('Extend must be used to extend a selector, it cannot be used on its own'); + } + }, + selectors: function () { + var s; + var selectors; + while (true) { + s = this.selector(); + if (!s) { + break; + } + if (selectors) { + selectors.push(s); + } + else { + selectors = [s]; + } + parserInput.commentStore.length = 0; + if (s.condition && selectors.length > 1) { + error("Guards are only currently allowed on a single selector."); + } + if (!parserInput.$char(',')) { + break; + } + if (s.condition) { + error("Guards are only currently allowed on a single selector."); + } + parserInput.commentStore.length = 0; + } + return selectors; + }, + attribute: function () { + if (!parserInput.$char('[')) { + return; + } + var entities = this.entities; + var key; + var val; + var op; + if (!(key = entities.variableCurly())) { + key = expect(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/); + } + op = parserInput.$re(/^[|~*$^]?=/); + if (op) { + val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\w-]+/) || entities.variableCurly(); + } + expectChar(']'); + return new (tree.Attribute)(key, op, val); + }, + // + // The `block` rule is used by `ruleset` and `mixin.definition`. + // It's a wrapper around the `primary` rule, with added `{}`. + // + block: function () { + var content; + if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) { + return content; + } + }, + blockRuleset: function () { + var block = this.block(); + if (block) { + block = new tree.Ruleset(null, block); + } + return block; + }, + detachedRuleset: function () { + var argInfo; + var params; + var variadic; + parserInput.save(); + if (parserInput.$re(/^[.#]\(/)) { + /** + * DR args currently only implemented for each() function, and not + * yet settable as `@dr: #(@arg) {}` + * This should be done when DRs are merged with mixins. + * See: https://github.com/less/less-meta/issues/16 + */ + argInfo = this.mixin.args(false); + params = argInfo.args; + variadic = argInfo.variadic; + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + } + var blockRuleset = this.blockRuleset(); + if (blockRuleset) { + parserInput.forget(); + if (params) { + return new tree.mixin.Definition(null, params, blockRuleset, null, variadic); + } + return new tree.DetachedRuleset(blockRuleset); + } + parserInput.restore(); + }, + // + // div, .class, body > p {...} + // + ruleset: function () { + var selectors; + var rules; + var debugInfo; + parserInput.save(); + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(parserInput.i); + } + selectors = this.selectors(); + if (selectors && (rules = this.block())) { + parserInput.forget(); + var ruleset = new (tree.Ruleset)(selectors, rules, context.strictImports); + if (context.dumpLineNumbers) { + ruleset.debugInfo = debugInfo; + } + return ruleset; + } + else { + parserInput.restore(); + } + }, + declaration: function () { + var name; + var value; + var index = parserInput.i; + var hasDR; + var c = parserInput.currentChar(); + var important; + var merge; + var isVariable; + if (c === '.' || c === '#' || c === '&' || c === ':') { + return; + } + parserInput.save(); + name = this.variable() || this.ruleProperty(); + if (name) { + isVariable = typeof name === 'string'; + if (isVariable) { + value = this.detachedRuleset(); + if (value) { + hasDR = true; + } + } + parserInput.commentStore.length = 0; + if (!value) { + // a name returned by this.ruleProperty() is always an array of the form: + // [string-1, ..., string-n, ""] or [string-1, ..., string-n, "+"] + // where each item is a tree.Keyword or tree.Variable + merge = !isVariable && name.length > 1 && name.pop().value; + // Custom property values get permissive parsing + if (name[0].value && name[0].value.slice(0, 2) === '--') { + value = this.permissiveValue(); + } + // Try to store values as anonymous + // If we need the value later we'll re-parse it in ruleset.parseValue + else { + value = this.anonymousValue(); + } + if (value) { + parserInput.forget(); + // anonymous values absorb the end ';' which is required for them to work + return new (tree.Declaration)(name, value, false, merge, index, fileInfo); + } + if (!value) { + value = this.value(); + } + if (value) { + important = this.important(); + } + else if (isVariable) { + // As a last resort, try permissiveValue + value = this.permissiveValue(); + } + } + if (value && (this.end() || hasDR)) { + parserInput.forget(); + return new (tree.Declaration)(name, value, important, merge, index, fileInfo); + } + else { + parserInput.restore(); + } + } + else { + parserInput.restore(); + } + }, + anonymousValue: function () { + var index = parserInput.i; + var match = parserInput.$re(/^([^.#@\$+\/'"*`(;{}-]*);/); + if (match) { + return new (tree.Anonymous)(match[1], index); + } + }, + /** + * Used for custom properties, at-rules, and variables (as fallback) + * Parses almost anything inside of {} [] () "" blocks + * until it reaches outer-most tokens. + * + * First, it will try to parse comments and entities to reach + * the end. This is mostly like the Expression parser except no + * math is allowed. + */ + permissiveValue: function (untilTokens) { + var i; + var e; + var done; + var value; + var tok = untilTokens || ';'; + var index = parserInput.i; + var result = []; + function testCurrentChar() { + var char = parserInput.currentChar(); + if (typeof tok === 'string') { + return char === tok; + } + else { + return tok.test(char); + } + } + if (testCurrentChar()) { + return; + } + value = []; + do { + e = this.comment(); + if (e) { + value.push(e); + continue; + } + e = this.entity(); + if (e) { + value.push(e); + } + } while (e); + done = testCurrentChar(); + if (value.length > 0) { + value = new (tree.Expression)(value); + if (done) { + return value; + } + else { + result.push(value); + } + // Preserve space before $parseUntil as it will not + if (parserInput.prevChar() === ' ') { + result.push(new tree.Anonymous(' ', index)); + } + } + parserInput.save(); + value = parserInput.$parseUntil(tok); + if (value) { + if (typeof value === 'string') { + error("Expected '" + value + "'", 'Parse'); + } + if (value.length === 1 && value[0] === ' ') { + parserInput.forget(); + return new tree.Anonymous('', index); + } + var item = void 0; + for (i = 0; i < value.length; i++) { + item = value[i]; + if (Array.isArray(item)) { + // Treat actual quotes as normal quoted values + result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo)); + } + else { + if (i === value.length - 1) { + item = item.trim(); + } + // Treat like quoted values, but replace vars like unquoted expressions + var quote = new tree.Quoted('\'', item, true, index, fileInfo); + quote.variableRegex = /@([\w-]+)/g; + quote.propRegex = /\$([\w-]+)/g; + result.push(quote); + } + } + parserInput.forget(); + return new tree.Expression(result, true); + } + parserInput.restore(); + }, + // + // An @import atrule + // + // @import "lib"; + // + // Depending on our environment, importing is done differently: + // In the browser, it's an XHR request, in Node, it would be a + // file-system operation. The function used for importing is + // stored in `import`, which we pass to the Import constructor. + // + 'import': function () { + var path; + var features; + var index = parserInput.i; + var dir = parserInput.$re(/^@import?\s+/); + if (dir) { + var options_1 = (dir ? this.importOptions() : null) || {}; + if ((path = this.entities.quoted() || this.entities.url())) { + features = this.mediaFeatures(); + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon or unrecognised media features on import'); + } + features = features && new (tree.Value)(features); + return new (tree.Import)(path, features, options_1, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed import statement'); + } + } + }, + importOptions: function () { + var o; + var options = {}; + var optionName; + var value; + // list of options, surrounded by parens + if (!parserInput.$char('(')) { + return null; + } + do { + o = this.importOption(); + if (o) { + optionName = o; + value = true; + switch (optionName) { + case 'css': + optionName = 'less'; + value = false; + break; + case 'once': + optionName = 'multiple'; + value = false; + break; + } + options[optionName] = value; + if (!parserInput.$char(',')) { + break; + } + } + } while (o); + expectChar(')'); + return options; + }, + importOption: function () { + var opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/); + if (opt) { + return opt[1]; + } + }, + mediaFeature: function () { + var entities = this.entities; + var nodes = []; + var e; + var p; + parserInput.save(); + do { + e = entities.keyword() || entities.variable() || entities.mixinLookup(); + if (e) { + nodes.push(e); + } + else if (parserInput.$char('(')) { + p = this.property(); + e = this.value(); + if (parserInput.$char(')')) { + if (p && e) { + nodes.push(new (tree.Paren)(new (tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true))); + } + else if (e) { + nodes.push(new (tree.Paren)(e)); + } + else { + error('badly formed media feature definition'); + } + } + else { + error('Missing closing \')\'', 'Parse'); + } + } + } while (e); + parserInput.forget(); + if (nodes.length > 0) { + return new (tree.Expression)(nodes); + } + }, + mediaFeatures: function () { + var entities = this.entities; + var features = []; + var e; + do { + e = this.mediaFeature(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + else { + e = entities.variable() || entities.mixinLookup(); + if (e) { + features.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } + } while (e); + return features.length > 0 ? features : null; + }, + media: function () { + var features; + var rules; + var media; + var debugInfo; + var index = parserInput.i; + if (context.dumpLineNumbers) { + debugInfo = getDebugInfo(index); + } + parserInput.save(); + if (parserInput.$str('@media')) { + features = this.mediaFeatures(); + rules = this.block(); + if (!rules) { + error('media definitions require block statements after any features'); + } + parserInput.forget(); + media = new (tree.Media)(rules, features, index, fileInfo); + if (context.dumpLineNumbers) { + media.debugInfo = debugInfo; + } + return media; + } + parserInput.restore(); + }, + // + // A @plugin directive, used to import plugins dynamically. + // + // @plugin (args) "lib"; + // + plugin: function () { + var path; + var args; + var options; + var index = parserInput.i; + var dir = parserInput.$re(/^@plugin?\s+/); + if (dir) { + args = this.pluginArgs(); + if (args) { + options = { + pluginArgs: args, + isPlugin: true + }; + } + else { + options = { isPlugin: true }; + } + if ((path = this.entities.quoted() || this.entities.url())) { + if (!parserInput.$char(';')) { + parserInput.i = index; + error('missing semi-colon on @plugin'); + } + return new (tree.Import)(path, null, options, index, fileInfo); + } + else { + parserInput.i = index; + error('malformed @plugin statement'); + } + } + }, + pluginArgs: function () { + // list of options, surrounded by parens + parserInput.save(); + if (!parserInput.$char('(')) { + parserInput.restore(); + return null; + } + var args = parserInput.$re(/^\s*([^\);]+)\)\s*/); + if (args[1]) { + parserInput.forget(); + return args[1].trim(); + } + else { + parserInput.restore(); + return null; + } + }, + // + // A CSS AtRule + // + // @charset "utf-8"; + // + atrule: function () { + var index = parserInput.i; + var name; + var value; + var rules; + var nonVendorSpecificName; + var hasIdentifier; + var hasExpression; + var hasUnknown; + var hasBlock = true; + var isRooted = true; + if (parserInput.currentChar() !== '@') { + return; + } + value = this['import']() || this.plugin() || this.media(); + if (value) { + return value; + } + parserInput.save(); + name = parserInput.$re(/^@[a-z-]+/); + if (!name) { + return; + } + nonVendorSpecificName = name; + if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) { + nonVendorSpecificName = "@" + name.slice(name.indexOf('-', 2) + 1); + } + switch (nonVendorSpecificName) { + case '@charset': + hasIdentifier = true; + hasBlock = false; + break; + case '@namespace': + hasExpression = true; + hasBlock = false; + break; + case '@keyframes': + case '@counter-style': + hasIdentifier = true; + break; + case '@document': + case '@supports': + hasUnknown = true; + isRooted = false; + break; + default: + hasUnknown = true; + break; + } + parserInput.commentStore.length = 0; + if (hasIdentifier) { + value = this.entity(); + if (!value) { + error("expected " + name + " identifier"); + } + } + else if (hasExpression) { + value = this.expression(); + if (!value) { + error("expected " + name + " expression"); + } + } + else if (hasUnknown) { + value = this.permissiveValue(/^[{;]/); + hasBlock = (parserInput.currentChar() === '{'); + if (!value) { + if (!hasBlock && parserInput.currentChar() !== ';') { + error(name + " rule is missing block or ending semi-colon"); + } + } + else if (!value.value) { + value = null; + } + } + if (hasBlock) { + rules = this.blockRuleset(); + } + if (rules || (!hasBlock && value && parserInput.$char(';'))) { + parserInput.forget(); + return new (tree.AtRule)(name, value, rules, index, fileInfo, context.dumpLineNumbers ? getDebugInfo(index) : null, isRooted); + } + parserInput.restore('at-rule options not recognised'); + }, + // + // A Value is a comma-delimited list of Expressions + // + // font-family: Baskerville, Georgia, serif; + // + // In a Rule, a Value represents everything after the `:`, + // and before the `;`. + // + value: function () { + var e; + var expressions = []; + var index = parserInput.i; + do { + e = this.expression(); + if (e) { + expressions.push(e); + if (!parserInput.$char(',')) { + break; + } + } + } while (e); + if (expressions.length > 0) { + return new (tree.Value)(expressions, index); + } + }, + important: function () { + if (parserInput.currentChar() === '!') { + return parserInput.$re(/^! *important/); + } + }, + sub: function () { + var a; + var e; + parserInput.save(); + if (parserInput.$char('(')) { + a = this.addition(); + if (a && parserInput.$char(')')) { + parserInput.forget(); + e = new (tree.Expression)([a]); + e.parens = true; + return e; + } + parserInput.restore('Expected \')\''); + return; + } + parserInput.restore(); + }, + multiplication: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.operand(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + if (parserInput.peek(/^\/[*\/]/)) { + break; + } + parserInput.save(); + op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./'); + if (!op) { + parserInput.forget(); + break; + } + a = this.operand(); + if (!a) { + parserInput.restore(); + break; + } + parserInput.forget(); + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + addition: function () { + var m; + var a; + var op; + var operation; + var isSpaced; + m = this.multiplication(); + if (m) { + isSpaced = parserInput.isWhitespace(-1); + while (true) { + op = parserInput.$re(/^[-+]\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-'))); + if (!op) { + break; + } + a = this.multiplication(); + if (!a) { + break; + } + m.parensInOp = true; + a.parensInOp = true; + operation = new (tree.Operation)(op, [operation || m, a], isSpaced); + isSpaced = parserInput.isWhitespace(-1); + } + return operation || m; + } + }, + conditions: function () { + var a; + var b; + var index = parserInput.i; + var condition; + a = this.condition(true); + if (a) { + while (true) { + if (!parserInput.peek(/^,\s*(not\s*)?\(/) || !parserInput.$char(',')) { + break; + } + b = this.condition(true); + if (!b) { + break; + } + condition = new (tree.Condition)('or', condition || a, b, index); + } + return condition || a; + } + }, + condition: function (needsParens) { + var result; + var logical; + var next; + function or() { + return parserInput.$str('or'); + } + result = this.conditionAnd(needsParens); + if (!result) { + return; + } + logical = or(); + if (logical) { + next = this.condition(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + conditionAnd: function (needsParens) { + var result; + var logical; + var next; + var self = this; + function insideCondition() { + var cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens); + if (!cond && !needsParens) { + return self.atomicCondition(needsParens); + } + return cond; + } + function and() { + return parserInput.$str('and'); + } + result = insideCondition(); + if (!result) { + return; + } + logical = and(); + if (logical) { + next = this.conditionAnd(needsParens); + if (next) { + result = new (tree.Condition)(logical, result, next); + } + else { + return; + } + } + return result; + }, + negatedCondition: function (needsParens) { + if (parserInput.$str('not')) { + var result = this.parenthesisCondition(needsParens); + if (result) { + result.negate = !result.negate; + } + return result; + } + }, + parenthesisCondition: function (needsParens) { + function tryConditionFollowedByParenthesis(me) { + var body; + parserInput.save(); + body = me.condition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore(); + return; + } + parserInput.forget(); + return body; + } + var body; + parserInput.save(); + if (!parserInput.$str('(')) { + parserInput.restore(); + return; + } + body = tryConditionFollowedByParenthesis(this); + if (body) { + parserInput.forget(); + return body; + } + body = this.atomicCondition(needsParens); + if (!body) { + parserInput.restore(); + return; + } + if (!parserInput.$char(')')) { + parserInput.restore("expected ')' got '" + parserInput.currentChar() + "'"); + return; + } + parserInput.forget(); + return body; + }, + atomicCondition: function (needsParens) { + var entities = this.entities; + var index = parserInput.i; + var a; + var b; + var c; + var op; + function cond() { + return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup(); + } + cond = cond.bind(this); + a = cond(); + if (a) { + if (parserInput.$char('>')) { + if (parserInput.$char('=')) { + op = '>='; + } + else { + op = '>'; + } + } + else if (parserInput.$char('<')) { + if (parserInput.$char('=')) { + op = '<='; + } + else { + op = '<'; + } + } + else if (parserInput.$char('=')) { + if (parserInput.$char('>')) { + op = '=>'; + } + else if (parserInput.$char('<')) { + op = '=<'; + } + else { + op = '='; + } + } + if (op) { + b = cond(); + if (b) { + c = new (tree.Condition)(op, a, b, index, false); + } + else { + error('expected expression'); + } + } + else { + c = new (tree.Condition)('=', a, new (tree.Keyword)('true'), index, false); + } + return c; + } + }, + // + // An operand is anything that can be part of an operation, + // such as a Color, or a Variable + // + operand: function () { + var entities = this.entities; + var negate; + if (parserInput.peek(/^-[@\$\(]/)) { + negate = parserInput.$char('-'); + } + var o = this.sub() || entities.dimension() || + entities.color() || entities.variable() || + entities.property() || entities.call() || + entities.quoted(true) || entities.colorKeyword() || + entities.mixinLookup(); + if (negate) { + o.parensInOp = true; + o = new (tree.Negative)(o); + } + return o; + }, + // + // Expressions either represent mathematical operations, + // or white-space delimited Entities. + // + // 1px solid black + // @var * 2 + // + expression: function () { + var entities = []; + var e; + var delim; + var index = parserInput.i; + do { + e = this.comment(); + if (e) { + entities.push(e); + continue; + } + e = this.addition() || this.entity(); + if (e) { + entities.push(e); + // operations do not allow keyword "/" dimension (e.g. small/20px) so we support that here + if (!parserInput.peek(/^\/[\/*]/)) { + delim = parserInput.$char('/'); + if (delim) { + entities.push(new (tree.Anonymous)(delim, index)); + } + } + } + } while (e); + if (entities.length > 0) { + return new (tree.Expression)(entities); + } + }, + property: function () { + var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); + if (name) { + return name[1]; + } + }, + ruleProperty: function () { + var name = []; + var index = []; + var s; + var k; + parserInput.save(); + var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); + if (simpleProperty) { + name = [new (tree.Keyword)(simpleProperty[1])]; + parserInput.forget(); + return name; + } + function match(re) { + var i = parserInput.i; + var chunk = parserInput.$re(re); + if (chunk) { + index.push(i); + return name.push(chunk[1]); + } + } + match(/^(\*?)/); + while (true) { + if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { + break; + } + } + if ((name.length > 1) && match(/^((?:\+_|\+)?)\s*:/)) { + parserInput.forget(); + // at last, we have the complete match now. move forward, + // convert name particles to tree objects and return: + if (name[0] === '') { + name.shift(); + index.shift(); + } + for (k = 0; k < name.length; k++) { + s = name[k]; + name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ? + new (tree.Keyword)(s) : + (s.charAt(0) === '@' ? + new (tree.Variable)("@" + s.slice(2, -1), index[k], fileInfo) : + new (tree.Property)("$" + s.slice(2, -1), index[k], fileInfo)); + } + return name; + } + parserInput.restore(); } - } - } while (e); - - if (entities.length > 0) { - return new tree.Expression(entities); - } - }, - property: function property() { - var name = parserInput.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/); - - if (name) { - return name[1]; - } - }, - ruleProperty: function ruleProperty() { - var name = []; - var index = []; - var s; - var k; - parserInput.save(); - var simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\s*:/); - - if (simpleProperty) { - name = [new tree.Keyword(simpleProperty[1])]; - parserInput.forget(); - return name; - } - - function match(re) { - var i = parserInput.i; - var chunk = parserInput.$re(re); - - if (chunk) { - index.push(i); - return name.push(chunk[1]); - } - } - - match(/^(\*?)/); - - while (true) { - if (!match(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/)) { - break; - } - } - - if (name.length > 1 && match(/^((?:\+_|\+)?)\s*:/)) { - parserInput.forget(); // at last, we have the complete match now. move forward, - // convert name particles to tree objects and return: - - if (name[0] === '') { - name.shift(); - index.shift(); - } - - for (k = 0; k < name.length; k++) { - s = name[k]; - name[k] = s.charAt(0) !== '@' && s.charAt(0) !== '$' ? new tree.Keyword(s) : s.charAt(0) === '@' ? new tree.Variable("@".concat(s.slice(2, -1)), index[k], fileInfo) : new tree.Property("$".concat(s.slice(2, -1)), index[k], fileInfo); - } - - return name; } - - parserInput.restore(); - } - } - }; + }; }; - Parser.serializeVars = function (vars) { - var s = ''; - - for (var name in vars) { - if (Object.hasOwnProperty.call(vars, name)) { - var value = vars[name]; - s += "".concat((name[0] === '@' ? '' : '@') + name, ": ").concat(value).concat(String(value).slice(-1) === ';' ? '' : ';'); + var s = ''; + for (var name_1 in vars) { + if (Object.hasOwnProperty.call(vars, name_1)) { + var value = vars[name_1]; + s += ((name_1[0] === '@') ? '' : '@') + name_1 + ": " + value + ((String(value).slice(-1) === ';') ? '' : ';'); + } } - } - - return s; + return s; }; function boolean(condition) { - return condition ? Keyword.True : Keyword.False; + return condition ? Keyword.True : Keyword.False; } - function If(condition, trueValue, falseValue) { - return condition ? trueValue : falseValue || new Anonymous(); + return condition ? trueValue + : (falseValue || new Anonymous); } - - var boolean$1 = { - boolean: boolean, - 'if': If - }; + var boolean$1 = { boolean: boolean, 'if': If }; var colorFunctions; - function clamp$1(val) { - return Math.min(1, Math.max(0, val)); + return Math.min(1, Math.max(0, val)); } - function hsla(origColor, hsl) { - var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); - - if (color) { - if (origColor.value && /^(rgb|hsl)/.test(origColor.value)) { - color.value = origColor.value; - } else { - color.value = 'rgb'; - } - - return color; - } - } - - function toHSL(color) { - if (color.toHSL) { - return color.toHSL(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } - } - - function toHSV(color) { - if (color.toHSV) { - return color.toHSV(); - } else { - throw new Error('Argument cannot be evaluated to a color'); - } - } - - function number(n) { - if (n instanceof Dimension) { - return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); - } else if (typeof n === 'number') { - return n; - } else { - throw { - type: 'Argument', - message: 'color functions take numbers as parameters' - }; - } - } - - function scaled(n, size) { - if (n instanceof Dimension && n.unit.is('%')) { - return parseFloat(n.value * size / 100); - } else { - return number(n); - } - } - - colorFunctions = { - rgb: function rgb(r, g, b) { - var color = colorFunctions.rgba(r, g, b, 1.0); - + var color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a); if (color) { - color.value = 'rgb'; - return color; - } - }, - rgba: function rgba(r, g, b, a) { - try { - if (r instanceof Color) { - if (g) { - a = number(g); - } else { - a = r.alpha; + if (origColor.value && + /^(rgb|hsl)/.test(origColor.value)) { + color.value = origColor.value; } - - return new Color(r.rgb, a, 'rgba'); - } - - var rgb = [r, g, b].map(function (c) { - return scaled(c, 255); - }); - a = number(a); - return new Color(rgb, a, 'rgba'); - } catch (e) {} - }, - hsl: function hsl(h, s, l) { - var color = colorFunctions.hsla(h, s, l, 1.0); - - if (color) { - color.value = 'hsl'; - return color; - } - }, - hsla: function hsla(h, s, l, a) { - try { - var hue = function hue(h) { - h = h < 0 ? h + 1 : h > 1 ? h - 1 : h; - - if (h * 6 < 1) { - return m1 + (m2 - m1) * h * 6; - } else if (h * 2 < 1) { - return m2; - } else if (h * 3 < 2) { - return m1 + (m2 - m1) * (2 / 3 - h) * 6; - } else { - return m1; - } - }; - - if (h instanceof Color) { - if (s) { - a = number(s); - } else { - a = h.alpha; + else { + color.value = 'rgb'; } - - return new Color(h.rgb, a, 'hsla'); - } - - var m1; - var m2; - h = number(h) % 360 / 360; - s = clamp$1(number(s)); - l = clamp$1(number(l)); - a = clamp$1(number(a)); - m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s; - m1 = l * 2 - m2; - var rgb = [hue(h + 1 / 3) * 255, hue(h) * 255, hue(h - 1 / 3) * 255]; - a = number(a); - return new Color(rgb, a, 'hsla'); - } catch (e) {} - }, - hsv: function hsv(h, s, v) { - return colorFunctions.hsva(h, s, v, 1.0); - }, - hsva: function hsva(h, s, v, a) { - h = number(h) % 360 / 360 * 360; - s = number(s); - v = number(v); - a = number(a); - var i; - var f; - i = Math.floor(h / 60 % 6); - f = h / 60 - i; - var vs = [v, v * (1 - s), v * (1 - f * s), v * (1 - (1 - f) * s)]; - var perm = [[0, 3, 1], [2, 0, 1], [1, 0, 3], [1, 2, 0], [3, 1, 0], [0, 1, 2]]; - return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); - }, - hue: function hue(color) { - return new Dimension(toHSL(color).h); - }, - saturation: function saturation(color) { - return new Dimension(toHSL(color).s * 100, '%'); - }, - lightness: function lightness(color) { - return new Dimension(toHSL(color).l * 100, '%'); - }, - hsvhue: function hsvhue(color) { - return new Dimension(toHSV(color).h); - }, - hsvsaturation: function hsvsaturation(color) { - return new Dimension(toHSV(color).s * 100, '%'); - }, - hsvvalue: function hsvvalue(color) { - return new Dimension(toHSV(color).v * 100, '%'); - }, - red: function red(color) { - return new Dimension(color.rgb[0]); - }, - green: function green(color) { - return new Dimension(color.rgb[1]); - }, - blue: function blue(color) { - return new Dimension(color.rgb[2]); - }, - alpha: function alpha(color) { - return new Dimension(toHSL(color).a); - }, - luma: function luma(color) { - return new Dimension(color.luma() * color.alpha * 100, '%'); - }, - luminance: function luminance(color) { - var luminance = 0.2126 * color.rgb[0] / 255 + 0.7152 * color.rgb[1] / 255 + 0.0722 * color.rgb[2] / 255; - return new Dimension(luminance * color.alpha * 100, '%'); - }, - saturate: function saturate(color, amount, method) { - // filter: saturate(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; - } - - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s += hsl.s * amount.value / 100; - } else { - hsl.s += amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - desaturate: function desaturate(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.s -= hsl.s * amount.value / 100; - } else { - hsl.s -= amount.value / 100; - } - - hsl.s = clamp$1(hsl.s); - return hsla(color, hsl); - }, - lighten: function lighten(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l += hsl.l * amount.value / 100; - } else { - hsl.l += amount.value / 100; + return color; } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - darken: function darken(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.l -= hsl.l * amount.value / 100; - } else { - hsl.l -= amount.value / 100; + } + function toHSL(color) { + if (color.toHSL) { + return color.toHSL(); } - - hsl.l = clamp$1(hsl.l); - return hsla(color, hsl); - }, - fadein: function fadein(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a += hsl.a * amount.value / 100; - } else { - hsl.a += amount.value / 100; + else { + throw new Error('Argument cannot be evaluated to a color'); } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fadeout: function fadeout(color, amount, method) { - var hsl = toHSL(color); - - if (typeof method !== 'undefined' && method.value === 'relative') { - hsl.a -= hsl.a * amount.value / 100; - } else { - hsl.a -= amount.value / 100; + } + function toHSV(color) { + if (color.toHSV) { + return color.toHSV(); } - - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - fade: function fade(color, amount) { - var hsl = toHSL(color); - hsl.a = amount.value / 100; - hsl.a = clamp$1(hsl.a); - return hsla(color, hsl); - }, - spin: function spin(color, amount) { - var hsl = toHSL(color); - var hue = (hsl.h + amount.value) % 360; - hsl.h = hue < 0 ? 360 + hue : hue; - return hsla(color, hsl); - }, - // - // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein - // http://sass-lang.com - // - mix: function mix(color1, color2, weight) { - if (!weight) { - weight = new Dimension(50); + else { + throw new Error('Argument cannot be evaluated to a color'); } - - var p = weight.value / 100.0; - var w = p * 2 - 1; - var a = toHSL(color1).a - toHSL(color2).a; - var w1 = ((w * a == -1 ? w : (w + a) / (1 + w * a)) + 1) / 2.0; - var w2 = 1 - w1; - var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, color1.rgb[1] * w1 + color2.rgb[1] * w2, color1.rgb[2] * w1 + color2.rgb[2] * w2]; - var alpha = color1.alpha * p + color2.alpha * (1 - p); - return new Color(rgb, alpha); - }, - greyscale: function greyscale(color) { - return colorFunctions.desaturate(color, new Dimension(100)); - }, - contrast: function contrast(color, dark, light, threshold) { - // filter: contrast(3.2); - // should be kept as is, so check for color - if (!color.rgb) { - return null; + } + function number(n) { + if (n instanceof Dimension) { + return parseFloat(n.unit.is('%') ? n.value / 100 : n.value); } - - if (typeof light === 'undefined') { - light = colorFunctions.rgba(255, 255, 255, 1.0); + else if (typeof n === 'number') { + return n; } - - if (typeof dark === 'undefined') { - dark = colorFunctions.rgba(0, 0, 0, 1.0); - } // Figure out which is actually light and dark: - - - if (dark.luma() > light.luma()) { - var t = light; - light = dark; - dark = t; + else { + throw { + type: 'Argument', + message: 'color functions take numbers as parameters' + }; } - - if (typeof threshold === 'undefined') { - threshold = 0.43; - } else { - threshold = number(threshold); + } + function scaled(n, size) { + if (n instanceof Dimension && n.unit.is('%')) { + return parseFloat(n.value * size / 100); } - - if (color.luma() < threshold) { - return light; - } else { - return dark; - } - }, - // Changes made in 2.7.0 - Reverted in 3.0.0 - // contrast: function (color, color1, color2, threshold) { - // // Return which of `color1` and `color2` has the greatest contrast with `color` - // // according to the standard WCAG contrast ratio calculation. - // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef - // // The threshold param is no longer used, in line with SASS. - // // filter: contrast(3.2); - // // should be kept as is, so check for color - // if (!color.rgb) { - // return null; - // } - // if (typeof color1 === 'undefined') { - // color1 = colorFunctions.rgba(0, 0, 0, 1.0); - // } - // if (typeof color2 === 'undefined') { - // color2 = colorFunctions.rgba(255, 255, 255, 1.0); - // } - // var contrast1, contrast2; - // var luma = color.luma(); - // var luma1 = color1.luma(); - // var luma2 = color2.luma(); - // // Calculate contrast ratios for each color - // if (luma > luma1) { - // contrast1 = (luma + 0.05) / (luma1 + 0.05); - // } else { - // contrast1 = (luma1 + 0.05) / (luma + 0.05); - // } - // if (luma > luma2) { - // contrast2 = (luma + 0.05) / (luma2 + 0.05); - // } else { - // contrast2 = (luma2 + 0.05) / (luma + 0.05); - // } - // if (contrast1 > contrast2) { - // return color1; - // } else { - // return color2; - // } - // }, - argb: function argb(color) { - return new Anonymous(color.toARGB()); - }, - color: function color(c) { - if (c instanceof Quoted && /^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value)) { - var val = c.value.slice(1); - return new Color(val, undefined, "#".concat(val)); + else { + return number(n); } - - if (c instanceof Color || (c = Color.fromKeyword(c.value))) { - c.value = undefined; - return c; + } + colorFunctions = { + rgb: function (r, g, b) { + var color = colorFunctions.rgba(r, g, b, 1.0); + if (color) { + color.value = 'rgb'; + return color; + } + }, + rgba: function (r, g, b, a) { + try { + if (r instanceof Color) { + if (g) { + a = number(g); + } + else { + a = r.alpha; + } + return new Color(r.rgb, a, 'rgba'); + } + var rgb = [r, g, b].map(function (c) { return scaled(c, 255); }); + a = number(a); + return new Color(rgb, a, 'rgba'); + } + catch (e) { } + }, + hsl: function (h, s, l) { + var color = colorFunctions.hsla(h, s, l, 1.0); + if (color) { + color.value = 'hsl'; + return color; + } + }, + hsla: function (h, s, l, a) { + try { + if (h instanceof Color) { + if (s) { + a = number(s); + } + else { + a = h.alpha; + } + return new Color(h.rgb, a, 'hsla'); + } + var m1_1; + var m2_1; + function hue(h) { + h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h); + if (h * 6 < 1) { + return m1_1 + (m2_1 - m1_1) * h * 6; + } + else if (h * 2 < 1) { + return m2_1; + } + else if (h * 3 < 2) { + return m1_1 + (m2_1 - m1_1) * (2 / 3 - h) * 6; + } + else { + return m1_1; + } + } + h = (number(h) % 360) / 360; + s = clamp$1(number(s)); + l = clamp$1(number(l)); + a = clamp$1(number(a)); + m2_1 = l <= 0.5 ? l * (s + 1) : l + s - l * s; + m1_1 = l * 2 - m2_1; + var rgb = [ + hue(h + 1 / 3) * 255, + hue(h) * 255, + hue(h - 1 / 3) * 255 + ]; + a = number(a); + return new Color(rgb, a, 'hsla'); + } + catch (e) { } + }, + hsv: function (h, s, v) { + return colorFunctions.hsva(h, s, v, 1.0); + }, + hsva: function (h, s, v, a) { + h = ((number(h) % 360) / 360) * 360; + s = number(s); + v = number(v); + a = number(a); + var i; + var f; + i = Math.floor((h / 60) % 6); + f = (h / 60) - i; + var vs = [v, + v * (1 - s), + v * (1 - f * s), + v * (1 - (1 - f) * s)]; + var perm = [[0, 3, 1], + [2, 0, 1], + [1, 0, 3], + [1, 2, 0], + [3, 1, 0], + [0, 1, 2]]; + return colorFunctions.rgba(vs[perm[i][0]] * 255, vs[perm[i][1]] * 255, vs[perm[i][2]] * 255, a); + }, + hue: function (color) { + return new Dimension(toHSL(color).h); + }, + saturation: function (color) { + return new Dimension(toHSL(color).s * 100, '%'); + }, + lightness: function (color) { + return new Dimension(toHSL(color).l * 100, '%'); + }, + hsvhue: function (color) { + return new Dimension(toHSV(color).h); + }, + hsvsaturation: function (color) { + return new Dimension(toHSV(color).s * 100, '%'); + }, + hsvvalue: function (color) { + return new Dimension(toHSV(color).v * 100, '%'); + }, + red: function (color) { + return new Dimension(color.rgb[0]); + }, + green: function (color) { + return new Dimension(color.rgb[1]); + }, + blue: function (color) { + return new Dimension(color.rgb[2]); + }, + alpha: function (color) { + return new Dimension(toHSL(color).a); + }, + luma: function (color) { + return new Dimension(color.luma() * color.alpha * 100, '%'); + }, + luminance: function (color) { + var luminance = (0.2126 * color.rgb[0] / 255) + + (0.7152 * color.rgb[1] / 255) + + (0.0722 * color.rgb[2] / 255); + return new Dimension(luminance * color.alpha * 100, '%'); + }, + saturate: function (color, amount, method) { + // filter: saturate(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s += hsl.s * amount.value / 100; + } + else { + hsl.s += amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + desaturate: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.s -= hsl.s * amount.value / 100; + } + else { + hsl.s -= amount.value / 100; + } + hsl.s = clamp$1(hsl.s); + return hsla(color, hsl); + }, + lighten: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l += hsl.l * amount.value / 100; + } + else { + hsl.l += amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + darken: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.l -= hsl.l * amount.value / 100; + } + else { + hsl.l -= amount.value / 100; + } + hsl.l = clamp$1(hsl.l); + return hsla(color, hsl); + }, + fadein: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a += hsl.a * amount.value / 100; + } + else { + hsl.a += amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fadeout: function (color, amount, method) { + var hsl = toHSL(color); + if (typeof method !== 'undefined' && method.value === 'relative') { + hsl.a -= hsl.a * amount.value / 100; + } + else { + hsl.a -= amount.value / 100; + } + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + fade: function (color, amount) { + var hsl = toHSL(color); + hsl.a = amount.value / 100; + hsl.a = clamp$1(hsl.a); + return hsla(color, hsl); + }, + spin: function (color, amount) { + var hsl = toHSL(color); + var hue = (hsl.h + amount.value) % 360; + hsl.h = hue < 0 ? 360 + hue : hue; + return hsla(color, hsl); + }, + // + // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein + // http://sass-lang.com + // + mix: function (color1, color2, weight) { + if (!weight) { + weight = new Dimension(50); + } + var p = weight.value / 100.0; + var w = p * 2 - 1; + var a = toHSL(color1).a - toHSL(color2).a; + var w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0; + var w2 = 1 - w1; + var rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2, + color1.rgb[1] * w1 + color2.rgb[1] * w2, + color1.rgb[2] * w1 + color2.rgb[2] * w2]; + var alpha = color1.alpha * p + color2.alpha * (1 - p); + return new Color(rgb, alpha); + }, + greyscale: function (color) { + return colorFunctions.desaturate(color, new Dimension(100)); + }, + contrast: function (color, dark, light, threshold) { + // filter: contrast(3.2); + // should be kept as is, so check for color + if (!color.rgb) { + return null; + } + if (typeof light === 'undefined') { + light = colorFunctions.rgba(255, 255, 255, 1.0); + } + if (typeof dark === 'undefined') { + dark = colorFunctions.rgba(0, 0, 0, 1.0); + } + // Figure out which is actually light and dark: + if (dark.luma() > light.luma()) { + var t = light; + light = dark; + dark = t; + } + if (typeof threshold === 'undefined') { + threshold = 0.43; + } + else { + threshold = number(threshold); + } + if (color.luma() < threshold) { + return light; + } + else { + return dark; + } + }, + // Changes made in 2.7.0 - Reverted in 3.0.0 + // contrast: function (color, color1, color2, threshold) { + // // Return which of `color1` and `color2` has the greatest contrast with `color` + // // according to the standard WCAG contrast ratio calculation. + // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef + // // The threshold param is no longer used, in line with SASS. + // // filter: contrast(3.2); + // // should be kept as is, so check for color + // if (!color.rgb) { + // return null; + // } + // if (typeof color1 === 'undefined') { + // color1 = colorFunctions.rgba(0, 0, 0, 1.0); + // } + // if (typeof color2 === 'undefined') { + // color2 = colorFunctions.rgba(255, 255, 255, 1.0); + // } + // var contrast1, contrast2; + // var luma = color.luma(); + // var luma1 = color1.luma(); + // var luma2 = color2.luma(); + // // Calculate contrast ratios for each color + // if (luma > luma1) { + // contrast1 = (luma + 0.05) / (luma1 + 0.05); + // } else { + // contrast1 = (luma1 + 0.05) / (luma + 0.05); + // } + // if (luma > luma2) { + // contrast2 = (luma + 0.05) / (luma2 + 0.05); + // } else { + // contrast2 = (luma2 + 0.05) / (luma + 0.05); + // } + // if (contrast1 > contrast2) { + // return color1; + // } else { + // return color2; + // } + // }, + argb: function (color) { + return new Anonymous(color.toARGB()); + }, + color: function (c) { + if ((c instanceof Quoted) && + (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) { + var val = c.value.slice(1); + return new Color(val, undefined, "#" + val); + } + if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) { + c.value = undefined; + return c; + } + throw { + type: 'Argument', + message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' + }; + }, + tint: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); + }, + shade: function (color, amount) { + return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); } - - throw { - type: 'Argument', - message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF' - }; - }, - tint: function tint(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount); - }, - shade: function shade(color, amount) { - return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount); - } }; var color = colorFunctions; + // Color Blending // ref: http://www.w3.org/TR/compositing-1 - function colorBlend(mode, color1, color2) { - var ab = color1.alpha; // result - - var // backdrop - cb; - var as = color2.alpha; - var // source - cs; - var ar; - var cr; - var r = []; - ar = as + ab * (1 - as); - - for (var i = 0; i < 3; i++) { - cb = color1.rgb[i] / 255; - cs = color2.rgb[i] / 255; - cr = mode(cb, cs); - - if (ar) { - cr = (as * cs + ab * (cb - as * (cb + cs - cr))) / ar; - } - - r[i] = cr * 255; - } - - return new Color(r, ar); + var ab = color1.alpha; // result + var // backdrop + cb; + var as = color2.alpha; + var // source + cs; + var ar; + var cr; + var r = []; + ar = as + ab * (1 - as); + for (var i_1 = 0; i_1 < 3; i_1++) { + cb = color1.rgb[i_1] / 255; + cs = color2.rgb[i_1] / 255; + cr = mode(cb, cs); + if (ar) { + cr = (as * cs + ab * (cb - + as * (cb + cs - cr))) / ar; + } + r[i_1] = cr * 255; + } + return new Color(r, ar); } - var colorBlendModeFunctions = { - multiply: function multiply(cb, cs) { - return cb * cs; - }, - screen: function screen(cb, cs) { - return cb + cs - cb * cs; - }, - overlay: function overlay(cb, cs) { - cb *= 2; - return cb <= 1 ? colorBlendModeFunctions.multiply(cb, cs) : colorBlendModeFunctions.screen(cb - 1, cs); - }, - softlight: function softlight(cb, cs) { - var d = 1; - var e = cb; - - if (cs > 0.5) { - e = 1; - d = cb > 0.25 ? Math.sqrt(cb) : ((16 * cb - 12) * cb + 4) * cb; + multiply: function (cb, cs) { + return cb * cs; + }, + screen: function (cb, cs) { + return cb + cs - cb * cs; + }, + overlay: function (cb, cs) { + cb *= 2; + return (cb <= 1) ? + colorBlendModeFunctions.multiply(cb, cs) : + colorBlendModeFunctions.screen(cb - 1, cs); + }, + softlight: function (cb, cs) { + var d = 1; + var e = cb; + if (cs > 0.5) { + e = 1; + d = (cb > 0.25) ? Math.sqrt(cb) + : ((16 * cb - 12) * cb + 4) * cb; + } + return cb - (1 - 2 * cs) * e * (d - cb); + }, + hardlight: function (cb, cs) { + return colorBlendModeFunctions.overlay(cs, cb); + }, + difference: function (cb, cs) { + return Math.abs(cb - cs); + }, + exclusion: function (cb, cs) { + return cb + cs - 2 * cb * cs; + }, + // non-w3c functions: + average: function (cb, cs) { + return (cb + cs) / 2; + }, + negation: function (cb, cs) { + return 1 - Math.abs(cb + cs - 1); } - - return cb - (1 - 2 * cs) * e * (d - cb); - }, - hardlight: function hardlight(cb, cs) { - return colorBlendModeFunctions.overlay(cs, cb); - }, - difference: function difference(cb, cs) { - return Math.abs(cb - cs); - }, - exclusion: function exclusion(cb, cs) { - return cb + cs - 2 * cb * cs; - }, - // non-w3c functions: - average: function average(cb, cs) { - return (cb + cs) / 2; - }, - negation: function negation(cb, cs) { - return 1 - Math.abs(cb + cs - 1); - } }; - for (var f in colorBlendModeFunctions) { - if (colorBlendModeFunctions.hasOwnProperty(f)) { - colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); - } + if (colorBlendModeFunctions.hasOwnProperty(f)) { + colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]); + } } var dataUri = (function (environment) { - var fallback = function fallback(functionThis, node) { - return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); - }; - - return { - 'data-uri': function dataUri(mimetypeNode, filePathNode) { - if (!filePathNode) { - filePathNode = mimetypeNode; - mimetypeNode = null; - } - - var mimetype = mimetypeNode && mimetypeNode.value; - var filePath = filePathNode.value; - var currentFileInfo = this.currentFileInfo; - var currentDirectory = currentFileInfo.rewriteUrls ? currentFileInfo.currentDirectory : currentFileInfo.entryPath; - var fragmentStart = filePath.indexOf('#'); - var fragment = ''; - - if (fragmentStart !== -1) { - fragment = filePath.slice(fragmentStart); - filePath = filePath.slice(0, fragmentStart); - } - - var context = clone(this.context); - context.rawBuffer = true; - var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); - - if (!fileManager) { - return fallback(this, filePathNode); - } - - var useBase64 = false; // detect the mimetype if not given - - if (!mimetypeNode) { - mimetype = environment.mimeLookup(filePath); - - if (mimetype === 'image/svg+xml') { - useBase64 = false; - } else { - // use base 64 unless it's an ASCII or UTF-8 format - var charset = environment.charsetLookup(mimetype); - useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; - } - - if (useBase64) { - mimetype += ';base64'; - } - } else { - useBase64 = /;base64$/.test(mimetype); - } - - var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); - - if (!fileSync.contents) { - logger.warn("Skipped data-uri embedding of ".concat(filePath, " because file not found")); - return fallback(this, filePathNode || mimetypeNode); - } - - var buf = fileSync.contents; - - if (useBase64 && !environment.encodeBase64) { - return fallback(this, filePathNode); - } - - buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); - var uri = "data:".concat(mimetype, ",").concat(buf).concat(fragment); - return new URL(new Quoted("\"".concat(uri, "\""), uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); - } - }; + var fallback = function (functionThis, node) { return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); }; + return { 'data-uri': function (mimetypeNode, filePathNode) { + if (!filePathNode) { + filePathNode = mimetypeNode; + mimetypeNode = null; + } + var mimetype = mimetypeNode && mimetypeNode.value; + var filePath = filePathNode.value; + var currentFileInfo = this.currentFileInfo; + var currentDirectory = currentFileInfo.rewriteUrls ? + currentFileInfo.currentDirectory : currentFileInfo.entryPath; + var fragmentStart = filePath.indexOf('#'); + var fragment = ''; + if (fragmentStart !== -1) { + fragment = filePath.slice(fragmentStart); + filePath = filePath.slice(0, fragmentStart); + } + var context = clone(this.context); + context.rawBuffer = true; + var fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true); + if (!fileManager) { + return fallback(this, filePathNode); + } + var useBase64 = false; + // detect the mimetype if not given + if (!mimetypeNode) { + mimetype = environment.mimeLookup(filePath); + if (mimetype === 'image/svg+xml') { + useBase64 = false; + } + else { + // use base 64 unless it's an ASCII or UTF-8 format + var charset = environment.charsetLookup(mimetype); + useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0; + } + if (useBase64) { + mimetype += ';base64'; + } + } + else { + useBase64 = /;base64$/.test(mimetype); + } + var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment); + if (!fileSync.contents) { + logger.warn("Skipped data-uri embedding of " + filePath + " because file not found"); + return fallback(this, filePathNode || mimetypeNode); + } + var buf = fileSync.contents; + if (useBase64 && !environment.encodeBase64) { + return fallback(this, filePathNode); + } + buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf); + var uri = "data:" + mimetype + "," + buf + fragment; + return new URL(new Quoted("\"" + uri + "\"", uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; }); - var getItemsFromNode = function getItemsFromNode(node) { - // handle non-array values as an array of length 1 - // return 'undefined' if index is invalid - var items = Array.isArray(node.value) ? node.value : Array(node); - return items; + var getItemsFromNode = function (node) { + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + var items = Array.isArray(node.value) ? + node.value : Array(node); + return items; }; - var list = { - _SELF: function _SELF(n) { - return n; - }, - extract: function extract(values, index) { - // (1-based index) - index = index.value - 1; - return getItemsFromNode(values)[index]; - }, - length: function length(values) { - return new Dimension(getItemsFromNode(values).length); - }, - - /** - * Creates a Less list of incremental values. - * Modeled after Lodash's range function, also exists natively in PHP - * - * @param {Dimension} [start=1] - * @param {Dimension} end - e.g. 10 or 10px - unit is added to output - * @param {Dimension} [step=1] - */ - range: function range(start, end, step) { - var from; - var to; - var stepValue = 1; - var list = []; - - if (end) { - to = end; - from = start.value; - - if (step) { - stepValue = step.value; - } - } else { - from = 1; - to = start; - } - - for (var i = from; i <= to.value; i += stepValue) { - list.push(new Dimension(i, to.unit)); + _SELF: function (n) { + return n; + }, + extract: function (values, index) { + // (1-based index) + index = index.value - 1; + return getItemsFromNode(values)[index]; + }, + length: function (values) { + return new Dimension(getItemsFromNode(values).length); + }, + /** + * Creates a Less list of incremental values. + * Modeled after Lodash's range function, also exists natively in PHP + * + * @param {Dimension} [start=1] + * @param {Dimension} end - e.g. 10 or 10px - unit is added to output + * @param {Dimension} [step=1] + */ + range: function (start, end, step) { + var from; + var to; + var stepValue = 1; + var list = []; + if (end) { + to = end; + from = start.value; + if (step) { + stepValue = step.value; + } + } + else { + from = 1; + to = start; + } + for (var i_1 = from; i_1 <= to.value; i_1 += stepValue) { + list.push(new Dimension(i_1, to.unit)); + } + return new Expression(list); + }, + each: function (list, rs) { + var rules = []; + var newRules; + var iterator; + if (list.value && !(list instanceof Quoted)) { + if (Array.isArray(list.value)) { + iterator = list.value; + } + else { + iterator = [list.value]; + } + } + else if (list.ruleset) { + iterator = list.ruleset.rules; + } + else if (list.rules) { + iterator = list.rules; + } + else if (Array.isArray(list)) { + iterator = list; + } + else { + iterator = [list]; + } + var valueName = '@value'; + var keyName = '@key'; + var indexName = '@index'; + if (rs.params) { + valueName = rs.params[0] && rs.params[0].name; + keyName = rs.params[1] && rs.params[1].name; + indexName = rs.params[2] && rs.params[2].name; + rs = rs.rules; + } + else { + rs = rs.ruleset; + } + for (var i_2 = 0; i_2 < iterator.length; i_2++) { + var key = void 0; + var value = void 0; + var item = iterator[i_2]; + if (item instanceof Declaration) { + key = typeof item.name === 'string' ? item.name : item.name[0].value; + value = item.value; + } + else { + key = new Dimension(i_2 + 1); + value = item; + } + if (item instanceof Comment) { + continue; + } + newRules = rs.rules.slice(0); + if (valueName) { + newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); + } + if (indexName) { + newRules.push(new Declaration(indexName, new Dimension(i_2 + 1), false, false, this.index, this.currentFileInfo)); + } + if (keyName) { + newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); + } + rules.push(new Ruleset([new (Selector)([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); + } + return new Ruleset([new (Selector)([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); } + }; - return new Expression(list); - }, - each: function each(list, rs) { - var rules = []; - var newRules; - var iterator; - - if (list.value && !(list instanceof Quoted)) { - if (Array.isArray(list.value)) { - iterator = list.value; - } else { - iterator = [list.value]; - } - } else if (list.ruleset) { - iterator = list.ruleset.rules; - } else if (list.rules) { - iterator = list.rules; - } else if (Array.isArray(list)) { - iterator = list; - } else { - iterator = [list]; + var MathHelper = function (fn, unit, n) { + if (!(n instanceof Dimension)) { + throw { type: 'Argument', message: 'argument must be a number' }; } - - var valueName = '@value'; - var keyName = '@key'; - var indexName = '@index'; - - if (rs.params) { - valueName = rs.params[0] && rs.params[0].name; - keyName = rs.params[1] && rs.params[1].name; - indexName = rs.params[2] && rs.params[2].name; - rs = rs.rules; - } else { - rs = rs.ruleset; + if (unit == null) { + unit = n.unit; } - - for (var i = 0; i < iterator.length; i++) { - var key = void 0; - var value = void 0; - var item = iterator[i]; - - if (item instanceof Declaration) { - key = typeof item.name === 'string' ? item.name : item.name[0].value; - value = item.value; - } else { - key = new Dimension(i + 1); - value = item; - } - - if (item instanceof Comment) { - continue; - } - - newRules = rs.rules.slice(0); - - if (valueName) { - newRules.push(new Declaration(valueName, value, false, false, this.index, this.currentFileInfo)); - } - - if (indexName) { - newRules.push(new Declaration(indexName, new Dimension(i + 1), false, false, this.index, this.currentFileInfo)); - } - - if (keyName) { - newRules.push(new Declaration(keyName, key, false, false, this.index, this.currentFileInfo)); - } - - rules.push(new Ruleset([new Selector([new Element("", '&')])], newRules, rs.strictImports, rs.visibilityInfo())); + else { + n = n.unify(); } - - return new Ruleset([new Selector([new Element("", '&')])], rules, rs.strictImports, rs.visibilityInfo()).eval(this.context); - } - }; - - var MathHelper = function MathHelper(fn, unit, n) { - if (!(n instanceof Dimension)) { - throw { - type: 'Argument', - message: 'argument must be a number' - }; - } - - if (unit == null) { - unit = n.unit; - } else { - n = n.unify(); - } - - return new Dimension(fn(parseFloat(n.value)), unit); + return new Dimension(fn(parseFloat(n.value)), unit); }; var mathFunctions = { - // name, unit - ceil: null, - floor: null, - sqrt: null, - abs: null, - tan: '', - sin: '', - cos: '', - atan: 'rad', - asin: 'rad', - acos: 'rad' + // name, unit + ceil: null, + floor: null, + sqrt: null, + abs: null, + tan: '', + sin: '', + cos: '', + atan: 'rad', + asin: 'rad', + acos: 'rad' }; - for (var f$1 in mathFunctions) { - if (mathFunctions.hasOwnProperty(f$1)) { - mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); - } + if (mathFunctions.hasOwnProperty(f$1)) { + mathFunctions[f$1] = MathHelper.bind(null, Math[f$1], mathFunctions[f$1]); + } } - mathFunctions.round = function (n, f) { - var fraction = typeof f === 'undefined' ? 0 : f.value; - return MathHelper(function (num) { - return num.toFixed(fraction); - }, null, n); + var fraction = typeof f === 'undefined' ? 0 : f.value; + return MathHelper(function (num) { return num.toFixed(fraction); }, null, n); }; - var minMax = function minMax(isMin, args) { - args = Array.prototype.slice.call(args); - - switch (args.length) { - case 0: - throw { - type: 'Argument', - message: 'one or more arguments required' - }; - } - - var i; // key is the unit.toString() for unified Dimension values, - - var j; - var current; - var currentUnified; - var referenceUnified; - var unit; - var unitStatic; - var unitClone; - var // elems only contains original argument values. - order = []; - var values = {}; // value is the index into the order array. - - for (i = 0; i < args.length; i++) { - current = args[i]; - - if (!(current instanceof Dimension)) { - if (Array.isArray(args[i].value)) { - Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); - } - - continue; - } - - currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); - unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); - unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; - unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; - j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; - - if (j === undefined) { - if (unitStatic !== undefined && unit !== unitStatic) { - throw { - type: 'Argument', - message: 'incompatible types' - }; - } - - values[unit] = order.length; - order.push(current); - continue; + var minMax = function (isMin, args) { + args = Array.prototype.slice.call(args); + switch (args.length) { + case 0: throw { type: 'Argument', message: 'one or more arguments required' }; + } + var i; // key is the unit.toString() for unified Dimension values, + var j; + var current; + var currentUnified; + var referenceUnified; + var unit; + var unitStatic; + var unitClone; + var // elems only contains original argument values. + order = []; + var values = {}; + // value is the index into the order array. + for (i = 0; i < args.length; i++) { + current = args[i]; + if (!(current instanceof Dimension)) { + if (Array.isArray(args[i].value)) { + Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value)); + } + continue; + } + currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify(); + unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString(); + unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic; + unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone; + j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit]; + if (j === undefined) { + if (unitStatic !== undefined && unit !== unitStatic) { + throw { type: 'Argument', message: 'incompatible types' }; + } + values[unit] = order.length; + order.push(current); + continue; + } + referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); + if (isMin && currentUnified.value < referenceUnified.value || + !isMin && currentUnified.value > referenceUnified.value) { + order[j] = current; + } } - - referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify(); - - if (isMin && currentUnified.value < referenceUnified.value || !isMin && currentUnified.value > referenceUnified.value) { - order[j] = current; + if (order.length == 1) { + return order[0]; } - } - - if (order.length == 1) { - return order[0]; - } - - args = order.map(function (a) { - return a.toCSS(this.context); - }).join(this.context.compress ? ',' : ', '); - return new Anonymous("".concat(isMin ? 'min' : 'max', "(").concat(args, ")")); + args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', '); + return new Anonymous((isMin ? 'min' : 'max') + "(" + args + ")"); }; - var number$1 = { - min: function min() { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return minMax(true, args); - }, - max: function max() { - for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) { - args[_key2] = arguments[_key2]; - } - - return minMax(false, args); - }, - convert: function convert(val, unit) { - return val.convertTo(unit.value); - }, - pi: function pi() { - return new Dimension(Math.PI); - }, - mod: function mod(a, b) { - return new Dimension(a.value % b.value, a.unit); - }, - pow: function pow(x, y) { - if (typeof x === 'number' && typeof y === 'number') { - x = new Dimension(x); - y = new Dimension(y); - } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { - throw { - type: 'Argument', - message: 'arguments must be numbers' - }; + min: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return minMax(true, args); + }, + max: function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return minMax(false, args); + }, + convert: function (val, unit) { + return val.convertTo(unit.value); + }, + pi: function () { + return new Dimension(Math.PI); + }, + mod: function (a, b) { + return new Dimension(a.value % b.value, a.unit); + }, + pow: function (x, y) { + if (typeof x === 'number' && typeof y === 'number') { + x = new Dimension(x); + y = new Dimension(y); + } + else if (!(x instanceof Dimension) || !(y instanceof Dimension)) { + throw { type: 'Argument', message: 'arguments must be numbers' }; + } + return new Dimension(Math.pow(x.value, y.value), x.unit); + }, + percentage: function (n) { + var result = MathHelper(function (num) { return num * 100; }, '%', n); + return result; } - - return new Dimension(Math.pow(x.value, y.value), x.unit); - }, - percentage: function percentage(n) { - var result = MathHelper(function (num) { - return num * 100; - }, '%', n); - return result; - } }; var string = { - e: function e(str) { - return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); - }, - escape: function escape(str) { - return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B').replace(/\(/g, '%28').replace(/\)/g, '%29')); - }, - replace: function replace(string, pattern, replacement, flags) { - var result = string.value; - replacement = replacement.type === 'Quoted' ? replacement.value : replacement.toCSS(); - result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); - return new Quoted(string.quote || '', result, string.escaped); - }, - '%': function _(string - /* arg, arg, ... */ - ) { - var args = Array.prototype.slice.call(arguments, 1); - var result = string.value; - - var _loop = function _loop(i) { - /* jshint loopfunc:true */ - result = result.replace(/%[sda]/i, function (token) { - var value = args[i].type === 'Quoted' && token.match(/s/i) ? args[i].value : args[i].toCSS(); - return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; - }); - }; - - for (var i = 0; i < args.length; i++) { - _loop(i); - } - - result = result.replace(/%%/g, '%'); - return new Quoted(string.quote || '', result, string.escaped); - } - }; - - var svg = (function (environment) { - return { - 'svg-gradient': function svgGradient(direction) { - var stops; - var gradientDirectionSvg; - var gradientType = 'linear'; - var rectangleDimension = 'x="0" y="0" width="1" height="1"'; - var renderEnv = { - compress: false - }; - var returner; - var directionValue = direction.toCSS(renderEnv); - var i; - var color; - var position; - var positionValue; - var alpha; - - function throwArgumentDescriptor() { - throw { - type: 'Argument', - message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + ' end_color [end_position] or direction, color list' + e: function (str) { + return new Quoted('"', str instanceof JavaScript ? str.evaluated : str.value, true); + }, + escape: function (str) { + return new Anonymous(encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B') + .replace(/\(/g, '%28').replace(/\)/g, '%29')); + }, + replace: function (string, pattern, replacement, flags) { + var result = string.value; + replacement = (replacement.type === 'Quoted') ? + replacement.value : replacement.toCSS(); + result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement); + return new Quoted(string.quote || '', result, string.escaped); + }, + '%': function (string /* arg, arg, ... */) { + var args = Array.prototype.slice.call(arguments, 1); + var result = string.value; + var _loop_1 = function (i_1) { + /* jshint loopfunc:true */ + result = result.replace(/%[sda]/i, function (token) { + var value = ((args[i_1].type === 'Quoted') && + token.match(/s/i)) ? args[i_1].value : args[i_1].toCSS(); + return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value; + }); }; - } - - if (arguments.length == 2) { - if (arguments[1].value.length < 2) { - throwArgumentDescriptor(); - } - - stops = arguments[1].value; - } else if (arguments.length < 3) { - throwArgumentDescriptor(); - } else { - stops = Array.prototype.slice.call(arguments, 1); - } - - switch (directionValue) { - case 'to bottom': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; - break; - - case 'to right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; - break; - - case 'to bottom right': - gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; - break; - - case 'to top right': - gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; - break; - - case 'ellipse': - case 'ellipse at center': - gradientType = 'radial'; - gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; - rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; - break; - - default: - throw { - type: 'Argument', - message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' - }; - } - - returner = "<".concat(gradientType, "Gradient id=\"g\" ").concat(gradientDirectionSvg, ">"); - - for (i = 0; i < stops.length; i += 1) { - if (stops[i] instanceof Expression) { - color = stops[i].value[0]; - position = stops[i].value[1]; - } else { - color = stops[i]; - position = undefined; + for (var i_1 = 0; i_1 < args.length; i_1++) { + _loop_1(i_1); } - - if (!(color instanceof Color) || !((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension)) { - throwArgumentDescriptor(); - } - - positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; - alpha = color.alpha; - returner += ""); - } - - returner += ""); - returner = encodeURIComponent(returner); - returner = "data:image/svg+xml,".concat(returner); - return new URL(new Quoted("'".concat(returner, "'"), returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + result = result.replace(/%%/g, '%'); + return new Quoted(string.quote || '', result, string.escaped); } - }; - }); - - var isa = function isa(n, Type) { - return n instanceof Type ? Keyword.True : Keyword.False; }; - var isunit = function isunit(n, unit) { - if (unit === undefined) { - throw { - type: 'Argument', - message: 'missing the required second argument to isunit.' - }; - } - - unit = typeof unit.value === 'string' ? unit.value : unit; - - if (typeof unit !== 'string') { - throw { - type: 'Argument', - message: 'Second argument to isunit should be a unit or a string.' - }; - } + var svg = (function (environment) { + return { 'svg-gradient': function (direction) { + var stops; + var gradientDirectionSvg; + var gradientType = 'linear'; + var rectangleDimension = 'x="0" y="0" width="1" height="1"'; + var renderEnv = { compress: false }; + var returner; + var directionValue = direction.toCSS(renderEnv); + var i; + var color; + var position; + var positionValue; + var alpha; + function throwArgumentDescriptor() { + throw { type: 'Argument', + message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' + + ' end_color [end_position] or direction, color list' }; + } + if (arguments.length == 2) { + if (arguments[1].value.length < 2) { + throwArgumentDescriptor(); + } + stops = arguments[1].value; + } + else if (arguments.length < 3) { + throwArgumentDescriptor(); + } + else { + stops = Array.prototype.slice.call(arguments, 1); + } + switch (directionValue) { + case 'to bottom': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"'; + break; + case 'to right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"'; + break; + case 'to bottom right': + gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"'; + break; + case 'to top right': + gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"'; + break; + case 'ellipse': + case 'ellipse at center': + gradientType = 'radial'; + gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"'; + rectangleDimension = 'x="-50" y="-50" width="101" height="101"'; + break; + default: + throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' + + ' \'to bottom right\', \'to top right\' or \'ellipse at center\'' }; + } + returner = "<" + gradientType + "Gradient id=\"g\" " + gradientDirectionSvg + ">"; + for (i = 0; i < stops.length; i += 1) { + if (stops[i] instanceof Expression) { + color = stops[i].value[0]; + position = stops[i].value[1]; + } + else { + color = stops[i]; + position = undefined; + } + if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) { + throwArgumentDescriptor(); + } + positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%'; + alpha = color.alpha; + returner += ""; + } + returner += ""; + returner = encodeURIComponent(returner); + returner = "data:image/svg+xml," + returner; + return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo); + } }; + }); - return n instanceof Dimension && n.unit.is(unit) ? Keyword.True : Keyword.False; + var isa = function (n, Type) { return (n instanceof Type) ? Keyword.True : Keyword.False; }; + var isunit = function (n, unit) { + if (unit === undefined) { + throw { type: 'Argument', message: 'missing the required second argument to isunit.' }; + } + unit = typeof unit.value === 'string' ? unit.value : unit; + if (typeof unit !== 'string') { + throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' }; + } + return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False; }; - var types = { - isruleset: function isruleset(n) { - return isa(n, DetachedRuleset); - }, - iscolor: function iscolor(n) { - return isa(n, Color); - }, - isnumber: function isnumber(n) { - return isa(n, Dimension); - }, - isstring: function isstring(n) { - return isa(n, Quoted); - }, - iskeyword: function iskeyword(n) { - return isa(n, Keyword); - }, - isurl: function isurl(n) { - return isa(n, URL); - }, - ispixel: function ispixel(n) { - return isunit(n, 'px'); - }, - ispercentage: function ispercentage(n) { - return isunit(n, '%'); - }, - isem: function isem(n) { - return isunit(n, 'em'); - }, - isunit: isunit, - unit: function unit(val, _unit) { - if (!(val instanceof Dimension)) { - throw { - type: 'Argument', - message: "the first argument to unit must be a number".concat(val instanceof Operation ? '. Have you forgotten parenthesis?' : '') - }; - } - - if (_unit) { - if (_unit instanceof Keyword) { - _unit = _unit.value; - } else { - _unit = _unit.toCSS(); - } - } else { - _unit = ''; + isruleset: function (n) { + return isa(n, DetachedRuleset); + }, + iscolor: function (n) { + return isa(n, Color); + }, + isnumber: function (n) { + return isa(n, Dimension); + }, + isstring: function (n) { + return isa(n, Quoted); + }, + iskeyword: function (n) { + return isa(n, Keyword); + }, + isurl: function (n) { + return isa(n, URL); + }, + ispixel: function (n) { + return isunit(n, 'px'); + }, + ispercentage: function (n) { + return isunit(n, '%'); + }, + isem: function (n) { + return isunit(n, 'em'); + }, + isunit: isunit, + unit: function (val, unit) { + if (!(val instanceof Dimension)) { + throw { type: 'Argument', + message: "the first argument to unit must be a number" + (val instanceof Operation ? '. Have you forgotten parenthesis?' : '') }; + } + if (unit) { + if (unit instanceof Keyword) { + unit = unit.value; + } + else { + unit = unit.toCSS(); + } + } + else { + unit = ''; + } + return new Dimension(val.value, unit); + }, + 'get-unit': function (n) { + return new Anonymous(n.unit); } - - return new Dimension(val.value, _unit); - }, - 'get-unit': function getUnit(n) { - return new Anonymous(n.unit); - } }; var Functions = (function (environment) { - var functions = { - functionRegistry: functionRegistry, - functionCaller: functionCaller - }; // register functions - - functionRegistry.addMultiple(boolean$1); - functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); - functionRegistry.addMultiple(color); - functionRegistry.addMultiple(colorBlend); - functionRegistry.addMultiple(dataUri(environment)); - functionRegistry.addMultiple(list); - functionRegistry.addMultiple(mathFunctions); - functionRegistry.addMultiple(number$1); - functionRegistry.addMultiple(string); - functionRegistry.addMultiple(svg()); - functionRegistry.addMultiple(types); - return functions; + var functions = { functionRegistry: functionRegistry, functionCaller: functionCaller }; + // register functions + functionRegistry.addMultiple(boolean$1); + functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc)); + functionRegistry.addMultiple(color); + functionRegistry.addMultiple(colorBlend); + functionRegistry.addMultiple(dataUri(environment)); + functionRegistry.addMultiple(list); + functionRegistry.addMultiple(mathFunctions); + functionRegistry.addMultiple(number$1); + functionRegistry.addMultiple(string); + functionRegistry.addMultiple(svg()); + functionRegistry.addMultiple(types); + return functions; }); var sourceMapOutput = (function (environment) { - var SourceMapOutput = - /*#__PURE__*/ - function () { - function SourceMapOutput(options) { - _classCallCheck(this, SourceMapOutput); - - this._css = []; - this._rootNode = options.rootNode; - this._contentsMap = options.contentsMap; - this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; - - if (options.sourceMapFilename) { - this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); - } - - this._outputFilename = options.outputFilename; - this.sourceMapURL = options.sourceMapURL; - - if (options.sourceMapBasepath) { - this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); - } - - if (options.sourceMapRootpath) { - this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); - - if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { - this._sourceMapRootpath += '/'; - } - } else { - this._sourceMapRootpath = ''; - } - - this._outputSourceFiles = options.outputSourceFiles; - this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); - this._lineNumber = 0; - this._column = 0; - } - - _createClass(SourceMapOutput, [{ - key: "removeBasepath", - value: function removeBasepath(path) { - if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { - path = path.substring(this._sourceMapBasepath.length); - - if (path.charAt(0) === '\\' || path.charAt(0) === '/') { - path = path.substring(1); - } - } - - return path; - } - }, { - key: "normalizeFilename", - value: function normalizeFilename(filename) { - filename = filename.replace(/\\/g, '/'); - filename = this.removeBasepath(filename); - return (this._sourceMapRootpath || '') + filename; - } - }, { - key: "add", - value: function add(chunk, fileInfo, index, mapLines) { - // ignore adding empty strings - if (!chunk) { - return; - } - - var lines; - var sourceLines; - var columns; - var sourceColumns; - var i; - - if (fileInfo && fileInfo.filename) { - var inputSource = this._contentsMap[fileInfo.filename]; // remove vars/banner added to the top of the file - - if (this._contentsIgnoredCharsMap[fileInfo.filename]) { - // adjust the index - index -= this._contentsIgnoredCharsMap[fileInfo.filename]; - - if (index < 0) { - index = 0; - } // adjust the source - - - inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); - } // ignore empty content - - - if (inputSource === undefined) { - return; - } - - inputSource = inputSource.substring(0, index); - sourceLines = inputSource.split('\n'); - sourceColumns = sourceLines[sourceLines.length - 1]; - } - - lines = chunk.split('\n'); - columns = lines[lines.length - 1]; - - if (fileInfo && fileInfo.filename) { - if (!mapLines) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + 1, - column: this._column - }, - original: { - line: sourceLines.length, - column: sourceColumns.length - }, - source: this.normalizeFilename(fileInfo.filename) - }); - } else { - for (i = 0; i < lines.length; i++) { - this._sourceMapGenerator.addMapping({ - generated: { - line: this._lineNumber + i + 1, - column: i === 0 ? this._column : 0 - }, - original: { - line: sourceLines.length + i, - column: i === 0 ? sourceColumns.length : 0 - }, - source: this.normalizeFilename(fileInfo.filename) - }); + var SourceMapOutput = /** @class */ (function () { + function SourceMapOutput(options) { + this._css = []; + this._rootNode = options.rootNode; + this._contentsMap = options.contentsMap; + this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap; + if (options.sourceMapFilename) { + this._sourceMapFilename = options.sourceMapFilename.replace(/\\/g, '/'); } - } - } - - if (lines.length === 1) { - this._column += columns.length; - } else { - this._lineNumber += lines.length - 1; - this._column = columns.length; - } - - this._css.push(chunk); - } - }, { - key: "isEmpty", - value: function isEmpty() { - return this._css.length === 0; - } - }, { - key: "toCSS", - value: function toCSS(context) { - this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ - file: this._outputFilename, - sourceRoot: null - }); - - if (this._outputSourceFiles) { - for (var filename in this._contentsMap) { - if (this._contentsMap.hasOwnProperty(filename)) { - var source = this._contentsMap[filename]; - - if (this._contentsIgnoredCharsMap[filename]) { - source = source.slice(this._contentsIgnoredCharsMap[filename]); - } - - this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + this._outputFilename = options.outputFilename; + this.sourceMapURL = options.sourceMapURL; + if (options.sourceMapBasepath) { + this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\/g, '/'); } - } - } - - this._rootNode.genCSS(context, this); - - if (this._css.length > 0) { - var sourceMapURL; - var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); - - if (this.sourceMapURL) { - sourceMapURL = this.sourceMapURL; - } else if (this._sourceMapFilename) { - sourceMapURL = this._sourceMapFilename; - } - - this.sourceMapURL = sourceMapURL; - this.sourceMap = sourceMapContent; - } - - return this._css.join(''); - } - }]); - + if (options.sourceMapRootpath) { + this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\/g, '/'); + if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') { + this._sourceMapRootpath += '/'; + } + } + else { + this._sourceMapRootpath = ''; + } + this._outputSourceFiles = options.outputSourceFiles; + this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator(); + this._lineNumber = 0; + this._column = 0; + } + SourceMapOutput.prototype.removeBasepath = function (path) { + if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) { + path = path.substring(this._sourceMapBasepath.length); + if (path.charAt(0) === '\\' || path.charAt(0) === '/') { + path = path.substring(1); + } + } + return path; + }; + SourceMapOutput.prototype.normalizeFilename = function (filename) { + filename = filename.replace(/\\/g, '/'); + filename = this.removeBasepath(filename); + return (this._sourceMapRootpath || '') + filename; + }; + SourceMapOutput.prototype.add = function (chunk, fileInfo, index, mapLines) { + // ignore adding empty strings + if (!chunk) { + return; + } + var lines; + var sourceLines; + var columns; + var sourceColumns; + var i; + if (fileInfo && fileInfo.filename) { + var inputSource = this._contentsMap[fileInfo.filename]; + // remove vars/banner added to the top of the file + if (this._contentsIgnoredCharsMap[fileInfo.filename]) { + // adjust the index + index -= this._contentsIgnoredCharsMap[fileInfo.filename]; + if (index < 0) { + index = 0; + } + // adjust the source + inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]); + } + // ignore empty content + if (inputSource === undefined) { + return; + } + inputSource = inputSource.substring(0, index); + sourceLines = inputSource.split('\n'); + sourceColumns = sourceLines[sourceLines.length - 1]; + } + lines = chunk.split('\n'); + columns = lines[lines.length - 1]; + if (fileInfo && fileInfo.filename) { + if (!mapLines) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column }, + original: { line: sourceLines.length, column: sourceColumns.length }, + source: this.normalizeFilename(fileInfo.filename) }); + } + else { + for (i = 0; i < lines.length; i++) { + this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0 }, + original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0 }, + source: this.normalizeFilename(fileInfo.filename) }); + } + } + } + if (lines.length === 1) { + this._column += columns.length; + } + else { + this._lineNumber += lines.length - 1; + this._column = columns.length; + } + this._css.push(chunk); + }; + SourceMapOutput.prototype.isEmpty = function () { + return this._css.length === 0; + }; + SourceMapOutput.prototype.toCSS = function (context) { + this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null }); + if (this._outputSourceFiles) { + for (var filename in this._contentsMap) { + if (this._contentsMap.hasOwnProperty(filename)) { + var source = this._contentsMap[filename]; + if (this._contentsIgnoredCharsMap[filename]) { + source = source.slice(this._contentsIgnoredCharsMap[filename]); + } + this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source); + } + } + } + this._rootNode.genCSS(context, this); + if (this._css.length > 0) { + var sourceMapURL = void 0; + var sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON()); + if (this.sourceMapURL) { + sourceMapURL = this.sourceMapURL; + } + else if (this._sourceMapFilename) { + sourceMapURL = this._sourceMapFilename; + } + this.sourceMapURL = sourceMapURL; + this.sourceMap = sourceMapContent; + } + return this._css.join(''); + }; + return SourceMapOutput; + }()); return SourceMapOutput; - }(); - - return SourceMapOutput; - }); - - var sourceMapBuilder = (function (SourceMapOutput, environment) { - var SourceMapBuilder = - /*#__PURE__*/ - function () { - function SourceMapBuilder(options) { - _classCallCheck(this, SourceMapBuilder); - - this.options = options; - } - - _createClass(SourceMapBuilder, [{ - key: "toCSS", - value: function toCSS(rootNode, options, imports) { - var sourceMapOutput = new SourceMapOutput({ - contentsIgnoredCharsMap: imports.contentsIgnoredChars, - rootNode: rootNode, - contentsMap: imports.contents, - sourceMapFilename: this.options.sourceMapFilename, - sourceMapURL: this.options.sourceMapURL, - outputFilename: this.options.sourceMapOutputFilename, - sourceMapBasepath: this.options.sourceMapBasepath, - sourceMapRootpath: this.options.sourceMapRootpath, - outputSourceFiles: this.options.outputSourceFiles, - sourceMapGenerator: this.options.sourceMapGenerator, - sourceMapFileInline: this.options.sourceMapFileInline - }); - var css = sourceMapOutput.toCSS(options); - this.sourceMap = sourceMapOutput.sourceMap; - this.sourceMapURL = sourceMapOutput.sourceMapURL; - - if (this.options.sourceMapInputFilename) { - this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); - } - - if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { - this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); - } - - return css + this.getCSSAppendage(); - } - }, { - key: "getCSSAppendage", - value: function getCSSAppendage() { - var sourceMapURL = this.sourceMapURL; + }); - if (this.options.sourceMapFileInline) { - if (this.sourceMap === undefined) { + var sourceMapBuilder = (function (SourceMapOutput, environment) { + var SourceMapBuilder = /** @class */ (function () { + function SourceMapBuilder(options) { + this.options = options; + } + SourceMapBuilder.prototype.toCSS = function (rootNode, options, imports) { + var sourceMapOutput = new SourceMapOutput({ + contentsIgnoredCharsMap: imports.contentsIgnoredChars, + rootNode: rootNode, + contentsMap: imports.contents, + sourceMapFilename: this.options.sourceMapFilename, + sourceMapURL: this.options.sourceMapURL, + outputFilename: this.options.sourceMapOutputFilename, + sourceMapBasepath: this.options.sourceMapBasepath, + sourceMapRootpath: this.options.sourceMapRootpath, + outputSourceFiles: this.options.outputSourceFiles, + sourceMapGenerator: this.options.sourceMapGenerator, + sourceMapFileInline: this.options.sourceMapFileInline + }); + var css = sourceMapOutput.toCSS(options); + this.sourceMap = sourceMapOutput.sourceMap; + this.sourceMapURL = sourceMapOutput.sourceMapURL; + if (this.options.sourceMapInputFilename) { + this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename); + } + if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) { + this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL); + } + return css + this.getCSSAppendage(); + }; + SourceMapBuilder.prototype.getCSSAppendage = function () { + var sourceMapURL = this.sourceMapURL; + if (this.options.sourceMapFileInline) { + if (this.sourceMap === undefined) { + return ''; + } + sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap); + } + if (sourceMapURL) { + return "/*# sourceMappingURL=" + sourceMapURL + " */"; + } return ''; - } - - sourceMapURL = "data:application/json;base64,".concat(environment.encodeBase64(this.sourceMap)); - } - - if (sourceMapURL) { - return "/*# sourceMappingURL=".concat(sourceMapURL, " */"); - } - - return ''; - } - }, { - key: "getExternalSourceMap", - value: function getExternalSourceMap() { - return this.sourceMap; - } - }, { - key: "setExternalSourceMap", - value: function setExternalSourceMap(sourceMap) { - this.sourceMap = sourceMap; - } - }, { - key: "isInline", - value: function isInline() { - return this.options.sourceMapFileInline; - } - }, { - key: "getSourceMapURL", - value: function getSourceMapURL() { - return this.sourceMapURL; - } - }, { - key: "getOutputFilename", - value: function getOutputFilename() { - return this.options.sourceMapOutputFilename; - } - }, { - key: "getInputFilename", - value: function getInputFilename() { - return this.sourceMapInputFilename; - } - }]); - + }; + SourceMapBuilder.prototype.getExternalSourceMap = function () { + return this.sourceMap; + }; + SourceMapBuilder.prototype.setExternalSourceMap = function (sourceMap) { + this.sourceMap = sourceMap; + }; + SourceMapBuilder.prototype.isInline = function () { + return this.options.sourceMapFileInline; + }; + SourceMapBuilder.prototype.getSourceMapURL = function () { + return this.sourceMapURL; + }; + SourceMapBuilder.prototype.getOutputFilename = function () { + return this.options.sourceMapOutputFilename; + }; + SourceMapBuilder.prototype.getInputFilename = function () { + return this.sourceMapInputFilename; + }; + return SourceMapBuilder; + }()); return SourceMapBuilder; - }(); - - return SourceMapBuilder; }); - var transformTree = (function (root) { - var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; - var evaldRoot; - var variables = options.variables; - var evalEnv = new contexts.Eval(options); // - // Allows setting variables with a hash, so: - // - // `{ color: new tree.Color('#f01') }` will become: - // - // new tree.Declaration('@color', - // new tree.Value([ - // new tree.Expression([ - // new tree.Color('#f01') - // ]) - // ]) - // ) - // - - if (_typeof(variables) === 'object' && !Array.isArray(variables)) { - variables = Object.keys(variables).map(function (k) { - var value = variables[k]; - - if (!(value instanceof tree.Value)) { - if (!(value instanceof tree.Expression)) { - value = new tree.Expression([value]); + var transformTree = (function (root, options) { + if (options === void 0) { options = {}; } + var evaldRoot; + var variables = options.variables; + var evalEnv = new contexts.Eval(options); + // + // Allows setting variables with a hash, so: + // + // `{ color: new tree.Color('#f01') }` will become: + // + // new tree.Declaration('@color', + // new tree.Value([ + // new tree.Expression([ + // new tree.Color('#f01') + // ]) + // ]) + // ) + // + if (typeof variables === 'object' && !Array.isArray(variables)) { + variables = Object.keys(variables).map(function (k) { + var value = variables[k]; + if (!(value instanceof tree.Value)) { + if (!(value instanceof tree.Expression)) { + value = new tree.Expression([value]); + } + value = new tree.Value([value]); + } + return new tree.Declaration("@" + k, value, false, null, 0); + }); + evalEnv.frames = [new tree.Ruleset(null, variables)]; + } + var visitors$1 = [ + new visitors.JoinSelectorVisitor(), + new visitors.MarkVisibleSelectorsVisitor(true), + new visitors.ExtendVisitor(), + new visitors.ToCSSVisitor({ compress: Boolean(options.compress) }) + ]; + var preEvalVisitors = []; + var v; + var visitorIterator; + /** + * first() / get() allows visitors to be added while visiting + * + * @todo Add scoping for visitors just like functions for @plugin; right now they're global + */ + if (options.pluginManager) { + visitorIterator = options.pluginManager.visitor(); + for (var i = 0; i < 2; i++) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (v.isPreEvalVisitor) { + if (i === 0 || preEvalVisitors.indexOf(v) === -1) { + preEvalVisitors.push(v); + v.run(root); + } + } + else { + if (i === 0 || visitors$1.indexOf(v) === -1) { + if (v.isPreVisitor) { + visitors$1.unshift(v); + } + else { + visitors$1.push(v); + } + } + } + } } - - value = new tree.Value([value]); - } - - return new tree.Declaration("@".concat(k), value, false, null, 0); - }); - evalEnv.frames = [new tree.Ruleset(null, variables)]; - } - - var visitors$1 = [new visitors.JoinSelectorVisitor(), new visitors.MarkVisibleSelectorsVisitor(true), new visitors.ExtendVisitor(), new visitors.ToCSSVisitor({ - compress: Boolean(options.compress) - })]; - var preEvalVisitors = []; - var v; - var visitorIterator; - /** - * first() / get() allows visitors to be added while visiting - * - * @todo Add scoping for visitors just like functions for @plugin; right now they're global - */ - - if (options.pluginManager) { - visitorIterator = options.pluginManager.visitor(); - - for (var i = 0; i < 2; i++) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (v.isPreEvalVisitor) { - if (i === 0 || preEvalVisitors.indexOf(v) === -1) { - preEvalVisitors.push(v); - v.run(root); - } - } else { - if (i === 0 || visitors$1.indexOf(v) === -1) { - if (v.isPreVisitor) { - visitors$1.unshift(v); - } else { - visitors$1.push(v); - } - } - } - } - } - } - - evaldRoot = root.eval(evalEnv); - - for (var i = 0; i < visitors$1.length; i++) { - visitors$1[i].run(evaldRoot); - } // Run any remaining visitors added after eval pass - - - if (options.pluginManager) { - visitorIterator.first(); - - while (v = visitorIterator.get()) { - if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { - v.run(evaldRoot); - } } - } - - return evaldRoot; - }); - - var parseTree = (function (SourceMapBuilder) { - var ParseTree = - /*#__PURE__*/ - function () { - function ParseTree(root, imports) { - _classCallCheck(this, ParseTree); - - this.root = root; - this.imports = imports; + evaldRoot = root.eval(evalEnv); + for (var i = 0; i < visitors$1.length; i++) { + visitors$1[i].run(evaldRoot); } - - _createClass(ParseTree, [{ - key: "toCSS", - value: function toCSS(options) { - var evaldRoot; - var result = {}; - var sourceMapBuilder; - - try { - evaldRoot = transformTree(this.root, options); - } catch (e) { - throw new LessError(e, this.imports); - } - - try { - var compress = Boolean(options.compress); - - if (compress) { - logger.warn('The compress option has been deprecated. ' + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); - } - - var toCSSOptions = { - compress: compress, - dumpLineNumbers: options.dumpLineNumbers, - strictUnits: Boolean(options.strictUnits), - numPrecision: 8 - }; - - if (options.sourceMap) { - sourceMapBuilder = new SourceMapBuilder(options.sourceMap); - result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); - } else { - result.css = evaldRoot.toCSS(toCSSOptions); - } - } catch (e) { - throw new LessError(e, this.imports); - } - - if (options.pluginManager) { - var postProcessors = options.pluginManager.getPostProcessors(); - - for (var i = 0; i < postProcessors.length; i++) { - result.css = postProcessors[i].process(result.css, { - sourceMap: sourceMapBuilder, - options: options, - imports: this.imports - }); - } - } - - if (options.sourceMap) { - result.map = sourceMapBuilder.getExternalSourceMap(); - } - - result.imports = []; - - for (var file in this.imports.files) { - if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) { - result.imports.push(file); - } + // Run any remaining visitors added after eval pass + if (options.pluginManager) { + visitorIterator.first(); + while ((v = visitorIterator.get())) { + if (visitors$1.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) { + v.run(evaldRoot); + } } - - return result; - } - }]); - - return ParseTree; - }(); - - return ParseTree; - }); - - var importManager = (function (environment) { - // FileInfo = { - // 'rewriteUrls' - option - whether to adjust URL's to be relative - // 'filename' - full resolved filename of current file - // 'rootpath' - path to append to normal URLs for this node - // 'currentDirectory' - path to the current file, absolute - // 'rootFilename' - filename of the base file - // 'entryPath' - absolute path to the entry file - // 'reference' - whether the file should not be output and only output parts that are referenced - var ImportManager = - /*#__PURE__*/ - function () { - function ImportManager(less, context, rootFileInfo) { - _classCallCheck(this, ImportManager); - - this.less = less; - this.rootFilename = rootFileInfo.filename; - this.paths = context.paths || []; // Search paths, when importing - - this.contents = {}; // map - filename to contents of all the files - - this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore - - this.mime = context.mime; - this.error = null; - this.context = context; // Deprecated? Unused outside of here, could be useful. - - this.queue = []; // Files which haven't been imported yet - - this.files = {}; // Holds the imported parse trees. } - /** - * Add an import to be imported - * @param path - the raw path - * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) - * @param currentFileInfo - the current file info (used for instance to work out relative paths) - * @param importOptions - import options - * @param callback - callback for when it is imported - */ - - - _createClass(ImportManager, [{ - key: "push", - value: function push(path, tryAppendExtension, currentFileInfo, importOptions, callback) { - var importManager = this; - var pluginLoader = this.context.pluginManager.Loader; - this.queue.push(path); - - var fileParsedFunc = function fileParsedFunc(e, root, fullPath) { - importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue - - var importedEqualsRoot = fullPath === importManager.rootFilename; + return evaldRoot; + }); - if (importOptions.optional && e) { - callback(null, { - rules: [] - }, false, null); - logger.info("The file ".concat(fullPath, " was skipped because it was not found and the import was marked optional.")); - } else { - // Inline imports aren't cached here. - // If we start to cache them, please make sure they won't conflict with non-inline imports of the - // same name as they used to do before this comment and the condition below have been added. - if (!importManager.files[fullPath] && !importOptions.inline) { - importManager.files[fullPath] = { - root: root, - options: importOptions - }; + var parseTree = (function (SourceMapBuilder) { + var ParseTree = /** @class */ (function () { + function ParseTree(root, imports) { + this.root = root; + this.imports = imports; + } + ParseTree.prototype.toCSS = function (options) { + var evaldRoot; + var result = {}; + var sourceMapBuilder; + try { + evaldRoot = transformTree(this.root, options); } - - if (e && !importManager.error) { - importManager.error = e; + catch (e) { + throw new LessError(e, this.imports); } - - callback(e, root, importedEqualsRoot, fullPath); - } - }; - - var newFileInfo = { - rewriteUrls: this.context.rewriteUrls, - entryPath: currentFileInfo.entryPath, - rootpath: currentFileInfo.rootpath, - rootFilename: currentFileInfo.rootFilename + try { + var compress = Boolean(options.compress); + if (compress) { + logger.warn('The compress option has been deprecated. ' + + 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.'); + } + var toCSSOptions = { + compress: compress, + dumpLineNumbers: options.dumpLineNumbers, + strictUnits: Boolean(options.strictUnits), + numPrecision: 8 + }; + if (options.sourceMap) { + sourceMapBuilder = new SourceMapBuilder(options.sourceMap); + result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports); + } + else { + result.css = evaldRoot.toCSS(toCSSOptions); + } + } + catch (e) { + throw new LessError(e, this.imports); + } + if (options.pluginManager) { + var postProcessors = options.pluginManager.getPostProcessors(); + for (var i_1 = 0; i_1 < postProcessors.length; i_1++) { + result.css = postProcessors[i_1].process(result.css, { sourceMap: sourceMapBuilder, options: options, imports: this.imports }); + } + } + if (options.sourceMap) { + result.map = sourceMapBuilder.getExternalSourceMap(); + } + result.imports = []; + for (var file_1 in this.imports.files) { + if (this.imports.files.hasOwnProperty(file_1) && file_1 !== this.imports.rootFilename) { + result.imports.push(file_1); + } + } + return result; }; - var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + return ParseTree; + }()); + return ParseTree; + }); - if (!fileManager) { - fileParsedFunc({ - message: "Could not find a file-manager for ".concat(path) - }); - return; + var importManager = (function (environment) { + // FileInfo = { + // 'rewriteUrls' - option - whether to adjust URL's to be relative + // 'filename' - full resolved filename of current file + // 'rootpath' - path to append to normal URLs for this node + // 'currentDirectory' - path to the current file, absolute + // 'rootFilename' - filename of the base file + // 'entryPath' - absolute path to the entry file + // 'reference' - whether the file should not be output and only output parts that are referenced + var ImportManager = /** @class */ (function () { + function ImportManager(less, context, rootFileInfo) { + this.less = less; + this.rootFilename = rootFileInfo.filename; + this.paths = context.paths || []; // Search paths, when importing + this.contents = {}; // map - filename to contents of all the files + this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore + this.mime = context.mime; + this.error = null; + this.context = context; + // Deprecated? Unused outside of here, could be useful. + this.queue = []; // Files which haven't been imported yet + this.files = {}; // Holds the imported parse trees. } - - var loadFileCallback = function loadFileCallback(loadedFile) { - var plugin; - var resolvedFilename = loadedFile.filename; - var contents = loadedFile.contents.replace(/^\uFEFF/, ''); // Pass on an updated rootpath if path of imported file is relative and file - // is in a (sub|sup) directory - // - // Examples: - // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', - // then rootpath should become 'less/module/nav/' - // - If path of imported file is '../mixins.less' and rootpath is 'less/', - // then rootpath should become 'less/../' - - newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); - - if (newFileInfo.rewriteUrls) { - newFileInfo.rootpath = fileManager.join(importManager.context.rootpath || '', fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); - - if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { - newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + /** + * Add an import to be imported + * @param path - the raw path + * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension) + * @param currentFileInfo - the current file info (used for instance to work out relative paths) + * @param importOptions - import options + * @param callback - callback for when it is imported + */ + ImportManager.prototype.push = function (path, tryAppendExtension, currentFileInfo, importOptions, callback) { + var importManager = this; + var pluginLoader = this.context.pluginManager.Loader; + this.queue.push(path); + var fileParsedFunc = function (e, root, fullPath) { + importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue + var importedEqualsRoot = fullPath === importManager.rootFilename; + if (importOptions.optional && e) { + callback(null, { rules: [] }, false, null); + logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional."); + } + else { + // Inline imports aren't cached here. + // If we start to cache them, please make sure they won't conflict with non-inline imports of the + // same name as they used to do before this comment and the condition below have been added. + if (!importManager.files[fullPath] && !importOptions.inline) { + importManager.files[fullPath] = { root: root, options: importOptions }; + } + if (e && !importManager.error) { + importManager.error = e; + } + callback(e, root, importedEqualsRoot, fullPath); + } + }; + var newFileInfo = { + rewriteUrls: this.context.rewriteUrls, + entryPath: currentFileInfo.entryPath, + rootpath: currentFileInfo.rootpath, + rootFilename: currentFileInfo.rootFilename + }; + var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment); + if (!fileManager) { + fileParsedFunc({ message: "Could not find a file-manager for " + path }); + return; + } + var loadFileCallback = function (loadedFile) { + var plugin; + var resolvedFilename = loadedFile.filename; + var contents = loadedFile.contents.replace(/^\uFEFF/, ''); + // Pass on an updated rootpath if path of imported file is relative and file + // is in a (sub|sup) directory + // + // Examples: + // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/', + // then rootpath should become 'less/module/nav/' + // - If path of imported file is '../mixins.less' and rootpath is 'less/', + // then rootpath should become 'less/../' + newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename); + if (newFileInfo.rewriteUrls) { + newFileInfo.rootpath = fileManager.join((importManager.context.rootpath || ''), fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath)); + if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) { + newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath); + } + } + newFileInfo.filename = resolvedFilename; + var newEnv = new contexts.Parse(importManager.context); + newEnv.processImports = false; + importManager.contents[resolvedFilename] = contents; + if (currentFileInfo.reference || importOptions.reference) { + newFileInfo.reference = true; + } + if (importOptions.isPlugin) { + plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); + if (plugin instanceof LessError) { + fileParsedFunc(plugin, null, resolvedFilename); + } + else { + fileParsedFunc(null, plugin, resolvedFilename); + } + } + else if (importOptions.inline) { + fileParsedFunc(null, contents, resolvedFilename); + } + else { + // import (multiple) parse trees apparently get altered and can't be cached. + // TODO: investigate why this is + if (importManager.files[resolvedFilename] + && !importManager.files[resolvedFilename].options.multiple + && !importOptions.multiple) { + fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); + } + else { + new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { + fileParsedFunc(e, root, resolvedFilename); + }); + } + } + }; + var promise; + var context = clone(this.context); + if (tryAppendExtension) { + context.ext = importOptions.isPlugin ? '.js' : '.less'; + } + if (importOptions.isPlugin) { + context.mime = 'application/javascript'; + promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); + } + else { + promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { + if (err) { + fileParsedFunc(err); + } + else { + loadFileCallback(loadedFile); + } + }); + } + if (promise) { + promise.then(loadFileCallback, fileParsedFunc); } - } - - newFileInfo.filename = resolvedFilename; - var newEnv = new contexts.Parse(importManager.context); - newEnv.processImports = false; - importManager.contents[resolvedFilename] = contents; - - if (currentFileInfo.reference || importOptions.reference) { - newFileInfo.reference = true; - } - - if (importOptions.isPlugin) { - plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo); - - if (plugin instanceof LessError) { - fileParsedFunc(plugin, null, resolvedFilename); - } else { - fileParsedFunc(null, plugin, resolvedFilename); - } - } else if (importOptions.inline) { - fileParsedFunc(null, contents, resolvedFilename); - } else { - // import (multiple) parse trees apparently get altered and can't be cached. - // TODO: investigate why this is - if (importManager.files[resolvedFilename] && !importManager.files[resolvedFilename].options.multiple && !importOptions.multiple) { - fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename); - } else { - new Parser(newEnv, importManager, newFileInfo).parse(contents, function (e, root) { - fileParsedFunc(e, root, resolvedFilename); - }); - } - } }; - - var promise; - var context = clone(this.context); - - if (tryAppendExtension) { - context.ext = importOptions.isPlugin ? '.js' : '.less'; - } - - if (importOptions.isPlugin) { - context.mime = 'application/javascript'; - promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager); - } else { - promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment, function (err, loadedFile) { - if (err) { - fileParsedFunc(err); - } else { - loadFileCallback(loadedFile); - } - }); - } - - if (promise) { - promise.then(loadFileCallback, fileParsedFunc); - } - } - }]); - + return ImportManager; + }()); return ImportManager; - }(); - - return ImportManager; }); var Render = (function (environment, ParseTree, ImportManager) { - var render = function render(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - render.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - this.parse(input, options, function (err, root, imports, options) { - if (err) { - return callback(err); + var render = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + render.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - - var result; - - try { - var parseTree = new ParseTree(root, imports); - result = parseTree.toCSS(options); - } catch (err) { - return callback(err); + else { + this.parse(input, options, function (err, root, imports, options) { + if (err) { + return callback(err); + } + var result; + try { + var parseTree = new ParseTree(root, imports); + result = parseTree.toCSS(options); + } + catch (err) { + return callback(err); + } + callback(null, result); + }); } - - callback(null, result); - }); - } - }; - - return render; + }; + return render; }); /** * Plugin Manager */ - var PluginManager = - /*#__PURE__*/ - function () { - function PluginManager(less) { - _classCallCheck(this, PluginManager); - - this.less = less; - this.visitors = []; - this.preProcessors = []; - this.postProcessors = []; - this.installedPlugins = []; - this.fileManagers = []; - this.iterator = -1; - this.pluginCache = {}; - this.Loader = new less.PluginLoader(less); - } - /** - * Adds all the plugins in the array - * @param {Array} plugins - */ - - - _createClass(PluginManager, [{ - key: "addPlugins", - value: function addPlugins(plugins) { - if (plugins) { - for (var i = 0; i < plugins.length; i++) { - this.addPlugin(plugins[i]); - } - } + var PluginManager = /** @class */ (function () { + function PluginManager(less) { + this.less = less; + this.visitors = []; + this.preProcessors = []; + this.postProcessors = []; + this.installedPlugins = []; + this.fileManagers = []; + this.iterator = -1; + this.pluginCache = {}; + this.Loader = new less.PluginLoader(less); } + /** + * Adds all the plugins in the array + * @param {Array} plugins + */ + PluginManager.prototype.addPlugins = function (plugins) { + if (plugins) { + for (var i_1 = 0; i_1 < plugins.length; i_1++) { + this.addPlugin(plugins[i_1]); + } + } + }; /** * * @param plugin * @param {String} filename */ - - }, { - key: "addPlugin", - value: function addPlugin(plugin, filename, functionRegistry) { - this.installedPlugins.push(plugin); - - if (filename) { - this.pluginCache[filename] = plugin; - } - - if (plugin.install) { - plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); - } - } + PluginManager.prototype.addPlugin = function (plugin, filename, functionRegistry) { + this.installedPlugins.push(plugin); + if (filename) { + this.pluginCache[filename] = plugin; + } + if (plugin.install) { + plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry); + } + }; /** * * @param filename */ - - }, { - key: "get", - value: function get(filename) { - return this.pluginCache[filename]; - } + PluginManager.prototype.get = function (filename) { + return this.pluginCache[filename]; + }; /** * Adds a visitor. The visitor object has options on itself to determine * when it should run. * @param visitor */ - - }, { - key: "addVisitor", - value: function addVisitor(visitor) { - this.visitors.push(visitor); - } + PluginManager.prototype.addVisitor = function (visitor) { + this.visitors.push(visitor); + }; /** * Adds a pre processor object * @param {object} preProcessor * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import */ - - }, { - key: "addPreProcessor", - value: function addPreProcessor(preProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { - if (this.preProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPreProcessor = function (preProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) { + if (this.preProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.preProcessors.splice(indexToInsertAt, 0, { - preProcessor: preProcessor, - priority: priority - }); - } + this.preProcessors.splice(indexToInsertAt, 0, { preProcessor: preProcessor, priority: priority }); + }; /** * Adds a post processor object * @param {object} postProcessor * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression */ - - }, { - key: "addPostProcessor", - value: function addPostProcessor(postProcessor, priority) { - var indexToInsertAt; - - for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { - if (this.postProcessors[indexToInsertAt].priority >= priority) { - break; + PluginManager.prototype.addPostProcessor = function (postProcessor, priority) { + var indexToInsertAt; + for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) { + if (this.postProcessors[indexToInsertAt].priority >= priority) { + break; + } } - } - - this.postProcessors.splice(indexToInsertAt, 0, { - postProcessor: postProcessor, - priority: priority - }); - } + this.postProcessors.splice(indexToInsertAt, 0, { postProcessor: postProcessor, priority: priority }); + }; /** * * @param manager */ - - }, { - key: "addFileManager", - value: function addFileManager(manager) { - this.fileManagers.push(manager); - } + PluginManager.prototype.addFileManager = function (manager) { + this.fileManagers.push(manager); + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPreProcessors", - value: function getPreProcessors() { - var preProcessors = []; - - for (var i = 0; i < this.preProcessors.length; i++) { - preProcessors.push(this.preProcessors[i].preProcessor); - } - - return preProcessors; - } + PluginManager.prototype.getPreProcessors = function () { + var preProcessors = []; + for (var i_2 = 0; i_2 < this.preProcessors.length; i_2++) { + preProcessors.push(this.preProcessors[i_2].preProcessor); + } + return preProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getPostProcessors", - value: function getPostProcessors() { - var postProcessors = []; - - for (var i = 0; i < this.postProcessors.length; i++) { - postProcessors.push(this.postProcessors[i].postProcessor); - } - - return postProcessors; - } + PluginManager.prototype.getPostProcessors = function () { + var postProcessors = []; + for (var i_3 = 0; i_3 < this.postProcessors.length; i_3++) { + postProcessors.push(this.postProcessors[i_3].postProcessor); + } + return postProcessors; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getVisitors", - value: function getVisitors() { - return this.visitors; - } - }, { - key: "visitor", - value: function visitor() { - var self = this; - return { - first: function first() { - self.iterator = -1; - return self.visitors[self.iterator]; - }, - get: function get() { - self.iterator += 1; - return self.visitors[self.iterator]; - } - }; - } + PluginManager.prototype.getVisitors = function () { + return this.visitors; + }; + PluginManager.prototype.visitor = function () { + var self = this; + return { + first: function () { + self.iterator = -1; + return self.visitors[self.iterator]; + }, + get: function () { + self.iterator += 1; + return self.visitors[self.iterator]; + } + }; + }; /** * * @returns {Array} * @private */ - - }, { - key: "getFileManagers", - value: function getFileManagers() { - return this.fileManagers; - } - }]); - - return PluginManager; - }(); - + PluginManager.prototype.getFileManagers = function () { + return this.fileManagers; + }; + return PluginManager; + }()); var pm; - function PluginManagerFactory(less, newFactory) { - if (newFactory || !pm) { - pm = new PluginManager(less); - } - - return pm; + if (newFactory || !pm) { + pm = new PluginManager(less); + } + return pm; } var Parse = (function (environment, ParseTree, ImportManager) { - var parse = function parse(input, options, callback) { - if (typeof options === 'function') { - callback = options; - options = copyOptions(this.options, {}); - } else { - options = copyOptions(this.options, options || {}); - } - - if (!callback) { - var self = this; - return new Promise(function (resolve, reject) { - parse.call(self, input, options, function (err, output) { - if (err) { - reject(err); - } else { - resolve(output); - } - }); - }); - } else { - var context; - var rootFileInfo; - var pluginManager = new PluginManagerFactory(this, !options.reUsePluginManager); - options.pluginManager = pluginManager; - context = new contexts.Parse(options); - - if (options.rootFileInfo) { - rootFileInfo = options.rootFileInfo; - } else { - var filename = options.filename || 'input'; - var entryPath = filename.replace(/[^\/\\]*$/, ''); - rootFileInfo = { - filename: filename, - rewriteUrls: context.rewriteUrls, - rootpath: context.rootpath || '', - currentDirectory: entryPath, - entryPath: entryPath, - rootFilename: filename - }; // add in a missing trailing slash - - if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { - rootFileInfo.rootpath += '/'; + var parse = function (input, options, callback) { + if (typeof options === 'function') { + callback = options; + options = copyOptions(this.options, {}); + } + else { + options = copyOptions(this.options, options || {}); + } + if (!callback) { + var self_1 = this; + return new Promise(function (resolve, reject) { + parse.call(self_1, input, options, function (err, output) { + if (err) { + reject(err); + } + else { + resolve(output); + } + }); + }); } - } - - var imports = new ImportManager(this, context, rootFileInfo); - this.importManager = imports; // TODO: allow the plugins to be just a list of paths or names - // Do an async plugin queue like lessc - - if (options.plugins) { - options.plugins.forEach(function (plugin) { - var evalResult; - var contents; - - if (plugin.fileContent) { - contents = plugin.fileContent.replace(/^\uFEFF/, ''); - evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename); - - if (evalResult instanceof LessError) { - return callback(evalResult); + else { + var context_1; + var rootFileInfo = void 0; + var pluginManager_1 = new PluginManagerFactory(this, !options.reUsePluginManager); + options.pluginManager = pluginManager_1; + context_1 = new contexts.Parse(options); + if (options.rootFileInfo) { + rootFileInfo = options.rootFileInfo; } - } else { - pluginManager.addPlugin(plugin); - } - }); - } - - new Parser(context, imports, rootFileInfo).parse(input, function (e, root) { - if (e) { - return callback(e); + else { + var filename = options.filename || 'input'; + var entryPath = filename.replace(/[^\/\\]*$/, ''); + rootFileInfo = { + filename: filename, + rewriteUrls: context_1.rewriteUrls, + rootpath: context_1.rootpath || '', + currentDirectory: entryPath, + entryPath: entryPath, + rootFilename: filename + }; + // add in a missing trailing slash + if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') { + rootFileInfo.rootpath += '/'; + } + } + var imports_1 = new ImportManager(this, context_1, rootFileInfo); + this.importManager = imports_1; + // TODO: allow the plugins to be just a list of paths or names + // Do an async plugin queue like lessc + if (options.plugins) { + options.plugins.forEach(function (plugin) { + var evalResult; + var contents; + if (plugin.fileContent) { + contents = plugin.fileContent.replace(/^\uFEFF/, ''); + evalResult = pluginManager_1.Loader.evalPlugin(contents, context_1, imports_1, plugin.options, plugin.filename); + if (evalResult instanceof LessError) { + return callback(evalResult); + } + } + else { + pluginManager_1.addPlugin(plugin); + } + }); + } + new Parser(context_1, imports_1, rootFileInfo) + .parse(input, function (e, root) { + if (e) { + return callback(e); + } + callback(null, root, imports_1, options); + }, options); } - - callback(null, root, imports, options); - }, options); - } - }; - - return parse; + }; + return parse; }); var lessRoot = (function (environment$1, fileManagers) { - /** - * @todo - * This original code could be improved quite a bit. - * Many classes / modules currently add side-effects / mutations to passed in objects, - * which makes it hard to refactor and reason about. - */ - environment$1 = new environment(environment$1, fileManagers); - var SourceMapOutput = sourceMapOutput(environment$1); - var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment$1); - var ParseTree = parseTree(SourceMapBuilder); - var ImportManager = importManager(environment$1); - var render = Render(environment$1, ParseTree); - var parse = Parse(environment$1, ParseTree, ImportManager); - var functions = Functions(environment$1); - /** - * @todo - * This root properties / methods need to be organized. - * It's not clear what should / must be public and why. - */ - - var initial = { - version: [3, 10, 3], - data: data, - tree: tree, - Environment: environment, - AbstractFileManager: AbstractFileManager, - AbstractPluginLoader: AbstractPluginLoader, - environment: environment$1, - visitors: visitors, - Parser: Parser, - functions: functions, - contexts: contexts, - SourceMapOutput: SourceMapOutput, - SourceMapBuilder: SourceMapBuilder, - ParseTree: ParseTree, - ImportManager: ImportManager, - render: render, - parse: parse, - LessError: LessError, - transformTree: transformTree, - utils: utils, - PluginManager: PluginManagerFactory, - logger: logger - }; // Create a public API - - var ctor = function ctor(t) { - return function () { - for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { - args[_key] = arguments[_key]; - } - - return _construct(t, args); + /** + * @todo + * This original code could be improved quite a bit. + * Many classes / modules currently add side-effects / mutations to passed in objects, + * which makes it hard to refactor and reason about. + */ + environment$1 = new environment(environment$1, fileManagers); + var SourceMapOutput = sourceMapOutput(environment$1); + var SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment$1); + var ParseTree = parseTree(SourceMapBuilder); + var ImportManager = importManager(environment$1); + var render = Render(environment$1, ParseTree); + var parse = Parse(environment$1, ParseTree, ImportManager); + var functions = Functions(environment$1); + /** + * @todo + * This root properties / methods need to be organized. + * It's not clear what should / must be public and why. + */ + var initial = { + version: [3, 11, 0], + data: data, + tree: tree, + Environment: environment, + AbstractFileManager: AbstractFileManager, + AbstractPluginLoader: AbstractPluginLoader, + environment: environment$1, + visitors: visitors, + Parser: Parser, + functions: functions, + contexts: contexts, + SourceMapOutput: SourceMapOutput, + SourceMapBuilder: SourceMapBuilder, + ParseTree: ParseTree, + ImportManager: ImportManager, + render: render, + parse: parse, + LessError: LessError, + transformTree: transformTree, + utils: utils, + PluginManager: PluginManagerFactory, + logger: logger }; - }; - - var t; - var api = Object.create(initial); - - for (var n in initial.tree) { - /* eslint guard-for-in: 0 */ - t = initial.tree[n]; - - if (typeof t === 'function') { - api[n.toLowerCase()] = ctor(t); - } else { - api[n] = Object.create(null); - - for (var o in t) { + // Create a public API + var ctor = function (t) { return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + return new (t.bind.apply(t, __spreadArrays([void 0], args)))(); + }; }; + var t; + var api = Object.create(initial); + for (var n in initial.tree) { /* eslint guard-for-in: 0 */ - api[n][o.toLowerCase()] = ctor(t[o]); - } + t = initial.tree[n]; + if (typeof t === 'function') { + api[n.toLowerCase()] = ctor(t); + } + else { + api[n] = Object.create(null); + for (var o in t) { + /* eslint guard-for-in: 0 */ + api[n][o.toLowerCase()] = ctor(t[o]); + } + } } - } - - return api; + return api; }); + /* global window, XMLHttpRequest */ var options; var logger$1; - var fileCache = {}; // TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load - - var FileManager = - /*#__PURE__*/ - function (_AbstractFileManager) { - _inherits(FileManager, _AbstractFileManager); - - function FileManager() { - _classCallCheck(this, FileManager); - - return _possibleConstructorReturn(this, _getPrototypeOf(FileManager).apply(this, arguments)); - } - - _createClass(FileManager, [{ - key: "alwaysMakePathsAbsolute", - value: function alwaysMakePathsAbsolute() { - return true; - } - }, { - key: "join", - value: function join(basePath, laterPath) { - if (!basePath) { - return laterPath; - } - - return this.extractUrlParts(laterPath, basePath).path; - } - }, { - key: "doXHR", - value: function doXHR(url, type, callback, errback) { - var xhr = new XMLHttpRequest(); - var async = options.isFileProtocol ? options.fileAsync : true; - - if (typeof xhr.overrideMimeType === 'function') { - xhr.overrideMimeType('text/css'); - } - - logger$1.debug("XHR: Getting '".concat(url, "'")); - xhr.open('GET', url, async); - xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); - xhr.send(null); - - function handleResponse(xhr, callback, errback) { - if (xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText, xhr.getResponseHeader('Last-Modified')); - } else if (typeof errback === 'function') { - errback(xhr.status, url); + var fileCache = {}; + // TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load + var FileManager = /** @class */ (function (_super) { + __extends(FileManager, _super); + function FileManager() { + return _super !== null && _super.apply(this, arguments) || this; + } + FileManager.prototype.alwaysMakePathsAbsolute = function () { + return true; + }; + FileManager.prototype.getPossibleFileExtensions = function (path, ext) { + if (this.isPathWithExtension(path, ext)) { + return ['']; } - } - - if (options.isFileProtocol && !options.fileAsync) { - if (xhr.status === 0 || xhr.status >= 200 && xhr.status < 300) { - callback(xhr.responseText); - } else { - errback(xhr.status, url); - } - } else if (async) { - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { + // if file doesn't have dot in name it require extention + if (path.indexOf(".") === -1) { + return [ext]; + } + // path has dots in name it might be with or without extention (like .css) + return [ext, '']; + }; + FileManager.prototype.join = function (basePath, laterPath) { + if (!basePath) { + return laterPath; + } + return this.extractUrlParts(laterPath, basePath).path; + }; + FileManager.prototype.doXHR = function (url, type, callback, errback) { + var xhr = new XMLHttpRequest(); + var async = options.isFileProtocol ? options.fileAsync : true; + if (typeof xhr.overrideMimeType === 'function') { + xhr.overrideMimeType('text/css'); + } + logger$1.debug("XHR: Getting '" + url + "'"); + xhr.open('GET', url, async); + xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5'); + xhr.send(null); + function handleResponse(xhr, callback, errback) { + if (xhr.status >= 200 && xhr.status < 300) { + callback(xhr.responseText, xhr.getResponseHeader('Last-Modified')); + } + else if (typeof errback === 'function') { + errback(xhr.status, url); + } + } + if (options.isFileProtocol && !options.fileAsync) { + if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) { + callback(xhr.responseText); + } + else { + errback(xhr.status, url); + } + } + else if (async) { + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + handleResponse(xhr, callback, errback); + } + }; + } + else { handleResponse(xhr, callback, errback); - } - }; - } else { - handleResponse(xhr, callback, errback); - } - } - }, { - key: "supports", - value: function supports() { - return true; - } - }, { - key: "clearFileCache", - value: function clearFileCache() { - fileCache = {}; - } - }, { - key: "loadFile", - value: function loadFile(filename, currentDirectory, options, environment) { - // TODO: Add prefix support like less-node? - // What about multiple paths? - if (currentDirectory && !this.isPathAbsolute(filename)) { - filename = currentDirectory + filename; - } - - filename = options.ext ? this.tryAppendExtension(filename, options.ext) : filename; - options = options || {}; // sheet may be set to the stylesheet for the initial load or a collection of properties including - // some context variables for imports - - var hrefParts = this.extractUrlParts(filename, window.location.href); - var href = hrefParts.url; - var self = this; - return new Promise(function (resolve, reject) { - if (options.useFileCache && fileCache[href]) { - try { - var lessText = fileCache[href]; - return resolve({ - contents: lessText, - filename: href, - webInfo: { - lastModified: new Date() - } - }); - } catch (e) { - return reject({ - filename: href, - message: "Error loading file ".concat(href, " error was ").concat(e.message) - }); - } } - - self.doXHR(href, options.mime, function doXHRCallback(data, lastModified) { - // per file cache - fileCache[href] = data; // Use remote copy (re-parse) - - resolve({ - contents: data, - filename: href, - webInfo: { - lastModified: lastModified - } - }); - }, function doXHRError(status, url) { - reject({ - type: 'File', - message: "'".concat(url, "' wasn't found (").concat(status, ")"), - href: href - }); + }; + FileManager.prototype.tryToLoad = function (href) { + var _this = this; + return new Promise(function (resolve, reject) { + if (options.useFileCache && fileCache[href]) { + try { + var lessText_1 = fileCache[href]; + return resolve({ contents: lessText_1, filename: href, webInfo: { lastModified: new Date() } }); + } + catch (e) { + return reject({ filename: href, message: "Error loading file " + href + " error was " + e.message }); + } + } + _this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) { + // per file cache + fileCache[href] = data; + // Use remote copy (re-parse) + resolve({ contents: data, filename: href, webInfo: { lastModified: lastModified } }); + }, function doXHRError(status, url) { + reject({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href }); + }); }); - }); - } - }]); - - return FileManager; - }(AbstractFileManager); - + }; + FileManager.prototype.supports = function () { + return true; + }; + FileManager.prototype.clearFileCache = function () { + fileCache = {}; + }; + FileManager.prototype.loadFile = function (filename, currentDirectory, options, environment) { + // TODO: Add prefix support like less-node? + // What about multiple paths? + var _this = this; + if (currentDirectory && !this.isPathAbsolute(filename)) { + filename = currentDirectory + filename; + } + var extensions = this.getPossibleFileExtensions(filename, options.ext || ''); + options = options || {}; + // sheet may be set to the stylesheet for the initial load or a collection of properties including + // some context variables for imports + var hrefParts = this.extractUrlParts(filename, window.location.href); + var href = hrefParts.url; + var hrefs = extensions.map(function (ext) { return _this.tryAppendExtension(href, ext); }); + return hrefs.reduce(function (prev, href) { return prev.catch(function () { return _this.tryToLoad(href); }); }, this.tryToLoad(hrefs.shift())); + }; + return FileManager; + }(AbstractFileManager)); var FM = (function (opts, log) { - options = opts; - logger$1 = log; - return FileManager; + options = opts; + logger$1 = log; + return FileManager; }); + // TODO: Add tests for browser @plugin /** * Browser Plugin Loader */ - - var PluginLoader = - /*#__PURE__*/ - function (_AbstractPluginLoader) { - _inherits(PluginLoader, _AbstractPluginLoader); - - function PluginLoader(less) { - var _this; - - _classCallCheck(this, PluginLoader); - - _this = _possibleConstructorReturn(this, _getPrototypeOf(PluginLoader).call(this)); - _this.less = less; // Should we shim this.require for browser? Probably not? - - return _this; - } - - _createClass(PluginLoader, [{ - key: "loadPlugin", - value: function loadPlugin(filename, basePath, context, environment, fileManager) { - return new Promise(function (fulfill, reject) { - fileManager.loadFile(filename, basePath, context, environment).then(fulfill).catch(reject); - }); - } - }]); - - return PluginLoader; - }(AbstractPluginLoader); + var PluginLoader = /** @class */ (function (_super) { + __extends(PluginLoader, _super); + function PluginLoader(less) { + var _this = _super.call(this) || this; + _this.less = less; + return _this; + // Should we shim this.require for browser? Probably not? + } + PluginLoader.prototype.loadPlugin = function (filename, basePath, context, environment, fileManager) { + return new Promise(function (fulfill, reject) { + fileManager.loadFile(filename, basePath, context, environment) + .then(fulfill).catch(reject); + }); + }; + return PluginLoader; + }(AbstractPluginLoader)); var LogListener = (function (less, options) { - var logLevel_debug = 4; - var logLevel_info = 3; - var logLevel_warn = 2; - var logLevel_error = 1; // The amount of logging in the javascript console. - // 3 - Debug, information and errors - // 2 - Information and errors - // 1 - Errors - // 0 - None - // Defaults to 2 - - options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : options.env === 'development' ? logLevel_info : logLevel_error; - - if (!options.loggers) { - options.loggers = [{ - debug: function debug(msg) { - if (options.logLevel >= logLevel_debug) { - console.log(msg); - } - }, - info: function info(msg) { - if (options.logLevel >= logLevel_info) { - console.log(msg); - } - }, - warn: function warn(msg) { - if (options.logLevel >= logLevel_warn) { - console.warn(msg); - } - }, - error: function error(msg) { - if (options.logLevel >= logLevel_error) { - console.error(msg); - } - } - }]; - } - - for (var i = 0; i < options.loggers.length; i++) { - less.logger.addListener(options.loggers[i]); - } + var logLevel_debug = 4; + var logLevel_info = 3; + var logLevel_warn = 2; + var logLevel_error = 1; + // The amount of logging in the javascript console. + // 3 - Debug, information and errors + // 2 - Information and errors + // 1 - Errors + // 0 - None + // Defaults to 2 + options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error); + if (!options.loggers) { + options.loggers = [{ + debug: function (msg) { + if (options.logLevel >= logLevel_debug) { + console.log(msg); + } + }, + info: function (msg) { + if (options.logLevel >= logLevel_info) { + console.log(msg); + } + }, + warn: function (msg) { + if (options.logLevel >= logLevel_warn) { + console.warn(msg); + } + }, + error: function (msg) { + if (options.logLevel >= logLevel_error) { + console.error(msg); + } + } + }]; + } + for (var i_1 = 0; i_1 < options.loggers.length; i_1++) { + less.logger.addListener(options.loggers[i_1]); + } }); var ErrorReporting = (function (window, less, options) { - function errorHTML(e, rootHref) { - var id = "less-error-message:".concat(extractId(rootHref || '')); - var template = '
  • {content}
  • '; - var elem = window.document.createElement('div'); - var timer; - var content; - var errors = []; - var filename = e.filename || rootHref; - var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; - elem.id = id; - elem.className = 'less-error-message'; - content = "

    ".concat(e.type || 'Syntax', "Error: ").concat(e.message || 'There is an error in your .less file') + "

    in ").concat(filenameNoPath, " "); - - var errorline = function errorline(e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)).replace(/\{class\}/, classname).replace(/\{content\}/, e.extract[i])); - } - }; - - if (e.line) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += "on line ".concat(e.line, ", column ").concat(e.column + 1, ":

      ").concat(errors.join(''), "
    "); + function errorHTML(e, rootHref) { + var id = "less-error-message:" + extractId(rootHref || ''); + var template = '
  • {content}
  • '; + var elem = window.document.createElement('div'); + var timer; + var content; + var errors = []; + var filename = e.filename || rootHref; + var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1]; + elem.id = id; + elem.className = 'less-error-message'; + content = "

    " + (e.type || 'Syntax') + "Error: " + (e.message || 'There is an error in your .less file') + + ("

    in " + filenameNoPath + " "); + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + if (e.line) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += "on line " + e.line + ", column " + (e.column + 1) + ":

      " + errors.join('') + "
    "; + } + if (e.stack && (e.extract || options.logLevel >= 4)) { + content += "
    Stack Trace
    " + e.stack.split('\n').slice(1).join('
    '); + } + elem.innerHTML = content; + // CSS for error messages + browser.createCSS(window.document, [ + '.less-error-message ul, .less-error-message li {', + 'list-style-type: none;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'margin: 0;', + '}', + '.less-error-message label {', + 'font-size: 12px;', + 'margin-right: 15px;', + 'padding: 4px 0;', + 'color: #cc7777;', + '}', + '.less-error-message pre {', + 'color: #dd6666;', + 'padding: 4px 0;', + 'margin: 0;', + 'display: inline-block;', + '}', + '.less-error-message pre.line {', + 'color: #ff0000;', + '}', + '.less-error-message h3 {', + 'font-size: 20px;', + 'font-weight: bold;', + 'padding: 15px 0 5px 0;', + 'margin: 0;', + '}', + '.less-error-message a {', + 'color: #10a', + '}', + '.less-error-message .error {', + 'color: red;', + 'font-weight: bold;', + 'padding-bottom: 2px;', + 'border-bottom: 1px dashed red;', + '}' + ].join('\n'), { title: 'error-message' }); + elem.style.cssText = [ + 'font-family: Arial, sans-serif', + 'border: 1px solid #e00', + 'background-color: #eee', + 'border-radius: 5px', + '-webkit-border-radius: 5px', + '-moz-border-radius: 5px', + 'color: #e00', + 'padding: 15px', + 'margin-bottom: 15px' + ].join(';'); + if (options.env === 'development') { + timer = setInterval(function () { + var document = window.document; + var body = document.body; + if (body) { + if (document.getElementById(id)) { + body.replaceChild(elem, document.getElementById(id)); + } + else { + body.insertBefore(elem, body.firstChild); + } + clearInterval(timer); + } + }, 10); + } } - - if (e.stack && (e.extract || options.logLevel >= 4)) { - content += "
    Stack Trace
    ".concat(e.stack.split('\n').slice(1).join('
    ')); + function removeErrorHTML(path) { + var node = window.document.getElementById("less-error-message:" + extractId(path)); + if (node) { + node.parentNode.removeChild(node); + } } - - elem.innerHTML = content; // CSS for error messages - - browser.createCSS(window.document, ['.less-error-message ul, .less-error-message li {', 'list-style-type: none;', 'margin-right: 15px;', 'padding: 4px 0;', 'margin: 0;', '}', '.less-error-message label {', 'font-size: 12px;', 'margin-right: 15px;', 'padding: 4px 0;', 'color: #cc7777;', '}', '.less-error-message pre {', 'color: #dd6666;', 'padding: 4px 0;', 'margin: 0;', 'display: inline-block;', '}', '.less-error-message pre.line {', 'color: #ff0000;', '}', '.less-error-message h3 {', 'font-size: 20px;', 'font-weight: bold;', 'padding: 15px 0 5px 0;', 'margin: 0;', '}', '.less-error-message a {', 'color: #10a', '}', '.less-error-message .error {', 'color: red;', 'font-weight: bold;', 'padding-bottom: 2px;', 'border-bottom: 1px dashed red;', '}'].join('\n'), { - title: 'error-message' - }); - elem.style.cssText = ['font-family: Arial, sans-serif', 'border: 1px solid #e00', 'background-color: #eee', 'border-radius: 5px', '-webkit-border-radius: 5px', '-moz-border-radius: 5px', 'color: #e00', 'padding: 15px', 'margin-bottom: 15px'].join(';'); - - if (options.env === 'development') { - timer = setInterval(function () { - var document = window.document; - var body = document.body; - - if (body) { - if (document.getElementById(id)) { - body.replaceChild(elem, document.getElementById(id)); - } else { - body.insertBefore(elem, body.firstChild); - } - - clearInterval(timer); + function removeError(path) { + if (!options.errorReporting || options.errorReporting === 'html') { + removeErrorHTML(path); + } + else if (options.errorReporting === 'console') ; + else if (typeof options.errorReporting === 'function') { + options.errorReporting('remove', path); } - }, 10); } - } - - function removeErrorHTML(path) { - var node = window.document.getElementById("less-error-message:".concat(extractId(path))); - - if (node) { - node.parentNode.removeChild(node); + function errorConsole(e, rootHref) { + var template = '{line} {content}'; + var filename = e.filename || rootHref; + var errors = []; + var content = (e.type || 'Syntax') + "Error: " + (e.message || 'There is an error in your .less file') + " in " + filename; + var errorline = function (e, i, classname) { + if (e.extract[i] !== undefined) { + errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)) + .replace(/\{class\}/, classname) + .replace(/\{content\}/, e.extract[i])); + } + }; + if (e.line) { + errorline(e, 0, ''); + errorline(e, 1, 'line'); + errorline(e, 2, ''); + content += " on line " + e.line + ", column " + (e.column + 1) + ":\n" + errors.join('\n'); + } + if (e.stack && (e.extract || options.logLevel >= 4)) { + content += "\nStack Trace\n" + e.stack; + } + less.logger.error(content); } - } - - function removeError(path) { - if (!options.errorReporting || options.errorReporting === 'html') { - removeErrorHTML(path); - } else if (options.errorReporting === 'console') ; else if (typeof options.errorReporting === 'function') { - options.errorReporting('remove', path); + function error(e, rootHref) { + if (!options.errorReporting || options.errorReporting === 'html') { + errorHTML(e, rootHref); + } + else if (options.errorReporting === 'console') { + errorConsole(e, rootHref); + } + else if (typeof options.errorReporting === 'function') { + options.errorReporting('add', e, rootHref); + } } - } - - function errorConsole(e, rootHref) { - var template = '{line} {content}'; - var filename = e.filename || rootHref; - var errors = []; - var content = "".concat(e.type || 'Syntax', "Error: ").concat(e.message || 'There is an error in your .less file', " in ").concat(filename); - - var errorline = function errorline(e, i, classname) { - if (e.extract[i] !== undefined) { - errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1)).replace(/\{class\}/, classname).replace(/\{content\}/, e.extract[i])); - } + return { + add: error, + remove: removeError }; - - if (e.line) { - errorline(e, 0, ''); - errorline(e, 1, 'line'); - errorline(e, 2, ''); - content += " on line ".concat(e.line, ", column ").concat(e.column + 1, ":\n").concat(errors.join('\n')); - } - - if (e.stack && (e.extract || options.logLevel >= 4)) { - content += "\nStack Trace\n".concat(e.stack); - } - - less.logger.error(content); - } - - function error(e, rootHref) { - if (!options.errorReporting || options.errorReporting === 'html') { - errorHTML(e, rootHref); - } else if (options.errorReporting === 'console') { - errorConsole(e, rootHref); - } else if (typeof options.errorReporting === 'function') { - options.errorReporting('add', e, rootHref); - } - } - - return { - add: error, - remove: removeError - }; }); // Cache system is a bit outdated and could do with work var Cache = (function (window, options, logger) { - var cache = null; - - if (options.env !== 'development') { - try { - cache = typeof window.localStorage === 'undefined' ? null : window.localStorage; - } catch (_) {} - } - - return { - setCSS: function setCSS(path, lastModified, modifyVars, styles) { - if (cache) { - logger.info("saving ".concat(path, " to cache.")); - + var cache = null; + if (options.env !== 'development') { try { - cache.setItem(path, styles); - cache.setItem("".concat(path, ":timestamp"), lastModified); - - if (modifyVars) { - cache.setItem("".concat(path, ":vars"), JSON.stringify(modifyVars)); - } - } catch (e) { - // TODO - could do with adding more robust error handling - logger.error("failed to save \"".concat(path, "\" to local storage for caching.")); - } - } - }, - getCSS: function getCSS(path, webInfo, modifyVars) { - var css = cache && cache.getItem(path); - var timestamp = cache && cache.getItem("".concat(path, ":timestamp")); - var vars = cache && cache.getItem("".concat(path, ":vars")); - modifyVars = modifyVars || {}; - vars = vars || "{}"; // if not set, treat as the JSON representation of an empty object - - if (timestamp && webInfo.lastModified && new Date(webInfo.lastModified).valueOf() === new Date(timestamp).valueOf() && JSON.stringify(modifyVars) === vars) { - // Use local copy - return css; - } + cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage; + } + catch (_) { } } - }; + return { + setCSS: function (path, lastModified, modifyVars, styles) { + if (cache) { + logger.info("saving " + path + " to cache."); + try { + cache.setItem(path, styles); + cache.setItem(path + ":timestamp", lastModified); + if (modifyVars) { + cache.setItem(path + ":vars", JSON.stringify(modifyVars)); + } + } + catch (e) { + // TODO - could do with adding more robust error handling + logger.error("failed to save \"" + path + "\" to local storage for caching."); + } + } + }, + getCSS: function (path, webInfo, modifyVars) { + var css = cache && cache.getItem(path); + var timestamp = cache && cache.getItem(path + ":timestamp"); + var vars = cache && cache.getItem(path + ":vars"); + modifyVars = modifyVars || {}; + vars = vars || "{}"; // if not set, treat as the JSON representation of an empty object + if (timestamp && webInfo.lastModified && + (new Date(webInfo.lastModified).valueOf() === + new Date(timestamp).valueOf()) && + JSON.stringify(modifyVars) === vars) { + // Use local copy + return css; + } + } + }; }); var ImageSize = (function () { - function _imageSize() { - throw { - type: 'Runtime', - message: 'Image size functions are not supported in browser version of less' - }; - } - - var imageFunctions = { - 'image-size': function imageSize(filePathNode) { - _imageSize(); - - return -1; - }, - 'image-width': function imageWidth(filePathNode) { - _imageSize(); - - return -1; - }, - 'image-height': function imageHeight(filePathNode) { - _imageSize(); - - return -1; + function imageSize() { + throw { + type: 'Runtime', + message: 'Image size functions are not supported in browser version of less' + }; } - }; - functionRegistry.addMultiple(imageFunctions); + var imageFunctions = { + 'image-size': function (filePathNode) { + imageSize(); + return -1; + }, + 'image-width': function (filePathNode) { + imageSize(); + return -1; + }, + 'image-height': function (filePathNode) { + imageSize(); + return -1; + } + }; + functionRegistry.addMultiple(imageFunctions); }); // var root = (function (window, options) { - var document = window.document; - var less = lessRoot(); - less.options = options; - var environment = less.environment; - var FileManager = FM(options, less.logger); - var fileManager = new FileManager(); - environment.addFileManager(fileManager); - less.FileManager = FileManager; - less.PluginLoader = PluginLoader; - LogListener(less, options); - var errors = ErrorReporting(window, less, options); - var cache = less.cache = options.cache || Cache(window, options, less.logger); - ImageSize(less.environment); // Setup user functions - Deprecate? - - if (options.functions) { - less.functions.functionRegistry.addMultiple(options.functions); - } - - var typePattern = /^text\/(x-)?less$/; - - function clone(obj) { - var cloned = {}; - - for (var prop in obj) { - if (obj.hasOwnProperty(prop)) { - cloned[prop] = obj[prop]; - } - } - - return cloned; - } // only really needed for phantom - - - function bind(func, thisArg) { - var curryArgs = Array.prototype.slice.call(arguments, 2); - return function () { - var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0)); - return func.apply(thisArg, args); - }; - } - - function loadStyles(modifyVars) { - var styles = document.getElementsByTagName('style'); - var style; - - for (var i = 0; i < styles.length; i++) { - style = styles[i]; - - if (style.type.match(typePattern)) { - var instanceOptions = clone(options); - instanceOptions.modifyVars = modifyVars; - var lessText = style.innerHTML || ''; - instanceOptions.filename = document.location.href.replace(/#.*$/, ''); - /* jshint loopfunc:true */ - // use closure to store current style - - less.render(lessText, instanceOptions, bind(function (style, e, result) { - if (e) { - errors.add(e, 'inline'); - } else { - style.type = 'text/css'; - - if (style.styleSheet) { - style.styleSheet.cssText = result.css; - } else { - style.innerHTML = result.css; + var document = window.document; + var less = lessRoot(); + less.options = options; + var environment = less.environment; + var FileManager = FM(options, less.logger); + var fileManager = new FileManager(); + environment.addFileManager(fileManager); + less.FileManager = FileManager; + less.PluginLoader = PluginLoader; + LogListener(less, options); + var errors = ErrorReporting(window, less, options); + var cache = less.cache = options.cache || Cache(window, options, less.logger); + ImageSize(less.environment); + // Setup user functions - Deprecate? + if (options.functions) { + less.functions.functionRegistry.addMultiple(options.functions); + } + var typePattern = /^text\/(x-)?less$/; + function clone(obj) { + var cloned = {}; + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cloned[prop] = obj[prop]; } - } - }, null, style)); - } + } + return cloned; } - } - - function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { - var instanceOptions = clone(options); - addDataAttr(instanceOptions, sheet); - instanceOptions.mime = sheet.type; - - if (modifyVars) { - instanceOptions.modifyVars = modifyVars; + // only really needed for phantom + function bind(func, thisArg) { + var curryArgs = Array.prototype.slice.call(arguments, 2); + return function () { + var args = curryArgs.concat(Array.prototype.slice.call(arguments, 0)); + return func.apply(thisArg, args); + }; } - - function loadInitialFileCallback(loadedFile) { - var data = loadedFile.contents; - var path = loadedFile.filename; - var webInfo = loadedFile.webInfo; - var newFileInfo = { - currentDirectory: fileManager.getPath(path), - filename: path, - rootFilename: path, - rewriteUrls: instanceOptions.rewriteUrls - }; - newFileInfo.entryPath = newFileInfo.currentDirectory; - newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory; - - if (webInfo) { - webInfo.remaining = remaining; - var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars); - - if (!reload && css) { - webInfo.local = true; - callback(null, css, data, sheet, webInfo, path); - return; - } - } // TODO add tests around how this behaves when reloading - - - errors.remove(path); - instanceOptions.rootFileInfo = newFileInfo; - less.render(data, instanceOptions, function (e, result) { - if (e) { - e.href = path; - callback(e); - } else { - cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css); - callback(null, result.css, data, sheet, webInfo, path); + function loadStyles(modifyVars) { + var styles = document.getElementsByTagName('style'); + var style; + for (var i_1 = 0; i_1 < styles.length; i_1++) { + style = styles[i_1]; + if (style.type.match(typePattern)) { + var instanceOptions = clone(options); + instanceOptions.modifyVars = modifyVars; + var lessText_1 = style.innerHTML || ''; + instanceOptions.filename = document.location.href.replace(/#.*$/, ''); + /* jshint loopfunc:true */ + // use closure to store current style + less.render(lessText_1, instanceOptions, bind(function (style, e, result) { + if (e) { + errors.add(e, 'inline'); + } + else { + style.type = 'text/css'; + if (style.styleSheet) { + style.styleSheet.cssText = result.css; + } + else { + style.innerHTML = result.css; + } + } + }, null, style)); + } } - }); } - - fileManager.loadFile(sheet.href, null, instanceOptions, environment).then(function (loadedFile) { - loadInitialFileCallback(loadedFile); - }).catch(function (err) { - console.log(err); - callback(err); - }); - } - - function loadStyleSheets(callback, reload, modifyVars) { - for (var i = 0; i < less.sheets.length; i++) { - loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars); - } - } - - function initRunningMode() { - if (less.env === 'development') { - less.watchTimer = setInterval(function () { - if (less.watchMode) { - fileManager.clearFileCache(); - loadStyleSheets(function (e, css, _, sheet, webInfo) { - if (e) { - errors.add(e, e.href || sheet.href); - } else if (css) { - browser.createCSS(window.document, css, sheet); - } - }); - } - }, options.poll); - } - } // - // Watch mode - // - - - less.watch = function () { - if (!less.watchMode) { - less.env = 'development'; - initRunningMode(); + function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) { + var instanceOptions = clone(options); + addDataAttr(instanceOptions, sheet); + instanceOptions.mime = sheet.type; + if (modifyVars) { + instanceOptions.modifyVars = modifyVars; + } + function loadInitialFileCallback(loadedFile) { + var data = loadedFile.contents; + var path = loadedFile.filename; + var webInfo = loadedFile.webInfo; + var newFileInfo = { + currentDirectory: fileManager.getPath(path), + filename: path, + rootFilename: path, + rewriteUrls: instanceOptions.rewriteUrls + }; + newFileInfo.entryPath = newFileInfo.currentDirectory; + newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory; + if (webInfo) { + webInfo.remaining = remaining; + var css = cache.getCSS(path, webInfo, instanceOptions.modifyVars); + if (!reload && css) { + webInfo.local = true; + callback(null, css, data, sheet, webInfo, path); + return; + } + } + // TODO add tests around how this behaves when reloading + errors.remove(path); + instanceOptions.rootFileInfo = newFileInfo; + less.render(data, instanceOptions, function (e, result) { + if (e) { + e.href = path; + callback(e); + } + else { + cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css); + callback(null, result.css, data, sheet, webInfo, path); + } + }); + } + fileManager.loadFile(sheet.href, null, instanceOptions, environment) + .then(function (loadedFile) { + loadInitialFileCallback(loadedFile); + }).catch(function (err) { + console.log(err); + callback(err); + }); } - - this.watchMode = true; - return true; - }; - - less.unwatch = function () { - clearInterval(less.watchTimer); - this.watchMode = false; - return false; - }; // - // Synchronously get all tags with the 'rel' attribute set to - // "stylesheet/less". - // - - - less.registerStylesheetsImmediately = function () { - var links = document.getElementsByTagName('link'); - less.sheets = []; - - for (var i = 0; i < links.length; i++) { - if (links[i].rel === 'stylesheet/less' || links[i].rel.match(/stylesheet/) && links[i].type.match(typePattern)) { - less.sheets.push(links[i]); - } - } - }; // - // Asynchronously get all tags with the 'rel' attribute set to - // "stylesheet/less", returning a Promise. - // - - - less.registerStylesheets = function () { - return new Promise(function (resolve, reject) { - less.registerStylesheetsImmediately(); - resolve(); - }); - }; // - // With this function, it's possible to alter variables and re-render - // CSS without reloading less-files - // - - - less.modifyVars = function (record) { - return less.refresh(true, record, false); - }; - - less.refresh = function (reload, modifyVars, clearFileCache) { - if ((reload || clearFileCache) && clearFileCache !== false) { - fileManager.clearFileCache(); + function loadStyleSheets(callback, reload, modifyVars) { + for (var i_2 = 0; i_2 < less.sheets.length; i_2++) { + loadStyleSheet(less.sheets[i_2], callback, reload, less.sheets.length - (i_2 + 1), modifyVars); + } + } + function initRunningMode() { + if (less.env === 'development') { + less.watchTimer = setInterval(function () { + if (less.watchMode) { + fileManager.clearFileCache(); + loadStyleSheets(function (e, css, _, sheet, webInfo) { + if (e) { + errors.add(e, e.href || sheet.href); + } + else if (css) { + browser.createCSS(window.document, css, sheet); + } + }); + } + }, options.poll); + } } - - return new Promise(function (resolve, reject) { - var startTime; - var endTime; - var totalMilliseconds; - var remainingSheets; - startTime = endTime = new Date(); // Set counter for remaining unprocessed sheets - - remainingSheets = less.sheets.length; - - if (remainingSheets === 0) { - endTime = new Date(); - totalMilliseconds = endTime - startTime; - less.logger.info('Less has finished and no sheets were loaded.'); - resolve({ - startTime: startTime, - endTime: endTime, - totalMilliseconds: totalMilliseconds, - sheets: less.sheets.length + // + // Watch mode + // + less.watch = function () { + if (!less.watchMode) { + less.env = 'development'; + initRunningMode(); + } + this.watchMode = true; + return true; + }; + less.unwatch = function () { clearInterval(less.watchTimer); this.watchMode = false; return false; }; + // + // Synchronously get all tags with the 'rel' attribute set to + // "stylesheet/less". + // + less.registerStylesheetsImmediately = function () { + var links = document.getElementsByTagName('link'); + less.sheets = []; + for (var i_3 = 0; i_3 < links.length; i_3++) { + if (links[i_3].rel === 'stylesheet/less' || (links[i_3].rel.match(/stylesheet/) && + (links[i_3].type.match(typePattern)))) { + less.sheets.push(links[i_3]); + } + } + }; + // + // Asynchronously get all tags with the 'rel' attribute set to + // "stylesheet/less", returning a Promise. + // + less.registerStylesheets = function () { return new Promise(function (resolve, reject) { + less.registerStylesheetsImmediately(); + resolve(); + }); }; + // + // With this function, it's possible to alter variables and re-render + // CSS without reloading less-files + // + less.modifyVars = function (record) { return less.refresh(true, record, false); }; + less.refresh = function (reload, modifyVars, clearFileCache) { + if ((reload || clearFileCache) && clearFileCache !== false) { + fileManager.clearFileCache(); + } + return new Promise(function (resolve, reject) { + var startTime; + var endTime; + var totalMilliseconds; + var remainingSheets; + startTime = endTime = new Date(); + // Set counter for remaining unprocessed sheets + remainingSheets = less.sheets.length; + if (remainingSheets === 0) { + endTime = new Date(); + totalMilliseconds = endTime - startTime; + less.logger.info('Less has finished and no sheets were loaded.'); + resolve({ + startTime: startTime, + endTime: endTime, + totalMilliseconds: totalMilliseconds, + sheets: less.sheets.length + }); + } + else { + // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array + loadStyleSheets(function (e, css, _, sheet, webInfo) { + if (e) { + errors.add(e, e.href || sheet.href); + reject(e); + return; + } + if (webInfo.local) { + less.logger.info("Loading " + sheet.href + " from cache."); + } + else { + less.logger.info("Rendered " + sheet.href + " successfully."); + } + browser.createCSS(window.document, css, sheet); + less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + "ms"); + // Count completed sheet + remainingSheets--; + // Check if the last remaining sheet was processed and then call the promise + if (remainingSheets === 0) { + totalMilliseconds = new Date() - startTime; + less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + "ms"); + resolve({ + startTime: startTime, + endTime: endTime, + totalMilliseconds: totalMilliseconds, + sheets: less.sheets.length + }); + } + endTime = new Date(); + }, reload, modifyVars); + } + loadStyles(modifyVars); }); - } else { - // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array - loadStyleSheets(function (e, css, _, sheet, webInfo) { - if (e) { - errors.add(e, e.href || sheet.href); - reject(e); - return; - } - - if (webInfo.local) { - less.logger.info("Loading ".concat(sheet.href, " from cache.")); - } else { - less.logger.info("Rendered ".concat(sheet.href, " successfully.")); - } - - browser.createCSS(window.document, css, sheet); - less.logger.info("CSS for ".concat(sheet.href, " generated in ").concat(new Date() - endTime, "ms")); // Count completed sheet - - remainingSheets--; // Check if the last remaining sheet was processed and then call the promise - - if (remainingSheets === 0) { - totalMilliseconds = new Date() - startTime; - less.logger.info("Less has finished. CSS generated in ".concat(totalMilliseconds, "ms")); - resolve({ - startTime: startTime, - endTime: endTime, - totalMilliseconds: totalMilliseconds, - sheets: less.sheets.length - }); - } - - endTime = new Date(); - }, reload, modifyVars); - } - - loadStyles(modifyVars); - }); - }; - - less.refreshStyles = loadStyles; - return less; + }; + less.refreshStyles = loadStyles; + return less; }); /** @@ -14269,63 +11518,54 @@ * to kick-start less using the browser api */ var options$1 = defaultOptions(); - if (window.less) { - for (var key in window.less) { - if (window.less.hasOwnProperty(key)) { - options$1[key] = window.less[key]; + for (var key in window.less) { + if (window.less.hasOwnProperty(key)) { + options$1[key] = window.less[key]; + } } - } } - addDefaultOptions(window, options$1); options$1.plugins = options$1.plugins || []; - if (window.LESS_PLUGINS) { - options$1.plugins = options$1.plugins.concat(window.LESS_PLUGINS); + options$1.plugins = options$1.plugins.concat(window.LESS_PLUGINS); } - var less = root(window, options$1); window.less = less; var css; var head; - var style; // Always restore page visibility - + var style; + // Always restore page visibility function resolveOrReject(data) { - if (data.filename) { - console.warn(data); - } - - if (!options$1.async) { - head.removeChild(style); - } + if (data.filename) { + console.warn(data); + } + if (!options$1.async) { + head.removeChild(style); + } } - if (options$1.onReady) { - if (/!watch/.test(window.location.hash)) { - less.watch(); - } // Simulate synchronous stylesheet loading by hiding page rendering - - - if (!options$1.async) { - css = 'body { display: none !important }'; - head = document.head || document.getElementsByTagName('head')[0]; - style = document.createElement('style'); - style.type = 'text/css'; - - if (style.styleSheet) { - style.styleSheet.cssText = css; - } else { - style.appendChild(document.createTextNode(css)); + if (/!watch/.test(window.location.hash)) { + less.watch(); } - - head.appendChild(style); - } - - less.registerStylesheetsImmediately(); - less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject); + // Simulate synchronous stylesheet loading by hiding page rendering + if (!options$1.async) { + css = 'body { display: none !important }'; + head = document.head || document.getElementsByTagName('head')[0]; + style = document.createElement('style'); + style.type = 'text/css'; + if (style.styleSheet) { + style.styleSheet.cssText = css; + } + else { + style.appendChild(document.createTextNode(css)); + } + head.appendChild(style); + } + less.registerStylesheetsImmediately(); + less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject); } return less; -})); +}))); diff --git a/dist/less.min.js b/dist/less.min.js index 5472db1a0..63a97e29e 100644 --- a/dist/less.min.js +++ b/dist/less.min.js @@ -1,11 +1,11 @@ /** - * Less - Leaner CSS v3.10.3 + * Less - Leaner CSS v3.11.0 * http://lesscss.org * - * Copyright (c) 2009-2019, Alexis Sellier + * Copyright (c) 2009-2020, Alexis Sellier * Licensed under the Apache-2.0 License. * * @license Apache-2.0 */ -!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):(e=e||self).less=t()}(this,function(){"use strict";function e(e){return e.replace(/^[a-z-]+:\/+?[^\/]+/,"").replace(/[\?\&]livereload=\w+/,"").replace(/^\//,"").replace(/\.[a-zA-Z]+$/,"").replace(/[^\.\w-]+/g,"-").replace(/\./g,":")}function t(e,t){for(var n in t.dataset)if(t.dataset.hasOwnProperty(n))if("env"===n||"dumpLineNumbers"===n||"rootpath"===n||"errorReporting"===n)e[n]=t.dataset[n];else try{e[n]=JSON.parse(t.dataset[n])}catch(e){}}var n={createCSS:function(t,n,i){var r=i.href||"",a="less:".concat(i.title||e(r)),s=t.getElementById(a),o=!1,l=t.createElement("style");l.setAttribute("type","text/css"),i.media&&l.setAttribute("media",i.media),l.id=a,l.styleSheet||(l.appendChild(t.createTextNode(n)),o=null!==s&&s.childNodes.length>0&&l.childNodes.length>0&&s.firstChild.nodeValue===l.firstChild.nodeValue);var u=t.getElementsByTagName("head")[0];if(null===s||!1===o){var c=i&&i.nextSibling||null;c?c.parentNode.insertBefore(l,c):u.appendChild(l)}if(s&&!1===o&&s.parentNode.removeChild(s),l.styleSheet)try{l.styleSheet.cssText=n}catch(e){throw new Error("Couldn't reassign styleSheet.cssText.")}},currentScript:function(e){var t,n=e.document;return n.currentScript||(t=n.getElementsByTagName("script"))[t.length-1]}};function i(e){return(i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){for(var n=0;nt?1:void 0};var y=function(e){function t(e,n,i){var a;r(this,t);var s=h(a=f(this,l(t).call(this)));return Array.isArray(e)?a.rgb=e:e.length>=6?(a.rgb=[],e.match(/.{2}/g).map(function(e,t){t<3?s.rgb.push(parseInt(e,16)):s.alpha=parseInt(e,16)/255})):(a.rgb=[],e.split("").map(function(e,t){t<3?s.rgb.push(parseInt(e+e,16)):s.alpha=parseInt(e+e,16)/255})),a.alpha=a.alpha||("number"==typeof n?n:1),void 0!==i&&(a.value=i),a}return o(t,g),s(t,[{key:"luma",value:function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255;return.2126*(e=e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4))+.7152*(t=t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4))+.0722*(n=n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}},{key:"genCSS",value:function(e,t){t.add(this.toCSS(e))}},{key:"toCSS",value:function(e,t){var n,i,r,a=e&&e.compress&&!t,s=[];if(i=this.fround(e,this.alpha),this.value)if(0===this.value.indexOf("rgb"))i<1&&(r="rgba");else{if(0!==this.value.indexOf("hsl"))return this.value;r=i<1?"hsla":"hsl"}else i<1&&(r="rgba");switch(r){case"rgba":s=this.rgb.map(function(e){return b(Math.round(e),255)}).concat(b(i,1));break;case"hsla":s.push(b(i,1));case"hsl":n=this.toHSL(),s=[this.fround(e,n.h),"".concat(this.fround(e,100*n.s),"%"),"".concat(this.fround(e,100*n.l),"%")].concat(s)}if(r)return"".concat(r,"(").concat(s.join(",".concat(a?"":" ")),")");if(n=this.toRGB(),a){var o=n.split("");o[1]===o[2]&&o[3]===o[4]&&o[5]===o[6]&&(n="#".concat(o[1]).concat(o[3]).concat(o[5]))}return n}},{key:"operate",value:function(e,n,i){for(var r=new Array(3),a=this.alpha*(1-i.alpha)+i.alpha,s=0;s<3;s++)r[s]=this._operate(e,n,this.rgb[s],i.rgb[s]);return new t(r,a)}},{key:"toRGB",value:function(){return w(this.rgb)}},{key:"toHSL",value:function(){var e,t,n=this.rgb[0]/255,i=this.rgb[1]/255,r=this.rgb[2]/255,a=this.alpha,s=Math.max(n,i,r),o=Math.min(n,i,r),l=(s+o)/2,u=s-o;if(s===o)e=t=0;else{switch(t=l>.5?u/(2-s-o):u/(s+o),s){case n:e=(i-r)/u+(i0&&void 0!==arguments[0]?arguments[0]:{},t=this.value,n=e.firstSelector;return t instanceof k&&(e.firstSelector=!0),t=t.toCSS?t.toCSS(e):t,e.firstSelector=n,""===t&&"&"===this.combinator.value.charAt(0)?"":this.combinator.toCSS(e)+t}}]),t}();I.prototype.type="Element";var C={ALWAYS:0,PARENS_DIVISION:1,PARENS:2,STRICT_LEGACY:3},_={OFF:0,LOCAL:1,ALL:2};var A=function(e,t){return e(t={exports:{}},t.exports),t.exports}(function(e){var t=function(){function e(e,t){return null!=t&&e instanceof t}var t,n,i;try{t=Map}catch(e){t=function(){}}try{n=Set}catch(e){n=function(){}}try{i=Promise}catch(e){i=function(){}}function r(a,o,l,u,c){"object"==typeof o&&(l=o.depth,u=o.prototype,c=o.includeNonEnumerable,o=o.circular);var h=[],f=[],p="undefined"!=typeof Buffer;return void 0===o&&(o=!0),void 0===l&&(l=1/0),function a(l,v){if(null===l)return null;if(0===v)return l;var d,m;if("object"!=typeof l)return l;if(e(l,t))d=new t;else if(e(l,n))d=new n;else if(e(l,i))d=new i(function(e,t){l.then(function(t){e(a(t,v-1))},function(e){t(a(e,v-1))})});else if(r.__isArray(l))d=[];else if(r.__isRegExp(l))d=new RegExp(l.source,s(l)),l.lastIndex&&(d.lastIndex=l.lastIndex);else if(r.__isDate(l))d=new Date(l.getTime());else{if(p&&Buffer.isBuffer(l))return d=Buffer.allocUnsafe?Buffer.allocUnsafe(l.length):new Buffer(l.length),l.copy(d),d;e(l,Error)?d=Object.create(l):void 0===u?(m=Object.getPrototypeOf(l),d=Object.create(m)):(d=Object.create(u),m=u)}if(o){var g=h.indexOf(l);if(-1!=g)return f[g];h.push(l),f.push(d)}for(var y in e(l,t)&&l.forEach(function(e,t){var n=a(t,v-1),i=a(e,v-1);d.set(n,i)}),e(l,n)&&l.forEach(function(e){var t=a(e,v-1);d.add(t)}),l){var b;m&&(b=Object.getOwnPropertyDescriptor(m,y)),b&&null==b.set||(d[y]=a(l[y],v-1))}if(Object.getOwnPropertySymbols){var w=Object.getOwnPropertySymbols(l);for(y=0;y=0&&"\n"!==t.charAt(n);)r++;return"number"==typeof e&&(i=(t.slice(0,e).match(/\n/g)||"").length),{line:i,column:r}}function P(e){var t,n=e.length,i=new Array(n);for(t=0;t1&&void 0!==arguments[1]?arguments[1]:[],n=0,i=e.length;n|Function):(\d+):(\d+)/);c&&(c[2]&&(this.line=parseInt(c[2])-2),c[3]&&(this.column=parseInt(c[3])))}this.callLine=l+1,this.callExtract=u[l],this.extract=[u[this.line-2],u[this.line-1],u[this.line]]}};if(void 0===Object.create){var L=function(){};L.prototype=Error.prototype,$.prototype=new L}else $.prototype=Object.create(Error.prototype);$.prototype.constructor=$,$.prototype.toString=function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t="",n=this.extract||[],r=[],a=function(e){return e};if(e.stylize){var s=i(e.stylize);if("function"!==s)throw Error("options.stylize should be a function, got a ".concat(s,"!"));a=e.stylize}if(null!==this.line){if("string"==typeof n[0]&&r.push(a("".concat(this.line-1," ").concat(n[0]),"grey")),"string"==typeof n[1]){var o="".concat(this.line," ");n[1]&&(o+=n[1].slice(0,this.column)+a(a(a(n[1].substr(this.column,1),"bold")+n[1].slice(this.column+1),"red"),"inverse")),r.push(o)}"string"==typeof n[2]&&r.push(a("".concat(this.line+1," ").concat(n[2]),"grey")),r="".concat(r.join("\n")+a("","reset"),"\n")}return t+=a("".concat(this.type,"Error: ").concat(this.message),"red"),this.filename&&(t+=a(" in ","red")+this.filename),this.line&&(t+=a(" on line ".concat(this.line,", column ").concat(this.column+1,":"),"grey")),t+="\n".concat(r),this.callLine&&(t+="".concat(a("from ","red")+(this.filename||""),"/n"),t+="".concat(a(this.callLine,"grey")," ").concat(this.callExtract,"/n")),t};var D=function(e){function t(e,n,i,a,s,o){var u;return r(this,t),(u=f(this,l(t).call(this))).extendList=n,u.condition=i,u.evaldCondition=!i,u._index=a,u._fileInfo=s,u.elements=u.getElements(e),u.mixinElements_=void 0,u.copyVisibilityInfo(o),u.setParent(u.elements,h(u)),u}return o(t,g),s(t,[{key:"accept",value:function(e){this.elements&&(this.elements=e.visitArray(this.elements)),this.extendList&&(this.extendList=e.visitArray(this.extendList)),this.condition&&(this.condition=e.visit(this.condition))}},{key:"createDerived",value:function(e,n,i){var r=new t(e=this.getElements(e),n||this.extendList,null,this.getIndex(),this.fileInfo(),this.visibilityInfo());return r.evaldCondition=null!=i?i:this.evaldCondition,r.mediaEmpty=this.mediaEmpty,r}},{key:"getElements",value:function(e){return e?("string"==typeof e&&this.parse.parseNode(e,["selector"],this._index,this._fileInfo,function(t,n){if(t)throw new $({index:t.index,message:t.message},this.parse.imports,this._fileInfo.filename);e=n[0].elements}),e):[new I("","&",!1,this._index,this._fileInfo)]}},{key:"createEmptySelectors",value:function(){var e=[new t([new I("","&",!1,this._index,this._fileInfo)],null,null,this._index,this._fileInfo)];return e[0].mediaEmpty=!0,e}},{key:"match",value:function(e){var t,n,i=this.elements,r=i.length;if(0===(t=(e=e.mixinElements()).length)||rC.PARENS_DIVISION)||this.parensStack&&this.parensStack.length))}},{key:"pathRequiresRewrite",value:function(e){return(this.rewriteUrls===_.LOCAL?K:Q)(e)}},{key:"rewritePath",value:function(e,t){var n;return t=t||"",n=this.normalizePath(t+e),K(e)&&Q(t)&&!1===K(n)&&(n="./".concat(n)),n}},{key:"normalizePath",value:function(e){var t,n=e.split("/").reverse();for(e=[];0!==n.length;)switch(t=n.pop()){case".":break;case"..":0===e.length||".."===e[e.length-1]?e.push(t):e.pop();break;default:e.push(t)}return e.join("/")}}]),e}();var Z=function e(t){return{_data:{},add:function(e,t){e=e.toLowerCase(),this._data.hasOwnProperty(e),this._data[e]=t},addMultiple:function(e){var t=this;Object.keys(e).forEach(function(n){t.add(n,e[n])})},get:function(e){return this._data[e]||t&&t.get(e)},getLocalFunctions:function(){return this._data},inherit:function(){return e(this)},create:function(t){return e(t)}}}(null),Y={eval:function(){var e=this.value_,t=this.error_;if(t)throw t;if(null!=e)return e?j.True:j.False},value:function(e){this.value_=e},error:function(e){this.error_=e},reset:function(){this.value_=this.error_=null}},X=function(e){function t(e,n,i,a){var s;return r(this,t),(s=f(this,l(t).call(this))).selectors=e,s.rules=n,s._lookups={},s._variables=null,s._properties=null,s.strictImports=i,s.copyVisibilityInfo(a),s.allowRoot=!0,s.setParent(s.selectors,h(s)),s.setParent(s.rules,h(s)),s}return o(t,g),s(t,[{key:"isRulesetLike",value:function(){return!0}},{key:"accept",value:function(e){this.paths?this.paths=e.visitArray(this.paths,!0):this.selectors&&(this.selectors=e.visitArray(this.selectors)),this.rules&&this.rules.length&&(this.rules=e.visitArray(this.rules))}},{key:"eval",value:function(e){var n,i,r,a,s,o=!1;if(this.selectors&&(i=this.selectors.length)){for(n=new Array(i),Y.error({type:"Syntax",message:"it is currently only allowed in parametric mixin guards,"}),a=0;a0;e--){var t=this.rules[e-1];if(t instanceof q)return this.parseValue(t)}}},{key:"parseValue",value:function(e){var t=this;function n(e){return e.value instanceof B&&!e.parsed?("string"==typeof e.value.value?this.parse.parseNode(e.value.value,["value","important"],e.value.getIndex(),e.fileInfo(),function(t,n){t&&(e.parsed=!0),n&&(e.value=n[0],e.important=n[1]||"",e.parsed=!0)}):e.parsed=!0,e):e}if(Array.isArray(e)){var i=[];return e.forEach(function(e){i.push(n.call(t,e))}),i}return n.call(t,e)}},{key:"rulesets",value:function(){if(!this.rules)return[];var e,t,n=[],i=this.rules;for(e=0;t=i[e];e++)t.isRuleset&&n.push(t);return n}},{key:"prependRule",value:function(e){var t=this.rules;t?t.unshift(e):this.rules=[e],this.setParent(e,this)}},{key:"find",value:function(e){var t,n,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:this,r=arguments.length>2?arguments[2]:void 0,a=[],s=e.toCSS();return s in this._lookups?this._lookups[s]:(this.rulesets().forEach(function(s){if(s!==i)for(var o=0;ot){if(!r||r(s)){n=s.find(new D(e.elements.slice(t)),i,r);for(var l=0;l0&&t.add(l),e.firstSelector=!0,s[0].genCSS(e,t),e.firstSelector=!1,i=1;i0?(a=(r=P(e)).pop(),s=i.createDerived(P(a.elements))):s=i.createDerived([]),t.length>0){var o=n.combinator,l=t[0].elements[0];o.emptyOrWhitespace&&!l.combinator.emptyOrWhitespace&&(o=l.combinator),s.elements.push(new I(o,l.value,n.isVariable,n._index,n._fileInfo)),s.elements=s.elements.concat(t[0].elements.slice(1))}if(0!==s.elements.length&&r.push(s),t.length>1){var u=t.slice(1);u=u.map(function(e){return e.createDerived(e.elements,[])}),r=r.concat(u)}return r}function s(e,t,n,i,r){var s;for(s=0;s0?i[i.length-1]=i[i.length-1].createDerived(i[i.length-1].elements.concat(e)):i.push(new D(e));else t.push([new D(e)])}function l(e,t){var n=t.createDerived(t.elements,t.extendList,t.evaldCondition);return n.copyVisibilityInfo(e),n}var u,c;if(!function e(t,n,l){var u,c,h,f,p,v,d,m,g,y,b,w,x=!1;for(f=[],p=[[]],u=0;m=l.elements[u];u++)if("&"!==m.value){var S=(w=void 0,(b=m).value instanceof k&&(w=b.value.value)instanceof D?w:null);if(null!=S){o(f,p);var C,_=[],A=[];for(C=e(_,n,S),x=x||C,h=0;h<_.length;h++)s(p,[r(i(_[h],m),m)],m,l,A);p=A,f=[]}else f.push(m)}else{for(x=!0,v=[],o(f,p),c=0;c0&&d[0].elements.push(new I(m.combinator,"",m.isVariable,m._index,m._fileInfo)),v.push(d);else for(h=0;h0&&(t.push(p[u]),y=p[u][g-1],p[u][g-1]=y.createDerived(y.elements,l.extendList));return x}(c=[],t,n))if(t.length>0)for(c=[],u=0;u0)for(t=0;t-1e-6&&(i=n.toFixed(20).replace(/0+$/,"")),e&&e.compress){if(0===n&&this.unit.isLength())return void t.add(i);n>0&&n<1&&(i=i.substr(1))}t.add(i),this.unit.genCSS(e,t)}},{key:"operate",value:function(e,n,i){var r=this._operate(e,n,this.value,i.value),a=this.unit.clone();if("+"===n||"-"===n)if(0===a.numerator.length&&0===a.denominator.length)a=i.unit.clone(),this.unit.backupUnit&&(a.backupUnit=this.unit.backupUnit);else if(0===i.unit.numerator.length&&0===a.denominator.length);else{if(i=i.convertTo(this.unit.usedUnits()),e.strictUnits&&i.unit.toString()!==a.toString())throw new Error("Incompatible units. Change the units or use the unit function. "+"Bad units: '".concat(a.toString(),"' and '").concat(i.unit.toString(),"'."));r=this._operate(e,n,this.value,i.value)}else"*"===n?(a.numerator=a.numerator.concat(i.unit.numerator).sort(),a.denominator=a.denominator.concat(i.unit.denominator).sort(),a.cancel()):"/"===n&&(a.numerator=a.numerator.concat(i.unit.denominator).sort(),a.denominator=a.denominator.concat(i.unit.numerator).sort(),a.cancel());return new t(r,a)}},{key:"compare",value:function(e){var n,i;if(e instanceof t){if(this.unit.isEmpty()||e.unit.isEmpty())n=this,i=e;else if(n=this.unify(),i=e.unify(),0!==n.unit.compare(i.unit))return;return g.numericCompare(n.value,i.value)}}},{key:"unify",value:function(){return this.convertTo({length:"px",duration:"s",angle:"rad"})}},{key:"convertTo",value:function(e){var n,i,r,a,s,o=this.value,l=this.unit.clone(),u={};if("string"==typeof e){for(n in d)d[n].hasOwnProperty(e)&&((u={})[n]=e);e=u}for(i in s=function(e,t){return r.hasOwnProperty(e)?(t?o/=r[e]/r[a]:o*=r[e]/r[a],a):e},e)e.hasOwnProperty(i)&&(a=e[i],r=d[i],l.map(s));return l.cancel(),new t(o,l)}}]),t}();ie.prototype.type="Dimension";var re=C,ae=function(e){function t(e,n,i){var a;return r(this,t),(a=f(this,l(t).call(this))).op=e.trim(),a.operands=n,a.isSpaced=i,a}return o(t,g),s(t,[{key:"accept",value:function(e){this.operands=e.visitArray(this.operands)}},{key:"eval",value:function(e){var n,i=this.operands[0].eval(e),r=this.operands[1].eval(e);if(e.isMathOn(this.op)){if(n="./"===this.op?"/":this.op,i instanceof ie&&r instanceof y&&(i=i.toColor()),r instanceof ie&&i instanceof y&&(r=r.toColor()),!i.operate){if(i instanceof t&&"/"===i.op&&e.math===re.PARENS_DIVISION)return new t(this.op,[i,r],this.isSpaced);throw{type:"Operation",message:"Operation on an invalid type"}}return i.operate(e,n,r)}return new t(this.op,[i,r],this.isSpaced)}},{key:"genCSS",value:function(e,t){this.operands[0].genCSS(e,t),this.isSpaced&&t.add(" "),t.add(this.op),this.isSpaced&&t.add(" "),this.operands[1].genCSS(e,t)}}]),t}();ae.prototype.type="Operation";var se=C,oe=function(e){function t(e,n){var i;if(r(this,t),(i=f(this,l(t).call(this))).value=e,i.noSpacing=n,!e)throw new Error("Expression requires an array parameter");return i}return o(t,g),s(t,[{key:"accept",value:function(e){this.value=e.visitArray(this.value)}},{key:"eval",value:function(e){var n,i=e.isMathOn(),r=this.parens&&(e.math!==se.STRICT_LEGACY||!this.parensInOp),a=!1;return r&&e.inParenthesis(),this.value.length>1?n=new t(this.value.map(function(t){return t.eval?t.eval(e):t}),this.noSpacing):1===this.value.length?(!this.value[0].parens||this.value[0].parensInOp||e.inCalc||(a=!0),n=this.value[0].eval(e)):n=this,r&&e.outOfParenthesis(),!this.parens||!this.parensInOp||i||a||n instanceof ie||(n=new k(n)),n}},{key:"genCSS",value:function(e,t){for(var n=0;n1){var n=new D([],null,null,this.getIndex(),this.fileInfo()).createEmptySelectors();(t=new X(n,e.mediaBlocks)).multiMedia=!0,t.copyVisibilityInfo(this.visibilityInfo()),this.setParent(t,this)}return delete e.mediaBlocks,delete e.mediaPath,t}},{key:"evalNested",value:function(e){var t,n,i=e.mediaPath.concat([this]);for(t=0;t0;t--)e.splice(t,0,new B("and"));return new oe(e)})),this.setParent(this.features,this),new X([],[])}},{key:"permute",value:function(e){if(0===e.length)return[];if(1===e.length)return e[0];for(var t=[],n=this.permute(e.slice(1)),i=0;i1?"[".concat(e.value.map(function(e){return e.toCSS()}).join(", "),"]"):e.toCSS()}}]),t}(),ye=function(e){function t(e,n,i,a){var s;return r(this,t),(s=f(this,l(t).call(this))).escaped=n,s.expression=e,s._index=i,s._fileInfo=a,s}return o(t,ge),s(t,[{key:"eval",value:function(e){var t=this.evaluateJavaScript(this.expression,e),n=i(t);return"number"!==n||isNaN(t)?"string"===n?new pe('"'.concat(t,'"'),t,this.escaped,this._index):Array.isArray(t)?new B(t.join(", ")):new B(t):new ie(t)}}]),t}();ye.prototype.type="JavaScript";var be=function(e){function t(e,n){var i;return r(this,t),(i=f(this,l(t).call(this))).key=e,i.value=n,i}return o(t,g),s(t,[{key:"accept",value:function(e){this.value=e.visit(this.value)}},{key:"eval",value:function(e){return this.value.eval?new t(this.key,this.value.eval(e)):this}},{key:"genCSS",value:function(e,t){t.add("".concat(this.key,"=")),this.value.genCSS?this.value.genCSS(e,t):t.add(this.value)}}]),t}();be.prototype.type="Assignment";var we=function(e){function t(e,n,i,a,s){var o;return r(this,t),(o=f(this,l(t).call(this))).op=e.trim(),o.lvalue=n,o.rvalue=i,o._index=a,o.negate=s,o}return o(t,g),s(t,[{key:"accept",value:function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)}},{key:"eval",value:function(e){var t=function(e,t,n){switch(e){case"and":return t&&n;case"or":return t||n;default:switch(g.compare(t,n)){case-1:return"<"===e||"=<"===e||"<="===e;case 0:return"="===e||">="===e||"=<"===e||"<="===e;case 1:return">"===e||">="===e;default:return!1}}}(this.op,this.lvalue.eval(e),this.rvalue.eval(e));return this.negate?!t:t}}]),t}();we.prototype.type="Condition";var ke=function(e){function t(e){var n;return r(this,t),(n=f(this,l(t).call(this))).value=e,n}return o(t,g),t}();ke.prototype.type="UnicodeDescriptor";var xe=function(e){function t(e){var n;return r(this,t),(n=f(this,l(t).call(this))).value=e,n}return o(t,g),s(t,[{key:"genCSS",value:function(e,t){t.add("-"),this.value.genCSS(e,t)}},{key:"eval",value:function(e){return e.isMathOn()?new ae("*",[new ie(-1),this.value]).eval(e):new t(this.value.eval(e))}}]),t}();xe.prototype.type="Negative";var Se=function(e){function t(e,n,i,a,s){var o;switch(r(this,t),(o=f(this,l(t).call(this))).selector=e,o.option=n,o.object_id=t.next_id++,o.parent_ids=[o.object_id],o._index=i,o._fileInfo=a,o.copyVisibilityInfo(s),o.allowRoot=!0,n){case"all":o.allowBefore=!0,o.allowAfter=!0;break;default:o.allowBefore=!1,o.allowAfter=!1}return o.setParent(o.selector,h(o)),o}return o(t,g),s(t,[{key:"accept",value:function(e){this.selector=e.visit(this.selector)}},{key:"eval",value:function(e){return new t(this.selector.eval(e),this.option,this.getIndex(),this.fileInfo(),this.visibilityInfo())}},{key:"clone",value:function(e){return new t(this.selector,this.option,this.getIndex(),this.fileInfo(),this.visibilityInfo())}},{key:"findSelfSelectors",value:function(e){var t,n,i=[];for(t=0;t0&&n.length&&""===n[0].combinator.value&&(n[0].combinator.value=" "),i=i.concat(e[t].elements);this.selfSelectors=[new D(i)],this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo())}}]),t}();Se.next_id=0,Se.prototype.type="Extend";var Ie=function(e){function t(e,n,i){var a;return r(this,t),(a=f(this,l(t).call(this))).variable=e,a._index=n,a._fileInfo=i,a.allowRoot=!0,a}return o(t,g),s(t,[{key:"eval",value:function(e){var t,n=new ce(this.variable,this.getIndex(),this.fileInfo()).eval(e),i=new $({message:"Could not evaluate variable call ".concat(this.variable)});if(!n.ruleset){if(n.rules)t=n;else if(Array.isArray(n))t=new X("",n);else{if(!Array.isArray(n.value))throw i;t=new X("",n.value)}n=new te(t)}if(n.ruleset)return n.callEval(e);throw i}}]),t}();Ie.prototype.type="VariableCall";var Ce=function(e){function t(e,n,i,a,s){var o;return r(this,t),(o=f(this,l(t).call(this))).value=e,o.lookups=n,o.important=i,o._index=a,o._fileInfo=s,o}return o(t,g),s(t,[{key:"eval",value:function(e){var t,n,i=this.value.eval(e);for(t=0;tthis.params.length)return!1}n=Math.min(a,this.arity);for(var s=0;s0){for(c=!0,o=0;o0)f=I;else if(f=S,p[S]+p[I]>1)throw{type:"Runtime",message:"Ambiguous use of `default()` found when matching for `".concat(this.format(m),"`"),index:this.getIndex(),filename:this.fileInfo().filename};for(o=0;o=0;s--){var o=a[s];if(o[r?"supportsSync":"supports"](e,t,n,i))return o}return null}},{key:"addFileManager",value:function(e){this.fileManagers.push(e)}},{key:"clearFileManagers",value:function(){this.fileManagers=[]}}]),e}(),Re=function(){function e(){r(this,e)}return s(e,[{key:"getPath",value:function(e){var t=e.lastIndexOf("?");return t>0&&(e=e.slice(0,t)),(t=e.lastIndexOf("/"))<0&&(t=e.lastIndexOf("\\")),t<0?"":e.slice(0,t+1)}},{key:"tryAppendExtension",value:function(e,t){return/(\.[a-z]*$)|([\?;].*)$/.test(e)?e:e+t}},{key:"tryAppendLessExtension",value:function(e){return this.tryAppendExtension(e,".less")}},{key:"supportsSync",value:function(){return!1}},{key:"alwaysMakePathsAbsolute",value:function(){return!1}},{key:"isPathAbsolute",value:function(e){return/^(?:[a-z-]+:|\/|\\|#)/i.test(e)}},{key:"join",value:function(e,t){return e?e+t:t}},{key:"pathDiff",value:function(e,t){var n,i,r,a,s=this.extractUrlParts(e),o=this.extractUrlParts(t),l="";if(s.hostPart!==o.hostPart)return"";for(i=Math.max(o.directories.length,s.directories.length),n=0;nparseInt(t[n])?-1:1;return 0}},{key:"versionToString",value:function(e){for(var t="",n=0;n0;){var e=this.imports[0];if(!e.isReady)return;this.imports=this.imports.slice(1),e.callback.apply(null,e.args)}if(0===this.variableImports.length)break;var t=this.variableImports[0];this.variableImports=this.variableImports.slice(1),t()}}finally{this._currentDepth--}0===this._currentDepth&&this._onSequencerEmpty&&this._onSequencerEmpty()}}]),e}(),Ne=function(e,t){this._visitor=new Le(this),this._importer=e,this._finish=t,this.context=new G.Eval,this.importCount=0,this.onceFileDetectionMap={},this.recursionDetector={},this._sequencer=new De(this._onSequencerEmpty.bind(this))};Ne.prototype={isReplacing:!1,run:function(e){try{this._visitor.visit(e)}catch(e){this.error=e}this.isFinished=!0,this._sequencer.tryRun()},_onSequencerEmpty:function(){this.isFinished&&this._finish(this.error)},visitImport:function(e,t){var n=e.options.inline;if(!e.css||n){var i=new G.Eval(this.context,P(this.context.frames)),r=i.frames[0];this.importCount++,e.isVariableImport()?this._sequencer.addVariableImport(this.processImportNode.bind(this,e,i,r)):this.processImportNode(e,i,r)}t.visitDeeper=!1},processImportNode:function(e,t,n){var i,r=e.options.inline;try{i=e.evalForImport(t)}catch(t){t.filename||(t.index=e.getIndex(),t.filename=e.fileInfo().filename),e.css=!0,e.error=t}if(!i||i.css&&!r)this.importCount--,this.isFinished&&this._sequencer.tryRun();else{i.options.multiple&&(t.importMultiple=!0);for(var a=void 0===i.css,s=0;s=0||(o=[u.selfSelectors[0]],(a=f.findMatch(l,o)).length&&(l.hasFoundMatches=!0,l.selfSelectors.forEach(function(e){var t=u.visibilityInfo();s=f.extendSelector(a,o,e,l.isVisible()),(c=new Me.Extend(u.selector,u.option,0,u.fileInfo(),t)).selfSelectors=s,s[s.length-1].extendList=[c],h.push(c),c.ruleset=u.ruleset,c.parent_ids=c.parent_ids.concat(u.parent_ids,l.parent_ids),u.firstExtendOnThisSelectorPath&&(c.firstExtendOnThisSelectorPath=!0,u.ruleset.paths.push(s))})));if(h.length){if(this.extendChainCount++,n>100){var p="{unable to calculate}",v="{unable to calculate}";try{p=h[0].selfSelectors[0].toCSS(),v=h[0].selector.toCSS()}catch(e){}throw{message:"extend circular reference detected. One of the circular extends is currently:".concat(p,":extend(").concat(v,")")}}return h.concat(f.doExtendChaining(h,t,n+1))}return h}},{key:"visitDeclaration",value:function(e,t){t.visitDeeper=!1}},{key:"visitMixinDefinition",value:function(e,t){t.visitDeeper=!1}},{key:"visitSelector",value:function(e,t){t.visitDeeper=!1}},{key:"visitRuleset",value:function(e,t){if(!e.root){var n,i,r,a,s=this.allExtendsStack[this.allExtendsStack.length-1],o=[],l=this;for(r=0;r0&&u[l.matched].combinator.value!==s?l=null:l.matched++,l&&(l.finished=l.matched===u.length,l.finished&&!e.allowAfter&&(r+1u&&c>0&&(h[h.length-1].elements=h[h.length-1].elements.concat(t[u].elements.slice(c)),c=0,u++),l=a.elements.slice(c,o.index).concat([s]).concat(n.elements.slice(1)),u===o.pathIndex&&r>0?h[h.length-1].elements=h[h.length-1].elements.concat(l):(h=h.concat(t.slice(u,o.pathIndex))).push(new Me.Selector(l)),u=o.endPathIndex,(c=o.endPathElementIndex)>=t[u].elements.length&&(c=0,u++);return u0&&(h[h.length-1].elements=h[h.length-1].elements.concat(t[u].elements.slice(c)),u++),h=(h=h.concat(t.slice(u,t.length))).map(function(e){var t=e.createDerived(e.elements);return i?t.ensureVisibility():t.ensureInvisibility(),t})}},{key:"visitMedia",value:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)}},{key:"visitMediaOut",value:function(e){var t=this.allExtendsStack.length-1;this.allExtendsStack.length=t}},{key:"visitAtRule",value:function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)}},{key:"visitAtRuleOut",value:function(e){var t=this.allExtendsStack.length-1;this.allExtendsStack.length=t}}]),e}(),qe=function(){function e(){r(this,e),this.contexts=[[]],this._visitor=new Le(this)}return s(e,[{key:"run",value:function(e){return this._visitor.visit(e)}},{key:"visitDeclaration",value:function(e,t){t.visitDeeper=!1}},{key:"visitMixinDefinition",value:function(e,t){t.visitDeeper=!1}},{key:"visitRuleset",value:function(e,t){var n,i=this.contexts[this.contexts.length-1],r=[];this.contexts.push(r),e.root||((n=e.selectors)&&(n=n.filter(function(e){return e.getIsOutput()}),e.selectors=n.length?n:n=null,n&&e.joinSelectors(r,i,n)),n||(e.rules=null),e.paths=r)}},{key:"visitRulesetOut",value:function(e){this.contexts.length=this.contexts.length-1}},{key:"visitMedia",value:function(e,t){var n=this.contexts[this.contexts.length-1];e.rules[0].root=0===n.length||n[0].multiMedia}},{key:"visitAtRule",value:function(e,t){var n=this.contexts[this.contexts.length-1];e.rules&&e.rules.length&&(e.rules[0].root=e.isRooted||0===n.length||null)}}]),e}(),Te=function(){function e(t){r(this,e),this._visitor=new Le(this),this._context=t}return s(e,[{key:"containsSilentNonBlockedChild",value:function(e){var t;if(!e)return!1;for(var n=0;n0}},{key:"resolveVisibility",value:function(e,t){if(!e.blocksVisibility()){if(this.isEmpty(e)&&!this.containsSilentNonBlockedChild(t))return;return e}var n=e.rules[0];if(this.keepOnlyVisibleChilds(n),!this.isEmpty(n))return e.ensureVisibility(),e.removeVisibilityBlock(),e}},{key:"isVisibleRuleset",value:function(e){return!!e.firstRoot||!this.isEmpty(e)&&!(!e.root&&!this.hasVisibleSelector(e))}}]),e}(),ze=function(e){this._visitor=new Le(this),this._context=e,this.utils=new Te(e)};ze.prototype={isReplacing:!0,run:function(e){return this._visitor.visit(e)},visitDeclaration:function(e,t){if(!e.blocksVisibility()&&!e.variable)return e},visitMixinDefinition:function(e,t){e.frames=[]},visitExtend:function(e,t){},visitComment:function(e,t){if(!e.blocksVisibility()&&!e.isSilent(this._context))return e},visitMedia:function(e,t){var n=e.rules[0].rules;return e.accept(this._visitor),t.visitDeeper=!1,this.utils.resolveVisibility(e,n)},visitImport:function(e,t){if(!e.blocksVisibility())return e},visitAtRule:function(e,t){return e.rules&&e.rules.length?this.visitAtRuleWithBody(e,t):this.visitAtRuleWithoutBody(e,t)},visitAnonymous:function(e,t){if(!e.blocksVisibility())return e.accept(this._visitor),e},visitAtRuleWithBody:function(e,t){var n=function(e){var t=e.rules;return function(e){var t=e.rules;return 1===t.length&&(!t[0].paths||0===t[0].paths.length)}(e)?t[0].rules:t}(e);return e.accept(this._visitor),t.visitDeeper=!1,this.utils.isEmpty(e)||this._mergeRules(e.rules[0].rules),this.utils.resolveVisibility(e,n)},visitAtRuleWithoutBody:function(e,t){if(!e.blocksVisibility()){if("@charset"===e.name){if(this.charset){if(e.debugInfo){var n=new Me.Comment("/* ".concat(e.toCSS(this._context).replace(/\n/g,"")," */\n"));return n.debugInfo=e.debugInfo,this._visitor.visit(n)}return}this.charset=!0}return e}},checkValidNodes:function(e,t){if(e)for(var n=0;n0?e.accept(this._visitor):e.rules=null,t.visitDeeper=!1}return e.rules&&(this._mergeRules(e.rules),this._removeDuplicateRules(e.rules)),this.utils.isVisibleRuleset(e)&&(e.ensureVisibility(),i.splice(0,0,e)),1===i.length?i[0]:i},_compileRulesetPaths:function(e){e.paths&&(e.paths=e.paths.filter(function(e){var t;for(" "===e[0].elements[0].combinator.value&&(e[0].elements[0].combinator=new Me.Combinator("")),t=0;t=0;i--)if((n=e[i])instanceof Me.Declaration)if(r[n.name]){(t=r[n.name])instanceof Me.Declaration&&(t=r[n.name]=[r[n.name].toCSS(this._context)]);var a=n.toCSS(this._context);-1!==t.indexOf(a)?e.splice(i,1):t.push(a)}else r[n.name]=n}},_mergeRules:function(e){if(e){for(var t={},n=[],i=0;i0){var t=e[0],n=[],i=[new Me.Expression(n)];e.forEach(function(e){"+"===e.merge&&n.length>0&&i.push(new Me.Expression(n=[])),n.push(e.value),t.important=t.important||e.important}),t.value=new Me.Value(i)}})}}};var Ge={Visitor:Le,ImportVisitor:Ne,MarkVisibleSelectorsVisitor:je,ExtendVisitor:Ue,JoinSelectorVisitor:qe,ToCSSVisitor:ze},We=function(){var e,t,n,i,r,a,s,o=[],l={},u=32,c=9,h=10,f=13,p=47;function v(n){for(var i,o,d,m=l.i,g=t,y=l.i-s,b=l.i+a.length-y,w=l.i+=n,k=e;l.i=0){d={index:l.i,text:k.substr(l.i,S+2-l.i),isLineComment:!1},l.i+=d.text.length-1,l.commentStore.push(d);continue}}break}if(i!==u&&i!==h&&i!==c&&i!==f)break}if(a=a.slice(n+l.i-w+y),s=l.i,!a.length){if(tn||l.i===n&&e&&!i)&&(n=l.i,i=e);var r=o.pop();a=r.current,s=l.i=r.i,t=r.j},l.forget=function(){o.pop()},l.isWhitespace=function(t){var n=l.i+(t||0),i=e.charCodeAt(n);return i===u||i===f||i===c||i===h},l.$re=function(e){l.i>s&&(a=a.slice(l.i-s),s=l.i);var t=e.exec(a);return t?(v(t[0].length),"string"==typeof t?t:1===t.length?t[0]:t):null},l.$char=function(t){return e.charAt(l.i)!==t?null:(v(1),t)},l.$str=function(t){for(var n=t.length,i=0;ic&&(d=!1)}}while(d);return r||null},l.autoCommentAbsorb=!0,l.commentStore=[],l.finished=!1,l.peek=function(t){if("string"==typeof t){for(var n=0;n57||t<43||t===p||44===t},l.start=function(i,o,u){e=i,l.i=t=s=n=0,r=o?function(e,t){var n,i,r,a,s,o,l,u,c,h=e.length,f=0,p=0,v=[],d=0;function m(t){var n=s-d;n<512&&!t||!n||(v.push(e.slice(d,s+1)),d=s+1)}for(s=0;s=97&&l<=122||l<34))switch(l){case 40:p++,i=s;continue;case 41:if(--p<0)return t("missing opening `(`",s);continue;case 59:p||m();continue;case 123:f++,n=s;continue;case 125:if(--f<0)return t("missing opening `{`",s);f||p||m();continue;case 92:if(s96)){if(u==l){c=1;break}if(92==u){if(s==h-1)return t("unescaped `\\`",s);s++}}if(c)continue;return t("unmatched `".concat(String.fromCharCode(l),"`"),o);case 47:if(p||s==h-1)continue;if(47==(u=e.charCodeAt(s+1)))for(s+=2;sn&&a>r?"missing closing `}` or `*/`":"missing closing `}`",n):0!==p?t("missing closing `)`",i):(m(!0),v)}(i,u):[i],a=r[0],v(0)},l.end=function(){var t,r=l.i>=e.length;return l.i=e.length-1,furthestChar:e[l.i]}},l},Je=function e(t,n,i){var r,a=We();function s(e,t){throw new $({index:a.i,filename:i.filename,type:t||"Syntax",message:e},n)}function o(e,t){var n=e instanceof Function?e.call(r):a.$re(e);if(n)return n;s(t||("string"==typeof e?"expected '".concat(e,"' got '").concat(a.currentChar(),"'"):"unexpected token"))}function l(e,t){if(a.$char(e))return e;s(t||"expected '".concat(e,"' got '").concat(a.currentChar(),"'"))}function u(e){var t=i.filename;return{lineNumber:M(e,a.getInput()).line+1,fileName:t}}return{parserInput:a,imports:n,fileInfo:i,parseNode:function(e,t,i,s,o){var l,u=[],c=a;try{c.start(e,!1,function(e,t){o({message:e,index:t+i})});for(var h,f,p=0;h=t[p];p++)if(f=c.i,l=r[h]()){try{l._index=f+i,l._fileInfo=s}catch(e){}u.push(l)}else u.push(null);c.end().isFinished?o(null,u):o(!0,null)}catch(e){throw new $({index:e.index+i,message:e.message},n,s.filename)}},parse:function(r,s,o){var l,u,c,h,f=null,p="";if(u=o&&o.globalVars?"".concat(e.serializeVars(o.globalVars),"\n"):"",c=o&&o.modifyVars?"\n".concat(e.serializeVars(o.modifyVars)):"",t.pluginManager)for(var v=t.pluginManager.getPreProcessors(),d=0;d");return e},args:function(e){var t,n,i,o,l,u,c,h=r.entities,f={args:null,variadic:!1},p=[],v=[],d=[],m=!0;for(a.save();;){if(e)u=r.detachedRuleset()||r.expression();else{if(a.commentStore.length=0,a.$str("...")){f.variadic=!0,a.$char(";")&&!t&&(t=!0),(t?v:d).push({variadic:!0});break}u=h.variable()||h.property()||h.literal()||h.keyword()||this.call(!0)}if(!u||!m)break;o=null,u.throwAwayComments&&u.throwAwayComments(),l=u;var g=null;if(e?u.value&&1==u.value.length&&(g=u.value[0]):g=u,g&&(g instanceof Me.Variable||g instanceof Me.Property))if(a.$char(":")){if(p.length>0&&(t&&s("Cannot mix ; and , as delimiter types"),n=!0),!(l=r.detachedRuleset()||r.expression())){if(!e)return a.restore(),f.args=[],f;s("could not understand value for named argument")}o=i=g.name}else if(a.$str("...")){if(!e){f.variadic=!0,a.$char(";")&&!t&&(t=!0),(t?v:d).push({name:u.name,variadic:!0});break}c=!0}else e||(i=o=g.name,l=null);l&&p.push(l),d.push({name:o,value:l,expand:c}),a.$char(",")?m=!0:((m=";"===a.$char(";"))||t)&&(n&&s("Cannot mix ; and , as delimiter types"),t=!0,p.length>1&&(l=new Me.Value(p)),v.push({name:i,value:l,expand:c}),i=null,p=[],n=!1)}return a.forget(),f.args=t?v:d,f},definition:function(){var e,t,n,i,s=[],l=!1;if(!("."!==a.currentChar()&&"#"!==a.currentChar()||a.peek(/^[^{]*\}/)))if(a.save(),t=a.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=t[1];var u=this.args(!1);if(s=u.args,l=u.variadic,!a.$char(")"))return void a.restore("Missing closing ')'");if(a.commentStore.length=0,a.$str("when")&&(i=o(r.conditions,"expected condition")),n=r.block())return a.forget(),new Me.mixin.Definition(e,s,n,i,l);a.restore()}else a.forget()},ruleLookups:function(){var e,t=[];if("["===a.currentChar()){for(;;){if(a.save(),!(e=this.lookupValue())&&""!==e){a.restore();break}t.push(e),a.forget()}return t.length>0?t:void 0}},lookupValue:function(){if(a.save(),a.$char("[")){var e=a.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);if(a.$char("]"))return e||""===e?(a.forget(),e):void a.restore();a.restore()}else a.restore()}},entity:function(){var e=this.entities;return this.comment()||e.literal()||e.variable()||e.url()||e.property()||e.call()||e.keyword()||this.mixin.call(!0)||e.javascript()},end:function(){return a.$char(";")||a.peek("}")},ieAlpha:function(){var e;if(a.$re(/^opacity=/i))return(e=a.$re(/^\d+/))||(e=o(r.entities.variable,"Could not parse alpha"),e="@{".concat(e.name.slice(1),"}")),l(")"),new Me.Quoted("","alpha(opacity=".concat(e,")"))},element:function(){var e,t,n,r=a.i;if(t=this.combinator(),(e=a.$re(/^(?:\d+\.\d+|\d+)%/)||a.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||a.$char("*")||a.$char("&")||this.attribute()||a.$re(/^\([^&()@]+\)/)||a.$re(/^[\.#:](?=@)/)||this.entities.variableCurly())||(a.save(),a.$char("(")?(n=this.selector(!1))&&a.$char(")")?(e=new Me.Paren(n),a.forget()):a.restore("Missing closing ')'"):a.forget()),e)return new Me.Element(t,e,e instanceof Me.Variable,r,i)},combinator:function(){var e=a.currentChar();if("/"===e){a.save();var t=a.$re(/^\/[a-z]+\//i);if(t)return a.forget(),new Me.Combinator(t);a.restore()}if(">"===e||"+"===e||"~"===e||"|"===e||"^"===e){for(a.i++,"^"===e&&"^"===a.currentChar()&&(e="^^",a.i++);a.isWhitespace();)a.i++;return new Me.Combinator(e)}return a.isWhitespace(-1)?new Me.Combinator(" "):new Me.Combinator(null)},selector:function(e){var t,n,r,l,u,c,h,f=a.i;for(e=!1!==e;(e&&(n=this.extend())||e&&(c=a.$str("when"))||(l=this.element()))&&(c?h=o(this.conditions,"expected condition"):h?s("CSS guard can only be used at the end of selector"):n?u=u?u.concat(n):n:(u&&s("Extend can only be used at the end of selector"),r=a.currentChar(),t?t.push(l):t=[l],l=null),"{"!==r&&"}"!==r&&";"!==r&&","!==r&&")"!==r););if(t)return new Me.Selector(t,u,h,f,i);u&&s("Extend must be used to extend a selector, it cannot be used on its own")},selectors:function(){for(var e,t;(e=this.selector())&&(t?t.push(e):t=[e],a.commentStore.length=0,e.condition&&t.length>1&&s("Guards are only currently allowed on a single selector."),a.$char(","));)e.condition&&s("Guards are only currently allowed on a single selector."),a.commentStore.length=0;return t},attribute:function(){if(a.$char("[")){var e,t,n,i=this.entities;return(e=i.variableCurly())||(e=o(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/)),(n=a.$re(/^[|~*$^]?=/))&&(t=i.quoted()||a.$re(/^[0-9]+%/)||a.$re(/^[\w-]+/)||i.variableCurly()),l("]"),new Me.Attribute(e,n,t)}},block:function(){var e;if(a.$char("{")&&(e=this.primary())&&a.$char("}"))return e},blockRuleset:function(){var e=this.block();return e&&(e=new Me.Ruleset(null,e)),e},detachedRuleset:function(){var e,t,n;if(a.save(),!a.$re(/^[.#]\(/)||(t=(e=this.mixin.args(!1)).args,n=e.variadic,a.$char(")"))){var i=this.blockRuleset();if(i)return a.forget(),t?new Me.mixin.Definition(null,t,i,null,n):new Me.DetachedRuleset(i);a.restore()}else a.restore()},ruleset:function(){var e,n,i;if(a.save(),t.dumpLineNumbers&&(i=u(a.i)),(e=this.selectors())&&(n=this.block())){a.forget();var r=new Me.Ruleset(e,n,t.strictImports);return t.dumpLineNumbers&&(r.debugInfo=i),r}a.restore()},declaration:function(){var e,t,n,r,s,o,l=a.i,u=a.currentChar();if("."!==u&&"#"!==u&&"&"!==u&&":"!==u)if(a.save(),e=this.variable()||this.ruleProperty()){if((o="string"==typeof e)&&(t=this.detachedRuleset())&&(n=!0),a.commentStore.length=0,!t){if(s=!o&&e.length>1&&e.pop().value,t=e[0].value&&"--"===e[0].value.slice(0,2)?this.permissiveValue():this.anonymousValue())return a.forget(),new Me.Declaration(e,t,!1,s,l,i);t||(t=this.value()),t?r=this.important():o&&(t=this.permissiveValue())}if(t&&(this.end()||n))return a.forget(),new Me.Declaration(e,t,r,s,l,i);a.restore()}else a.restore()},anonymousValue:function(){var e=a.i,t=a.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);if(t)return new Me.Anonymous(t[1],e)},permissiveValue:function(e){var t,n,r,o,l=e||";",u=a.i,c=[];function h(){var e=a.currentChar();return"string"==typeof l?e===l:l.test(e)}if(!h()){o=[];do{(n=this.comment())?o.push(n):(n=this.entity())&&o.push(n)}while(n);if(r=h(),o.length>0){if(o=new Me.Expression(o),r)return o;c.push(o)," "===a.prevChar()&&c.push(new Me.Anonymous(" ",u))}if(a.save(),o=a.$parseUntil(l)){if("string"==typeof o&&s("Expected '".concat(o,"'"),"Parse"),1===o.length&&" "===o[0])return a.forget(),new Me.Anonymous("",u);var f;for(t=0;t0)return new Me.Expression(r)},mediaFeatures:function(){var e,t=this.entities,n=[];do{if(e=this.mediaFeature()){if(n.push(e),!a.$char(","))break}else if((e=t.variable()||t.mixinLookup())&&(n.push(e),!a.$char(",")))break}while(e);return n.length>0?n:null},media:function(){var e,n,r,o,l=a.i;if(t.dumpLineNumbers&&(o=u(l)),a.save(),a.$str("@media"))return e=this.mediaFeatures(),(n=this.block())||s("media definitions require block statements after any features"),a.forget(),r=new Me.Media(n,e,l,i),t.dumpLineNumbers&&(r.debugInfo=o),r;a.restore()},plugin:function(){var e,t,n,r=a.i;if(a.$re(/^@plugin?\s+/)){if(n=(t=this.pluginArgs())?{pluginArgs:t,isPlugin:!0}:{isPlugin:!0},e=this.entities.quoted()||this.entities.url())return a.$char(";")||(a.i=r,s("missing semi-colon on @plugin")),new Me.Import(e,null,n,r,i);a.i=r,s("malformed @plugin statement")}},pluginArgs:function(){if(a.save(),!a.$char("("))return a.restore(),null;var e=a.$re(/^\s*([^\);]+)\)\s*/);return e[1]?(a.forget(),e[1].trim()):(a.restore(),null)},atrule:function(){var e,n,r,o,l,c,h,f=a.i,p=!0,v=!0;if("@"===a.currentChar()){if(n=this.import()||this.plugin()||this.media())return n;if(a.save(),e=a.$re(/^@[a-z-]+/)){switch(o=e,"-"==e.charAt(1)&&e.indexOf("-",2)>0&&(o="@".concat(e.slice(e.indexOf("-",2)+1))),o){case"@charset":l=!0,p=!1;break;case"@namespace":c=!0,p=!1;break;case"@keyframes":case"@counter-style":l=!0;break;case"@document":case"@supports":h=!0,v=!1;break;default:h=!0}if(a.commentStore.length=0,l?(n=this.entity())||s("expected ".concat(e," identifier")):c?(n=this.expression())||s("expected ".concat(e," expression")):h&&(n=this.permissiveValue(/^[{;]/),p="{"===a.currentChar(),n?n.value||(n=null):p||";"===a.currentChar()||s("".concat(e," rule is missing block or ending semi-colon"))),p&&(r=this.blockRuleset()),r||!p&&n&&a.$char(";"))return a.forget(),new Me.AtRule(e,n,r,f,i,t.dumpLineNumbers?u(f):null,v);a.restore("at-rule options not recognised")}}},value:function(){var e,t=[],n=a.i;do{if((e=this.expression())&&(t.push(e),!a.$char(",")))break}while(e);if(t.length>0)return new Me.Value(t,n)},important:function(){if("!"===a.currentChar())return a.$re(/^! *important/)},sub:function(){var e,t;if(a.save(),a.$char("("))return(e=this.addition())&&a.$char(")")?(a.forget(),(t=new Me.Expression([e])).parens=!0,t):void a.restore("Expected ')'");a.restore()},multiplication:function(){var e,t,n,i,r;if(e=this.operand()){for(r=a.isWhitespace(-1);!a.peek(/^\/[*\/]/);){if(a.save(),!(n=a.$char("/")||a.$char("*")||a.$str("./"))){a.forget();break}if(!(t=this.operand())){a.restore();break}a.forget(),e.parensInOp=!0,t.parensInOp=!0,i=new Me.Operation(n,[i||e,t],r),r=a.isWhitespace(-1)}return i||e}},addition:function(){var e,t,n,i,r;if(e=this.multiplication()){for(r=a.isWhitespace(-1);(n=a.$re(/^[-+]\s+/)||!r&&(a.$char("+")||a.$char("-")))&&(t=this.multiplication());)e.parensInOp=!0,t.parensInOp=!0,i=new Me.Operation(n,[i||e,t],r),r=a.isWhitespace(-1);return i||e}},conditions:function(){var e,t,n,i=a.i;if(e=this.condition(!0)){for(;a.peek(/^,\s*(not\s*)?\(/)&&a.$char(",")&&(t=this.condition(!0));)n=new Me.Condition("or",n||e,t,i);return n||e}},condition:function(e){var t,n,i;if(t=this.conditionAnd(e)){if(n=a.$str("or")){if(!(i=this.condition(e)))return;t=new Me.Condition(n,t,i)}return t}},conditionAnd:function(e){var t,n,i,r,s=this;if(t=(r=s.negatedCondition(e)||s.parenthesisCondition(e))||e?r:s.atomicCondition(e)){if(n=a.$str("and")){if(!(i=this.conditionAnd(e)))return;t=new Me.Condition(n,t,i)}return t}},negatedCondition:function(e){if(a.$str("not")){var t=this.parenthesisCondition(e);return t&&(t.negate=!t.negate),t}},parenthesisCondition:function(e){var t;if(a.save(),a.$str("(")){if(t=function(t){var n;if(a.save(),n=t.condition(e)){if(a.$char(")"))return a.forget(),n;a.restore()}else a.restore()}(this))return a.forget(),t;if(t=this.atomicCondition(e)){if(a.$char(")"))return a.forget(),t;a.restore("expected ')' got '".concat(a.currentChar(),"'"))}else a.restore()}else a.restore()},atomicCondition:function(e){var t,n,i,r,o=this.entities,l=a.i;function u(){return this.addition()||o.keyword()||o.quoted()||o.mixinLookup()}if(t=(u=u.bind(this))())return a.$char(">")?r=a.$char("=")?">=":">":a.$char("<")?r=a.$char("=")?"<=":"<":a.$char("=")&&(r=a.$char(">")?"=>":a.$char("<")?"=<":"="),r?(n=u())?i=new Me.Condition(r,t,n,l,!1):s("expected expression"):i=new Me.Condition("=",t,new Me.Keyword("true"),l,!1),i},operand:function(){var e,t=this.entities;a.peek(/^-[@\$\(]/)&&(e=a.$char("-"));var n=this.sub()||t.dimension()||t.color()||t.variable()||t.property()||t.call()||t.quoted(!0)||t.colorKeyword()||t.mixinLookup();return e&&(n.parensInOp=!0,n=new Me.Negative(n)),n},expression:function(){var e,t,n=[],i=a.i;do{(e=this.comment())?n.push(e):(e=this.addition()||this.entity())&&(n.push(e),a.peek(/^\/[\/*]/)||(t=a.$char("/"))&&n.push(new Me.Anonymous(t,i)))}while(e);if(n.length>0)return new Me.Expression(n)},property:function(){var e=a.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);if(e)return e[1]},ruleProperty:function(){var e,t,n=[],r=[];a.save();var s=a.$re(/^([_a-zA-Z0-9-]+)\s*:/);if(s)return n=[new Me.Keyword(s[1])],a.forget(),n;function o(e){var t=a.i,i=a.$re(e);if(i)return r.push(t),n.push(i[1])}for(o(/^(\*?)/);o(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/););if(n.length>1&&o(/^((?:\+_|\+)?)\s*:/)){for(a.forget(),""===n[0]&&(n.shift(),r.shift()),t=0;t1?e-1:e)<1?r+(a-r)*e*6:2*e<1?a:3*e<2?r+(a-r)*(2/3-e)*6:r};if(e instanceof y)return i=t?et(t):e.alpha,new y(e.rgb,i,"hsla");e=et(e)%360/360,t=Ke(et(t)),n=Ke(et(n)),i=Ke(et(i)),r=2*n-(a=n<=.5?n*(t+1):n+t-n*t);var o=[255*s(e+1/3),255*s(e),255*s(e-1/3)];return i=et(i),new y(o,i,"hsla")}catch(e){}},hsv:function(e,t,n){return He.hsva(e,t,n,1)},hsva:function(e,t,n,i){var r,a;e=et(e)%360/360*360,t=et(t),n=et(n),i=et(i);var s=[n,n*(1-t),n*(1-(a=e/60-(r=Math.floor(e/60%6)))*t),n*(1-(1-a)*t)],o=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return He.rgba(255*s[o[r][0]],255*s[o[r][1]],255*s[o[r][2]],i)},hue:function(e){return new ie(Ye(e).h)},saturation:function(e){return new ie(100*Ye(e).s,"%")},lightness:function(e){return new ie(100*Ye(e).l,"%")},hsvhue:function(e){return new ie(Xe(e).h)},hsvsaturation:function(e){return new ie(100*Xe(e).s,"%")},hsvvalue:function(e){return new ie(100*Xe(e).v,"%")},red:function(e){return new ie(e.rgb[0])},green:function(e){return new ie(e.rgb[1])},blue:function(e){return new ie(e.rgb[2])},alpha:function(e){return new ie(Ye(e).a)},luma:function(e){return new ie(e.luma()*e.alpha*100,"%")},luminance:function(e){var t=.2126*e.rgb[0]/255+.7152*e.rgb[1]/255+.0722*e.rgb[2]/255;return new ie(t*e.alpha*100,"%")},saturate:function(e,t,n){if(!e.rgb)return null;var i=Ye(e);return void 0!==n&&"relative"===n.value?i.s+=i.s*t.value/100:i.s+=t.value/100,i.s=Ke(i.s),Ze(e,i)},desaturate:function(e,t,n){var i=Ye(e);return void 0!==n&&"relative"===n.value?i.s-=i.s*t.value/100:i.s-=t.value/100,i.s=Ke(i.s),Ze(e,i)},lighten:function(e,t,n){var i=Ye(e);return void 0!==n&&"relative"===n.value?i.l+=i.l*t.value/100:i.l+=t.value/100,i.l=Ke(i.l),Ze(e,i)},darken:function(e,t,n){var i=Ye(e);return void 0!==n&&"relative"===n.value?i.l-=i.l*t.value/100:i.l-=t.value/100,i.l=Ke(i.l),Ze(e,i)},fadein:function(e,t,n){var i=Ye(e);return void 0!==n&&"relative"===n.value?i.a+=i.a*t.value/100:i.a+=t.value/100,i.a=Ke(i.a),Ze(e,i)},fadeout:function(e,t,n){var i=Ye(e);return void 0!==n&&"relative"===n.value?i.a-=i.a*t.value/100:i.a-=t.value/100,i.a=Ke(i.a),Ze(e,i)},fade:function(e,t){var n=Ye(e);return n.a=t.value/100,n.a=Ke(n.a),Ze(e,n)},spin:function(e,t){var n=Ye(e),i=(n.h+t.value)%360;return n.h=i<0?360+i:i,Ze(e,n)},mix:function(e,t,n){n||(n=new ie(50));var i=n.value/100,r=2*i-1,a=Ye(e).a-Ye(t).a,s=((r*a==-1?r:(r+a)/(1+r*a))+1)/2,o=1-s,l=[e.rgb[0]*s+t.rgb[0]*o,e.rgb[1]*s+t.rgb[1]*o,e.rgb[2]*s+t.rgb[2]*o],u=e.alpha*i+t.alpha*(1-i);return new y(l,u)},greyscale:function(e){return He.desaturate(e,new ie(100))},contrast:function(e,t,n,i){if(!e.rgb)return null;if(void 0===n&&(n=He.rgba(255,255,255,1)),void 0===t&&(t=He.rgba(0,0,0,1)),t.luma()>n.luma()){var r=n;n=t,t=r}return i=void 0===i?.43:et(i),e.luma().5&&(i=1,n=e>.25?Math.sqrt(e):((16*e-12)*e+4)*e),e-(1-2*t)*i*(n-e)},hardlight:function(e,t){return it.overlay(t,e)},difference:function(e,t){return Math.abs(e-t)},exclusion:function(e,t){return e+t-2*e*t},average:function(e,t){return(e+t)/2},negation:function(e,t){return 1-Math.abs(e+t-1)}};for(var rt in it)it.hasOwnProperty(rt)&&(nt[rt]=nt.bind(null,it[rt]));var at=function(e){return Array.isArray(e.value)?e.value:Array(e)},st={_SELF:function(e){return e},extract:function(e,t){return t=t.value-1,at(e)[t]},length:function(e){return new ie(at(e).length)},range:function(e,t,n){var i,r,a=1,s=[];t?(r=t,i=e.value,n&&(a=n.value)):(i=1,r=e);for(var o=i;o<=r.value;o+=a)s.push(new ie(o,r.unit));return new oe(s)},each:function(e,t){var n,i,r=[];i=!e.value||e instanceof pe?e.ruleset?e.ruleset.rules:e.rules?e.rules:Array.isArray(e)?e:[e]:Array.isArray(e.value)?e.value:[e.value];var a="@value",s="@key",o="@index";t.params?(a=t.params[0]&&t.params[0].name,s=t.params[1]&&t.params[1].name,o=t.params[2]&&t.params[2].name,t=t.rules):t=t.ruleset;for(var l=0;ls.value)&&(c[i]=r);else{if(void 0!==l&&o!==l)throw{type:"Argument",message:"incompatible types"};h[o]=c.length,c.push(r)}else Array.isArray(t[n].value)&&Array.prototype.push.apply(t,Array.prototype.slice.call(t[n].value));return 1==c.length?c[0]:(t=c.map(function(e){return e.toCSS(this.context)}).join(this.context.compress?",":", "),new B("".concat(e?"min":"max","(").concat(t,")")))},ft={min:function(){for(var e=arguments.length,t=new Array(e),n=0;n"),r=0;r");return i+="'),i=encodeURIComponent(i),i="data:image/svg+xml,".concat(i),new ve(new pe("'".concat(i,"'"),i,!1,this.index,this.currentFileInfo),this.index,this.currentFileInfo)}}),Z.addMultiple(mt),t},yt=function(e){var t,n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=n.variables,a=new G.Eval(n);"object"!==i(r)||Array.isArray(r)||(r=Object.keys(r).map(function(e){var t=r[e];return t instanceof Me.Value||(t instanceof Me.Expression||(t=new Me.Expression([t])),t=new Me.Value([t])),new Me.Declaration("@".concat(e),t,!1,null,0)}),a.frames=[new Me.Ruleset(null,r)]);var s,o,l=[new Ge.JoinSelectorVisitor,new Ge.MarkVisibleSelectorsVisitor(!0),new Ge.ExtendVisitor,new Ge.ToCSSVisitor({compress:Boolean(n.compress)})],u=[];if(n.pluginManager){o=n.pluginManager.visitor();for(var c=0;c<2;c++)for(o.first();s=o.get();)s.isPreEvalVisitor?0!==c&&-1!==u.indexOf(s)||(u.push(s),s.run(e)):0!==c&&-1!==l.indexOf(s)||(s.isPreVisitor?l.unshift(s):l.push(s))}t=e.eval(a);for(c=0;c=t);n++);this.preProcessors.splice(n,0,{preProcessor:e,priority:t})}},{key:"addPostProcessor",value:function(e,t){var n;for(n=0;n=t);n++);this.postProcessors.splice(n,0,{postProcessor:e,priority:t})}},{key:"addFileManager",value:function(e){this.fileManagers.push(e)}},{key:"getPreProcessors",value:function(){for(var e=[],t=0;t0){var i,r=JSON.stringify(this._sourceMapGenerator.toJSON());this.sourceMapURL?i=this.sourceMapURL:this._sourceMapFilename&&(i=this._sourceMapFilename),this.sourceMapURL=i,this.sourceMap=r}return this._css.join("")}}]),t}()}(e=new Ee(e,t)),a=function(e,t){return function(){function n(e){r(this,n),this.options=e}return s(n,[{key:"toCSS",value:function(t,n,i){var r=new e({contentsIgnoredCharsMap:i.contentsIgnoredChars,rootNode:t,contentsMap:i.contents,sourceMapFilename:this.options.sourceMapFilename,sourceMapURL:this.options.sourceMapURL,outputFilename:this.options.sourceMapOutputFilename,sourceMapBasepath:this.options.sourceMapBasepath,sourceMapRootpath:this.options.sourceMapRootpath,outputSourceFiles:this.options.outputSourceFiles,sourceMapGenerator:this.options.sourceMapGenerator,sourceMapFileInline:this.options.sourceMapFileInline}),a=r.toCSS(n);return this.sourceMap=r.sourceMap,this.sourceMapURL=r.sourceMapURL,this.options.sourceMapInputFilename&&(this.sourceMapInputFilename=r.normalizeFilename(this.options.sourceMapInputFilename)),void 0!==this.options.sourceMapBasepath&&void 0!==this.sourceMapURL&&(this.sourceMapURL=r.removeBasepath(this.sourceMapURL)),a+this.getCSSAppendage()}},{key:"getCSSAppendage",value:function(){var e=this.sourceMapURL;if(this.options.sourceMapFileInline){if(void 0===this.sourceMap)return"";e="data:application/json;base64,".concat(t.encodeBase64(this.sourceMap))}return e?"/*# sourceMappingURL=".concat(e," */"):""}},{key:"getExternalSourceMap",value:function(){return this.sourceMap}},{key:"setExternalSourceMap",value:function(e){this.sourceMap=e}},{key:"isInline",value:function(){return this.options.sourceMapFileInline}},{key:"getSourceMapURL",value:function(){return this.sourceMapURL}},{key:"getOutputFilename",value:function(){return this.options.sourceMapOutputFilename}},{key:"getInputFilename",value:function(){return this.sourceMapInputFilename}}]),n}()}(i,e),o=function(e){return function(){function t(e,n){r(this,t),this.root=e,this.imports=n}return s(t,[{key:"toCSS",value:function(t){var n,i,r={};try{n=yt(this.root,t)}catch(e){throw new $(e,this.imports)}try{var a=Boolean(t.compress);a&&Pe.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.");var s={compress:a,dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(t.strictUnits),numPrecision:8};t.sourceMap?(i=new e(t.sourceMap),r.css=i.toCSS(n,s,this.imports)):r.css=n.toCSS(s)}catch(e){throw new $(e,this.imports)}if(t.pluginManager)for(var o=t.pluginManager.getPostProcessors(),l=0;l=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):"function"==typeof i&&i(t.status,e)}"function"==typeof r.overrideMimeType&&r.overrideMimeType("text/css"),xt.debug("XHR: Getting '".concat(e,"'")),r.open("GET",e,a),r.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),r.send(null),kt.isFileProtocol&&!kt.fileAsync?0===r.status||r.status>=200&&r.status<300?n(r.responseText):i(r.status,e):a?r.onreadystatechange=function(){4==r.readyState&&s(r,n,i)}:s(r,n,i)}},{key:"supports",value:function(){return!0}},{key:"clearFileCache",value:function(){It={}}},{key:"loadFile",value:function(e,t,n,i){t&&!this.isPathAbsolute(e)&&(e=t+e),e=n.ext?this.tryAppendExtension(e,n.ext):e,n=n||{};var r=this.extractUrlParts(e,window.location.href).url,a=this;return new Promise(function(e,t){if(n.useFileCache&&It[r])try{var i=It[r];return e({contents:i,filename:r,webInfo:{lastModified:new Date}})}catch(e){return t({filename:r,message:"Error loading file ".concat(r," error was ").concat(e.message)})}a.doXHR(r,n.mime,function(t,n){It[r]=t,e({contents:t,filename:r,webInfo:{lastModified:n}})},function(e,n){t({type:"File",message:"'".concat(n,"' wasn't found (").concat(e,")"),href:r})})})}}]),t}(),_t=function(e,t){return kt=e,xt=t,Ct},At=function(e){function t(e){var n;return r(this,t),(n=f(this,l(t).call(this))).less=e,n}return o(t,Oe),s(t,[{key:"loadPlugin",value:function(e,t,n,i,r){return new Promise(function(a,s){r.loadFile(e,t,n,i).then(a).catch(s)})}}]),t}(),Mt=function(t,i,r){return{add:function(a,s){r.errorReporting&&"html"!==r.errorReporting?"console"===r.errorReporting?function(e,t){var n=e.filename||t,a=[],s="".concat(e.type||"Syntax","Error: ").concat(e.message||"There is an error in your .less file"," in ").concat(n),o=function(e,t,n){void 0!==e.extract[t]&&a.push("{line} {content}".replace(/\{line\}/,(parseInt(e.line,10)||0)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};e.line&&(o(e,0,""),o(e,1,"line"),o(e,2,""),s+=" on line ".concat(e.line,", column ").concat(e.column+1,":\n").concat(a.join("\n"))),e.stack&&(e.extract||r.logLevel>=4)&&(s+="\nStack Trace\n".concat(e.stack)),i.logger.error(s)}(a,s):"function"==typeof r.errorReporting&&r.errorReporting("add",a,s):function(i,a){var s,o,l="less-error-message:".concat(e(a||"")),u=t.document.createElement("div"),c=[],h=i.filename||a,f=h.match(/([^\/]+(\?.*)?)$/)[1];u.id=l,u.className="less-error-message",o="

    ".concat(i.type||"Syntax","Error: ").concat(i.message||"There is an error in your .less file")+'

    in ').concat(f," ");var p=function(e,t,n){void 0!==e.extract[t]&&c.push('

  • {content}
  • '.replace(/\{line\}/,(parseInt(e.line,10)||0)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};i.line&&(p(i,0,""),p(i,1,"line"),p(i,2,""),o+="on line ".concat(i.line,", column ").concat(i.column+1,":

      ").concat(c.join(""),"
    ")),i.stack&&(i.extract||r.logLevel>=4)&&(o+="
    Stack Trace
    ".concat(i.stack.split("\n").slice(1).join("
    "))),u.innerHTML=o,n.createCSS(t.document,[".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),u.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),"development"===r.env&&(s=setInterval(function(){var e=t.document,n=e.body;n&&(e.getElementById(l)?n.replaceChild(u,e.getElementById(l)):n.insertBefore(u,n.firstChild),clearInterval(s))},10))}(a,s)},remove:function(n){r.errorReporting&&"html"!==r.errorReporting?"console"===r.errorReporting||"function"==typeof r.errorReporting&&r.errorReporting("remove",n):function(n){var i=t.document.getElementById("less-error-message:".concat(e(n)));i&&i.parentNode.removeChild(i)}(n)}}},Pt={javascriptEnabled:!1,depends:!1,compress:!1,lint:!1,paths:[],color:!0,strictImports:!1,insecure:!1,rootpath:"",rewriteUrls:!1,math:0,strictUnits:!1,globalVars:null,modifyVars:null,urlArgs:""};if(window.less)for(var Et in window.less)window.less.hasOwnProperty(Et)&&(Pt[Et]=window.less[Et]);!function(e,i){t(i,n.currentScript(e)),void 0===i.isFileProtocol&&(i.isFileProtocol=/^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(e.location.protocol)),i.async=i.async||!1,i.fileAsync=i.fileAsync||!1,i.poll=i.poll||(i.isFileProtocol?1e3:1500),i.env=i.env||("127.0.0.1"==e.location.hostname||"0.0.0.0"==e.location.hostname||"localhost"==e.location.hostname||e.location.port&&e.location.port.length>0||i.isFileProtocol?"development":"production");var r=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(e.location.hash);r&&(i.dumpLineNumbers=r[1]),void 0===i.useFileCache&&(i.useFileCache=!0),void 0===i.onReady&&(i.onReady=!0),i.relativeUrls&&(i.rewriteUrls="all")}(window,Pt),Pt.plugins=Pt.plugins||[],window.LESS_PLUGINS&&(Pt.plugins=Pt.plugins.concat(window.LESS_PLUGINS));var Rt,Ot,Ft,Vt=function(e,i){var r=e.document,a=St();a.options=i;var s=a.environment,o=_t(i,a.logger),l=new o;s.addFileManager(l),a.FileManager=o,a.PluginLoader=At,function(e,t){t.logLevel=void 0!==t.logLevel?t.logLevel:"development"===t.env?3:1,t.loggers||(t.loggers=[{debug:function(e){t.logLevel>=4&&console.log(e)},info:function(e){t.logLevel>=3&&console.log(e)},warn:function(e){t.logLevel>=2&&console.warn(e)},error:function(e){t.logLevel>=1&&console.error(e)}}]);for(var n=0;n0&&l.childNodes.length>0&&s.firstChild.nodeValue===l.firstChild.nodeValue);var u=t.getElementsByTagName("head")[0];if(null===s||!1===a){var c=i&&i.nextSibling||null;c?c.parentNode.insertBefore(l,c):u.appendChild(l)}if(s&&!1===a&&s.parentNode.removeChild(s),l.styleSheet)try{l.styleSheet.cssText=n}catch(e){throw new Error("Couldn't reassign styleSheet.cssText.")}},i=function(e){var t,n=e.document;return n.currentScript||(t=n.getElementsByTagName("script"))[t.length-1]},r=function(e,t){return(r=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var n in t)t.hasOwnProperty(n)&&(e[n]=t[n])})(e,t)};function o(e,t){function n(){this.constructor=e}r(e,t),e.prototype=null===t?Object.create(t):(n.prototype=t.prototype,new n)}function s(){for(var e=0,t=0,n=arguments.length;tt?1:void 0};var h=function(e){function t(t,n,i){var r=e.call(this)||this,o=r;return Array.isArray(t)?r.rgb=t:t.length>=6?(r.rgb=[],t.match(/.{2}/g).map((function(e,t){t<3?o.rgb.push(parseInt(e,16)):o.alpha=parseInt(e,16)/255}))):(r.rgb=[],t.split("").map((function(e,t){t<3?o.rgb.push(parseInt(e+e,16)):o.alpha=parseInt(e+e,16)/255}))),r.alpha=r.alpha||("number"==typeof n?n:1),void 0!==i&&(r.value=i),r}return o(t,e),t.prototype.luma=function(){var e=this.rgb[0]/255,t=this.rgb[1]/255,n=this.rgb[2]/255;return.2126*(e=e<=.03928?e/12.92:Math.pow((e+.055)/1.055,2.4))+.7152*(t=t<=.03928?t/12.92:Math.pow((t+.055)/1.055,2.4))+.0722*(n=n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))},t.prototype.genCSS=function(e,t){t.add(this.toCSS(e))},t.prototype.toCSS=function(e,t){var n,i,r,o=e&&e.compress&&!t,s=[];if(i=this.fround(e,this.alpha),this.value)if(0===this.value.indexOf("rgb"))i<1&&(r="rgba");else{if(0!==this.value.indexOf("hsl"))return this.value;r=i<1?"hsla":"hsl"}else i<1&&(r="rgba");switch(r){case"rgba":s=this.rgb.map((function(e){return f(Math.round(e),255)})).concat(f(i,1));break;case"hsla":s.push(f(i,1));case"hsl":n=this.toHSL(),s=[this.fround(e,n.h),this.fround(e,100*n.s)+"%",this.fround(e,100*n.l)+"%"].concat(s)}if(r)return r+"("+s.join(","+(o?"":" "))+")";if(n=this.toRGB(),o){var a=n.split("");a[1]===a[2]&&a[3]===a[4]&&a[5]===a[6]&&(n="#"+a[1]+a[3]+a[5])}return n},t.prototype.operate=function(e,n,i){for(var r=new Array(3),o=this.alpha*(1-i.alpha)+i.alpha,s=0;s<3;s++)r[s]=this._operate(e,n,this.rgb[s],i.rgb[s]);return new t(r,o)},t.prototype.toRGB=function(){return p(this.rgb)},t.prototype.toHSL=function(){var e,t,n=this.rgb[0]/255,i=this.rgb[1]/255,r=this.rgb[2]/255,o=this.alpha,s=Math.max(n,i,r),a=Math.min(n,i,r),l=(s+a)/2,u=s-a;if(s===a)e=t=0;else{switch(t=l>.5?u/(2-s-a):u/(s+a),s){case n:e=(i-r)/u+(i=0&&"\n"!==t.charAt(n);)r++;return"number"==typeof e&&(i=(t.slice(0,e).match(/\n/g)||"").length),{line:i,column:r}}function C(e){var t,n=e.length,i=new Array(n);for(t=0;t|Function):(\d+):(\d+)/,R=function(e,t,n){Error.call(this);var i=e.filename||n;if(this.message=e.message,this.stack=e.stack,t&&i){var r=t.contents[i],o=I(e.index,r),s=o.line,a=o.column,l=e.call&&I(e.call,r).line,u=r?r.split("\n"):"";if(this.type=e.type||"Syntax",this.filename=i,this.index=e.index,this.line="number"==typeof s?s+1:null,this.column=a,!this.line&&this.stack){var c=this.stack.match(E),h=new Function("a","throw new Error()"),f=0;try{h()}catch(e){var p=e.stack.match(E);f=1-parseInt(p[2])}c&&(c[2]&&(this.line=parseInt(c[2])+f),c[3]&&(this.column=parseInt(c[3])))}this.callLine=l+1,this.callExtract=u[l],this.extract=[u[this.line-2],u[this.line-1],u[this.line]]}};if(void 0===Object.create){var F=function(){};F.prototype=Error.prototype,R.prototype=new F}else R.prototype=Object.create(Error.prototype);R.prototype.constructor=R,R.prototype.toString=function(e){void 0===e&&(e={});var t="",n=this.extract||[],i=[],r=function(e){return e};if(e.stylize){var o=typeof e.stylize;if("function"!==o)throw Error("options.stylize should be a function, got a "+o+"!");r=e.stylize}if(null!==this.line){if("string"==typeof n[0]&&i.push(r(this.line-1+" "+n[0],"grey")),"string"==typeof n[1]){var s=this.line+" ";n[1]&&(s+=n[1].slice(0,this.column)+r(r(r(n[1].substr(this.column,1),"bold")+n[1].slice(this.column+1),"red"),"inverse")),i.push(s)}"string"==typeof n[2]&&i.push(r(this.line+1+" "+n[2],"grey")),i=i.join("\n")+r("","reset")+"\n"}return t+=r(this.type+"Error: "+this.message,"red"),this.filename&&(t+=r(" in ","red")+this.filename),this.line&&(t+=r(" on line "+this.line+", column "+(this.column+1)+":","grey")),t+="\n"+i,this.callLine&&(t+=r("from ","red")+(this.filename||"")+"/n",t+=r(this.callLine,"grey")+" "+this.callExtract+"/n"),t};var V=function(e){function t(t,n,i,r,o,s){var a=e.call(this)||this;return a.extendList=n,a.condition=i,a.evaldCondition=!i,a._index=r,a._fileInfo=o,a.elements=a.getElements(t),a.mixinElements_=void 0,a.copyVisibilityInfo(s),a.setParent(a.elements,a),a}return o(t,e),t.prototype.accept=function(e){this.elements&&(this.elements=e.visitArray(this.elements)),this.extendList&&(this.extendList=e.visitArray(this.extendList)),this.condition&&(this.condition=e.visit(this.condition))},t.prototype.createDerived=function(e,n,i){var r=new t(e=this.getElements(e),n||this.extendList,null,this.getIndex(),this.fileInfo(),this.visibilityInfo());return r.evaldCondition=null!=i?i:this.evaldCondition,r.mediaEmpty=this.mediaEmpty,r},t.prototype.getElements=function(e){return e?("string"==typeof e&&this.parse.parseNode(e,["selector"],this._index,this._fileInfo,(function(t,n){if(t)throw new R({index:t.index,message:t.message},this.parse.imports,this._fileInfo.filename);e=n[0].elements})),e):[new g("","&",!1,this._index,this._fileInfo)]},t.prototype.createEmptySelectors=function(){var e=[new t([new g("","&",!1,this._index,this._fileInfo)],null,null,this._index,this._fileInfo)];return e[0].mediaEmpty=!0,e},t.prototype.match=function(e){var t,n,i=this.elements,r=i.length;if(0===(t=(e=e.mixinElements()).length)||ry.PARENS_DIVISION)||this.parensStack&&this.parensStack.length))},e.prototype.pathRequiresRewrite=function(e){return(this.rewriteUrls===w?W:G)(e)},e.prototype.rewritePath=function(e,t){var n;return t=t||"",n=this.normalizePath(t+e),W(e)&&G(t)&&!1===W(n)&&(n="./"+n),n},e.prototype.normalizePath=function(e){var t,n=e.split("/").reverse();for(e=[];0!==n.length;)switch(t=n.pop()){case".":break;case"..":0===e.length||".."===e[e.length-1]?e.push(t):e.pop();break;default:e.push(t)}return e.join("/")},e}();var J=function e(t){return{_data:{},add:function(e,t){e=e.toLowerCase(),this._data.hasOwnProperty(e),this._data[e]=t},addMultiple:function(e){var t=this;Object.keys(e).forEach((function(n){t.add(n,e[n])}))},get:function(e){return this._data[e]||t&&t.get(e)},getLocalFunctions:function(){return this._data},inherit:function(){return e(this)},create:function(t){return e(t)}}}(null),H={eval:function(){var e=this.value_,t=this.error_;if(t)throw t;if(null!=e)return e?$.True:$.False},value:function(e){this.value_=e},error:function(e){this.error_=e},reset:function(){this.value_=this.error_=null}},Q=function(e){function t(t,n,i,r){var o=e.call(this)||this;return o.selectors=t,o.rules=n,o._lookups={},o._variables=null,o._properties=null,o.strictImports=i,o.copyVisibilityInfo(r),o.allowRoot=!0,o.setParent(o.selectors,o),o.setParent(o.rules,o),o}return o(t,e),t.prototype.isRulesetLike=function(){return!0},t.prototype.accept=function(e){this.paths?this.paths=e.visitArray(this.paths,!0):this.selectors&&(this.selectors=e.visitArray(this.selectors)),this.rules&&this.rules.length&&(this.rules=e.visitArray(this.rules))},t.prototype.eval=function(e){var n,i,r,o,s,a=!1;if(this.selectors&&(i=this.selectors.length)){for(n=new Array(i),H.error({type:"Syntax",message:"it is currently only allowed in parametric mixin guards,"}),o=0;o0;e--){var t=this.rules[e-1];if(t instanceof N)return this.parseValue(t)}},t.prototype.parseValue=function(e){var t=this;function n(e){return e.value instanceof L&&!e.parsed?("string"==typeof e.value.value?this.parse.parseNode(e.value.value,["value","important"],e.value.getIndex(),e.fileInfo(),(function(t,n){t&&(e.parsed=!0),n&&(e.value=n[0],e.important=n[1]||"",e.parsed=!0)})):e.parsed=!0,e):e}if(Array.isArray(e)){var i=[];return e.forEach((function(e){i.push(n.call(t,e))})),i}return n.call(t,e)},t.prototype.rulesets=function(){if(!this.rules)return[];var e,t,n=[],i=this.rules;for(e=0;t=i[e];e++)t.isRuleset&&n.push(t);return n},t.prototype.prependRule=function(e){var t=this.rules;t?t.unshift(e):this.rules=[e],this.setParent(e,this)},t.prototype.find=function(e,t,n){void 0===t&&(t=this);var i,r,o=[],s=e.toCSS();return s in this._lookups?this._lookups[s]:(this.rulesets().forEach((function(s){if(s!==t)for(var a=0;ai){if(!n||n(s)){r=s.find(new V(e.elements.slice(i)),t,n);for(var l=0;l0&&t.add(l),e.firstSelector=!0,s[0].genCSS(e,t),e.firstSelector=!1,i=1;i0?(o=(r=C(e)).pop(),s=i.createDerived(C(o.elements))):s=i.createDerived([]),t.length>0){var a=n.combinator,l=t[0].elements[0];a.emptyOrWhitespace&&!l.combinator.emptyOrWhitespace&&(a=l.combinator),s.elements.push(new g(a,l.value,n.isVariable,n._index,n._fileInfo)),s.elements=s.elements.concat(t[0].elements.slice(1))}if(0!==s.elements.length&&r.push(s),t.length>1){var u=t.slice(1);u=u.map((function(e){return e.createDerived(e.elements,[])})),r=r.concat(u)}return r}function s(e,t,n,i,r){var s;for(s=0;s0?i[i.length-1]=i[i.length-1].createDerived(i[i.length-1].elements.concat(e)):i.push(new V(e));else t.push([new V(e)])}function l(e,t){var n=t.createDerived(t.elements,t.extendList,t.evaldCondition);return n.copyVisibilityInfo(e),n}var u,c;if(!function e(t,n,l){var u,c,h,f,p,d,m,y,b,w,x,S,I=!1;for(f=[],p=[[]],u=0;y=l.elements[u];u++)if("&"!==y.value){var C=(S=void 0,(x=y).value instanceof v&&(S=x.value.value)instanceof V?S:null);if(null!=C){a(f,p);var _,k=[],A=[];for(_=e(k,n,C),I=I||_,h=0;h0&&m[0].elements.push(new g(y.combinator,"",y.isVariable,y._index,y._fileInfo)),d.push(m);else for(h=0;h0&&(t.push(p[u]),w=p[u][b-1],p[u][b-1]=w.createDerived(w.elements,l.extendList));return I}(c=[],t,n))if(t.length>0)for(c=[],u=0;u0)for(t=0;t-1e-6&&(i=n.toFixed(20).replace(/0+$/,"")),e&&e.compress){if(0===n&&this.unit.isLength())return void t.add(i);n>0&&n<1&&(i=i.substr(1))}t.add(i),this.unit.genCSS(e,t)},t.prototype.operate=function(e,n,i){var r=this._operate(e,n,this.value,i.value),o=this.unit.clone();if("+"===n||"-"===n)if(0===o.numerator.length&&0===o.denominator.length)o=i.unit.clone(),this.unit.backupUnit&&(o.backupUnit=this.unit.backupUnit);else if(0===i.unit.numerator.length&&0===o.denominator.length);else{if(i=i.convertTo(this.unit.usedUnits()),e.strictUnits&&i.unit.toString()!==o.toString())throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '"+o.toString()+"' and '"+i.unit.toString()+"'.");r=this._operate(e,n,this.value,i.value)}else"*"===n?(o.numerator=o.numerator.concat(i.unit.numerator).sort(),o.denominator=o.denominator.concat(i.unit.denominator).sort(),o.cancel()):"/"===n&&(o.numerator=o.numerator.concat(i.unit.denominator).sort(),o.denominator=o.denominator.concat(i.unit.numerator).sort(),o.cancel());return new t(r,o)},t.prototype.compare=function(e){var n,i;if(e instanceof t){if(this.unit.isEmpty()||e.unit.isEmpty())n=this,i=e;else if(n=this.unify(),i=e.unify(),0!==n.unit.compare(i.unit))return;return c.numericCompare(n.value,i.value)}},t.prototype.unify=function(){return this.convertTo({length:"px",duration:"s",angle:"rad"})},t.prototype.convertTo=function(e){var n,i,r,o,s,a=this.value,u=this.unit.clone(),c={};if("string"==typeof e){for(n in l)l[n].hasOwnProperty(e)&&((c={})[n]=e);e=c}for(i in s=function(e,t){return r.hasOwnProperty(e)?(t?a/=r[e]/r[o]:a*=r[e]/r[o],o):e},e)e.hasOwnProperty(i)&&(o=e[i],r=l[i],u.map(s));return u.cancel(),new t(a,u)},t}(c);X.prototype.type="Dimension";var ee=y,te=function(e){function t(t,n,i){var r=e.call(this)||this;return r.op=t.trim(),r.operands=n,r.isSpaced=i,r}return o(t,e),t.prototype.accept=function(e){this.operands=e.visitArray(this.operands)},t.prototype.eval=function(e){var n,i=this.operands[0].eval(e),r=this.operands[1].eval(e);if(e.isMathOn(this.op)){if(n="./"===this.op?"/":this.op,i instanceof X&&r instanceof h&&(i=i.toColor()),r instanceof X&&i instanceof h&&(r=r.toColor()),!i.operate){if(i instanceof t&&"/"===i.op&&e.math===ee.PARENS_DIVISION)return new t(this.op,[i,r],this.isSpaced);throw{type:"Operation",message:"Operation on an invalid type"}}return i.operate(e,n,r)}return new t(this.op,[i,r],this.isSpaced)},t.prototype.genCSS=function(e,t){this.operands[0].genCSS(e,t),this.isSpaced&&t.add(" "),t.add(this.op),this.isSpaced&&t.add(" "),this.operands[1].genCSS(e,t)},t}(c);te.prototype.type="Operation";var ne=y,ie=function(e){function t(t,n){var i=e.call(this)||this;if(i.value=t,i.noSpacing=n,!t)throw new Error("Expression requires an array parameter");return i}return o(t,e),t.prototype.accept=function(e){this.value=e.visitArray(this.value)},t.prototype.eval=function(e){var n,i=e.isMathOn(),r=this.parens&&(e.math!==ne.STRICT_LEGACY||!this.parensInOp),o=!1;return r&&e.inParenthesis(),this.value.length>1?n=new t(this.value.map((function(t){return t.eval?t.eval(e):t})),this.noSpacing):1===this.value.length?(!this.value[0].parens||this.value[0].parensInOp||e.inCalc||(o=!0),n=this.value[0].eval(e)):n=this,r&&e.outOfParenthesis(),!this.parens||!this.parensInOp||i||o||n instanceof X||(n=new v(n)),n},t.prototype.genCSS=function(e,t){for(var n=0;n1){var n=new V([],null,null,this.getIndex(),this.fileInfo()).createEmptySelectors();(t=new Q(n,e.mediaBlocks)).multiMedia=!0,t.copyVisibilityInfo(this.visibilityInfo()),this.setParent(t,this)}return delete e.mediaBlocks,delete e.mediaPath,t},t.prototype.evalNested=function(e){var t,n,i=e.mediaPath.concat([this]);for(t=0;t0;t--)e.splice(t,0,new L("and"));return new ie(e)}))),this.setParent(this.features,this),new Q([],[])},t.prototype.permute=function(e){if(0===e.length)return[];if(1===e.length)return e[0];for(var t=[],n=this.permute(e.slice(1)),i=0;i1?"["+e.value.map((function(e){return e.toCSS()})).join(", ")+"]":e.toCSS()},t}(c));pe.prototype.type="JavaScript";var ve=function(e){function t(t,n){var i=e.call(this)||this;return i.key=t,i.value=n,i}return o(t,e),t.prototype.accept=function(e){this.value=e.visit(this.value)},t.prototype.eval=function(e){return this.value.eval?new t(this.key,this.value.eval(e)):this},t.prototype.genCSS=function(e,t){t.add(this.key+"="),this.value.genCSS?this.value.genCSS(e,t):t.add(this.value)},t}(c);ve.prototype.type="Assignment";var de=function(e){function t(t,n,i,r,o){var s=e.call(this)||this;return s.op=t.trim(),s.lvalue=n,s.rvalue=i,s._index=r,s.negate=o,s}return o(t,e),t.prototype.accept=function(e){this.lvalue=e.visit(this.lvalue),this.rvalue=e.visit(this.rvalue)},t.prototype.eval=function(e){var t=function(e,t,n){switch(e){case"and":return t&&n;case"or":return t||n;default:switch(c.compare(t,n)){case-1:return"<"===e||"=<"===e||"<="===e;case 0:return"="===e||">="===e||"=<"===e||"<="===e;case 1:return">"===e||">="===e;default:return!1}}}(this.op,this.lvalue.eval(e),this.rvalue.eval(e));return this.negate?!t:t},t}(c);de.prototype.type="Condition";var me=function(e){function t(t){var n=e.call(this)||this;return n.value=t,n}return o(t,e),t}(c);me.prototype.type="UnicodeDescriptor";var ge=function(e){function t(t){var n=e.call(this)||this;return n.value=t,n}return o(t,e),t.prototype.genCSS=function(e,t){t.add("-"),this.value.genCSS(e,t)},t.prototype.eval=function(e){return e.isMathOn()?new te("*",[new X(-1),this.value]).eval(e):new t(this.value.eval(e))},t}(c);ge.prototype.type="Negative";var ye=function(e){function t(n,i,r,o,s){var a=e.call(this)||this;switch(a.selector=n,a.option=i,a.object_id=t.next_id++,a.parent_ids=[a.object_id],a._index=r,a._fileInfo=o,a.copyVisibilityInfo(s),a.allowRoot=!0,i){case"all":a.allowBefore=!0,a.allowAfter=!0;break;default:a.allowBefore=!1,a.allowAfter=!1}return a.setParent(a.selector,a),a}return o(t,e),t.prototype.accept=function(e){this.selector=e.visit(this.selector)},t.prototype.eval=function(e){return new t(this.selector.eval(e),this.option,this.getIndex(),this.fileInfo(),this.visibilityInfo())},t.prototype.clone=function(e){return new t(this.selector,this.option,this.getIndex(),this.fileInfo(),this.visibilityInfo())},t.prototype.findSelfSelectors=function(e){var t,n,i=[];for(t=0;t0&&n.length&&""===n[0].combinator.value&&(n[0].combinator.value=" "),i=i.concat(e[t].elements);this.selfSelectors=[new V(i)],this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo())},t}(c);ye.next_id=0,ye.prototype.type="Extend";var be=function(e){function t(t,n,i){var r=e.call(this)||this;return r.variable=t,r._index=n,r._fileInfo=i,r.allowRoot=!0,r}return o(t,e),t.prototype.eval=function(e){var t,n=new se(this.variable,this.getIndex(),this.fileInfo()).eval(e),i=new R({message:"Could not evaluate variable call "+this.variable});if(!n.ruleset){if(n.rules)t=n;else if(Array.isArray(n))t=new Q("",n);else{if(!Array.isArray(n.value))throw i;t=new Q("",n.value)}n=new Z(t)}if(n.ruleset)return n.callEval(e);throw i},t}(c);be.prototype.type="VariableCall";var we=function(e){function t(t,n,i,r){var o=e.call(this)||this;return o.value=t,o.lookups=n,o._index=i,o._fileInfo=r,o}return o(t,e),t.prototype.eval=function(e){var t,n,i=this.value.eval(e);for(t=0;tthis.params.length)return!1}n=Math.min(o,this.arity);for(var s=0;s0){for(c=!0,a=0;a0)f=2;else if(f=1,p[1]+p[2]>1)throw{type:"Runtime",message:"Ambiguous use of `default()` found when matching for `"+this.format(m)+"`",index:this.getIndex(),filename:this.fileInfo().filename};for(a=0;a=0;s--){var a=o[s];if(a[r?"supportsSync":"supports"](e,t,n,i))return a}return null},e.prototype.addFileManager=function(e){this.fileManagers.push(e)},e.prototype.clearFileManagers=function(){this.fileManagers=[]},e}(),ke=function(){function e(){}return e.prototype.getPath=function(e){var t=e.lastIndexOf("?");return t>0&&(e=e.slice(0,t)),(t=e.lastIndexOf("/"))<0&&(t=e.lastIndexOf("\\")),t<0?"":e.slice(0,t+1)},e.prototype.isPathWithExtension=function(e,t){var n=e.lastIndexOf(t);return-1!==n&&n===e.length-t.length},e.prototype.tryAppendExtension=function(e,t){return this.isPathWithExtension(e,t)?e:e+t},e.prototype.tryAppendLessExtension=function(e){return this.tryAppendExtension(e,".less")},e.prototype.supportsSync=function(){return!1},e.prototype.alwaysMakePathsAbsolute=function(){return!1},e.prototype.isPathAbsolute=function(e){return/^(?:[a-z-]+:|\/|\\|#)/i.test(e)},e.prototype.join=function(e,t){return e?e+t:t},e.prototype.pathDiff=function(e,t){var n,i,r,o,s=this.extractUrlParts(e),a=this.extractUrlParts(t),l="";if(s.hostPart!==a.hostPart)return"";for(i=Math.max(a.directories.length,s.directories.length),n=0;nparseInt(t[n])?-1:1;return 0},e.prototype.versionToString=function(e){for(var t="",n=0;n0;){var e=this.imports[0];if(!e.isReady)return;this.imports=this.imports.slice(1),e.callback.apply(null,e.args)}if(0===this.variableImports.length)break;var t=this.variableImports[0];this.variableImports=this.variableImports.slice(1),t()}}finally{this._currentDepth--}0===this._currentDepth&&this._onSequencerEmpty&&this._onSequencerEmpty()},e}(),Ve=function(e,t){this._visitor=new Re(this),this._importer=e,this._finish=t,this.context=new j.Eval,this.importCount=0,this.onceFileDetectionMap={},this.recursionDetector={},this._sequencer=new Fe(this._onSequencerEmpty.bind(this))};Ve.prototype={isReplacing:!1,run:function(e){try{this._visitor.visit(e)}catch(e){this.error=e}this.isFinished=!0,this._sequencer.tryRun()},_onSequencerEmpty:function(){this.isFinished&&this._finish(this.error)},visitImport:function(e,t){var n=e.options.inline;if(!e.css||n){var i=new j.Eval(this.context,C(this.context.frames)),r=i.frames[0];this.importCount++,e.isVariableImport()?this._sequencer.addVariableImport(this.processImportNode.bind(this,e,i,r)):this.processImportNode(e,i,r)}t.visitDeeper=!1},processImportNode:function(e,t,n){var i,r=e.options.inline;try{i=e.evalForImport(t)}catch(t){t.filename||(t.index=e.getIndex(),t.filename=e.fileInfo().filename),e.css=!0,e.error=t}if(!i||i.css&&!r)this.importCount--,this.isFinished&&this._sequencer.tryRun();else{i.options.multiple&&(t.importMultiple=!0);for(var o=void 0===i.css,s=0;s=0||(a=[u.selfSelectors[0]],(o=f.findMatch(l,a)).length&&(l.hasFoundMatches=!0,l.selfSelectors.forEach((function(e){var t=u.visibilityInfo();s=f.extendSelector(o,a,e,l.isVisible()),(c=new Ie.Extend(u.selector,u.option,0,u.fileInfo(),t)).selfSelectors=s,s[s.length-1].extendList=[c],h.push(c),c.ruleset=u.ruleset,c.parent_ids=c.parent_ids.concat(u.parent_ids,l.parent_ids),u.firstExtendOnThisSelectorPath&&(c.firstExtendOnThisSelectorPath=!0,u.ruleset.paths.push(s))}))));if(h.length){if(this.extendChainCount++,n>100){var p="{unable to calculate}",v="{unable to calculate}";try{p=h[0].selfSelectors[0].toCSS(),v=h[0].selector.toCSS()}catch(e){}throw{message:"extend circular reference detected. One of the circular extends is currently:"+p+":extend("+v+")"}}return h.concat(f.doExtendChaining(h,t,n+1))}return h},e.prototype.visitDeclaration=function(e,t){t.visitDeeper=!1},e.prototype.visitMixinDefinition=function(e,t){t.visitDeeper=!1},e.prototype.visitSelector=function(e,t){t.visitDeeper=!1},e.prototype.visitRuleset=function(e,t){if(!e.root){var n,i,r,o,s=this.allExtendsStack[this.allExtendsStack.length-1],a=[],l=this;for(r=0;r0&&u[l.matched].combinator.value!==s?l=null:l.matched++,l&&(l.finished=l.matched===u.length,l.finished&&!e.allowAfter&&(r+1u&&c>0&&(h[h.length-1].elements=h[h.length-1].elements.concat(t[u].elements.slice(c)),c=0,u++),l=o.elements.slice(c,a.index).concat([s]).concat(n.elements.slice(1)),u===a.pathIndex&&r>0?h[h.length-1].elements=h[h.length-1].elements.concat(l):(h=h.concat(t.slice(u,a.pathIndex))).push(new Ie.Selector(l)),u=a.endPathIndex,(c=a.endPathElementIndex)>=t[u].elements.length&&(c=0,u++);return u0&&(h[h.length-1].elements=h[h.length-1].elements.concat(t[u].elements.slice(c)),u++),h=(h=h.concat(t.slice(u,t.length))).map((function(e){var t=e.createDerived(e.elements);return i?t.ensureVisibility():t.ensureInvisibility(),t}))},e.prototype.visitMedia=function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},e.prototype.visitMediaOut=function(e){var t=this.allExtendsStack.length-1;this.allExtendsStack.length=t},e.prototype.visitAtRule=function(e,t){var n=e.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length-1]);n=n.concat(this.doExtendChaining(n,e.allExtends)),this.allExtendsStack.push(n)},e.prototype.visitAtRuleOut=function(e){var t=this.allExtendsStack.length-1;this.allExtendsStack.length=t},e}(),De=function(){function e(){this.contexts=[[]],this._visitor=new Re(this)}return e.prototype.run=function(e){return this._visitor.visit(e)},e.prototype.visitDeclaration=function(e,t){t.visitDeeper=!1},e.prototype.visitMixinDefinition=function(e,t){t.visitDeeper=!1},e.prototype.visitRuleset=function(e,t){var n,i=this.contexts[this.contexts.length-1],r=[];this.contexts.push(r),e.root||((n=e.selectors)&&(n=n.filter((function(e){return e.getIsOutput()})),e.selectors=n.length?n:n=null,n&&e.joinSelectors(r,i,n)),n||(e.rules=null),e.paths=r)},e.prototype.visitRulesetOut=function(e){this.contexts.length=this.contexts.length-1},e.prototype.visitMedia=function(e,t){var n=this.contexts[this.contexts.length-1];e.rules[0].root=0===n.length||n[0].multiMedia},e.prototype.visitAtRule=function(e,t){var n=this.contexts[this.contexts.length-1];e.rules&&e.rules.length&&(e.rules[0].root=e.isRooted||0===n.length||null)},e}(),Ne=function(){function e(e){this._visitor=new Re(this),this._context=e}return e.prototype.containsSilentNonBlockedChild=function(e){var t;if(!e)return!1;for(var n=0;n0},e.prototype.resolveVisibility=function(e,t){if(!e.blocksVisibility()){if(this.isEmpty(e)&&!this.containsSilentNonBlockedChild(t))return;return e}var n=e.rules[0];if(this.keepOnlyVisibleChilds(n),!this.isEmpty(n))return e.ensureVisibility(),e.removeVisibilityBlock(),e},e.prototype.isVisibleRuleset=function(e){return!!e.firstRoot||!this.isEmpty(e)&&!(!e.root&&!this.hasVisibleSelector(e))},e}(),Be=function(e){this._visitor=new Re(this),this._context=e,this.utils=new Ne(e)};Be.prototype={isReplacing:!0,run:function(e){return this._visitor.visit(e)},visitDeclaration:function(e,t){if(!e.blocksVisibility()&&!e.variable)return e},visitMixinDefinition:function(e,t){e.frames=[]},visitExtend:function(e,t){},visitComment:function(e,t){if(!e.blocksVisibility()&&!e.isSilent(this._context))return e},visitMedia:function(e,t){var n=e.rules[0].rules;return e.accept(this._visitor),t.visitDeeper=!1,this.utils.resolveVisibility(e,n)},visitImport:function(e,t){if(!e.blocksVisibility())return e},visitAtRule:function(e,t){return e.rules&&e.rules.length?this.visitAtRuleWithBody(e,t):this.visitAtRuleWithoutBody(e,t)},visitAnonymous:function(e,t){if(!e.blocksVisibility())return e.accept(this._visitor),e},visitAtRuleWithBody:function(e,t){var n=function(e){var t=e.rules;return function(e){var t=e.rules;return 1===t.length&&(!t[0].paths||0===t[0].paths.length)}(e)?t[0].rules:t}(e);return e.accept(this._visitor),t.visitDeeper=!1,this.utils.isEmpty(e)||this._mergeRules(e.rules[0].rules),this.utils.resolveVisibility(e,n)},visitAtRuleWithoutBody:function(e,t){if(!e.blocksVisibility()){if("@charset"===e.name){if(this.charset){if(e.debugInfo){var n=new Ie.Comment("/* "+e.toCSS(this._context).replace(/\n/g,"")+" */\n");return n.debugInfo=e.debugInfo,this._visitor.visit(n)}return}this.charset=!0}return e}},checkValidNodes:function(e,t){if(e)for(var n=0;n0?e.accept(this._visitor):e.rules=null,t.visitDeeper=!1}return e.rules&&(this._mergeRules(e.rules),this._removeDuplicateRules(e.rules)),this.utils.isVisibleRuleset(e)&&(e.ensureVisibility(),i.splice(0,0,e)),1===i.length?i[0]:i},_compileRulesetPaths:function(e){e.paths&&(e.paths=e.paths.filter((function(e){var t;for(" "===e[0].elements[0].combinator.value&&(e[0].elements[0].combinator=new Ie.Combinator("")),t=0;t=0;i--)if((n=e[i])instanceof Ie.Declaration)if(r[n.name]){(t=r[n.name])instanceof Ie.Declaration&&(t=r[n.name]=[r[n.name].toCSS(this._context)]);var o=n.toCSS(this._context);-1!==t.indexOf(o)?e.splice(i,1):t.push(o)}else r[n.name]=n}},_mergeRules:function(e){if(e){for(var t={},n=[],i=0;i0){var t=e[0],n=[],i=[new Ie.Expression(n)];e.forEach((function(e){"+"===e.merge&&n.length>0&&i.push(new Ie.Expression(n=[])),n.push(e.value),t.important=t.important||e.important})),t.value=new Ie.Value(i)}}))}}};var Ue={Visitor:Re,ImportVisitor:Ve,MarkVisibleSelectorsVisitor:Oe,ExtendVisitor:Le,JoinSelectorVisitor:De,ToCSSVisitor:Be},je=function(){var e,t,n,i,r,o,s,a=[],l={};function u(n){for(var i,a,c,h=l.i,f=t,p=l.i-s,v=l.i+o.length-p,d=l.i+=n,m=e;l.i=0){c={index:l.i,text:m.substr(l.i,y+2-l.i),isLineComment:!1},l.i+=c.text.length-1,l.commentStore.push(c);continue}}break}if(32!==i&&10!==i&&9!==i&&13!==i)break}if(o=o.slice(n+l.i-d+p),s=l.i,!o.length){if(tn||l.i===n&&e&&!i)&&(n=l.i,i=e);var r=a.pop();o=r.current,s=l.i=r.i,t=r.j},l.forget=function(){a.pop()},l.isWhitespace=function(t){var n=l.i+(t||0),i=e.charCodeAt(n);return 32===i||13===i||9===i||10===i},l.$re=function(e){l.i>s&&(o=o.slice(l.i-s),s=l.i);var t=e.exec(o);return t?(u(t[0].length),"string"==typeof t?t:1===t.length?t[0]:t):null},l.$char=function(t){return e.charAt(l.i)!==t?null:(u(1),t)},l.$str=function(t){for(var n=t.length,i=0;ih&&(d=!1)}}while(d);return r||null},l.autoCommentAbsorb=!0,l.commentStore=[],l.finished=!1,l.peek=function(t){if("string"==typeof t){for(var n=0;n57||t<43||47===t||44===t},l.start=function(i,a,c){e=i,l.i=t=s=n=0,r=a?function(e,t){var n,i,r,o,s,a,l,u,c,h=e.length,f=0,p=0,v=[],d=0;function m(t){var n=s-d;n<512&&!t||!n||(v.push(e.slice(d,s+1)),d=s+1)}for(s=0;s=97&&l<=122||l<34))switch(l){case 40:p++,i=s;continue;case 41:if(--p<0)return t("missing opening `(`",s);continue;case 59:p||m();continue;case 123:f++,n=s;continue;case 125:if(--f<0)return t("missing opening `{`",s);f||p||m();continue;case 92:if(s96)){if(u==l){c=1;break}if(92==u){if(s==h-1)return t("unescaped `\\`",s);s++}}if(c)continue;return t("unmatched `"+String.fromCharCode(l)+"`",a);case 47:if(p||s==h-1)continue;if(47==(u=e.charCodeAt(s+1)))for(s+=2;sn&&o>r?"missing closing `}` or `*/`":"missing closing `}`",n):0!==p?t("missing closing `)`",i):(m(!0),v)}(i,c):[i],o=r[0],u(0)},l.end=function(){var t,r=l.i>=e.length;return l.i=e.length-1,furthestChar:e[l.i]}},l},qe=function e(t,n,i){var r,o=je();function s(e,t){throw new R({index:o.i,filename:i.filename,type:t||"Syntax",message:e},n)}function a(e,t){var n=e instanceof Function?e.call(r):o.$re(e);if(n)return n;s(t||("string"==typeof e?"expected '"+e+"' got '"+o.currentChar()+"'":"unexpected token"))}function l(e,t){if(o.$char(e))return e;s(t||"expected '"+e+"' got '"+o.currentChar()+"'")}function u(e){var t=i.filename;return{lineNumber:I(e,o.getInput()).line+1,fileName:t}}return{parserInput:o,imports:n,fileInfo:i,parseNode:function(e,t,i,s,a){var l,u=[],c=o;try{c.start(e,!1,(function(e,t){a({message:e,index:t+i})}));for(var h,f=0,p=void 0;p=t[f];f++)if(h=c.i,l=r[p]()){try{l._index=h+i,l._fileInfo=s}catch(e){}u.push(l)}else u.push(null);c.end().isFinished?a(null,u):a(!0,null)}catch(e){throw new R({index:e.index+i,message:e.message},n,s.filename)}},parse:function(r,s,a){var l,u,c,h,f=null,p="";if(u=a&&a.globalVars?e.serializeVars(a.globalVars)+"\n":"",c=a&&a.modifyVars?"\n"+e.serializeVars(a.modifyVars):"",t.pluginManager)for(var v=t.pluginManager.getPreProcessors(),d=0;d");return e},args:function(e){var t,n,i,a,l,u,c,h=r.entities,f={args:null,variadic:!1},p=[],v=[],d=[],m=!0;for(o.save();;){if(e)u=r.detachedRuleset()||r.expression();else{if(o.commentStore.length=0,o.$str("...")){f.variadic=!0,o.$char(";")&&!t&&(t=!0),(t?v:d).push({variadic:!0});break}u=h.variable()||h.property()||h.literal()||h.keyword()||this.call(!0)}if(!u||!m)break;a=null,u.throwAwayComments&&u.throwAwayComments(),l=u;var g=null;if(e?u.value&&1==u.value.length&&(g=u.value[0]):g=u,g&&(g instanceof Ie.Variable||g instanceof Ie.Property))if(o.$char(":")){if(p.length>0&&(t&&s("Cannot mix ; and , as delimiter types"),n=!0),!(l=r.detachedRuleset()||r.expression())){if(!e)return o.restore(),f.args=[],f;s("could not understand value for named argument")}a=i=g.name}else if(o.$str("...")){if(!e){f.variadic=!0,o.$char(";")&&!t&&(t=!0),(t?v:d).push({name:u.name,variadic:!0});break}c=!0}else e||(i=a=g.name,l=null);l&&p.push(l),d.push({name:a,value:l,expand:c}),o.$char(",")?m=!0:((m=";"===o.$char(";"))||t)&&(n&&s("Cannot mix ; and , as delimiter types"),t=!0,p.length>1&&(l=new Ie.Value(p)),v.push({name:i,value:l,expand:c}),i=null,p=[],n=!1)}return o.forget(),f.args=t?v:d,f},definition:function(){var e,t,n,i,s=[],l=!1;if(!("."!==o.currentChar()&&"#"!==o.currentChar()||o.peek(/^[^{]*\}/)))if(o.save(),t=o.$re(/^([#.](?:[\w-]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\s*\(/)){e=t[1];var u=this.args(!1);if(s=u.args,l=u.variadic,!o.$char(")"))return void o.restore("Missing closing ')'");if(o.commentStore.length=0,o.$str("when")&&(i=a(r.conditions,"expected condition")),n=r.block())return o.forget(),new Ie.mixin.Definition(e,s,n,i,l);o.restore()}else o.restore()},ruleLookups:function(){var e,t=[];if("["===o.currentChar()){for(;;){if(o.save(),!(e=this.lookupValue())&&""!==e){o.restore();break}t.push(e),o.forget()}return t.length>0?t:void 0}},lookupValue:function(){if(o.save(),o.$char("[")){var e=o.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);if(o.$char("]"))return e||""===e?(o.forget(),e):void o.restore();o.restore()}else o.restore()}},entity:function(){var e=this.entities;return this.comment()||e.literal()||e.variable()||e.url()||e.property()||e.call()||e.keyword()||this.mixin.call(!0)||e.javascript()},end:function(){return o.$char(";")||o.peek("}")},ieAlpha:function(){var e;if(o.$re(/^opacity=/i))return(e=o.$re(/^\d+/))||(e="@{"+(e=a(r.entities.variable,"Could not parse alpha")).name.slice(1)+"}"),l(")"),new Ie.Quoted("","alpha(opacity="+e+")")},element:function(){var e,t,n,r=o.i;if(t=this.combinator(),(e=o.$re(/^(?:\d+\.\d+|\d+)%/)||o.$re(/^(?:[.#]?|:*)(?:[\w-]|[^\x00-\x9f]|\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/)||o.$char("*")||o.$char("&")||this.attribute()||o.$re(/^\([^&()@]+\)/)||o.$re(/^[\.#:](?=@)/)||this.entities.variableCurly())||(o.save(),o.$char("(")?(n=this.selector(!1))&&o.$char(")")?(e=new Ie.Paren(n),o.forget()):o.restore("Missing closing ')'"):o.forget()),e)return new Ie.Element(t,e,e instanceof Ie.Variable,r,i)},combinator:function(){var e=o.currentChar();if("/"===e){o.save();var t=o.$re(/^\/[a-z]+\//i);if(t)return o.forget(),new Ie.Combinator(t);o.restore()}if(">"===e||"+"===e||"~"===e||"|"===e||"^"===e){for(o.i++,"^"===e&&"^"===o.currentChar()&&(e="^^",o.i++);o.isWhitespace();)o.i++;return new Ie.Combinator(e)}return o.isWhitespace(-1)?new Ie.Combinator(" "):new Ie.Combinator(null)},selector:function(e){var t,n,r,l,u,c,h,f=o.i;for(e=!1!==e;(e&&(n=this.extend())||e&&(c=o.$str("when"))||(l=this.element()))&&(c?h=a(this.conditions,"expected condition"):h?s("CSS guard can only be used at the end of selector"):n?u=u?u.concat(n):n:(u&&s("Extend can only be used at the end of selector"),r=o.currentChar(),t?t.push(l):t=[l],l=null),"{"!==r&&"}"!==r&&";"!==r&&","!==r&&")"!==r););if(t)return new Ie.Selector(t,u,h,f,i);u&&s("Extend must be used to extend a selector, it cannot be used on its own")},selectors:function(){for(var e,t;(e=this.selector())&&(t?t.push(e):t=[e],o.commentStore.length=0,e.condition&&t.length>1&&s("Guards are only currently allowed on a single selector."),o.$char(","));)e.condition&&s("Guards are only currently allowed on a single selector."),o.commentStore.length=0;return t},attribute:function(){if(o.$char("[")){var e,t,n,i=this.entities;return(e=i.variableCurly())||(e=a(/^(?:[_A-Za-z0-9-\*]*\|)?(?:[_A-Za-z0-9-]|\\.)+/)),(n=o.$re(/^[|~*$^]?=/))&&(t=i.quoted()||o.$re(/^[0-9]+%/)||o.$re(/^[\w-]+/)||i.variableCurly()),l("]"),new Ie.Attribute(e,n,t)}},block:function(){var e;if(o.$char("{")&&(e=this.primary())&&o.$char("}"))return e},blockRuleset:function(){var e=this.block();return e&&(e=new Ie.Ruleset(null,e)),e},detachedRuleset:function(){var e,t,n;if(o.save(),!o.$re(/^[.#]\(/)||(t=(e=this.mixin.args(!1)).args,n=e.variadic,o.$char(")"))){var i=this.blockRuleset();if(i)return o.forget(),t?new Ie.mixin.Definition(null,t,i,null,n):new Ie.DetachedRuleset(i);o.restore()}else o.restore()},ruleset:function(){var e,n,i;if(o.save(),t.dumpLineNumbers&&(i=u(o.i)),(e=this.selectors())&&(n=this.block())){o.forget();var r=new Ie.Ruleset(e,n,t.strictImports);return t.dumpLineNumbers&&(r.debugInfo=i),r}o.restore()},declaration:function(){var e,t,n,r,s,a,l=o.i,u=o.currentChar();if("."!==u&&"#"!==u&&"&"!==u&&":"!==u)if(o.save(),e=this.variable()||this.ruleProperty()){if((a="string"==typeof e)&&(t=this.detachedRuleset())&&(n=!0),o.commentStore.length=0,!t){if(s=!a&&e.length>1&&e.pop().value,t=e[0].value&&"--"===e[0].value.slice(0,2)?this.permissiveValue():this.anonymousValue())return o.forget(),new Ie.Declaration(e,t,!1,s,l,i);t||(t=this.value()),t?r=this.important():a&&(t=this.permissiveValue())}if(t&&(this.end()||n))return o.forget(),new Ie.Declaration(e,t,r,s,l,i);o.restore()}else o.restore()},anonymousValue:function(){var e=o.i,t=o.$re(/^([^.#@\$+\/'"*`(;{}-]*);/);if(t)return new Ie.Anonymous(t[1],e)},permissiveValue:function(e){var t,n,r,a,l=e||";",u=o.i,c=[];function h(){var e=o.currentChar();return"string"==typeof l?e===l:l.test(e)}if(!h()){a=[];do{(n=this.comment())?a.push(n):(n=this.entity())&&a.push(n)}while(n);if(r=h(),a.length>0){if(a=new Ie.Expression(a),r)return a;c.push(a)," "===o.prevChar()&&c.push(new Ie.Anonymous(" ",u))}if(o.save(),a=o.$parseUntil(l)){if("string"==typeof a&&s("Expected '"+a+"'","Parse"),1===a.length&&" "===a[0])return o.forget(),new Ie.Anonymous("",u);var f=void 0;for(t=0;t0)return new Ie.Expression(r)},mediaFeatures:function(){var e,t=this.entities,n=[];do{if(e=this.mediaFeature()){if(n.push(e),!o.$char(","))break}else if((e=t.variable()||t.mixinLookup())&&(n.push(e),!o.$char(",")))break}while(e);return n.length>0?n:null},media:function(){var e,n,r,a,l=o.i;if(t.dumpLineNumbers&&(a=u(l)),o.save(),o.$str("@media"))return e=this.mediaFeatures(),(n=this.block())||s("media definitions require block statements after any features"),o.forget(),r=new Ie.Media(n,e,l,i),t.dumpLineNumbers&&(r.debugInfo=a),r;o.restore()},plugin:function(){var e,t,n,r=o.i;if(o.$re(/^@plugin?\s+/)){if(n=(t=this.pluginArgs())?{pluginArgs:t,isPlugin:!0}:{isPlugin:!0},e=this.entities.quoted()||this.entities.url())return o.$char(";")||(o.i=r,s("missing semi-colon on @plugin")),new Ie.Import(e,null,n,r,i);o.i=r,s("malformed @plugin statement")}},pluginArgs:function(){if(o.save(),!o.$char("("))return o.restore(),null;var e=o.$re(/^\s*([^\);]+)\)\s*/);return e[1]?(o.forget(),e[1].trim()):(o.restore(),null)},atrule:function(){var e,n,r,a,l,c,h,f=o.i,p=!0,v=!0;if("@"===o.currentChar()){if(n=this.import()||this.plugin()||this.media())return n;if(o.save(),e=o.$re(/^@[a-z-]+/)){switch(a=e,"-"==e.charAt(1)&&e.indexOf("-",2)>0&&(a="@"+e.slice(e.indexOf("-",2)+1)),a){case"@charset":l=!0,p=!1;break;case"@namespace":c=!0,p=!1;break;case"@keyframes":case"@counter-style":l=!0;break;case"@document":case"@supports":h=!0,v=!1;break;default:h=!0}if(o.commentStore.length=0,l?(n=this.entity())||s("expected "+e+" identifier"):c?(n=this.expression())||s("expected "+e+" expression"):h&&(n=this.permissiveValue(/^[{;]/),p="{"===o.currentChar(),n?n.value||(n=null):p||";"===o.currentChar()||s(e+" rule is missing block or ending semi-colon")),p&&(r=this.blockRuleset()),r||!p&&n&&o.$char(";"))return o.forget(),new Ie.AtRule(e,n,r,f,i,t.dumpLineNumbers?u(f):null,v);o.restore("at-rule options not recognised")}}},value:function(){var e,t=[],n=o.i;do{if((e=this.expression())&&(t.push(e),!o.$char(",")))break}while(e);if(t.length>0)return new Ie.Value(t,n)},important:function(){if("!"===o.currentChar())return o.$re(/^! *important/)},sub:function(){var e,t;if(o.save(),o.$char("("))return(e=this.addition())&&o.$char(")")?(o.forget(),(t=new Ie.Expression([e])).parens=!0,t):void o.restore("Expected ')'");o.restore()},multiplication:function(){var e,t,n,i,r;if(e=this.operand()){for(r=o.isWhitespace(-1);!o.peek(/^\/[*\/]/);){if(o.save(),!(n=o.$char("/")||o.$char("*")||o.$str("./"))){o.forget();break}if(!(t=this.operand())){o.restore();break}o.forget(),e.parensInOp=!0,t.parensInOp=!0,i=new Ie.Operation(n,[i||e,t],r),r=o.isWhitespace(-1)}return i||e}},addition:function(){var e,t,n,i,r;if(e=this.multiplication()){for(r=o.isWhitespace(-1);(n=o.$re(/^[-+]\s+/)||!r&&(o.$char("+")||o.$char("-")))&&(t=this.multiplication());)e.parensInOp=!0,t.parensInOp=!0,i=new Ie.Operation(n,[i||e,t],r),r=o.isWhitespace(-1);return i||e}},conditions:function(){var e,t,n,i=o.i;if(e=this.condition(!0)){for(;o.peek(/^,\s*(not\s*)?\(/)&&o.$char(",")&&(t=this.condition(!0));)n=new Ie.Condition("or",n||e,t,i);return n||e}},condition:function(e){var t,n,i;if(t=this.conditionAnd(e)){if(n=o.$str("or")){if(!(i=this.condition(e)))return;t=new Ie.Condition(n,t,i)}return t}},conditionAnd:function(e){var t,n,i,r,s=this;if(t=(r=s.negatedCondition(e)||s.parenthesisCondition(e))||e?r:s.atomicCondition(e)){if(n=o.$str("and")){if(!(i=this.conditionAnd(e)))return;t=new Ie.Condition(n,t,i)}return t}},negatedCondition:function(e){if(o.$str("not")){var t=this.parenthesisCondition(e);return t&&(t.negate=!t.negate),t}},parenthesisCondition:function(e){var t;if(o.save(),o.$str("(")){if(t=function(t){var n;if(o.save(),n=t.condition(e)){if(o.$char(")"))return o.forget(),n;o.restore()}else o.restore()}(this))return o.forget(),t;if(t=this.atomicCondition(e)){if(o.$char(")"))return o.forget(),t;o.restore("expected ')' got '"+o.currentChar()+"'")}else o.restore()}else o.restore()},atomicCondition:function(e){var t,n,i,r,a=this.entities,l=o.i;function u(){return this.addition()||a.keyword()||a.quoted()||a.mixinLookup()}if(t=(u=u.bind(this))())return o.$char(">")?r=o.$char("=")?">=":">":o.$char("<")?r=o.$char("=")?"<=":"<":o.$char("=")&&(r=o.$char(">")?"=>":o.$char("<")?"=<":"="),r?(n=u())?i=new Ie.Condition(r,t,n,l,!1):s("expected expression"):i=new Ie.Condition("=",t,new Ie.Keyword("true"),l,!1),i},operand:function(){var e,t=this.entities;o.peek(/^-[@\$\(]/)&&(e=o.$char("-"));var n=this.sub()||t.dimension()||t.color()||t.variable()||t.property()||t.call()||t.quoted(!0)||t.colorKeyword()||t.mixinLookup();return e&&(n.parensInOp=!0,n=new Ie.Negative(n)),n},expression:function(){var e,t,n=[],i=o.i;do{(e=this.comment())?n.push(e):(e=this.addition()||this.entity())&&(n.push(e),o.peek(/^\/[\/*]/)||(t=o.$char("/"))&&n.push(new Ie.Anonymous(t,i)))}while(e);if(n.length>0)return new Ie.Expression(n)},property:function(){var e=o.$re(/^(\*?-?[_a-zA-Z0-9-]+)\s*:/);if(e)return e[1]},ruleProperty:function(){var e,t,n=[],r=[];o.save();var s=o.$re(/^([_a-zA-Z0-9-]+)\s*:/);if(s)return n=[new Ie.Keyword(s[1])],o.forget(),n;function a(e){var t=o.i,i=o.$re(e);if(i)return r.push(t),n.push(i[1])}for(a(/^(\*?)/);a(/^((?:[\w-]+)|(?:[@\$]\{[\w-]+\}))/););if(n.length>1&&a(/^((?:\+_|\+)?)\s*:/)){for(o.forget(),""===n[0]&&(n.shift(),r.shift()),t=0;t1?e-1:e)<1?r+(o-r)*e*6:2*e<1?o:3*e<2?r+(o-r)*(2/3-e)*6:r}e=Qe(e)%360/360,t=Ge(Qe(t)),n=Ge(Qe(n)),i=Ge(Qe(i)),r=2*n-(o=n<=.5?n*(t+1):n+t-n*t);var a=[255*s(e+1/3),255*s(e),255*s(e-1/3)];return i=Qe(i),new h(a,i,"hsla")}catch(e){}},hsv:function(e,t,n){return Te.hsva(e,t,n,1)},hsva:function(e,t,n,i){var r,o;e=Qe(e)%360/360*360,t=Qe(t),n=Qe(n),i=Qe(i);var s=[n,n*(1-t),n*(1-(o=e/60-(r=Math.floor(e/60%6)))*t),n*(1-(1-o)*t)],a=[[0,3,1],[2,0,1],[1,0,3],[1,2,0],[3,1,0],[0,1,2]];return Te.rgba(255*s[a[r][0]],255*s[a[r][1]],255*s[a[r][2]],i)},hue:function(e){return new X(Je(e).h)},saturation:function(e){return new X(100*Je(e).s,"%")},lightness:function(e){return new X(100*Je(e).l,"%")},hsvhue:function(e){return new X(He(e).h)},hsvsaturation:function(e){return new X(100*He(e).s,"%")},hsvvalue:function(e){return new X(100*He(e).v,"%")},red:function(e){return new X(e.rgb[0])},green:function(e){return new X(e.rgb[1])},blue:function(e){return new X(e.rgb[2])},alpha:function(e){return new X(Je(e).a)},luma:function(e){return new X(e.luma()*e.alpha*100,"%")},luminance:function(e){var t=.2126*e.rgb[0]/255+.7152*e.rgb[1]/255+.0722*e.rgb[2]/255;return new X(t*e.alpha*100,"%")},saturate:function(e,t,n){if(!e.rgb)return null;var i=Je(e);return void 0!==n&&"relative"===n.value?i.s+=i.s*t.value/100:i.s+=t.value/100,i.s=Ge(i.s),We(e,i)},desaturate:function(e,t,n){var i=Je(e);return void 0!==n&&"relative"===n.value?i.s-=i.s*t.value/100:i.s-=t.value/100,i.s=Ge(i.s),We(e,i)},lighten:function(e,t,n){var i=Je(e);return void 0!==n&&"relative"===n.value?i.l+=i.l*t.value/100:i.l+=t.value/100,i.l=Ge(i.l),We(e,i)},darken:function(e,t,n){var i=Je(e);return void 0!==n&&"relative"===n.value?i.l-=i.l*t.value/100:i.l-=t.value/100,i.l=Ge(i.l),We(e,i)},fadein:function(e,t,n){var i=Je(e);return void 0!==n&&"relative"===n.value?i.a+=i.a*t.value/100:i.a+=t.value/100,i.a=Ge(i.a),We(e,i)},fadeout:function(e,t,n){var i=Je(e);return void 0!==n&&"relative"===n.value?i.a-=i.a*t.value/100:i.a-=t.value/100,i.a=Ge(i.a),We(e,i)},fade:function(e,t){var n=Je(e);return n.a=t.value/100,n.a=Ge(n.a),We(e,n)},spin:function(e,t){var n=Je(e),i=(n.h+t.value)%360;return n.h=i<0?360+i:i,We(e,n)},mix:function(e,t,n){n||(n=new X(50));var i=n.value/100,r=2*i-1,o=Je(e).a-Je(t).a,s=((r*o==-1?r:(r+o)/(1+r*o))+1)/2,a=1-s,l=[e.rgb[0]*s+t.rgb[0]*a,e.rgb[1]*s+t.rgb[1]*a,e.rgb[2]*s+t.rgb[2]*a],u=e.alpha*i+t.alpha*(1-i);return new h(l,u)},greyscale:function(e){return Te.desaturate(e,new X(100))},contrast:function(e,t,n,i){if(!e.rgb)return null;if(void 0===n&&(n=Te.rgba(255,255,255,1)),void 0===t&&(t=Te.rgba(0,0,0,1)),t.luma()>n.luma()){var r=n;n=t,t=r}return i=void 0===i?.43:Qe(i),e.luma().5&&(i=1,n=e>.25?Math.sqrt(e):((16*e-12)*e+4)*e),e-(1-2*t)*i*(n-e)},hardlight:function(e,t){return Ye.overlay(t,e)},difference:function(e,t){return Math.abs(e-t)},exclusion:function(e,t){return e+t-2*e*t},average:function(e,t){return(e+t)/2},negation:function(e,t){return 1-Math.abs(e+t-1)}};for(var Xe in Ye)Ye.hasOwnProperty(Xe)&&(Ze[Xe]=Ze.bind(null,Ye[Xe]));var et=function(e){return Array.isArray(e.value)?e.value:Array(e)},tt={_SELF:function(e){return e},extract:function(e,t){return t=t.value-1,et(e)[t]},length:function(e){return new X(et(e).length)},range:function(e,t,n){var i,r,o=1,s=[];t?(r=t,i=e.value,n&&(o=n.value)):(i=1,r=e);for(var a=i;a<=r.value;a+=o)s.push(new X(a,r.unit));return new ie(s)},each:function(e,t){var n,i,r=[];i=!e.value||e instanceof ue?e.ruleset?e.ruleset.rules:e.rules?e.rules:Array.isArray(e)?e:[e]:Array.isArray(e.value)?e.value:[e.value];var o="@value",s="@key",a="@index";t.params?(o=t.params[0]&&t.params[0].name,s=t.params[1]&&t.params[1].name,a=t.params[2]&&t.params[2].name,t=t.rules):t=t.ruleset;for(var l=0;ls.value)&&(c[i]=r);else{if(void 0!==l&&a!==l)throw{type:"Argument",message:"incompatible types"};h[a]=c.length,c.push(r)}else Array.isArray(t[n].value)&&Array.prototype.push.apply(t,Array.prototype.slice.call(t[n].value));return 1==c.length?c[0]:(t=c.map((function(e){return e.toCSS(this.context)})).join(this.context.compress?",":", "),new L((e?"min":"max")+"("+t+")"))},at={min:function(){for(var e=[],t=0;t",r=0;r";return i+="',i=encodeURIComponent(i),new ce(new ue("'"+(i="data:image/svg+xml,"+i)+"'",i,!1,this.index,this.currentFileInfo),this.index,this.currentFileInfo)}}),J.addMultiple(ht),t},pt=function(e,t){var n;void 0===t&&(t={});var i=t.variables,r=new j.Eval(t);"object"!=typeof i||Array.isArray(i)||(i=Object.keys(i).map((function(e){var t=i[e];return t instanceof Ie.Value||(t instanceof Ie.Expression||(t=new Ie.Expression([t])),t=new Ie.Value([t])),new Ie.Declaration("@"+e,t,!1,null,0)})),r.frames=[new Ie.Ruleset(null,i)]);var o,s,a=[new Ue.JoinSelectorVisitor,new Ue.MarkVisibleSelectorsVisitor(!0),new Ue.ExtendVisitor,new Ue.ToCSSVisitor({compress:Boolean(t.compress)})],l=[];if(t.pluginManager){s=t.pluginManager.visitor();for(var u=0;u<2;u++)for(s.first();o=s.get();)o.isPreEvalVisitor?0!==u&&-1!==l.indexOf(o)||(l.push(o),o.run(e)):0!==u&&-1!==a.indexOf(o)||(o.isPreVisitor?a.unshift(o):a.push(o))}n=e.eval(r);for(u=0;u=t);n++);this.preProcessors.splice(n,0,{preProcessor:e,priority:t})},e.prototype.addPostProcessor=function(e,t){var n;for(n=0;n=t);n++);this.postProcessors.splice(n,0,{postProcessor:e,priority:t})},e.prototype.addFileManager=function(e){this.fileManagers.push(e)},e.prototype.getPreProcessors=function(){for(var e=[],t=0;t0){var i=void 0,r=JSON.stringify(this._sourceMapGenerator.toJSON());this.sourceMapURL?i=this.sourceMapURL:this._sourceMapFilename&&(i=this._sourceMapFilename),this.sourceMapURL=i,this.sourceMap=r}return this._css.join("")},t}()}(e=new _e(e,t)),r=function(e,t){return function(){function n(e){this.options=e}return n.prototype.toCSS=function(t,n,i){var r=new e({contentsIgnoredCharsMap:i.contentsIgnoredChars,rootNode:t,contentsMap:i.contents,sourceMapFilename:this.options.sourceMapFilename,sourceMapURL:this.options.sourceMapURL,outputFilename:this.options.sourceMapOutputFilename,sourceMapBasepath:this.options.sourceMapBasepath,sourceMapRootpath:this.options.sourceMapRootpath,outputSourceFiles:this.options.outputSourceFiles,sourceMapGenerator:this.options.sourceMapGenerator,sourceMapFileInline:this.options.sourceMapFileInline}),o=r.toCSS(n);return this.sourceMap=r.sourceMap,this.sourceMapURL=r.sourceMapURL,this.options.sourceMapInputFilename&&(this.sourceMapInputFilename=r.normalizeFilename(this.options.sourceMapInputFilename)),void 0!==this.options.sourceMapBasepath&&void 0!==this.sourceMapURL&&(this.sourceMapURL=r.removeBasepath(this.sourceMapURL)),o+this.getCSSAppendage()},n.prototype.getCSSAppendage=function(){var e=this.sourceMapURL;if(this.options.sourceMapFileInline){if(void 0===this.sourceMap)return"";e="data:application/json;base64,"+t.encodeBase64(this.sourceMap)}return e?"/*# sourceMappingURL="+e+" */":""},n.prototype.getExternalSourceMap=function(){return this.sourceMap},n.prototype.setExternalSourceMap=function(e){this.sourceMap=e},n.prototype.isInline=function(){return this.options.sourceMapFileInline},n.prototype.getSourceMapURL=function(){return this.sourceMapURL},n.prototype.getOutputFilename=function(){return this.options.sourceMapOutputFilename},n.prototype.getInputFilename=function(){return this.sourceMapInputFilename},n}()}(i,e),o=function(e){return function(){function t(e,t){this.root=e,this.imports=t}return t.prototype.toCSS=function(t){var n,i,r={};try{n=pt(this.root,t)}catch(e){throw new R(e,this.imports)}try{var o=Boolean(t.compress);o&&Ce.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.");var s={compress:o,dumpLineNumbers:t.dumpLineNumbers,strictUnits:Boolean(t.strictUnits),numPrecision:8};t.sourceMap?(i=new e(t.sourceMap),r.css=i.toCSS(n,s,this.imports)):r.css=n.toCSS(s)}catch(e){throw new R(e,this.imports)}if(t.pluginManager)for(var a=t.pluginManager.getPostProcessors(),l=0;l=200&&t.status<300?n(t.responseText,t.getResponseHeader("Last-Modified")):"function"==typeof i&&i(t.status,e)}"function"==typeof r.overrideMimeType&&r.overrideMimeType("text/css"),gt.debug("XHR: Getting '"+e+"'"),r.open("GET",e,o),r.setRequestHeader("Accept",t||"text/x-less, text/css; q=0.9, */*; q=0.5"),r.send(null),mt.isFileProtocol&&!mt.fileAsync?0===r.status||r.status>=200&&r.status<300?n(r.responseText):i(r.status,e):o?r.onreadystatechange=function(){4==r.readyState&&s(r,n,i)}:s(r,n,i)},t.prototype.tryToLoad=function(e){var t=this;return new Promise((function(n,i){if(mt.useFileCache&&bt[e])try{var r=bt[e];return n({contents:r,filename:e,webInfo:{lastModified:new Date}})}catch(t){return i({filename:e,message:"Error loading file "+e+" error was "+t.message})}t.doXHR(e,mt.mime,(function(t,i){bt[e]=t,n({contents:t,filename:e,webInfo:{lastModified:i}})}),(function(t,n){i({type:"File",message:"'"+n+"' wasn't found ("+t+")",href:e})}))}))},t.prototype.supports=function(){return!0},t.prototype.clearFileCache=function(){bt={}},t.prototype.loadFile=function(e,t,n,i){var r=this;t&&!this.isPathAbsolute(e)&&(e=t+e);var o=this.getPossibleFileExtensions(e,n.ext||"");n=n||{};var s=this.extractUrlParts(e,window.location.href).url,a=o.map((function(e){return r.tryAppendExtension(s,e)}));return a.reduce((function(e,t){return e.catch((function(){return r.tryToLoad(t)}))}),this.tryToLoad(a.shift()))},t}(ke),xt=function(e,t){return mt=e,gt=t,wt},St=function(e){function t(t){var n=e.call(this)||this;return n.less=t,n}return o(t,e),t.prototype.loadPlugin=function(e,t,n,i,r){return new Promise((function(o,s){r.loadFile(e,t,n,i).then(o).catch(s)}))},t}(Ae),It=function(t,i,r){return{add:function(o,s){r.errorReporting&&"html"!==r.errorReporting?"console"===r.errorReporting?function(e,t){var n=e.filename||t,o=[],s=(e.type||"Syntax")+"Error: "+(e.message||"There is an error in your .less file")+" in "+n,a=function(e,t,n){void 0!==e.extract[t]&&o.push("{line} {content}".replace(/\{line\}/,(parseInt(e.line,10)||0)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};e.line&&(a(e,0,""),a(e,1,"line"),a(e,2,""),s+=" on line "+e.line+", column "+(e.column+1)+":\n"+o.join("\n")),e.stack&&(e.extract||r.logLevel>=4)&&(s+="\nStack Trace\n"+e.stack),i.logger.error(s)}(o,s):"function"==typeof r.errorReporting&&r.errorReporting("add",o,s):function(i,o){var s,a,l="less-error-message:"+e(o||""),u=t.document.createElement("div"),c=[],h=i.filename||o,f=h.match(/([^\/]+(\?.*)?)$/)[1];u.id=l,u.className="less-error-message",a="

    "+(i.type||"Syntax")+"Error: "+(i.message||"There is an error in your .less file")+'

    in '+f+" ";var p=function(e,t,n){void 0!==e.extract[t]&&c.push('

  • {content}
  • '.replace(/\{line\}/,(parseInt(e.line,10)||0)+(t-1)).replace(/\{class\}/,n).replace(/\{content\}/,e.extract[t]))};i.line&&(p(i,0,""),p(i,1,"line"),p(i,2,""),a+="on line "+i.line+", column "+(i.column+1)+":

      "+c.join("")+"
    "),i.stack&&(i.extract||r.logLevel>=4)&&(a+="
    Stack Trace
    "+i.stack.split("\n").slice(1).join("
    ")),u.innerHTML=a,n(t.document,[".less-error-message ul, .less-error-message li {","list-style-type: none;","margin-right: 15px;","padding: 4px 0;","margin: 0;","}",".less-error-message label {","font-size: 12px;","margin-right: 15px;","padding: 4px 0;","color: #cc7777;","}",".less-error-message pre {","color: #dd6666;","padding: 4px 0;","margin: 0;","display: inline-block;","}",".less-error-message pre.line {","color: #ff0000;","}",".less-error-message h3 {","font-size: 20px;","font-weight: bold;","padding: 15px 0 5px 0;","margin: 0;","}",".less-error-message a {","color: #10a","}",".less-error-message .error {","color: red;","font-weight: bold;","padding-bottom: 2px;","border-bottom: 1px dashed red;","}"].join("\n"),{title:"error-message"}),u.style.cssText=["font-family: Arial, sans-serif","border: 1px solid #e00","background-color: #eee","border-radius: 5px","-webkit-border-radius: 5px","-moz-border-radius: 5px","color: #e00","padding: 15px","margin-bottom: 15px"].join(";"),"development"===r.env&&(s=setInterval((function(){var e=t.document,n=e.body;n&&(e.getElementById(l)?n.replaceChild(u,e.getElementById(l)):n.insertBefore(u,n.firstChild),clearInterval(s))}),10))}(o,s)},remove:function(n){r.errorReporting&&"html"!==r.errorReporting?"console"===r.errorReporting||"function"==typeof r.errorReporting&&r.errorReporting("remove",n):function(n){var i=t.document.getElementById("less-error-message:"+e(n));i&&i.parentNode.removeChild(i)}(n)}}},Ct={javascriptEnabled:!1,depends:!1,compress:!1,lint:!1,paths:[],color:!0,strictImports:!1,insecure:!1,rootpath:"",rewriteUrls:!1,math:0,strictUnits:!1,globalVars:null,modifyVars:null,urlArgs:""};if(window.less)for(var _t in window.less)window.less.hasOwnProperty(_t)&&(Ct[_t]=window.less[_t]);!function(e,n){t(n,i(e)),void 0===n.isFileProtocol&&(n.isFileProtocol=/^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(e.location.protocol)),n.async=n.async||!1,n.fileAsync=n.fileAsync||!1,n.poll=n.poll||(n.isFileProtocol?1e3:1500),n.env=n.env||("127.0.0.1"==e.location.hostname||"0.0.0.0"==e.location.hostname||"localhost"==e.location.hostname||e.location.port&&e.location.port.length>0||n.isFileProtocol?"development":"production");var r=/!dumpLineNumbers:(comments|mediaquery|all)/.exec(e.location.hash);r&&(n.dumpLineNumbers=r[1]),void 0===n.useFileCache&&(n.useFileCache=!0),void 0===n.onReady&&(n.onReady=!0),n.relativeUrls&&(n.rewriteUrls="all")}(window,Ct),Ct.plugins=Ct.plugins||[],window.LESS_PLUGINS&&(Ct.plugins=Ct.plugins.concat(window.LESS_PLUGINS));var kt,At,Mt,Pt=function(e,i){var r=e.document,o=yt();o.options=i;var s=o.environment,a=xt(i,o.logger),l=new a;s.addFileManager(l),o.FileManager=a,o.PluginLoader=St,function(e,t){t.logLevel=void 0!==t.logLevel?t.logLevel:"development"===t.env?3:1,t.loggers||(t.loggers=[{debug:function(e){t.logLevel>=4&&console.log(e)},info:function(e){t.logLevel>=3&&console.log(e)},warn:function(e){t.logLevel>=2&&console.warn(e)},error:function(e){t.logLevel>=1&&console.error(e)}}]);for(var n=0;n 0 && styleNode.childNodes.length > 0 &&\n oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);\n }\n\n const head = document.getElementsByTagName('head')[0];\n\n // If there is no oldStyleNode, just append; otherwise, only append if we need\n // to replace oldStyleNode with an updated stylesheet\n if (oldStyleNode === null || keepOldStyleNode === false) {\n const nextEl = sheet && sheet.nextSibling || null;\n if (nextEl) {\n nextEl.parentNode.insertBefore(styleNode, nextEl);\n } else {\n head.appendChild(styleNode);\n }\n }\n if (oldStyleNode && keepOldStyleNode === false) {\n oldStyleNode.parentNode.removeChild(oldStyleNode);\n }\n\n // For IE.\n // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.\n // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head\n if (styleNode.styleSheet) {\n try {\n styleNode.styleSheet.cssText = styles;\n } catch (e) {\n throw new Error('Couldn\\'t reassign styleSheet.cssText.');\n }\n }\n },\n currentScript: function(window) {\n const document = window.document;\n return document.currentScript || (() => {\n const scripts = document.getElementsByTagName('script');\n return scripts[scripts.length - 1];\n })();\n }\n};\n","export default {\n 'aliceblue':'#f0f8ff',\n 'antiquewhite':'#faebd7',\n 'aqua':'#00ffff',\n 'aquamarine':'#7fffd4',\n 'azure':'#f0ffff',\n 'beige':'#f5f5dc',\n 'bisque':'#ffe4c4',\n 'black':'#000000',\n 'blanchedalmond':'#ffebcd',\n 'blue':'#0000ff',\n 'blueviolet':'#8a2be2',\n 'brown':'#a52a2a',\n 'burlywood':'#deb887',\n 'cadetblue':'#5f9ea0',\n 'chartreuse':'#7fff00',\n 'chocolate':'#d2691e',\n 'coral':'#ff7f50',\n 'cornflowerblue':'#6495ed',\n 'cornsilk':'#fff8dc',\n 'crimson':'#dc143c',\n 'cyan':'#00ffff',\n 'darkblue':'#00008b',\n 'darkcyan':'#008b8b',\n 'darkgoldenrod':'#b8860b',\n 'darkgray':'#a9a9a9',\n 'darkgrey':'#a9a9a9',\n 'darkgreen':'#006400',\n 'darkkhaki':'#bdb76b',\n 'darkmagenta':'#8b008b',\n 'darkolivegreen':'#556b2f',\n 'darkorange':'#ff8c00',\n 'darkorchid':'#9932cc',\n 'darkred':'#8b0000',\n 'darksalmon':'#e9967a',\n 'darkseagreen':'#8fbc8f',\n 'darkslateblue':'#483d8b',\n 'darkslategray':'#2f4f4f',\n 'darkslategrey':'#2f4f4f',\n 'darkturquoise':'#00ced1',\n 'darkviolet':'#9400d3',\n 'deeppink':'#ff1493',\n 'deepskyblue':'#00bfff',\n 'dimgray':'#696969',\n 'dimgrey':'#696969',\n 'dodgerblue':'#1e90ff',\n 'firebrick':'#b22222',\n 'floralwhite':'#fffaf0',\n 'forestgreen':'#228b22',\n 'fuchsia':'#ff00ff',\n 'gainsboro':'#dcdcdc',\n 'ghostwhite':'#f8f8ff',\n 'gold':'#ffd700',\n 'goldenrod':'#daa520',\n 'gray':'#808080',\n 'grey':'#808080',\n 'green':'#008000',\n 'greenyellow':'#adff2f',\n 'honeydew':'#f0fff0',\n 'hotpink':'#ff69b4',\n 'indianred':'#cd5c5c',\n 'indigo':'#4b0082',\n 'ivory':'#fffff0',\n 'khaki':'#f0e68c',\n 'lavender':'#e6e6fa',\n 'lavenderblush':'#fff0f5',\n 'lawngreen':'#7cfc00',\n 'lemonchiffon':'#fffacd',\n 'lightblue':'#add8e6',\n 'lightcoral':'#f08080',\n 'lightcyan':'#e0ffff',\n 'lightgoldenrodyellow':'#fafad2',\n 'lightgray':'#d3d3d3',\n 'lightgrey':'#d3d3d3',\n 'lightgreen':'#90ee90',\n 'lightpink':'#ffb6c1',\n 'lightsalmon':'#ffa07a',\n 'lightseagreen':'#20b2aa',\n 'lightskyblue':'#87cefa',\n 'lightslategray':'#778899',\n 'lightslategrey':'#778899',\n 'lightsteelblue':'#b0c4de',\n 'lightyellow':'#ffffe0',\n 'lime':'#00ff00',\n 'limegreen':'#32cd32',\n 'linen':'#faf0e6',\n 'magenta':'#ff00ff',\n 'maroon':'#800000',\n 'mediumaquamarine':'#66cdaa',\n 'mediumblue':'#0000cd',\n 'mediumorchid':'#ba55d3',\n 'mediumpurple':'#9370d8',\n 'mediumseagreen':'#3cb371',\n 'mediumslateblue':'#7b68ee',\n 'mediumspringgreen':'#00fa9a',\n 'mediumturquoise':'#48d1cc',\n 'mediumvioletred':'#c71585',\n 'midnightblue':'#191970',\n 'mintcream':'#f5fffa',\n 'mistyrose':'#ffe4e1',\n 'moccasin':'#ffe4b5',\n 'navajowhite':'#ffdead',\n 'navy':'#000080',\n 'oldlace':'#fdf5e6',\n 'olive':'#808000',\n 'olivedrab':'#6b8e23',\n 'orange':'#ffa500',\n 'orangered':'#ff4500',\n 'orchid':'#da70d6',\n 'palegoldenrod':'#eee8aa',\n 'palegreen':'#98fb98',\n 'paleturquoise':'#afeeee',\n 'palevioletred':'#d87093',\n 'papayawhip':'#ffefd5',\n 'peachpuff':'#ffdab9',\n 'peru':'#cd853f',\n 'pink':'#ffc0cb',\n 'plum':'#dda0dd',\n 'powderblue':'#b0e0e6',\n 'purple':'#800080',\n 'rebeccapurple':'#663399',\n 'red':'#ff0000',\n 'rosybrown':'#bc8f8f',\n 'royalblue':'#4169e1',\n 'saddlebrown':'#8b4513',\n 'salmon':'#fa8072',\n 'sandybrown':'#f4a460',\n 'seagreen':'#2e8b57',\n 'seashell':'#fff5ee',\n 'sienna':'#a0522d',\n 'silver':'#c0c0c0',\n 'skyblue':'#87ceeb',\n 'slateblue':'#6a5acd',\n 'slategray':'#708090',\n 'slategrey':'#708090',\n 'snow':'#fffafa',\n 'springgreen':'#00ff7f',\n 'steelblue':'#4682b4',\n 'tan':'#d2b48c',\n 'teal':'#008080',\n 'thistle':'#d8bfd8',\n 'tomato':'#ff6347',\n 'turquoise':'#40e0d0',\n 'violet':'#ee82ee',\n 'wheat':'#f5deb3',\n 'white':'#ffffff',\n 'whitesmoke':'#f5f5f5',\n 'yellow':'#ffff00',\n 'yellowgreen':'#9acd32'\n};","export default {\n length: {\n 'm': 1,\n 'cm': 0.01,\n 'mm': 0.001,\n 'in': 0.0254,\n 'px': 0.0254 / 96,\n 'pt': 0.0254 / 72,\n 'pc': 0.0254 / 72 * 12\n },\n duration: {\n 's': 1,\n 'ms': 0.001\n },\n angle: {\n 'rad': 1 / (2 * Math.PI),\n 'deg': 1 / 360,\n 'grad': 1 / 400,\n 'turn': 1\n }\n};","import colors from './colors';\nimport unitConversions from './unit-conversions';\n\nexport default { colors, unitConversions };\n","class Node {\n constructor() {\n this.parent = null;\n this.visibilityBlocks = undefined;\n this.nodeVisible = undefined;\n this.rootNode = null;\n this.parsed = null;\n\n const self = this;\n Object.defineProperty(this, 'currentFileInfo', {\n get: function() { return self.fileInfo(); }\n });\n Object.defineProperty(this, 'index', {\n get: function() { return self.getIndex(); }\n });\n\n }\n\n setParent(nodes, parent) {\n function set(node) {\n if (node && node instanceof Node) {\n node.parent = parent;\n }\n }\n if (Array.isArray(nodes)) {\n nodes.forEach(set);\n }\n else {\n set(nodes);\n }\n }\n\n getIndex() {\n return this._index || (this.parent && this.parent.getIndex()) || 0;\n }\n\n fileInfo() {\n return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};\n }\n\n isRulesetLike() {\n return false;\n }\n\n toCSS(context) {\n const strs = [];\n this.genCSS(context, {\n add: function(chunk, fileInfo, index) {\n strs.push(chunk);\n },\n isEmpty: function () {\n return strs.length === 0;\n }\n });\n return strs.join('');\n }\n\n genCSS(context, output) {\n output.add(this.value);\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n eval() { return this; }\n\n _operate(context, op, a, b) {\n switch (op) {\n case '+': return a + b;\n case '-': return a - b;\n case '*': return a * b;\n case '/': return a / b;\n }\n }\n\n fround(context, value) {\n const precision = context && context.numPrecision;\n // add \"epsilon\" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:\n return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;\n }\n\n // Returns true if this node represents root of ast imported by reference\n blocksVisibility() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n return this.visibilityBlocks !== 0;\n }\n\n addVisibilityBlock() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n this.visibilityBlocks = this.visibilityBlocks + 1;\n }\n\n removeVisibilityBlock() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n this.visibilityBlocks = this.visibilityBlocks - 1;\n }\n\n // Turns on node visibility - if called node will be shown in output regardless\n // of whether it comes from import by reference or not\n ensureVisibility() {\n this.nodeVisible = true;\n }\n\n // Turns off node visibility - if called node will NOT be shown in output regardless\n // of whether it comes from import by reference or not\n ensureInvisibility() {\n this.nodeVisible = false;\n }\n\n // return values:\n // false - the node must not be visible\n // true - the node must be visible\n // undefined or null - the node has the same visibility as its parent\n isVisible() {\n return this.nodeVisible;\n }\n\n visibilityInfo() {\n return {\n visibilityBlocks: this.visibilityBlocks,\n nodeVisible: this.nodeVisible\n };\n }\n\n copyVisibilityInfo(info) {\n if (!info) {\n return;\n }\n this.visibilityBlocks = info.visibilityBlocks;\n this.nodeVisible = info.nodeVisible;\n }\n}\n\nNode.compare = (a, b) => {\n /* returns:\n -1: a < b\n 0: a = b\n 1: a > b\n and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */\n\n if ((a.compare) &&\n // for \"symmetric results\" force toCSS-based comparison\n // of Quoted or Anonymous if either value is one of those\n !(b.type === 'Quoted' || b.type === 'Anonymous')) {\n return a.compare(b);\n } else if (b.compare) {\n return -b.compare(a);\n } else if (a.type !== b.type) {\n return undefined;\n }\n\n a = a.value;\n b = b.value;\n if (!Array.isArray(a)) {\n return a === b ? 0 : undefined;\n }\n if (a.length !== b.length) {\n return undefined;\n }\n for (let i = 0; i < a.length; i++) {\n if (Node.compare(a[i], b[i]) !== 0) {\n return undefined;\n }\n }\n return 0;\n};\n\nNode.numericCompare = (a, b) => a < b ? -1\n : a === b ? 0\n : a > b ? 1 : undefined;\nexport default Node;\n","import Node from './node';\nimport colors from '../data/colors';\n\n//\n// RGB Colors - #ff0014, #eee\n//\nclass Color extends Node {\n constructor(rgb, a, originalForm) {\n super();\n\n const self = this;\n //\n // The end goal here, is to parse the arguments\n // into an integer triplet, such as `128, 255, 0`\n //\n // This facilitates operations and conversions.\n //\n if (Array.isArray(rgb)) {\n this.rgb = rgb;\n } else if (rgb.length >= 6) {\n this.rgb = [];\n rgb.match(/.{2}/g).map((c, i) => {\n if (i < 3) {\n self.rgb.push(parseInt(c, 16));\n } else {\n self.alpha = (parseInt(c, 16)) / 255;\n }\n });\n } else {\n this.rgb = [];\n rgb.split('').map((c, i) => {\n if (i < 3) {\n self.rgb.push(parseInt(c + c, 16));\n } else {\n self.alpha = (parseInt(c + c, 16)) / 255;\n }\n });\n }\n this.alpha = this.alpha || (typeof a === 'number' ? a : 1);\n if (typeof originalForm !== 'undefined') {\n this.value = originalForm;\n }\n }\n\n luma() {\n let r = this.rgb[0] / 255;\n let g = this.rgb[1] / 255;\n let b = this.rgb[2] / 255;\n\n r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);\n g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);\n b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);\n\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context));\n }\n\n toCSS(context, doNotCompress) {\n const compress = context && context.compress && !doNotCompress;\n let color;\n let alpha;\n let colorFunction;\n let args = [];\n\n // `value` is set if this color was originally\n // converted from a named color string so we need\n // to respect this and try to output named color too.\n alpha = this.fround(context, this.alpha);\n\n if (this.value) {\n if (this.value.indexOf('rgb') === 0) {\n if (alpha < 1) {\n colorFunction = 'rgba';\n }\n } else if (this.value.indexOf('hsl') === 0) {\n if (alpha < 1) {\n colorFunction = 'hsla';\n } else {\n colorFunction = 'hsl';\n }\n } else {\n return this.value;\n }\n } else {\n if (alpha < 1) {\n colorFunction = 'rgba';\n }\n }\n\n switch (colorFunction) {\n case 'rgba':\n args = this.rgb.map(c => clamp(Math.round(c), 255)).concat(clamp(alpha, 1));\n break;\n case 'hsla':\n args.push(clamp(alpha, 1));\n case 'hsl':\n color = this.toHSL();\n args = [\n this.fround(context, color.h),\n `${this.fround(context, color.s * 100)}%`,\n `${this.fround(context, color.l * 100)}%`\n ].concat(args);\n }\n\n if (colorFunction) {\n // Values are capped between `0` and `255`, rounded and zero-padded.\n return `${colorFunction}(${args.join(`,${compress ? '' : ' '}`)})`;\n }\n\n color = this.toRGB();\n\n if (compress) {\n const splitcolor = color.split('');\n\n // Convert color to short format\n if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {\n color = `#${splitcolor[1]}${splitcolor[3]}${splitcolor[5]}`;\n }\n }\n\n return color;\n }\n\n //\n // Operations have to be done per-channel, if not,\n // channels will spill onto each other. Once we have\n // our result, in the form of an integer triplet,\n // we create a new Color node to hold the result.\n //\n operate(context, op, other) {\n const rgb = new Array(3);\n const alpha = this.alpha * (1 - other.alpha) + other.alpha;\n for (let c = 0; c < 3; c++) {\n rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);\n }\n return new Color(rgb, alpha);\n }\n\n toRGB() {\n return toHex(this.rgb);\n }\n\n toHSL() {\n const r = this.rgb[0] / 255;\n const g = this.rgb[1] / 255;\n const b = this.rgb[2] / 255;\n const a = this.alpha;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h;\n let s;\n const l = (max + min) / 2;\n const d = max - min;\n\n if (max === min) {\n h = s = 0;\n } else {\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h * 360, s, l, a };\n }\n\n // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\n toHSV() {\n const r = this.rgb[0] / 255;\n const g = this.rgb[1] / 255;\n const b = this.rgb[2] / 255;\n const a = this.alpha;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h;\n let s;\n const v = max;\n\n const d = max - min;\n if (max === 0) {\n s = 0;\n } else {\n s = d / max;\n }\n\n if (max === min) {\n h = 0;\n } else {\n switch (max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h * 360, s, v, a };\n }\n\n toARGB() {\n return toHex([this.alpha * 255].concat(this.rgb));\n }\n\n compare(x) {\n return (x.rgb &&\n x.rgb[0] === this.rgb[0] &&\n x.rgb[1] === this.rgb[1] &&\n x.rgb[2] === this.rgb[2] &&\n x.alpha === this.alpha) ? 0 : undefined;\n }\n}\n\nColor.prototype.type = 'Color';\n\nfunction clamp(v, max) {\n return Math.min(Math.max(v, 0), max);\n}\n\nfunction toHex(v) {\n return `#${v.map(c => {\n c = clamp(Math.round(c), 255);\n return (c < 16 ? '0' : '') + c.toString(16);\n }).join('')}`;\n}\n\nColor.fromKeyword = keyword => {\n let c;\n const key = keyword.toLowerCase();\n if (colors.hasOwnProperty(key)) {\n c = new Color(colors[key].slice(1));\n }\n else if (key === 'transparent') {\n c = new Color([0, 0, 0], 0);\n }\n\n if (c) {\n c.value = keyword;\n return c;\n }\n};\nexport default Color;\n","import Node from './node';\n\nclass Paren extends Node {\n constructor(node) {\n super();\n\n this.value = node;\n }\n\n genCSS(context, output) {\n output.add('(');\n this.value.genCSS(context, output);\n output.add(')');\n }\n\n eval(context) {\n return new Paren(this.value.eval(context));\n }\n}\n\nParen.prototype.type = 'Paren';\nexport default Paren;\n","import Node from './node';\nconst _noSpaceCombinators = {\n '': true,\n ' ': true,\n '|': true\n};\n\nclass Combinator extends Node {\n constructor(value) {\n super();\n\n if (value === ' ') {\n this.value = ' ';\n this.emptyOrWhitespace = true;\n } else {\n this.value = value ? value.trim() : '';\n this.emptyOrWhitespace = this.value === '';\n }\n }\n\n genCSS(context, output) {\n const spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';\n output.add(spaceOrEmpty + this.value + spaceOrEmpty);\n }\n}\n\nCombinator.prototype.type = 'Combinator';\n\nexport default Combinator;\n","import Node from './node';\nimport Paren from './paren';\nimport Combinator from './combinator';\n\nclass Element extends Node {\n constructor(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.combinator = combinator instanceof Combinator ?\n combinator : new Combinator(combinator);\n\n if (typeof value === 'string') {\n this.value = value.trim();\n } else if (value) {\n this.value = value;\n } else {\n this.value = '';\n }\n this.isVariable = isVariable;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.combinator, this);\n }\n\n accept(visitor) {\n const value = this.value;\n this.combinator = visitor.visit(this.combinator);\n if (typeof value === 'object') {\n this.value = visitor.visit(value);\n }\n }\n\n eval(context) {\n return new Element(this.combinator,\n this.value.eval ? this.value.eval(context) : this.value,\n this.isVariable,\n this.getIndex(),\n this.fileInfo(), this.visibilityInfo());\n }\n\n clone() {\n return new Element(this.combinator,\n this.value,\n this.isVariable,\n this.getIndex(),\n this.fileInfo(), this.visibilityInfo());\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context), this.fileInfo(), this.getIndex());\n }\n\n toCSS(context = {}) {\n let value = this.value;\n const firstSelector = context.firstSelector;\n if (value instanceof Paren) {\n // selector in parens should not be affected by outer selector\n // flags (breaks only interpolated selectors - see #1973)\n context.firstSelector = true;\n }\n value = value.toCSS ? value.toCSS(context) : value;\n context.firstSelector = firstSelector;\n if (value === '' && this.combinator.value.charAt(0) === '&') {\n return '';\n } else {\n return this.combinator.toCSS(context) + value;\n }\n }\n}\n\nElement.prototype.type = 'Element';\nexport default Element;\n","\nexport const Math = {\n ALWAYS: 0,\n PARENS_DIVISION: 1,\n PARENS: 2,\n STRICT_LEGACY: 3\n};\n\nexport const RewriteUrls = {\n OFF: 0,\n LOCAL: 1,\n ALL: 2\n};","var clone = (function() {\n'use strict';\n\nfunction _instanceof(obj, type) {\n return type != null && obj instanceof type;\n}\n\nvar nativeMap;\ntry {\n nativeMap = Map;\n} catch(_) {\n // maybe a reference error because no `Map`. Give it a dummy value that no\n // value will ever be an instanceof.\n nativeMap = function() {};\n}\n\nvar nativeSet;\ntry {\n nativeSet = Set;\n} catch(_) {\n nativeSet = function() {};\n}\n\nvar nativePromise;\ntry {\n nativePromise = Promise;\n} catch(_) {\n nativePromise = function() {};\n}\n\n/**\n * Clones (copies) an Object using deep copying.\n *\n * This function supports circular references by default, but if you are certain\n * there are no circular references in your object, you can save some CPU time\n * by calling clone(obj, false).\n *\n * Caution: if `circular` is false and `parent` contains circular references,\n * your program may enter an infinite loop and crash.\n *\n * @param `parent` - the object to be cloned\n * @param `circular` - set to true if the object to be cloned may contain\n * circular references. (optional - true by default)\n * @param `depth` - set to a number if the object is only to be cloned to\n * a particular depth. (optional - defaults to Infinity)\n * @param `prototype` - sets the prototype to be used when cloning an object.\n * (optional - defaults to parent prototype).\n * @param `includeNonEnumerable` - set to true if the non-enumerable properties\n * should be cloned as well. Non-enumerable properties on the prototype\n * chain will be ignored. (optional - false by default)\n*/\nfunction clone(parent, circular, depth, prototype, includeNonEnumerable) {\n if (typeof circular === 'object') {\n depth = circular.depth;\n prototype = circular.prototype;\n includeNonEnumerable = circular.includeNonEnumerable;\n circular = circular.circular;\n }\n // maintain two arrays for circular references, where corresponding parents\n // and children have the same index\n var allParents = [];\n var allChildren = [];\n\n var useBuffer = typeof Buffer != 'undefined';\n\n if (typeof circular == 'undefined')\n circular = true;\n\n if (typeof depth == 'undefined')\n depth = Infinity;\n\n // recurse this function so we don't reset allParents and allChildren\n function _clone(parent, depth) {\n // cloning null always returns null\n if (parent === null)\n return null;\n\n if (depth === 0)\n return parent;\n\n var child;\n var proto;\n if (typeof parent != 'object') {\n return parent;\n }\n\n if (_instanceof(parent, nativeMap)) {\n child = new nativeMap();\n } else if (_instanceof(parent, nativeSet)) {\n child = new nativeSet();\n } else if (_instanceof(parent, nativePromise)) {\n child = new nativePromise(function (resolve, reject) {\n parent.then(function(value) {\n resolve(_clone(value, depth - 1));\n }, function(err) {\n reject(_clone(err, depth - 1));\n });\n });\n } else if (clone.__isArray(parent)) {\n child = [];\n } else if (clone.__isRegExp(parent)) {\n child = new RegExp(parent.source, __getRegExpFlags(parent));\n if (parent.lastIndex) child.lastIndex = parent.lastIndex;\n } else if (clone.__isDate(parent)) {\n child = new Date(parent.getTime());\n } else if (useBuffer && Buffer.isBuffer(parent)) {\n if (Buffer.allocUnsafe) {\n // Node.js >= 4.5.0\n child = Buffer.allocUnsafe(parent.length);\n } else {\n // Older Node.js versions\n child = new Buffer(parent.length);\n }\n parent.copy(child);\n return child;\n } else if (_instanceof(parent, Error)) {\n child = Object.create(parent);\n } else {\n if (typeof prototype == 'undefined') {\n proto = Object.getPrototypeOf(parent);\n child = Object.create(proto);\n }\n else {\n child = Object.create(prototype);\n proto = prototype;\n }\n }\n\n if (circular) {\n var index = allParents.indexOf(parent);\n\n if (index != -1) {\n return allChildren[index];\n }\n allParents.push(parent);\n allChildren.push(child);\n }\n\n if (_instanceof(parent, nativeMap)) {\n parent.forEach(function(value, key) {\n var keyChild = _clone(key, depth - 1);\n var valueChild = _clone(value, depth - 1);\n child.set(keyChild, valueChild);\n });\n }\n if (_instanceof(parent, nativeSet)) {\n parent.forEach(function(value) {\n var entryChild = _clone(value, depth - 1);\n child.add(entryChild);\n });\n }\n\n for (var i in parent) {\n var attrs;\n if (proto) {\n attrs = Object.getOwnPropertyDescriptor(proto, i);\n }\n\n if (attrs && attrs.set == null) {\n continue;\n }\n child[i] = _clone(parent[i], depth - 1);\n }\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(parent);\n for (var i = 0; i < symbols.length; i++) {\n // Don't need to worry about cloning a symbol because it is a primitive,\n // like a number or string.\n var symbol = symbols[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);\n if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {\n continue;\n }\n child[symbol] = _clone(parent[symbol], depth - 1);\n if (!descriptor.enumerable) {\n Object.defineProperty(child, symbol, {\n enumerable: false\n });\n }\n }\n }\n\n if (includeNonEnumerable) {\n var allPropertyNames = Object.getOwnPropertyNames(parent);\n for (var i = 0; i < allPropertyNames.length; i++) {\n var propertyName = allPropertyNames[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);\n if (descriptor && descriptor.enumerable) {\n continue;\n }\n child[propertyName] = _clone(parent[propertyName], depth - 1);\n Object.defineProperty(child, propertyName, {\n enumerable: false\n });\n }\n }\n\n return child;\n }\n\n return _clone(parent, depth);\n}\n\n/**\n * Simple flat clone using prototype, accepts only objects, usefull for property\n * override on FLAT configuration object (no nested props).\n *\n * USE WITH CAUTION! This may not behave as you wish if you do not know how this\n * works.\n */\nclone.clonePrototype = function clonePrototype(parent) {\n if (parent === null)\n return null;\n\n var c = function () {};\n c.prototype = parent;\n return new c();\n};\n\n// private utility functions\n\nfunction __objToStr(o) {\n return Object.prototype.toString.call(o);\n}\nclone.__objToStr = __objToStr;\n\nfunction __isDate(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Date]';\n}\nclone.__isDate = __isDate;\n\nfunction __isArray(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Array]';\n}\nclone.__isArray = __isArray;\n\nfunction __isRegExp(o) {\n return typeof o === 'object' && __objToStr(o) === '[object RegExp]';\n}\nclone.__isRegExp = __isRegExp;\n\nfunction __getRegExpFlags(re) {\n var flags = '';\n if (re.global) flags += 'g';\n if (re.ignoreCase) flags += 'i';\n if (re.multiline) flags += 'm';\n return flags;\n}\nclone.__getRegExpFlags = __getRegExpFlags;\n\nreturn clone;\n})();\n\nif (typeof module === 'object' && module.exports) {\n module.exports = clone;\n}\n","/* jshint proto: true */\nimport * as Constants from './constants';\nimport CloneHelper from 'clone';\n\nexport function getLocation(index, inputStream) {\n let n = index + 1;\n let line = null;\n let column = -1;\n\n while (--n >= 0 && inputStream.charAt(n) !== '\\n') {\n column++;\n }\n\n if (typeof index === 'number') {\n line = (inputStream.slice(0, index).match(/\\n/g) || '').length;\n }\n\n return {\n line,\n column\n };\n}\n\nexport function copyArray(arr) {\n let i;\n const length = arr.length;\n const copy = new Array(length);\n\n for (i = 0; i < length; i++) {\n copy[i] = arr[i];\n }\n return copy;\n}\n\nexport function clone(obj) {\n const cloned = {};\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n cloned[prop] = obj[prop];\n }\n }\n return cloned;\n}\n\nexport function defaults(obj1, obj2) {\n let newObj = obj2 || {};\n if (!obj2._defaults) {\n newObj = {};\n const defaults = CloneHelper(obj1);\n newObj._defaults = defaults;\n const cloned = obj2 ? CloneHelper(obj2) : {};\n Object.assign(newObj, defaults, cloned);\n }\n return newObj;\n}\n\nexport function copyOptions(obj1, obj2) {\n if (obj2 && obj2._defaults) {\n return obj2;\n }\n const opts = defaults(obj1, obj2);\n if (opts.strictMath) {\n opts.math = Constants.Math.STRICT_LEGACY;\n }\n // Back compat with changed relativeUrls option\n if (opts.relativeUrls) {\n opts.rewriteUrls = Constants.RewriteUrls.ALL;\n }\n if (typeof opts.math === 'string') {\n switch (opts.math.toLowerCase()) {\n case 'always':\n opts.math = Constants.Math.ALWAYS;\n break;\n case 'parens-division':\n opts.math = Constants.Math.PARENS_DIVISION;\n break;\n case 'strict':\n case 'parens':\n opts.math = Constants.Math.PARENS;\n break;\n case 'strict-legacy':\n opts.math = Constants.Math.STRICT_LEGACY;\n }\n }\n if (typeof opts.rewriteUrls === 'string') {\n switch (opts.rewriteUrls.toLowerCase()) {\n case 'off':\n opts.rewriteUrls = Constants.RewriteUrls.OFF;\n break;\n case 'local':\n opts.rewriteUrls = Constants.RewriteUrls.LOCAL;\n break;\n case 'all':\n opts.rewriteUrls = Constants.RewriteUrls.ALL;\n break;\n }\n }\n return opts;\n}\n\nexport function merge(obj1, obj2) {\n for (const prop in obj2) {\n if (obj2.hasOwnProperty(prop)) {\n obj1[prop] = obj2[prop];\n }\n }\n return obj1;\n}\n\nexport function flattenArray(arr, result = []) {\n for (let i = 0, length = arr.length; i < length; i++) {\n const value = arr[i];\n if (Array.isArray(value)) {\n flattenArray(value, result);\n } else {\n if (value !== undefined) {\n result.push(value);\n }\n }\n }\n return result;\n}","import * as utils from './utils';\n/**\n * This is a centralized class of any error that could be thrown internally (mostly by the parser).\n * Besides standard .message it keeps some additional data like a path to the file where the error\n * occurred along with line and column numbers.\n *\n * @class\n * @extends Error\n * @type {module.LessError}\n *\n * @prop {string} type\n * @prop {string} filename\n * @prop {number} index\n * @prop {number} line\n * @prop {number} column\n * @prop {number} callLine\n * @prop {number} callExtract\n * @prop {string[]} extract\n *\n * @param {Object} e - An error object to wrap around or just a descriptive object\n * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?\n * @param {string} [currentFilename]\n */\nconst LessError = function LessError(e, fileContentMap, currentFilename) {\n Error.call(this);\n\n const filename = e.filename || currentFilename;\n\n this.message = e.message;\n this.stack = e.stack;\n\n if (fileContentMap && filename) {\n const input = fileContentMap.contents[filename];\n const loc = utils.getLocation(e.index, input);\n const line = loc.line;\n const col = loc.column;\n const callLine = e.call && utils.getLocation(e.call, input).line;\n const lines = input ? input.split('\\n') : '';\n\n this.type = e.type || 'Syntax';\n this.filename = filename;\n this.index = e.index;\n this.line = typeof line === 'number' ? line + 1 : null;\n this.column = col;\n\n if (!this.line && this.stack) {\n const found = this.stack.match(/(|Function):(\\d+):(\\d+)/);\n\n if (found) {\n if (found[2]) {\n this.line = parseInt(found[2]) - 2;\n }\n if (found[3]) {\n this.column = parseInt(found[3]);\n }\n }\n }\n\n this.callLine = callLine + 1;\n this.callExtract = lines[callLine];\n\n this.extract = [\n lines[this.line - 2],\n lines[this.line - 1],\n lines[this.line]\n ];\n }\n\n};\n\nif (typeof Object.create === 'undefined') {\n const F = () => {};\n F.prototype = Error.prototype;\n LessError.prototype = new F();\n} else {\n LessError.prototype = Object.create(Error.prototype);\n}\n\nLessError.prototype.constructor = LessError;\n\n/**\n * An overridden version of the default Object.prototype.toString\n * which uses additional information to create a helpful message.\n *\n * @param {Object} options\n * @returns {string}\n */\nLessError.prototype.toString = function(options = {}) {\n let message = '';\n const extract = this.extract || [];\n let error = [];\n let stylize = str => str;\n if (options.stylize) {\n const type = typeof options.stylize;\n if (type !== 'function') {\n throw Error(`options.stylize should be a function, got a ${type}!`);\n }\n stylize = options.stylize;\n }\n\n if (this.line !== null) {\n if (typeof extract[0] === 'string') {\n error.push(stylize(`${this.line - 1} ${extract[0]}`, 'grey'));\n }\n\n if (typeof extract[1] === 'string') {\n let errorTxt = `${this.line} `;\n if (extract[1]) {\n errorTxt += extract[1].slice(0, this.column) +\n stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +\n extract[1].slice(this.column + 1), 'red'), 'inverse');\n }\n error.push(errorTxt);\n }\n\n if (typeof extract[2] === 'string') {\n error.push(stylize(`${this.line + 1} ${extract[2]}`, 'grey'));\n }\n error = `${error.join('\\n') + stylize('', 'reset')}\\n`;\n }\n\n message += stylize(`${this.type}Error: ${this.message}`, 'red');\n if (this.filename) {\n message += stylize(' in ', 'red') + this.filename;\n }\n if (this.line) {\n message += stylize(` on line ${this.line}, column ${this.column + 1}:`, 'grey');\n }\n\n message += `\\n${error}`;\n\n if (this.callLine) {\n message += `${stylize('from ', 'red') + (this.filename || '')}/n`;\n message += `${stylize(this.callLine, 'grey')} ${this.callExtract}/n`;\n }\n\n return message;\n};\n\nexport default LessError;","import Node from './node';\nimport Element from './element';\nimport LessError from '../less-error';\n\nclass Selector extends Node {\n constructor(elements, extendList, condition, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.extendList = extendList;\n this.condition = condition;\n this.evaldCondition = !condition;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.elements = this.getElements(elements);\n this.mixinElements_ = undefined;\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.elements, this);\n }\n\n accept(visitor) {\n if (this.elements) {\n this.elements = visitor.visitArray(this.elements);\n }\n if (this.extendList) {\n this.extendList = visitor.visitArray(this.extendList);\n }\n if (this.condition) {\n this.condition = visitor.visit(this.condition);\n }\n }\n\n createDerived(elements, extendList, evaldCondition) {\n elements = this.getElements(elements);\n const newSelector = new Selector(elements, extendList || this.extendList,\n null, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;\n newSelector.mediaEmpty = this.mediaEmpty;\n return newSelector;\n }\n\n getElements(els) {\n if (!els) {\n return [new Element('', '&', false, this._index, this._fileInfo)];\n }\n if (typeof els === 'string') {\n this.parse.parseNode(\n els, \n ['selector'],\n this._index, \n this._fileInfo, \n function(err, result) {\n if (err) {\n throw new LessError({\n index: err.index,\n message: err.message\n }, this.parse.imports, this._fileInfo.filename);\n }\n els = result[0].elements;\n });\n }\n return els;\n }\n\n createEmptySelectors() {\n const el = new Element('', '&', false, this._index, this._fileInfo);\n const sels = [new Selector([el], null, null, this._index, this._fileInfo)];\n sels[0].mediaEmpty = true;\n return sels;\n }\n\n match(other) {\n const elements = this.elements;\n const len = elements.length;\n let olen;\n let i;\n\n other = other.mixinElements();\n olen = other.length;\n if (olen === 0 || len < olen) {\n return 0;\n } else {\n for (i = 0; i < olen; i++) {\n if (elements[i].value !== other[i]) {\n return 0;\n }\n }\n }\n\n return olen; // return number of matched elements\n }\n\n mixinElements() {\n if (this.mixinElements_) {\n return this.mixinElements_;\n }\n\n let elements = this.elements.map( v => v.combinator.value + (v.value.value || v.value)).join('').match(/[,&#\\*\\.\\w-]([\\w-]|(\\\\.))*/g);\n\n if (elements) {\n if (elements[0] === '&') {\n elements.shift();\n }\n } else {\n elements = [];\n }\n\n return (this.mixinElements_ = elements);\n }\n\n isJustParentSelector() {\n return !this.mediaEmpty &&\n this.elements.length === 1 &&\n this.elements[0].value === '&' &&\n (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');\n }\n\n eval(context) {\n const evaldCondition = this.condition && this.condition.eval(context);\n let elements = this.elements;\n let extendList = this.extendList;\n\n elements = elements && elements.map(e => e.eval(context));\n extendList = extendList && extendList.map(extend => extend.eval(context));\n\n return this.createDerived(elements, extendList, evaldCondition);\n }\n\n genCSS(context, output) {\n let i;\n let element;\n if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {\n output.add(' ', this.fileInfo(), this.getIndex());\n }\n for (i = 0; i < this.elements.length; i++) {\n element = this.elements[i];\n element.genCSS(context, output);\n }\n }\n\n getIsOutput() {\n return this.evaldCondition;\n }\n}\n\nSelector.prototype.type = 'Selector';\nexport default Selector;\n","import Node from './node';\n\nclass Value extends Node {\n constructor(value) {\n super();\n\n if (!value) {\n throw new Error('Value requires an array argument');\n }\n if (!Array.isArray(value)) {\n this.value = [ value ];\n }\n else {\n this.value = value;\n }\n }\n\n accept(visitor) {\n if (this.value) {\n this.value = visitor.visitArray(this.value);\n }\n }\n\n eval(context) {\n if (this.value.length === 1) {\n return this.value[0].eval(context);\n } else {\n return new Value(this.value.map(v => v.eval(context)));\n }\n }\n\n genCSS(context, output) {\n let i;\n for (i = 0; i < this.value.length; i++) {\n this.value[i].genCSS(context, output);\n if (i + 1 < this.value.length) {\n output.add((context && context.compress) ? ',' : ', ');\n }\n }\n }\n}\n\nValue.prototype.type = 'Value';\nexport default Value;\n","import Node from './node';\n\nclass Keyword extends Node {\n constructor(value) {\n super();\n\n this.value = value;\n }\n\n genCSS(context, output) {\n if (this.value === '%') { throw { type: 'Syntax', message: 'Invalid % without number' }; }\n output.add(this.value);\n }\n}\n\nKeyword.prototype.type = 'Keyword';\n\nKeyword.True = new Keyword('true');\nKeyword.False = new Keyword('false');\n\nexport default Keyword;\n","import Node from './node';\n\nclass Anonymous extends Node {\n constructor(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {\n super();\n\n this.value = value;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.mapLines = mapLines;\n this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;\n this.allowRoot = true;\n this.copyVisibilityInfo(visibilityInfo);\n }\n\n eval() {\n return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());\n }\n\n compare(other) {\n return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n }\n\n isRulesetLike() {\n return this.rulesetLike;\n }\n\n genCSS(context, output) {\n this.nodeVisible = Boolean(this.value);\n if (this.nodeVisible) {\n output.add(this.value, this._fileInfo, this._index, this.mapLines);\n }\n }\n}\n\nAnonymous.prototype.type = 'Anonymous';\nexport default Anonymous;\n","import Node from './node';\nimport Value from './value';\nimport Keyword from './keyword';\nimport Anonymous from './anonymous';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\n\nclass Declaration extends Node {\n constructor(name, value, important, merge, index, currentFileInfo, inline, variable) {\n super();\n\n this.name = name;\n this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);\n this.important = important ? ` ${important.trim()}` : '';\n this.merge = merge;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.inline = inline || false;\n this.variable = (variable !== undefined) ? variable\n : (name.charAt && (name.charAt(0) === '@'));\n this.allowRoot = true;\n this.setParent(this.value, this);\n }\n\n genCSS(context, output) {\n output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());\n try {\n this.value.genCSS(context, output);\n }\n catch (e) {\n e.index = this._index;\n e.filename = this._fileInfo.filename;\n throw e;\n }\n output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);\n }\n\n eval(context) {\n let mathBypass = false;\n let prevMath;\n let name = this.name;\n let evaldValue;\n let variable = this.variable;\n if (typeof name !== 'string') {\n // expand 'primitive' name directly to get\n // things faster (~10% for benchmark.less):\n name = (name.length === 1) && (name[0] instanceof Keyword) ?\n name[0].value : evalName(context, name);\n variable = false; // never treat expanded interpolation as new variable name\n }\n\n // @todo remove when parens-division is default\n if (name === 'font' && context.math === MATH.ALWAYS) {\n mathBypass = true;\n prevMath = context.math;\n context.math = MATH.PARENS_DIVISION;\n }\n try {\n context.importantScope.push({});\n evaldValue = this.value.eval(context);\n\n if (!this.variable && evaldValue.type === 'DetachedRuleset') {\n throw { message: 'Rulesets cannot be evaluated on a property.',\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n let important = this.important;\n const importantResult = context.importantScope.pop();\n if (!important && importantResult.important) {\n important = importantResult.important;\n }\n\n return new Declaration(name,\n evaldValue,\n important,\n this.merge,\n this.getIndex(), this.fileInfo(), this.inline,\n variable);\n }\n catch (e) {\n if (typeof e.index !== 'number') {\n e.index = this.getIndex();\n e.filename = this.fileInfo().filename;\n }\n throw e;\n }\n finally {\n if (mathBypass) {\n context.math = prevMath;\n }\n }\n }\n\n makeImportant() {\n return new Declaration(this.name,\n this.value,\n '!important',\n this.merge,\n this.getIndex(), this.fileInfo(), this.inline);\n }\n}\n\nfunction evalName(context, name) {\n let value = '';\n let i;\n const n = name.length;\n const output = {add: function (s) {value += s;}};\n for (i = 0; i < n; i++) {\n name[i].eval(context).genCSS(context, output);\n }\n return value;\n}\n\nDeclaration.prototype.type = 'Declaration';\nexport default Declaration;","const debugInfo = (context, ctx, lineSeparator) => {\n let result = '';\n if (context.dumpLineNumbers && !context.compress) {\n switch (context.dumpLineNumbers) {\n case 'comments':\n result = debugInfo.asComment(ctx);\n break;\n case 'mediaquery':\n result = debugInfo.asMediaQuery(ctx);\n break;\n case 'all':\n result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx);\n break;\n }\n }\n return result;\n};\n\ndebugInfo.asComment = ctx => `/* line ${ctx.debugInfo.lineNumber}, ${ctx.debugInfo.fileName} */\\n`;\n\ndebugInfo.asMediaQuery = ctx => {\n let filenameWithProtocol = ctx.debugInfo.fileName;\n if (!/^[a-z]+:\\/\\//i.test(filenameWithProtocol)) {\n filenameWithProtocol = `file://${filenameWithProtocol}`;\n }\n return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:\\/\\\\])/g, a => {\n if (a == '\\\\') {\n a = '\\/';\n }\n return `\\\\${a}`;\n })}}line{font-family:\\\\00003${ctx.debugInfo.lineNumber}}}\\n`;\n};\n\nexport default debugInfo;\n","import Node from './node';\nimport getDebugInfo from './debug-info';\n\nclass Comment extends Node {\n constructor(value, isLineComment, index, currentFileInfo) {\n super();\n\n this.value = value;\n this.isLineComment = isLineComment;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.allowRoot = true;\n }\n\n genCSS(context, output) {\n if (this.debugInfo) {\n output.add(getDebugInfo(context, this), this.fileInfo(), this.getIndex());\n }\n output.add(this.value);\n }\n\n isSilent(context) {\n const isCompressed = context.compress && this.value[2] !== '!';\n return this.isLineComment || isCompressed;\n }\n}\n\nComment.prototype.type = 'Comment';\nexport default Comment;\n","const contexts = {};\nexport default contexts;\nimport * as Constants from './constants';\n\nconst copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {\n if (!original) { return; }\n\n for (let i = 0; i < propertiesToCopy.length; i++) {\n if (original.hasOwnProperty(propertiesToCopy[i])) {\n destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];\n }\n }\n};\n\n/*\n parse is used whilst parsing\n */\nconst parseCopyProperties = [\n // options\n 'paths', // option - unmodified - paths to search for imports on\n 'rewriteUrls', // option - whether to adjust URL's to be relative\n 'rootpath', // option - rootpath to append to URL's\n 'strictImports', // option -\n 'insecure', // option - whether to allow imports from insecure ssl hosts\n 'dumpLineNumbers', // option - whether to dump line numbers\n 'compress', // option - whether to compress\n 'syncImport', // option - whether to import synchronously\n 'chunkInput', // option - whether to chunk input. more performant but causes parse issues.\n 'mime', // browser only - mime type for sheet import\n 'useFileCache', // browser only - whether to use the per file session cache\n // context\n 'processImports', // option & context - whether to process imports. if false then imports will not be imported.\n // Used by the import manager to stop multiple import visitors being created.\n 'pluginManager' // Used as the plugin manager for the session\n];\n\ncontexts.Parse = function(options) {\n copyFromOriginal(options, this, parseCopyProperties);\n\n if (typeof this.paths === 'string') { this.paths = [this.paths]; }\n};\n\nconst evalCopyProperties = [\n 'paths', // additional include paths\n 'compress', // whether to compress\n 'math', // whether math has to be within parenthesis\n 'strictUnits', // whether units need to evaluate correctly\n 'sourceMap', // whether to output a source map\n 'importMultiple', // whether we are currently importing multiple copies\n 'urlArgs', // whether to add args into url tokens\n 'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false\n 'pluginManager', // Used as the plugin manager for the session\n 'importantScope', // used to bubble up !important statements\n 'rewriteUrls' // option - whether to adjust URL's to be relative\n];\n\nfunction isPathRelative(path) {\n return !/^(?:[a-z-]+:|\\/|#)/i.test(path);\n}\n\nfunction isPathLocalRelative(path) {\n return path.charAt(0) === '.';\n}\n\ncontexts.Eval = class {\n constructor(options, frames) {\n copyFromOriginal(options, this, evalCopyProperties);\n\n if (typeof this.paths === 'string') { this.paths = [this.paths]; }\n\n this.frames = frames || [];\n this.importantScope = this.importantScope || [];\n this.inCalc = false;\n this.mathOn = true;\n }\n\n enterCalc() {\n if (!this.calcStack) {\n this.calcStack = [];\n }\n this.calcStack.push(true);\n this.inCalc = true;\n }\n\n exitCalc() {\n this.calcStack.pop();\n if (!this.calcStack) {\n this.inCalc = false;\n }\n }\n\n inParenthesis() {\n if (!this.parensStack) {\n this.parensStack = [];\n }\n this.parensStack.push(true);\n };\n\n outOfParenthesis() {\n this.parensStack.pop();\n };\n\n isMathOn(op) {\n if (!this.mathOn) {\n return false;\n }\n if (op === '/' && this.math !== Constants.Math.ALWAYS && (!this.parensStack || !this.parensStack.length)) {\n return false;\n }\n if (this.math > Constants.Math.PARENS_DIVISION) {\n return this.parensStack && this.parensStack.length;\n }\n return true;\n }\n\n pathRequiresRewrite(path) {\n const isRelative = this.rewriteUrls === Constants.RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;\n\n return isRelative(path);\n }\n\n rewritePath(path, rootpath) {\n let newPath;\n\n rootpath = rootpath || '';\n newPath = this.normalizePath(rootpath + path);\n\n // If a path was explicit relative and the rootpath was not an absolute path\n // we must ensure that the new path is also explicit relative.\n if (isPathLocalRelative(path) &&\n isPathRelative(rootpath) &&\n isPathLocalRelative(newPath) === false) {\n newPath = `./${newPath}`;\n }\n\n return newPath;\n }\n\n normalizePath(path) {\n const segments = path.split('/').reverse();\n let segment;\n\n path = [];\n while (segments.length !== 0) {\n segment = segments.pop();\n switch ( segment ) {\n case '.':\n break;\n case '..':\n if ((path.length === 0) || (path[path.length - 1] === '..')) {\n path.push( segment );\n } else {\n path.pop();\n }\n break;\n default:\n path.push(segment);\n break;\n }\n }\n\n return path.join('/');\n }\n}\n","function makeRegistry( base ) {\n return {\n _data: {},\n add: function(name, func) {\n // precautionary case conversion, as later querying of\n // the registry by function-caller uses lower case as well.\n name = name.toLowerCase();\n\n if (this._data.hasOwnProperty(name)) {\n // TODO warn\n }\n this._data[name] = func;\n },\n addMultiple: function(functions) {\n Object.keys(functions).forEach(\n name => {\n this.add(name, functions[name]);\n });\n },\n get: function(name) {\n return this._data[name] || ( base && base.get( name ));\n },\n getLocalFunctions: function() {\n return this._data;\n },\n inherit: function() {\n return makeRegistry( this );\n },\n create: function(base) {\n return makeRegistry(base);\n }\n };\n}\n\nexport default makeRegistry( null );","import Keyword from '../tree/keyword';\n\nconst defaultFunc = {\n eval: function () {\n const v = this.value_;\n const e = this.error_;\n if (e) {\n throw e;\n }\n if (v != null) {\n return v ? Keyword.True : Keyword.False;\n }\n },\n value: function (v) {\n this.value_ = v;\n },\n error: function (e) {\n this.error_ = e;\n },\n reset: function () {\n this.value_ = this.error_ = null;\n }\n};\n\nexport default defaultFunc;\n","import Node from './node';\nimport Declaration from './declaration';\nimport Keyword from './keyword';\nimport Comment from './comment';\nimport Paren from './paren';\nimport Selector from './selector';\nimport Element from './element';\nimport Anonymous from './anonymous';\nimport contexts from '../contexts';\nimport globalFunctionRegistry from '../functions/function-registry';\nimport defaultFunc from '../functions/default';\nimport getDebugInfo from './debug-info';\nimport * as utils from '../utils';\n\nclass Ruleset extends Node {\n constructor(selectors, rules, strictImports, visibilityInfo) {\n super();\n\n this.selectors = selectors;\n this.rules = rules;\n this._lookups = {};\n this._variables = null;\n this._properties = null;\n this.strictImports = strictImports;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n\n this.setParent(this.selectors, this);\n this.setParent(this.rules, this);\n\n }\n\n isRulesetLike() {\n return true;\n }\n\n accept(visitor) {\n if (this.paths) {\n this.paths = visitor.visitArray(this.paths, true);\n } else if (this.selectors) {\n this.selectors = visitor.visitArray(this.selectors);\n }\n if (this.rules && this.rules.length) {\n this.rules = visitor.visitArray(this.rules);\n }\n }\n\n eval(context) {\n const that = this;\n let selectors;\n let selCnt;\n let selector;\n let i;\n let hasVariable;\n let hasOnePassingSelector = false;\n\n if (this.selectors && (selCnt = this.selectors.length)) {\n selectors = new Array(selCnt);\n defaultFunc.error({\n type: 'Syntax',\n message: 'it is currently only allowed in parametric mixin guards,'\n });\n\n for (i = 0; i < selCnt; i++) {\n selector = this.selectors[i].eval(context);\n for (var j = 0; j < selector.elements.length; j++) {\n if (selector.elements[j].isVariable) {\n hasVariable = true;\n break;\n }\n }\n selectors[i] = selector;\n if (selector.evaldCondition) {\n hasOnePassingSelector = true;\n }\n }\n\n if (hasVariable) {\n const toParseSelectors = new Array(selCnt);\n for (i = 0; i < selCnt; i++) {\n selector = selectors[i];\n toParseSelectors[i] = selector.toCSS(context);\n }\n this.parse.parseNode(\n toParseSelectors.join(','),\n [\"selectors\"], \n selectors[0].getIndex(), \n selectors[0].fileInfo(), \n (err, result) => {\n if (result) {\n selectors = utils.flattenArray(result);\n }\n });\n }\n\n defaultFunc.reset();\n } else {\n hasOnePassingSelector = true;\n }\n\n let rules = this.rules ? utils.copyArray(this.rules) : null;\n const ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo());\n let rule;\n let subRule;\n\n ruleset.originalRuleset = this;\n ruleset.root = this.root;\n ruleset.firstRoot = this.firstRoot;\n ruleset.allowImports = this.allowImports;\n\n if (this.debugInfo) {\n ruleset.debugInfo = this.debugInfo;\n }\n\n if (!hasOnePassingSelector) {\n rules.length = 0;\n }\n\n // inherit a function registry from the frames stack when possible;\n // otherwise from the global registry\n ruleset.functionRegistry = (frames => {\n let i = 0;\n const n = frames.length;\n let found;\n for ( ; i !== n ; ++i ) {\n found = frames[ i ].functionRegistry;\n if ( found ) { return found; }\n }\n return globalFunctionRegistry;\n })(context.frames).inherit();\n\n // push the current ruleset to the frames stack\n const ctxFrames = context.frames;\n ctxFrames.unshift(ruleset);\n\n // currrent selectors\n let ctxSelectors = context.selectors;\n if (!ctxSelectors) {\n context.selectors = ctxSelectors = [];\n }\n ctxSelectors.unshift(this.selectors);\n\n // Evaluate imports\n if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {\n ruleset.evalImports(context);\n }\n\n // Store the frames around mixin definitions,\n // so they can be evaluated like closures when the time comes.\n const rsRules = ruleset.rules;\n for (i = 0; (rule = rsRules[i]); i++) {\n if (rule.evalFirst) {\n rsRules[i] = rule.eval(context);\n }\n }\n\n const mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;\n\n // Evaluate mixin calls.\n for (i = 0; (rule = rsRules[i]); i++) {\n if (rule.type === 'MixinCall') {\n /* jshint loopfunc:true */\n rules = rule.eval(context).filter(r => {\n if ((r instanceof Declaration) && r.variable) {\n // do not pollute the scope if the variable is\n // already there. consider returning false here\n // but we need a way to \"return\" variable from mixins\n return !(ruleset.variable(r.name));\n }\n return true;\n });\n rsRules.splice(...[i, 1].concat(rules));\n i += rules.length - 1;\n ruleset.resetCache();\n } else if (rule.type === 'VariableCall') {\n /* jshint loopfunc:true */\n rules = rule.eval(context).rules.filter(r => {\n if ((r instanceof Declaration) && r.variable) {\n // do not pollute the scope at all\n return false;\n }\n return true;\n });\n rsRules.splice(...[i, 1].concat(rules));\n i += rules.length - 1;\n ruleset.resetCache();\n }\n }\n\n // Evaluate everything else\n for (i = 0; (rule = rsRules[i]); i++) {\n if (!rule.evalFirst) {\n rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;\n }\n }\n\n // Evaluate everything else\n for (i = 0; (rule = rsRules[i]); i++) {\n // for rulesets, check if it is a css guard and can be removed\n if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {\n // check if it can be folded in (e.g. & where)\n if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {\n rsRules.splice(i--, 1);\n\n for (var j = 0; (subRule = rule.rules[j]); j++) {\n if (subRule instanceof Node) {\n subRule.copyVisibilityInfo(rule.visibilityInfo());\n if (!(subRule instanceof Declaration) || !subRule.variable) {\n rsRules.splice(++i, 0, subRule);\n }\n }\n }\n }\n }\n }\n\n // Pop the stack\n ctxFrames.shift();\n ctxSelectors.shift();\n\n if (context.mediaBlocks) {\n for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {\n context.mediaBlocks[i].bubbleSelectors(selectors);\n }\n }\n\n return ruleset;\n }\n\n evalImports(context) {\n const rules = this.rules;\n let i;\n let importRules;\n if (!rules) { return; }\n\n for (i = 0; i < rules.length; i++) {\n if (rules[i].type === 'Import') {\n importRules = rules[i].eval(context);\n if (importRules && (importRules.length || importRules.length === 0)) {\n rules.splice(...[i, 1].concat(importRules));\n i += importRules.length - 1;\n } else {\n rules.splice(i, 1, importRules);\n }\n this.resetCache();\n }\n }\n }\n\n makeImportant() {\n const result = new Ruleset(this.selectors, this.rules.map(r => {\n if (r.makeImportant) {\n return r.makeImportant();\n } else {\n return r;\n }\n }), this.strictImports, this.visibilityInfo());\n\n return result;\n }\n\n matchArgs(args) {\n return !args || args.length === 0;\n }\n\n // lets you call a css selector with a guard\n matchCondition(args, context) {\n const lastSelector = this.selectors[this.selectors.length - 1];\n if (!lastSelector.evaldCondition) {\n return false;\n }\n if (lastSelector.condition &&\n !lastSelector.condition.eval(\n new contexts.Eval(context,\n context.frames))) {\n return false;\n }\n return true;\n }\n\n resetCache() {\n this._rulesets = null;\n this._variables = null;\n this._properties = null;\n this._lookups = {};\n }\n\n variables() {\n if (!this._variables) {\n this._variables = !this.rules ? {} : this.rules.reduce((hash, r) => {\n if (r instanceof Declaration && r.variable === true) {\n hash[r.name] = r;\n }\n // when evaluating variables in an import statement, imports have not been eval'd\n // so we need to go inside import statements.\n // guard against root being a string (in the case of inlined less)\n if (r.type === 'Import' && r.root && r.root.variables) {\n const vars = r.root.variables();\n for (const name in vars) {\n if (vars.hasOwnProperty(name)) {\n hash[name] = r.root.variable(name);\n }\n }\n }\n return hash;\n }, {});\n }\n return this._variables;\n }\n\n properties() {\n if (!this._properties) {\n this._properties = !this.rules ? {} : this.rules.reduce((hash, r) => {\n if (r instanceof Declaration && r.variable !== true) {\n const name = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?\n r.name[0].value : r.name;\n // Properties don't overwrite as they can merge\n if (!hash[`$${name}`]) {\n hash[`$${name}`] = [ r ];\n }\n else {\n hash[`$${name}`].push(r);\n }\n }\n return hash;\n }, {});\n }\n return this._properties;\n }\n\n variable(name) {\n const decl = this.variables()[name];\n if (decl) {\n return this.parseValue(decl);\n }\n }\n\n property(name) {\n const decl = this.properties()[name];\n if (decl) {\n return this.parseValue(decl);\n }\n }\n\n lastDeclaration() {\n for (let i = this.rules.length; i > 0; i--) {\n const decl = this.rules[i - 1];\n if (decl instanceof Declaration) {\n return this.parseValue(decl);\n }\n }\n }\n\n parseValue(toParse) {\n const self = this;\n function transformDeclaration(decl) {\n if (decl.value instanceof Anonymous && !decl.parsed) {\n if (typeof decl.value.value === 'string') {\n this.parse.parseNode(\n decl.value.value,\n ['value', 'important'], \n decl.value.getIndex(), \n decl.fileInfo(), \n (err, result) => {\n if (err) {\n decl.parsed = true;\n }\n if (result) {\n decl.value = result[0];\n decl.important = result[1] || '';\n decl.parsed = true;\n }\n });\n } else {\n decl.parsed = true;\n }\n\n return decl;\n }\n else {\n return decl;\n }\n }\n if (!Array.isArray(toParse)) {\n return transformDeclaration.call(self, toParse);\n }\n else {\n const nodes = [];\n toParse.forEach(n => {\n nodes.push(transformDeclaration.call(self, n));\n });\n return nodes;\n }\n }\n\n rulesets() {\n if (!this.rules) { return []; }\n\n const filtRules = [];\n const rules = this.rules;\n let i;\n let rule;\n\n for (i = 0; (rule = rules[i]); i++) {\n if (rule.isRuleset) {\n filtRules.push(rule);\n }\n }\n\n return filtRules;\n }\n\n prependRule(rule) {\n const rules = this.rules;\n if (rules) {\n rules.unshift(rule);\n } else {\n this.rules = [ rule ];\n }\n this.setParent(rule, this);\n }\n\n find(selector, self = this, filter) {\n const rules = [];\n let match;\n let foundMixins;\n const key = selector.toCSS();\n\n if (key in this._lookups) { return this._lookups[key]; }\n\n this.rulesets().forEach(rule => {\n if (rule !== self) {\n for (let j = 0; j < rule.selectors.length; j++) {\n match = selector.match(rule.selectors[j]);\n if (match) {\n if (selector.elements.length > match) {\n if (!filter || filter(rule)) {\n foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);\n for (let i = 0; i < foundMixins.length; ++i) {\n foundMixins[i].path.push(rule);\n }\n Array.prototype.push.apply(rules, foundMixins);\n }\n } else {\n rules.push({ rule, path: []});\n }\n break;\n }\n }\n }\n });\n this._lookups[key] = rules;\n return rules;\n }\n\n genCSS(context, output) {\n let i;\n let j;\n const charsetRuleNodes = [];\n let ruleNodes = [];\n\n let // Line number debugging\n debugInfo;\n\n let rule;\n let path;\n\n context.tabLevel = (context.tabLevel || 0);\n\n if (!this.root) {\n context.tabLevel++;\n }\n\n const tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' ');\n const tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' ');\n let sep;\n\n let charsetNodeIndex = 0;\n let importNodeIndex = 0;\n for (i = 0; (rule = this.rules[i]); i++) {\n if (rule instanceof Comment) {\n if (importNodeIndex === i) {\n importNodeIndex++;\n }\n ruleNodes.push(rule);\n } else if (rule.isCharset && rule.isCharset()) {\n ruleNodes.splice(charsetNodeIndex, 0, rule);\n charsetNodeIndex++;\n importNodeIndex++;\n } else if (rule.type === 'Import') {\n ruleNodes.splice(importNodeIndex, 0, rule);\n importNodeIndex++;\n } else {\n ruleNodes.push(rule);\n }\n }\n ruleNodes = charsetRuleNodes.concat(ruleNodes);\n\n // If this is the root node, we don't render\n // a selector, or {}.\n if (!this.root) {\n debugInfo = getDebugInfo(context, this, tabSetStr);\n\n if (debugInfo) {\n output.add(debugInfo);\n output.add(tabSetStr);\n }\n\n const paths = this.paths;\n const pathCnt = paths.length;\n let pathSubCnt;\n\n sep = context.compress ? ',' : (`,\\n${tabSetStr}`);\n\n for (i = 0; i < pathCnt; i++) {\n path = paths[i];\n if (!(pathSubCnt = path.length)) { continue; }\n if (i > 0) { output.add(sep); }\n\n context.firstSelector = true;\n path[0].genCSS(context, output);\n\n context.firstSelector = false;\n for (j = 1; j < pathSubCnt; j++) {\n path[j].genCSS(context, output);\n }\n }\n\n output.add((context.compress ? '{' : ' {\\n') + tabRuleStr);\n }\n\n // Compile rules and rulesets\n for (i = 0; (rule = ruleNodes[i]); i++) {\n\n if (i + 1 === ruleNodes.length) {\n context.lastRule = true;\n }\n\n const currentLastRule = context.lastRule;\n if (rule.isRulesetLike(rule)) {\n context.lastRule = false;\n }\n\n if (rule.genCSS) {\n rule.genCSS(context, output);\n } else if (rule.value) {\n output.add(rule.value.toString());\n }\n\n context.lastRule = currentLastRule;\n\n if (!context.lastRule && rule.isVisible()) {\n output.add(context.compress ? '' : (`\\n${tabRuleStr}`));\n } else {\n context.lastRule = false;\n }\n }\n\n if (!this.root) {\n output.add((context.compress ? '}' : `\\n${tabSetStr}}`));\n context.tabLevel--;\n }\n\n if (!output.isEmpty() && !context.compress && this.firstRoot) {\n output.add('\\n');\n }\n }\n\n joinSelectors(paths, context, selectors) {\n for (let s = 0; s < selectors.length; s++) {\n this.joinSelector(paths, context, selectors[s]);\n }\n }\n\n joinSelector(paths, context, selector) {\n function createParenthesis(elementsToPak, originalElement) {\n let replacementParen;\n let j;\n if (elementsToPak.length === 0) {\n replacementParen = new Paren(elementsToPak[0]);\n } else {\n const insideParent = new Array(elementsToPak.length);\n for (j = 0; j < elementsToPak.length; j++) {\n insideParent[j] = new Element(\n null,\n elementsToPak[j],\n originalElement.isVariable,\n originalElement._index,\n originalElement._fileInfo\n );\n }\n replacementParen = new Paren(new Selector(insideParent));\n }\n return replacementParen;\n }\n\n function createSelector(containedElement, originalElement) {\n let element;\n let selector;\n element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);\n selector = new Selector([element]);\n return selector;\n }\n\n // joins selector path from `beginningPath` with selector path in `addPath`\n // `replacedElement` contains element that is being replaced by `addPath`\n // returns concatenated path\n function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {\n let newSelectorPath;\n let lastSelector;\n let newJoinedSelector;\n // our new selector path\n newSelectorPath = [];\n\n // construct the joined selector - if & is the first thing this will be empty,\n // if not newJoinedSelector will be the last set of elements in the selector\n if (beginningPath.length > 0) {\n newSelectorPath = utils.copyArray(beginningPath);\n lastSelector = newSelectorPath.pop();\n newJoinedSelector = originalSelector.createDerived(utils.copyArray(lastSelector.elements));\n }\n else {\n newJoinedSelector = originalSelector.createDerived([]);\n }\n\n if (addPath.length > 0) {\n // /deep/ is a CSS4 selector - (removed, so should deprecate)\n // that is valid without anything in front of it\n // so if the & does not have a combinator that is \"\" or \" \" then\n // and there is a combinator on the parent, then grab that.\n // this also allows + a { & .b { .a & { ... though not sure why you would want to do that\n let combinator = replacedElement.combinator;\n\n const parentEl = addPath[0].elements[0];\n if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {\n combinator = parentEl.combinator;\n }\n // join the elements so far with the first part of the parent\n newJoinedSelector.elements.push(new Element(\n combinator,\n parentEl.value,\n replacedElement.isVariable,\n replacedElement._index,\n replacedElement._fileInfo\n ));\n newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));\n }\n\n // now add the joined selector - but only if it is not empty\n if (newJoinedSelector.elements.length !== 0) {\n newSelectorPath.push(newJoinedSelector);\n }\n\n // put together the parent selectors after the join (e.g. the rest of the parent)\n if (addPath.length > 1) {\n let restOfPath = addPath.slice(1);\n restOfPath = restOfPath.map(selector => selector.createDerived(selector.elements, []));\n newSelectorPath = newSelectorPath.concat(restOfPath);\n }\n return newSelectorPath;\n }\n\n // joins selector path from `beginningPath` with every selector path in `addPaths` array\n // `replacedElement` contains element that is being replaced by `addPath`\n // returns array with all concatenated paths\n function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {\n let j;\n for (j = 0; j < beginningPath.length; j++) {\n const newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);\n result.push(newSelectorPath);\n }\n return result;\n }\n\n function mergeElementsOnToSelectors(elements, selectors) {\n let i;\n let sel;\n\n if (elements.length === 0) {\n return ;\n }\n if (selectors.length === 0) {\n selectors.push([ new Selector(elements) ]);\n return;\n }\n\n for (i = 0; (sel = selectors[i]); i++) {\n // if the previous thing in sel is a parent this needs to join on to it\n if (sel.length > 0) {\n sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));\n }\n else {\n sel.push(new Selector(elements));\n }\n }\n }\n\n // replace all parent selectors inside `inSelector` by content of `context` array\n // resulting selectors are returned inside `paths` array\n // returns true if `inSelector` contained at least one parent selector\n function replaceParentSelector(paths, context, inSelector) {\n // The paths are [[Selector]]\n // The first list is a list of comma separated selectors\n // The inner list is a list of inheritance separated selectors\n // e.g.\n // .a, .b {\n // .c {\n // }\n // }\n // == [[.a] [.c]] [[.b] [.c]]\n //\n let i;\n\n let j;\n let k;\n let currentElements;\n let newSelectors;\n let selectorsMultiplied;\n let sel;\n let el;\n let hadParentSelector = false;\n let length;\n let lastSelector;\n function findNestedSelector(element) {\n let maybeSelector;\n if (!(element.value instanceof Paren)) {\n return null;\n }\n\n maybeSelector = element.value.value;\n if (!(maybeSelector instanceof Selector)) {\n return null;\n }\n\n return maybeSelector;\n }\n\n // the elements from the current selector so far\n currentElements = [];\n // the current list of new selectors to add to the path.\n // We will build it up. We initiate it with one empty selector as we \"multiply\" the new selectors\n // by the parents\n newSelectors = [\n []\n ];\n\n for (i = 0; (el = inSelector.elements[i]); i++) {\n // non parent reference elements just get added\n if (el.value !== '&') {\n const nestedSelector = findNestedSelector(el);\n if (nestedSelector != null) {\n // merge the current list of non parent selector elements\n // on to the current list of selectors to add\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n const nestedPaths = [];\n let replaced;\n const replacedNewSelectors = [];\n replaced = replaceParentSelector(nestedPaths, context, nestedSelector);\n hadParentSelector = hadParentSelector || replaced;\n // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors\n for (k = 0; k < nestedPaths.length; k++) {\n const replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);\n addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);\n }\n newSelectors = replacedNewSelectors;\n currentElements = [];\n } else {\n currentElements.push(el);\n }\n\n } else {\n hadParentSelector = true;\n // the new list of selectors to add\n selectorsMultiplied = [];\n\n // merge the current list of non parent selector elements\n // on to the current list of selectors to add\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n // loop through our current selectors\n for (j = 0; j < newSelectors.length; j++) {\n sel = newSelectors[j];\n // if we don't have any parent paths, the & might be in a mixin so that it can be used\n // whether there are parents or not\n if (context.length === 0) {\n // the combinator used on el should now be applied to the next element instead so that\n // it is not lost\n if (sel.length > 0) {\n sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));\n }\n selectorsMultiplied.push(sel);\n }\n else {\n // and the parent selectors\n for (k = 0; k < context.length; k++) {\n // We need to put the current selectors\n // then join the last selector's elements on to the parents selectors\n const newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);\n // add that to our new set of selectors\n selectorsMultiplied.push(newSelectorPath);\n }\n }\n }\n\n // our new selectors has been multiplied, so reset the state\n newSelectors = selectorsMultiplied;\n currentElements = [];\n }\n }\n\n // if we have any elements left over (e.g. .a& .b == .b)\n // add them on to all the current selectors\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n for (i = 0; i < newSelectors.length; i++) {\n length = newSelectors[i].length;\n if (length > 0) {\n paths.push(newSelectors[i]);\n lastSelector = newSelectors[i][length - 1];\n newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);\n }\n }\n\n return hadParentSelector;\n }\n\n function deriveSelector(visibilityInfo, deriveFrom) {\n const newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);\n newSelector.copyVisibilityInfo(visibilityInfo);\n return newSelector;\n }\n\n // joinSelector code follows\n let i;\n\n let newPaths;\n let hadParentSelector;\n\n newPaths = [];\n hadParentSelector = replaceParentSelector(newPaths, context, selector);\n\n if (!hadParentSelector) {\n if (context.length > 0) {\n newPaths = [];\n for (i = 0; i < context.length; i++) {\n\n const concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));\n\n concatenated.push(selector);\n newPaths.push(concatenated);\n }\n }\n else {\n newPaths = [[selector]];\n }\n }\n\n for (i = 0; i < newPaths.length; i++) {\n paths.push(newPaths[i]);\n }\n }\n}\n\nRuleset.prototype.type = 'Ruleset';\nRuleset.prototype.isRuleset = true;\nexport default Ruleset;\n","import Node from './node';\nimport Selector from './selector';\nimport Ruleset from './ruleset';\nimport Anonymous from './anonymous';\n\nclass AtRule extends Node {\n constructor(\n name,\n value,\n rules,\n index,\n currentFileInfo,\n debugInfo,\n isRooted,\n visibilityInfo\n ) {\n super();\n\n let i;\n\n this.name = name;\n this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);\n if (rules) {\n if (Array.isArray(rules)) {\n this.rules = rules;\n } else {\n this.rules = [rules];\n this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();\n }\n for (i = 0; i < this.rules.length; i++) {\n this.rules[i].allowImports = true;\n }\n this.setParent(this.rules, this);\n }\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.debugInfo = debugInfo;\n this.isRooted = isRooted || false;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n }\n\n accept(visitor) {\n const value = this.value;\n const rules = this.rules;\n if (rules) {\n this.rules = visitor.visitArray(rules);\n }\n if (value) {\n this.value = visitor.visit(value);\n }\n }\n\n isRulesetLike() {\n return this.rules || !this.isCharset();\n }\n\n isCharset() {\n return '@charset' === this.name;\n }\n\n genCSS(context, output) {\n const value = this.value;\n const rules = this.rules;\n output.add(this.name, this.fileInfo(), this.getIndex());\n if (value) {\n output.add(' ');\n value.genCSS(context, output);\n }\n if (rules) {\n this.outputRuleset(context, output, rules);\n } else {\n output.add(';');\n }\n }\n\n eval(context) {\n let mediaPathBackup;\n let mediaBlocksBackup;\n let value = this.value;\n let rules = this.rules;\n\n // media stored inside other atrule should not bubble over it\n // backpup media bubbling information\n mediaPathBackup = context.mediaPath;\n mediaBlocksBackup = context.mediaBlocks;\n // deleted media bubbling information\n context.mediaPath = [];\n context.mediaBlocks = [];\n\n if (value) {\n value = value.eval(context);\n }\n if (rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n rules = [rules[0].eval(context)];\n rules[0].root = true;\n }\n // restore media bubbling information\n context.mediaPath = mediaPathBackup;\n context.mediaBlocks = mediaBlocksBackup;\n\n return new AtRule(this.name, value, rules,\n this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo());\n }\n\n variable(name) {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.variable.call(this.rules[0], name);\n }\n }\n\n find(...args) {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.find.apply(this.rules[0], args);\n }\n }\n\n rulesets() {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.rulesets.apply(this.rules[0]);\n }\n }\n\n outputRuleset(context, output, rules) {\n const ruleCnt = rules.length;\n let i;\n context.tabLevel = (context.tabLevel | 0) + 1;\n\n // Compressed\n if (context.compress) {\n output.add('{');\n for (i = 0; i < ruleCnt; i++) {\n rules[i].genCSS(context, output);\n }\n output.add('}');\n context.tabLevel--;\n return;\n }\n\n // Non-compressed\n const tabSetStr = `\\n${Array(context.tabLevel).join(' ')}`;\n\n const tabRuleStr = `${tabSetStr} `;\n if (!ruleCnt) {\n output.add(` {${tabSetStr}}`);\n } else {\n output.add(` {${tabRuleStr}`);\n rules[0].genCSS(context, output);\n for (i = 1; i < ruleCnt; i++) {\n output.add(tabRuleStr);\n rules[i].genCSS(context, output);\n }\n output.add(`${tabSetStr}}`);\n }\n\n context.tabLevel--;\n }\n}\n\nAtRule.prototype.type = 'AtRule';\nexport default AtRule;\n","import Node from './node';\nimport contexts from '../contexts';\nimport * as utils from '../utils';\n\nclass DetachedRuleset extends Node {\n constructor(ruleset, frames) {\n super();\n\n this.ruleset = ruleset;\n this.frames = frames;\n this.setParent(this.ruleset, this);\n }\n\n accept(visitor) {\n this.ruleset = visitor.visit(this.ruleset);\n }\n\n eval(context) {\n const frames = this.frames || utils.copyArray(context.frames);\n return new DetachedRuleset(this.ruleset, frames);\n }\n\n callEval(context) {\n return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);\n }\n}\n\nDetachedRuleset.prototype.type = 'DetachedRuleset';\nDetachedRuleset.prototype.evalFirst = true;\nexport default DetachedRuleset;\n","import Node from './node';\nimport unitConversions from '../data/unit-conversions';\nimport * as utils from '../utils';\n\nclass Unit extends Node {\n constructor(numerator, denominator, backupUnit) {\n super();\n\n this.numerator = numerator ? utils.copyArray(numerator).sort() : [];\n this.denominator = denominator ? utils.copyArray(denominator).sort() : [];\n if (backupUnit) {\n this.backupUnit = backupUnit;\n } else if (numerator && numerator.length) {\n this.backupUnit = numerator[0];\n }\n }\n\n clone() {\n return new Unit(utils.copyArray(this.numerator), utils.copyArray(this.denominator), this.backupUnit);\n }\n\n genCSS(context, output) {\n // Dimension checks the unit is singular and throws an error if in strict math mode.\n const strictUnits = context && context.strictUnits;\n if (this.numerator.length === 1) {\n output.add(this.numerator[0]); // the ideal situation\n } else if (!strictUnits && this.backupUnit) {\n output.add(this.backupUnit);\n } else if (!strictUnits && this.denominator.length) {\n output.add(this.denominator[0]);\n }\n }\n\n toString() {\n let i;\n let returnStr = this.numerator.join('*');\n for (i = 0; i < this.denominator.length; i++) {\n returnStr += `/${this.denominator[i]}`;\n }\n return returnStr;\n }\n\n compare(other) {\n return this.is(other.toString()) ? 0 : undefined;\n }\n\n is(unitString) {\n return this.toString().toUpperCase() === unitString.toUpperCase();\n }\n\n isLength() {\n return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS());\n }\n\n isEmpty() {\n return this.numerator.length === 0 && this.denominator.length === 0;\n }\n\n isSingular() {\n return this.numerator.length <= 1 && this.denominator.length === 0;\n }\n\n map(callback) {\n let i;\n\n for (i = 0; i < this.numerator.length; i++) {\n this.numerator[i] = callback(this.numerator[i], false);\n }\n\n for (i = 0; i < this.denominator.length; i++) {\n this.denominator[i] = callback(this.denominator[i], true);\n }\n }\n\n usedUnits() {\n let group;\n const result = {};\n let mapUnit;\n let groupName;\n\n mapUnit = atomicUnit => {\n /* jshint loopfunc:true */\n if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {\n result[groupName] = atomicUnit;\n }\n\n return atomicUnit;\n };\n\n for (groupName in unitConversions) {\n if (unitConversions.hasOwnProperty(groupName)) {\n group = unitConversions[groupName];\n\n this.map(mapUnit);\n }\n }\n\n return result;\n }\n\n cancel() {\n const counter = {};\n let atomicUnit;\n let i;\n\n for (i = 0; i < this.numerator.length; i++) {\n atomicUnit = this.numerator[i];\n counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;\n }\n\n for (i = 0; i < this.denominator.length; i++) {\n atomicUnit = this.denominator[i];\n counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;\n }\n\n this.numerator = [];\n this.denominator = [];\n\n for (atomicUnit in counter) {\n if (counter.hasOwnProperty(atomicUnit)) {\n const count = counter[atomicUnit];\n\n if (count > 0) {\n for (i = 0; i < count; i++) {\n this.numerator.push(atomicUnit);\n }\n } else if (count < 0) {\n for (i = 0; i < -count; i++) {\n this.denominator.push(atomicUnit);\n }\n }\n }\n }\n\n this.numerator.sort();\n this.denominator.sort();\n }\n}\n\nUnit.prototype.type = 'Unit';\nexport default Unit;\n","import Node from './node';\nimport unitConversions from '../data/unit-conversions';\nimport Unit from './unit';\nimport Color from './color';\n\n//\n// A number with a unit\n//\nclass Dimension extends Node {\n constructor(value, unit) {\n super();\n\n this.value = parseFloat(value);\n if (isNaN(this.value)) {\n throw new Error('Dimension is not a number.');\n }\n this.unit = (unit && unit instanceof Unit) ? unit :\n new Unit(unit ? [unit] : undefined);\n this.setParent(this.unit, this);\n }\n\n accept(visitor) {\n this.unit = visitor.visit(this.unit);\n }\n\n eval(context) {\n return this;\n }\n\n toColor() {\n return new Color([this.value, this.value, this.value]);\n }\n\n genCSS(context, output) {\n if ((context && context.strictUnits) && !this.unit.isSingular()) {\n throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`);\n }\n\n const value = this.fround(context, this.value);\n let strValue = String(value);\n\n if (value !== 0 && value < 0.000001 && value > -0.000001) {\n // would be output 1e-6 etc.\n strValue = value.toFixed(20).replace(/0+$/, '');\n }\n\n if (context && context.compress) {\n // Zero values doesn't need a unit\n if (value === 0 && this.unit.isLength()) {\n output.add(strValue);\n return;\n }\n\n // Float values doesn't need a leading zero\n if (value > 0 && value < 1) {\n strValue = (strValue).substr(1);\n }\n }\n\n output.add(strValue);\n this.unit.genCSS(context, output);\n }\n\n // In an operation between two Dimensions,\n // we default to the first Dimension's unit,\n // so `1px + 2` will yield `3px`.\n operate(context, op, other) {\n /* jshint noempty:false */\n let value = this._operate(context, op, this.value, other.value);\n\n let unit = this.unit.clone();\n\n if (op === '+' || op === '-') {\n if (unit.numerator.length === 0 && unit.denominator.length === 0) {\n unit = other.unit.clone();\n if (this.unit.backupUnit) {\n unit.backupUnit = this.unit.backupUnit;\n }\n } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {\n // do nothing\n } else {\n other = other.convertTo(this.unit.usedUnits());\n\n if (context.strictUnits && other.unit.toString() !== unit.toString()) {\n throw new Error(`Incompatible units. Change the units or use the unit function. ` + \n `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`);\n }\n\n value = this._operate(context, op, this.value, other.value);\n }\n } else if (op === '*') {\n unit.numerator = unit.numerator.concat(other.unit.numerator).sort();\n unit.denominator = unit.denominator.concat(other.unit.denominator).sort();\n unit.cancel();\n } else if (op === '/') {\n unit.numerator = unit.numerator.concat(other.unit.denominator).sort();\n unit.denominator = unit.denominator.concat(other.unit.numerator).sort();\n unit.cancel();\n }\n return new Dimension(value, unit);\n }\n\n compare(other) {\n let a;\n let b;\n\n if (!(other instanceof Dimension)) {\n return undefined;\n }\n\n if (this.unit.isEmpty() || other.unit.isEmpty()) {\n a = this;\n b = other;\n } else {\n a = this.unify();\n b = other.unify();\n if (a.unit.compare(b.unit) !== 0) {\n return undefined;\n }\n }\n\n return Node.numericCompare(a.value, b.value);\n }\n\n unify() {\n return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });\n }\n\n convertTo(conversions) {\n let value = this.value;\n const unit = this.unit.clone();\n let i;\n let groupName;\n let group;\n let targetUnit;\n let derivedConversions = {};\n let applyUnit;\n\n if (typeof conversions === 'string') {\n for (i in unitConversions) {\n if (unitConversions[i].hasOwnProperty(conversions)) {\n derivedConversions = {};\n derivedConversions[i] = conversions;\n }\n }\n conversions = derivedConversions;\n }\n applyUnit = (atomicUnit, denominator) => {\n /* jshint loopfunc:true */\n if (group.hasOwnProperty(atomicUnit)) {\n if (denominator) {\n value = value / (group[atomicUnit] / group[targetUnit]);\n } else {\n value = value * (group[atomicUnit] / group[targetUnit]);\n }\n\n return targetUnit;\n }\n\n return atomicUnit;\n };\n\n for (groupName in conversions) {\n if (conversions.hasOwnProperty(groupName)) {\n targetUnit = conversions[groupName];\n group = unitConversions[groupName];\n\n unit.map(applyUnit);\n }\n }\n\n unit.cancel();\n\n return new Dimension(value, unit);\n }\n}\n\nDimension.prototype.type = 'Dimension';\nexport default Dimension;\n","import Node from './node';\nimport Color from './color';\nimport Dimension from './dimension';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\n\nclass Operation extends Node {\n constructor(op, operands, isSpaced) {\n super();\n\n this.op = op.trim();\n this.operands = operands;\n this.isSpaced = isSpaced;\n }\n\n accept(visitor) {\n this.operands = visitor.visitArray(this.operands);\n }\n\n eval(context) {\n let a = this.operands[0].eval(context);\n let b = this.operands[1].eval(context);\n let op;\n\n if (context.isMathOn(this.op)) {\n op = this.op === './' ? '/' : this.op;\n if (a instanceof Dimension && b instanceof Color) {\n a = a.toColor();\n }\n if (b instanceof Dimension && a instanceof Color) {\n b = b.toColor();\n }\n if (!a.operate) {\n if (a instanceof Operation && a.op === '/' && context.math === MATH.PARENS_DIVISION) {\n return new Operation(this.op, [a, b], this.isSpaced);\n }\n throw { type: 'Operation',\n message: 'Operation on an invalid type' };\n }\n\n return a.operate(context, op, b);\n } else {\n return new Operation(this.op, [a, b], this.isSpaced);\n }\n }\n\n genCSS(context, output) {\n this.operands[0].genCSS(context, output);\n if (this.isSpaced) {\n output.add(' ');\n }\n output.add(this.op);\n if (this.isSpaced) {\n output.add(' ');\n }\n this.operands[1].genCSS(context, output);\n }\n}\n\nOperation.prototype.type = 'Operation';\nexport default Operation;\n","import Node from './node';\nimport Paren from './paren';\nimport Comment from './comment';\nimport Dimension from './dimension';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\nclass Expression extends Node {\n constructor(value, noSpacing) {\n super();\n\n this.value = value;\n this.noSpacing = noSpacing;\n if (!value) {\n throw new Error('Expression requires an array parameter');\n }\n }\n\n accept(visitor) {\n this.value = visitor.visitArray(this.value);\n }\n\n eval(context) {\n let returnValue;\n const mathOn = context.isMathOn();\n\n const inParenthesis = this.parens && \n (context.math !== MATH.STRICT_LEGACY || !this.parensInOp);\n\n let doubleParen = false;\n if (inParenthesis) {\n context.inParenthesis();\n }\n if (this.value.length > 1) {\n returnValue = new Expression(this.value.map(e => {\n if (!e.eval) {\n return e;\n }\n return e.eval(context);\n }), this.noSpacing);\n } else if (this.value.length === 1) {\n if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {\n doubleParen = true;\n }\n returnValue = this.value[0].eval(context);\n } else {\n returnValue = this;\n }\n if (inParenthesis) {\n context.outOfParenthesis();\n }\n if (this.parens && this.parensInOp && !mathOn && !doubleParen \n && (!(returnValue instanceof Dimension))) {\n returnValue = new Paren(returnValue);\n }\n return returnValue;\n }\n\n genCSS(context, output) {\n for (let i = 0; i < this.value.length; i++) {\n this.value[i].genCSS(context, output);\n if (!this.noSpacing && i + 1 < this.value.length) {\n output.add(' ');\n }\n }\n }\n\n throwAwayComments() {\n this.value = this.value.filter(v => !(v instanceof Comment));\n }\n}\n\nExpression.prototype.type = 'Expression';\nexport default Expression;\n","import Expression from '../tree/expression';\n\nclass functionCaller {\n constructor(name, context, index, currentFileInfo) {\n this.name = name.toLowerCase();\n this.index = index;\n this.context = context;\n this.currentFileInfo = currentFileInfo;\n\n this.func = context.frames[0].functionRegistry.get(this.name);\n }\n\n isValid() {\n return Boolean(this.func);\n }\n\n call(args) {\n // This code is terrible and should be replaced as per this issue...\n // https://github.com/less/less.js/issues/2477\n if (Array.isArray(args)) {\n args = args.filter(item => {\n if (item.type === 'Comment') {\n return false;\n }\n return true;\n })\n .map(item => {\n if (item.type === 'Expression') {\n const subNodes = item.value.filter(item => {\n if (item.type === 'Comment') {\n return false;\n }\n return true;\n });\n if (subNodes.length === 1) {\n return subNodes[0];\n } else {\n return new Expression(subNodes);\n }\n }\n return item;\n });\n }\n\n return this.func(...args);\n }\n}\n\nexport default functionCaller;\n","import Node from './node';\nimport Anonymous from './anonymous';\nimport FunctionCaller from '../functions/function-caller';\n\n//\n// A function call node.\n//\nclass Call extends Node {\n constructor(name, args, index, currentFileInfo) {\n super();\n\n this.name = name;\n this.args = args;\n this.calc = name === 'calc';\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n accept(visitor) {\n if (this.args) {\n this.args = visitor.visitArray(this.args);\n }\n }\n\n //\n // When evaluating a function call,\n // we either find the function in the functionRegistry,\n // in which case we call it, passing the evaluated arguments,\n // if this returns null or we cannot find the function, we\n // simply print it out as it appeared originally [2].\n //\n // The reason why we evaluate the arguments, is in the case where\n // we try to pass a variable to a function, like: `saturate(@color)`.\n // The function should receive the value, not the variable.\n //\n eval(context) {\n /**\n * Turn off math for calc(), and switch back on for evaluating nested functions\n */\n const currentMathContext = context.mathOn;\n context.mathOn = !this.calc;\n if (this.calc || context.inCalc) {\n context.enterCalc();\n }\n const args = this.args.map(a => a.eval(context));\n if (this.calc || context.inCalc) {\n context.exitCalc();\n }\n context.mathOn = currentMathContext;\n\n let result;\n const funcCaller = new FunctionCaller(this.name, context, this.getIndex(), this.fileInfo());\n\n if (funcCaller.isValid()) {\n try {\n result = funcCaller.call(args);\n } catch (e) {\n throw { \n type: e.type || 'Runtime',\n message: `error evaluating function \\`${this.name}\\`${e.message ? `: ${e.message}` : ''}`,\n index: this.getIndex(), \n filename: this.fileInfo().filename,\n line: e.lineNumber,\n column: e.columnNumber\n };\n }\n\n if (result !== null && result !== undefined) {\n // Results that that are not nodes are cast as Anonymous nodes\n // Falsy values or booleans are returned as empty nodes\n if (!(result instanceof Node)) {\n if (!result || result === true) {\n result = new Anonymous(null); \n }\n else {\n result = new Anonymous(result.toString()); \n }\n \n }\n result._index = this._index;\n result._fileInfo = this._fileInfo;\n return result;\n }\n\n }\n\n return new Call(this.name, args, this.getIndex(), this.fileInfo());\n }\n\n genCSS(context, output) {\n output.add(`${this.name}(`, this.fileInfo(), this.getIndex());\n\n for (let i = 0; i < this.args.length; i++) {\n this.args[i].genCSS(context, output);\n if (i + 1 < this.args.length) {\n output.add(', ');\n }\n }\n\n output.add(')');\n }\n}\n\nCall.prototype.type = 'Call';\nexport default Call;\n","import Node from './node';\nimport Call from './call';\n\nclass Variable extends Node {\n constructor(name, index, currentFileInfo) {\n super();\n\n this.name = name;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n let variable;\n let name = this.name;\n\n if (name.indexOf('@@') === 0) {\n name = `@${new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value}`;\n }\n\n if (this.evaluating) {\n throw { type: 'Name',\n message: `Recursive variable definition for ${name}`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n this.evaluating = true;\n\n variable = this.find(context.frames, frame => {\n const v = frame.variable(name);\n if (v) {\n if (v.important) {\n const importantScope = context.importantScope[context.importantScope.length - 1];\n importantScope.important = v.important;\n }\n // If in calc, wrap vars in a function call to cascade evaluate args first\n if (context.inCalc) {\n return (new Call('_SELF', [v.value])).eval(context);\n }\n else {\n return v.value.eval(context);\n }\n }\n });\n if (variable) {\n this.evaluating = false;\n return variable;\n } else {\n throw { type: 'Name',\n message: `variable ${name} is undefined`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n }\n\n find(obj, fun) {\n for (let i = 0, r; i < obj.length; i++) {\n r = fun.call(obj, obj[i]);\n if (r) { return r; }\n }\n return null;\n }\n}\n\nVariable.prototype.type = 'Variable';\nexport default Variable;\n","import Node from './node';\nimport Declaration from './declaration';\n\nclass Property extends Node {\n constructor(name, index, currentFileInfo) {\n super();\n\n this.name = name;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n let property;\n const name = this.name;\n // TODO: shorten this reference\n const mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules;\n\n if (this.evaluating) {\n throw { type: 'Name',\n message: `Recursive property reference for ${name}`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n this.evaluating = true;\n\n property = this.find(context.frames, frame => {\n let v;\n const vArr = frame.property(name);\n if (vArr) {\n for (let i = 0; i < vArr.length; i++) {\n v = vArr[i];\n\n vArr[i] = new Declaration(v.name,\n v.value,\n v.important,\n v.merge,\n v.index,\n v.currentFileInfo,\n v.inline,\n v.variable\n );\n }\n mergeRules(vArr);\n\n v = vArr[vArr.length - 1];\n if (v.important) {\n const importantScope = context.importantScope[context.importantScope.length - 1];\n importantScope.important = v.important;\n }\n v = v.value.eval(context);\n return v;\n }\n });\n if (property) {\n this.evaluating = false;\n return property;\n } else {\n throw { type: 'Name',\n message: `Property '${name}' is undefined`,\n filename: this.currentFileInfo.filename,\n index: this.index };\n }\n }\n\n find(obj, fun) {\n for (let i = 0, r; i < obj.length; i++) {\n r = fun.call(obj, obj[i]);\n if (r) { return r; }\n }\n return null;\n }\n}\n\nProperty.prototype.type = 'Property';\nexport default Property;\n","import Node from './node';\n\nclass Attribute extends Node {\n constructor(key, op, value) {\n super();\n\n this.key = key;\n this.op = op;\n this.value = value;\n }\n\n eval(context) {\n return new Attribute(this.key.eval ? this.key.eval(context) : this.key,\n this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context));\n }\n\n toCSS(context) {\n let value = this.key.toCSS ? this.key.toCSS(context) : this.key;\n\n if (this.op) {\n value += this.op;\n value += (this.value.toCSS ? this.value.toCSS(context) : this.value);\n }\n\n return `[${value}]`;\n }\n}\n\nAttribute.prototype.type = 'Attribute';\nexport default Attribute;\n","import Node from './node';\nimport Variable from './variable';\nimport Property from './property';\n\n\nclass Quoted extends Node {\n constructor(str, content, escaped, index, currentFileInfo) {\n super();\n\n this.escaped = (escaped == null) ? true : escaped;\n this.value = content || '';\n this.quote = str.charAt(0);\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.variableRegex = /@\\{([\\w-]+)\\}/g;\n this.propRegex = /\\$\\{([\\w-]+)\\}/g;\n this.allowRoot = escaped;\n }\n\n genCSS(context, output) {\n if (!this.escaped) {\n output.add(this.quote, this.fileInfo(), this.getIndex());\n }\n output.add(this.value);\n if (!this.escaped) {\n output.add(this.quote);\n }\n }\n\n containsVariables() {\n return this.value.match(this.variableRegex);\n }\n\n eval(context) {\n const that = this;\n let value = this.value;\n const variableReplacement = (_, name) => {\n const v = new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context, true);\n return (v instanceof Quoted) ? v.value : v.toCSS();\n };\n const propertyReplacement = (_, name) => {\n const v = new Property(`$${name}`, that.getIndex(), that.fileInfo()).eval(context, true);\n return (v instanceof Quoted) ? v.value : v.toCSS();\n };\n function iterativeReplace(value, regexp, replacementFnc) {\n let evaluatedValue = value;\n do {\n value = evaluatedValue.toString();\n evaluatedValue = value.replace(regexp, replacementFnc);\n } while (value !== evaluatedValue);\n return evaluatedValue;\n }\n value = iterativeReplace(value, this.variableRegex, variableReplacement);\n value = iterativeReplace(value, this.propRegex, propertyReplacement);\n\n return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());\n }\n\n compare(other) {\n // when comparing quoted strings allow the quote to differ\n if (other.type === 'Quoted' && !this.escaped && !other.escaped) {\n return Node.numericCompare(this.value, other.value);\n } else {\n return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n }\n }\n}\n\nQuoted.prototype.type = 'Quoted';\nexport default Quoted;\n","import Node from './node';\n\nclass URL extends Node {\n constructor(val, index, currentFileInfo, isEvald) {\n super();\n\n this.value = val;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.isEvald = isEvald;\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n genCSS(context, output) {\n output.add('url(');\n this.value.genCSS(context, output);\n output.add(')');\n }\n\n eval(context) {\n const val = this.value.eval(context);\n let rootpath;\n\n if (!this.isEvald) {\n // Add the rootpath if the URL requires a rewrite\n rootpath = this.fileInfo() && this.fileInfo().rootpath;\n if (typeof rootpath === 'string' &&\n typeof val.value === 'string' &&\n context.pathRequiresRewrite(val.value)) {\n if (!val.quote) {\n rootpath = escapePath(rootpath);\n }\n val.value = context.rewritePath(val.value, rootpath);\n } else {\n val.value = context.normalizePath(val.value);\n }\n\n // Add url args if enabled\n if (context.urlArgs) {\n if (!val.value.match(/^\\s*data:/)) {\n const delimiter = val.value.indexOf('?') === -1 ? '?' : '&';\n const urlArgs = delimiter + context.urlArgs;\n if (val.value.indexOf('#') !== -1) {\n val.value = val.value.replace('#', `${urlArgs}#`);\n } else {\n val.value += urlArgs;\n }\n }\n }\n }\n\n return new URL(val, this.getIndex(), this.fileInfo(), true);\n }\n}\n\nURL.prototype.type = 'Url';\n\nfunction escapePath(path) {\n return path.replace(/[\\(\\)'\"\\s]/g, match => `\\\\${match}`);\n}\n\nexport default URL;\n","import Ruleset from './ruleset';\nimport Value from './value';\nimport Selector from './selector';\nimport Anonymous from './anonymous';\nimport Expression from './expression';\nimport AtRule from './atrule';\nimport * as utils from '../utils';\n\nclass Media extends AtRule {\n constructor(value, features, index, currentFileInfo, visibilityInfo) {\n super();\n\n this._index = index;\n this._fileInfo = currentFileInfo;\n\n const selectors = (new Selector([], null, null, this._index, this._fileInfo)).createEmptySelectors();\n\n this.features = new Value(features);\n this.rules = [new Ruleset(selectors, value)];\n this.rules[0].allowImports = true;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n this.setParent(selectors, this);\n this.setParent(this.features, this);\n this.setParent(this.rules, this);\n }\n\n isRulesetLike() {\n return true;\n }\n\n accept(visitor) {\n if (this.features) {\n this.features = visitor.visit(this.features);\n }\n if (this.rules) {\n this.rules = visitor.visitArray(this.rules);\n }\n }\n\n genCSS(context, output) {\n output.add('@media ', this._fileInfo, this._index);\n this.features.genCSS(context, output);\n this.outputRuleset(context, output, this.rules);\n }\n\n eval(context) {\n if (!context.mediaBlocks) {\n context.mediaBlocks = [];\n context.mediaPath = [];\n }\n\n const media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo());\n if (this.debugInfo) {\n this.rules[0].debugInfo = this.debugInfo;\n media.debugInfo = this.debugInfo;\n }\n \n media.features = this.features.eval(context);\n\n context.mediaPath.push(media);\n context.mediaBlocks.push(media);\n\n this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();\n context.frames.unshift(this.rules[0]);\n media.rules = [this.rules[0].eval(context)];\n context.frames.shift();\n\n context.mediaPath.pop();\n\n return context.mediaPath.length === 0 ? media.evalTop(context) :\n media.evalNested(context);\n }\n\n evalTop(context) {\n let result = this;\n\n // Render all dependent Media blocks.\n if (context.mediaBlocks.length > 1) {\n const selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors();\n result = new Ruleset(selectors, context.mediaBlocks);\n result.multiMedia = true;\n result.copyVisibilityInfo(this.visibilityInfo());\n this.setParent(result, this);\n }\n\n delete context.mediaBlocks;\n delete context.mediaPath;\n\n return result;\n }\n\n evalNested(context) {\n let i;\n let value;\n const path = context.mediaPath.concat([this]);\n\n // Extract the media-query conditions separated with `,` (OR).\n for (i = 0; i < path.length; i++) {\n value = path[i].features instanceof Value ?\n path[i].features.value : path[i].features;\n path[i] = Array.isArray(value) ? value : [value];\n }\n\n // Trace all permutations to generate the resulting media-query.\n //\n // (a, b and c) with nested (d, e) ->\n // a and d\n // a and e\n // b and c and d\n // b and c and e\n this.features = new Value(this.permute(path).map(path => {\n path = path.map(fragment => fragment.toCSS ? fragment : new Anonymous(fragment));\n\n for (i = path.length - 1; i > 0; i--) {\n path.splice(i, 0, new Anonymous('and'));\n }\n\n return new Expression(path);\n }));\n this.setParent(this.features, this);\n\n // Fake a tree-node that doesn't output anything.\n return new Ruleset([], []);\n }\n\n permute(arr) {\n if (arr.length === 0) {\n return [];\n } else if (arr.length === 1) {\n return arr[0];\n } else {\n const result = [];\n const rest = this.permute(arr.slice(1));\n for (let i = 0; i < rest.length; i++) {\n for (let j = 0; j < arr[0].length; j++) {\n result.push([arr[0][j]].concat(rest[i]));\n }\n }\n return result;\n }\n }\n\n bubbleSelectors(selectors) {\n if (!selectors) {\n return;\n }\n this.rules = [new Ruleset(utils.copyArray(selectors), [this.rules[0]])];\n this.setParent(this.rules, this);\n }\n}\n\nMedia.prototype.type = 'Media';\nexport default Media;\n","import Node from './node';\nimport Media from './media';\nimport URL from './url';\nimport Quoted from './quoted';\nimport Ruleset from './ruleset';\nimport Anonymous from './anonymous';\nimport * as utils from '../utils';\nimport LessError from '../less-error';\n\n//\n// CSS @import node\n//\n// The general strategy here is that we don't want to wait\n// for the parsing to be completed, before we start importing\n// the file. That's because in the context of a browser,\n// most of the time will be spent waiting for the server to respond.\n//\n// On creation, we push the import path to our import queue, though\n// `import,push`, we also pass it a callback, which it'll call once\n// the file has been fetched, and parsed.\n//\nclass Import extends Node {\n constructor(path, features, options, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.options = options;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.path = path;\n this.features = features;\n this.allowRoot = true;\n\n if (this.options.less !== undefined || this.options.inline) {\n this.css = !this.options.less || this.options.inline;\n } else {\n const pathValue = this.getPath();\n if (pathValue && /[#\\.\\&\\?]css([\\?;].*)?$/.test(pathValue)) {\n this.css = true;\n }\n }\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.features, this);\n this.setParent(this.path, this);\n }\n\n accept(visitor) {\n if (this.features) {\n this.features = visitor.visit(this.features);\n }\n this.path = visitor.visit(this.path);\n if (!this.options.isPlugin && !this.options.inline && this.root) {\n this.root = visitor.visit(this.root);\n }\n }\n\n genCSS(context, output) {\n if (this.css && this.path._fileInfo.reference === undefined) {\n output.add('@import ', this._fileInfo, this._index);\n this.path.genCSS(context, output);\n if (this.features) {\n output.add(' ');\n this.features.genCSS(context, output);\n }\n output.add(';');\n }\n }\n\n getPath() {\n return (this.path instanceof URL) ?\n this.path.value.value : this.path.value;\n }\n\n isVariableImport() {\n let path = this.path;\n if (path instanceof URL) {\n path = path.value;\n }\n if (path instanceof Quoted) {\n return path.containsVariables();\n }\n\n return true;\n }\n\n evalForImport(context) {\n let path = this.path;\n\n if (path instanceof URL) {\n path = path.value;\n }\n\n return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo());\n }\n\n evalPath(context) {\n const path = this.path.eval(context);\n const fileInfo = this._fileInfo;\n\n if (!(path instanceof URL)) {\n // Add the rootpath if the URL requires a rewrite\n const pathValue = path.value;\n if (fileInfo &&\n pathValue &&\n context.pathRequiresRewrite(pathValue)) {\n path.value = context.rewritePath(pathValue, fileInfo.rootpath);\n } else {\n path.value = context.normalizePath(path.value);\n }\n }\n\n return path;\n }\n\n eval(context) {\n const result = this.doEval(context);\n if (this.options.reference || this.blocksVisibility()) {\n if (result.length || result.length === 0) {\n result.forEach(node => {\n node.addVisibilityBlock();\n }\n );\n } else {\n result.addVisibilityBlock();\n }\n }\n return result;\n }\n\n doEval(context) {\n let ruleset;\n let registry;\n const features = this.features && this.features.eval(context);\n\n if (this.options.isPlugin) {\n if (this.root && this.root.eval) {\n try {\n this.root.eval(context);\n }\n catch (e) {\n e.message = 'Plugin error during evaluation';\n throw new LessError(e, this.root.imports, this.root.filename);\n }\n }\n registry = context.frames[0] && context.frames[0].functionRegistry;\n if ( registry && this.root && this.root.functions ) {\n registry.addMultiple( this.root.functions );\n }\n\n return [];\n }\n\n if (this.skip) {\n if (typeof this.skip === 'function') {\n this.skip = this.skip();\n }\n if (this.skip) {\n return [];\n }\n }\n if (this.options.inline) {\n const contents = new Anonymous(this.root, 0,\n {\n filename: this.importedFilename,\n reference: this.path._fileInfo && this.path._fileInfo.reference\n }, true, true);\n\n return this.features ? new Media([contents], this.features.value) : [contents];\n } else if (this.css) {\n const newImport = new Import(this.evalPath(context), features, this.options, this._index);\n if (!newImport.css && this.error) {\n throw this.error;\n }\n return newImport;\n } else {\n ruleset = new Ruleset(null, utils.copyArray(this.root.rules));\n ruleset.evalImports(context);\n\n return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;\n }\n }\n}\n\nImport.prototype.type = 'Import';\nexport default Import;\n","import Node from './node';\nimport Variable from './variable';\n\nclass JsEvalNode extends Node {\n evaluateJavaScript(expression, context) {\n let result;\n const that = this;\n const evalContext = {};\n\n if (!context.javascriptEnabled) {\n throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n expression = expression.replace(/@\\{([\\w-]+)\\}/g, (_, name) => that.jsify(new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context)));\n\n try {\n expression = new Function(`return (${expression})`);\n } catch (e) {\n throw { message: `JavaScript evaluation error: ${e.message} from \\`${expression}\\`` ,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n const variables = context.frames[0].variables();\n for (const k in variables) {\n if (variables.hasOwnProperty(k)) {\n /* jshint loopfunc:true */\n evalContext[k.slice(1)] = {\n value: variables[k].value,\n toJS: function () {\n return this.value.eval(context).toCSS();\n }\n };\n }\n }\n\n try {\n result = expression.call(evalContext);\n } catch (e) {\n throw { message: `JavaScript evaluation error: '${e.name}: ${e.message.replace(/[\"]/g, '\\'')}'` ,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n return result;\n }\n\n jsify(obj) {\n if (Array.isArray(obj.value) && (obj.value.length > 1)) {\n return `[${obj.value.map(v => v.toCSS()).join(', ')}]`;\n } else {\n return obj.toCSS();\n }\n }\n}\n\nexport default JsEvalNode;\n","import JsEvalNode from './js-eval-node';\nimport Dimension from './dimension';\nimport Quoted from './quoted';\nimport Anonymous from './anonymous';\n\nclass JavaScript extends JsEvalNode {\n constructor(string, escaped, index, currentFileInfo) {\n super();\n\n this.escaped = escaped;\n this.expression = string;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n const result = this.evaluateJavaScript(this.expression, context);\n const type = typeof result;\n\n if (type === 'number' && !isNaN(result)) {\n return new Dimension(result);\n } else if (type === 'string') {\n return new Quoted(`\"${result}\"`, result, this.escaped, this._index);\n } else if (Array.isArray(result)) {\n return new Anonymous(result.join(', '));\n } else {\n return new Anonymous(result);\n }\n }\n}\n\nJavaScript.prototype.type = 'JavaScript';\nexport default JavaScript;\n","import Node from './node';\n\nclass Assignment extends Node {\n constructor(key, val) {\n super();\n\n this.key = key;\n this.value = val;\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n eval(context) {\n if (this.value.eval) {\n return new Assignment(this.key, this.value.eval(context));\n }\n return this;\n }\n\n genCSS(context, output) {\n output.add(`${this.key}=`);\n if (this.value.genCSS) {\n this.value.genCSS(context, output);\n } else {\n output.add(this.value);\n }\n }\n}\n\nAssignment.prototype.type = 'Assignment';\nexport default Assignment;\n","import Node from './node';\n\nclass Condition extends Node {\n constructor(op, l, r, i, negate) {\n super();\n\n this.op = op.trim();\n this.lvalue = l;\n this.rvalue = r;\n this._index = i;\n this.negate = negate;\n }\n\n accept(visitor) {\n this.lvalue = visitor.visit(this.lvalue);\n this.rvalue = visitor.visit(this.rvalue);\n }\n\n eval(context) {\n const result = ((op, a, b) => {\n switch (op) {\n case 'and': return a && b;\n case 'or': return a || b;\n default:\n switch (Node.compare(a, b)) {\n case -1:\n return op === '<' || op === '=<' || op === '<=';\n case 0:\n return op === '=' || op === '>=' || op === '=<' || op === '<=';\n case 1:\n return op === '>' || op === '>=';\n default:\n return false;\n }\n }\n })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));\n\n return this.negate ? !result : result;\n }\n}\n\nCondition.prototype.type = 'Condition';\nexport default Condition;\n","import Node from './node';\n\nclass UnicodeDescriptor extends Node {\n constructor(value) {\n super();\n\n this.value = value;\n }\n}\n\nUnicodeDescriptor.prototype.type = 'UnicodeDescriptor';\n\nexport default UnicodeDescriptor;\n","import Node from './node';\nimport Operation from './operation';\nimport Dimension from './dimension';\n\nclass Negative extends Node {\n constructor(node) {\n super();\n\n this.value = node;\n }\n\n genCSS(context, output) {\n output.add('-');\n this.value.genCSS(context, output);\n }\n\n eval(context) {\n if (context.isMathOn()) {\n return (new Operation('*', [new Dimension(-1), this.value])).eval(context);\n }\n return new Negative(this.value.eval(context));\n }\n}\n\nNegative.prototype.type = 'Negative';\nexport default Negative;\n","import Node from './node';\nimport Selector from './selector';\n\nclass Extend extends Node {\n constructor(selector, option, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.selector = selector;\n this.option = option;\n this.object_id = Extend.next_id++;\n this.parent_ids = [this.object_id];\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n\n switch (option) {\n case 'all':\n this.allowBefore = true;\n this.allowAfter = true;\n break;\n default:\n this.allowBefore = false;\n this.allowAfter = false;\n break;\n }\n this.setParent(this.selector, this);\n }\n\n accept(visitor) {\n this.selector = visitor.visit(this.selector);\n }\n\n eval(context) {\n return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n }\n\n clone(context) {\n return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n }\n\n // it concatenates (joins) all selectors in selector array\n findSelfSelectors(selectors) {\n let selfElements = [];\n let i;\n let selectorElements;\n\n for (i = 0; i < selectors.length; i++) {\n selectorElements = selectors[i].elements;\n // duplicate the logic in genCSS function inside the selector node.\n // future TODO - move both logics into the selector joiner visitor\n if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {\n selectorElements[0].combinator.value = ' ';\n }\n selfElements = selfElements.concat(selectors[i].elements);\n }\n\n this.selfSelectors = [new Selector(selfElements)];\n this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());\n }\n}\n\nExtend.next_id = 0;\n\nExtend.prototype.type = 'Extend';\nexport default Extend;\n","import Node from './node';\nimport Variable from './variable';\nimport Ruleset from './ruleset';\nimport DetachedRuleset from './detached-ruleset';\nimport LessError from '../less-error';\n\nclass VariableCall extends Node {\n constructor(variable, index, currentFileInfo) {\n super();\n\n this.variable = variable;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.allowRoot = true;\n }\n\n eval(context) {\n let rules;\n let detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context);\n const error = new LessError({message: `Could not evaluate variable call ${this.variable}`});\n\n if (!detachedRuleset.ruleset) {\n if (detachedRuleset.rules) {\n rules = detachedRuleset;\n }\n else if (Array.isArray(detachedRuleset)) {\n rules = new Ruleset('', detachedRuleset);\n }\n else if (Array.isArray(detachedRuleset.value)) {\n rules = new Ruleset('', detachedRuleset.value);\n }\n else {\n throw error;\n }\n detachedRuleset = new DetachedRuleset(rules);\n }\n\n if (detachedRuleset.ruleset) {\n return detachedRuleset.callEval(context);\n }\n throw error;\n }\n}\n\nVariableCall.prototype.type = 'VariableCall';\nexport default VariableCall;\n","import Node from './node';\nimport Variable from './variable';\nimport Ruleset from './ruleset';\nimport Selector from './selector';\n\nclass NamespaceValue extends Node {\n constructor(ruleCall, lookups, important, index, fileInfo) {\n super();\n\n this.value = ruleCall;\n this.lookups = lookups;\n this.important = important;\n this._index = index;\n this._fileInfo = fileInfo;\n }\n\n eval(context) {\n let i;\n let j;\n let name;\n let rules = this.value.eval(context);\n\n for (i = 0; i < this.lookups.length; i++) {\n name = this.lookups[i];\n\n /**\n * Eval'd DRs return rulesets.\n * Eval'd mixins return rules, so let's make a ruleset if we need it.\n * We need to do this because of late parsing of values\n */\n if (Array.isArray(rules)) {\n rules = new Ruleset([new Selector()], rules);\n }\n\n if (name === '') {\n rules = rules.lastDeclaration();\n }\n else if (name.charAt(0) === '@') {\n if (name.charAt(1) === '@') {\n name = `@${new Variable(name.substr(1)).eval(context).value}`;\n }\n if (rules.variables) {\n rules = rules.variable(name);\n }\n \n if (!rules) {\n throw { type: 'Name',\n message: `variable ${name} not found`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n }\n else {\n if (name.substring(0, 2) === '$@') {\n name = `$${new Variable(name.substr(1)).eval(context).value}`;\n }\n else {\n name = name.charAt(0) === '$' ? name : `$${name}`;\n }\n if (rules.properties) {\n rules = rules.property(name);\n }\n \n if (!rules) {\n throw { type: 'Name',\n message: `property \"${name.substr(1)}\" not found`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n // Properties are an array of values, since a ruleset can have multiple props.\n // We pick the last one (the \"cascaded\" value)\n rules = rules[rules.length - 1];\n }\n\n if (rules.value) {\n rules = rules.eval(context).value;\n }\n if (rules.ruleset) {\n rules = rules.ruleset.eval(context);\n }\n }\n return rules;\n }\n}\n\nNamespaceValue.prototype.type = 'NamespaceValue';\nexport default NamespaceValue;\n","import Selector from './selector';\nimport Element from './element';\nimport Ruleset from './ruleset';\nimport Declaration from './declaration';\nimport DetachedRuleset from './detached-ruleset';\nimport Expression from './expression';\nimport contexts from '../contexts';\nimport * as utils from '../utils';\n\nclass Definition extends Ruleset {\n constructor(name, params, rules, condition, variadic, frames, visibilityInfo) {\n super();\n\n this.name = name || 'anonymous mixin';\n this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];\n this.params = params;\n this.condition = condition;\n this.variadic = variadic;\n this.arity = params.length;\n this.rules = rules;\n this._lookups = {};\n const optionalParameters = [];\n this.required = params.reduce((count, p) => {\n if (!p.name || (p.name && !p.value)) {\n return count + 1;\n }\n else {\n optionalParameters.push(p.name);\n return count;\n }\n }, 0);\n this.optionalParameters = optionalParameters;\n this.frames = frames;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n }\n\n accept(visitor) {\n if (this.params && this.params.length) {\n this.params = visitor.visitArray(this.params);\n }\n this.rules = visitor.visitArray(this.rules);\n if (this.condition) {\n this.condition = visitor.visit(this.condition);\n }\n }\n\n evalParams(context, mixinEnv, args, evaldArguments) {\n /* jshint boss:true */\n const frame = new Ruleset(null, null);\n\n let varargs;\n let arg;\n const params = utils.copyArray(this.params);\n let i;\n let j;\n let val;\n let name;\n let isNamedFound;\n let argIndex;\n let argsLength = 0;\n\n if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {\n frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();\n }\n mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));\n\n if (args) {\n args = utils.copyArray(args);\n argsLength = args.length;\n\n for (i = 0; i < argsLength; i++) {\n arg = args[i];\n if (name = (arg && arg.name)) {\n isNamedFound = false;\n for (j = 0; j < params.length; j++) {\n if (!evaldArguments[j] && name === params[j].name) {\n evaldArguments[j] = arg.value.eval(context);\n frame.prependRule(new Declaration(name, arg.value.eval(context)));\n isNamedFound = true;\n break;\n }\n }\n if (isNamedFound) {\n args.splice(i, 1);\n i--;\n continue;\n } else {\n throw { type: 'Runtime', message: `Named argument for ${this.name} ${args[i].name} not found` };\n }\n }\n }\n }\n argIndex = 0;\n for (i = 0; i < params.length; i++) {\n if (evaldArguments[i]) { continue; }\n\n arg = args && args[argIndex];\n\n if (name = params[i].name) {\n if (params[i].variadic) {\n varargs = [];\n for (j = argIndex; j < argsLength; j++) {\n varargs.push(args[j].value.eval(context));\n }\n frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));\n } else {\n val = arg && arg.value;\n if (val) {\n // This was a mixin call, pass in a detached ruleset of it's eval'd rules\n if (Array.isArray(val)) {\n val = new DetachedRuleset(new Ruleset('', val));\n }\n else {\n val = val.eval(context);\n }\n } else if (params[i].value) {\n val = params[i].value.eval(mixinEnv);\n frame.resetCache();\n } else {\n throw { type: 'Runtime', message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` };\n }\n\n frame.prependRule(new Declaration(name, val));\n evaldArguments[i] = val;\n }\n }\n\n if (params[i].variadic && args) {\n for (j = argIndex; j < argsLength; j++) {\n evaldArguments[j] = args[j].value.eval(context);\n }\n }\n argIndex++;\n }\n\n return frame;\n }\n\n makeImportant() {\n const rules = !this.rules ? this.rules : this.rules.map(r => {\n if (r.makeImportant) {\n return r.makeImportant(true);\n } else {\n return r;\n }\n });\n const result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);\n return result;\n }\n\n eval(context) {\n return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || utils.copyArray(context.frames));\n }\n\n evalCall(context, args, important) {\n const _arguments = [];\n const mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;\n const frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);\n let rules;\n let ruleset;\n\n frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));\n\n rules = utils.copyArray(this.rules);\n\n ruleset = new Ruleset(null, rules);\n ruleset.originalRuleset = this;\n ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));\n if (important) {\n ruleset = ruleset.makeImportant();\n }\n return ruleset;\n }\n\n matchCondition(args, context) {\n if (this.condition && !this.condition.eval(\n new contexts.Eval(context,\n [this.evalParams(context, /* the parameter variables */\n new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]\n .concat(this.frames || []) // the parent namespace/mixin frames\n .concat(context.frames)))) { // the current environment frames\n return false;\n }\n return true;\n }\n\n matchArgs(args, context) {\n const allArgsCnt = (args && args.length) || 0;\n let len;\n const optionalParameters = this.optionalParameters;\n const requiredArgsCnt = !args ? 0 : args.reduce((count, p) => {\n if (optionalParameters.indexOf(p.name) < 0) {\n return count + 1;\n } else {\n return count;\n }\n }, 0);\n\n if (!this.variadic) {\n if (requiredArgsCnt < this.required) {\n return false;\n }\n if (allArgsCnt > this.params.length) {\n return false;\n }\n } else {\n if (requiredArgsCnt < (this.required - 1)) {\n return false;\n }\n }\n\n // check patterns\n len = Math.min(requiredArgsCnt, this.arity);\n\n for (let i = 0; i < len; i++) {\n if (!this.params[i].name && !this.params[i].variadic) {\n if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) {\n return false;\n }\n }\n }\n return true;\n }\n}\n\nDefinition.prototype.type = 'MixinDefinition';\nDefinition.prototype.evalFirst = true;\nexport default Definition;\n","import Node from './node';\nimport Selector from './selector';\nimport MixinDefinition from './mixin-definition';\nimport defaultFunc from '../functions/default';\n\nclass MixinCall extends Node {\n constructor(elements, args, index, currentFileInfo, important) {\n super();\n\n this.selector = new Selector(elements);\n this.arguments = args || [];\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.important = important;\n this.allowRoot = true;\n this.setParent(this.selector, this);\n }\n\n accept(visitor) {\n if (this.selector) {\n this.selector = visitor.visit(this.selector);\n }\n if (this.arguments.length) {\n this.arguments = visitor.visitArray(this.arguments);\n }\n }\n\n eval(context) {\n let mixins;\n let mixin;\n let mixinPath;\n const args = [];\n let arg;\n let argValue;\n const rules = [];\n let match = false;\n let i;\n let m;\n let f;\n let isRecursive;\n let isOneFound;\n const candidates = [];\n let candidate;\n const conditionResult = [];\n let defaultResult;\n const defFalseEitherCase = -1;\n const defNone = 0;\n const defTrue = 1;\n const defFalse = 2;\n let count;\n let originalRuleset;\n let noArgumentsFilter;\n\n this.selector = this.selector.eval(context);\n\n function calcDefGroup(mixin, mixinPath) {\n let f;\n let p;\n let namespace;\n\n for (f = 0; f < 2; f++) {\n conditionResult[f] = true;\n defaultFunc.value(f);\n for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {\n namespace = mixinPath[p];\n if (namespace.matchCondition) {\n conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);\n }\n }\n if (mixin.matchCondition) {\n conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);\n }\n }\n if (conditionResult[0] || conditionResult[1]) {\n if (conditionResult[0] != conditionResult[1]) {\n return conditionResult[1] ?\n defTrue : defFalse;\n }\n\n return defNone;\n }\n return defFalseEitherCase;\n }\n\n for (i = 0; i < this.arguments.length; i++) {\n arg = this.arguments[i];\n argValue = arg.value.eval(context);\n if (arg.expand && Array.isArray(argValue.value)) {\n argValue = argValue.value;\n for (m = 0; m < argValue.length; m++) {\n args.push({value: argValue[m]});\n }\n } else {\n args.push({name: arg.name, value: argValue});\n }\n }\n\n noArgumentsFilter = rule => rule.matchArgs(null, context);\n\n for (i = 0; i < context.frames.length; i++) {\n if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {\n isOneFound = true;\n\n // To make `default()` function independent of definition order we have two \"subpasses\" here.\n // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),\n // and build candidate list with corresponding flags. Then, when we know all possible matches,\n // we make a final decision.\n\n for (m = 0; m < mixins.length; m++) {\n mixin = mixins[m].rule;\n mixinPath = mixins[m].path;\n isRecursive = false;\n for (f = 0; f < context.frames.length; f++) {\n if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {\n isRecursive = true;\n break;\n }\n }\n if (isRecursive) {\n continue;\n }\n\n if (mixin.matchArgs(args, context)) {\n candidate = {mixin, group: calcDefGroup(mixin, mixinPath)};\n\n if (candidate.group !== defFalseEitherCase) {\n candidates.push(candidate);\n }\n\n match = true;\n }\n }\n\n defaultFunc.reset();\n\n count = [0, 0, 0];\n for (m = 0; m < candidates.length; m++) {\n count[candidates[m].group]++;\n }\n\n if (count[defNone] > 0) {\n defaultResult = defFalse;\n } else {\n defaultResult = defTrue;\n if ((count[defTrue] + count[defFalse]) > 1) {\n throw { type: 'Runtime',\n message: `Ambiguous use of \\`default()\\` found when matching for \\`${this.format(args)}\\``,\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n }\n\n for (m = 0; m < candidates.length; m++) {\n candidate = candidates[m].group;\n if ((candidate === defNone) || (candidate === defaultResult)) {\n try {\n mixin = candidates[m].mixin;\n if (!(mixin instanceof MixinDefinition)) {\n originalRuleset = mixin.originalRuleset || mixin;\n mixin = new MixinDefinition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());\n mixin.originalRuleset = originalRuleset;\n }\n const newRules = mixin.evalCall(context, args, this.important).rules;\n this._setVisibilityToReplacement(newRules);\n Array.prototype.push.apply(rules, newRules);\n } catch (e) {\n throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };\n }\n }\n }\n\n if (match) {\n return rules;\n }\n }\n }\n if (isOneFound) {\n throw { type: 'Runtime',\n message: `No matching definition was found for \\`${this.format(args)}\\``,\n index: this.getIndex(), filename: this.fileInfo().filename };\n } else {\n throw { type: 'Name',\n message: `${this.selector.toCSS().trim()} is undefined`,\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n }\n\n _setVisibilityToReplacement(replacement) {\n let i;\n let rule;\n if (this.blocksVisibility()) {\n for (i = 0; i < replacement.length; i++) {\n rule = replacement[i];\n rule.addVisibilityBlock();\n }\n }\n }\n\n format(args) {\n return `${this.selector.toCSS().trim()}(${args ? args.map(a => {\n let argValue = '';\n if (a.name) {\n argValue += `${a.name}:`;\n }\n if (a.value.toCSS) {\n argValue += a.value.toCSS();\n } else {\n argValue += '???';\n }\n return argValue;\n }).join(', ') : ''})`;\n }\n}\n\nMixinCall.prototype.type = 'MixinCall';\nexport default MixinCall;\n","const tree = Object.create(null);\n\nimport Node from './node';\nimport Color from './color';\nimport AtRule from './atrule';\nimport DetachedRuleset from './detached-ruleset';\nimport Operation from './operation';\nimport Dimension from './dimension';\nimport Unit from './unit';\nimport Keyword from './keyword';\nimport Variable from './variable';\nimport Property from './property';\nimport Ruleset from './ruleset';\nimport Element from './element';\nimport Attribute from './attribute';\nimport Combinator from './combinator';\nimport Selector from './selector';\nimport Quoted from './quoted';\nimport Expression from './expression';\nimport Declaration from './declaration';\nimport Call from './call';\nimport URL from './url';\nimport Import from './import';\nimport Comment from './comment';\nimport Anonymous from './anonymous';\nimport Value from './value';\nimport JavaScript from './javascript';\nimport Assignment from './assignment';\nimport Condition from './condition';\nimport Paren from './paren';\nimport Media from './media';\nimport UnicodeDescriptor from './unicode-descriptor';\nimport Negative from './negative';\nimport Extend from './extend';\nimport VariableCall from './variable-call';\nimport NamespaceValue from './namespace-value';\n\n// mixins\nimport MixinCall from './mixin-call';\nimport MixinDefinition from './mixin-definition';\n\nexport default {\n Node, Color, AtRule, DetachedRuleset, Operation,\n Dimension, Unit, Keyword, Variable, Property,\n Ruleset, Element, Attribute, Combinator, Selector,\n Quoted, Expression, Declaration, Call, URL, Import,\n Comment, Anonymous, Value, JavaScript, Assignment,\n Condition, Paren, Media, UnicodeDescriptor, Negative,\n Extend, VariableCall, NamespaceValue,\n mixin: {\n Call: MixinCall,\n Definition: MixinDefinition\n }\n};","export default {\n error: function(msg) {\n this._fireEvent('error', msg);\n },\n warn: function(msg) {\n this._fireEvent('warn', msg);\n },\n info: function(msg) {\n this._fireEvent('info', msg);\n },\n debug: function(msg) {\n this._fireEvent('debug', msg);\n },\n addListener: function(listener) {\n this._listeners.push(listener);\n },\n removeListener: function(listener) {\n for (let i = 0; i < this._listeners.length; i++) {\n if (this._listeners[i] === listener) {\n this._listeners.splice(i, 1);\n return;\n }\n }\n },\n _fireEvent: function(type, msg) {\n for (let i = 0; i < this._listeners.length; i++) {\n const logFunction = this._listeners[i][type];\n if (logFunction) {\n logFunction(msg);\n }\n }\n },\n _listeners: []\n};\n","/**\n * @todo Document why this abstraction exists, and the relationship between\n * environment, file managers, and plugin manager\n */\n\nimport logger from '../logger';\n\nclass environment {\n constructor(externalEnvironment, fileManagers) {\n this.fileManagers = fileManagers || [];\n externalEnvironment = externalEnvironment || {};\n\n const optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];\n const requiredFunctions = [];\n const functions = requiredFunctions.concat(optionalFunctions);\n\n for (let i = 0; i < functions.length; i++) {\n const propName = functions[i];\n const environmentFunc = externalEnvironment[propName];\n if (environmentFunc) {\n this[propName] = environmentFunc.bind(externalEnvironment);\n } else if (i < requiredFunctions.length) {\n this.warn(`missing required function in environment - ${propName}`);\n }\n }\n }\n\n getFileManager(filename, currentDirectory, options, environment, isSync) {\n\n if (!filename) {\n logger.warn('getFileManager called with no filename.. Please report this issue. continuing.');\n }\n if (currentDirectory == null) {\n logger.warn('getFileManager called with null directory.. Please report this issue. continuing.');\n }\n\n let fileManagers = this.fileManagers;\n if (options.pluginManager) {\n fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());\n }\n for (let i = fileManagers.length - 1; i >= 0 ; i--) {\n const fileManager = fileManagers[i];\n if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {\n return fileManager;\n }\n }\n return null;\n }\n\n addFileManager(fileManager) {\n this.fileManagers.push(fileManager);\n }\n\n clearFileManagers() {\n this.fileManagers = [];\n }\n}\n\nexport default environment;\n","class AbstractFileManager {\n getPath(filename) {\n let j = filename.lastIndexOf('?');\n if (j > 0) {\n filename = filename.slice(0, j);\n }\n j = filename.lastIndexOf('/');\n if (j < 0) {\n j = filename.lastIndexOf('\\\\');\n }\n if (j < 0) {\n return '';\n }\n return filename.slice(0, j + 1);\n }\n\n tryAppendExtension(path, ext) {\n return /(\\.[a-z]*$)|([\\?;].*)$/.test(path) ? path : path + ext;\n }\n\n tryAppendLessExtension(path) {\n return this.tryAppendExtension(path, '.less');\n };\n\n supportsSync() { return false; }\n\n alwaysMakePathsAbsolute() { return false; }\n\n isPathAbsolute(filename) {\n return (/^(?:[a-z-]+:|\\/|\\\\|#)/i).test(filename);\n }\n // TODO: pull out / replace?\n join(basePath, laterPath) {\n if (!basePath) {\n return laterPath;\n }\n return basePath + laterPath;\n };\n\n pathDiff(url, baseUrl) {\n // diff between two paths to create a relative path\n const urlParts = this.extractUrlParts(url);\n const baseUrlParts = this.extractUrlParts(baseUrl);\n\n let i;\n let max;\n let urlDirectories;\n let baseUrlDirectories;\n let diff = '';\n if (urlParts.hostPart !== baseUrlParts.hostPart) {\n return '';\n }\n max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);\n for (i = 0; i < max; i++) {\n if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }\n }\n baseUrlDirectories = baseUrlParts.directories.slice(i);\n urlDirectories = urlParts.directories.slice(i);\n for (i = 0; i < baseUrlDirectories.length - 1; i++) {\n diff += '../';\n }\n for (i = 0; i < urlDirectories.length - 1; i++) {\n diff += `${urlDirectories[i]}/`;\n }\n return diff;\n };\n // helper function, not part of API\n extractUrlParts(url, baseUrl) {\n // urlParts[1] = protocol://hostname/ OR /\n // urlParts[2] = / if path relative to host base\n // urlParts[3] = directories\n // urlParts[4] = filename\n // urlParts[5] = parameters\n\n const urlPartsRegex = /^((?:[a-z-]+:)?\\/{2}(?:[^\\/\\?#]*\\/)|([\\/\\\\]))?((?:[^\\/\\\\\\?#]*[\\/\\\\])*)([^\\/\\\\\\?#]*)([#\\?].*)?$/i;\n\n const urlParts = url.match(urlPartsRegex);\n const returner = {};\n let rawDirectories = [];\n const directories = [];\n let i;\n let baseUrlParts;\n\n if (!urlParts) {\n throw new Error(`Could not parse sheet href - '${url}'`);\n }\n\n // Stylesheets in IE don't always return the full path\n if (baseUrl && (!urlParts[1] || urlParts[2])) {\n baseUrlParts = baseUrl.match(urlPartsRegex);\n if (!baseUrlParts) {\n throw new Error(`Could not parse page url - '${baseUrl}'`);\n }\n urlParts[1] = urlParts[1] || baseUrlParts[1] || '';\n if (!urlParts[2]) {\n urlParts[3] = baseUrlParts[3] + urlParts[3];\n }\n }\n\n if (urlParts[3]) {\n rawDirectories = urlParts[3].replace(/\\\\/g, '/').split('/');\n\n // collapse '..' and skip '.'\n for (i = 0; i < rawDirectories.length; i++) {\n\n if (rawDirectories[i] === '..') {\n directories.pop();\n }\n else if (rawDirectories[i] !== '.') {\n directories.push(rawDirectories[i]);\n }\n \n }\n }\n\n returner.hostPart = urlParts[1];\n returner.directories = directories;\n returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');\n returner.path = (urlParts[1] || '') + directories.join('/');\n returner.filename = urlParts[4];\n returner.fileUrl = returner.path + (urlParts[4] || '');\n returner.url = returner.fileUrl + (urlParts[5] || '');\n return returner;\n };\n}\n\nexport default AbstractFileManager;\n","import functionRegistry from '../functions/function-registry';\nimport LessError from '../less-error';\n\nclass AbstractPluginLoader {\n constructor() {\n // Implemented by Node.js plugin loader\n this.require = () => null\n }\n\n evalPlugin(contents, context, imports, pluginOptions, fileInfo) {\n let loader;\n let registry;\n let pluginObj;\n let localModule;\n let pluginManager;\n let filename;\n let result;\n\n pluginManager = context.pluginManager;\n\n if (fileInfo) {\n if (typeof fileInfo === 'string') {\n filename = fileInfo;\n }\n else {\n filename = fileInfo.filename;\n }\n }\n const shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;\n\n if (filename) {\n pluginObj = pluginManager.get(filename);\n\n if (pluginObj) {\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n if (result) {\n return result;\n }\n try {\n if (pluginObj.use) {\n pluginObj.use.call(this.context, pluginObj);\n }\n }\n catch (e) {\n e.message = e.message || 'Error during @plugin call';\n return new LessError(e, imports, filename);\n }\n return pluginObj;\n }\n }\n localModule = {\n exports: {},\n pluginManager,\n fileInfo\n };\n registry = functionRegistry.create();\n\n const registerPlugin = obj => {\n pluginObj = obj;\n };\n\n try {\n loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);\n loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);\n }\n catch (e) {\n return new LessError(e, imports, filename);\n }\n\n if (!pluginObj) {\n pluginObj = localModule.exports;\n }\n pluginObj = this.validatePlugin(pluginObj, filename, shortname);\n\n if (pluginObj instanceof LessError) {\n return pluginObj;\n }\n\n if (pluginObj) {\n pluginObj.imports = imports;\n pluginObj.filename = filename;\n\n // For < 3.x (or unspecified minVersion) - setOptions() before install()\n if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n\n if (result) {\n return result;\n }\n }\n\n // Run on first load\n pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);\n pluginObj.functions = registry.getLocalFunctions();\n\n // Need to call setOptions again because the pluginObj might have functions\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n if (result) {\n return result;\n }\n\n // Run every @plugin call\n try {\n if (pluginObj.use) {\n pluginObj.use.call(this.context, pluginObj);\n }\n }\n catch (e) {\n e.message = e.message || 'Error during @plugin call';\n return new LessError(e, imports, filename);\n }\n\n }\n else {\n return new LessError({ message: 'Not a valid plugin' }, imports, filename);\n }\n\n return pluginObj;\n }\n\n trySetOptions(plugin, filename, name, options) {\n if (options && !plugin.setOptions) {\n return new LessError({\n message: `Options have been provided but the plugin ${name} does not support any options.`\n });\n }\n try {\n plugin.setOptions && plugin.setOptions(options);\n }\n catch (e) {\n return new LessError(e);\n }\n }\n\n validatePlugin(plugin, filename, name) {\n if (plugin) {\n // support plugins being a function\n // so that the plugin can be more usable programmatically\n if (typeof plugin === 'function') {\n plugin = new plugin();\n }\n\n if (plugin.minVersion) {\n if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {\n return new LessError({\n message: `Plugin ${name} requires version ${this.versionToString(plugin.minVersion)}`\n });\n }\n }\n return plugin;\n }\n return null;\n }\n\n compareVersion(aVersion, bVersion) {\n if (typeof aVersion === 'string') {\n aVersion = aVersion.match(/^(\\d+)\\.?(\\d+)?\\.?(\\d+)?/);\n aVersion.shift();\n }\n for (let i = 0; i < aVersion.length; i++) {\n if (aVersion[i] !== bVersion[i]) {\n return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1;\n }\n }\n return 0;\n }\n\n versionToString(version) {\n let versionString = '';\n for (let i = 0; i < version.length; i++) {\n versionString += (versionString ? '.' : '') + version[i];\n }\n return versionString;\n }\n\n printUsage(plugins) {\n for (let i = 0; i < plugins.length; i++) {\n const plugin = plugins[i];\n if (plugin.printUsage) {\n plugin.printUsage();\n }\n }\n }\n}\n\nexport default AbstractPluginLoader;\n\n","import tree from '../tree';\nconst _visitArgs = { visitDeeper: true };\nlet _hasIndexed = false;\n\nfunction _noop(node) {\n return node;\n}\n\nfunction indexNodeTypes(parent, ticker) {\n // add .typeIndex to tree node types for lookup table\n let key;\n\n let child;\n for (key in parent) { \n /* eslint guard-for-in: 0 */\n child = parent[key];\n switch (typeof child) {\n case 'function':\n // ignore bound functions directly on tree which do not have a prototype\n // or aren't nodes\n if (child.prototype && child.prototype.type) {\n child.prototype.typeIndex = ticker++;\n }\n break;\n case 'object':\n ticker = indexNodeTypes(child, ticker);\n break;\n \n }\n }\n return ticker;\n}\n\nclass Visitor {\n constructor(implementation) {\n this._implementation = implementation;\n this._visitInCache = {};\n this._visitOutCache = {};\n\n if (!_hasIndexed) {\n indexNodeTypes(tree, 1);\n _hasIndexed = true;\n }\n }\n\n visit(node) {\n if (!node) {\n return node;\n }\n\n const nodeTypeIndex = node.typeIndex;\n if (!nodeTypeIndex) {\n // MixinCall args aren't a node type?\n if (node.value && node.value.typeIndex) {\n this.visit(node.value);\n }\n return node;\n }\n\n const impl = this._implementation;\n let func = this._visitInCache[nodeTypeIndex];\n let funcOut = this._visitOutCache[nodeTypeIndex];\n const visitArgs = _visitArgs;\n let fnName;\n\n visitArgs.visitDeeper = true;\n\n if (!func) {\n fnName = `visit${node.type}`;\n func = impl[fnName] || _noop;\n funcOut = impl[`${fnName}Out`] || _noop;\n this._visitInCache[nodeTypeIndex] = func;\n this._visitOutCache[nodeTypeIndex] = funcOut;\n }\n\n if (func !== _noop) {\n const newNode = func.call(impl, node, visitArgs);\n if (node && impl.isReplacing) {\n node = newNode;\n }\n }\n\n if (visitArgs.visitDeeper && node && node.accept) {\n node.accept(this);\n }\n\n if (funcOut != _noop) {\n funcOut.call(impl, node);\n }\n\n return node;\n }\n\n visitArray(nodes, nonReplacing) {\n if (!nodes) {\n return nodes;\n }\n\n const cnt = nodes.length;\n let i;\n\n // Non-replacing\n if (nonReplacing || !this._implementation.isReplacing) {\n for (i = 0; i < cnt; i++) {\n this.visit(nodes[i]);\n }\n return nodes;\n }\n\n // Replacing\n const out = [];\n for (i = 0; i < cnt; i++) {\n const evald = this.visit(nodes[i]);\n if (evald === undefined) { continue; }\n if (!evald.splice) {\n out.push(evald);\n } else if (evald.length) {\n this.flatten(evald, out);\n }\n }\n return out;\n }\n\n flatten(arr, out) {\n if (!out) {\n out = [];\n }\n\n let cnt;\n let i;\n let item;\n let nestedCnt;\n let j;\n let nestedItem;\n\n for (i = 0, cnt = arr.length; i < cnt; i++) {\n item = arr[i];\n if (item === undefined) {\n continue;\n }\n if (!item.splice) {\n out.push(item);\n continue;\n }\n\n for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {\n nestedItem = item[j];\n if (nestedItem === undefined) {\n continue;\n }\n if (!nestedItem.splice) {\n out.push(nestedItem);\n } else if (nestedItem.length) {\n this.flatten(nestedItem, out);\n }\n }\n }\n\n return out;\n }\n}\n\nexport default Visitor;\n","class ImportSequencer {\n constructor(onSequencerEmpty) {\n this.imports = [];\n this.variableImports = [];\n this._onSequencerEmpty = onSequencerEmpty;\n this._currentDepth = 0;\n }\n\n addImport(callback) {\n const importSequencer = this;\n\n const importItem = {\n callback,\n args: null,\n isReady: false\n };\n\n this.imports.push(importItem);\n return function(...args) {\n importItem.args = Array.prototype.slice.call(args, 0);\n importItem.isReady = true;\n importSequencer.tryRun();\n };\n }\n\n addVariableImport(callback) {\n this.variableImports.push(callback);\n }\n\n tryRun() {\n this._currentDepth++;\n try {\n while (true) {\n while (this.imports.length > 0) {\n const importItem = this.imports[0];\n if (!importItem.isReady) {\n return;\n }\n this.imports = this.imports.slice(1);\n importItem.callback.apply(null, importItem.args);\n }\n if (this.variableImports.length === 0) {\n break;\n }\n const variableImport = this.variableImports[0];\n this.variableImports = this.variableImports.slice(1);\n variableImport();\n }\n } finally {\n this._currentDepth--;\n }\n if (this._currentDepth === 0 && this._onSequencerEmpty) {\n this._onSequencerEmpty();\n }\n }\n}\n\nexport default ImportSequencer;\n","import contexts from '../contexts';\nimport Visitor from './visitor';\nimport ImportSequencer from './import-sequencer';\nimport * as utils from '../utils';\n\nconst ImportVisitor = function(importer, finish) {\n\n this._visitor = new Visitor(this);\n this._importer = importer;\n this._finish = finish;\n this.context = new contexts.Eval();\n this.importCount = 0;\n this.onceFileDetectionMap = {};\n this.recursionDetector = {};\n this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));\n};\n\nImportVisitor.prototype = {\n isReplacing: false,\n run: function (root) {\n try {\n // process the contents\n this._visitor.visit(root);\n }\n catch (e) {\n this.error = e;\n }\n\n this.isFinished = true;\n this._sequencer.tryRun();\n },\n _onSequencerEmpty: function() {\n if (!this.isFinished) {\n return;\n }\n this._finish(this.error);\n },\n visitImport: function (importNode, visitArgs) {\n const inlineCSS = importNode.options.inline;\n\n if (!importNode.css || inlineCSS) {\n\n const context = new contexts.Eval(this.context, utils.copyArray(this.context.frames));\n const importParent = context.frames[0];\n\n this.importCount++;\n if (importNode.isVariableImport()) {\n this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));\n } else {\n this.processImportNode(importNode, context, importParent);\n }\n }\n visitArgs.visitDeeper = false;\n },\n processImportNode: function(importNode, context, importParent) {\n let evaldImportNode;\n const inlineCSS = importNode.options.inline;\n\n try {\n evaldImportNode = importNode.evalForImport(context);\n } catch (e) {\n if (!e.filename) { e.index = importNode.getIndex(); e.filename = importNode.fileInfo().filename; }\n // attempt to eval properly and treat as css\n importNode.css = true;\n // if that fails, this error will be thrown\n importNode.error = e;\n }\n\n if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {\n if (evaldImportNode.options.multiple) {\n context.importMultiple = true;\n }\n\n // try appending if we haven't determined if it is css or not\n const tryAppendLessExtension = evaldImportNode.css === undefined;\n\n for (let i = 0; i < importParent.rules.length; i++) {\n if (importParent.rules[i] === importNode) {\n importParent.rules[i] = evaldImportNode;\n break;\n }\n }\n\n const onImported = this.onImported.bind(this, evaldImportNode, context);\n const sequencedOnImported = this._sequencer.addImport(onImported);\n\n this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(),\n evaldImportNode.options, sequencedOnImported);\n } else {\n this.importCount--;\n if (this.isFinished) {\n this._sequencer.tryRun();\n }\n }\n },\n onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {\n if (e) {\n if (!e.filename) {\n e.index = importNode.getIndex(); e.filename = importNode.fileInfo().filename;\n }\n this.error = e;\n }\n\n const importVisitor = this;\n const inlineCSS = importNode.options.inline;\n const isPlugin = importNode.options.isPlugin;\n const isOptional = importNode.options.optional;\n const duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;\n\n if (!context.importMultiple) {\n if (duplicateImport) {\n importNode.skip = true;\n } else {\n importNode.skip = () => {\n if (fullPath in importVisitor.onceFileDetectionMap) {\n return true;\n }\n importVisitor.onceFileDetectionMap[fullPath] = true;\n return false;\n };\n }\n }\n\n if (!fullPath && isOptional) {\n importNode.skip = true;\n }\n\n if (root) {\n importNode.root = root;\n importNode.importedFilename = fullPath;\n\n if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {\n importVisitor.recursionDetector[fullPath] = true;\n\n const oldContext = this.context;\n this.context = context;\n try {\n this._visitor.visit(root);\n } catch (e) {\n this.error = e;\n }\n this.context = oldContext;\n }\n }\n\n importVisitor.importCount--;\n\n if (importVisitor.isFinished) {\n importVisitor._sequencer.tryRun();\n }\n },\n visitDeclaration: function (declNode, visitArgs) {\n if (declNode.value.type === 'DetachedRuleset') {\n this.context.frames.unshift(declNode);\n } else {\n visitArgs.visitDeeper = false;\n }\n },\n visitDeclarationOut: function(declNode) {\n if (declNode.value.type === 'DetachedRuleset') {\n this.context.frames.shift();\n }\n },\n visitAtRule: function (atRuleNode, visitArgs) {\n this.context.frames.unshift(atRuleNode);\n },\n visitAtRuleOut: function (atRuleNode) {\n this.context.frames.shift();\n },\n visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n this.context.frames.unshift(mixinDefinitionNode);\n },\n visitMixinDefinitionOut: function (mixinDefinitionNode) {\n this.context.frames.shift();\n },\n visitRuleset: function (rulesetNode, visitArgs) {\n this.context.frames.unshift(rulesetNode);\n },\n visitRulesetOut: function (rulesetNode) {\n this.context.frames.shift();\n },\n visitMedia: function (mediaNode, visitArgs) {\n this.context.frames.unshift(mediaNode.rules[0]);\n },\n visitMediaOut: function (mediaNode) {\n this.context.frames.shift();\n }\n};\nexport default ImportVisitor;\n","class SetTreeVisibilityVisitor {\n constructor(visible) {\n this.visible = visible;\n }\n\n run(root) {\n this.visit(root);\n }\n\n visitArray(nodes) {\n if (!nodes) {\n return nodes;\n }\n\n const cnt = nodes.length;\n let i;\n for (i = 0; i < cnt; i++) {\n this.visit(nodes[i]);\n }\n return nodes;\n }\n\n visit(node) {\n if (!node) {\n return node;\n }\n if (node.constructor === Array) {\n return this.visitArray(node);\n }\n\n if (!node.blocksVisibility || node.blocksVisibility()) {\n return node;\n }\n if (this.visible) {\n node.ensureVisibility();\n } else {\n node.ensureInvisibility();\n }\n\n node.accept(this);\n return node;\n }\n}\n\nexport default SetTreeVisibilityVisitor;","import tree from '../tree';\nimport Visitor from './visitor';\nimport logger from '../logger';\nimport * as utils from '../utils';\n\n/* jshint loopfunc:true */\n\nclass ExtendFinderVisitor {\n constructor() {\n this._visitor = new Visitor(this);\n this.contexts = [];\n this.allExtendsStack = [[]];\n }\n\n run(root) {\n root = this._visitor.visit(root);\n root.allExtends = this.allExtendsStack[0];\n return root;\n }\n\n visitDeclaration(declNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n if (rulesetNode.root) {\n return;\n }\n\n let i;\n let j;\n let extend;\n const allSelectorsExtendList = [];\n let extendList;\n\n // get &:extend(.a); rules which apply to all selectors in this ruleset\n const rules = rulesetNode.rules;\n\n const ruleCnt = rules ? rules.length : 0;\n for (i = 0; i < ruleCnt; i++) {\n if (rulesetNode.rules[i] instanceof tree.Extend) {\n allSelectorsExtendList.push(rules[i]);\n rulesetNode.extendOnEveryPath = true;\n }\n }\n\n // now find every selector and apply the extends that apply to all extends\n // and the ones which apply to an individual extend\n const paths = rulesetNode.paths;\n for (i = 0; i < paths.length; i++) {\n const selectorPath = paths[i];\n const selector = selectorPath[selectorPath.length - 1];\n const selExtendList = selector.extendList;\n\n extendList = selExtendList ? utils.copyArray(selExtendList).concat(allSelectorsExtendList)\n : allSelectorsExtendList;\n\n if (extendList) {\n extendList = extendList.map(allSelectorsExtend => allSelectorsExtend.clone());\n }\n\n for (j = 0; j < extendList.length; j++) {\n this.foundExtends = true;\n extend = extendList[j];\n extend.findSelfSelectors(selectorPath);\n extend.ruleset = rulesetNode;\n if (j === 0) { extend.firstExtendOnThisSelectorPath = true; }\n this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);\n }\n }\n\n this.contexts.push(rulesetNode.selectors);\n }\n\n visitRulesetOut(rulesetNode) {\n if (!rulesetNode.root) {\n this.contexts.length = this.contexts.length - 1;\n }\n }\n\n visitMedia(mediaNode, visitArgs) {\n mediaNode.allExtends = [];\n this.allExtendsStack.push(mediaNode.allExtends);\n }\n\n visitMediaOut(mediaNode) {\n this.allExtendsStack.length = this.allExtendsStack.length - 1;\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n atRuleNode.allExtends = [];\n this.allExtendsStack.push(atRuleNode.allExtends);\n }\n\n visitAtRuleOut(atRuleNode) {\n this.allExtendsStack.length = this.allExtendsStack.length - 1;\n }\n}\n\nclass ProcessExtendsVisitor {\n constructor() {\n this._visitor = new Visitor(this);\n }\n\n run(root) {\n const extendFinder = new ExtendFinderVisitor();\n this.extendIndices = {};\n extendFinder.run(root);\n if (!extendFinder.foundExtends) { return root; }\n root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));\n this.allExtendsStack = [root.allExtends];\n const newRoot = this._visitor.visit(root);\n this.checkExtendsForNonMatched(root.allExtends);\n return newRoot;\n }\n\n checkExtendsForNonMatched(extendList) {\n const indices = this.extendIndices;\n extendList.filter(extend => !extend.hasFoundMatches && extend.parent_ids.length == 1).forEach(extend => {\n let selector = '_unknown_';\n try {\n selector = extend.selector.toCSS({});\n }\n catch (_) {}\n\n if (!indices[`${extend.index} ${selector}`]) {\n indices[`${extend.index} ${selector}`] = true;\n logger.warn(`extend '${selector}' has no matches`);\n }\n });\n }\n\n doExtendChaining(extendsList, extendsListTarget, iterationCount) {\n //\n // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering\n // and pasting the selector we would do normally, but we are also adding an extend with the same target selector\n // this means this new extend can then go and alter other extends\n //\n // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors\n // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already\n // processed if we look at each selector at a time, as is done in visitRuleset\n\n let extendIndex;\n\n let targetExtendIndex;\n let matches;\n const extendsToAdd = [];\n let newSelector;\n const extendVisitor = this;\n let selectorPath;\n let extend;\n let targetExtend;\n let newExtend;\n\n iterationCount = iterationCount || 0;\n\n // loop through comparing every extend with every target extend.\n // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place\n // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one\n // and the second is the target.\n // the separation into two lists allows us to process a subset of chains with a bigger set, as is the\n // case when processing media queries\n for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {\n for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {\n\n extend = extendsList[extendIndex];\n targetExtend = extendsListTarget[targetExtendIndex];\n\n // look for circular references\n if ( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ) { continue; }\n\n // find a match in the target extends self selector (the bit before :extend)\n selectorPath = [targetExtend.selfSelectors[0]];\n matches = extendVisitor.findMatch(extend, selectorPath);\n\n if (matches.length) {\n extend.hasFoundMatches = true;\n\n // we found a match, so for each self selector..\n extend.selfSelectors.forEach(selfSelector => {\n const info = targetExtend.visibilityInfo();\n\n // process the extend as usual\n newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());\n\n // but now we create a new extend from it\n newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info);\n newExtend.selfSelectors = newSelector;\n\n // add the extend onto the list of extends for that selector\n newSelector[newSelector.length - 1].extendList = [newExtend];\n\n // record that we need to add it.\n extendsToAdd.push(newExtend);\n newExtend.ruleset = targetExtend.ruleset;\n\n // remember its parents for circular references\n newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);\n\n // only process the selector once.. if we have :extend(.a,.b) then multiple\n // extends will look at the same selector path, so when extending\n // we know that any others will be duplicates in terms of what is added to the css\n if (targetExtend.firstExtendOnThisSelectorPath) {\n newExtend.firstExtendOnThisSelectorPath = true;\n targetExtend.ruleset.paths.push(newSelector);\n }\n });\n }\n }\n }\n\n if (extendsToAdd.length) {\n // try to detect circular references to stop a stack overflow.\n // may no longer be needed.\n this.extendChainCount++;\n if (iterationCount > 100) {\n let selectorOne = '{unable to calculate}';\n let selectorTwo = '{unable to calculate}';\n try {\n selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();\n selectorTwo = extendsToAdd[0].selector.toCSS();\n }\n catch (e) {}\n throw { message: `extend circular reference detected. One of the circular extends is currently:${selectorOne}:extend(${selectorTwo})`};\n }\n\n // now process the new extends on the existing rules so that we can handle a extending b extending c extending\n // d extending e...\n return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));\n } else {\n return extendsToAdd;\n }\n }\n\n visitDeclaration(ruleNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitSelector(selectorNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n if (rulesetNode.root) {\n return;\n }\n let matches;\n let pathIndex;\n let extendIndex;\n const allExtends = this.allExtendsStack[this.allExtendsStack.length - 1];\n const selectorsToAdd = [];\n const extendVisitor = this;\n let selectorPath;\n\n // look at each selector path in the ruleset, find any extend matches and then copy, find and replace\n\n for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {\n for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {\n selectorPath = rulesetNode.paths[pathIndex];\n\n // extending extends happens initially, before the main pass\n if (rulesetNode.extendOnEveryPath) { continue; }\n const extendList = selectorPath[selectorPath.length - 1].extendList;\n if (extendList && extendList.length) { continue; }\n\n matches = this.findMatch(allExtends[extendIndex], selectorPath);\n\n if (matches.length) {\n allExtends[extendIndex].hasFoundMatches = true;\n\n allExtends[extendIndex].selfSelectors.forEach(selfSelector => {\n let extendedSelectors;\n extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());\n selectorsToAdd.push(extendedSelectors);\n });\n }\n }\n }\n rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);\n }\n\n findMatch(extend, haystackSelectorPath) {\n //\n // look through the haystack selector path to try and find the needle - extend.selector\n // returns an array of selector matches that can then be replaced\n //\n let haystackSelectorIndex;\n\n let hackstackSelector;\n let hackstackElementIndex;\n let haystackElement;\n let targetCombinator;\n let i;\n const extendVisitor = this;\n const needleElements = extend.selector.elements;\n const potentialMatches = [];\n let potentialMatch;\n const matches = [];\n\n // loop through the haystack elements\n for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {\n hackstackSelector = haystackSelectorPath[haystackSelectorIndex];\n\n for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {\n\n haystackElement = hackstackSelector.elements[hackstackElementIndex];\n\n // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.\n if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {\n potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,\n initialCombinator: haystackElement.combinator});\n }\n\n for (i = 0; i < potentialMatches.length; i++) {\n potentialMatch = potentialMatches[i];\n\n // selectors add \" \" onto the first element. When we use & it joins the selectors together, but if we don't\n // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to\n // work out what the resulting combinator will be\n targetCombinator = haystackElement.combinator.value;\n if (targetCombinator === '' && hackstackElementIndex === 0) {\n targetCombinator = ' ';\n }\n\n // if we don't match, null our match to indicate failure\n if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||\n (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {\n potentialMatch = null;\n } else {\n potentialMatch.matched++;\n }\n\n // if we are still valid and have finished, test whether we have elements after and whether these are allowed\n if (potentialMatch) {\n potentialMatch.finished = potentialMatch.matched === needleElements.length;\n if (potentialMatch.finished &&\n (!extend.allowAfter &&\n (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {\n potentialMatch = null;\n }\n }\n // if null we remove, if not, we are still valid, so either push as a valid match or continue\n if (potentialMatch) {\n if (potentialMatch.finished) {\n potentialMatch.length = needleElements.length;\n potentialMatch.endPathIndex = haystackSelectorIndex;\n potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match\n potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again\n matches.push(potentialMatch);\n }\n } else {\n potentialMatches.splice(i, 1);\n i--;\n }\n }\n }\n }\n return matches;\n }\n\n isElementValuesEqual(elementValue1, elementValue2) {\n if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {\n return elementValue1 === elementValue2;\n }\n if (elementValue1 instanceof tree.Attribute) {\n if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {\n return false;\n }\n if (!elementValue1.value || !elementValue2.value) {\n if (elementValue1.value || elementValue2.value) {\n return false;\n }\n return true;\n }\n elementValue1 = elementValue1.value.value || elementValue1.value;\n elementValue2 = elementValue2.value.value || elementValue2.value;\n return elementValue1 === elementValue2;\n }\n elementValue1 = elementValue1.value;\n elementValue2 = elementValue2.value;\n if (elementValue1 instanceof tree.Selector) {\n if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {\n return false;\n }\n for (let i = 0; i < elementValue1.elements.length; i++) {\n if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) {\n if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) {\n return false;\n }\n }\n if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) {\n return false;\n }\n }\n return true;\n }\n return false;\n }\n\n extendSelector(matches, selectorPath, replacementSelector, isVisible) {\n // for a set of matches, replace each match with the replacement selector\n\n let currentSelectorPathIndex = 0;\n\n let currentSelectorPathElementIndex = 0;\n let path = [];\n let matchIndex;\n let selector;\n let firstElement;\n let match;\n let newElements;\n\n for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {\n match = matches[matchIndex];\n selector = selectorPath[match.pathIndex];\n firstElement = new tree.Element(\n match.initialCombinator,\n replacementSelector.elements[0].value,\n replacementSelector.elements[0].isVariable,\n replacementSelector.elements[0].getIndex(),\n replacementSelector.elements[0].fileInfo()\n );\n\n if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {\n path[path.length - 1].elements = path[path.length - 1]\n .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n currentSelectorPathElementIndex = 0;\n currentSelectorPathIndex++;\n }\n\n newElements = selector.elements\n .slice(currentSelectorPathElementIndex, match.index)\n .concat([firstElement])\n .concat(replacementSelector.elements.slice(1));\n\n if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {\n path[path.length - 1].elements =\n path[path.length - 1].elements.concat(newElements);\n } else {\n path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));\n\n path.push(new tree.Selector(\n newElements\n ));\n }\n currentSelectorPathIndex = match.endPathIndex;\n currentSelectorPathElementIndex = match.endPathElementIndex;\n if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {\n currentSelectorPathElementIndex = 0;\n currentSelectorPathIndex++;\n }\n }\n\n if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {\n path[path.length - 1].elements = path[path.length - 1]\n .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n currentSelectorPathIndex++;\n }\n\n path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));\n path = path.map(currentValue => {\n // we can re-use elements here, because the visibility property matters only for selectors\n const derived = currentValue.createDerived(currentValue.elements);\n if (isVisible) {\n derived.ensureVisibility();\n } else {\n derived.ensureInvisibility();\n }\n return derived;\n });\n return path;\n }\n\n visitMedia(mediaNode, visitArgs) {\n let newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));\n this.allExtendsStack.push(newAllExtends);\n }\n\n visitMediaOut(mediaNode) {\n const lastIndex = this.allExtendsStack.length - 1;\n this.allExtendsStack.length = lastIndex;\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n let newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends));\n this.allExtendsStack.push(newAllExtends);\n }\n\n visitAtRuleOut(atRuleNode) {\n const lastIndex = this.allExtendsStack.length - 1;\n this.allExtendsStack.length = lastIndex;\n }\n}\n\nexport default ProcessExtendsVisitor;\n","import Visitor from './visitor';\n\nclass JoinSelectorVisitor {\n constructor() {\n this.contexts = [[]];\n this._visitor = new Visitor(this);\n }\n\n run(root) {\n return this._visitor.visit(root);\n }\n\n visitDeclaration(declNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n const paths = [];\n let selectors;\n\n this.contexts.push(paths);\n\n if (!rulesetNode.root) {\n selectors = rulesetNode.selectors;\n if (selectors) {\n selectors = selectors.filter(selector => selector.getIsOutput());\n rulesetNode.selectors = selectors.length ? selectors : (selectors = null);\n if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); }\n }\n if (!selectors) { rulesetNode.rules = null; }\n rulesetNode.paths = paths;\n }\n }\n\n visitRulesetOut(rulesetNode) {\n this.contexts.length = this.contexts.length - 1;\n }\n\n visitMedia(mediaNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n if (atRuleNode.rules && atRuleNode.rules.length) {\n atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null);\n }\n }\n}\n\nexport default JoinSelectorVisitor;\n","import tree from '../tree';\nimport Visitor from './visitor';\n\nclass CSSVisitorUtils {\n constructor(context) {\n this._visitor = new Visitor(this);\n this._context = context;\n }\n\n containsSilentNonBlockedChild(bodyRules) {\n let rule;\n if (!bodyRules) {\n return false;\n }\n for (let r = 0; r < bodyRules.length; r++) {\n rule = bodyRules[r];\n if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {\n // the atrule contains something that was referenced (likely by extend)\n // therefore it needs to be shown in output too\n return true;\n }\n }\n return false;\n }\n\n keepOnlyVisibleChilds(owner) {\n if (owner && owner.rules) {\n owner.rules = owner.rules.filter(thing => thing.isVisible());\n }\n }\n\n isEmpty(owner) {\n return (owner && owner.rules) \n ? (owner.rules.length === 0) : true;\n }\n\n hasVisibleSelector(rulesetNode) {\n return (rulesetNode && rulesetNode.paths)\n ? (rulesetNode.paths.length > 0) : false;\n }\n\n resolveVisibility(node, originalRules) {\n if (!node.blocksVisibility()) {\n if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {\n return ;\n }\n\n return node;\n }\n\n const compiledRulesBody = node.rules[0];\n this.keepOnlyVisibleChilds(compiledRulesBody);\n\n if (this.isEmpty(compiledRulesBody)) {\n return ;\n }\n\n node.ensureVisibility();\n node.removeVisibilityBlock();\n\n return node;\n }\n\n isVisibleRuleset(rulesetNode) {\n if (rulesetNode.firstRoot) {\n return true;\n }\n\n if (this.isEmpty(rulesetNode)) {\n return false;\n }\n\n if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {\n return false;\n }\n\n return true;\n }\n}\n\nconst ToCSSVisitor = function(context) {\n this._visitor = new Visitor(this);\n this._context = context;\n this.utils = new CSSVisitorUtils(context);\n};\n\nToCSSVisitor.prototype = {\n isReplacing: true,\n run: function (root) {\n return this._visitor.visit(root);\n },\n\n visitDeclaration: function (declNode, visitArgs) {\n if (declNode.blocksVisibility() || declNode.variable) {\n return;\n }\n return declNode;\n },\n\n visitMixinDefinition: function (mixinNode, visitArgs) {\n // mixin definitions do not get eval'd - this means they keep state\n // so we have to clear that state here so it isn't used if toCSS is called twice\n mixinNode.frames = [];\n },\n\n visitExtend: function (extendNode, visitArgs) {\n },\n\n visitComment: function (commentNode, visitArgs) {\n if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {\n return;\n }\n return commentNode;\n },\n\n visitMedia: function(mediaNode, visitArgs) {\n const originalRules = mediaNode.rules[0].rules;\n mediaNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n\n return this.utils.resolveVisibility(mediaNode, originalRules);\n },\n\n visitImport: function (importNode, visitArgs) {\n if (importNode.blocksVisibility()) {\n return ;\n }\n return importNode;\n },\n\n visitAtRule: function(atRuleNode, visitArgs) {\n if (atRuleNode.rules && atRuleNode.rules.length) {\n return this.visitAtRuleWithBody(atRuleNode, visitArgs);\n } else {\n return this.visitAtRuleWithoutBody(atRuleNode, visitArgs);\n }\n },\n\n visitAnonymous: function(anonymousNode, visitArgs) {\n if (!anonymousNode.blocksVisibility()) {\n anonymousNode.accept(this._visitor);\n return anonymousNode;\n }\n },\n\n visitAtRuleWithBody: function(atRuleNode, visitArgs) {\n // if there is only one nested ruleset and that one has no path, then it is\n // just fake ruleset\n function hasFakeRuleset(atRuleNode) {\n const bodyRules = atRuleNode.rules;\n return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);\n }\n function getBodyRules(atRuleNode) {\n const nodeRules = atRuleNode.rules;\n if (hasFakeRuleset(atRuleNode)) {\n return nodeRules[0].rules;\n }\n\n return nodeRules;\n }\n // it is still true that it is only one ruleset in array\n // this is last such moment\n // process childs\n const originalRules = getBodyRules(atRuleNode);\n atRuleNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n\n if (!this.utils.isEmpty(atRuleNode)) {\n this._mergeRules(atRuleNode.rules[0].rules);\n }\n\n return this.utils.resolveVisibility(atRuleNode, originalRules);\n },\n\n visitAtRuleWithoutBody: function(atRuleNode, visitArgs) {\n if (atRuleNode.blocksVisibility()) {\n return;\n }\n\n if (atRuleNode.name === '@charset') {\n // Only output the debug info together with subsequent @charset definitions\n // a comment (or @media statement) before the actual @charset atrule would\n // be considered illegal css as it has to be on the first line\n if (this.charset) {\n if (atRuleNode.debugInfo) {\n const comment = new tree.Comment(`/* ${atRuleNode.toCSS(this._context).replace(/\\n/g, '')} */\\n`);\n comment.debugInfo = atRuleNode.debugInfo;\n return this._visitor.visit(comment);\n }\n return;\n }\n this.charset = true;\n }\n\n return atRuleNode;\n },\n\n checkValidNodes: function(rules, isRoot) {\n if (!rules) {\n return;\n }\n\n for (let i = 0; i < rules.length; i++) {\n const ruleNode = rules[i];\n if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) {\n throw { message: 'Properties must be inside selector blocks. They cannot be in the root',\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n if (ruleNode instanceof tree.Call) {\n throw { message: `Function '${ruleNode.name}' is undefined`,\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n if (ruleNode.type && !ruleNode.allowRoot) {\n throw { message: `${ruleNode.type} node returned by a function is not valid here`,\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n }\n },\n\n visitRuleset: function (rulesetNode, visitArgs) {\n // at this point rulesets are nested into each other\n let rule;\n\n const rulesets = [];\n\n this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);\n\n if (!rulesetNode.root) {\n // remove invisible paths\n this._compileRulesetPaths(rulesetNode);\n\n // remove rulesets from this ruleset body and compile them separately\n const nodeRules = rulesetNode.rules;\n\n let nodeRuleCnt = nodeRules ? nodeRules.length : 0;\n for (let i = 0; i < nodeRuleCnt; ) {\n rule = nodeRules[i];\n if (rule && rule.rules) {\n // visit because we are moving them out from being a child\n rulesets.push(this._visitor.visit(rule));\n nodeRules.splice(i, 1);\n nodeRuleCnt--;\n continue;\n }\n i++;\n }\n // accept the visitor to remove rules and refactor itself\n // then we can decide nogw whether we want it or not\n // compile body\n if (nodeRuleCnt > 0) {\n rulesetNode.accept(this._visitor);\n } else {\n rulesetNode.rules = null;\n }\n visitArgs.visitDeeper = false;\n } else { // if (! rulesetNode.root) {\n rulesetNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n }\n\n if (rulesetNode.rules) {\n this._mergeRules(rulesetNode.rules);\n this._removeDuplicateRules(rulesetNode.rules);\n }\n\n // now decide whether we keep the ruleset\n if (this.utils.isVisibleRuleset(rulesetNode)) {\n rulesetNode.ensureVisibility();\n rulesets.splice(0, 0, rulesetNode);\n }\n\n if (rulesets.length === 1) {\n return rulesets[0];\n }\n return rulesets;\n },\n\n _compileRulesetPaths: function(rulesetNode) {\n if (rulesetNode.paths) {\n rulesetNode.paths = rulesetNode.paths\n .filter(p => {\n let i;\n if (p[0].elements[0].combinator.value === ' ') {\n p[0].elements[0].combinator = new(tree.Combinator)('');\n }\n for (i = 0; i < p.length; i++) {\n if (p[i].isVisible() && p[i].getIsOutput()) {\n return true;\n }\n }\n return false;\n });\n }\n },\n\n _removeDuplicateRules: function(rules) {\n if (!rules) { return; }\n\n // remove duplicates\n const ruleCache = {};\n\n let ruleList;\n let rule;\n let i;\n\n for (i = rules.length - 1; i >= 0 ; i--) {\n rule = rules[i];\n if (rule instanceof tree.Declaration) {\n if (!ruleCache[rule.name]) {\n ruleCache[rule.name] = rule;\n } else {\n ruleList = ruleCache[rule.name];\n if (ruleList instanceof tree.Declaration) {\n ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];\n }\n const ruleCSS = rule.toCSS(this._context);\n if (ruleList.indexOf(ruleCSS) !== -1) {\n rules.splice(i, 1);\n } else {\n ruleList.push(ruleCSS);\n }\n }\n }\n }\n },\n\n _mergeRules: function(rules) {\n if (!rules) {\n return; \n }\n\n const groups = {};\n const groupsArr = [];\n\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i];\n if (rule.merge) {\n const key = rule.name;\n groups[key] ? rules.splice(i--, 1) : \n groupsArr.push(groups[key] = []);\n groups[key].push(rule);\n }\n }\n\n groupsArr.forEach(group => {\n if (group.length > 0) {\n const result = group[0];\n let space = [];\n const comma = [new tree.Expression(space)];\n group.forEach(rule => {\n if ((rule.merge === '+') && (space.length > 0)) {\n comma.push(new tree.Expression(space = []));\n }\n space.push(rule.value);\n result.important = result.important || rule.important;\n });\n result.value = new tree.Value(comma);\n }\n });\n }\n};\n\nexport default ToCSSVisitor;\n","import Visitor from './visitor';\nimport ImportVisitor from './import-visitor';\nimport MarkVisibleSelectorsVisitor from './set-tree-visibility-visitor';\nimport ExtendVisitor from './extend-visitor';\nimport JoinSelectorVisitor from './join-selector-visitor';\nimport ToCSSVisitor from './to-css-visitor';\n\nexport default {\n Visitor,\n ImportVisitor,\n MarkVisibleSelectorsVisitor,\n ExtendVisitor,\n JoinSelectorVisitor,\n ToCSSVisitor\n};\n","import chunker from './chunker';\n\nexport default () => {\n let // Less input string\n input;\n\n let // current chunk\n j;\n\n const // holds state for backtracking\n saveStack = [];\n\n let // furthest index the parser has gone to\n furthest;\n\n let // if this is furthest we got to, this is the probably cause\n furthestPossibleErrorMessage;\n\n let // chunkified input\n chunks;\n\n let // current chunk\n current;\n\n let // index of current chunk, in `input`\n currentPos;\n\n const parserInput = {};\n const CHARCODE_SPACE = 32;\n const CHARCODE_TAB = 9;\n const CHARCODE_LF = 10;\n const CHARCODE_CR = 13;\n const CHARCODE_PLUS = 43;\n const CHARCODE_COMMA = 44;\n const CHARCODE_FORWARD_SLASH = 47;\n const CHARCODE_9 = 57;\n\n function skipWhitespace(length) {\n const oldi = parserInput.i;\n const oldj = j;\n const curr = parserInput.i - currentPos;\n const endIndex = parserInput.i + current.length - curr;\n const mem = (parserInput.i += length);\n const inp = input;\n let c;\n let nextChar;\n let comment;\n\n for (; parserInput.i < endIndex; parserInput.i++) {\n c = inp.charCodeAt(parserInput.i);\n\n if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {\n nextChar = inp.charAt(parserInput.i + 1);\n if (nextChar === '/') {\n comment = {index: parserInput.i, isLineComment: true};\n let nextNewLine = inp.indexOf('\\n', parserInput.i + 2);\n if (nextNewLine < 0) {\n nextNewLine = endIndex;\n }\n parserInput.i = nextNewLine;\n comment.text = inp.substr(comment.index, parserInput.i - comment.index);\n parserInput.commentStore.push(comment);\n continue;\n } else if (nextChar === '*') {\n const nextStarSlash = inp.indexOf('*/', parserInput.i + 2);\n if (nextStarSlash >= 0) {\n comment = {\n index: parserInput.i,\n text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),\n isLineComment: false\n };\n parserInput.i += comment.text.length - 1;\n parserInput.commentStore.push(comment);\n continue;\n }\n }\n break;\n }\n\n if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {\n break;\n }\n }\n\n current = current.slice(length + parserInput.i - mem + curr);\n currentPos = parserInput.i;\n\n if (!current.length) {\n if (j < chunks.length - 1) {\n current = chunks[++j];\n skipWhitespace(0); // skip space at the beginning of a chunk\n return true; // things changed\n }\n parserInput.finished = true;\n }\n\n return oldi !== parserInput.i || oldj !== j;\n }\n\n parserInput.save = () => {\n currentPos = parserInput.i;\n saveStack.push( { current, i: parserInput.i, j });\n };\n parserInput.restore = possibleErrorMessage => {\n\n if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {\n furthest = parserInput.i;\n furthestPossibleErrorMessage = possibleErrorMessage;\n }\n const state = saveStack.pop();\n current = state.current;\n currentPos = parserInput.i = state.i;\n j = state.j;\n };\n parserInput.forget = () => {\n saveStack.pop();\n };\n parserInput.isWhitespace = offset => {\n const pos = parserInput.i + (offset || 0);\n const code = input.charCodeAt(pos);\n return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);\n };\n\n // Specialization of $(tok)\n parserInput.$re = tok => {\n if (parserInput.i > currentPos) {\n current = current.slice(parserInput.i - currentPos);\n currentPos = parserInput.i;\n }\n\n const m = tok.exec(current);\n if (!m) {\n return null;\n }\n\n skipWhitespace(m[0].length);\n if (typeof m === 'string') {\n return m;\n }\n\n return m.length === 1 ? m[0] : m;\n };\n\n parserInput.$char = tok => {\n if (input.charAt(parserInput.i) !== tok) {\n return null;\n }\n skipWhitespace(1);\n return tok;\n };\n\n parserInput.$str = tok => {\n const tokLength = tok.length;\n\n // https://jsperf.com/string-startswith/21\n for (let i = 0; i < tokLength; i++) {\n if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n return null;\n }\n }\n\n skipWhitespace(tokLength);\n return tok;\n };\n\n parserInput.$quoted = loc => {\n const pos = loc || parserInput.i;\n const startChar = input.charAt(pos);\n\n if (startChar !== '\\'' && startChar !== '\"') {\n return;\n }\n const length = input.length;\n const currentPosition = pos;\n\n for (let i = 1; i + currentPosition < length; i++) {\n const nextChar = input.charAt(i + currentPosition);\n switch (nextChar) {\n case '\\\\':\n i++;\n continue;\n case '\\r':\n case '\\n':\n break;\n case startChar:\n const str = input.substr(currentPosition, i + 1);\n if (!loc && loc !== 0) {\n skipWhitespace(i + 1);\n return str\n }\n return [startChar, str];\n default:\n }\n }\n return null;\n };\n\n /**\n * Permissive parsing. Ignores everything except matching {} [] () and quotes\n * until matching token (outside of blocks)\n */\n parserInput.$parseUntil = tok => {\n let quote = '';\n let returnVal = null;\n let inComment = false;\n let blockDepth = 0;\n const blockStack = [];\n const parseGroups = [];\n const length = input.length;\n const startPos = parserInput.i;\n let lastPos = parserInput.i;\n let i = parserInput.i;\n let loop = true;\n let testChar;\n\n if (typeof tok === 'string') {\n testChar = char => char === tok\n } else {\n testChar = char => tok.test(char)\n }\n\n do {\n let prevChar;\n let nextChar = input.charAt(i);\n if (blockDepth === 0 && testChar(nextChar)) {\n returnVal = input.substr(lastPos, i - lastPos);\n if (returnVal) {\n parseGroups.push(returnVal);\n }\n else {\n parseGroups.push(' ');\n }\n returnVal = parseGroups;\n skipWhitespace(i - startPos);\n loop = false\n } else {\n if (inComment) {\n if (nextChar === '*' && \n input.charAt(i + 1) === '/') {\n i++;\n blockDepth--;\n inComment = false;\n }\n i++;\n continue;\n }\n switch (nextChar) {\n case '\\\\':\n i++;\n nextChar = input.charAt(i);\n parseGroups.push(input.substr(lastPos, i - lastPos + 1));\n lastPos = i + 1;\n break;\n case '/':\n if (input.charAt(i + 1) === '*') {\n i++;\n inComment = true;\n blockDepth++;\n }\n break;\n case '\\'':\n case '\"':\n quote = parserInput.$quoted(i);\n if (quote) {\n parseGroups.push(input.substr(lastPos, i - lastPos), quote);\n i += quote[1].length - 1;\n lastPos = i + 1;\n }\n else {\n skipWhitespace(i - startPos);\n returnVal = nextChar;\n loop = false;\n }\n break;\n case '{':\n blockStack.push('}');\n blockDepth++;\n break;\n case '(':\n blockStack.push(')');\n blockDepth++;\n break;\n case '[':\n blockStack.push(']');\n blockDepth++;\n break;\n case '}':\n case ')':\n case ']':\n const expected = blockStack.pop();\n if (nextChar === expected) {\n blockDepth--;\n } else {\n // move the parser to the error and return expected\n skipWhitespace(i - startPos);\n returnVal = expected;\n loop = false;\n }\n }\n i++;\n if (i > length) {\n loop = false;\n }\n }\n prevChar = nextChar;\n } while (loop);\n\n return returnVal ? returnVal : null;\n }\n\n parserInput.autoCommentAbsorb = true;\n parserInput.commentStore = [];\n parserInput.finished = false;\n\n // Same as $(), but don't change the state of the parser,\n // just return the match.\n parserInput.peek = tok => {\n if (typeof tok === 'string') {\n // https://jsperf.com/string-startswith/21\n for (let i = 0; i < tok.length; i++) {\n if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n return false;\n }\n }\n return true;\n } else {\n return tok.test(current);\n }\n };\n\n // Specialization of peek()\n // TODO remove or change some currentChar calls to peekChar\n parserInput.peekChar = tok => input.charAt(parserInput.i) === tok;\n\n parserInput.currentChar = () => input.charAt(parserInput.i);\n\n parserInput.prevChar = () => input.charAt(parserInput.i - 1);\n\n parserInput.getInput = () => input;\n\n parserInput.peekNotNumeric = () => {\n const c = input.charCodeAt(parserInput.i);\n // Is the first char of the dimension 0-9, '.', '+' or '-'\n return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;\n };\n\n parserInput.start = (str, chunkInput, failFunction) => {\n input = str;\n parserInput.i = j = currentPos = furthest = 0;\n\n // chunking apparently makes things quicker (but my tests indicate\n // it might actually make things slower in node at least)\n // and it is a non-perfect parse - it can't recognise\n // unquoted urls, meaning it can't distinguish comments\n // meaning comments with quotes or {}() in them get 'counted'\n // and then lead to parse errors.\n // In addition if the chunking chunks in the wrong place we might\n // not be able to parse a parser statement in one go\n // this is officially deprecated but can be switched on via an option\n // in the case it causes too much performance issues.\n if (chunkInput) {\n chunks = chunker(str, failFunction);\n } else {\n chunks = [str];\n }\n\n current = chunks[0];\n\n skipWhitespace(0);\n };\n\n parserInput.end = () => {\n let message;\n const isFinished = parserInput.i >= input.length;\n\n if (parserInput.i < furthest) {\n message = furthestPossibleErrorMessage;\n parserInput.i = furthest;\n }\n return {\n isFinished,\n furthest: parserInput.i,\n furthestPossibleErrorMessage: message,\n furthestReachedEnd: parserInput.i >= input.length - 1,\n furthestChar: input[parserInput.i]\n };\n };\n\n return parserInput;\n};\n","// Split the input into chunks.\nexport default (input, fail) => {\n const len = input.length;\n let level = 0;\n let parenLevel = 0;\n let lastOpening;\n let lastOpeningParen;\n let lastMultiComment;\n let lastMultiCommentEndBrace;\n const chunks = [];\n let emitFrom = 0;\n let chunkerCurrentIndex;\n let currentChunkStartIndex;\n let cc;\n let cc2;\n let matched;\n\n function emitChunk(force) {\n const len = chunkerCurrentIndex - emitFrom;\n if (((len < 512) && !force) || !len) {\n return;\n }\n chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));\n emitFrom = chunkerCurrentIndex + 1;\n }\n\n for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc = input.charCodeAt(chunkerCurrentIndex);\n if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {\n // a-z or whitespace\n continue;\n }\n\n switch (cc) {\n case 40: // (\n parenLevel++;\n lastOpeningParen = chunkerCurrentIndex;\n continue;\n case 41: // )\n if (--parenLevel < 0) {\n return fail('missing opening `(`', chunkerCurrentIndex);\n }\n continue;\n case 59: // ;\n if (!parenLevel) { emitChunk(); }\n continue;\n case 123: // {\n level++;\n lastOpening = chunkerCurrentIndex;\n continue;\n case 125: // }\n if (--level < 0) {\n return fail('missing opening `{`', chunkerCurrentIndex);\n }\n if (!level && !parenLevel) { emitChunk(); }\n continue;\n case 92: // \\\n if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }\n return fail('unescaped `\\\\`', chunkerCurrentIndex);\n case 34:\n case 39:\n case 96: // \", ' and `\n matched = 0;\n currentChunkStartIndex = chunkerCurrentIndex;\n for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if (cc2 > 96) { continue; }\n if (cc2 == cc) { matched = 1; break; }\n if (cc2 == 92) { // \\\n if (chunkerCurrentIndex == len - 1) {\n return fail('unescaped `\\\\`', chunkerCurrentIndex);\n }\n chunkerCurrentIndex++;\n }\n }\n if (matched) { continue; }\n return fail(`unmatched \\`${String.fromCharCode(cc)}\\``, currentChunkStartIndex);\n case 47: // /, check for comment\n if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }\n cc2 = input.charCodeAt(chunkerCurrentIndex + 1);\n if (cc2 == 47) {\n // //, find lnfeed\n for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }\n }\n } else if (cc2 == 42) {\n // /*, find */\n lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;\n for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }\n if (cc2 != 42) { continue; }\n if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }\n }\n if (chunkerCurrentIndex == len - 1) {\n return fail('missing closing `*/`', currentChunkStartIndex);\n }\n chunkerCurrentIndex++;\n }\n continue;\n case 42: // *, check for unmatched */\n if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {\n return fail('unmatched `/*`', chunkerCurrentIndex);\n }\n continue;\n }\n }\n\n if (level !== 0) {\n if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {\n return fail('missing closing `}` or `*/`', lastOpening);\n } else {\n return fail('missing closing `}`', lastOpening);\n }\n } else if (parenLevel !== 0) {\n return fail('missing closing `)`', lastOpeningParen);\n }\n\n emitChunk(true);\n return chunks;\n};\n","import LessError from '../less-error';\nimport tree from '../tree';\nimport visitors from '../visitors';\nimport getParserInput from './parser-input';\nimport * as utils from '../utils';\nimport functionRegistry from '../functions/function-registry';\n\n//\n// less.js - parser\n//\n// A relatively straight-forward predictive parser.\n// There is no tokenization/lexing stage, the input is parsed\n// in one sweep.\n//\n// To make the parser fast enough to run in the browser, several\n// optimization had to be made:\n//\n// - Matching and slicing on a huge input is often cause of slowdowns.\n// The solution is to chunkify the input into smaller strings.\n// The chunks are stored in the `chunks` var,\n// `j` holds the current chunk index, and `currentPos` holds\n// the index of the current chunk in relation to `input`.\n// This gives us an almost 4x speed-up.\n//\n// - In many cases, we don't need to match individual tokens;\n// for example, if a value doesn't hold any variables, operations\n// or dynamic references, the parser can effectively 'skip' it,\n// treating it as a literal.\n// An example would be '1px solid #000' - which evaluates to itself,\n// we don't need to know what the individual components are.\n// The drawback, of course is that you don't get the benefits of\n// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,\n// and a smaller speed-up in the code-gen.\n//\n//\n// Token matching is done with the `$` function, which either takes\n// a terminal string or regexp, or a non-terminal function to call.\n// It also takes care of moving all the indices forwards.\n//\n\nconst Parser = function Parser(context, imports, fileInfo) {\n let parsers;\n const parserInput = getParserInput();\n\n function error(msg, type) {\n throw new LessError(\n {\n index: parserInput.i,\n filename: fileInfo.filename,\n type: type || 'Syntax',\n message: msg\n },\n imports\n );\n }\n\n function expect(arg, msg) {\n // some older browsers return typeof 'function' for RegExp\n const result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);\n if (result) {\n return result;\n }\n \n error(msg || (typeof arg === 'string'\n ? `expected '${arg}' got '${parserInput.currentChar()}'`\n : 'unexpected token'));\n }\n\n // Specialization of expect()\n function expectChar(arg, msg) {\n if (parserInput.$char(arg)) {\n return arg;\n }\n error(msg || `expected '${arg}' got '${parserInput.currentChar()}'`);\n }\n\n function getDebugInfo(index) {\n const filename = fileInfo.filename;\n\n return {\n lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,\n fileName: filename\n };\n }\n\n /**\n * Used after initial parsing to create nodes on the fly\n * \n * @param {String} str - string to parse \n * @param {Array} parseList - array of parsers to run input through e.g. [\"value\", \"important\"]\n * @param {Number} currentIndex - start number to begin indexing\n * @param {Object} fileInfo - fileInfo to attach to created nodes\n */\n function parseNode(str, parseList, currentIndex, fileInfo, callback) {\n let result;\n const returnNodes = [];\n const parser = parserInput;\n\n try {\n parser.start(str, false, function fail(msg, index) {\n callback({\n message: msg,\n index: index + currentIndex\n });\n });\n for (let x = 0, p, i; (p = parseList[x]); x++) {\n i = parser.i;\n result = parsers[p]();\n if (result) {\n try {\n result._index = i + currentIndex;\n result._fileInfo = fileInfo;\n } catch (e) {}\n returnNodes.push(result);\n }\n else {\n returnNodes.push(null);\n }\n }\n\n const endInfo = parser.end();\n if (endInfo.isFinished) {\n callback(null, returnNodes);\n }\n else {\n callback(true, null);\n }\n } catch (e) {\n throw new LessError({\n index: e.index + currentIndex,\n message: e.message\n }, imports, fileInfo.filename);\n }\n }\n\n //\n // The Parser\n //\n return {\n parserInput,\n imports,\n fileInfo,\n parseNode,\n //\n // Parse an input string into an abstract syntax tree,\n // @param str A string containing 'less' markup\n // @param callback call `callback` when done.\n // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply\n //\n parse: function (str, callback, additionalData) {\n let root;\n let error = null;\n let globalVars;\n let modifyVars;\n let ignored;\n let preText = '';\n\n globalVars = (additionalData && additionalData.globalVars) ? `${Parser.serializeVars(additionalData.globalVars)}\\n` : '';\n modifyVars = (additionalData && additionalData.modifyVars) ? `\\n${Parser.serializeVars(additionalData.modifyVars)}` : '';\n\n if (context.pluginManager) {\n const preProcessors = context.pluginManager.getPreProcessors();\n for (let i = 0; i < preProcessors.length; i++) {\n str = preProcessors[i].process(str, { context, imports, fileInfo });\n }\n }\n\n if (globalVars || (additionalData && additionalData.banner)) {\n preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;\n ignored = imports.contentsIgnoredChars;\n ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;\n ignored[fileInfo.filename] += preText.length;\n }\n\n str = str.replace(/\\r\\n?/g, '\\n');\n // Remove potential UTF Byte Order Mark\n str = preText + str.replace(/^\\uFEFF/, '') + modifyVars;\n imports.contents[fileInfo.filename] = str;\n\n // Start with the primary rule.\n // The whole syntax tree is held under a Ruleset node,\n // with the `root` property set to true, so no `{}` are\n // output. The callback is called when the input is parsed.\n try {\n parserInput.start(str, context.chunkInput, function fail(msg, index) {\n throw new LessError({\n index,\n type: 'Parse',\n message: msg,\n filename: fileInfo.filename\n }, imports);\n });\n\n tree.Node.prototype.parse = this;\n root = new tree.Ruleset(null, this.parsers.primary());\n tree.Node.prototype.rootNode = root;\n root.root = true;\n root.firstRoot = true;\n root.functionRegistry = functionRegistry.inherit();\n \n } catch (e) {\n return callback(new LessError(e, imports, fileInfo.filename));\n }\n\n // If `i` is smaller than the `input.length - 1`,\n // it means the parser wasn't able to parse the whole\n // string, so we've got a parsing error.\n //\n // We try to extract a \\n delimited string,\n // showing the line where the parse error occurred.\n // We split it up into two parts (the part which parsed,\n // and the part which didn't), so we can color them differently.\n const endInfo = parserInput.end();\n if (!endInfo.isFinished) {\n\n let message = endInfo.furthestPossibleErrorMessage;\n\n if (!message) {\n message = 'Unrecognised input';\n if (endInfo.furthestChar === '}') {\n message += '. Possibly missing opening \\'{\\'';\n } else if (endInfo.furthestChar === ')') {\n message += '. Possibly missing opening \\'(\\'';\n } else if (endInfo.furthestReachedEnd) {\n message += '. Possibly missing something';\n }\n }\n\n error = new LessError({\n type: 'Parse',\n message,\n index: endInfo.furthest,\n filename: fileInfo.filename\n }, imports);\n }\n\n const finish = e => {\n e = error || e || imports.error;\n\n if (e) {\n if (!(e instanceof LessError)) {\n e = new LessError(e, imports, fileInfo.filename);\n }\n\n return callback(e);\n }\n else {\n return callback(null, root);\n }\n };\n\n if (context.processImports !== false) {\n new visitors.ImportVisitor(imports, finish)\n .run(root);\n } else {\n return finish();\n }\n },\n\n //\n // Here in, the parsing rules/functions\n //\n // The basic structure of the syntax tree generated is as follows:\n //\n // Ruleset -> Declaration -> Value -> Expression -> Entity\n //\n // Here's some Less code:\n //\n // .class {\n // color: #fff;\n // border: 1px solid #000;\n // width: @w + 4px;\n // > .child {...}\n // }\n //\n // And here's what the parse tree might look like:\n //\n // Ruleset (Selector '.class', [\n // Declaration (\"color\", Value ([Expression [Color #fff]]))\n // Declaration (\"border\", Value ([Expression [Dimension 1px][Keyword \"solid\"][Color #000]]))\n // Declaration (\"width\", Value ([Expression [Operation \" + \" [Variable \"@w\"][Dimension 4px]]]))\n // Ruleset (Selector [Element '>', '.child'], [...])\n // ])\n //\n // In general, most rules will try to parse a token with the `$re()` function, and if the return\n // value is truly, will return a new node, of the relevant type. Sometimes, we need to check\n // first, before parsing, that's when we use `peek()`.\n //\n parsers: parsers = {\n //\n // The `primary` rule is the *entry* and *exit* point of the parser.\n // The rules here can appear at any level of the parse tree.\n //\n // The recursive nature of the grammar is an interplay between the `block`\n // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,\n // as represented by this simplified grammar:\n //\n // primary → (ruleset | declaration)+\n // ruleset → selector+ block\n // block → '{' primary '}'\n //\n // Only at one point is the primary rule not called from the\n // block rule: at the root level.\n //\n primary: function () {\n const mixin = this.mixin;\n let root = [];\n let node;\n\n while (true) {\n while (true) {\n node = this.comment();\n if (!node) { break; }\n root.push(node);\n }\n // always process comments before deciding if finished\n if (parserInput.finished) {\n break;\n }\n if (parserInput.peek('}')) {\n break;\n }\n\n node = this.extendRule();\n if (node) {\n root = root.concat(node);\n continue;\n }\n\n node = mixin.definition() || this.declaration() || this.ruleset() ||\n mixin.call(false, false) || this.variableCall() || this.entities.call() || this.atrule();\n if (node) {\n root.push(node);\n } else {\n let foundSemiColon = false;\n while (parserInput.$char(';')) {\n foundSemiColon = true;\n }\n if (!foundSemiColon) {\n break;\n }\n }\n }\n\n return root;\n },\n\n // comments are collected by the main parsing mechanism and then assigned to nodes\n // where the current structure allows it\n comment: function () {\n if (parserInput.commentStore.length) {\n const comment = parserInput.commentStore.shift();\n return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);\n }\n },\n\n //\n // Entities are tokens which can be found inside an Expression\n //\n entities: {\n mixinLookup: function() {\n return parsers.mixin.call(true, true);\n },\n //\n // A string, which supports escaping \" and '\n //\n // \"milky way\" 'he\\'s the one!'\n //\n quoted: function (forceEscaped) {\n let str;\n const index = parserInput.i;\n let isEscaped = false;\n\n parserInput.save();\n if (parserInput.$char('~')) {\n isEscaped = true;\n } else if (forceEscaped) {\n parserInput.restore();\n return;\n }\n\n str = parserInput.$quoted();\n if (!str) {\n parserInput.restore();\n return;\n }\n parserInput.forget();\n\n return new(tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);\n },\n\n //\n // A catch-all word, such as:\n //\n // black border-collapse\n //\n keyword: function () {\n const k = parserInput.$char('%') || parserInput.$re(/^\\[?(?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\\]?/);\n if (k) {\n return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);\n }\n },\n\n //\n // A function call\n //\n // rgb(255, 0, 255)\n //\n // The arguments are parsed with the `entities.arguments` parser.\n //\n call: function () {\n let name;\n let args;\n let func;\n const index = parserInput.i;\n\n // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n if (parserInput.peek(/^url\\(/i)) {\n return;\n }\n\n parserInput.save();\n\n name = parserInput.$re(/^([\\w-]+|%|progid:[\\w\\.]+)\\(/);\n if (!name) {\n parserInput.forget(); \n return;\n }\n\n name = name[1];\n func = this.customFuncCall(name);\n if (func) {\n args = func.parse();\n if (args && func.stop) {\n parserInput.forget();\n return args;\n }\n }\n\n args = this.arguments(args);\n\n if (!parserInput.$char(')')) {\n parserInput.restore('Could not parse call arguments or missing \\')\\'');\n return;\n }\n\n parserInput.forget();\n\n return new(tree.Call)(name, args, index, fileInfo);\n },\n \n //\n // Parsing rules for functions with non-standard args, e.g.:\n //\n // boolean(not(2 > 1))\n //\n // This is a quick prototype, to be modified/improved when\n // more custom-parsed funcs come (e.g. `selector(...)`)\n //\n\n customFuncCall: function (name) {\n /* Ideally the table is to be moved out of here for faster perf.,\n but it's quite tricky since it relies on all these `parsers`\n and `expect` available only here */\n return {\n alpha: f(parsers.ieAlpha, true),\n boolean: f(condition),\n 'if': f(condition)\n }[name.toLowerCase()];\n\n function f(parse, stop) {\n return {\n parse, // parsing function\n stop // when true - stop after parse() and return its result, \n // otherwise continue for plain args\n };\n }\n \n function condition() {\n return [expect(parsers.condition, 'expected condition')];\n }\n },\n\n arguments: function (prevArgs) {\n let argsComma = prevArgs || [];\n const argsSemiColon = [];\n let isSemiColonSeparated;\n let value;\n\n parserInput.save();\n\n while (true) {\n if (prevArgs) {\n prevArgs = false;\n } else {\n value = parsers.detachedRuleset() || this.assignment() || parsers.expression();\n if (!value) {\n break;\n }\n\n if (value.value && value.value.length == 1) {\n value = value.value[0];\n }\n\n argsComma.push(value);\n }\n\n if (parserInput.$char(',')) {\n continue;\n }\n\n if (parserInput.$char(';') || isSemiColonSeparated) {\n isSemiColonSeparated = true;\n value = (argsComma.length < 1) ? argsComma[0]\n : new tree.Value(argsComma);\n argsSemiColon.push(value);\n argsComma = [];\n }\n }\n\n parserInput.forget();\n return isSemiColonSeparated ? argsSemiColon : argsComma;\n },\n literal: function () {\n return this.dimension() ||\n this.color() ||\n this.quoted() ||\n this.unicodeDescriptor();\n },\n\n // Assignments are argument entities for calls.\n // They are present in ie filter properties as shown below.\n //\n // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )\n //\n\n assignment: function () {\n let key;\n let value;\n parserInput.save();\n key = parserInput.$re(/^\\w+(?=\\s?=)/i);\n if (!key) {\n parserInput.restore();\n return;\n }\n if (!parserInput.$char('=')) {\n parserInput.restore();\n return;\n }\n value = parsers.entity();\n if (value) {\n parserInput.forget();\n return new(tree.Assignment)(key, value);\n } else {\n parserInput.restore();\n }\n },\n\n //\n // Parse url() tokens\n //\n // We use a specific rule for urls, because they don't really behave like\n // standard function calls. The difference is that the argument doesn't have\n // to be enclosed within a string, so it can't be parsed as an Expression.\n //\n url: function () {\n let value;\n const index = parserInput.i;\n\n parserInput.autoCommentAbsorb = false;\n\n if (!parserInput.$str('url(')) {\n parserInput.autoCommentAbsorb = true;\n return;\n }\n\n value = this.quoted() || this.variable() || this.property() ||\n parserInput.$re(/^(?:(?:\\\\[\\(\\)'\"])|[^\\(\\)'\"])+/) || '';\n\n parserInput.autoCommentAbsorb = true;\n\n expectChar(')');\n\n return new(tree.URL)((value.value != null || \n value instanceof tree.Variable || \n value instanceof tree.Property) ?\n value : new(tree.Anonymous)(value, index), index, fileInfo);\n },\n\n //\n // A Variable entity, such as `@fink`, in\n //\n // width: @fink + 2px\n //\n // We use a different parser for variable definitions,\n // see `parsers.variable`.\n //\n variable: function () {\n let ch;\n let name;\n const index = parserInput.i;\n\n parserInput.save();\n if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\\w-]+/))) {\n ch = parserInput.currentChar();\n if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\\s/)) {\n // this may be a VariableCall lookup\n const result = parsers.variableCall(name);\n if (result) {\n parserInput.forget();\n return result;\n }\n }\n parserInput.forget();\n return new(tree.Variable)(name, index, fileInfo);\n }\n parserInput.restore();\n },\n\n // A variable entity using the protective {} e.g. @{var}\n variableCurly: function () {\n let curly;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\\{([\\w-]+)\\}/))) {\n return new(tree.Variable)(`@${curly[1]}`, index, fileInfo);\n }\n },\n //\n // A Property accessor, such as `$color`, in\n //\n // background-color: $color\n //\n property: function () {\n let name;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\\$[\\w-]+/))) {\n return new(tree.Property)(name, index, fileInfo);\n }\n },\n\n // A property entity useing the protective {} e.g. ${prop}\n propertyCurly: function () {\n let curly;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\\$\\{([\\w-]+)\\}/))) {\n return new(tree.Property)(`$${curly[1]}`, index, fileInfo);\n }\n },\n //\n // A Hexadecimal color\n //\n // #4F3C2F\n //\n // `rgb` and `hsl` colors are parsed through the `entities.call` parser.\n //\n color: function () {\n let rgb;\n parserInput.save();\n\n if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\\w.#\\[])?/))) {\n if (!rgb[2]) {\n parserInput.forget();\n return new(tree.Color)(rgb[1], undefined, rgb[0]);\n } \n }\n parserInput.restore();\n },\n\n colorKeyword: function () {\n parserInput.save();\n const autoCommentAbsorb = parserInput.autoCommentAbsorb;\n parserInput.autoCommentAbsorb = false;\n const k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);\n parserInput.autoCommentAbsorb = autoCommentAbsorb;\n if (!k) {\n parserInput.forget();\n return;\n }\n parserInput.restore();\n const color = tree.Color.fromKeyword(k);\n if (color) {\n parserInput.$str(k);\n return color;\n }\n },\n\n //\n // A Dimension, that is, a number and a unit\n //\n // 0.5em 95%\n //\n dimension: function () {\n if (parserInput.peekNotNumeric()) {\n return;\n }\n\n const value = parserInput.$re(/^([+-]?\\d*\\.?\\d+)(%|[a-z_]+)?/i);\n if (value) {\n return new(tree.Dimension)(value[1], value[2]);\n }\n },\n\n //\n // A unicode descriptor, as is used in unicode-range\n //\n // U+0?? or U+00A1-00A9\n //\n unicodeDescriptor: function () {\n let ud;\n\n ud = parserInput.$re(/^U\\+[0-9a-fA-F?]+(\\-[0-9a-fA-F?]+)?/);\n if (ud) {\n return new(tree.UnicodeDescriptor)(ud[0]);\n }\n },\n\n //\n // JavaScript code to be evaluated\n //\n // `window.location.href`\n //\n javascript: function () {\n let js;\n const index = parserInput.i;\n\n parserInput.save();\n\n const escape = parserInput.$char('~');\n const jsQuote = parserInput.$char('`');\n\n if (!jsQuote) {\n parserInput.restore();\n return;\n }\n\n js = parserInput.$re(/^[^`]*`/);\n if (js) {\n parserInput.forget();\n return new(tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);\n }\n parserInput.restore('invalid javascript definition');\n }\n },\n\n //\n // The variable part of a variable definition. Used in the `rule` parser\n //\n // @fink:\n //\n variable: function () {\n let name;\n\n if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\\w-]+)\\s*:/))) { return name[1]; }\n },\n\n //\n // Call a variable value to retrieve a detached ruleset\n // or a value from a detached ruleset's rules.\n //\n // @fink();\n // @fink;\n // color: @fink[@color];\n //\n variableCall: function (parsedName) {\n let lookups;\n let important;\n const i = parserInput.i;\n const inValue = !!parsedName;\n let name = parsedName;\n\n parserInput.save();\n\n if (name || (parserInput.currentChar() === '@'\n && (name = parserInput.$re(/^(@[\\w-]+)(\\(\\s*\\))?/)))) {\n\n lookups = this.mixin.ruleLookups();\n\n if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) {\n parserInput.restore('Missing \\'[...]\\' lookup in variable call');\n return;\n }\n\n if (!inValue) {\n name = name[1];\n }\n\n if (lookups && parsers.important()) {\n important = true;\n }\n\n const call = new tree.VariableCall(name, i, fileInfo);\n if (!inValue && parsers.end()) {\n parserInput.forget();\n return call;\n }\n else {\n parserInput.forget();\n return new tree.NamespaceValue(call, lookups, important, i, fileInfo);\n }\n }\n\n parserInput.restore();\n },\n\n //\n // extend syntax - used to extend selectors\n //\n extend: function(isRule) {\n let elements;\n let e;\n const index = parserInput.i;\n let option;\n let extendList;\n let extend;\n\n if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {\n return;\n }\n\n do {\n option = null;\n elements = null;\n while (!(option = parserInput.$re(/^(all)(?=\\s*(\\)|,))/))) {\n e = this.element();\n if (!e) {\n break;\n }\n if (elements) {\n elements.push(e);\n } else {\n elements = [ e ];\n }\n }\n\n option = option && option[1];\n if (!elements) {\n error('Missing target selector for :extend().');\n }\n extend = new(tree.Extend)(new(tree.Selector)(elements), option, index, fileInfo);\n if (extendList) {\n extendList.push(extend);\n } else {\n extendList = [ extend ];\n }\n } while (parserInput.$char(','));\n\n expect(/^\\)/);\n\n if (isRule) {\n expect(/^;/);\n }\n\n return extendList;\n },\n\n //\n // extendRule - used in a rule to extend all the parent selectors\n //\n extendRule: function() {\n return this.extend(true);\n },\n\n //\n // Mixins\n //\n mixin: {\n //\n // A Mixin call, with an optional argument list\n //\n // #mixins > .square(#fff);\n // #mixins.square(#fff);\n // .rounded(4px, black);\n // .button;\n //\n // We can lookup / return a value using the lookup syntax:\n //\n // color: #mixin.square(#fff)[@color];\n //\n // The `while` loop is there because mixins can be\n // namespaced, but we only support the child and descendant\n // selector for now.\n //\n call: function (inValue, getLookup) {\n const s = parserInput.currentChar();\n let important = false;\n let lookups;\n const index = parserInput.i;\n let elements;\n let args;\n let hasParens;\n\n if (s !== '.' && s !== '#') { return; }\n\n parserInput.save(); // stop us absorbing part of an invalid selector\n\n elements = this.elements();\n\n if (elements) {\n if (parserInput.$char('(')) {\n args = this.args(true).args;\n expectChar(')');\n hasParens = true;\n }\n\n if (getLookup !== false) {\n lookups = this.ruleLookups();\n }\n if (getLookup === true && !lookups) {\n parserInput.restore();\n return;\n }\n\n if (inValue && !lookups && !hasParens) {\n // This isn't a valid in-value mixin call\n parserInput.restore();\n return;\n }\n\n if (!inValue && parsers.important()) {\n important = true;\n }\n\n if (inValue || parsers.end()) {\n parserInput.forget();\n const mixin = new(tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important);\n if (lookups) {\n return new tree.NamespaceValue(mixin, lookups, important);\n }\n else {\n return mixin;\n }\n }\n }\n\n parserInput.restore();\n },\n /**\n * Matching elements for mixins\n * (Start with . or # and can have > )\n */\n elements: function() {\n let elements;\n let e;\n let c;\n let elem;\n let elemIndex;\n const re = /^[#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;\n while (true) {\n elemIndex = parserInput.i;\n e = parserInput.$re(re);\n \n if (!e) {\n break;\n }\n elem = new(tree.Element)(c, e, false, elemIndex, fileInfo);\n if (elements) {\n elements.push(elem);\n } else {\n elements = [ elem ];\n }\n c = parserInput.$char('>');\n }\n return elements;\n },\n args: function (isCall) {\n const entities = parsers.entities;\n const returner = { args:null, variadic: false };\n let expressions = [];\n const argsSemiColon = [];\n const argsComma = [];\n let isSemiColonSeparated;\n let expressionContainsNamed;\n let name;\n let nameLoop;\n let value;\n let arg;\n let expand;\n let hasSep = true;\n\n parserInput.save();\n\n while (true) {\n if (isCall) {\n arg = parsers.detachedRuleset() || parsers.expression();\n } else {\n parserInput.commentStore.length = 0;\n if (parserInput.$str('...')) {\n returner.variadic = true;\n if (parserInput.$char(';') && !isSemiColonSeparated) {\n isSemiColonSeparated = true;\n }\n (isSemiColonSeparated ? argsSemiColon : argsComma)\n .push({ variadic: true });\n break;\n }\n arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true);\n }\n\n if (!arg || !hasSep) {\n break;\n }\n\n nameLoop = null;\n if (arg.throwAwayComments) {\n arg.throwAwayComments();\n }\n value = arg;\n let val = null;\n\n if (isCall) {\n // Variable\n if (arg.value && arg.value.length == 1) {\n val = arg.value[0];\n }\n } else {\n val = arg;\n }\n\n if (val && (val instanceof tree.Variable || val instanceof tree.Property)) {\n if (parserInput.$char(':')) {\n if (expressions.length > 0) {\n if (isSemiColonSeparated) {\n error('Cannot mix ; and , as delimiter types');\n }\n expressionContainsNamed = true;\n }\n\n value = parsers.detachedRuleset() || parsers.expression();\n\n if (!value) {\n if (isCall) {\n error('could not understand value for named argument');\n } else {\n parserInput.restore();\n returner.args = [];\n return returner;\n }\n }\n nameLoop = (name = val.name);\n } else if (parserInput.$str('...')) {\n if (!isCall) {\n returner.variadic = true;\n if (parserInput.$char(';') && !isSemiColonSeparated) {\n isSemiColonSeparated = true;\n }\n (isSemiColonSeparated ? argsSemiColon : argsComma)\n .push({ name: arg.name, variadic: true });\n break;\n } else {\n expand = true;\n }\n } else if (!isCall) {\n name = nameLoop = val.name;\n value = null;\n }\n }\n\n if (value) {\n expressions.push(value);\n }\n\n argsComma.push({ name:nameLoop, value, expand });\n\n if (parserInput.$char(',')) {\n hasSep = true;\n continue;\n }\n hasSep = parserInput.$char(';') === ';';\n\n if (hasSep || isSemiColonSeparated) {\n\n if (expressionContainsNamed) {\n error('Cannot mix ; and , as delimiter types');\n }\n\n isSemiColonSeparated = true;\n\n if (expressions.length > 1) {\n value = new(tree.Value)(expressions);\n }\n argsSemiColon.push({ name, value, expand });\n\n name = null;\n expressions = [];\n expressionContainsNamed = false;\n }\n }\n\n parserInput.forget();\n returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;\n return returner;\n },\n //\n // A Mixin definition, with a list of parameters\n //\n // .rounded (@radius: 2px, @color) {\n // ...\n // }\n //\n // Until we have a finer grained state-machine, we have to\n // do a look-ahead, to make sure we don't have a mixin call.\n // See the `rule` function for more information.\n //\n // We start by matching `.rounded (`, and then proceed on to\n // the argument list, which has optional default values.\n // We store the parameters in `params`, with a `value` key,\n // if there is a value, such as in the case of `@radius`.\n //\n // Once we've got our params list, and a closing `)`, we parse\n // the `{...}` block.\n //\n definition: function () {\n let name;\n let params = [];\n let match;\n let ruleset;\n let cond;\n let variadic = false;\n if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||\n parserInput.peek(/^[^{]*\\}/)) {\n return;\n }\n\n parserInput.save();\n\n match = parserInput.$re(/^([#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\\s*\\(/);\n if (match) {\n name = match[1];\n\n const argInfo = this.args(false);\n params = argInfo.args;\n variadic = argInfo.variadic;\n\n // .mixincall(\"@{a}\");\n // looks a bit like a mixin definition..\n // also\n // .mixincall(@a: {rule: set;});\n // so we have to be nice and restore\n if (!parserInput.$char(')')) {\n parserInput.restore('Missing closing \\')\\'');\n return;\n }\n\n parserInput.commentStore.length = 0;\n\n if (parserInput.$str('when')) { // Guard\n cond = expect(parsers.conditions, 'expected condition');\n }\n\n ruleset = parsers.block();\n\n if (ruleset) {\n parserInput.forget();\n return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);\n } else {\n parserInput.restore();\n }\n } else {\n parserInput.forget();\n }\n },\n \n ruleLookups: function() {\n let rule;\n let args;\n const lookups = [];\n\n if (parserInput.currentChar() !== '[') { \n return;\n }\n\n while (true) {\n parserInput.save();\n args = null;\n rule = this.lookupValue();\n if (!rule && rule !== '') {\n parserInput.restore();\n break;\n }\n lookups.push(rule);\n parserInput.forget();\n }\n if (lookups.length > 0) {\n return lookups;\n }\n },\n \n lookupValue: function() {\n parserInput.save();\n \n if (!parserInput.$char('[')) { \n parserInput.restore();\n return;\n }\n \n const name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);\n \n if (!parserInput.$char(']')) {\n parserInput.restore();\n return;\n } \n\n if (name || name === '') {\n parserInput.forget();\n return name;\n }\n \n parserInput.restore();\n }\n },\n //\n // Entities are the smallest recognized token,\n // and can be found inside a rule's value.\n //\n entity: function () {\n const entities = this.entities;\n\n return this.comment() || entities.literal() || entities.variable() || entities.url() ||\n entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||\n entities.javascript();\n },\n\n //\n // A Declaration terminator. Note that we use `peek()` to check for '}',\n // because the `block` rule will be expecting it, but we still need to make sure\n // it's there, if ';' was omitted.\n //\n end: function () {\n return parserInput.$char(';') || parserInput.peek('}');\n },\n\n //\n // IE's alpha function\n //\n // alpha(opacity=88)\n //\n ieAlpha: function () {\n let value;\n\n // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n if (!parserInput.$re(/^opacity=/i)) { return; }\n value = parserInput.$re(/^\\d+/);\n if (!value) {\n value = expect(parsers.entities.variable, 'Could not parse alpha');\n value = `@{${value.name.slice(1)}}`;\n }\n expectChar(')');\n return new tree.Quoted('', `alpha(opacity=${value})`);\n },\n\n //\n // A Selector Element\n //\n // div\n // + h1\n // #socks\n // input[type=\"text\"]\n //\n // Elements are the building blocks for Selectors,\n // they are made out of a `Combinator` (see combinator rule),\n // and an element name, such as a tag a class, or `*`.\n //\n element: function () {\n let e;\n let c;\n let v;\n const index = parserInput.i;\n\n c = this.combinator();\n\n e = parserInput.$re(/^(?:\\d+\\.\\d+|\\d+)%/) ||\n parserInput.$re(/^(?:[.#]?|:*)(?:[\\w-]|[^\\x00-\\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||\n parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||\n parserInput.$re(/^\\([^&()@]+\\)/) || parserInput.$re(/^[\\.#:](?=@)/) ||\n this.entities.variableCurly();\n\n if (!e) {\n parserInput.save();\n if (parserInput.$char('(')) {\n if ((v = this.selector(false)) && parserInput.$char(')')) {\n e = new(tree.Paren)(v);\n parserInput.forget();\n } else {\n parserInput.restore('Missing closing \\')\\'');\n }\n } else {\n parserInput.forget();\n }\n }\n\n if (e) { return new(tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo); }\n },\n\n //\n // Combinators combine elements together, in a Selector.\n //\n // Because our parser isn't white-space sensitive, special care\n // has to be taken, when parsing the descendant combinator, ` `,\n // as it's an empty space. We have to check the previous character\n // in the input, to see if it's a ` ` character. More info on how\n // we deal with this in *combinator.js*.\n //\n combinator: function () {\n let c = parserInput.currentChar();\n\n if (c === '/') {\n parserInput.save();\n const slashedCombinator = parserInput.$re(/^\\/[a-z]+\\//i);\n if (slashedCombinator) {\n parserInput.forget();\n return new(tree.Combinator)(slashedCombinator);\n }\n parserInput.restore();\n }\n\n if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {\n parserInput.i++;\n if (c === '^' && parserInput.currentChar() === '^') {\n c = '^^';\n parserInput.i++;\n }\n while (parserInput.isWhitespace()) { parserInput.i++; }\n return new(tree.Combinator)(c);\n } else if (parserInput.isWhitespace(-1)) {\n return new(tree.Combinator)(' ');\n } else {\n return new(tree.Combinator)(null);\n }\n },\n //\n // A CSS Selector\n // with less extensions e.g. the ability to extend and guard\n //\n // .class > div + h1\n // li a:hover\n //\n // Selectors are made out of one or more Elements, see above.\n //\n selector: function (isLess) {\n const index = parserInput.i;\n let elements;\n let extendList;\n let c;\n let e;\n let allExtends;\n let when;\n let condition;\n isLess = isLess !== false;\n while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {\n if (when) {\n condition = expect(this.conditions, 'expected condition');\n } else if (condition) {\n error('CSS guard can only be used at the end of selector');\n } else if (extendList) {\n if (allExtends) {\n allExtends = allExtends.concat(extendList);\n } else {\n allExtends = extendList;\n }\n } else {\n if (allExtends) { error('Extend can only be used at the end of selector'); }\n c = parserInput.currentChar();\n if (elements) {\n elements.push(e);\n } else {\n elements = [ e ];\n }\n e = null;\n }\n if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {\n break;\n }\n }\n\n if (elements) { return new(tree.Selector)(elements, allExtends, condition, index, fileInfo); }\n if (allExtends) { error('Extend must be used to extend a selector, it cannot be used on its own'); }\n },\n selectors: function () {\n let s;\n let selectors;\n while (true) {\n s = this.selector();\n if (!s) {\n break;\n }\n if (selectors) {\n selectors.push(s);\n } else {\n selectors = [ s ];\n }\n parserInput.commentStore.length = 0;\n if (s.condition && selectors.length > 1) {\n error(\"Guards are only currently allowed on a single selector.\");\n }\n if (!parserInput.$char(',')) { break; }\n if (s.condition) {\n error(\"Guards are only currently allowed on a single selector.\");\n }\n parserInput.commentStore.length = 0;\n }\n return selectors;\n },\n attribute: function () {\n if (!parserInput.$char('[')) { return; }\n\n const entities = this.entities;\n let key;\n let val;\n let op;\n\n if (!(key = entities.variableCurly())) {\n key = expect(/^(?:[_A-Za-z0-9-\\*]*\\|)?(?:[_A-Za-z0-9-]|\\\\.)+/);\n }\n\n op = parserInput.$re(/^[|~*$^]?=/);\n if (op) {\n val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\\w-]+/) || entities.variableCurly();\n }\n\n expectChar(']');\n\n return new(tree.Attribute)(key, op, val);\n },\n\n //\n // The `block` rule is used by `ruleset` and `mixin.definition`.\n // It's a wrapper around the `primary` rule, with added `{}`.\n //\n block: function () {\n let content;\n if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {\n return content;\n }\n },\n\n blockRuleset: function() {\n let block = this.block();\n\n if (block) {\n block = new tree.Ruleset(null, block);\n }\n return block;\n },\n\n detachedRuleset: function() {\n let argInfo;\n let params;\n let variadic;\n\n parserInput.save();\n if (parserInput.$re(/^[.#]\\(/)) {\n /**\n * DR args currently only implemented for each() function, and not \n * yet settable as `@dr: #(@arg) {}`\n * This should be done when DRs are merged with mixins.\n * See: https://github.com/less/less-meta/issues/16\n */\n argInfo = this.mixin.args(false);\n params = argInfo.args;\n variadic = argInfo.variadic;\n if (!parserInput.$char(')')) {\n parserInput.restore();\n return;\n }\n }\n const blockRuleset = this.blockRuleset();\n if (blockRuleset) {\n parserInput.forget();\n if (params) {\n return new tree.mixin.Definition(null, params, blockRuleset, null, variadic);\n }\n return new tree.DetachedRuleset(blockRuleset);\n }\n parserInput.restore();\n },\n\n //\n // div, .class, body > p {...}\n //\n ruleset: function () {\n let selectors;\n let rules;\n let debugInfo;\n\n parserInput.save();\n\n if (context.dumpLineNumbers) {\n debugInfo = getDebugInfo(parserInput.i);\n }\n\n selectors = this.selectors();\n\n if (selectors && (rules = this.block())) {\n parserInput.forget();\n const ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports);\n if (context.dumpLineNumbers) {\n ruleset.debugInfo = debugInfo;\n }\n return ruleset;\n } else {\n parserInput.restore();\n }\n },\n declaration: function () {\n let name;\n let value;\n const index = parserInput.i;\n let hasDR;\n const c = parserInput.currentChar();\n let important;\n let merge;\n let isVariable;\n\n if (c === '.' || c === '#' || c === '&' || c === ':') { return; }\n\n parserInput.save();\n\n name = this.variable() || this.ruleProperty();\n if (name) {\n isVariable = typeof name === 'string';\n\n if (isVariable) {\n value = this.detachedRuleset();\n if (value) {\n hasDR = true;\n }\n }\n\n parserInput.commentStore.length = 0;\n if (!value) {\n // a name returned by this.ruleProperty() is always an array of the form:\n // [string-1, ..., string-n, \"\"] or [string-1, ..., string-n, \"+\"]\n // where each item is a tree.Keyword or tree.Variable\n merge = !isVariable && name.length > 1 && name.pop().value;\n\n // Custom property values get permissive parsing\n if (name[0].value && name[0].value.slice(0, 2) === '--') {\n value = this.permissiveValue();\n }\n // Try to store values as anonymous\n // If we need the value later we'll re-parse it in ruleset.parseValue\n else {\n value = this.anonymousValue();\n }\n if (value) {\n parserInput.forget();\n // anonymous values absorb the end ';' which is required for them to work\n return new(tree.Declaration)(name, value, false, merge, index, fileInfo);\n }\n\n if (!value) {\n value = this.value();\n }\n\n if (value) {\n important = this.important();\n } else if (isVariable) {\n // As a last resort, try permissiveValue\n value = this.permissiveValue();\n }\n }\n\n if (value && (this.end() || hasDR)) {\n parserInput.forget();\n return new(tree.Declaration)(name, value, important, merge, index, fileInfo);\n }\n else {\n parserInput.restore();\n }\n } else {\n parserInput.restore();\n }\n },\n anonymousValue: function () {\n const index = parserInput.i;\n const match = parserInput.$re(/^([^.#@\\$+\\/'\"*`(;{}-]*);/);\n if (match) {\n return new(tree.Anonymous)(match[1], index);\n }\n },\n /**\n * Used for custom properties, at-rules, and variables (as fallback)\n * Parses almost anything inside of {} [] () \"\" blocks\n * until it reaches outer-most tokens.\n * \n * First, it will try to parse comments and entities to reach\n * the end. This is mostly like the Expression parser except no\n * math is allowed.\n */\n permissiveValue: function (untilTokens) {\n let i;\n let e;\n let done;\n let value;\n const tok = untilTokens || ';';\n const index = parserInput.i;\n const result = [];\n\n function testCurrentChar() {\n const char = parserInput.currentChar();\n if (typeof tok === 'string') {\n return char === tok;\n } else {\n return tok.test(char);\n }\n }\n if (testCurrentChar()) {\n return;\n }\n value = [];\n do {\n e = this.comment();\n if (e) {\n value.push(e);\n continue;\n }\n e = this.entity();\n if (e) {\n value.push(e);\n }\n } while (e);\n\n done = testCurrentChar();\n\n if (value.length > 0) {\n value = new(tree.Expression)(value);\n if (done) {\n return value;\n }\n else {\n result.push(value);\n }\n // Preserve space before $parseUntil as it will not\n if (parserInput.prevChar() === ' ') {\n result.push(new tree.Anonymous(' ', index));\n }\n }\n parserInput.save();\n\n value = parserInput.$parseUntil(tok);\n\n if (value) {\n if (typeof value === 'string') {\n error(`Expected '${value}'`, 'Parse');\n }\n if (value.length === 1 && value[0] === ' ') {\n parserInput.forget();\n return new tree.Anonymous('', index);\n }\n let item;\n for (i = 0; i < value.length; i++) {\n item = value[i];\n if (Array.isArray(item)) {\n // Treat actual quotes as normal quoted values\n result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));\n }\n else {\n if (i === value.length - 1) {\n item = item.trim();\n }\n // Treat like quoted values, but replace vars like unquoted expressions\n const quote = new tree.Quoted('\\'', item, true, index, fileInfo);\n quote.variableRegex = /@([\\w-]+)/g;\n quote.propRegex = /\\$([\\w-]+)/g;\n result.push(quote);\n }\n }\n parserInput.forget();\n return new tree.Expression(result, true);\n }\n parserInput.restore();\n },\n\n //\n // An @import atrule\n //\n // @import \"lib\";\n //\n // Depending on our environment, importing is done differently:\n // In the browser, it's an XHR request, in Node, it would be a\n // file-system operation. The function used for importing is\n // stored in `import`, which we pass to the Import constructor.\n //\n 'import': function () {\n let path;\n let features;\n const index = parserInput.i;\n\n const dir = parserInput.$re(/^@import?\\s+/);\n\n if (dir) {\n const options = (dir ? this.importOptions() : null) || {};\n\n if ((path = this.entities.quoted() || this.entities.url())) {\n features = this.mediaFeatures();\n\n if (!parserInput.$char(';')) {\n parserInput.i = index;\n error('missing semi-colon or unrecognised media features on import');\n }\n features = features && new(tree.Value)(features);\n return new(tree.Import)(path, features, options, index, fileInfo);\n }\n else {\n parserInput.i = index;\n error('malformed import statement');\n }\n }\n },\n\n importOptions: function() {\n let o;\n const options = {};\n let optionName;\n let value;\n\n // list of options, surrounded by parens\n if (!parserInput.$char('(')) { return null; }\n do {\n o = this.importOption();\n if (o) {\n optionName = o;\n value = true;\n switch (optionName) {\n case 'css':\n optionName = 'less';\n value = false;\n break;\n case 'once':\n optionName = 'multiple';\n value = false;\n break;\n }\n options[optionName] = value;\n if (!parserInput.$char(',')) { break; }\n }\n } while (o);\n expectChar(')');\n return options;\n },\n\n importOption: function() {\n const opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);\n if (opt) {\n return opt[1];\n }\n },\n\n mediaFeature: function () {\n const entities = this.entities;\n const nodes = [];\n let e;\n let p;\n parserInput.save();\n do {\n e = entities.keyword() || entities.variable() || entities.mixinLookup();\n if (e) {\n nodes.push(e);\n } else if (parserInput.$char('(')) {\n p = this.property();\n e = this.value();\n if (parserInput.$char(')')) {\n if (p && e) {\n nodes.push(new(tree.Paren)(new(tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true)));\n } else if (e) {\n nodes.push(new(tree.Paren)(e));\n } else {\n error('badly formed media feature definition');\n }\n } else {\n error('Missing closing \\')\\'', 'Parse');\n }\n }\n } while (e);\n\n parserInput.forget();\n if (nodes.length > 0) {\n return new(tree.Expression)(nodes);\n }\n },\n\n mediaFeatures: function () {\n const entities = this.entities;\n const features = [];\n let e;\n do {\n e = this.mediaFeature();\n if (e) {\n features.push(e);\n if (!parserInput.$char(',')) { break; }\n } else {\n e = entities.variable() || entities.mixinLookup();\n if (e) {\n features.push(e);\n if (!parserInput.$char(',')) { break; }\n }\n }\n } while (e);\n\n return features.length > 0 ? features : null;\n },\n\n media: function () {\n let features;\n let rules;\n let media;\n let debugInfo;\n const index = parserInput.i;\n\n if (context.dumpLineNumbers) {\n debugInfo = getDebugInfo(index);\n }\n\n parserInput.save();\n\n if (parserInput.$str('@media')) {\n features = this.mediaFeatures();\n\n rules = this.block();\n\n if (!rules) {\n error('media definitions require block statements after any features');\n }\n\n parserInput.forget();\n\n media = new(tree.Media)(rules, features, index, fileInfo);\n if (context.dumpLineNumbers) {\n media.debugInfo = debugInfo;\n }\n\n return media;\n }\n\n parserInput.restore();\n },\n\n //\n\n // A @plugin directive, used to import plugins dynamically.\n //\n // @plugin (args) \"lib\";\n //\n plugin: function () {\n let path;\n let args;\n let options;\n const index = parserInput.i;\n const dir = parserInput.$re(/^@plugin?\\s+/);\n\n if (dir) {\n args = this.pluginArgs();\n\n if (args) {\n options = {\n pluginArgs: args,\n isPlugin: true\n };\n }\n else {\n options = { isPlugin: true };\n }\n\n if ((path = this.entities.quoted() || this.entities.url())) {\n\n if (!parserInput.$char(';')) {\n parserInput.i = index;\n error('missing semi-colon on @plugin');\n }\n return new(tree.Import)(path, null, options, index, fileInfo);\n }\n else {\n parserInput.i = index;\n error('malformed @plugin statement');\n }\n }\n },\n\n pluginArgs: function() {\n // list of options, surrounded by parens\n parserInput.save();\n if (!parserInput.$char('(')) {\n parserInput.restore();\n return null;\n }\n const args = parserInput.$re(/^\\s*([^\\);]+)\\)\\s*/);\n if (args[1]) {\n parserInput.forget();\n return args[1].trim();\n }\n else { \n parserInput.restore();\n return null;\n }\n },\n\n //\n // A CSS AtRule\n //\n // @charset \"utf-8\";\n //\n atrule: function () {\n const index = parserInput.i;\n let name;\n let value;\n let rules;\n let nonVendorSpecificName;\n let hasIdentifier;\n let hasExpression;\n let hasUnknown;\n let hasBlock = true;\n let isRooted = true;\n\n if (parserInput.currentChar() !== '@') { return; }\n\n value = this['import']() || this.plugin() || this.media();\n if (value) {\n return value;\n }\n\n parserInput.save();\n\n name = parserInput.$re(/^@[a-z-]+/);\n\n if (!name) { return; }\n\n nonVendorSpecificName = name;\n if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {\n nonVendorSpecificName = `@${name.slice(name.indexOf('-', 2) + 1)}`;\n }\n\n switch (nonVendorSpecificName) {\n case '@charset':\n hasIdentifier = true;\n hasBlock = false;\n break;\n case '@namespace':\n hasExpression = true;\n hasBlock = false;\n break;\n case '@keyframes':\n case '@counter-style':\n hasIdentifier = true;\n break;\n case '@document':\n case '@supports':\n hasUnknown = true;\n isRooted = false;\n break;\n default:\n hasUnknown = true;\n break;\n }\n\n parserInput.commentStore.length = 0;\n\n if (hasIdentifier) {\n value = this.entity();\n if (!value) {\n error(`expected ${name} identifier`);\n }\n } else if (hasExpression) {\n value = this.expression();\n if (!value) {\n error(`expected ${name} expression`);\n }\n } else if (hasUnknown) {\n value = this.permissiveValue(/^[{;]/);\n hasBlock = (parserInput.currentChar() === '{');\n if (!value) {\n if (!hasBlock && parserInput.currentChar() !== ';') {\n error(`${name} rule is missing block or ending semi-colon`);\n }\n }\n else if (!value.value) {\n value = null;\n }\n }\n\n if (hasBlock) {\n rules = this.blockRuleset();\n }\n\n if (rules || (!hasBlock && value && parserInput.$char(';'))) {\n parserInput.forget();\n return new(tree.AtRule)(name, value, rules, index, fileInfo,\n context.dumpLineNumbers ? getDebugInfo(index) : null,\n isRooted\n );\n }\n\n parserInput.restore('at-rule options not recognised');\n },\n\n //\n // A Value is a comma-delimited list of Expressions\n //\n // font-family: Baskerville, Georgia, serif;\n //\n // In a Rule, a Value represents everything after the `:`,\n // and before the `;`.\n //\n value: function () {\n let e;\n const expressions = [];\n const index = parserInput.i;\n\n do {\n e = this.expression();\n if (e) {\n expressions.push(e);\n if (!parserInput.$char(',')) { break; }\n }\n } while (e);\n\n if (expressions.length > 0) {\n return new(tree.Value)(expressions, index);\n }\n },\n important: function () {\n if (parserInput.currentChar() === '!') {\n return parserInput.$re(/^! *important/);\n }\n },\n sub: function () {\n let a;\n let e;\n\n parserInput.save();\n if (parserInput.$char('(')) {\n a = this.addition();\n if (a && parserInput.$char(')')) {\n parserInput.forget();\n e = new(tree.Expression)([a]);\n e.parens = true;\n return e;\n }\n parserInput.restore('Expected \\')\\'');\n return;\n }\n parserInput.restore();\n },\n multiplication: function () {\n let m;\n let a;\n let op;\n let operation;\n let isSpaced;\n m = this.operand();\n if (m) {\n isSpaced = parserInput.isWhitespace(-1);\n while (true) {\n if (parserInput.peek(/^\\/[*\\/]/)) {\n break;\n }\n\n parserInput.save();\n\n op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./');\n\n if (!op) { parserInput.forget(); break; }\n\n a = this.operand();\n\n if (!a) { parserInput.restore(); break; }\n parserInput.forget();\n\n m.parensInOp = true;\n a.parensInOp = true;\n operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n isSpaced = parserInput.isWhitespace(-1);\n }\n return operation || m;\n }\n },\n addition: function () {\n let m;\n let a;\n let op;\n let operation;\n let isSpaced;\n m = this.multiplication();\n if (m) {\n isSpaced = parserInput.isWhitespace(-1);\n while (true) {\n op = parserInput.$re(/^[-+]\\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));\n if (!op) {\n break;\n }\n a = this.multiplication();\n if (!a) {\n break;\n }\n\n m.parensInOp = true;\n a.parensInOp = true;\n operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n isSpaced = parserInput.isWhitespace(-1);\n }\n return operation || m;\n }\n },\n conditions: function () {\n let a;\n let b;\n const index = parserInput.i;\n let condition;\n\n a = this.condition(true);\n if (a) {\n while (true) {\n if (!parserInput.peek(/^,\\s*(not\\s*)?\\(/) || !parserInput.$char(',')) {\n break;\n }\n b = this.condition(true);\n if (!b) {\n break;\n }\n condition = new(tree.Condition)('or', condition || a, b, index);\n }\n return condition || a;\n }\n },\n condition: function (needsParens) {\n let result;\n let logical;\n let next;\n function or() {\n return parserInput.$str('or');\n }\n\n result = this.conditionAnd(needsParens);\n if (!result) {\n return ;\n }\n logical = or();\n if (logical) {\n next = this.condition(needsParens);\n if (next) {\n result = new(tree.Condition)(logical, result, next);\n } else {\n return ;\n }\n }\n return result;\n },\n conditionAnd: function (needsParens) {\n let result;\n let logical;\n let next;\n const self = this;\n function insideCondition() {\n const cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);\n if (!cond && !needsParens) {\n return self.atomicCondition(needsParens);\n }\n return cond;\n }\n function and() {\n return parserInput.$str('and');\n }\n\n result = insideCondition();\n if (!result) {\n return ;\n }\n logical = and();\n if (logical) {\n next = this.conditionAnd(needsParens);\n if (next) {\n result = new(tree.Condition)(logical, result, next);\n } else {\n return ;\n }\n }\n return result;\n },\n negatedCondition: function (needsParens) {\n if (parserInput.$str('not')) {\n const result = this.parenthesisCondition(needsParens);\n if (result) {\n result.negate = !result.negate;\n }\n return result;\n }\n },\n parenthesisCondition: function (needsParens) {\n function tryConditionFollowedByParenthesis(me) {\n let body;\n parserInput.save();\n body = me.condition(needsParens);\n if (!body) {\n parserInput.restore();\n return ;\n }\n if (!parserInput.$char(')')) {\n parserInput.restore();\n return ;\n }\n parserInput.forget();\n return body;\n }\n\n let body;\n parserInput.save();\n if (!parserInput.$str('(')) {\n parserInput.restore();\n return ;\n }\n body = tryConditionFollowedByParenthesis(this);\n if (body) {\n parserInput.forget();\n return body;\n }\n\n body = this.atomicCondition(needsParens);\n if (!body) {\n parserInput.restore();\n return ;\n }\n if (!parserInput.$char(')')) {\n parserInput.restore(`expected ')' got '${parserInput.currentChar()}'`);\n return ;\n }\n parserInput.forget();\n return body;\n },\n atomicCondition: function (needsParens) {\n const entities = this.entities;\n const index = parserInput.i;\n let a;\n let b;\n let c;\n let op;\n\n function cond() {\n return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();\n }\n cond = cond.bind(this);\n\n a = cond();\n if (a) {\n if (parserInput.$char('>')) {\n if (parserInput.$char('=')) {\n op = '>=';\n } else {\n op = '>';\n }\n } else\n if (parserInput.$char('<')) {\n if (parserInput.$char('=')) {\n op = '<=';\n } else {\n op = '<';\n }\n } else\n if (parserInput.$char('=')) {\n if (parserInput.$char('>')) {\n op = '=>';\n } else if (parserInput.$char('<')) {\n op = '=<';\n } else {\n op = '=';\n }\n }\n if (op) {\n b = cond();\n if (b) {\n c = new(tree.Condition)(op, a, b, index, false);\n } else {\n error('expected expression');\n }\n } else {\n c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, false);\n }\n return c;\n }\n },\n\n //\n // An operand is anything that can be part of an operation,\n // such as a Color, or a Variable\n //\n operand: function () {\n const entities = this.entities;\n let negate;\n\n if (parserInput.peek(/^-[@\\$\\(]/)) {\n negate = parserInput.$char('-');\n }\n\n let o = this.sub() || entities.dimension() ||\n entities.color() || entities.variable() ||\n entities.property() || entities.call() ||\n entities.quoted(true) || entities.colorKeyword() ||\n entities.mixinLookup();\n\n if (negate) {\n o.parensInOp = true;\n o = new(tree.Negative)(o);\n }\n\n return o;\n },\n\n //\n // Expressions either represent mathematical operations,\n // or white-space delimited Entities.\n //\n // 1px solid black\n // @var * 2\n //\n expression: function () {\n const entities = [];\n let e;\n let delim;\n const index = parserInput.i;\n\n do {\n e = this.comment();\n if (e) {\n entities.push(e);\n continue;\n }\n e = this.addition() || this.entity();\n if (e) {\n entities.push(e);\n // operations do not allow keyword \"/\" dimension (e.g. small/20px) so we support that here\n if (!parserInput.peek(/^\\/[\\/*]/)) {\n delim = parserInput.$char('/');\n if (delim) {\n entities.push(new(tree.Anonymous)(delim, index));\n }\n }\n }\n } while (e);\n if (entities.length > 0) {\n return new(tree.Expression)(entities);\n }\n },\n property: function () {\n const name = parserInput.$re(/^(\\*?-?[_a-zA-Z0-9-]+)\\s*:/);\n if (name) {\n return name[1];\n }\n },\n ruleProperty: function () {\n let name = [];\n const index = [];\n let s;\n let k;\n\n parserInput.save();\n\n const simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\\s*:/);\n if (simpleProperty) {\n name = [new(tree.Keyword)(simpleProperty[1])];\n parserInput.forget();\n return name;\n }\n\n function match(re) {\n const i = parserInput.i;\n const chunk = parserInput.$re(re);\n if (chunk) {\n index.push(i);\n return name.push(chunk[1]);\n }\n }\n\n match(/^(\\*?)/);\n while (true) {\n if (!match(/^((?:[\\w-]+)|(?:[@\\$]\\{[\\w-]+\\}))/)) {\n break;\n }\n }\n\n if ((name.length > 1) && match(/^((?:\\+_|\\+)?)\\s*:/)) {\n parserInput.forget();\n\n // at last, we have the complete match now. move forward,\n // convert name particles to tree objects and return:\n if (name[0] === '') {\n name.shift();\n index.shift();\n }\n for (k = 0; k < name.length; k++) {\n s = name[k];\n name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?\n new(tree.Keyword)(s) :\n (s.charAt(0) === '@' ?\n new(tree.Variable)(`@${s.slice(2, -1)}`, index[k], fileInfo) :\n new(tree.Property)(`$${s.slice(2, -1)}`, index[k], fileInfo));\n }\n return name;\n }\n parserInput.restore();\n }\n }\n };\n};\nParser.serializeVars = vars => {\n let s = '';\n\n for (const name in vars) {\n if (Object.hasOwnProperty.call(vars, name)) {\n const value = vars[name];\n s += `${((name[0] === '@') ? '' : '@') + name}: ${value}${(String(value).slice(-1) === ';') ? '' : ';'}`;\n }\n }\n\n return s;\n};\n\nexport default Parser;\n","import Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nlet colorFunctions;\n\nfunction clamp(val) {\n return Math.min(1, Math.max(0, val));\n}\nfunction hsla(origColor, hsl) {\n const color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);\n if (color) {\n if (origColor.value && \n /^(rgb|hsl)/.test(origColor.value)) {\n color.value = origColor.value;\n } else {\n color.value = 'rgb';\n }\n return color;\n }\n}\nfunction toHSL(color) {\n if (color.toHSL) {\n return color.toHSL();\n } else {\n throw new Error('Argument cannot be evaluated to a color');\n }\n}\n\nfunction toHSV(color) {\n if (color.toHSV) {\n return color.toHSV();\n } else {\n throw new Error('Argument cannot be evaluated to a color');\n }\n}\n\nfunction number(n) {\n if (n instanceof Dimension) {\n return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);\n } else if (typeof n === 'number') {\n return n;\n } else {\n throw {\n type: 'Argument',\n message: 'color functions take numbers as parameters'\n };\n }\n}\nfunction scaled(n, size) {\n if (n instanceof Dimension && n.unit.is('%')) {\n return parseFloat(n.value * size / 100);\n } else {\n return number(n);\n }\n}\ncolorFunctions = {\n rgb: function (r, g, b) {\n const color = colorFunctions.rgba(r, g, b, 1.0);\n if (color) {\n color.value = 'rgb';\n return color;\n }\n },\n rgba: function (r, g, b, a) {\n try {\n if (r instanceof Color) {\n if (g) {\n a = number(g);\n } else {\n a = r.alpha;\n }\n return new Color(r.rgb, a, 'rgba');\n }\n const rgb = [r, g, b].map(c => scaled(c, 255));\n a = number(a);\n return new Color(rgb, a, 'rgba');\n }\n catch (e) {}\n },\n hsl: function (h, s, l) {\n const color = colorFunctions.hsla(h, s, l, 1.0);\n if (color) {\n color.value = 'hsl';\n return color;\n }\n },\n hsla: function (h, s, l, a) {\n try {\n if (h instanceof Color) {\n if (s) {\n a = number(s);\n } else {\n a = h.alpha;\n }\n return new Color(h.rgb, a, 'hsla');\n }\n\n let m1;\n let m2;\n\n function hue(h) {\n h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);\n if (h * 6 < 1) {\n return m1 + (m2 - m1) * h * 6;\n }\n else if (h * 2 < 1) {\n return m2;\n }\n else if (h * 3 < 2) {\n return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n }\n else {\n return m1;\n }\n }\n\n h = (number(h) % 360) / 360;\n s = clamp(number(s));l = clamp(number(l));a = clamp(number(a));\n\n m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n m1 = l * 2 - m2;\n\n const rgb = [\n hue(h + 1 / 3) * 255,\n hue(h) * 255,\n hue(h - 1 / 3) * 255\n ];\n a = number(a);\n return new Color(rgb, a, 'hsla');\n }\n catch (e) {}\n },\n\n hsv: function(h, s, v) {\n return colorFunctions.hsva(h, s, v, 1.0);\n },\n\n hsva: function(h, s, v, a) {\n h = ((number(h) % 360) / 360) * 360;\n s = number(s);v = number(v);a = number(a);\n\n let i;\n let f;\n i = Math.floor((h / 60) % 6);\n f = (h / 60) - i;\n\n const vs = [v,\n v * (1 - s),\n v * (1 - f * s),\n v * (1 - (1 - f) * s)];\n const perm = [[0, 3, 1],\n [2, 0, 1],\n [1, 0, 3],\n [1, 2, 0],\n [3, 1, 0],\n [0, 1, 2]];\n\n return colorFunctions.rgba(vs[perm[i][0]] * 255,\n vs[perm[i][1]] * 255,\n vs[perm[i][2]] * 255,\n a);\n },\n\n hue: function (color) {\n return new Dimension(toHSL(color).h);\n },\n saturation: function (color) {\n return new Dimension(toHSL(color).s * 100, '%');\n },\n lightness: function (color) {\n return new Dimension(toHSL(color).l * 100, '%');\n },\n hsvhue: function(color) {\n return new Dimension(toHSV(color).h);\n },\n hsvsaturation: function (color) {\n return new Dimension(toHSV(color).s * 100, '%');\n },\n hsvvalue: function (color) {\n return new Dimension(toHSV(color).v * 100, '%');\n },\n red: function (color) {\n return new Dimension(color.rgb[0]);\n },\n green: function (color) {\n return new Dimension(color.rgb[1]);\n },\n blue: function (color) {\n return new Dimension(color.rgb[2]);\n },\n alpha: function (color) {\n return new Dimension(toHSL(color).a);\n },\n luma: function (color) {\n return new Dimension(color.luma() * color.alpha * 100, '%');\n },\n luminance: function (color) {\n const luminance =\n (0.2126 * color.rgb[0] / 255) +\n (0.7152 * color.rgb[1] / 255) +\n (0.0722 * color.rgb[2] / 255);\n\n return new Dimension(luminance * color.alpha * 100, '%');\n },\n saturate: function (color, amount, method) {\n // filter: saturate(3.2);\n // should be kept as is, so check for color\n if (!color.rgb) {\n return null;\n }\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.s += hsl.s * amount.value / 100;\n }\n else {\n hsl.s += amount.value / 100;\n }\n hsl.s = clamp(hsl.s);\n return hsla(color, hsl);\n },\n desaturate: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.s -= hsl.s * amount.value / 100;\n }\n else {\n hsl.s -= amount.value / 100;\n }\n hsl.s = clamp(hsl.s);\n return hsla(color, hsl);\n },\n lighten: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.l += hsl.l * amount.value / 100;\n }\n else {\n hsl.l += amount.value / 100;\n }\n hsl.l = clamp(hsl.l);\n return hsla(color, hsl);\n },\n darken: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.l -= hsl.l * amount.value / 100;\n }\n else {\n hsl.l -= amount.value / 100;\n }\n hsl.l = clamp(hsl.l);\n return hsla(color, hsl);\n },\n fadein: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.a += hsl.a * amount.value / 100;\n }\n else {\n hsl.a += amount.value / 100;\n }\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n fadeout: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.a -= hsl.a * amount.value / 100;\n }\n else {\n hsl.a -= amount.value / 100;\n }\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n fade: function (color, amount) {\n const hsl = toHSL(color);\n\n hsl.a = amount.value / 100;\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n spin: function (color, amount) {\n const hsl = toHSL(color);\n const hue = (hsl.h + amount.value) % 360;\n\n hsl.h = hue < 0 ? 360 + hue : hue;\n\n return hsla(color, hsl);\n },\n //\n // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein\n // http://sass-lang.com\n //\n mix: function (color1, color2, weight) {\n if (!weight) {\n weight = new Dimension(50);\n }\n const p = weight.value / 100.0;\n const w = p * 2 - 1;\n const a = toHSL(color1).a - toHSL(color2).a;\n\n const w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n const w2 = 1 - w1;\n\n const rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,\n color1.rgb[1] * w1 + color2.rgb[1] * w2,\n color1.rgb[2] * w1 + color2.rgb[2] * w2];\n\n const alpha = color1.alpha * p + color2.alpha * (1 - p);\n\n return new Color(rgb, alpha);\n },\n greyscale: function (color) {\n return colorFunctions.desaturate(color, new Dimension(100));\n },\n contrast: function (color, dark, light, threshold) {\n // filter: contrast(3.2);\n // should be kept as is, so check for color\n if (!color.rgb) {\n return null;\n }\n if (typeof light === 'undefined') {\n light = colorFunctions.rgba(255, 255, 255, 1.0);\n }\n if (typeof dark === 'undefined') {\n dark = colorFunctions.rgba(0, 0, 0, 1.0);\n }\n // Figure out which is actually light and dark:\n if (dark.luma() > light.luma()) {\n const t = light;\n light = dark;\n dark = t;\n }\n if (typeof threshold === 'undefined') {\n threshold = 0.43;\n } else {\n threshold = number(threshold);\n }\n if (color.luma() < threshold) {\n return light;\n } else {\n return dark;\n }\n },\n // Changes made in 2.7.0 - Reverted in 3.0.0\n // contrast: function (color, color1, color2, threshold) {\n // // Return which of `color1` and `color2` has the greatest contrast with `color`\n // // according to the standard WCAG contrast ratio calculation.\n // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n // // The threshold param is no longer used, in line with SASS.\n // // filter: contrast(3.2);\n // // should be kept as is, so check for color\n // if (!color.rgb) {\n // return null;\n // }\n // if (typeof color1 === 'undefined') {\n // color1 = colorFunctions.rgba(0, 0, 0, 1.0);\n // }\n // if (typeof color2 === 'undefined') {\n // color2 = colorFunctions.rgba(255, 255, 255, 1.0);\n // }\n // var contrast1, contrast2;\n // var luma = color.luma();\n // var luma1 = color1.luma();\n // var luma2 = color2.luma();\n // // Calculate contrast ratios for each color\n // if (luma > luma1) {\n // contrast1 = (luma + 0.05) / (luma1 + 0.05);\n // } else {\n // contrast1 = (luma1 + 0.05) / (luma + 0.05);\n // }\n // if (luma > luma2) {\n // contrast2 = (luma + 0.05) / (luma2 + 0.05);\n // } else {\n // contrast2 = (luma2 + 0.05) / (luma + 0.05);\n // }\n // if (contrast1 > contrast2) {\n // return color1;\n // } else {\n // return color2;\n // }\n // },\n argb: function (color) {\n return new Anonymous(color.toARGB());\n },\n color: function(c) {\n if ((c instanceof Quoted) &&\n (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {\n const val = c.value.slice(1);\n return new Color(val, undefined, `#${val}`);\n }\n if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {\n c.value = undefined;\n return c;\n }\n throw {\n type: 'Argument',\n message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'\n };\n },\n tint: function(color, amount) {\n return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);\n },\n shade: function(color, amount) {\n return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);\n }\n};\n\nexport default colorFunctions;\n","import Anonymous from '../tree/anonymous';\nimport Keyword from '../tree/keyword';\n\nfunction boolean(condition) {\n return condition ? Keyword.True : Keyword.False;\n}\n\nfunction If(condition, trueValue, falseValue) {\n return condition ? trueValue\n : (falseValue || new Anonymous);\n}\n\nexport default { boolean, 'if': If };\n","import Color from '../tree/color';\n\n// Color Blending\n// ref: http://www.w3.org/TR/compositing-1\n\nfunction colorBlend(mode, color1, color2) {\n const ab = color1.alpha; // result\n\n let // backdrop\n cb;\n\n const as = color2.alpha;\n\n let // source\n cs;\n\n let ar;\n let cr;\n const r = [];\n\n ar = as + ab * (1 - as);\n for (let i = 0; i < 3; i++) {\n cb = color1.rgb[i] / 255;\n cs = color2.rgb[i] / 255;\n cr = mode(cb, cs);\n if (ar) {\n cr = (as * cs + ab * (cb -\n as * (cb + cs - cr))) / ar;\n }\n r[i] = cr * 255;\n }\n\n return new Color(r, ar);\n}\n\nconst colorBlendModeFunctions = {\n multiply: function(cb, cs) {\n return cb * cs;\n },\n screen: function(cb, cs) {\n return cb + cs - cb * cs;\n },\n overlay: function(cb, cs) {\n cb *= 2;\n return (cb <= 1) ?\n colorBlendModeFunctions.multiply(cb, cs) :\n colorBlendModeFunctions.screen(cb - 1, cs);\n },\n softlight: function(cb, cs) {\n let d = 1;\n let e = cb;\n if (cs > 0.5) {\n e = 1;\n d = (cb > 0.25) ? Math.sqrt(cb)\n : ((16 * cb - 12) * cb + 4) * cb;\n }\n return cb - (1 - 2 * cs) * e * (d - cb);\n },\n hardlight: function(cb, cs) {\n return colorBlendModeFunctions.overlay(cs, cb);\n },\n difference: function(cb, cs) {\n return Math.abs(cb - cs);\n },\n exclusion: function(cb, cs) {\n return cb + cs - 2 * cb * cs;\n },\n\n // non-w3c functions:\n average: function(cb, cs) {\n return (cb + cs) / 2;\n },\n negation: function(cb, cs) {\n return 1 - Math.abs(cb + cs - 1);\n }\n};\n\nfor (const f in colorBlendModeFunctions) {\n if (colorBlendModeFunctions.hasOwnProperty(f)) {\n colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);\n }\n}\n\nexport default colorBlend;\n","import Comment from '../tree/comment';\nimport Dimension from '../tree/dimension';\nimport Declaration from '../tree/declaration';\nimport Expression from '../tree/expression';\nimport Ruleset from '../tree/ruleset';\nimport Selector from '../tree/selector';\nimport Element from '../tree/element';\nimport Quote from '../tree/quoted';\n\nconst getItemsFromNode = node => {\n // handle non-array values as an array of length 1\n // return 'undefined' if index is invalid\n const items = Array.isArray(node.value) ?\n node.value : Array(node);\n\n return items;\n};\n\nexport default {\n _SELF: function(n) {\n return n;\n },\n extract: function(values, index) {\n // (1-based index)\n index = index.value - 1;\n\n return getItemsFromNode(values)[index];\n },\n length: function(values) {\n return new Dimension(getItemsFromNode(values).length);\n },\n /**\n * Creates a Less list of incremental values.\n * Modeled after Lodash's range function, also exists natively in PHP\n * \n * @param {Dimension} [start=1]\n * @param {Dimension} end - e.g. 10 or 10px - unit is added to output\n * @param {Dimension} [step=1] \n */\n range: function(start, end, step) {\n let from;\n let to;\n let stepValue = 1;\n const list = [];\n if (end) {\n to = end;\n from = start.value;\n if (step) {\n stepValue = step.value;\n }\n }\n else {\n from = 1;\n to = start;\n }\n\n for (let i = from; i <= to.value; i += stepValue) {\n list.push(new Dimension(i, to.unit));\n }\n\n return new Expression(list);\n },\n each: function(list, rs) {\n const rules = [];\n let newRules;\n let iterator;\n\n if (list.value && !(list instanceof Quote)) {\n if (Array.isArray(list.value)) {\n iterator = list.value;\n } else {\n iterator = [list.value];\n }\n } else if (list.ruleset) {\n iterator = list.ruleset.rules;\n } else if (list.rules) {\n iterator = list.rules;\n } else if (Array.isArray(list)) {\n iterator = list;\n } else {\n iterator = [list];\n }\n\n let valueName = '@value';\n let keyName = '@key';\n let indexName = '@index';\n\n if (rs.params) {\n valueName = rs.params[0] && rs.params[0].name;\n keyName = rs.params[1] && rs.params[1].name;\n indexName = rs.params[2] && rs.params[2].name;\n rs = rs.rules;\n } else {\n rs = rs.ruleset;\n }\n\n for (let i = 0; i < iterator.length; i++) {\n let key;\n let value;\n const item = iterator[i];\n if (item instanceof Declaration) {\n key = typeof item.name === 'string' ? item.name : item.name[0].value;\n value = item.value;\n } else {\n key = new Dimension(i + 1);\n value = item;\n }\n\n if (item instanceof Comment) {\n continue;\n }\n\n newRules = rs.rules.slice(0);\n if (valueName) {\n newRules.push(new Declaration(valueName,\n value,\n false, false, this.index, this.currentFileInfo));\n }\n if (indexName) {\n newRules.push(new Declaration(indexName,\n new Dimension(i + 1),\n false, false, this.index, this.currentFileInfo));\n }\n if (keyName) {\n newRules.push(new Declaration(keyName,\n key,\n false, false, this.index, this.currentFileInfo));\n }\n\n rules.push(new Ruleset([ new(Selector)([ new Element(\"\", '&') ]) ],\n newRules,\n rs.strictImports,\n rs.visibilityInfo()\n ));\n }\n\n return new Ruleset([ new(Selector)([ new Element(\"\", '&') ]) ],\n rules,\n rs.strictImports,\n rs.visibilityInfo()\n ).eval(this.context);\n }\n};\n","import Dimension from '../tree/dimension';\n\nconst MathHelper = (fn, unit, n) => {\n if (!(n instanceof Dimension)) {\n throw { type: 'Argument', message: 'argument must be a number' };\n }\n if (unit == null) {\n unit = n.unit;\n } else {\n n = n.unify();\n }\n return new Dimension(fn(parseFloat(n.value)), unit);\n};\n\nexport default MathHelper;","import mathHelper from './math-helper.js';\n\nconst mathFunctions = {\n // name, unit\n ceil: null,\n floor: null,\n sqrt: null,\n abs: null,\n tan: '',\n sin: '',\n cos: '',\n atan: 'rad',\n asin: 'rad',\n acos: 'rad'\n};\n\nfor (const f in mathFunctions) {\n if (mathFunctions.hasOwnProperty(f)) {\n mathFunctions[f] = mathHelper.bind(null, Math[f], mathFunctions[f]);\n }\n}\n\nmathFunctions.round = (n, f) => {\n const fraction = typeof f === 'undefined' ? 0 : f.value;\n return mathHelper(num => num.toFixed(fraction), null, n);\n};\n\nexport default mathFunctions;\n","import Dimension from '../tree/dimension';\nimport Anonymous from '../tree/anonymous';\nimport mathHelper from './math-helper.js';\n\nconst minMax = function (isMin, args) {\n args = Array.prototype.slice.call(args);\n switch (args.length) {\n case 0: throw { type: 'Argument', message: 'one or more arguments required' };\n }\n let i; // key is the unit.toString() for unified Dimension values,\n let j;\n let current;\n let currentUnified;\n let referenceUnified;\n let unit;\n let unitStatic;\n let unitClone;\n\n const // elems only contains original argument values.\n order = [];\n\n const values = {};\n // value is the index into the order array.\n for (i = 0; i < args.length; i++) {\n current = args[i];\n if (!(current instanceof Dimension)) {\n if (Array.isArray(args[i].value)) {\n Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));\n }\n continue;\n }\n currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();\n unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();\n unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;\n unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;\n j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];\n if (j === undefined) {\n if (unitStatic !== undefined && unit !== unitStatic) {\n throw { type: 'Argument', message: 'incompatible types' };\n }\n values[unit] = order.length;\n order.push(current);\n continue;\n }\n referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();\n if ( isMin && currentUnified.value < referenceUnified.value ||\n !isMin && currentUnified.value > referenceUnified.value) {\n order[j] = current;\n }\n }\n if (order.length == 1) {\n return order[0];\n }\n args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');\n return new Anonymous(`${isMin ? 'min' : 'max'}(${args})`);\n};\n\nexport default {\n min: function(...args) {\n return minMax(true, args);\n },\n max: function(...args) {\n return minMax(false, args);\n },\n convert: function (val, unit) {\n return val.convertTo(unit.value);\n },\n pi: function () {\n return new Dimension(Math.PI);\n },\n mod: function(a, b) {\n return new Dimension(a.value % b.value, a.unit);\n },\n pow: function(x, y) {\n if (typeof x === 'number' && typeof y === 'number') {\n x = new Dimension(x);\n y = new Dimension(y);\n } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {\n throw { type: 'Argument', message: 'arguments must be numbers' };\n }\n\n return new Dimension(Math.pow(x.value, y.value), x.unit);\n },\n percentage: function (n) {\n const result = mathHelper(num => num * 100, '%', n);\n\n return result;\n }\n};\n","/**\n * Plugin Manager\n */\nclass PluginManager {\n constructor(less) {\n this.less = less;\n this.visitors = [];\n this.preProcessors = [];\n this.postProcessors = [];\n this.installedPlugins = [];\n this.fileManagers = [];\n this.iterator = -1;\n this.pluginCache = {};\n this.Loader = new less.PluginLoader(less);\n }\n\n /**\n * Adds all the plugins in the array\n * @param {Array} plugins\n */\n addPlugins(plugins) {\n if (plugins) {\n for (let i = 0; i < plugins.length; i++) {\n this.addPlugin(plugins[i]);\n }\n }\n }\n\n /**\n *\n * @param plugin\n * @param {String} filename\n */\n addPlugin(plugin, filename, functionRegistry) {\n this.installedPlugins.push(plugin);\n if (filename) {\n this.pluginCache[filename] = plugin;\n }\n if (plugin.install) {\n plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry);\n }\n }\n\n /**\n *\n * @param filename\n */\n get(filename) {\n return this.pluginCache[filename];\n }\n\n /**\n * Adds a visitor. The visitor object has options on itself to determine\n * when it should run.\n * @param visitor\n */\n addVisitor(visitor) {\n this.visitors.push(visitor);\n }\n\n /**\n * Adds a pre processor object\n * @param {object} preProcessor\n * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import\n */\n addPreProcessor(preProcessor, priority) {\n let indexToInsertAt;\n for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {\n if (this.preProcessors[indexToInsertAt].priority >= priority) {\n break;\n }\n }\n this.preProcessors.splice(indexToInsertAt, 0, {preProcessor, priority});\n }\n\n /**\n * Adds a post processor object\n * @param {object} postProcessor\n * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression\n */\n addPostProcessor(postProcessor, priority) {\n let indexToInsertAt;\n for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {\n if (this.postProcessors[indexToInsertAt].priority >= priority) {\n break;\n }\n }\n this.postProcessors.splice(indexToInsertAt, 0, {postProcessor, priority});\n }\n\n /**\n *\n * @param manager\n */\n addFileManager(manager) {\n this.fileManagers.push(manager);\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getPreProcessors() {\n const preProcessors = [];\n for (let i = 0; i < this.preProcessors.length; i++) {\n preProcessors.push(this.preProcessors[i].preProcessor);\n }\n return preProcessors;\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getPostProcessors() {\n const postProcessors = [];\n for (let i = 0; i < this.postProcessors.length; i++) {\n postProcessors.push(this.postProcessors[i].postProcessor);\n }\n return postProcessors;\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getVisitors() {\n return this.visitors;\n }\n\n visitor() {\n const self = this;\n return {\n first: function() {\n self.iterator = -1;\n return self.visitors[self.iterator];\n },\n get: function() {\n self.iterator += 1;\n return self.visitors[self.iterator];\n }\n };\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getFileManagers() {\n return this.fileManagers;\n }\n}\n\nlet pm;\n\nfunction PluginManagerFactory(less, newFactory) {\n if (newFactory || !pm) {\n pm = new PluginManager(less);\n }\n return pm;\n};\n\n//\nexport default PluginManagerFactory;\n","import Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nimport JavaScript from '../tree/javascript';\n\nexport default {\n e: function (str) {\n return new Quoted('\"', str instanceof JavaScript ? str.evaluated : str.value, true);\n },\n escape: function (str) {\n return new Anonymous(\n encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')\n .replace(/\\(/g, '%28').replace(/\\)/g, '%29'));\n },\n replace: function (string, pattern, replacement, flags) {\n let result = string.value;\n replacement = (replacement.type === 'Quoted') ?\n replacement.value : replacement.toCSS();\n result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);\n return new Quoted(string.quote || '', result, string.escaped);\n },\n '%': function (string /* arg, arg, ... */) {\n const args = Array.prototype.slice.call(arguments, 1);\n let result = string.value;\n\n for (let i = 0; i < args.length; i++) {\n /* jshint loopfunc:true */\n result = result.replace(/%[sda]/i, token => {\n const value = ((args[i].type === 'Quoted') &&\n token.match(/s/i)) ? args[i].value : args[i].toCSS();\n return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;\n });\n }\n result = result.replace(/%%/g, '%');\n return new Quoted(string.quote || '', result, string.escaped);\n }\n};\n","import Keyword from '../tree/keyword';\nimport DetachedRuleset from '../tree/detached-ruleset';\nimport Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nimport URL from '../tree/url';\nimport Operation from '../tree/operation';\n\nconst isa = (n, Type) => (n instanceof Type) ? Keyword.True : Keyword.False;\nconst isunit = (n, unit) => {\n if (unit === undefined) {\n throw { type: 'Argument', message: 'missing the required second argument to isunit.' };\n }\n unit = typeof unit.value === 'string' ? unit.value : unit;\n if (typeof unit !== 'string') {\n throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };\n }\n return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;\n};\n\nexport default {\n isruleset: function (n) {\n return isa(n, DetachedRuleset);\n },\n iscolor: function (n) {\n return isa(n, Color);\n },\n isnumber: function (n) {\n return isa(n, Dimension);\n },\n isstring: function (n) {\n return isa(n, Quoted);\n },\n iskeyword: function (n) {\n return isa(n, Keyword);\n },\n isurl: function (n) {\n return isa(n, URL);\n },\n ispixel: function (n) {\n return isunit(n, 'px');\n },\n ispercentage: function (n) {\n return isunit(n, '%');\n },\n isem: function (n) {\n return isunit(n, 'em');\n },\n isunit,\n unit: function (val, unit) {\n if (!(val instanceof Dimension)) {\n throw { type: 'Argument',\n message: `the first argument to unit must be a number${val instanceof Operation ? '. Have you forgotten parenthesis?' : ''}` };\n }\n if (unit) {\n if (unit instanceof Keyword) {\n unit = unit.value;\n } else {\n unit = unit.toCSS();\n }\n } else {\n unit = '';\n }\n return new Dimension(val.value, unit);\n },\n 'get-unit': function (n) {\n return new Anonymous(n.unit);\n }\n};\n","import functionRegistry from './function-registry';\nimport functionCaller from './function-caller';\n\nimport boolean from './boolean';\nimport defaultFunc from './default';\nimport color from './color';\nimport colorBlending from './color-blending';\nimport dataUri from './data-uri';\nimport list from './list';\nimport math from './math';\nimport number from './number';\nimport string from './string';\nimport svg from './svg';\nimport types from './types';\n\nexport default environment => {\n const functions = { functionRegistry, functionCaller };\n\n // register functions\n functionRegistry.addMultiple(boolean);\n functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));\n functionRegistry.addMultiple(color);\n functionRegistry.addMultiple(colorBlending);\n functionRegistry.addMultiple(dataUri(environment));\n functionRegistry.addMultiple(list);\n functionRegistry.addMultiple(math);\n functionRegistry.addMultiple(number);\n functionRegistry.addMultiple(string);\n functionRegistry.addMultiple(svg(environment));\n functionRegistry.addMultiple(types);\n\n return functions;\n};\n","import Quoted from '../tree/quoted';\nimport URL from '../tree/url';\nimport * as utils from '../utils';\nimport logger from '../logger';\n\nexport default environment => {\n \n const fallback = (functionThis, node) => new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); \n\n return { 'data-uri': function(mimetypeNode, filePathNode) {\n\n if (!filePathNode) {\n filePathNode = mimetypeNode;\n mimetypeNode = null;\n }\n\n let mimetype = mimetypeNode && mimetypeNode.value;\n let filePath = filePathNode.value;\n const currentFileInfo = this.currentFileInfo;\n const currentDirectory = currentFileInfo.rewriteUrls ?\n currentFileInfo.currentDirectory : currentFileInfo.entryPath;\n\n const fragmentStart = filePath.indexOf('#');\n let fragment = '';\n if (fragmentStart !== -1) {\n fragment = filePath.slice(fragmentStart);\n filePath = filePath.slice(0, fragmentStart);\n }\n const context = utils.clone(this.context);\n context.rawBuffer = true;\n\n const fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);\n\n if (!fileManager) {\n return fallback(this, filePathNode);\n }\n\n let useBase64 = false;\n\n // detect the mimetype if not given\n if (!mimetypeNode) {\n\n mimetype = environment.mimeLookup(filePath);\n\n if (mimetype === 'image/svg+xml') {\n useBase64 = false;\n } else {\n // use base 64 unless it's an ASCII or UTF-8 format\n const charset = environment.charsetLookup(mimetype);\n useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;\n }\n if (useBase64) { mimetype += ';base64'; }\n }\n else {\n useBase64 = /;base64$/.test(mimetype);\n }\n\n const fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);\n if (!fileSync.contents) {\n logger.warn(`Skipped data-uri embedding of ${filePath} because file not found`);\n return fallback(this, filePathNode || mimetypeNode);\n }\n let buf = fileSync.contents;\n if (useBase64 && !environment.encodeBase64) {\n return fallback(this, filePathNode);\n }\n\n buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);\n\n const uri = `data:${mimetype},${buf}${fragment}`;\n\n return new URL(new Quoted(`\"${uri}\"`, uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n }};\n};\n","import Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Expression from '../tree/expression';\nimport Quoted from '../tree/quoted';\nimport URL from '../tree/url';\n\nexport default environment => {\n return { 'svg-gradient': function(direction) {\n let stops;\n let gradientDirectionSvg;\n let gradientType = 'linear';\n let rectangleDimension = 'x=\"0\" y=\"0\" width=\"1\" height=\"1\"';\n const renderEnv = {compress: false};\n let returner;\n const directionValue = direction.toCSS(renderEnv);\n let i;\n let color;\n let position;\n let positionValue;\n let alpha;\n\n function throwArgumentDescriptor() {\n throw { type: 'Argument',\n message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +\n ' end_color [end_position] or direction, color list' };\n }\n\n if (arguments.length == 2) {\n if (arguments[1].value.length < 2) {\n throwArgumentDescriptor();\n }\n stops = arguments[1].value;\n } else if (arguments.length < 3) {\n throwArgumentDescriptor();\n } else {\n stops = Array.prototype.slice.call(arguments, 1);\n }\n\n switch (directionValue) {\n case 'to bottom':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\"';\n break;\n case 'to right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"';\n break;\n case 'to bottom right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\"';\n break;\n case 'to top right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\"';\n break;\n case 'ellipse':\n case 'ellipse at center':\n gradientType = 'radial';\n gradientDirectionSvg = 'cx=\"50%\" cy=\"50%\" r=\"75%\"';\n rectangleDimension = 'x=\"-50\" y=\"-50\" width=\"101\" height=\"101\"';\n break;\n default:\n throw { type: 'Argument', message: 'svg-gradient direction must be \\'to bottom\\', \\'to right\\',' +\n ' \\'to bottom right\\', \\'to top right\\' or \\'ellipse at center\\'' };\n }\n returner = `<${gradientType}Gradient id=\"g\" ${gradientDirectionSvg}>`;\n\n for (i = 0; i < stops.length; i += 1) {\n if (stops[i] instanceof Expression) {\n color = stops[i].value[0];\n position = stops[i].value[1];\n } else {\n color = stops[i];\n position = undefined;\n }\n\n if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {\n throwArgumentDescriptor();\n }\n positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';\n alpha = color.alpha;\n returner += ``;\n }\n returner += ``;\n\n returner = encodeURIComponent(returner);\n\n returner = `data:image/svg+xml,${returner}`;\n return new URL(new Quoted(`'${returner}'`, returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n }};\n};\n","import contexts from './contexts';\nimport visitor from './visitors';\nimport tree from './tree';\n\nexport default (root, options = {}) => {\n let evaldRoot;\n let variables = options.variables;\n const evalEnv = new contexts.Eval(options);\n\n //\n // Allows setting variables with a hash, so:\n //\n // `{ color: new tree.Color('#f01') }` will become:\n //\n // new tree.Declaration('@color',\n // new tree.Value([\n // new tree.Expression([\n // new tree.Color('#f01')\n // ])\n // ])\n // )\n //\n if (typeof variables === 'object' && !Array.isArray(variables)) {\n variables = Object.keys(variables).map(k => {\n let value = variables[k];\n\n if (!(value instanceof tree.Value)) {\n if (!(value instanceof tree.Expression)) {\n value = new tree.Expression([value]);\n }\n value = new tree.Value([value]);\n }\n return new tree.Declaration(`@${k}`, value, false, null, 0);\n });\n evalEnv.frames = [new tree.Ruleset(null, variables)];\n }\n\n const visitors = [\n new visitor.JoinSelectorVisitor(),\n new visitor.MarkVisibleSelectorsVisitor(true),\n new visitor.ExtendVisitor(),\n new visitor.ToCSSVisitor({compress: Boolean(options.compress)})\n ];\n\n const preEvalVisitors = [];\n let v;\n let visitorIterator;\n\n /**\n * first() / get() allows visitors to be added while visiting\n * \n * @todo Add scoping for visitors just like functions for @plugin; right now they're global\n */\n if (options.pluginManager) {\n visitorIterator = options.pluginManager.visitor();\n for (var i = 0; i < 2; i++) {\n visitorIterator.first();\n while ((v = visitorIterator.get())) {\n if (v.isPreEvalVisitor) {\n if (i === 0 || preEvalVisitors.indexOf(v) === -1) {\n preEvalVisitors.push(v);\n v.run(root);\n }\n }\n else {\n if (i === 0 || visitors.indexOf(v) === -1) {\n if (v.isPreVisitor) {\n visitors.unshift(v);\n }\n else {\n visitors.push(v);\n }\n }\n }\n }\n }\n }\n\n evaldRoot = root.eval(evalEnv);\n\n for (var i = 0; i < visitors.length; i++) {\n visitors[i].run(evaldRoot);\n }\n\n // Run any remaining visitors added after eval pass\n if (options.pluginManager) {\n visitorIterator.first();\n while ((v = visitorIterator.get())) {\n if (visitors.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {\n v.run(evaldRoot);\n }\n }\n }\n\n return evaldRoot;\n};\n","/* global window, XMLHttpRequest */\n\nimport AbstractFileManager from '../less/environment/abstract-file-manager.js';\n\nlet options;\nlet logger;\nlet fileCache = {};\n\n// TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load\nclass FileManager extends AbstractFileManager {\n alwaysMakePathsAbsolute() {\n return true;\n }\n\n join(basePath, laterPath) {\n if (!basePath) {\n return laterPath;\n }\n return this.extractUrlParts(laterPath, basePath).path;\n }\n\n doXHR(url, type, callback, errback) {\n const xhr = new XMLHttpRequest();\n const async = options.isFileProtocol ? options.fileAsync : true;\n\n if (typeof xhr.overrideMimeType === 'function') {\n xhr.overrideMimeType('text/css');\n }\n logger.debug(`XHR: Getting '${url}'`);\n xhr.open('GET', url, async);\n xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');\n xhr.send(null);\n\n function handleResponse(xhr, callback, errback) {\n if (xhr.status >= 200 && xhr.status < 300) {\n callback(xhr.responseText,\n xhr.getResponseHeader('Last-Modified'));\n } else if (typeof errback === 'function') {\n errback(xhr.status, url);\n }\n }\n\n if (options.isFileProtocol && !options.fileAsync) {\n if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {\n callback(xhr.responseText);\n } else {\n errback(xhr.status, url);\n }\n } else if (async) {\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 4) {\n handleResponse(xhr, callback, errback);\n }\n };\n } else {\n handleResponse(xhr, callback, errback);\n }\n }\n\n supports() {\n return true;\n }\n\n clearFileCache() {\n fileCache = {};\n }\n\n loadFile(filename, currentDirectory, options, environment) {\n // TODO: Add prefix support like less-node?\n // What about multiple paths?\n\n if (currentDirectory && !this.isPathAbsolute(filename)) {\n filename = currentDirectory + filename;\n }\n\n filename = options.ext ? this.tryAppendExtension(filename, options.ext) : filename;\n\n options = options || {};\n\n // sheet may be set to the stylesheet for the initial load or a collection of properties including\n // some context variables for imports\n const hrefParts = this.extractUrlParts(filename, window.location.href);\n const href = hrefParts.url;\n const self = this;\n \n return new Promise((resolve, reject) => {\n if (options.useFileCache && fileCache[href]) {\n try {\n const lessText = fileCache[href];\n return resolve({ contents: lessText, filename: href, webInfo: { lastModified: new Date() }});\n } catch (e) {\n return reject({ filename: href, message: `Error loading file ${href} error was ${e.message}` });\n }\n }\n\n self.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {\n // per file cache\n fileCache[href] = data;\n\n // Use remote copy (re-parse)\n resolve({ contents: data, filename: href, webInfo: { lastModified }});\n }, function doXHRError(status, url) {\n reject({ type: 'File', message: `'${url}' wasn't found (${status})`, href });\n });\n });\n }\n}\n\nexport default (opts, log) => {\n options = opts;\n logger = log;\n return FileManager;\n}\n","import data from './data';\nimport tree from './tree';\nimport Environment from './environment/environment';\nimport AbstractFileManager from './environment/abstract-file-manager';\nimport AbstractPluginLoader from './environment/abstract-plugin-loader';\nimport visitors from './visitors';\nimport Parser from './parser/parser';\nimport Functions from './functions';\nimport contexts from './contexts';\nimport sourceMapOutput from './source-map-output';\nimport sourceMapBuilder from './source-map-builder';\nimport parseTree from './parse-tree';\nimport importManager from './import-manager';\nimport Render from './render';\nimport Parse from './parse';\nimport LessError from './less-error';\nimport transformTree from './transform-tree';\nimport * as utils from './utils';\nimport PluginManager from './plugin-manager';\nimport logger from './logger';\n\nexport default (environment, fileManagers) => {\n /**\n * @todo\n * This original code could be improved quite a bit.\n * Many classes / modules currently add side-effects / mutations to passed in objects,\n * which makes it hard to refactor and reason about. \n */\n environment = new Environment(environment, fileManagers);\n\n const SourceMapOutput = sourceMapOutput(environment);\n const SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment);\n const ParseTree = parseTree(SourceMapBuilder);\n const ImportManager = importManager(environment);\n const render = Render(environment, ParseTree, ImportManager);\n const parse = Parse(environment, ParseTree, ImportManager);\n const functions = Functions(environment);\n\n /**\n * @todo\n * This root properties / methods need to be organized.\n * It's not clear what should / must be public and why.\n */\n const initial = {\n version: [3, 10, 3],\n data,\n tree,\n Environment,\n AbstractFileManager,\n AbstractPluginLoader,\n environment,\n visitors,\n Parser,\n functions,\n contexts,\n SourceMapOutput,\n SourceMapBuilder,\n ParseTree,\n ImportManager,\n render,\n parse,\n LessError,\n transformTree,\n utils,\n PluginManager,\n logger\n };\n\n // Create a public API\n const ctor = t => function (...args) {\n return new t(...args);\n };\n\n let t;\n const api = Object.create(initial);\n for (const n in initial.tree) {\n /* eslint guard-for-in: 0 */\n t = initial.tree[n];\n if (typeof t === 'function') {\n api[n.toLowerCase()] = ctor(t);\n }\n else {\n api[n] = Object.create(null);\n for (const o in t) {\n /* eslint guard-for-in: 0 */\n api[n][o.toLowerCase()] = ctor(t[o]);\n }\n }\n }\n\n return api;\n};\n","export default environment => {\n class SourceMapOutput {\n constructor(options) {\n this._css = [];\n this._rootNode = options.rootNode;\n this._contentsMap = options.contentsMap;\n this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;\n if (options.sourceMapFilename) {\n this._sourceMapFilename = options.sourceMapFilename.replace(/\\\\/g, '/');\n }\n this._outputFilename = options.outputFilename;\n this.sourceMapURL = options.sourceMapURL;\n if (options.sourceMapBasepath) {\n this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\\\/g, '/');\n }\n if (options.sourceMapRootpath) {\n this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\\\/g, '/');\n if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {\n this._sourceMapRootpath += '/';\n }\n } else {\n this._sourceMapRootpath = '';\n }\n this._outputSourceFiles = options.outputSourceFiles;\n this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();\n\n this._lineNumber = 0;\n this._column = 0;\n }\n\n removeBasepath(path) {\n if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) {\n path = path.substring(this._sourceMapBasepath.length);\n if (path.charAt(0) === '\\\\' || path.charAt(0) === '/') {\n path = path.substring(1);\n }\n }\n\n return path;\n }\n\n normalizeFilename(filename) {\n filename = filename.replace(/\\\\/g, '/');\n filename = this.removeBasepath(filename);\n return (this._sourceMapRootpath || '') + filename;\n }\n\n add(chunk, fileInfo, index, mapLines) {\n // ignore adding empty strings\n if (!chunk) {\n return;\n }\n\n let lines;\n let sourceLines;\n let columns;\n let sourceColumns;\n let i;\n\n if (fileInfo && fileInfo.filename) {\n let inputSource = this._contentsMap[fileInfo.filename];\n\n // remove vars/banner added to the top of the file\n if (this._contentsIgnoredCharsMap[fileInfo.filename]) {\n // adjust the index\n index -= this._contentsIgnoredCharsMap[fileInfo.filename];\n if (index < 0) { index = 0; }\n // adjust the source\n inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);\n }\n\n // ignore empty content\n if (inputSource === undefined) {\n return;\n }\n\n inputSource = inputSource.substring(0, index);\n sourceLines = inputSource.split('\\n');\n sourceColumns = sourceLines[sourceLines.length - 1];\n }\n\n lines = chunk.split('\\n');\n columns = lines[lines.length - 1];\n\n if (fileInfo && fileInfo.filename) {\n if (!mapLines) {\n this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},\n original: { line: sourceLines.length, column: sourceColumns.length},\n source: this.normalizeFilename(fileInfo.filename)});\n } else {\n for (i = 0; i < lines.length; i++) {\n this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},\n original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},\n source: this.normalizeFilename(fileInfo.filename)});\n }\n }\n }\n\n if (lines.length === 1) {\n this._column += columns.length;\n } else {\n this._lineNumber += lines.length - 1;\n this._column = columns.length;\n }\n\n this._css.push(chunk);\n }\n\n isEmpty() {\n return this._css.length === 0;\n }\n\n toCSS(context) {\n this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });\n\n if (this._outputSourceFiles) {\n for (const filename in this._contentsMap) {\n if (this._contentsMap.hasOwnProperty(filename)) {\n let source = this._contentsMap[filename];\n if (this._contentsIgnoredCharsMap[filename]) {\n source = source.slice(this._contentsIgnoredCharsMap[filename]);\n }\n this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);\n }\n }\n }\n\n this._rootNode.genCSS(context, this);\n\n if (this._css.length > 0) {\n let sourceMapURL;\n const sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());\n\n if (this.sourceMapURL) {\n sourceMapURL = this.sourceMapURL;\n } else if (this._sourceMapFilename) {\n sourceMapURL = this._sourceMapFilename;\n }\n this.sourceMapURL = sourceMapURL;\n\n this.sourceMap = sourceMapContent;\n }\n\n return this._css.join('');\n }\n }\n\n return SourceMapOutput;\n};\n","export default (SourceMapOutput, environment) => {\n class SourceMapBuilder {\n constructor(options) {\n this.options = options;\n }\n\n toCSS(rootNode, options, imports) {\n const sourceMapOutput = new SourceMapOutput(\n {\n contentsIgnoredCharsMap: imports.contentsIgnoredChars,\n rootNode,\n contentsMap: imports.contents,\n sourceMapFilename: this.options.sourceMapFilename,\n sourceMapURL: this.options.sourceMapURL,\n outputFilename: this.options.sourceMapOutputFilename,\n sourceMapBasepath: this.options.sourceMapBasepath,\n sourceMapRootpath: this.options.sourceMapRootpath,\n outputSourceFiles: this.options.outputSourceFiles,\n sourceMapGenerator: this.options.sourceMapGenerator,\n sourceMapFileInline: this.options.sourceMapFileInline\n });\n\n const css = sourceMapOutput.toCSS(options);\n this.sourceMap = sourceMapOutput.sourceMap;\n this.sourceMapURL = sourceMapOutput.sourceMapURL;\n if (this.options.sourceMapInputFilename) {\n this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);\n }\n if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {\n this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);\n }\n return css + this.getCSSAppendage();\n }\n\n getCSSAppendage() {\n\n let sourceMapURL = this.sourceMapURL;\n if (this.options.sourceMapFileInline) {\n if (this.sourceMap === undefined) {\n return '';\n }\n sourceMapURL = `data:application/json;base64,${environment.encodeBase64(this.sourceMap)}`;\n }\n\n if (sourceMapURL) {\n return `/*# sourceMappingURL=${sourceMapURL} */`;\n }\n return '';\n }\n\n getExternalSourceMap() {\n return this.sourceMap;\n }\n\n setExternalSourceMap(sourceMap) {\n this.sourceMap = sourceMap;\n }\n\n isInline() {\n return this.options.sourceMapFileInline;\n }\n\n getSourceMapURL() {\n return this.sourceMapURL;\n }\n\n getOutputFilename() {\n return this.options.sourceMapOutputFilename;\n }\n\n getInputFilename() {\n return this.sourceMapInputFilename;\n }\n }\n\n return SourceMapBuilder;\n};\n","import LessError from './less-error';\nimport transformTree from './transform-tree';\nimport logger from './logger';\n\nexport default SourceMapBuilder => {\n class ParseTree {\n constructor(root, imports) {\n this.root = root;\n this.imports = imports;\n }\n\n toCSS(options) {\n let evaldRoot;\n const result = {};\n let sourceMapBuilder;\n try {\n evaldRoot = transformTree(this.root, options);\n } catch (e) {\n throw new LessError(e, this.imports);\n }\n\n try {\n const compress = Boolean(options.compress);\n if (compress) {\n logger.warn('The compress option has been deprecated. ' + \n 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');\n }\n\n const toCSSOptions = {\n compress,\n dumpLineNumbers: options.dumpLineNumbers,\n strictUnits: Boolean(options.strictUnits),\n numPrecision: 8};\n\n if (options.sourceMap) {\n sourceMapBuilder = new SourceMapBuilder(options.sourceMap);\n result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);\n } else {\n result.css = evaldRoot.toCSS(toCSSOptions);\n }\n } catch (e) {\n throw new LessError(e, this.imports);\n }\n\n if (options.pluginManager) {\n const postProcessors = options.pluginManager.getPostProcessors();\n for (let i = 0; i < postProcessors.length; i++) {\n result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options, imports: this.imports });\n }\n }\n if (options.sourceMap) {\n result.map = sourceMapBuilder.getExternalSourceMap();\n }\n\n result.imports = [];\n for (const file in this.imports.files) {\n if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) {\n result.imports.push(file);\n }\n }\n return result;\n }\n }\n\n return ParseTree;\n};\n","import contexts from './contexts';\nimport Parser from './parser/parser';\nimport LessError from './less-error';\nimport * as utils from './utils';\nimport logger from './logger';\n\nexport default environment => {\n // FileInfo = {\n // 'rewriteUrls' - option - whether to adjust URL's to be relative\n // 'filename' - full resolved filename of current file\n // 'rootpath' - path to append to normal URLs for this node\n // 'currentDirectory' - path to the current file, absolute\n // 'rootFilename' - filename of the base file\n // 'entryPath' - absolute path to the entry file\n // 'reference' - whether the file should not be output and only output parts that are referenced\n\n class ImportManager {\n constructor(less, context, rootFileInfo) {\n this.less = less;\n this.rootFilename = rootFileInfo.filename;\n this.paths = context.paths || []; // Search paths, when importing\n this.contents = {}; // map - filename to contents of all the files\n this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore\n this.mime = context.mime;\n this.error = null;\n this.context = context;\n // Deprecated? Unused outside of here, could be useful.\n this.queue = []; // Files which haven't been imported yet\n this.files = {}; // Holds the imported parse trees.\n }\n\n /**\n * Add an import to be imported\n * @param path - the raw path\n * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)\n * @param currentFileInfo - the current file info (used for instance to work out relative paths)\n * @param importOptions - import options\n * @param callback - callback for when it is imported\n */\n push(path, tryAppendExtension, currentFileInfo, importOptions, callback) {\n const importManager = this;\n const pluginLoader = this.context.pluginManager.Loader;\n\n this.queue.push(path);\n\n const fileParsedFunc = (e, root, fullPath) => {\n importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue\n\n const importedEqualsRoot = fullPath === importManager.rootFilename;\n if (importOptions.optional && e) {\n callback(null, {rules:[]}, false, null);\n logger.info(`The file ${fullPath} was skipped because it was not found and the import was marked optional.`);\n }\n else {\n // Inline imports aren't cached here.\n // If we start to cache them, please make sure they won't conflict with non-inline imports of the\n // same name as they used to do before this comment and the condition below have been added.\n if (!importManager.files[fullPath] && !importOptions.inline) {\n importManager.files[fullPath] = { root, options: importOptions };\n }\n if (e && !importManager.error) { importManager.error = e; }\n callback(e, root, importedEqualsRoot, fullPath);\n }\n };\n\n const newFileInfo = {\n rewriteUrls: this.context.rewriteUrls,\n entryPath: currentFileInfo.entryPath,\n rootpath: currentFileInfo.rootpath,\n rootFilename: currentFileInfo.rootFilename\n };\n\n const fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);\n\n if (!fileManager) {\n fileParsedFunc({ message: `Could not find a file-manager for ${path}` });\n return;\n }\n\n const loadFileCallback = loadedFile => {\n let plugin;\n const resolvedFilename = loadedFile.filename;\n const contents = loadedFile.contents.replace(/^\\uFEFF/, '');\n\n // Pass on an updated rootpath if path of imported file is relative and file\n // is in a (sub|sup) directory\n //\n // Examples:\n // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',\n // then rootpath should become 'less/module/nav/'\n // - If path of imported file is '../mixins.less' and rootpath is 'less/',\n // then rootpath should become 'less/../'\n newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);\n if (newFileInfo.rewriteUrls) {\n newFileInfo.rootpath = fileManager.join(\n (importManager.context.rootpath || ''),\n fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));\n\n if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {\n newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);\n }\n }\n newFileInfo.filename = resolvedFilename;\n\n const newEnv = new contexts.Parse(importManager.context);\n\n newEnv.processImports = false;\n importManager.contents[resolvedFilename] = contents;\n\n if (currentFileInfo.reference || importOptions.reference) {\n newFileInfo.reference = true;\n }\n\n if (importOptions.isPlugin) {\n plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);\n if (plugin instanceof LessError) {\n fileParsedFunc(plugin, null, resolvedFilename);\n }\n else {\n fileParsedFunc(null, plugin, resolvedFilename);\n }\n } else if (importOptions.inline) {\n fileParsedFunc(null, contents, resolvedFilename);\n } else {\n\n // import (multiple) parse trees apparently get altered and can't be cached.\n // TODO: investigate why this is\n if (importManager.files[resolvedFilename]\n && !importManager.files[resolvedFilename].options.multiple\n && !importOptions.multiple) {\n\n fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);\n }\n else {\n new Parser(newEnv, importManager, newFileInfo).parse(contents, (e, root) => {\n fileParsedFunc(e, root, resolvedFilename);\n });\n }\n }\n };\n let promise;\n const context = utils.clone(this.context);\n\n if (tryAppendExtension) {\n context.ext = importOptions.isPlugin ? '.js' : '.less';\n }\n\n if (importOptions.isPlugin) {\n context.mime = 'application/javascript';\n promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);\n }\n else {\n promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment,\n (err, loadedFile) => {\n if (err) {\n fileParsedFunc(err);\n } else {\n loadFileCallback(loadedFile);\n }\n });\n }\n if (promise) {\n promise.then(loadFileCallback, fileParsedFunc);\n }\n }\n }\n\n return ImportManager;\n};\n","let PromiseConstructor;\nimport * as utils from './utils';\n\nexport default (environment, ParseTree, ImportManager) => {\n const render = function (input, options, callback) {\n if (typeof options === 'function') {\n callback = options;\n options = utils.copyOptions(this.options, {});\n }\n else {\n options = utils.copyOptions(this.options, options || {});\n }\n\n if (!callback) {\n const self = this;\n return new Promise((resolve, reject) => {\n render.call(self, input, options, (err, output) => {\n if (err) {\n reject(err);\n } else {\n resolve(output);\n }\n });\n });\n } else {\n this.parse(input, options, (err, root, imports, options) => {\n if (err) { return callback(err); }\n\n let result;\n try {\n const parseTree = new ParseTree(root, imports);\n result = parseTree.toCSS(options);\n }\n catch (err) { return callback(err); }\n\n callback(null, result);\n });\n }\n };\n\n return render;\n};\n","let PromiseConstructor;\nimport contexts from './contexts';\nimport Parser from './parser/parser';\nimport PluginManager from './plugin-manager';\nimport LessError from './less-error';\nimport * as utils from './utils';\n\nexport default (environment, ParseTree, ImportManager) => {\n const parse = function (input, options, callback) {\n\n if (typeof options === 'function') {\n callback = options;\n options = utils.copyOptions(this.options, {});\n }\n else {\n options = utils.copyOptions(this.options, options || {});\n }\n\n if (!callback) {\n const self = this;\n return new Promise((resolve, reject) => {\n parse.call(self, input, options, (err, output) => {\n if (err) {\n reject(err);\n } else {\n resolve(output);\n }\n });\n });\n } else {\n let context;\n let rootFileInfo;\n const pluginManager = new PluginManager(this, !options.reUsePluginManager);\n\n options.pluginManager = pluginManager;\n\n context = new contexts.Parse(options);\n\n if (options.rootFileInfo) {\n rootFileInfo = options.rootFileInfo;\n } else {\n const filename = options.filename || 'input';\n const entryPath = filename.replace(/[^\\/\\\\]*$/, '');\n rootFileInfo = {\n filename,\n rewriteUrls: context.rewriteUrls,\n rootpath: context.rootpath || '',\n currentDirectory: entryPath,\n entryPath,\n rootFilename: filename\n };\n // add in a missing trailing slash\n if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {\n rootFileInfo.rootpath += '/';\n }\n }\n\n const imports = new ImportManager(this, context, rootFileInfo);\n this.importManager = imports;\n\n // TODO: allow the plugins to be just a list of paths or names\n // Do an async plugin queue like lessc\n\n if (options.plugins) {\n options.plugins.forEach(plugin => {\n let evalResult;\n let contents;\n if (plugin.fileContent) {\n contents = plugin.fileContent.replace(/^\\uFEFF/, '');\n evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename);\n if (evalResult instanceof LessError) {\n return callback(evalResult);\n }\n }\n else {\n pluginManager.addPlugin(plugin);\n }\n });\n }\n\n new Parser(context, imports, rootFileInfo)\n .parse(input, (e, root) => {\n if (e) { return callback(e); }\n callback(null, root, imports, options);\n }, options);\n }\n };\n return parse;\n};\n","// TODO: Add tests for browser @plugin\n/* global window */\n\nimport AbstractPluginLoader from '../less/environment/abstract-plugin-loader.js';\n\n/**\n * Browser Plugin Loader\n */\nclass PluginLoader extends AbstractPluginLoader {\n constructor(less) {\n super();\n\n this.less = less;\n // Should we shim this.require for browser? Probably not?\n }\n\n loadPlugin(filename, basePath, context, environment, fileManager) {\n return new Promise((fulfill, reject) => {\n fileManager.loadFile(filename, basePath, context, environment)\n .then(fulfill).catch(reject);\n });\n }\n}\n\nexport default PluginLoader;\n\n","import * as utils from './utils';\nimport browser from './browser';\n\nexport default (window, less, options) => {\n\n function errorHTML(e, rootHref) {\n const id = `less-error-message:${utils.extractId(rootHref || '')}`;\n const template = '
  • {content}
  • ';\n const elem = window.document.createElement('div');\n let timer;\n let content;\n const errors = [];\n const filename = e.filename || rootHref;\n const filenameNoPath = filename.match(/([^\\/]+(\\?.*)?)$/)[1];\n\n elem.id = id;\n elem.className = 'less-error-message';\n\n content = `

    ${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'}` + \n `

    in ${filenameNoPath} `;\n\n const errorline = (e, i, classname) => {\n if (e.extract[i] !== undefined) {\n errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n .replace(/\\{class\\}/, classname)\n .replace(/\\{content\\}/, e.extract[i]));\n }\n };\n\n if (e.line) {\n errorline(e, 0, '');\n errorline(e, 1, 'line');\n errorline(e, 2, '');\n content += `on line ${e.line}, column ${e.column + 1}:

      ${errors.join('')}
    `;\n }\n if (e.stack && (e.extract || options.logLevel >= 4)) {\n content += `
    Stack Trace
    ${e.stack.split('\\n').slice(1).join('
    ')}`;\n }\n elem.innerHTML = content;\n\n // CSS for error messages\n browser.createCSS(window.document, [\n '.less-error-message ul, .less-error-message li {',\n 'list-style-type: none;',\n 'margin-right: 15px;',\n 'padding: 4px 0;',\n 'margin: 0;',\n '}',\n '.less-error-message label {',\n 'font-size: 12px;',\n 'margin-right: 15px;',\n 'padding: 4px 0;',\n 'color: #cc7777;',\n '}',\n '.less-error-message pre {',\n 'color: #dd6666;',\n 'padding: 4px 0;',\n 'margin: 0;',\n 'display: inline-block;',\n '}',\n '.less-error-message pre.line {',\n 'color: #ff0000;',\n '}',\n '.less-error-message h3 {',\n 'font-size: 20px;',\n 'font-weight: bold;',\n 'padding: 15px 0 5px 0;',\n 'margin: 0;',\n '}',\n '.less-error-message a {',\n 'color: #10a',\n '}',\n '.less-error-message .error {',\n 'color: red;',\n 'font-weight: bold;',\n 'padding-bottom: 2px;',\n 'border-bottom: 1px dashed red;',\n '}'\n ].join('\\n'), { title: 'error-message' });\n\n elem.style.cssText = [\n 'font-family: Arial, sans-serif',\n 'border: 1px solid #e00',\n 'background-color: #eee',\n 'border-radius: 5px',\n '-webkit-border-radius: 5px',\n '-moz-border-radius: 5px',\n 'color: #e00',\n 'padding: 15px',\n 'margin-bottom: 15px'\n ].join(';');\n\n if (options.env === 'development') {\n timer = setInterval(() => {\n const document = window.document;\n const body = document.body;\n if (body) {\n if (document.getElementById(id)) {\n body.replaceChild(elem, document.getElementById(id));\n } else {\n body.insertBefore(elem, body.firstChild);\n }\n clearInterval(timer);\n }\n }, 10);\n }\n }\n\n function removeErrorHTML(path) {\n const node = window.document.getElementById(`less-error-message:${utils.extractId(path)}`);\n if (node) {\n node.parentNode.removeChild(node);\n }\n }\n\n function removeErrorConsole(path) {\n // no action\n }\n\n function removeError(path) {\n if (!options.errorReporting || options.errorReporting === 'html') {\n removeErrorHTML(path);\n } else if (options.errorReporting === 'console') {\n removeErrorConsole(path);\n } else if (typeof options.errorReporting === 'function') {\n options.errorReporting('remove', path);\n }\n }\n\n function errorConsole(e, rootHref) {\n const template = '{line} {content}';\n const filename = e.filename || rootHref;\n const errors = [];\n let content = `${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'} in ${filename}`;\n\n const errorline = (e, i, classname) => {\n if (e.extract[i] !== undefined) {\n errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n .replace(/\\{class\\}/, classname)\n .replace(/\\{content\\}/, e.extract[i]));\n }\n };\n\n if (e.line) {\n errorline(e, 0, '');\n errorline(e, 1, 'line');\n errorline(e, 2, '');\n content += ` on line ${e.line}, column ${e.column + 1}:\\n${errors.join('\\n')}`;\n }\n if (e.stack && (e.extract || options.logLevel >= 4)) {\n content += `\\nStack Trace\\n${e.stack}`;\n }\n less.logger.error(content);\n }\n\n function error(e, rootHref) {\n if (!options.errorReporting || options.errorReporting === 'html') {\n errorHTML(e, rootHref);\n } else if (options.errorReporting === 'console') {\n errorConsole(e, rootHref);\n } else if (typeof options.errorReporting === 'function') {\n options.errorReporting('add', e, rootHref);\n }\n }\n\n return {\n add: error,\n remove: removeError\n };\n};\n","/**\n * Kicks off less and compiles any stylesheets\n * used in the browser distributed version of less\n * to kick-start less using the browser api\n */\n/* global window, document */\n\nimport defaultOptions from '../less/default-options';\nimport addDefaultOptions from './add-default-options';\nimport root from './index';\n\nconst options = defaultOptions();\n\nif (window.less) {\n for (const key in window.less) {\n if (window.less.hasOwnProperty(key)) {\n options[key] = window.less[key];\n }\n }\n}\naddDefaultOptions(window, options);\n\noptions.plugins = options.plugins || [];\n\nif (window.LESS_PLUGINS) {\n options.plugins = options.plugins.concat(window.LESS_PLUGINS);\n}\n\nconst less = root(window, options);\nexport default less;\n\nwindow.less = less;\n\nlet css;\nlet head;\nlet style;\n\n// Always restore page visibility\nfunction resolveOrReject(data) {\n if (data.filename) {\n console.warn(data);\n }\n if (!options.async) {\n head.removeChild(style);\n }\n}\n\nif (options.onReady) {\n if (/!watch/.test(window.location.hash)) {\n less.watch();\n }\n // Simulate synchronous stylesheet loading by hiding page rendering\n if (!options.async) {\n css = 'body { display: none !important }';\n head = document.head || document.getElementsByTagName('head')[0];\n style = document.createElement('style');\n\n style.type = 'text/css';\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n\n head.appendChild(style);\n }\n less.registerStylesheetsImmediately();\n less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);\n}\n","// Export a new default each time\nexport default () => ({\n /* Inline Javascript - @plugin still allowed */\n javascriptEnabled: false,\n\n /* Outputs a makefile import dependency list to stdout. */\n depends: false,\n\n /* (DEPRECATED) Compress using less built-in compression. \n * This does an okay job but does not utilise all the tricks of \n * dedicated css compression. */\n compress: false,\n\n /* Runs the less parser and just reports errors without any output. */\n lint: false,\n\n /* Sets available include paths.\n * If the file in an @import rule does not exist at that exact location, \n * less will look for it at the location(s) passed to this option. \n * You might use this for instance to specify a path to a library which \n * you want to be referenced simply and relatively in the less files. */\n paths: [],\n\n /* color output in the terminal */\n color: true,\n\n /* The strictImports controls whether the compiler will allow an @import inside of either \n * @media blocks or (a later addition) other selector blocks.\n * See: https://github.com/less/less.js/issues/656 */\n strictImports: false,\n\n /* Allow Imports from Insecure HTTPS Hosts */\n insecure: false,\n\n /* Allows you to add a path to every generated import and url in your css. \n * This does not affect less import statements that are processed, just ones \n * that are left in the output css. */\n rootpath: '',\n\n /* By default URLs are kept as-is, so if you import a file in a sub-directory \n * that references an image, exactly the same URL will be output in the css. \n * This option allows you to re-write URL's in imported files so that the \n * URL is always relative to the base imported file */\n rewriteUrls: false,\n\n /* How to process math \n * 0 always - eagerly try to solve all operations\n * 1 parens-division - require parens for division \"/\"\n * 2 parens | strict - require parens for all operations\n * 3 strict-legacy - legacy strict behavior (super-strict)\n */\n math: 0,\n\n /* Without this option, less attempts to guess at the output unit when it does maths. */\n strictUnits: false,\n\n /* Effectively the declaration is put at the top of your base Less file, \n * meaning it can be used but it also can be overridden if this variable \n * is defined in the file. */\n globalVars: null,\n\n /* As opposed to the global variable option, this puts the declaration at the\n * end of your base file, meaning it will override anything defined in your Less file. */\n modifyVars: null,\n\n /* This option allows you to specify a argument to go on to every URL. */\n urlArgs: ''\n});","import {addDataAttr} from './utils';\nimport browser from './browser';\n\nexport default (window, options) => {\n\n // use options from the current script tag data attribues\n addDataAttr(options, browser.currentScript(window));\n\n if (options.isFileProtocol === undefined) {\n options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);\n }\n\n // Load styles asynchronously (default: false)\n //\n // This is set to `false` by default, so that the body\n // doesn't start loading before the stylesheets are parsed.\n // Setting this to `true` can result in flickering.\n //\n options.async = options.async || false;\n options.fileAsync = options.fileAsync || false;\n\n // Interval between watch polls\n options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);\n\n options.env = options.env || (window.location.hostname == '127.0.0.1' ||\n window.location.hostname == '0.0.0.0' ||\n window.location.hostname == 'localhost' ||\n (window.location.port &&\n window.location.port.length > 0) ||\n options.isFileProtocol ? 'development'\n : 'production');\n\n const dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);\n if (dumpLineNumbers) {\n options.dumpLineNumbers = dumpLineNumbers[1];\n }\n\n if (options.useFileCache === undefined) {\n options.useFileCache = true;\n }\n\n if (options.onReady === undefined) {\n options.onReady = true;\n }\n\n if (options.relativeUrls) {\n options.rewriteUrls = 'all';\n }\n};\n","//\n// index.js\n// Should expose the additional browser functions on to the less object\n//\nimport {addDataAttr} from './utils';\nimport lessRoot from '../less';\nimport browser from './browser';\nimport FM from './file-manager';\nimport PluginLoader from './plugin-loader';\nimport LogListener from './log-listener';\nimport ErrorReporting from './error-reporting';\nimport Cache from './cache';\nimport ImageSize from './image-size';\n\nexport default (window, options) => {\n const document = window.document;\n const less = lessRoot();\n\n less.options = options;\n const environment = less.environment;\n const FileManager = FM(options, less.logger);\n const fileManager = new FileManager();\n environment.addFileManager(fileManager);\n less.FileManager = FileManager;\n less.PluginLoader = PluginLoader;\n\n LogListener(less, options);\n const errors = ErrorReporting(window, less, options);\n const cache = less.cache = options.cache || Cache(window, options, less.logger);\n ImageSize(less.environment);\n\n // Setup user functions - Deprecate?\n if (options.functions) {\n less.functions.functionRegistry.addMultiple(options.functions);\n }\n\n const typePattern = /^text\\/(x-)?less$/;\n\n function clone(obj) {\n const cloned = {};\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n cloned[prop] = obj[prop];\n }\n }\n return cloned;\n }\n\n // only really needed for phantom\n function bind(func, thisArg) {\n const curryArgs = Array.prototype.slice.call(arguments, 2);\n return function() {\n const args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));\n return func.apply(thisArg, args);\n };\n }\n\n function loadStyles(modifyVars) {\n const styles = document.getElementsByTagName('style');\n let style;\n\n for (let i = 0; i < styles.length; i++) {\n style = styles[i];\n if (style.type.match(typePattern)) {\n const instanceOptions = clone(options);\n instanceOptions.modifyVars = modifyVars;\n const lessText = style.innerHTML || '';\n instanceOptions.filename = document.location.href.replace(/#.*$/, '');\n\n /* jshint loopfunc:true */\n // use closure to store current style\n less.render(lessText, instanceOptions,\n bind((style, e, result) => {\n if (e) {\n errors.add(e, 'inline');\n } else {\n style.type = 'text/css';\n if (style.styleSheet) {\n style.styleSheet.cssText = result.css;\n } else {\n style.innerHTML = result.css;\n }\n }\n }, null, style));\n }\n }\n }\n\n function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {\n\n const instanceOptions = clone(options);\n addDataAttr(instanceOptions, sheet);\n instanceOptions.mime = sheet.type;\n\n if (modifyVars) {\n instanceOptions.modifyVars = modifyVars;\n }\n\n function loadInitialFileCallback(loadedFile) {\n const data = loadedFile.contents;\n const path = loadedFile.filename;\n const webInfo = loadedFile.webInfo;\n\n const newFileInfo = {\n currentDirectory: fileManager.getPath(path),\n filename: path,\n rootFilename: path,\n rewriteUrls: instanceOptions.rewriteUrls\n };\n\n newFileInfo.entryPath = newFileInfo.currentDirectory;\n newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;\n\n if (webInfo) {\n webInfo.remaining = remaining;\n\n const css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);\n if (!reload && css) {\n webInfo.local = true;\n callback(null, css, data, sheet, webInfo, path);\n return;\n }\n\n }\n\n // TODO add tests around how this behaves when reloading\n errors.remove(path);\n\n instanceOptions.rootFileInfo = newFileInfo;\n less.render(data, instanceOptions, (e, result) => {\n if (e) {\n e.href = path;\n callback(e);\n } else {\n cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);\n callback(null, result.css, data, sheet, webInfo, path);\n }\n });\n }\n\n fileManager.loadFile(sheet.href, null, instanceOptions, environment)\n .then(loadedFile => {\n loadInitialFileCallback(loadedFile);\n }).catch(err => {\n console.log(err);\n callback(err);\n });\n\n }\n\n function loadStyleSheets(callback, reload, modifyVars) {\n for (let i = 0; i < less.sheets.length; i++) {\n loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);\n }\n }\n\n function initRunningMode() {\n if (less.env === 'development') {\n less.watchTimer = setInterval(() => {\n if (less.watchMode) {\n fileManager.clearFileCache();\n loadStyleSheets((e, css, _, sheet, webInfo) => {\n if (e) {\n errors.add(e, e.href || sheet.href);\n } else if (css) {\n browser.createCSS(window.document, css, sheet);\n }\n });\n }\n }, options.poll);\n }\n }\n\n //\n // Watch mode\n //\n less.watch = function () {\n if (!less.watchMode ) {\n less.env = 'development';\n initRunningMode();\n }\n this.watchMode = true;\n return true;\n };\n\n less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };\n\n //\n // Synchronously get all tags with the 'rel' attribute set to\n // \"stylesheet/less\".\n //\n less.registerStylesheetsImmediately = () => {\n const links = document.getElementsByTagName('link');\n less.sheets = [];\n\n for (let i = 0; i < links.length; i++) {\n if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&\n (links[i].type.match(typePattern)))) {\n less.sheets.push(links[i]);\n }\n }\n };\n\n //\n // Asynchronously get all tags with the 'rel' attribute set to\n // \"stylesheet/less\", returning a Promise.\n //\n less.registerStylesheets = () => new Promise((resolve, reject) => {\n less.registerStylesheetsImmediately();\n resolve();\n });\n\n //\n // With this function, it's possible to alter variables and re-render\n // CSS without reloading less-files\n //\n less.modifyVars = record => less.refresh(true, record, false);\n\n less.refresh = (reload, modifyVars, clearFileCache) => {\n if ((reload || clearFileCache) && clearFileCache !== false) {\n fileManager.clearFileCache();\n }\n return new Promise((resolve, reject) => {\n let startTime;\n let endTime;\n let totalMilliseconds;\n let remainingSheets;\n startTime = endTime = new Date();\n\n // Set counter for remaining unprocessed sheets\n remainingSheets = less.sheets.length;\n\n if (remainingSheets === 0) {\n\n endTime = new Date();\n totalMilliseconds = endTime - startTime;\n less.logger.info('Less has finished and no sheets were loaded.');\n resolve({\n startTime,\n endTime,\n totalMilliseconds,\n sheets: less.sheets.length\n });\n\n } else {\n // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array\n loadStyleSheets((e, css, _, sheet, webInfo) => {\n if (e) {\n errors.add(e, e.href || sheet.href);\n reject(e);\n return;\n }\n if (webInfo.local) {\n less.logger.info(`Loading ${sheet.href} from cache.`);\n } else {\n less.logger.info(`Rendered ${sheet.href} successfully.`);\n }\n browser.createCSS(window.document, css, sheet);\n less.logger.info(`CSS for ${sheet.href} generated in ${new Date() - endTime}ms`);\n\n // Count completed sheet\n remainingSheets--;\n\n // Check if the last remaining sheet was processed and then call the promise\n if (remainingSheets === 0) {\n totalMilliseconds = new Date() - startTime;\n less.logger.info(`Less has finished. CSS generated in ${totalMilliseconds}ms`);\n resolve({\n startTime,\n endTime,\n totalMilliseconds,\n sheets: less.sheets.length\n });\n }\n endTime = new Date();\n }, reload, modifyVars);\n }\n\n loadStyles(modifyVars);\n });\n };\n\n less.refreshStyles = loadStyles;\n return less;\n};\n","export default (less, options) => {\n const logLevel_debug = 4;\n const logLevel_info = 3;\n const logLevel_warn = 2;\n const logLevel_error = 1;\n\n // The amount of logging in the javascript console.\n // 3 - Debug, information and errors\n // 2 - Information and errors\n // 1 - Errors\n // 0 - None\n // Defaults to 2\n options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);\n\n if (!options.loggers) {\n options.loggers = [{\n debug: function(msg) {\n if (options.logLevel >= logLevel_debug) {\n console.log(msg);\n }\n },\n info: function(msg) {\n if (options.logLevel >= logLevel_info) {\n console.log(msg);\n }\n },\n warn: function(msg) {\n if (options.logLevel >= logLevel_warn) {\n console.warn(msg);\n }\n },\n error: function(msg) {\n if (options.logLevel >= logLevel_error) {\n console.error(msg);\n }\n }\n }];\n }\n for (let i = 0; i < options.loggers.length; i++) {\n less.logger.addListener(options.loggers[i]);\n }\n};\n","// Cache system is a bit outdated and could do with work\n\nexport default (window, options, logger) => {\n let cache = null;\n if (options.env !== 'development') {\n try {\n cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;\n } catch (_) {}\n }\n return {\n setCSS: function(path, lastModified, modifyVars, styles) {\n if (cache) {\n logger.info(`saving ${path} to cache.`);\n try {\n cache.setItem(path, styles);\n cache.setItem(`${path}:timestamp`, lastModified);\n if (modifyVars) {\n cache.setItem(`${path}:vars`, JSON.stringify(modifyVars));\n }\n } catch (e) {\n // TODO - could do with adding more robust error handling\n logger.error(`failed to save \"${path}\" to local storage for caching.`);\n }\n }\n },\n getCSS: function(path, webInfo, modifyVars) {\n const css = cache && cache.getItem(path);\n const timestamp = cache && cache.getItem(`${path}:timestamp`);\n let vars = cache && cache.getItem(`${path}:vars`);\n\n modifyVars = modifyVars || {};\n vars = vars || \"{}\"; // if not set, treat as the JSON representation of an empty object\n\n if (timestamp && webInfo.lastModified &&\n (new Date(webInfo.lastModified).valueOf() ===\n new Date(timestamp).valueOf()) &&\n JSON.stringify(modifyVars) === vars) {\n // Use local copy\n return css;\n }\n }\n };\n};\n","\nimport functionRegistry from './../less/functions/function-registry';\n\nexport default () => {\n function imageSize() {\n throw {\n type: 'Runtime',\n message: 'Image size functions are not supported in browser version of less'\n };\n }\n\n const imageFunctions = {\n 'image-size': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n },\n 'image-width': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n },\n 'image-height': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n }\n };\n\n functionRegistry.addMultiple(imageFunctions);\n};\n"],"names":["extractId","href","replace","addDataAttr","options","tag","opt","dataset","hasOwnProperty","JSON","parse","_","createCSS","document","styles","sheet","id","title","utils","oldStyleNode","getElementById","keepOldStyleNode","styleNode","createElement","setAttribute","media","styleSheet","appendChild","createTextNode","childNodes","length","firstChild","nodeValue","head","getElementsByTagName","nextEl","nextSibling","parentNode","insertBefore","removeChild","cssText","e","Error","currentScript","window","scripts","duration","angle","Math","PI","colors","unitConversions","Node","parent","visibilityBlocks","undefined","nodeVisible","rootNode","parsed","self","this","Object","defineProperty","get","fileInfo","getIndex","nodes","set","node","Array","isArray","forEach","_index","_fileInfo","context","strs","genCSS","add","chunk","index","push","isEmpty","join","output","value","visitor","visit","op","a","b","precision","numPrecision","Number","toFixed","info","compare","type","i","numericCompare","Color","rgb","originalForm","match","map","c","parseInt","alpha","split","_this","r","g","pow","toCSS","doNotCompress","color","colorFunction","compress","args","fround","indexOf","clamp","round","concat","toHSL","h","s","l","toRGB","splitcolor","other","_operate","toHex","max","min","d","v","x","toString","prototype","fromKeyword","keyword","key","toLowerCase","slice","Paren","eval","_noSpaceCombinators","Combinator","emptyOrWhitespace","trim","spaceOrEmpty","Element","combinator","isVariable","currentFileInfo","visibilityInfo","copyVisibilityInfo","setParent","_typeof","firstSelector","charAt","ALWAYS","PARENS_DIVISION","PARENS","STRICT_LEGACY","RewriteUrls","OFF","LOCAL","ALL","clone","_instanceof","obj","nativeMap","nativeSet","nativePromise","Map","Set","Promise","circular","depth","includeNonEnumerable","allParents","allChildren","useBuffer","Buffer","Infinity","_clone","child","proto","resolve","reject","then","err","__isArray","__isRegExp","RegExp","source","__getRegExpFlags","lastIndex","__isDate","Date","getTime","isBuffer","allocUnsafe","copy","create","getPrototypeOf","keyChild","valueChild","entryChild","attrs","getOwnPropertyDescriptor","getOwnPropertySymbols","symbols","symbol","descriptor","enumerable","allPropertyNames","getOwnPropertyNames","propertyName","__objToStr","o","call","re","flags","global","ignoreCase","multiline","clonePrototype","module","exports","getLocation","inputStream","n","line","column","copyArray","arr","cloned","prop","defaults","obj1","obj2","newObj","_defaults","CloneHelper","assign","copyOptions","opts","strictMath","math","Constants","relativeUrls","rewriteUrls","flattenArray","result","LessError","fileContentMap","currentFilename","filename","message","stack","input","contents","loc","col","callLine","lines","found","callExtract","extract","F","constructor","error","stylize","str","errorTxt","substr","Selector","elements","extendList","condition","evaldCondition","getElements","mixinElements_","visitArray","newSelector","mediaEmpty","els","parseNode","imports","sels","olen","len","mixinElements","shift","extend","createDerived","Value","Keyword","True","False","Anonymous","mapLines","rulesetLike","allowRoot","Boolean","MATH","Declaration","name","important","merge","inline","variable","lastRule","prevMath","evaldValue","mathBypass","evalName","importantScope","importantResult","pop","debugInfo","ctx","lineSeparator","dumpLineNumbers","asComment","asMediaQuery","lineNumber","fileName","filenameWithProtocol","test","Comment","isLineComment","getDebugInfo","isCompressed","contexts","copyFromOriginal","original","destination","propertiesToCopy","parseCopyProperties","Parse","paths","evalCopyProperties","isPathRelative","path","isPathLocalRelative","Eval","frames","inCalc","mathOn","calcStack","parensStack","rootpath","newPath","normalizePath","segment","segments","reverse","makeRegistry","base","_data","func","addMultiple","functions","keys","getLocalFunctions","inherit","defaultFunc","value_","error_","reset","Ruleset","selectors","rules","strictImports","_lookups","_variables","_properties","selCnt","selector","hasVariable","hasOnePassingSelector","j","toParseSelectors","rule","subRule","ruleset","originalRuleset","root","firstRoot","allowImports","functionRegistry","globalFunctionRegistry","ctxFrames","unshift","ctxSelectors","evalImports","rsRules","evalFirst","mediaBlockCount","mediaBlocks","filter","splice","resetCache","isJustParentSelector","bubbleSelectors","importRules","makeImportant","lastSelector","_rulesets","reduce","hash","variables","vars","decl","parseValue","properties","toParse","transformDeclaration","filtRules","isRuleset","foundMixins","rulesets","find","apply","ruleNodes","tabLevel","sep","tabRuleStr","tabSetStr","charsetNodeIndex","importNodeIndex","isCharset","pathSubCnt","pathCnt","currentLastRule","isRulesetLike","isVisible","joinSelector","createParenthesis","elementsToPak","originalElement","replacementParen","insideParent","createSelector","containedElement","element","addReplacementIntoPath","beginningPath","addPath","replacedElement","originalSelector","newSelectorPath","newJoinedSelector","parentEl","restOfPath","addAllReplacementsIntoPath","addPaths","mergeElementsOnToSelectors","sel","deriveSelector","deriveFrom","newPaths","replaceParentSelector","inSelector","k","currentElements","newSelectors","selectorsMultiplied","el","maybeSelector","hadParentSelector","nestedSelector","replaced","nestedPaths","replacedNewSelectors","concatenated","bind","AtRule","isRooted","createEmptySelectors","outputRuleset","mediaPathBackup","mediaBlocksBackup","mediaPath","ruleCnt","DetachedRuleset","Unit","numerator","denominator","backupUnit","sort","strictUnits","returnStr","is","unitString","toUpperCase","callback","group","mapUnit","groupName","atomicUnit","counter","count","Dimension","unit","parseFloat","isNaN","isSingular","strValue","String","isLength","convertTo","usedUnits","cancel","unify","conversions","targetUnit","applyUnit","derivedConversions","Operation","operands","isSpaced","isMathOn","toColor","operate","Expression","noSpacing","returnValue","inParenthesis","parens","parensInOp","doubleParen","outOfParenthesis","functionCaller","item","subNodes","Call","calc","currentMathContext","enterCalc","exitCalc","funcCaller","FunctionCaller","isValid","columnNumber","Variable","evaluating","frame","fun","Property","property","mergeRules","pluginManager","less","visitors","ToCSSVisitor","_mergeRules","vArr","Attribute","Quoted","content","escaped","quote","variableRegex","propRegex","that","iterativeReplace","regexp","replacementFnc","evaluatedValue","URL","val","isEvald","pathRequiresRewrite","rewritePath","urlArgs","Media","features","evalTop","evalNested","multiMedia","permute","fragment","rest","Import","css","pathValue","getPath","isPlugin","reference","containsVariables","doEval","blocksVisibility","addVisibilityBlock","registry","skip","importedFilename","newImport","evalPath","JsEvalNode","expression","evalContext","javascriptEnabled","jsify","Function","toJS","JavaScript","string","evaluateJavaScript","Assignment","Condition","negate","lvalue","rvalue","UnicodeDescriptor","Negative","Extend","option","object_id","next_id","parent_ids","allowBefore","allowAfter","selectorElements","selfElements","selfSelectors","VariableCall","detachedRuleset","callEval","NamespaceValue","ruleCall","lookups","lastDeclaration","substring","Definition","params","variadic","arity","optionalParameters","required","p","mixinEnv","evaldArguments","varargs","arg","isNamedFound","argIndex","argsLength","prependRule","_arguments","mixinFrames","evalParams","allArgsCnt","requiredArgsCnt","MixinCall","arguments","mixins","mixin","mixinPath","argValue","m","f","isRecursive","isOneFound","candidate","defaultResult","noArgumentsFilter","candidates","conditionResult","defFalseEitherCase","defNone","defTrue","defFalse","calcDefGroup","namespace","matchCondition","expand","matchArgs","MixinDefinition","format","newRules","evalCall","_setVisibilityToReplacement","replacement","msg","_fireEvent","warn","debug","addListener","listener","_listeners","removeListener","logFunction","environment","externalEnvironment","fileManagers","requiredFunctions","propName","environmentFunc","currentDirectory","isSync","logger","getFileManagers","fileManager","AbstractFileManager","lastIndexOf","ext","tryAppendExtension","basePath","laterPath","url","baseUrl","urlDirectories","baseUrlDirectories","urlParts","extractUrlParts","baseUrlParts","diff","hostPart","directories","urlPartsRegex","returner","rawDirectories","rawPath","fileUrl","AbstractPluginLoader","require","pluginOptions","pluginObj","localModule","shortname","FileManager","trySetOptions","use","loader","tree","validatePlugin","minVersion","compareVersion","addPlugin","plugin","setOptions","version","versionToString","aVersion","bVersion","versionString","plugins","printUsage","_visitArgs","visitDeeper","_hasIndexed","_noop","Visitor","implementation","_implementation","_visitInCache","_visitOutCache","indexNodeTypes","ticker","typeIndex","nodeTypeIndex","fnName","impl","funcOut","visitArgs","newNode","isReplacing","accept","nonReplacing","cnt","out","evald","flatten","nestedCnt","nestedItem","ImportSequencer","onSequencerEmpty","variableImports","_onSequencerEmpty","_currentDepth","importSequencer","importItem","isReady","tryRun","variableImport","ImportVisitor","importer","finish","_visitor","_importer","_finish","importCount","onceFileDetectionMap","recursionDetector","_sequencer","run","isFinished","visitImport","importNode","inlineCSS","importParent","isVariableImport","addVariableImport","processImportNode","evaldImportNode","evalForImport","multiple","importMultiple","tryAppendLessExtension","onImported","sequencedOnImported","addImport","importedAtRoot","fullPath","importVisitor","isOptional","optional","duplicateImport","oldContext","visitDeclaration","declNode","visitDeclarationOut","visitAtRule","atRuleNode","visitAtRuleOut","visitMixinDefinition","mixinDefinitionNode","visitMixinDefinitionOut","visitRuleset","rulesetNode","visitRulesetOut","visitMedia","mediaNode","visitMediaOut","SetTreeVisibilityVisitor","visible","ensureVisibility","ensureInvisibility","ExtendFinderVisitor","allExtendsStack","allExtends","allSelectorsExtendList","extendOnEveryPath","selectorPath","selExtendList","allSelectorsExtend","foundExtends","findSelfSelectors","firstExtendOnThisSelectorPath","ProcessExtendsVisitor","extendFinder","extendIndices","doExtendChaining","newRoot","checkExtendsForNonMatched","indices","hasFoundMatches","extendsList","extendsListTarget","iterationCount","extendIndex","targetExtendIndex","matches","targetExtend","newExtend","extendsToAdd","extendVisitor","findMatch","selfSelector","extendSelector","extendChainCount","selectorOne","selectorTwo","ruleNode","selectorNode","pathIndex","selectorsToAdd","extendedSelectors","haystackSelectorPath","haystackSelectorIndex","hackstackSelector","hackstackElementIndex","haystackElement","targetCombinator","potentialMatch","needleElements","potentialMatches","matched","initialCombinator","isElementValuesEqual","finished","endPathIndex","endPathElementIndex","elementValue1","elementValue2","replacementSelector","matchIndex","firstElement","newElements","currentSelectorPathIndex","currentSelectorPathElementIndex","currentValue","derived","newAllExtends","JoinSelectorVisitor","getIsOutput","joinSelectors","CSSVisitorUtils","_context","bodyRules","isSilent","owner","thing","originalRules","containsSilentNonBlockedChild","compiledRulesBody","keepOnlyVisibleChilds","removeVisibilityBlock","hasVisibleSelector","mixinNode","visitExtend","extendNode","visitComment","commentNode","resolveVisibility","visitAtRuleWithBody","visitAtRuleWithoutBody","visitAnonymous","anonymousNode","nodeRules","hasFakeRuleset","getBodyRules","charset","comment","checkValidNodes","isRoot","_compileRulesetPaths","nodeRuleCnt","_removeDuplicateRules","isVisibleRuleset","ruleList","ruleCache","ruleCSS","groups","groupsArr","space","comma","MarkVisibleSelectorsVisitor","ExtendVisitor","furthest","furthestPossibleErrorMessage","chunks","current","currentPos","saveStack","parserInput","CHARCODE_SPACE","CHARCODE_TAB","CHARCODE_LF","CHARCODE_CR","CHARCODE_FORWARD_SLASH","skipWhitespace","nextChar","oldi","oldj","curr","endIndex","mem","inp","charCodeAt","autoCommentAbsorb","nextNewLine","text","commentStore","nextStarSlash","save","restore","possibleErrorMessage","state","forget","isWhitespace","offset","pos","code","$re","tok","exec","$char","$str","tokLength","$quoted","startChar","currentPosition","$parseUntil","testChar","returnVal","inComment","blockDepth","blockStack","parseGroups","startPos","lastPos","loop","char","expected","peek","peekChar","currentChar","prevChar","getInput","peekNotNumeric","start","chunkInput","failFunction","fail","lastOpening","lastOpeningParen","lastMultiComment","lastMultiCommentEndBrace","chunkerCurrentIndex","currentChunkStartIndex","cc","cc2","level","parenLevel","emitFrom","emitChunk","force","fromCharCode","chunker","end","furthestReachedEnd","furthestChar","Parser","parsers","getParserInput","expect","expectChar","parseList","currentIndex","returnNodes","parser","additionalData","globalVars","modifyVars","ignored","preText","serializeVars","preProcessors","getPreProcessors","process","banner","contentsIgnoredChars","primary","endInfo","processImports","extendRule","definition","declaration","variableCall","entities","atrule","foundSemiColon","mixinLookup","quoted","forceEscaped","isEscaped","customFuncCall","stop","ieAlpha","boolean","prevArgs","isSemiColonSeparated","argsComma","argsSemiColon","assignment","literal","dimension","unicodeDescriptor","entity","ch","variableCurly","curly","propertyCurly","colorKeyword","ud","javascript","js","escape","parsedName","inValue","ruleLookups","isRule","getLookup","hasParens","elem","elemIndex","isCall","expressionContainsNamed","nameLoop","expressions","hasSep","throwAwayComments","cond","argInfo","conditions","block","lookupValue","attribute","slashedCombinator","isLess","when","blockRuleset","hasDR","ruleProperty","permissiveValue","anonymousValue","untilTokens","done","testCurrentChar","dir","importOptions","mediaFeatures","optionName","importOption","mediaFeature","pluginArgs","nonVendorSpecificName","hasIdentifier","hasExpression","hasUnknown","hasBlock","sub","addition","multiplication","operation","operand","needsParens","logical","next","conditionAnd","negatedCondition","parenthesisCondition","atomicCondition","body","me","tryConditionFollowedByParenthesis","delim","simpleProperty","colorFunctions","trueValue","falseValue","hsla","origColor","hsl","toHSV","number","rgba","size","m1","m2","hue","hsv","hsva","vs","floor","perm","saturation","lightness","hsvhue","hsvsaturation","hsvvalue","red","green","blue","luma","luminance","saturate","amount","method","desaturate","lighten","darken","fadein","fadeout","fade","spin","mix","color1","color2","weight","w","w1","w2","greyscale","contrast","dark","light","threshold","t","argb","toARGB","tint","shade","colorBlend","mode","cb","cs","ar","cr","ab","as","colorBlendModeFunctions","multiply","screen","overlay","softlight","sqrt","hardlight","difference","abs","exclusion","average","negation","getItemsFromNode","_SELF","values","range","step","from","to","stepValue","list","each","rs","iterator","Quote","valueName","keyName","indexName","MathHelper","fn","mathFunctions","ceil","tan","sin","cos","atan","asin","acos","mathHelper","fraction","num","pm","minMax","isMin","currentUnified","referenceUnified","unitStatic","unitClone","order","convert","pi","mod","y","percentage","evaluated","encodeURI","pattern","token","encodeURIComponent","isa","Type","isunit","isruleset","iscolor","isnumber","isstring","iskeyword","isurl","ispixel","ispercentage","isem","colorBlending","fallback","functionThis","mimetypeNode","filePathNode","mimetype","filePath","entryPath","fragmentStart","rawBuffer","getFileManager","useBase64","mimeLookup","charsetLookup","fileSync","loadFileSync","buf","encodeBase64","uri","dataUri","direction","stops","gradientDirectionSvg","position","positionValue","gradientType","rectangleDimension","renderEnv","directionValue","throwArgumentDescriptor","types","evaldRoot","evalEnv","visitorIterator","preEvalVisitors","first","isPreEvalVisitor","isPreVisitor","PluginManager","postProcessors","installedPlugins","pluginCache","Loader","PluginLoader","install","preProcessor","priority","indexToInsertAt","postProcessor","manager","PluginManagerFactory","newFactory","SourceMapOutput","_css","_rootNode","_contentsMap","contentsMap","_contentsIgnoredCharsMap","contentsIgnoredCharsMap","sourceMapFilename","_sourceMapFilename","_outputFilename","outputFilename","sourceMapURL","sourceMapBasepath","_sourceMapBasepath","sourceMapRootpath","_sourceMapRootpath","_outputSourceFiles","outputSourceFiles","_sourceMapGeneratorConstructor","getSourceMapGenerator","_lineNumber","_column","removeBasepath","sourceLines","columns","sourceColumns","inputSource","_sourceMapGenerator","addMapping","generated","normalizeFilename","file","sourceRoot","setSourceContent","sourceMapContent","stringify","toJSON","sourceMap","sourceMapOutput","Environment","SourceMapBuilder","sourceMapOutputFilename","sourceMapGenerator","sourceMapFileInline","sourceMapInputFilename","getCSSAppendage","sourceMapBuilder","ParseTree","transformTree","toCSSOptions","getPostProcessors","getExternalSourceMap","files","rootFilename","parseTree","ImportManager","rootFileInfo","mime","queue","importManager","pluginLoader","fileParsedFunc","importedEqualsRoot","newFileInfo","promise","loadFileCallback","loadedFile","resolvedFilename","pathDiff","isPathAbsolute","alwaysMakePathsAbsolute","newEnv","evalPlugin","loadPlugin","loadFile","render","Render","reUsePluginManager","evalResult","fileContent","Functions","initial","data","ctor","api","fileCache","errback","xhr","XMLHttpRequest","async","isFileProtocol","fileAsync","handleResponse","status","responseText","getResponseHeader","overrideMimeType","open","setRequestHeader","send","onreadystatechange","readyState","location","useFileCache","lessText","webInfo","lastModified","doXHR","log","fulfill","catch","rootHref","errorReporting","errors","errorline","classname","logLevel","errorConsole","timer","filenameNoPath","className","innerHTML","browser","style","env","setInterval","replaceChild","clearInterval","errorHTML","remove","removeErrorHTML","depends","lint","insecure","protocol","poll","hostname","port","onReady","addDefaultOptions","LESS_PLUGINS","lessRoot","FM","addFileManager","loggers","console","LogListener","ErrorReporting","cache","localStorage","setCSS","setItem","getCSS","getItem","timestamp","valueOf","Cache","imageSize","imageFunctions","ImageSize","typePattern","thisArg","curryArgs","loadStyles","instanceOptions","loadStyleSheet","reload","remaining","local","loadInitialFileCallback","loadStyleSheets","sheets","watch","watchMode","watchTimer","clearFileCache","unwatch","registerStylesheetsImmediately","links","rel","registerStylesheets","record","refresh","startTime","endTime","totalMilliseconds","remainingSheets","refreshStyles","resolveOrReject","pageLoadFinished"],"mappings":";;;;;;;;;0LACO,SAASA,EAAUC,UACfA,EAAKC,QAAQ,sBAAuB,IACtCA,QAAQ,uBAAwB,IAChCA,QAAQ,MAAO,IACfA,QAAQ,eAAgB,IACxBA,QAAQ,aAAc,KACtBA,QAAQ,MAAO,KAGjB,SAASC,EAAYC,EAASC,OAC5B,IAAMC,KAAOD,EAAIE,WACdF,EAAIE,QAAQC,eAAeF,MACf,QAARA,GAAyB,oBAARA,GAAqC,aAARA,GAA8B,mBAARA,EACpEF,EAAQE,GAAOD,EAAIE,QAAQD,YAGvBF,EAAQE,GAAOG,KAAKC,MAAML,EAAIE,QAAQD,IAE1C,MAAOK,WCjBR,CACXC,UAAW,SAAUC,EAAUC,EAAQC,OAE7Bd,EAAOc,EAAMd,MAAQ,GAGrBe,iBAAaD,EAAME,OAASC,EAAgBjB,IAG5CkB,EAAeN,EAASO,eAAeJ,GACzCK,GAAmB,EAGjBC,EAAYT,EAASU,cAAc,SACzCD,EAAUE,aAAa,OAAQ,YAC3BT,EAAMU,OACNH,EAAUE,aAAa,QAAST,EAAMU,OAE1CH,EAAUN,GAAKA,EAEVM,EAAUI,aACXJ,EAAUK,YAAYd,EAASe,eAAed,IAG9CO,EAAqC,OAAjBF,GAAyBA,EAAaU,WAAWC,OAAS,GAAKR,EAAUO,WAAWC,OAAS,GAC7GX,EAAaY,WAAWC,YAAcV,EAAUS,WAAWC,eAG7DC,EAAOpB,EAASqB,qBAAqB,QAAQ,MAI9B,OAAjBf,IAA8C,IAArBE,EAA4B,KAC/Cc,EAASpB,GAASA,EAAMqB,aAAe,KACzCD,EACAA,EAAOE,WAAWC,aAAahB,EAAWa,GAE1CF,EAAKN,YAAYL,MAGrBH,IAAqC,IAArBE,GAChBF,EAAakB,WAAWE,YAAYpB,GAMpCG,EAAUI,eAENJ,EAAUI,WAAWc,QAAU1B,EACjC,MAAO2B,SACC,IAAIC,MAAM,2CAI5BC,cAAe,SAASC,OAGVC,EAFJhC,EAAW+B,EAAO/B,gBACjBA,EAAS8B,gBACNE,EAAUhC,EAASqB,qBAAqB,WAC/BW,EAAQf,OAAS,s7DC7D7B,WACC,uBACG,eACR,qBACM,gBACL,gBACA,iBACC,gBACD,yBACS,eACV,qBACM,gBACL,oBACI,oBACA,qBACC,oBACD,gBACJ,yBACS,mBACN,kBACD,eACH,mBACI,mBACA,wBACK,mBACL,mBACA,oBACC,oBACA,sBACE,yBACG,qBACJ,qBACA,kBACH,qBACG,uBACE,wBACC,wBACA,wBACA,wBACA,qBACH,mBACF,sBACG,kBACJ,kBACA,qBACG,oBACD,sBACE,sBACA,kBACJ,oBACE,qBACC,eACN,oBACK,eACL,eACA,gBACC,sBACM,mBACH,kBACD,oBACE,iBACH,gBACD,gBACA,mBACG,wBACK,oBACJ,uBACG,oBACH,qBACC,oBACD,+BACW,oBACX,oBACA,qBACC,oBACD,sBACE,wBACE,uBACD,yBACE,yBACA,yBACA,sBACH,eACP,oBACK,gBACJ,kBACE,iBACD,2BACU,qBACN,uBACE,uBACA,yBACE,0BACC,4BACE,0BACF,0BACA,uBACH,oBACH,oBACA,mBACD,sBACG,eACP,kBACG,gBACF,oBACI,iBACH,oBACG,iBACH,wBACO,oBACJ,wBACI,wBACA,qBACH,oBACD,eACL,eACA,eACA,qBACM,iBACJ,wBACO,cACV,oBACM,oBACA,sBACE,iBACL,qBACI,mBACF,mBACA,iBACF,iBACA,kBACC,oBACE,oBACA,oBACA,eACL,sBACO,oBACF,cACN,eACC,kBACG,iBACD,oBACG,iBACH,gBACD,gBACA,qBACK,iBACJ,sBACK,aCpJH,CACXA,OAAQ,GACC,KACC,OACA,QACA,SACA,MAAS,MACT,MAAS,MACT,MAAS,GAAK,IAExBgB,SAAU,GACD,KACC,MAEVC,MAAO,KACI,GAAK,EAAIC,KAAKC,QACd,EAAI,SACH,WACA,MCfD,CAAEC,OAAAA,EAAQC,gBAAAA,GCHnBC,yCAEOC,OAAS,UACTC,sBAAmBC,OACnBC,iBAAcD,OACdE,SAAW,UACXC,OAAS,SAERC,EAAOC,KACbC,OAAOC,eAAeF,KAAM,kBAAmB,CAC3CG,IAAK,kBAAoBJ,EAAKK,cAElCH,OAAOC,eAAeF,KAAM,QAAS,CACjCG,IAAK,kBAAoBJ,EAAKM,0DAK5BC,EAAOb,YACJc,EAAIC,GACLA,GAAQA,aAAgB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"} \ No newline at end of file +{"version":3,"file":"less.min.js","sources":["../lib/less-browser/utils.js","../lib/less-browser/browser.js","../lib/less/data/colors.js","../lib/less/data/unit-conversions.js","../lib/less/data/index.js","../lib/less/tree/node.js","../lib/less/tree/color.js","../lib/less/tree/paren.js","../lib/less/tree/combinator.js","../lib/less/tree/element.js","../lib/less/constants.js","../node_modules/clone/clone.js","../lib/less/utils.js","../lib/less/less-error.js","../lib/less/tree/selector.js","../lib/less/tree/value.js","../lib/less/tree/keyword.js","../lib/less/tree/anonymous.js","../lib/less/tree/declaration.js","../lib/less/tree/debug-info.js","../lib/less/tree/comment.js","../lib/less/contexts.js","../lib/less/functions/function-registry.js","../lib/less/functions/default.js","../lib/less/tree/ruleset.js","../lib/less/tree/atrule.js","../lib/less/tree/detached-ruleset.js","../lib/less/tree/unit.js","../lib/less/tree/dimension.js","../lib/less/tree/operation.js","../lib/less/tree/expression.js","../lib/less/functions/function-caller.js","../lib/less/tree/call.js","../lib/less/tree/variable.js","../lib/less/tree/property.js","../lib/less/tree/attribute.js","../lib/less/tree/quoted.js","../lib/less/tree/url.js","../lib/less/tree/media.js","../lib/less/tree/import.js","../lib/less/tree/js-eval-node.js","../lib/less/tree/javascript.js","../lib/less/tree/assignment.js","../lib/less/tree/condition.js","../lib/less/tree/unicode-descriptor.js","../lib/less/tree/negative.js","../lib/less/tree/extend.js","../lib/less/tree/variable-call.js","../lib/less/tree/namespace-value.js","../lib/less/tree/mixin-definition.js","../lib/less/tree/mixin-call.js","../lib/less/tree/index.js","../lib/less/logger.js","../lib/less/environment/environment.js","../lib/less/environment/abstract-file-manager.js","../lib/less/environment/abstract-plugin-loader.js","../lib/less/visitors/visitor.js","../lib/less/visitors/import-sequencer.js","../lib/less/visitors/import-visitor.js","../lib/less/visitors/set-tree-visibility-visitor.js","../lib/less/visitors/extend-visitor.js","../lib/less/visitors/join-selector-visitor.js","../lib/less/visitors/to-css-visitor.js","../lib/less/visitors/index.js","../lib/less/parser/parser-input.js","../lib/less/parser/chunker.js","../lib/less/parser/parser.js","../lib/less/functions/color.js","../lib/less/functions/boolean.js","../lib/less/functions/color-blending.js","../lib/less/functions/list.js","../lib/less/functions/math-helper.js","../lib/less/functions/math.js","../lib/less/functions/number.js","../lib/less/plugin-manager.js","../lib/less/functions/string.js","../lib/less/functions/types.js","../lib/less/functions/index.js","../lib/less/functions/data-uri.js","../lib/less/functions/svg.js","../lib/less/transform-tree.js","../lib/less-browser/file-manager.js","../lib/less/index.js","../lib/less/source-map-output.js","../lib/less/source-map-builder.js","../lib/less/parse-tree.js","../lib/less/import-manager.js","../lib/less/render.js","../lib/less/parse.js","../lib/less-browser/plugin-loader.js","../lib/less-browser/error-reporting.js","../lib/less-browser/bootstrap.js","../lib/less/default-options.js","../lib/less-browser/add-default-options.js","../lib/less-browser/index.js","../lib/less-browser/log-listener.js","../lib/less-browser/cache.js","../lib/less-browser/image-size.js"],"sourcesContent":["\nexport function extractId(href) {\n return href.replace(/^[a-z-]+:\\/+?[^\\/]+/, '') // Remove protocol & domain\n .replace(/[\\?\\&]livereload=\\w+/, '') // Remove LiveReload cachebuster\n .replace(/^\\//, '') // Remove root /\n .replace(/\\.[a-zA-Z]+$/, '') // Remove simple extension\n .replace(/[^\\.\\w-]+/g, '-') // Replace illegal characters\n .replace(/\\./g, ':'); // Replace dots with colons(for valid id)\n}\n\nexport function addDataAttr(options, tag) {\n for (const opt in tag.dataset) {\n if (tag.dataset.hasOwnProperty(opt)) {\n if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {\n options[opt] = tag.dataset[opt];\n } else {\n try {\n options[opt] = JSON.parse(tag.dataset[opt]);\n }\n catch (_) {}\n }\n }\n }\n}\n","import * as utils from './utils';\n\nexport default {\n createCSS: function (document, styles, sheet) {\n // Strip the query-string\n const href = sheet.href || '';\n\n // If there is no title set, use the filename, minus the extension\n const id = `less:${sheet.title || utils.extractId(href)}`;\n\n // If this has already been inserted into the DOM, we may need to replace it\n const oldStyleNode = document.getElementById(id);\n let keepOldStyleNode = false;\n\n // Create a new stylesheet node for insertion or (if necessary) replacement\n const styleNode = document.createElement('style');\n styleNode.setAttribute('type', 'text/css');\n if (sheet.media) {\n styleNode.setAttribute('media', sheet.media);\n }\n styleNode.id = id;\n\n if (!styleNode.styleSheet) {\n styleNode.appendChild(document.createTextNode(styles));\n\n // If new contents match contents of oldStyleNode, don't replace oldStyleNode\n keepOldStyleNode = (oldStyleNode !== null && oldStyleNode.childNodes.length > 0 && styleNode.childNodes.length > 0 &&\n oldStyleNode.firstChild.nodeValue === styleNode.firstChild.nodeValue);\n }\n\n const head = document.getElementsByTagName('head')[0];\n\n // If there is no oldStyleNode, just append; otherwise, only append if we need\n // to replace oldStyleNode with an updated stylesheet\n if (oldStyleNode === null || keepOldStyleNode === false) {\n const nextEl = sheet && sheet.nextSibling || null;\n if (nextEl) {\n nextEl.parentNode.insertBefore(styleNode, nextEl);\n } else {\n head.appendChild(styleNode);\n }\n }\n if (oldStyleNode && keepOldStyleNode === false) {\n oldStyleNode.parentNode.removeChild(oldStyleNode);\n }\n\n // For IE.\n // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.\n // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head\n if (styleNode.styleSheet) {\n try {\n styleNode.styleSheet.cssText = styles;\n } catch (e) {\n throw new Error('Couldn\\'t reassign styleSheet.cssText.');\n }\n }\n },\n currentScript: function(window) {\n const document = window.document;\n return document.currentScript || (() => {\n const scripts = document.getElementsByTagName('script');\n return scripts[scripts.length - 1];\n })();\n }\n};\n","export default {\n 'aliceblue':'#f0f8ff',\n 'antiquewhite':'#faebd7',\n 'aqua':'#00ffff',\n 'aquamarine':'#7fffd4',\n 'azure':'#f0ffff',\n 'beige':'#f5f5dc',\n 'bisque':'#ffe4c4',\n 'black':'#000000',\n 'blanchedalmond':'#ffebcd',\n 'blue':'#0000ff',\n 'blueviolet':'#8a2be2',\n 'brown':'#a52a2a',\n 'burlywood':'#deb887',\n 'cadetblue':'#5f9ea0',\n 'chartreuse':'#7fff00',\n 'chocolate':'#d2691e',\n 'coral':'#ff7f50',\n 'cornflowerblue':'#6495ed',\n 'cornsilk':'#fff8dc',\n 'crimson':'#dc143c',\n 'cyan':'#00ffff',\n 'darkblue':'#00008b',\n 'darkcyan':'#008b8b',\n 'darkgoldenrod':'#b8860b',\n 'darkgray':'#a9a9a9',\n 'darkgrey':'#a9a9a9',\n 'darkgreen':'#006400',\n 'darkkhaki':'#bdb76b',\n 'darkmagenta':'#8b008b',\n 'darkolivegreen':'#556b2f',\n 'darkorange':'#ff8c00',\n 'darkorchid':'#9932cc',\n 'darkred':'#8b0000',\n 'darksalmon':'#e9967a',\n 'darkseagreen':'#8fbc8f',\n 'darkslateblue':'#483d8b',\n 'darkslategray':'#2f4f4f',\n 'darkslategrey':'#2f4f4f',\n 'darkturquoise':'#00ced1',\n 'darkviolet':'#9400d3',\n 'deeppink':'#ff1493',\n 'deepskyblue':'#00bfff',\n 'dimgray':'#696969',\n 'dimgrey':'#696969',\n 'dodgerblue':'#1e90ff',\n 'firebrick':'#b22222',\n 'floralwhite':'#fffaf0',\n 'forestgreen':'#228b22',\n 'fuchsia':'#ff00ff',\n 'gainsboro':'#dcdcdc',\n 'ghostwhite':'#f8f8ff',\n 'gold':'#ffd700',\n 'goldenrod':'#daa520',\n 'gray':'#808080',\n 'grey':'#808080',\n 'green':'#008000',\n 'greenyellow':'#adff2f',\n 'honeydew':'#f0fff0',\n 'hotpink':'#ff69b4',\n 'indianred':'#cd5c5c',\n 'indigo':'#4b0082',\n 'ivory':'#fffff0',\n 'khaki':'#f0e68c',\n 'lavender':'#e6e6fa',\n 'lavenderblush':'#fff0f5',\n 'lawngreen':'#7cfc00',\n 'lemonchiffon':'#fffacd',\n 'lightblue':'#add8e6',\n 'lightcoral':'#f08080',\n 'lightcyan':'#e0ffff',\n 'lightgoldenrodyellow':'#fafad2',\n 'lightgray':'#d3d3d3',\n 'lightgrey':'#d3d3d3',\n 'lightgreen':'#90ee90',\n 'lightpink':'#ffb6c1',\n 'lightsalmon':'#ffa07a',\n 'lightseagreen':'#20b2aa',\n 'lightskyblue':'#87cefa',\n 'lightslategray':'#778899',\n 'lightslategrey':'#778899',\n 'lightsteelblue':'#b0c4de',\n 'lightyellow':'#ffffe0',\n 'lime':'#00ff00',\n 'limegreen':'#32cd32',\n 'linen':'#faf0e6',\n 'magenta':'#ff00ff',\n 'maroon':'#800000',\n 'mediumaquamarine':'#66cdaa',\n 'mediumblue':'#0000cd',\n 'mediumorchid':'#ba55d3',\n 'mediumpurple':'#9370d8',\n 'mediumseagreen':'#3cb371',\n 'mediumslateblue':'#7b68ee',\n 'mediumspringgreen':'#00fa9a',\n 'mediumturquoise':'#48d1cc',\n 'mediumvioletred':'#c71585',\n 'midnightblue':'#191970',\n 'mintcream':'#f5fffa',\n 'mistyrose':'#ffe4e1',\n 'moccasin':'#ffe4b5',\n 'navajowhite':'#ffdead',\n 'navy':'#000080',\n 'oldlace':'#fdf5e6',\n 'olive':'#808000',\n 'olivedrab':'#6b8e23',\n 'orange':'#ffa500',\n 'orangered':'#ff4500',\n 'orchid':'#da70d6',\n 'palegoldenrod':'#eee8aa',\n 'palegreen':'#98fb98',\n 'paleturquoise':'#afeeee',\n 'palevioletred':'#d87093',\n 'papayawhip':'#ffefd5',\n 'peachpuff':'#ffdab9',\n 'peru':'#cd853f',\n 'pink':'#ffc0cb',\n 'plum':'#dda0dd',\n 'powderblue':'#b0e0e6',\n 'purple':'#800080',\n 'rebeccapurple':'#663399',\n 'red':'#ff0000',\n 'rosybrown':'#bc8f8f',\n 'royalblue':'#4169e1',\n 'saddlebrown':'#8b4513',\n 'salmon':'#fa8072',\n 'sandybrown':'#f4a460',\n 'seagreen':'#2e8b57',\n 'seashell':'#fff5ee',\n 'sienna':'#a0522d',\n 'silver':'#c0c0c0',\n 'skyblue':'#87ceeb',\n 'slateblue':'#6a5acd',\n 'slategray':'#708090',\n 'slategrey':'#708090',\n 'snow':'#fffafa',\n 'springgreen':'#00ff7f',\n 'steelblue':'#4682b4',\n 'tan':'#d2b48c',\n 'teal':'#008080',\n 'thistle':'#d8bfd8',\n 'tomato':'#ff6347',\n 'turquoise':'#40e0d0',\n 'violet':'#ee82ee',\n 'wheat':'#f5deb3',\n 'white':'#ffffff',\n 'whitesmoke':'#f5f5f5',\n 'yellow':'#ffff00',\n 'yellowgreen':'#9acd32'\n};","export default {\n length: {\n 'm': 1,\n 'cm': 0.01,\n 'mm': 0.001,\n 'in': 0.0254,\n 'px': 0.0254 / 96,\n 'pt': 0.0254 / 72,\n 'pc': 0.0254 / 72 * 12\n },\n duration: {\n 's': 1,\n 'ms': 0.001\n },\n angle: {\n 'rad': 1 / (2 * Math.PI),\n 'deg': 1 / 360,\n 'grad': 1 / 400,\n 'turn': 1\n }\n};","import colors from './colors';\nimport unitConversions from './unit-conversions';\n\nexport default { colors, unitConversions };\n","class Node {\n constructor() {\n this.parent = null;\n this.visibilityBlocks = undefined;\n this.nodeVisible = undefined;\n this.rootNode = null;\n this.parsed = null;\n\n const self = this;\n Object.defineProperty(this, 'currentFileInfo', {\n get: function() { return self.fileInfo(); }\n });\n Object.defineProperty(this, 'index', {\n get: function() { return self.getIndex(); }\n });\n\n }\n\n setParent(nodes, parent) {\n function set(node) {\n if (node && node instanceof Node) {\n node.parent = parent;\n }\n }\n if (Array.isArray(nodes)) {\n nodes.forEach(set);\n }\n else {\n set(nodes);\n }\n }\n\n getIndex() {\n return this._index || (this.parent && this.parent.getIndex()) || 0;\n }\n\n fileInfo() {\n return this._fileInfo || (this.parent && this.parent.fileInfo()) || {};\n }\n\n isRulesetLike() {\n return false;\n }\n\n toCSS(context) {\n const strs = [];\n this.genCSS(context, {\n add: function(chunk, fileInfo, index) {\n strs.push(chunk);\n },\n isEmpty: function () {\n return strs.length === 0;\n }\n });\n return strs.join('');\n }\n\n genCSS(context, output) {\n output.add(this.value);\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n eval() { return this; }\n\n _operate(context, op, a, b) {\n switch (op) {\n case '+': return a + b;\n case '-': return a - b;\n case '*': return a * b;\n case '/': return a / b;\n }\n }\n\n fround(context, value) {\n const precision = context && context.numPrecision;\n // add \"epsilon\" to ensure numbers like 1.000000005 (represented as 1.000000004999...) are properly rounded:\n return (precision) ? Number((value + 2e-16).toFixed(precision)) : value;\n }\n\n // Returns true if this node represents root of ast imported by reference\n blocksVisibility() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n return this.visibilityBlocks !== 0;\n }\n\n addVisibilityBlock() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n this.visibilityBlocks = this.visibilityBlocks + 1;\n }\n\n removeVisibilityBlock() {\n if (this.visibilityBlocks == null) {\n this.visibilityBlocks = 0;\n }\n this.visibilityBlocks = this.visibilityBlocks - 1;\n }\n\n // Turns on node visibility - if called node will be shown in output regardless\n // of whether it comes from import by reference or not\n ensureVisibility() {\n this.nodeVisible = true;\n }\n\n // Turns off node visibility - if called node will NOT be shown in output regardless\n // of whether it comes from import by reference or not\n ensureInvisibility() {\n this.nodeVisible = false;\n }\n\n // return values:\n // false - the node must not be visible\n // true - the node must be visible\n // undefined or null - the node has the same visibility as its parent\n isVisible() {\n return this.nodeVisible;\n }\n\n visibilityInfo() {\n return {\n visibilityBlocks: this.visibilityBlocks,\n nodeVisible: this.nodeVisible\n };\n }\n\n copyVisibilityInfo(info) {\n if (!info) {\n return;\n }\n this.visibilityBlocks = info.visibilityBlocks;\n this.nodeVisible = info.nodeVisible;\n }\n}\n\nNode.compare = (a, b) => {\n /* returns:\n -1: a < b\n 0: a = b\n 1: a > b\n and *any* other value for a != b (e.g. undefined, NaN, -2 etc.) */\n\n if ((a.compare) &&\n // for \"symmetric results\" force toCSS-based comparison\n // of Quoted or Anonymous if either value is one of those\n !(b.type === 'Quoted' || b.type === 'Anonymous')) {\n return a.compare(b);\n } else if (b.compare) {\n return -b.compare(a);\n } else if (a.type !== b.type) {\n return undefined;\n }\n\n a = a.value;\n b = b.value;\n if (!Array.isArray(a)) {\n return a === b ? 0 : undefined;\n }\n if (a.length !== b.length) {\n return undefined;\n }\n for (let i = 0; i < a.length; i++) {\n if (Node.compare(a[i], b[i]) !== 0) {\n return undefined;\n }\n }\n return 0;\n};\n\nNode.numericCompare = (a, b) => a < b ? -1\n : a === b ? 0\n : a > b ? 1 : undefined;\nexport default Node;\n","import Node from './node';\nimport colors from '../data/colors';\n\n//\n// RGB Colors - #ff0014, #eee\n//\nclass Color extends Node {\n constructor(rgb, a, originalForm) {\n super();\n\n const self = this;\n //\n // The end goal here, is to parse the arguments\n // into an integer triplet, such as `128, 255, 0`\n //\n // This facilitates operations and conversions.\n //\n if (Array.isArray(rgb)) {\n this.rgb = rgb;\n } else if (rgb.length >= 6) {\n this.rgb = [];\n rgb.match(/.{2}/g).map((c, i) => {\n if (i < 3) {\n self.rgb.push(parseInt(c, 16));\n } else {\n self.alpha = (parseInt(c, 16)) / 255;\n }\n });\n } else {\n this.rgb = [];\n rgb.split('').map((c, i) => {\n if (i < 3) {\n self.rgb.push(parseInt(c + c, 16));\n } else {\n self.alpha = (parseInt(c + c, 16)) / 255;\n }\n });\n }\n this.alpha = this.alpha || (typeof a === 'number' ? a : 1);\n if (typeof originalForm !== 'undefined') {\n this.value = originalForm;\n }\n }\n\n luma() {\n let r = this.rgb[0] / 255;\n let g = this.rgb[1] / 255;\n let b = this.rgb[2] / 255;\n\n r = (r <= 0.03928) ? r / 12.92 : Math.pow(((r + 0.055) / 1.055), 2.4);\n g = (g <= 0.03928) ? g / 12.92 : Math.pow(((g + 0.055) / 1.055), 2.4);\n b = (b <= 0.03928) ? b / 12.92 : Math.pow(((b + 0.055) / 1.055), 2.4);\n\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context));\n }\n\n toCSS(context, doNotCompress) {\n const compress = context && context.compress && !doNotCompress;\n let color;\n let alpha;\n let colorFunction;\n let args = [];\n\n // `value` is set if this color was originally\n // converted from a named color string so we need\n // to respect this and try to output named color too.\n alpha = this.fround(context, this.alpha);\n\n if (this.value) {\n if (this.value.indexOf('rgb') === 0) {\n if (alpha < 1) {\n colorFunction = 'rgba';\n }\n } else if (this.value.indexOf('hsl') === 0) {\n if (alpha < 1) {\n colorFunction = 'hsla';\n } else {\n colorFunction = 'hsl';\n }\n } else {\n return this.value;\n }\n } else {\n if (alpha < 1) {\n colorFunction = 'rgba';\n }\n }\n\n switch (colorFunction) {\n case 'rgba':\n args = this.rgb.map(c => clamp(Math.round(c), 255)).concat(clamp(alpha, 1));\n break;\n case 'hsla':\n args.push(clamp(alpha, 1));\n case 'hsl':\n color = this.toHSL();\n args = [\n this.fround(context, color.h),\n `${this.fround(context, color.s * 100)}%`,\n `${this.fround(context, color.l * 100)}%`\n ].concat(args);\n }\n\n if (colorFunction) {\n // Values are capped between `0` and `255`, rounded and zero-padded.\n return `${colorFunction}(${args.join(`,${compress ? '' : ' '}`)})`;\n }\n\n color = this.toRGB();\n\n if (compress) {\n const splitcolor = color.split('');\n\n // Convert color to short format\n if (splitcolor[1] === splitcolor[2] && splitcolor[3] === splitcolor[4] && splitcolor[5] === splitcolor[6]) {\n color = `#${splitcolor[1]}${splitcolor[3]}${splitcolor[5]}`;\n }\n }\n\n return color;\n }\n\n //\n // Operations have to be done per-channel, if not,\n // channels will spill onto each other. Once we have\n // our result, in the form of an integer triplet,\n // we create a new Color node to hold the result.\n //\n operate(context, op, other) {\n const rgb = new Array(3);\n const alpha = this.alpha * (1 - other.alpha) + other.alpha;\n for (let c = 0; c < 3; c++) {\n rgb[c] = this._operate(context, op, this.rgb[c], other.rgb[c]);\n }\n return new Color(rgb, alpha);\n }\n\n toRGB() {\n return toHex(this.rgb);\n }\n\n toHSL() {\n const r = this.rgb[0] / 255;\n const g = this.rgb[1] / 255;\n const b = this.rgb[2] / 255;\n const a = this.alpha;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h;\n let s;\n const l = (max + min) / 2;\n const d = max - min;\n\n if (max === min) {\n h = s = 0;\n } else {\n s = l > 0.5 ? d / (2 - max - min) : d / (max + min);\n\n switch (max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h * 360, s, l, a };\n }\n\n // Adapted from http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript\n toHSV() {\n const r = this.rgb[0] / 255;\n const g = this.rgb[1] / 255;\n const b = this.rgb[2] / 255;\n const a = this.alpha;\n const max = Math.max(r, g, b);\n const min = Math.min(r, g, b);\n let h;\n let s;\n const v = max;\n\n const d = max - min;\n if (max === 0) {\n s = 0;\n } else {\n s = d / max;\n }\n\n if (max === min) {\n h = 0;\n } else {\n switch (max) {\n case r: h = (g - b) / d + (g < b ? 6 : 0); break;\n case g: h = (b - r) / d + 2; break;\n case b: h = (r - g) / d + 4; break;\n }\n h /= 6;\n }\n return { h: h * 360, s, v, a };\n }\n\n toARGB() {\n return toHex([this.alpha * 255].concat(this.rgb));\n }\n\n compare(x) {\n return (x.rgb &&\n x.rgb[0] === this.rgb[0] &&\n x.rgb[1] === this.rgb[1] &&\n x.rgb[2] === this.rgb[2] &&\n x.alpha === this.alpha) ? 0 : undefined;\n }\n}\n\nColor.prototype.type = 'Color';\n\nfunction clamp(v, max) {\n return Math.min(Math.max(v, 0), max);\n}\n\nfunction toHex(v) {\n return `#${v.map(c => {\n c = clamp(Math.round(c), 255);\n return (c < 16 ? '0' : '') + c.toString(16);\n }).join('')}`;\n}\n\nColor.fromKeyword = keyword => {\n let c;\n const key = keyword.toLowerCase();\n if (colors.hasOwnProperty(key)) {\n c = new Color(colors[key].slice(1));\n }\n else if (key === 'transparent') {\n c = new Color([0, 0, 0], 0);\n }\n\n if (c) {\n c.value = keyword;\n return c;\n }\n};\nexport default Color;\n","import Node from './node';\n\nclass Paren extends Node {\n constructor(node) {\n super();\n\n this.value = node;\n }\n\n genCSS(context, output) {\n output.add('(');\n this.value.genCSS(context, output);\n output.add(')');\n }\n\n eval(context) {\n return new Paren(this.value.eval(context));\n }\n}\n\nParen.prototype.type = 'Paren';\nexport default Paren;\n","import Node from './node';\nconst _noSpaceCombinators = {\n '': true,\n ' ': true,\n '|': true\n};\n\nclass Combinator extends Node {\n constructor(value) {\n super();\n\n if (value === ' ') {\n this.value = ' ';\n this.emptyOrWhitespace = true;\n } else {\n this.value = value ? value.trim() : '';\n this.emptyOrWhitespace = this.value === '';\n }\n }\n\n genCSS(context, output) {\n const spaceOrEmpty = (context.compress || _noSpaceCombinators[this.value]) ? '' : ' ';\n output.add(spaceOrEmpty + this.value + spaceOrEmpty);\n }\n}\n\nCombinator.prototype.type = 'Combinator';\n\nexport default Combinator;\n","import Node from './node';\nimport Paren from './paren';\nimport Combinator from './combinator';\n\nclass Element extends Node {\n constructor(combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.combinator = combinator instanceof Combinator ?\n combinator : new Combinator(combinator);\n\n if (typeof value === 'string') {\n this.value = value.trim();\n } else if (value) {\n this.value = value;\n } else {\n this.value = '';\n }\n this.isVariable = isVariable;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.combinator, this);\n }\n\n accept(visitor) {\n const value = this.value;\n this.combinator = visitor.visit(this.combinator);\n if (typeof value === 'object') {\n this.value = visitor.visit(value);\n }\n }\n\n eval(context) {\n return new Element(this.combinator,\n this.value.eval ? this.value.eval(context) : this.value,\n this.isVariable,\n this.getIndex(),\n this.fileInfo(), this.visibilityInfo());\n }\n\n clone() {\n return new Element(this.combinator,\n this.value,\n this.isVariable,\n this.getIndex(),\n this.fileInfo(), this.visibilityInfo());\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context), this.fileInfo(), this.getIndex());\n }\n\n toCSS(context = {}) {\n let value = this.value;\n const firstSelector = context.firstSelector;\n if (value instanceof Paren) {\n // selector in parens should not be affected by outer selector\n // flags (breaks only interpolated selectors - see #1973)\n context.firstSelector = true;\n }\n value = value.toCSS ? value.toCSS(context) : value;\n context.firstSelector = firstSelector;\n if (value === '' && this.combinator.value.charAt(0) === '&') {\n return '';\n } else {\n return this.combinator.toCSS(context) + value;\n }\n }\n}\n\nElement.prototype.type = 'Element';\nexport default Element;\n","\nexport const Math = {\n ALWAYS: 0,\n PARENS_DIVISION: 1,\n PARENS: 2,\n STRICT_LEGACY: 3\n};\n\nexport const RewriteUrls = {\n OFF: 0,\n LOCAL: 1,\n ALL: 2\n};","var clone = (function() {\n'use strict';\n\nfunction _instanceof(obj, type) {\n return type != null && obj instanceof type;\n}\n\nvar nativeMap;\ntry {\n nativeMap = Map;\n} catch(_) {\n // maybe a reference error because no `Map`. Give it a dummy value that no\n // value will ever be an instanceof.\n nativeMap = function() {};\n}\n\nvar nativeSet;\ntry {\n nativeSet = Set;\n} catch(_) {\n nativeSet = function() {};\n}\n\nvar nativePromise;\ntry {\n nativePromise = Promise;\n} catch(_) {\n nativePromise = function() {};\n}\n\n/**\n * Clones (copies) an Object using deep copying.\n *\n * This function supports circular references by default, but if you are certain\n * there are no circular references in your object, you can save some CPU time\n * by calling clone(obj, false).\n *\n * Caution: if `circular` is false and `parent` contains circular references,\n * your program may enter an infinite loop and crash.\n *\n * @param `parent` - the object to be cloned\n * @param `circular` - set to true if the object to be cloned may contain\n * circular references. (optional - true by default)\n * @param `depth` - set to a number if the object is only to be cloned to\n * a particular depth. (optional - defaults to Infinity)\n * @param `prototype` - sets the prototype to be used when cloning an object.\n * (optional - defaults to parent prototype).\n * @param `includeNonEnumerable` - set to true if the non-enumerable properties\n * should be cloned as well. Non-enumerable properties on the prototype\n * chain will be ignored. (optional - false by default)\n*/\nfunction clone(parent, circular, depth, prototype, includeNonEnumerable) {\n if (typeof circular === 'object') {\n depth = circular.depth;\n prototype = circular.prototype;\n includeNonEnumerable = circular.includeNonEnumerable;\n circular = circular.circular;\n }\n // maintain two arrays for circular references, where corresponding parents\n // and children have the same index\n var allParents = [];\n var allChildren = [];\n\n var useBuffer = typeof Buffer != 'undefined';\n\n if (typeof circular == 'undefined')\n circular = true;\n\n if (typeof depth == 'undefined')\n depth = Infinity;\n\n // recurse this function so we don't reset allParents and allChildren\n function _clone(parent, depth) {\n // cloning null always returns null\n if (parent === null)\n return null;\n\n if (depth === 0)\n return parent;\n\n var child;\n var proto;\n if (typeof parent != 'object') {\n return parent;\n }\n\n if (_instanceof(parent, nativeMap)) {\n child = new nativeMap();\n } else if (_instanceof(parent, nativeSet)) {\n child = new nativeSet();\n } else if (_instanceof(parent, nativePromise)) {\n child = new nativePromise(function (resolve, reject) {\n parent.then(function(value) {\n resolve(_clone(value, depth - 1));\n }, function(err) {\n reject(_clone(err, depth - 1));\n });\n });\n } else if (clone.__isArray(parent)) {\n child = [];\n } else if (clone.__isRegExp(parent)) {\n child = new RegExp(parent.source, __getRegExpFlags(parent));\n if (parent.lastIndex) child.lastIndex = parent.lastIndex;\n } else if (clone.__isDate(parent)) {\n child = new Date(parent.getTime());\n } else if (useBuffer && Buffer.isBuffer(parent)) {\n if (Buffer.allocUnsafe) {\n // Node.js >= 4.5.0\n child = Buffer.allocUnsafe(parent.length);\n } else {\n // Older Node.js versions\n child = new Buffer(parent.length);\n }\n parent.copy(child);\n return child;\n } else if (_instanceof(parent, Error)) {\n child = Object.create(parent);\n } else {\n if (typeof prototype == 'undefined') {\n proto = Object.getPrototypeOf(parent);\n child = Object.create(proto);\n }\n else {\n child = Object.create(prototype);\n proto = prototype;\n }\n }\n\n if (circular) {\n var index = allParents.indexOf(parent);\n\n if (index != -1) {\n return allChildren[index];\n }\n allParents.push(parent);\n allChildren.push(child);\n }\n\n if (_instanceof(parent, nativeMap)) {\n parent.forEach(function(value, key) {\n var keyChild = _clone(key, depth - 1);\n var valueChild = _clone(value, depth - 1);\n child.set(keyChild, valueChild);\n });\n }\n if (_instanceof(parent, nativeSet)) {\n parent.forEach(function(value) {\n var entryChild = _clone(value, depth - 1);\n child.add(entryChild);\n });\n }\n\n for (var i in parent) {\n var attrs;\n if (proto) {\n attrs = Object.getOwnPropertyDescriptor(proto, i);\n }\n\n if (attrs && attrs.set == null) {\n continue;\n }\n child[i] = _clone(parent[i], depth - 1);\n }\n\n if (Object.getOwnPropertySymbols) {\n var symbols = Object.getOwnPropertySymbols(parent);\n for (var i = 0; i < symbols.length; i++) {\n // Don't need to worry about cloning a symbol because it is a primitive,\n // like a number or string.\n var symbol = symbols[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, symbol);\n if (descriptor && !descriptor.enumerable && !includeNonEnumerable) {\n continue;\n }\n child[symbol] = _clone(parent[symbol], depth - 1);\n if (!descriptor.enumerable) {\n Object.defineProperty(child, symbol, {\n enumerable: false\n });\n }\n }\n }\n\n if (includeNonEnumerable) {\n var allPropertyNames = Object.getOwnPropertyNames(parent);\n for (var i = 0; i < allPropertyNames.length; i++) {\n var propertyName = allPropertyNames[i];\n var descriptor = Object.getOwnPropertyDescriptor(parent, propertyName);\n if (descriptor && descriptor.enumerable) {\n continue;\n }\n child[propertyName] = _clone(parent[propertyName], depth - 1);\n Object.defineProperty(child, propertyName, {\n enumerable: false\n });\n }\n }\n\n return child;\n }\n\n return _clone(parent, depth);\n}\n\n/**\n * Simple flat clone using prototype, accepts only objects, usefull for property\n * override on FLAT configuration object (no nested props).\n *\n * USE WITH CAUTION! This may not behave as you wish if you do not know how this\n * works.\n */\nclone.clonePrototype = function clonePrototype(parent) {\n if (parent === null)\n return null;\n\n var c = function () {};\n c.prototype = parent;\n return new c();\n};\n\n// private utility functions\n\nfunction __objToStr(o) {\n return Object.prototype.toString.call(o);\n}\nclone.__objToStr = __objToStr;\n\nfunction __isDate(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Date]';\n}\nclone.__isDate = __isDate;\n\nfunction __isArray(o) {\n return typeof o === 'object' && __objToStr(o) === '[object Array]';\n}\nclone.__isArray = __isArray;\n\nfunction __isRegExp(o) {\n return typeof o === 'object' && __objToStr(o) === '[object RegExp]';\n}\nclone.__isRegExp = __isRegExp;\n\nfunction __getRegExpFlags(re) {\n var flags = '';\n if (re.global) flags += 'g';\n if (re.ignoreCase) flags += 'i';\n if (re.multiline) flags += 'm';\n return flags;\n}\nclone.__getRegExpFlags = __getRegExpFlags;\n\nreturn clone;\n})();\n\nif (typeof module === 'object' && module.exports) {\n module.exports = clone;\n}\n","/* jshint proto: true */\nimport * as Constants from './constants';\nimport CloneHelper from 'clone';\n\nexport function getLocation(index, inputStream) {\n let n = index + 1;\n let line = null;\n let column = -1;\n\n while (--n >= 0 && inputStream.charAt(n) !== '\\n') {\n column++;\n }\n\n if (typeof index === 'number') {\n line = (inputStream.slice(0, index).match(/\\n/g) || '').length;\n }\n\n return {\n line,\n column\n };\n}\n\nexport function copyArray(arr) {\n let i;\n const length = arr.length;\n const copy = new Array(length);\n\n for (i = 0; i < length; i++) {\n copy[i] = arr[i];\n }\n return copy;\n}\n\nexport function clone(obj) {\n const cloned = {};\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n cloned[prop] = obj[prop];\n }\n }\n return cloned;\n}\n\nexport function defaults(obj1, obj2) {\n let newObj = obj2 || {};\n if (!obj2._defaults) {\n newObj = {};\n const defaults = CloneHelper(obj1);\n newObj._defaults = defaults;\n const cloned = obj2 ? CloneHelper(obj2) : {};\n Object.assign(newObj, defaults, cloned);\n }\n return newObj;\n}\n\nexport function copyOptions(obj1, obj2) {\n if (obj2 && obj2._defaults) {\n return obj2;\n }\n const opts = defaults(obj1, obj2);\n if (opts.strictMath) {\n opts.math = Constants.Math.STRICT_LEGACY;\n }\n // Back compat with changed relativeUrls option\n if (opts.relativeUrls) {\n opts.rewriteUrls = Constants.RewriteUrls.ALL;\n }\n if (typeof opts.math === 'string') {\n switch (opts.math.toLowerCase()) {\n case 'always':\n opts.math = Constants.Math.ALWAYS;\n break;\n case 'parens-division':\n opts.math = Constants.Math.PARENS_DIVISION;\n break;\n case 'strict':\n case 'parens':\n opts.math = Constants.Math.PARENS;\n break;\n case 'strict-legacy':\n opts.math = Constants.Math.STRICT_LEGACY;\n }\n }\n if (typeof opts.rewriteUrls === 'string') {\n switch (opts.rewriteUrls.toLowerCase()) {\n case 'off':\n opts.rewriteUrls = Constants.RewriteUrls.OFF;\n break;\n case 'local':\n opts.rewriteUrls = Constants.RewriteUrls.LOCAL;\n break;\n case 'all':\n opts.rewriteUrls = Constants.RewriteUrls.ALL;\n break;\n }\n }\n return opts;\n}\n\nexport function merge(obj1, obj2) {\n for (const prop in obj2) {\n if (obj2.hasOwnProperty(prop)) {\n obj1[prop] = obj2[prop];\n }\n }\n return obj1;\n}\n\nexport function flattenArray(arr, result = []) {\n for (let i = 0, length = arr.length; i < length; i++) {\n const value = arr[i];\n if (Array.isArray(value)) {\n flattenArray(value, result);\n } else {\n if (value !== undefined) {\n result.push(value);\n }\n }\n }\n return result;\n}","import * as utils from './utils';\n\nconst anonymousFunc = /(|Function):(\\d+):(\\d+)/;\n\n/**\n * This is a centralized class of any error that could be thrown internally (mostly by the parser).\n * Besides standard .message it keeps some additional data like a path to the file where the error\n * occurred along with line and column numbers.\n *\n * @class\n * @extends Error\n * @type {module.LessError}\n *\n * @prop {string} type\n * @prop {string} filename\n * @prop {number} index\n * @prop {number} line\n * @prop {number} column\n * @prop {number} callLine\n * @prop {number} callExtract\n * @prop {string[]} extract\n *\n * @param {Object} e - An error object to wrap around or just a descriptive object\n * @param {Object} fileContentMap - An object with file contents in 'contents' property (like importManager) @todo - move to fileManager?\n * @param {string} [currentFilename]\n */\nconst LessError = function LessError(e, fileContentMap, currentFilename) {\n Error.call(this);\n\n const filename = e.filename || currentFilename;\n\n this.message = e.message;\n this.stack = e.stack;\n\n if (fileContentMap && filename) {\n const input = fileContentMap.contents[filename];\n const loc = utils.getLocation(e.index, input);\n const line = loc.line;\n const col = loc.column;\n const callLine = e.call && utils.getLocation(e.call, input).line;\n const lines = input ? input.split('\\n') : '';\n\n this.type = e.type || 'Syntax';\n this.filename = filename;\n this.index = e.index;\n this.line = typeof line === 'number' ? line + 1 : null;\n this.column = col;\n\n if (!this.line && this.stack) {\n const found = this.stack.match(anonymousFunc);\n\n /**\n * We have to figure out how this environment stringifies anonymous functions\n * so we can correctly map plugin errors.\n * \n * Note, in Node 8, the output of anonymous funcs varied based on parameters\n * being present or not, so we inject dummy params.\n */\n const func = new Function('a', 'throw new Error()');\n let lineAdjust = 0;\n try {\n func();\n } catch (e) {\n const match = e.stack.match(anonymousFunc);\n const line = parseInt(match[2]);\n lineAdjust = 1 - line;\n }\n\n if (found) {\n if (found[2]) {\n this.line = parseInt(found[2]) + lineAdjust;\n }\n if (found[3]) {\n this.column = parseInt(found[3]);\n }\n }\n }\n\n this.callLine = callLine + 1;\n this.callExtract = lines[callLine];\n\n this.extract = [\n lines[this.line - 2],\n lines[this.line - 1],\n lines[this.line]\n ];\n }\n\n};\n\nif (typeof Object.create === 'undefined') {\n const F = () => {};\n F.prototype = Error.prototype;\n LessError.prototype = new F();\n} else {\n LessError.prototype = Object.create(Error.prototype);\n}\n\nLessError.prototype.constructor = LessError;\n\n/**\n * An overridden version of the default Object.prototype.toString\n * which uses additional information to create a helpful message.\n *\n * @param {Object} options\n * @returns {string}\n */\nLessError.prototype.toString = function(options = {}) {\n let message = '';\n const extract = this.extract || [];\n let error = [];\n let stylize = str => str;\n if (options.stylize) {\n const type = typeof options.stylize;\n if (type !== 'function') {\n throw Error(`options.stylize should be a function, got a ${type}!`);\n }\n stylize = options.stylize;\n }\n\n if (this.line !== null) {\n if (typeof extract[0] === 'string') {\n error.push(stylize(`${this.line - 1} ${extract[0]}`, 'grey'));\n }\n\n if (typeof extract[1] === 'string') {\n let errorTxt = `${this.line} `;\n if (extract[1]) {\n errorTxt += extract[1].slice(0, this.column) +\n stylize(stylize(stylize(extract[1].substr(this.column, 1), 'bold') +\n extract[1].slice(this.column + 1), 'red'), 'inverse');\n }\n error.push(errorTxt);\n }\n\n if (typeof extract[2] === 'string') {\n error.push(stylize(`${this.line + 1} ${extract[2]}`, 'grey'));\n }\n error = `${error.join('\\n') + stylize('', 'reset')}\\n`;\n }\n\n message += stylize(`${this.type}Error: ${this.message}`, 'red');\n if (this.filename) {\n message += stylize(' in ', 'red') + this.filename;\n }\n if (this.line) {\n message += stylize(` on line ${this.line}, column ${this.column + 1}:`, 'grey');\n }\n\n message += `\\n${error}`;\n\n if (this.callLine) {\n message += `${stylize('from ', 'red') + (this.filename || '')}/n`;\n message += `${stylize(this.callLine, 'grey')} ${this.callExtract}/n`;\n }\n\n return message;\n};\n\nexport default LessError;","import Node from './node';\nimport Element from './element';\nimport LessError from '../less-error';\n\nclass Selector extends Node {\n constructor(elements, extendList, condition, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.extendList = extendList;\n this.condition = condition;\n this.evaldCondition = !condition;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.elements = this.getElements(elements);\n this.mixinElements_ = undefined;\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.elements, this);\n }\n\n accept(visitor) {\n if (this.elements) {\n this.elements = visitor.visitArray(this.elements);\n }\n if (this.extendList) {\n this.extendList = visitor.visitArray(this.extendList);\n }\n if (this.condition) {\n this.condition = visitor.visit(this.condition);\n }\n }\n\n createDerived(elements, extendList, evaldCondition) {\n elements = this.getElements(elements);\n const newSelector = new Selector(elements, extendList || this.extendList,\n null, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n newSelector.evaldCondition = (evaldCondition != null) ? evaldCondition : this.evaldCondition;\n newSelector.mediaEmpty = this.mediaEmpty;\n return newSelector;\n }\n\n getElements(els) {\n if (!els) {\n return [new Element('', '&', false, this._index, this._fileInfo)];\n }\n if (typeof els === 'string') {\n this.parse.parseNode(\n els, \n ['selector'],\n this._index, \n this._fileInfo, \n function(err, result) {\n if (err) {\n throw new LessError({\n index: err.index,\n message: err.message\n }, this.parse.imports, this._fileInfo.filename);\n }\n els = result[0].elements;\n });\n }\n return els;\n }\n\n createEmptySelectors() {\n const el = new Element('', '&', false, this._index, this._fileInfo);\n const sels = [new Selector([el], null, null, this._index, this._fileInfo)];\n sels[0].mediaEmpty = true;\n return sels;\n }\n\n match(other) {\n const elements = this.elements;\n const len = elements.length;\n let olen;\n let i;\n\n other = other.mixinElements();\n olen = other.length;\n if (olen === 0 || len < olen) {\n return 0;\n } else {\n for (i = 0; i < olen; i++) {\n if (elements[i].value !== other[i]) {\n return 0;\n }\n }\n }\n\n return olen; // return number of matched elements\n }\n\n mixinElements() {\n if (this.mixinElements_) {\n return this.mixinElements_;\n }\n\n let elements = this.elements.map( v => v.combinator.value + (v.value.value || v.value)).join('').match(/[,&#\\*\\.\\w-]([\\w-]|(\\\\.))*/g);\n\n if (elements) {\n if (elements[0] === '&') {\n elements.shift();\n }\n } else {\n elements = [];\n }\n\n return (this.mixinElements_ = elements);\n }\n\n isJustParentSelector() {\n return !this.mediaEmpty &&\n this.elements.length === 1 &&\n this.elements[0].value === '&' &&\n (this.elements[0].combinator.value === ' ' || this.elements[0].combinator.value === '');\n }\n\n eval(context) {\n const evaldCondition = this.condition && this.condition.eval(context);\n let elements = this.elements;\n let extendList = this.extendList;\n\n elements = elements && elements.map(e => e.eval(context));\n extendList = extendList && extendList.map(extend => extend.eval(context));\n\n return this.createDerived(elements, extendList, evaldCondition);\n }\n\n genCSS(context, output) {\n let i;\n let element;\n if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {\n output.add(' ', this.fileInfo(), this.getIndex());\n }\n for (i = 0; i < this.elements.length; i++) {\n element = this.elements[i];\n element.genCSS(context, output);\n }\n }\n\n getIsOutput() {\n return this.evaldCondition;\n }\n}\n\nSelector.prototype.type = 'Selector';\nexport default Selector;\n","import Node from './node';\n\nclass Value extends Node {\n constructor(value) {\n super();\n\n if (!value) {\n throw new Error('Value requires an array argument');\n }\n if (!Array.isArray(value)) {\n this.value = [ value ];\n }\n else {\n this.value = value;\n }\n }\n\n accept(visitor) {\n if (this.value) {\n this.value = visitor.visitArray(this.value);\n }\n }\n\n eval(context) {\n if (this.value.length === 1) {\n return this.value[0].eval(context);\n } else {\n return new Value(this.value.map(v => v.eval(context)));\n }\n }\n\n genCSS(context, output) {\n let i;\n for (i = 0; i < this.value.length; i++) {\n this.value[i].genCSS(context, output);\n if (i + 1 < this.value.length) {\n output.add((context && context.compress) ? ',' : ', ');\n }\n }\n }\n}\n\nValue.prototype.type = 'Value';\nexport default Value;\n","import Node from './node';\n\nclass Keyword extends Node {\n constructor(value) {\n super();\n\n this.value = value;\n }\n\n genCSS(context, output) {\n if (this.value === '%') { throw { type: 'Syntax', message: 'Invalid % without number' }; }\n output.add(this.value);\n }\n}\n\nKeyword.prototype.type = 'Keyword';\n\nKeyword.True = new Keyword('true');\nKeyword.False = new Keyword('false');\n\nexport default Keyword;\n","import Node from './node';\n\nclass Anonymous extends Node {\n constructor(value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {\n super();\n\n this.value = value;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.mapLines = mapLines;\n this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike;\n this.allowRoot = true;\n this.copyVisibilityInfo(visibilityInfo);\n }\n\n eval() {\n return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());\n }\n\n compare(other) {\n return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n }\n\n isRulesetLike() {\n return this.rulesetLike;\n }\n\n genCSS(context, output) {\n this.nodeVisible = Boolean(this.value);\n if (this.nodeVisible) {\n output.add(this.value, this._fileInfo, this._index, this.mapLines);\n }\n }\n}\n\nAnonymous.prototype.type = 'Anonymous';\nexport default Anonymous;\n","import Node from './node';\nimport Value from './value';\nimport Keyword from './keyword';\nimport Anonymous from './anonymous';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\n\nclass Declaration extends Node {\n constructor(name, value, important, merge, index, currentFileInfo, inline, variable) {\n super();\n\n this.name = name;\n this.value = (value instanceof Node) ? value : new Value([value ? new Anonymous(value) : null]);\n this.important = important ? ` ${important.trim()}` : '';\n this.merge = merge;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.inline = inline || false;\n this.variable = (variable !== undefined) ? variable\n : (name.charAt && (name.charAt(0) === '@'));\n this.allowRoot = true;\n this.setParent(this.value, this);\n }\n\n genCSS(context, output) {\n output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());\n try {\n this.value.genCSS(context, output);\n }\n catch (e) {\n e.index = this._index;\n e.filename = this._fileInfo.filename;\n throw e;\n }\n output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);\n }\n\n eval(context) {\n let mathBypass = false;\n let prevMath;\n let name = this.name;\n let evaldValue;\n let variable = this.variable;\n if (typeof name !== 'string') {\n // expand 'primitive' name directly to get\n // things faster (~10% for benchmark.less):\n name = (name.length === 1) && (name[0] instanceof Keyword) ?\n name[0].value : evalName(context, name);\n variable = false; // never treat expanded interpolation as new variable name\n }\n\n // @todo remove when parens-division is default\n if (name === 'font' && context.math === MATH.ALWAYS) {\n mathBypass = true;\n prevMath = context.math;\n context.math = MATH.PARENS_DIVISION;\n }\n try {\n context.importantScope.push({});\n evaldValue = this.value.eval(context);\n\n if (!this.variable && evaldValue.type === 'DetachedRuleset') {\n throw { message: 'Rulesets cannot be evaluated on a property.',\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n let important = this.important;\n const importantResult = context.importantScope.pop();\n if (!important && importantResult.important) {\n important = importantResult.important;\n }\n\n return new Declaration(name,\n evaldValue,\n important,\n this.merge,\n this.getIndex(), this.fileInfo(), this.inline,\n variable);\n }\n catch (e) {\n if (typeof e.index !== 'number') {\n e.index = this.getIndex();\n e.filename = this.fileInfo().filename;\n }\n throw e;\n }\n finally {\n if (mathBypass) {\n context.math = prevMath;\n }\n }\n }\n\n makeImportant() {\n return new Declaration(this.name,\n this.value,\n '!important',\n this.merge,\n this.getIndex(), this.fileInfo(), this.inline);\n }\n}\n\nfunction evalName(context, name) {\n let value = '';\n let i;\n const n = name.length;\n const output = {add: function (s) {value += s;}};\n for (i = 0; i < n; i++) {\n name[i].eval(context).genCSS(context, output);\n }\n return value;\n}\n\nDeclaration.prototype.type = 'Declaration';\nexport default Declaration;","const debugInfo = (context, ctx, lineSeparator) => {\n let result = '';\n if (context.dumpLineNumbers && !context.compress) {\n switch (context.dumpLineNumbers) {\n case 'comments':\n result = debugInfo.asComment(ctx);\n break;\n case 'mediaquery':\n result = debugInfo.asMediaQuery(ctx);\n break;\n case 'all':\n result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx);\n break;\n }\n }\n return result;\n};\n\ndebugInfo.asComment = ctx => `/* line ${ctx.debugInfo.lineNumber}, ${ctx.debugInfo.fileName} */\\n`;\n\ndebugInfo.asMediaQuery = ctx => {\n let filenameWithProtocol = ctx.debugInfo.fileName;\n if (!/^[a-z]+:\\/\\//i.test(filenameWithProtocol)) {\n filenameWithProtocol = `file://${filenameWithProtocol}`;\n }\n return `@media -sass-debug-info{filename{font-family:${filenameWithProtocol.replace(/([.:\\/\\\\])/g, a => {\n if (a == '\\\\') {\n a = '\\/';\n }\n return `\\\\${a}`;\n })}}line{font-family:\\\\00003${ctx.debugInfo.lineNumber}}}\\n`;\n};\n\nexport default debugInfo;\n","import Node from './node';\nimport getDebugInfo from './debug-info';\n\nclass Comment extends Node {\n constructor(value, isLineComment, index, currentFileInfo) {\n super();\n\n this.value = value;\n this.isLineComment = isLineComment;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.allowRoot = true;\n }\n\n genCSS(context, output) {\n if (this.debugInfo) {\n output.add(getDebugInfo(context, this), this.fileInfo(), this.getIndex());\n }\n output.add(this.value);\n }\n\n isSilent(context) {\n const isCompressed = context.compress && this.value[2] !== '!';\n return this.isLineComment || isCompressed;\n }\n}\n\nComment.prototype.type = 'Comment';\nexport default Comment;\n","const contexts = {};\nexport default contexts;\nimport * as Constants from './constants';\n\nconst copyFromOriginal = function copyFromOriginal(original, destination, propertiesToCopy) {\n if (!original) { return; }\n\n for (let i = 0; i < propertiesToCopy.length; i++) {\n if (original.hasOwnProperty(propertiesToCopy[i])) {\n destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];\n }\n }\n};\n\n/*\n parse is used whilst parsing\n */\nconst parseCopyProperties = [\n // options\n 'paths', // option - unmodified - paths to search for imports on\n 'rewriteUrls', // option - whether to adjust URL's to be relative\n 'rootpath', // option - rootpath to append to URL's\n 'strictImports', // option -\n 'insecure', // option - whether to allow imports from insecure ssl hosts\n 'dumpLineNumbers', // option - whether to dump line numbers\n 'compress', // option - whether to compress\n 'syncImport', // option - whether to import synchronously\n 'chunkInput', // option - whether to chunk input. more performant but causes parse issues.\n 'mime', // browser only - mime type for sheet import\n 'useFileCache', // browser only - whether to use the per file session cache\n // context\n 'processImports', // option & context - whether to process imports. if false then imports will not be imported.\n // Used by the import manager to stop multiple import visitors being created.\n 'pluginManager' // Used as the plugin manager for the session\n];\n\ncontexts.Parse = function(options) {\n copyFromOriginal(options, this, parseCopyProperties);\n\n if (typeof this.paths === 'string') { this.paths = [this.paths]; }\n};\n\nconst evalCopyProperties = [\n 'paths', // additional include paths\n 'compress', // whether to compress\n 'math', // whether math has to be within parenthesis\n 'strictUnits', // whether units need to evaluate correctly\n 'sourceMap', // whether to output a source map\n 'importMultiple', // whether we are currently importing multiple copies\n 'urlArgs', // whether to add args into url tokens\n 'javascriptEnabled', // option - whether Inline JavaScript is enabled. if undefined, defaults to false\n 'pluginManager', // Used as the plugin manager for the session\n 'importantScope', // used to bubble up !important statements\n 'rewriteUrls' // option - whether to adjust URL's to be relative\n];\n\nfunction isPathRelative(path) {\n return !/^(?:[a-z-]+:|\\/|#)/i.test(path);\n}\n\nfunction isPathLocalRelative(path) {\n return path.charAt(0) === '.';\n}\n\ncontexts.Eval = class {\n constructor(options, frames) {\n copyFromOriginal(options, this, evalCopyProperties);\n\n if (typeof this.paths === 'string') { this.paths = [this.paths]; }\n\n this.frames = frames || [];\n this.importantScope = this.importantScope || [];\n this.inCalc = false;\n this.mathOn = true;\n }\n\n enterCalc() {\n if (!this.calcStack) {\n this.calcStack = [];\n }\n this.calcStack.push(true);\n this.inCalc = true;\n }\n\n exitCalc() {\n this.calcStack.pop();\n if (!this.calcStack) {\n this.inCalc = false;\n }\n }\n\n inParenthesis() {\n if (!this.parensStack) {\n this.parensStack = [];\n }\n this.parensStack.push(true);\n };\n\n outOfParenthesis() {\n this.parensStack.pop();\n };\n\n isMathOn(op) {\n if (!this.mathOn) {\n return false;\n }\n if (op === '/' && this.math !== Constants.Math.ALWAYS && (!this.parensStack || !this.parensStack.length)) {\n return false;\n }\n if (this.math > Constants.Math.PARENS_DIVISION) {\n return this.parensStack && this.parensStack.length;\n }\n return true;\n }\n\n pathRequiresRewrite(path) {\n const isRelative = this.rewriteUrls === Constants.RewriteUrls.LOCAL ? isPathLocalRelative : isPathRelative;\n\n return isRelative(path);\n }\n\n rewritePath(path, rootpath) {\n let newPath;\n\n rootpath = rootpath || '';\n newPath = this.normalizePath(rootpath + path);\n\n // If a path was explicit relative and the rootpath was not an absolute path\n // we must ensure that the new path is also explicit relative.\n if (isPathLocalRelative(path) &&\n isPathRelative(rootpath) &&\n isPathLocalRelative(newPath) === false) {\n newPath = `./${newPath}`;\n }\n\n return newPath;\n }\n\n normalizePath(path) {\n const segments = path.split('/').reverse();\n let segment;\n\n path = [];\n while (segments.length !== 0) {\n segment = segments.pop();\n switch ( segment ) {\n case '.':\n break;\n case '..':\n if ((path.length === 0) || (path[path.length - 1] === '..')) {\n path.push( segment );\n } else {\n path.pop();\n }\n break;\n default:\n path.push(segment);\n break;\n }\n }\n\n return path.join('/');\n }\n}\n","function makeRegistry( base ) {\n return {\n _data: {},\n add: function(name, func) {\n // precautionary case conversion, as later querying of\n // the registry by function-caller uses lower case as well.\n name = name.toLowerCase();\n\n if (this._data.hasOwnProperty(name)) {\n // TODO warn\n }\n this._data[name] = func;\n },\n addMultiple: function(functions) {\n Object.keys(functions).forEach(\n name => {\n this.add(name, functions[name]);\n });\n },\n get: function(name) {\n return this._data[name] || ( base && base.get( name ));\n },\n getLocalFunctions: function() {\n return this._data;\n },\n inherit: function() {\n return makeRegistry( this );\n },\n create: function(base) {\n return makeRegistry(base);\n }\n };\n}\n\nexport default makeRegistry( null );","import Keyword from '../tree/keyword';\n\nconst defaultFunc = {\n eval: function () {\n const v = this.value_;\n const e = this.error_;\n if (e) {\n throw e;\n }\n if (v != null) {\n return v ? Keyword.True : Keyword.False;\n }\n },\n value: function (v) {\n this.value_ = v;\n },\n error: function (e) {\n this.error_ = e;\n },\n reset: function () {\n this.value_ = this.error_ = null;\n }\n};\n\nexport default defaultFunc;\n","import Node from './node';\nimport Declaration from './declaration';\nimport Keyword from './keyword';\nimport Comment from './comment';\nimport Paren from './paren';\nimport Selector from './selector';\nimport Element from './element';\nimport Anonymous from './anonymous';\nimport contexts from '../contexts';\nimport globalFunctionRegistry from '../functions/function-registry';\nimport defaultFunc from '../functions/default';\nimport getDebugInfo from './debug-info';\nimport * as utils from '../utils';\n\nclass Ruleset extends Node {\n constructor(selectors, rules, strictImports, visibilityInfo) {\n super();\n\n this.selectors = selectors;\n this.rules = rules;\n this._lookups = {};\n this._variables = null;\n this._properties = null;\n this.strictImports = strictImports;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n\n this.setParent(this.selectors, this);\n this.setParent(this.rules, this);\n\n }\n\n isRulesetLike() {\n return true;\n }\n\n accept(visitor) {\n if (this.paths) {\n this.paths = visitor.visitArray(this.paths, true);\n } else if (this.selectors) {\n this.selectors = visitor.visitArray(this.selectors);\n }\n if (this.rules && this.rules.length) {\n this.rules = visitor.visitArray(this.rules);\n }\n }\n\n eval(context) {\n const that = this;\n let selectors;\n let selCnt;\n let selector;\n let i;\n let hasVariable;\n let hasOnePassingSelector = false;\n\n if (this.selectors && (selCnt = this.selectors.length)) {\n selectors = new Array(selCnt);\n defaultFunc.error({\n type: 'Syntax',\n message: 'it is currently only allowed in parametric mixin guards,'\n });\n\n for (i = 0; i < selCnt; i++) {\n selector = this.selectors[i].eval(context);\n for (var j = 0; j < selector.elements.length; j++) {\n if (selector.elements[j].isVariable) {\n hasVariable = true;\n break;\n }\n }\n selectors[i] = selector;\n if (selector.evaldCondition) {\n hasOnePassingSelector = true;\n }\n }\n\n if (hasVariable) {\n const toParseSelectors = new Array(selCnt);\n for (i = 0; i < selCnt; i++) {\n selector = selectors[i];\n toParseSelectors[i] = selector.toCSS(context);\n }\n this.parse.parseNode(\n toParseSelectors.join(','),\n [\"selectors\"], \n selectors[0].getIndex(), \n selectors[0].fileInfo(), \n (err, result) => {\n if (result) {\n selectors = utils.flattenArray(result);\n }\n });\n }\n\n defaultFunc.reset();\n } else {\n hasOnePassingSelector = true;\n }\n\n let rules = this.rules ? utils.copyArray(this.rules) : null;\n const ruleset = new Ruleset(selectors, rules, this.strictImports, this.visibilityInfo());\n let rule;\n let subRule;\n\n ruleset.originalRuleset = this;\n ruleset.root = this.root;\n ruleset.firstRoot = this.firstRoot;\n ruleset.allowImports = this.allowImports;\n\n if (this.debugInfo) {\n ruleset.debugInfo = this.debugInfo;\n }\n\n if (!hasOnePassingSelector) {\n rules.length = 0;\n }\n\n // inherit a function registry from the frames stack when possible;\n // otherwise from the global registry\n ruleset.functionRegistry = (frames => {\n let i = 0;\n const n = frames.length;\n let found;\n for ( ; i !== n ; ++i ) {\n found = frames[ i ].functionRegistry;\n if ( found ) { return found; }\n }\n return globalFunctionRegistry;\n })(context.frames).inherit();\n\n // push the current ruleset to the frames stack\n const ctxFrames = context.frames;\n ctxFrames.unshift(ruleset);\n\n // currrent selectors\n let ctxSelectors = context.selectors;\n if (!ctxSelectors) {\n context.selectors = ctxSelectors = [];\n }\n ctxSelectors.unshift(this.selectors);\n\n // Evaluate imports\n if (ruleset.root || ruleset.allowImports || !ruleset.strictImports) {\n ruleset.evalImports(context);\n }\n\n // Store the frames around mixin definitions,\n // so they can be evaluated like closures when the time comes.\n const rsRules = ruleset.rules;\n for (i = 0; (rule = rsRules[i]); i++) {\n if (rule.evalFirst) {\n rsRules[i] = rule.eval(context);\n }\n }\n\n const mediaBlockCount = (context.mediaBlocks && context.mediaBlocks.length) || 0;\n\n // Evaluate mixin calls.\n for (i = 0; (rule = rsRules[i]); i++) {\n if (rule.type === 'MixinCall') {\n /* jshint loopfunc:true */\n rules = rule.eval(context).filter(r => {\n if ((r instanceof Declaration) && r.variable) {\n // do not pollute the scope if the variable is\n // already there. consider returning false here\n // but we need a way to \"return\" variable from mixins\n return !(ruleset.variable(r.name));\n }\n return true;\n });\n rsRules.splice(...[i, 1].concat(rules));\n i += rules.length - 1;\n ruleset.resetCache();\n } else if (rule.type === 'VariableCall') {\n /* jshint loopfunc:true */\n rules = rule.eval(context).rules.filter(r => {\n if ((r instanceof Declaration) && r.variable) {\n // do not pollute the scope at all\n return false;\n }\n return true;\n });\n rsRules.splice(...[i, 1].concat(rules));\n i += rules.length - 1;\n ruleset.resetCache();\n }\n }\n\n // Evaluate everything else\n for (i = 0; (rule = rsRules[i]); i++) {\n if (!rule.evalFirst) {\n rsRules[i] = rule = rule.eval ? rule.eval(context) : rule;\n }\n }\n\n // Evaluate everything else\n for (i = 0; (rule = rsRules[i]); i++) {\n // for rulesets, check if it is a css guard and can be removed\n if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {\n // check if it can be folded in (e.g. & where)\n if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {\n rsRules.splice(i--, 1);\n\n for (var j = 0; (subRule = rule.rules[j]); j++) {\n if (subRule instanceof Node) {\n subRule.copyVisibilityInfo(rule.visibilityInfo());\n if (!(subRule instanceof Declaration) || !subRule.variable) {\n rsRules.splice(++i, 0, subRule);\n }\n }\n }\n }\n }\n }\n\n // Pop the stack\n ctxFrames.shift();\n ctxSelectors.shift();\n\n if (context.mediaBlocks) {\n for (i = mediaBlockCount; i < context.mediaBlocks.length; i++) {\n context.mediaBlocks[i].bubbleSelectors(selectors);\n }\n }\n\n return ruleset;\n }\n\n evalImports(context) {\n const rules = this.rules;\n let i;\n let importRules;\n if (!rules) { return; }\n\n for (i = 0; i < rules.length; i++) {\n if (rules[i].type === 'Import') {\n importRules = rules[i].eval(context);\n if (importRules && (importRules.length || importRules.length === 0)) {\n rules.splice(...[i, 1].concat(importRules));\n i += importRules.length - 1;\n } else {\n rules.splice(i, 1, importRules);\n }\n this.resetCache();\n }\n }\n }\n\n makeImportant() {\n const result = new Ruleset(this.selectors, this.rules.map(r => {\n if (r.makeImportant) {\n return r.makeImportant();\n } else {\n return r;\n }\n }), this.strictImports, this.visibilityInfo());\n\n return result;\n }\n\n matchArgs(args) {\n return !args || args.length === 0;\n }\n\n // lets you call a css selector with a guard\n matchCondition(args, context) {\n const lastSelector = this.selectors[this.selectors.length - 1];\n if (!lastSelector.evaldCondition) {\n return false;\n }\n if (lastSelector.condition &&\n !lastSelector.condition.eval(\n new contexts.Eval(context,\n context.frames))) {\n return false;\n }\n return true;\n }\n\n resetCache() {\n this._rulesets = null;\n this._variables = null;\n this._properties = null;\n this._lookups = {};\n }\n\n variables() {\n if (!this._variables) {\n this._variables = !this.rules ? {} : this.rules.reduce((hash, r) => {\n if (r instanceof Declaration && r.variable === true) {\n hash[r.name] = r;\n }\n // when evaluating variables in an import statement, imports have not been eval'd\n // so we need to go inside import statements.\n // guard against root being a string (in the case of inlined less)\n if (r.type === 'Import' && r.root && r.root.variables) {\n const vars = r.root.variables();\n for (const name in vars) {\n if (vars.hasOwnProperty(name)) {\n hash[name] = r.root.variable(name);\n }\n }\n }\n return hash;\n }, {});\n }\n return this._variables;\n }\n\n properties() {\n if (!this._properties) {\n this._properties = !this.rules ? {} : this.rules.reduce((hash, r) => {\n if (r instanceof Declaration && r.variable !== true) {\n const name = (r.name.length === 1) && (r.name[0] instanceof Keyword) ?\n r.name[0].value : r.name;\n // Properties don't overwrite as they can merge\n if (!hash[`$${name}`]) {\n hash[`$${name}`] = [ r ];\n }\n else {\n hash[`$${name}`].push(r);\n }\n }\n return hash;\n }, {});\n }\n return this._properties;\n }\n\n variable(name) {\n const decl = this.variables()[name];\n if (decl) {\n return this.parseValue(decl);\n }\n }\n\n property(name) {\n const decl = this.properties()[name];\n if (decl) {\n return this.parseValue(decl);\n }\n }\n\n lastDeclaration() {\n for (let i = this.rules.length; i > 0; i--) {\n const decl = this.rules[i - 1];\n if (decl instanceof Declaration) {\n return this.parseValue(decl);\n }\n }\n }\n\n parseValue(toParse) {\n const self = this;\n function transformDeclaration(decl) {\n if (decl.value instanceof Anonymous && !decl.parsed) {\n if (typeof decl.value.value === 'string') {\n this.parse.parseNode(\n decl.value.value,\n ['value', 'important'], \n decl.value.getIndex(), \n decl.fileInfo(), \n (err, result) => {\n if (err) {\n decl.parsed = true;\n }\n if (result) {\n decl.value = result[0];\n decl.important = result[1] || '';\n decl.parsed = true;\n }\n });\n } else {\n decl.parsed = true;\n }\n\n return decl;\n }\n else {\n return decl;\n }\n }\n if (!Array.isArray(toParse)) {\n return transformDeclaration.call(self, toParse);\n }\n else {\n const nodes = [];\n toParse.forEach(n => {\n nodes.push(transformDeclaration.call(self, n));\n });\n return nodes;\n }\n }\n\n rulesets() {\n if (!this.rules) { return []; }\n\n const filtRules = [];\n const rules = this.rules;\n let i;\n let rule;\n\n for (i = 0; (rule = rules[i]); i++) {\n if (rule.isRuleset) {\n filtRules.push(rule);\n }\n }\n\n return filtRules;\n }\n\n prependRule(rule) {\n const rules = this.rules;\n if (rules) {\n rules.unshift(rule);\n } else {\n this.rules = [ rule ];\n }\n this.setParent(rule, this);\n }\n\n find(selector, self = this, filter) {\n const rules = [];\n let match;\n let foundMixins;\n const key = selector.toCSS();\n\n if (key in this._lookups) { return this._lookups[key]; }\n\n this.rulesets().forEach(rule => {\n if (rule !== self) {\n for (let j = 0; j < rule.selectors.length; j++) {\n match = selector.match(rule.selectors[j]);\n if (match) {\n if (selector.elements.length > match) {\n if (!filter || filter(rule)) {\n foundMixins = rule.find(new Selector(selector.elements.slice(match)), self, filter);\n for (let i = 0; i < foundMixins.length; ++i) {\n foundMixins[i].path.push(rule);\n }\n Array.prototype.push.apply(rules, foundMixins);\n }\n } else {\n rules.push({ rule, path: []});\n }\n break;\n }\n }\n }\n });\n this._lookups[key] = rules;\n return rules;\n }\n\n genCSS(context, output) {\n let i;\n let j;\n const charsetRuleNodes = [];\n let ruleNodes = [];\n\n let // Line number debugging\n debugInfo;\n\n let rule;\n let path;\n\n context.tabLevel = (context.tabLevel || 0);\n\n if (!this.root) {\n context.tabLevel++;\n }\n\n const tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' ');\n const tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' ');\n let sep;\n\n let charsetNodeIndex = 0;\n let importNodeIndex = 0;\n for (i = 0; (rule = this.rules[i]); i++) {\n if (rule instanceof Comment) {\n if (importNodeIndex === i) {\n importNodeIndex++;\n }\n ruleNodes.push(rule);\n } else if (rule.isCharset && rule.isCharset()) {\n ruleNodes.splice(charsetNodeIndex, 0, rule);\n charsetNodeIndex++;\n importNodeIndex++;\n } else if (rule.type === 'Import') {\n ruleNodes.splice(importNodeIndex, 0, rule);\n importNodeIndex++;\n } else {\n ruleNodes.push(rule);\n }\n }\n ruleNodes = charsetRuleNodes.concat(ruleNodes);\n\n // If this is the root node, we don't render\n // a selector, or {}.\n if (!this.root) {\n debugInfo = getDebugInfo(context, this, tabSetStr);\n\n if (debugInfo) {\n output.add(debugInfo);\n output.add(tabSetStr);\n }\n\n const paths = this.paths;\n const pathCnt = paths.length;\n let pathSubCnt;\n\n sep = context.compress ? ',' : (`,\\n${tabSetStr}`);\n\n for (i = 0; i < pathCnt; i++) {\n path = paths[i];\n if (!(pathSubCnt = path.length)) { continue; }\n if (i > 0) { output.add(sep); }\n\n context.firstSelector = true;\n path[0].genCSS(context, output);\n\n context.firstSelector = false;\n for (j = 1; j < pathSubCnt; j++) {\n path[j].genCSS(context, output);\n }\n }\n\n output.add((context.compress ? '{' : ' {\\n') + tabRuleStr);\n }\n\n // Compile rules and rulesets\n for (i = 0; (rule = ruleNodes[i]); i++) {\n\n if (i + 1 === ruleNodes.length) {\n context.lastRule = true;\n }\n\n const currentLastRule = context.lastRule;\n if (rule.isRulesetLike(rule)) {\n context.lastRule = false;\n }\n\n if (rule.genCSS) {\n rule.genCSS(context, output);\n } else if (rule.value) {\n output.add(rule.value.toString());\n }\n\n context.lastRule = currentLastRule;\n\n if (!context.lastRule && rule.isVisible()) {\n output.add(context.compress ? '' : (`\\n${tabRuleStr}`));\n } else {\n context.lastRule = false;\n }\n }\n\n if (!this.root) {\n output.add((context.compress ? '}' : `\\n${tabSetStr}}`));\n context.tabLevel--;\n }\n\n if (!output.isEmpty() && !context.compress && this.firstRoot) {\n output.add('\\n');\n }\n }\n\n joinSelectors(paths, context, selectors) {\n for (let s = 0; s < selectors.length; s++) {\n this.joinSelector(paths, context, selectors[s]);\n }\n }\n\n joinSelector(paths, context, selector) {\n function createParenthesis(elementsToPak, originalElement) {\n let replacementParen;\n let j;\n if (elementsToPak.length === 0) {\n replacementParen = new Paren(elementsToPak[0]);\n } else {\n const insideParent = new Array(elementsToPak.length);\n for (j = 0; j < elementsToPak.length; j++) {\n insideParent[j] = new Element(\n null,\n elementsToPak[j],\n originalElement.isVariable,\n originalElement._index,\n originalElement._fileInfo\n );\n }\n replacementParen = new Paren(new Selector(insideParent));\n }\n return replacementParen;\n }\n\n function createSelector(containedElement, originalElement) {\n let element;\n let selector;\n element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);\n selector = new Selector([element]);\n return selector;\n }\n\n // joins selector path from `beginningPath` with selector path in `addPath`\n // `replacedElement` contains element that is being replaced by `addPath`\n // returns concatenated path\n function addReplacementIntoPath(beginningPath, addPath, replacedElement, originalSelector) {\n let newSelectorPath;\n let lastSelector;\n let newJoinedSelector;\n // our new selector path\n newSelectorPath = [];\n\n // construct the joined selector - if & is the first thing this will be empty,\n // if not newJoinedSelector will be the last set of elements in the selector\n if (beginningPath.length > 0) {\n newSelectorPath = utils.copyArray(beginningPath);\n lastSelector = newSelectorPath.pop();\n newJoinedSelector = originalSelector.createDerived(utils.copyArray(lastSelector.elements));\n }\n else {\n newJoinedSelector = originalSelector.createDerived([]);\n }\n\n if (addPath.length > 0) {\n // /deep/ is a CSS4 selector - (removed, so should deprecate)\n // that is valid without anything in front of it\n // so if the & does not have a combinator that is \"\" or \" \" then\n // and there is a combinator on the parent, then grab that.\n // this also allows + a { & .b { .a & { ... though not sure why you would want to do that\n let combinator = replacedElement.combinator;\n\n const parentEl = addPath[0].elements[0];\n if (combinator.emptyOrWhitespace && !parentEl.combinator.emptyOrWhitespace) {\n combinator = parentEl.combinator;\n }\n // join the elements so far with the first part of the parent\n newJoinedSelector.elements.push(new Element(\n combinator,\n parentEl.value,\n replacedElement.isVariable,\n replacedElement._index,\n replacedElement._fileInfo\n ));\n newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));\n }\n\n // now add the joined selector - but only if it is not empty\n if (newJoinedSelector.elements.length !== 0) {\n newSelectorPath.push(newJoinedSelector);\n }\n\n // put together the parent selectors after the join (e.g. the rest of the parent)\n if (addPath.length > 1) {\n let restOfPath = addPath.slice(1);\n restOfPath = restOfPath.map(selector => selector.createDerived(selector.elements, []));\n newSelectorPath = newSelectorPath.concat(restOfPath);\n }\n return newSelectorPath;\n }\n\n // joins selector path from `beginningPath` with every selector path in `addPaths` array\n // `replacedElement` contains element that is being replaced by `addPath`\n // returns array with all concatenated paths\n function addAllReplacementsIntoPath( beginningPath, addPaths, replacedElement, originalSelector, result) {\n let j;\n for (j = 0; j < beginningPath.length; j++) {\n const newSelectorPath = addReplacementIntoPath(beginningPath[j], addPaths, replacedElement, originalSelector);\n result.push(newSelectorPath);\n }\n return result;\n }\n\n function mergeElementsOnToSelectors(elements, selectors) {\n let i;\n let sel;\n\n if (elements.length === 0) {\n return ;\n }\n if (selectors.length === 0) {\n selectors.push([ new Selector(elements) ]);\n return;\n }\n\n for (i = 0; (sel = selectors[i]); i++) {\n // if the previous thing in sel is a parent this needs to join on to it\n if (sel.length > 0) {\n sel[sel.length - 1] = sel[sel.length - 1].createDerived(sel[sel.length - 1].elements.concat(elements));\n }\n else {\n sel.push(new Selector(elements));\n }\n }\n }\n\n // replace all parent selectors inside `inSelector` by content of `context` array\n // resulting selectors are returned inside `paths` array\n // returns true if `inSelector` contained at least one parent selector\n function replaceParentSelector(paths, context, inSelector) {\n // The paths are [[Selector]]\n // The first list is a list of comma separated selectors\n // The inner list is a list of inheritance separated selectors\n // e.g.\n // .a, .b {\n // .c {\n // }\n // }\n // == [[.a] [.c]] [[.b] [.c]]\n //\n let i;\n\n let j;\n let k;\n let currentElements;\n let newSelectors;\n let selectorsMultiplied;\n let sel;\n let el;\n let hadParentSelector = false;\n let length;\n let lastSelector;\n function findNestedSelector(element) {\n let maybeSelector;\n if (!(element.value instanceof Paren)) {\n return null;\n }\n\n maybeSelector = element.value.value;\n if (!(maybeSelector instanceof Selector)) {\n return null;\n }\n\n return maybeSelector;\n }\n\n // the elements from the current selector so far\n currentElements = [];\n // the current list of new selectors to add to the path.\n // We will build it up. We initiate it with one empty selector as we \"multiply\" the new selectors\n // by the parents\n newSelectors = [\n []\n ];\n\n for (i = 0; (el = inSelector.elements[i]); i++) {\n // non parent reference elements just get added\n if (el.value !== '&') {\n const nestedSelector = findNestedSelector(el);\n if (nestedSelector != null) {\n // merge the current list of non parent selector elements\n // on to the current list of selectors to add\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n const nestedPaths = [];\n let replaced;\n const replacedNewSelectors = [];\n replaced = replaceParentSelector(nestedPaths, context, nestedSelector);\n hadParentSelector = hadParentSelector || replaced;\n // the nestedPaths array should have only one member - replaceParentSelector does not multiply selectors\n for (k = 0; k < nestedPaths.length; k++) {\n const replacementSelector = createSelector(createParenthesis(nestedPaths[k], el), el);\n addAllReplacementsIntoPath(newSelectors, [replacementSelector], el, inSelector, replacedNewSelectors);\n }\n newSelectors = replacedNewSelectors;\n currentElements = [];\n } else {\n currentElements.push(el);\n }\n\n } else {\n hadParentSelector = true;\n // the new list of selectors to add\n selectorsMultiplied = [];\n\n // merge the current list of non parent selector elements\n // on to the current list of selectors to add\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n // loop through our current selectors\n for (j = 0; j < newSelectors.length; j++) {\n sel = newSelectors[j];\n // if we don't have any parent paths, the & might be in a mixin so that it can be used\n // whether there are parents or not\n if (context.length === 0) {\n // the combinator used on el should now be applied to the next element instead so that\n // it is not lost\n if (sel.length > 0) {\n sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));\n }\n selectorsMultiplied.push(sel);\n }\n else {\n // and the parent selectors\n for (k = 0; k < context.length; k++) {\n // We need to put the current selectors\n // then join the last selector's elements on to the parents selectors\n const newSelectorPath = addReplacementIntoPath(sel, context[k], el, inSelector);\n // add that to our new set of selectors\n selectorsMultiplied.push(newSelectorPath);\n }\n }\n }\n\n // our new selectors has been multiplied, so reset the state\n newSelectors = selectorsMultiplied;\n currentElements = [];\n }\n }\n\n // if we have any elements left over (e.g. .a& .b == .b)\n // add them on to all the current selectors\n mergeElementsOnToSelectors(currentElements, newSelectors);\n\n for (i = 0; i < newSelectors.length; i++) {\n length = newSelectors[i].length;\n if (length > 0) {\n paths.push(newSelectors[i]);\n lastSelector = newSelectors[i][length - 1];\n newSelectors[i][length - 1] = lastSelector.createDerived(lastSelector.elements, inSelector.extendList);\n }\n }\n\n return hadParentSelector;\n }\n\n function deriveSelector(visibilityInfo, deriveFrom) {\n const newSelector = deriveFrom.createDerived(deriveFrom.elements, deriveFrom.extendList, deriveFrom.evaldCondition);\n newSelector.copyVisibilityInfo(visibilityInfo);\n return newSelector;\n }\n\n // joinSelector code follows\n let i;\n\n let newPaths;\n let hadParentSelector;\n\n newPaths = [];\n hadParentSelector = replaceParentSelector(newPaths, context, selector);\n\n if (!hadParentSelector) {\n if (context.length > 0) {\n newPaths = [];\n for (i = 0; i < context.length; i++) {\n\n const concatenated = context[i].map(deriveSelector.bind(this, selector.visibilityInfo()));\n\n concatenated.push(selector);\n newPaths.push(concatenated);\n }\n }\n else {\n newPaths = [[selector]];\n }\n }\n\n for (i = 0; i < newPaths.length; i++) {\n paths.push(newPaths[i]);\n }\n }\n}\n\nRuleset.prototype.type = 'Ruleset';\nRuleset.prototype.isRuleset = true;\nexport default Ruleset;\n","import Node from './node';\nimport Selector from './selector';\nimport Ruleset from './ruleset';\nimport Anonymous from './anonymous';\n\nclass AtRule extends Node {\n constructor(\n name,\n value,\n rules,\n index,\n currentFileInfo,\n debugInfo,\n isRooted,\n visibilityInfo\n ) {\n super();\n\n let i;\n\n this.name = name;\n this.value = (value instanceof Node) ? value : (value ? new Anonymous(value) : value);\n if (rules) {\n if (Array.isArray(rules)) {\n this.rules = rules;\n } else {\n this.rules = [rules];\n this.rules[0].selectors = (new Selector([], null, null, index, currentFileInfo)).createEmptySelectors();\n }\n for (i = 0; i < this.rules.length; i++) {\n this.rules[i].allowImports = true;\n }\n this.setParent(this.rules, this);\n }\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.debugInfo = debugInfo;\n this.isRooted = isRooted || false;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n }\n\n accept(visitor) {\n const value = this.value;\n const rules = this.rules;\n if (rules) {\n this.rules = visitor.visitArray(rules);\n }\n if (value) {\n this.value = visitor.visit(value);\n }\n }\n\n isRulesetLike() {\n return this.rules || !this.isCharset();\n }\n\n isCharset() {\n return '@charset' === this.name;\n }\n\n genCSS(context, output) {\n const value = this.value;\n const rules = this.rules;\n output.add(this.name, this.fileInfo(), this.getIndex());\n if (value) {\n output.add(' ');\n value.genCSS(context, output);\n }\n if (rules) {\n this.outputRuleset(context, output, rules);\n } else {\n output.add(';');\n }\n }\n\n eval(context) {\n let mediaPathBackup;\n let mediaBlocksBackup;\n let value = this.value;\n let rules = this.rules;\n\n // media stored inside other atrule should not bubble over it\n // backpup media bubbling information\n mediaPathBackup = context.mediaPath;\n mediaBlocksBackup = context.mediaBlocks;\n // deleted media bubbling information\n context.mediaPath = [];\n context.mediaBlocks = [];\n\n if (value) {\n value = value.eval(context);\n }\n if (rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n rules = [rules[0].eval(context)];\n rules[0].root = true;\n }\n // restore media bubbling information\n context.mediaPath = mediaPathBackup;\n context.mediaBlocks = mediaBlocksBackup;\n\n return new AtRule(this.name, value, rules,\n this.getIndex(), this.fileInfo(), this.debugInfo, this.isRooted, this.visibilityInfo());\n }\n\n variable(name) {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.variable.call(this.rules[0], name);\n }\n }\n\n find(...args) {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.find.apply(this.rules[0], args);\n }\n }\n\n rulesets() {\n if (this.rules) {\n // assuming that there is only one rule at this point - that is how parser constructs the rule\n return Ruleset.prototype.rulesets.apply(this.rules[0]);\n }\n }\n\n outputRuleset(context, output, rules) {\n const ruleCnt = rules.length;\n let i;\n context.tabLevel = (context.tabLevel | 0) + 1;\n\n // Compressed\n if (context.compress) {\n output.add('{');\n for (i = 0; i < ruleCnt; i++) {\n rules[i].genCSS(context, output);\n }\n output.add('}');\n context.tabLevel--;\n return;\n }\n\n // Non-compressed\n const tabSetStr = `\\n${Array(context.tabLevel).join(' ')}`;\n\n const tabRuleStr = `${tabSetStr} `;\n if (!ruleCnt) {\n output.add(` {${tabSetStr}}`);\n } else {\n output.add(` {${tabRuleStr}`);\n rules[0].genCSS(context, output);\n for (i = 1; i < ruleCnt; i++) {\n output.add(tabRuleStr);\n rules[i].genCSS(context, output);\n }\n output.add(`${tabSetStr}}`);\n }\n\n context.tabLevel--;\n }\n}\n\nAtRule.prototype.type = 'AtRule';\nexport default AtRule;\n","import Node from './node';\nimport contexts from '../contexts';\nimport * as utils from '../utils';\n\nclass DetachedRuleset extends Node {\n constructor(ruleset, frames) {\n super();\n\n this.ruleset = ruleset;\n this.frames = frames;\n this.setParent(this.ruleset, this);\n }\n\n accept(visitor) {\n this.ruleset = visitor.visit(this.ruleset);\n }\n\n eval(context) {\n const frames = this.frames || utils.copyArray(context.frames);\n return new DetachedRuleset(this.ruleset, frames);\n }\n\n callEval(context) {\n return this.ruleset.eval(this.frames ? new contexts.Eval(context, this.frames.concat(context.frames)) : context);\n }\n}\n\nDetachedRuleset.prototype.type = 'DetachedRuleset';\nDetachedRuleset.prototype.evalFirst = true;\nexport default DetachedRuleset;\n","import Node from './node';\nimport unitConversions from '../data/unit-conversions';\nimport * as utils from '../utils';\n\nclass Unit extends Node {\n constructor(numerator, denominator, backupUnit) {\n super();\n\n this.numerator = numerator ? utils.copyArray(numerator).sort() : [];\n this.denominator = denominator ? utils.copyArray(denominator).sort() : [];\n if (backupUnit) {\n this.backupUnit = backupUnit;\n } else if (numerator && numerator.length) {\n this.backupUnit = numerator[0];\n }\n }\n\n clone() {\n return new Unit(utils.copyArray(this.numerator), utils.copyArray(this.denominator), this.backupUnit);\n }\n\n genCSS(context, output) {\n // Dimension checks the unit is singular and throws an error if in strict math mode.\n const strictUnits = context && context.strictUnits;\n if (this.numerator.length === 1) {\n output.add(this.numerator[0]); // the ideal situation\n } else if (!strictUnits && this.backupUnit) {\n output.add(this.backupUnit);\n } else if (!strictUnits && this.denominator.length) {\n output.add(this.denominator[0]);\n }\n }\n\n toString() {\n let i;\n let returnStr = this.numerator.join('*');\n for (i = 0; i < this.denominator.length; i++) {\n returnStr += `/${this.denominator[i]}`;\n }\n return returnStr;\n }\n\n compare(other) {\n return this.is(other.toString()) ? 0 : undefined;\n }\n\n is(unitString) {\n return this.toString().toUpperCase() === unitString.toUpperCase();\n }\n\n isLength() {\n return RegExp('^(px|em|ex|ch|rem|in|cm|mm|pc|pt|ex|vw|vh|vmin|vmax)$', 'gi').test(this.toCSS());\n }\n\n isEmpty() {\n return this.numerator.length === 0 && this.denominator.length === 0;\n }\n\n isSingular() {\n return this.numerator.length <= 1 && this.denominator.length === 0;\n }\n\n map(callback) {\n let i;\n\n for (i = 0; i < this.numerator.length; i++) {\n this.numerator[i] = callback(this.numerator[i], false);\n }\n\n for (i = 0; i < this.denominator.length; i++) {\n this.denominator[i] = callback(this.denominator[i], true);\n }\n }\n\n usedUnits() {\n let group;\n const result = {};\n let mapUnit;\n let groupName;\n\n mapUnit = atomicUnit => {\n /* jshint loopfunc:true */\n if (group.hasOwnProperty(atomicUnit) && !result[groupName]) {\n result[groupName] = atomicUnit;\n }\n\n return atomicUnit;\n };\n\n for (groupName in unitConversions) {\n if (unitConversions.hasOwnProperty(groupName)) {\n group = unitConversions[groupName];\n\n this.map(mapUnit);\n }\n }\n\n return result;\n }\n\n cancel() {\n const counter = {};\n let atomicUnit;\n let i;\n\n for (i = 0; i < this.numerator.length; i++) {\n atomicUnit = this.numerator[i];\n counter[atomicUnit] = (counter[atomicUnit] || 0) + 1;\n }\n\n for (i = 0; i < this.denominator.length; i++) {\n atomicUnit = this.denominator[i];\n counter[atomicUnit] = (counter[atomicUnit] || 0) - 1;\n }\n\n this.numerator = [];\n this.denominator = [];\n\n for (atomicUnit in counter) {\n if (counter.hasOwnProperty(atomicUnit)) {\n const count = counter[atomicUnit];\n\n if (count > 0) {\n for (i = 0; i < count; i++) {\n this.numerator.push(atomicUnit);\n }\n } else if (count < 0) {\n for (i = 0; i < -count; i++) {\n this.denominator.push(atomicUnit);\n }\n }\n }\n }\n\n this.numerator.sort();\n this.denominator.sort();\n }\n}\n\nUnit.prototype.type = 'Unit';\nexport default Unit;\n","import Node from './node';\nimport unitConversions from '../data/unit-conversions';\nimport Unit from './unit';\nimport Color from './color';\n\n//\n// A number with a unit\n//\nclass Dimension extends Node {\n constructor(value, unit) {\n super();\n\n this.value = parseFloat(value);\n if (isNaN(this.value)) {\n throw new Error('Dimension is not a number.');\n }\n this.unit = (unit && unit instanceof Unit) ? unit :\n new Unit(unit ? [unit] : undefined);\n this.setParent(this.unit, this);\n }\n\n accept(visitor) {\n this.unit = visitor.visit(this.unit);\n }\n\n eval(context) {\n return this;\n }\n\n toColor() {\n return new Color([this.value, this.value, this.value]);\n }\n\n genCSS(context, output) {\n if ((context && context.strictUnits) && !this.unit.isSingular()) {\n throw new Error(`Multiple units in dimension. Correct the units or use the unit function. Bad unit: ${this.unit.toString()}`);\n }\n\n const value = this.fround(context, this.value);\n let strValue = String(value);\n\n if (value !== 0 && value < 0.000001 && value > -0.000001) {\n // would be output 1e-6 etc.\n strValue = value.toFixed(20).replace(/0+$/, '');\n }\n\n if (context && context.compress) {\n // Zero values doesn't need a unit\n if (value === 0 && this.unit.isLength()) {\n output.add(strValue);\n return;\n }\n\n // Float values doesn't need a leading zero\n if (value > 0 && value < 1) {\n strValue = (strValue).substr(1);\n }\n }\n\n output.add(strValue);\n this.unit.genCSS(context, output);\n }\n\n // In an operation between two Dimensions,\n // we default to the first Dimension's unit,\n // so `1px + 2` will yield `3px`.\n operate(context, op, other) {\n /* jshint noempty:false */\n let value = this._operate(context, op, this.value, other.value);\n\n let unit = this.unit.clone();\n\n if (op === '+' || op === '-') {\n if (unit.numerator.length === 0 && unit.denominator.length === 0) {\n unit = other.unit.clone();\n if (this.unit.backupUnit) {\n unit.backupUnit = this.unit.backupUnit;\n }\n } else if (other.unit.numerator.length === 0 && unit.denominator.length === 0) {\n // do nothing\n } else {\n other = other.convertTo(this.unit.usedUnits());\n\n if (context.strictUnits && other.unit.toString() !== unit.toString()) {\n throw new Error(`Incompatible units. Change the units or use the unit function. ` + \n `Bad units: '${unit.toString()}' and '${other.unit.toString()}'.`);\n }\n\n value = this._operate(context, op, this.value, other.value);\n }\n } else if (op === '*') {\n unit.numerator = unit.numerator.concat(other.unit.numerator).sort();\n unit.denominator = unit.denominator.concat(other.unit.denominator).sort();\n unit.cancel();\n } else if (op === '/') {\n unit.numerator = unit.numerator.concat(other.unit.denominator).sort();\n unit.denominator = unit.denominator.concat(other.unit.numerator).sort();\n unit.cancel();\n }\n return new Dimension(value, unit);\n }\n\n compare(other) {\n let a;\n let b;\n\n if (!(other instanceof Dimension)) {\n return undefined;\n }\n\n if (this.unit.isEmpty() || other.unit.isEmpty()) {\n a = this;\n b = other;\n } else {\n a = this.unify();\n b = other.unify();\n if (a.unit.compare(b.unit) !== 0) {\n return undefined;\n }\n }\n\n return Node.numericCompare(a.value, b.value);\n }\n\n unify() {\n return this.convertTo({ length: 'px', duration: 's', angle: 'rad' });\n }\n\n convertTo(conversions) {\n let value = this.value;\n const unit = this.unit.clone();\n let i;\n let groupName;\n let group;\n let targetUnit;\n let derivedConversions = {};\n let applyUnit;\n\n if (typeof conversions === 'string') {\n for (i in unitConversions) {\n if (unitConversions[i].hasOwnProperty(conversions)) {\n derivedConversions = {};\n derivedConversions[i] = conversions;\n }\n }\n conversions = derivedConversions;\n }\n applyUnit = (atomicUnit, denominator) => {\n /* jshint loopfunc:true */\n if (group.hasOwnProperty(atomicUnit)) {\n if (denominator) {\n value = value / (group[atomicUnit] / group[targetUnit]);\n } else {\n value = value * (group[atomicUnit] / group[targetUnit]);\n }\n\n return targetUnit;\n }\n\n return atomicUnit;\n };\n\n for (groupName in conversions) {\n if (conversions.hasOwnProperty(groupName)) {\n targetUnit = conversions[groupName];\n group = unitConversions[groupName];\n\n unit.map(applyUnit);\n }\n }\n\n unit.cancel();\n\n return new Dimension(value, unit);\n }\n}\n\nDimension.prototype.type = 'Dimension';\nexport default Dimension;\n","import Node from './node';\nimport Color from './color';\nimport Dimension from './dimension';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\n\nclass Operation extends Node {\n constructor(op, operands, isSpaced) {\n super();\n\n this.op = op.trim();\n this.operands = operands;\n this.isSpaced = isSpaced;\n }\n\n accept(visitor) {\n this.operands = visitor.visitArray(this.operands);\n }\n\n eval(context) {\n let a = this.operands[0].eval(context);\n let b = this.operands[1].eval(context);\n let op;\n\n if (context.isMathOn(this.op)) {\n op = this.op === './' ? '/' : this.op;\n if (a instanceof Dimension && b instanceof Color) {\n a = a.toColor();\n }\n if (b instanceof Dimension && a instanceof Color) {\n b = b.toColor();\n }\n if (!a.operate) {\n if (a instanceof Operation && a.op === '/' && context.math === MATH.PARENS_DIVISION) {\n return new Operation(this.op, [a, b], this.isSpaced);\n }\n throw { type: 'Operation',\n message: 'Operation on an invalid type' };\n }\n\n return a.operate(context, op, b);\n } else {\n return new Operation(this.op, [a, b], this.isSpaced);\n }\n }\n\n genCSS(context, output) {\n this.operands[0].genCSS(context, output);\n if (this.isSpaced) {\n output.add(' ');\n }\n output.add(this.op);\n if (this.isSpaced) {\n output.add(' ');\n }\n this.operands[1].genCSS(context, output);\n }\n}\n\nOperation.prototype.type = 'Operation';\nexport default Operation;\n","import Node from './node';\nimport Paren from './paren';\nimport Comment from './comment';\nimport Dimension from './dimension';\nimport * as Constants from '../constants';\nconst MATH = Constants.Math;\n\nclass Expression extends Node {\n constructor(value, noSpacing) {\n super();\n\n this.value = value;\n this.noSpacing = noSpacing;\n if (!value) {\n throw new Error('Expression requires an array parameter');\n }\n }\n\n accept(visitor) {\n this.value = visitor.visitArray(this.value);\n }\n\n eval(context) {\n let returnValue;\n const mathOn = context.isMathOn();\n\n const inParenthesis = this.parens && \n (context.math !== MATH.STRICT_LEGACY || !this.parensInOp);\n\n let doubleParen = false;\n if (inParenthesis) {\n context.inParenthesis();\n }\n if (this.value.length > 1) {\n returnValue = new Expression(this.value.map(e => {\n if (!e.eval) {\n return e;\n }\n return e.eval(context);\n }), this.noSpacing);\n } else if (this.value.length === 1) {\n if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {\n doubleParen = true;\n }\n returnValue = this.value[0].eval(context);\n } else {\n returnValue = this;\n }\n if (inParenthesis) {\n context.outOfParenthesis();\n }\n if (this.parens && this.parensInOp && !mathOn && !doubleParen \n && (!(returnValue instanceof Dimension))) {\n returnValue = new Paren(returnValue);\n }\n return returnValue;\n }\n\n genCSS(context, output) {\n for (let i = 0; i < this.value.length; i++) {\n this.value[i].genCSS(context, output);\n if (!this.noSpacing && i + 1 < this.value.length) {\n output.add(' ');\n }\n }\n }\n\n throwAwayComments() {\n this.value = this.value.filter(v => !(v instanceof Comment));\n }\n}\n\nExpression.prototype.type = 'Expression';\nexport default Expression;\n","import Expression from '../tree/expression';\n\nclass functionCaller {\n constructor(name, context, index, currentFileInfo) {\n this.name = name.toLowerCase();\n this.index = index;\n this.context = context;\n this.currentFileInfo = currentFileInfo;\n\n this.func = context.frames[0].functionRegistry.get(this.name);\n }\n\n isValid() {\n return Boolean(this.func);\n }\n\n call(args) {\n // This code is terrible and should be replaced as per this issue...\n // https://github.com/less/less.js/issues/2477\n if (Array.isArray(args)) {\n args = args.filter(item => {\n if (item.type === 'Comment') {\n return false;\n }\n return true;\n })\n .map(item => {\n if (item.type === 'Expression') {\n const subNodes = item.value.filter(item => {\n if (item.type === 'Comment') {\n return false;\n }\n return true;\n });\n if (subNodes.length === 1) {\n return subNodes[0];\n } else {\n return new Expression(subNodes);\n }\n }\n return item;\n });\n }\n\n return this.func(...args);\n }\n}\n\nexport default functionCaller;\n","import Node from './node';\nimport Anonymous from './anonymous';\nimport FunctionCaller from '../functions/function-caller';\n\n//\n// A function call node.\n//\nclass Call extends Node {\n constructor(name, args, index, currentFileInfo) {\n super();\n\n this.name = name;\n this.args = args;\n this.calc = name === 'calc';\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n accept(visitor) {\n if (this.args) {\n this.args = visitor.visitArray(this.args);\n }\n }\n\n //\n // When evaluating a function call,\n // we either find the function in the functionRegistry,\n // in which case we call it, passing the evaluated arguments,\n // if this returns null or we cannot find the function, we\n // simply print it out as it appeared originally [2].\n //\n // The reason why we evaluate the arguments, is in the case where\n // we try to pass a variable to a function, like: `saturate(@color)`.\n // The function should receive the value, not the variable.\n //\n eval(context) {\n /**\n * Turn off math for calc(), and switch back on for evaluating nested functions\n */\n const currentMathContext = context.mathOn;\n context.mathOn = !this.calc;\n if (this.calc || context.inCalc) {\n context.enterCalc();\n }\n const args = this.args.map(a => a.eval(context));\n if (this.calc || context.inCalc) {\n context.exitCalc();\n }\n context.mathOn = currentMathContext;\n\n let result;\n const funcCaller = new FunctionCaller(this.name, context, this.getIndex(), this.fileInfo());\n\n if (funcCaller.isValid()) {\n try {\n result = funcCaller.call(args);\n } catch (e) {\n throw { \n type: e.type || 'Runtime',\n message: `error evaluating function \\`${this.name}\\`${e.message ? `: ${e.message}` : ''}`,\n index: this.getIndex(), \n filename: this.fileInfo().filename,\n line: e.lineNumber,\n column: e.columnNumber\n };\n }\n\n if (result !== null && result !== undefined) {\n // Results that that are not nodes are cast as Anonymous nodes\n // Falsy values or booleans are returned as empty nodes\n if (!(result instanceof Node)) {\n if (!result || result === true) {\n result = new Anonymous(null); \n }\n else {\n result = new Anonymous(result.toString()); \n }\n \n }\n result._index = this._index;\n result._fileInfo = this._fileInfo;\n return result;\n }\n\n }\n\n return new Call(this.name, args, this.getIndex(), this.fileInfo());\n }\n\n genCSS(context, output) {\n output.add(`${this.name}(`, this.fileInfo(), this.getIndex());\n\n for (let i = 0; i < this.args.length; i++) {\n this.args[i].genCSS(context, output);\n if (i + 1 < this.args.length) {\n output.add(', ');\n }\n }\n\n output.add(')');\n }\n}\n\nCall.prototype.type = 'Call';\nexport default Call;\n","import Node from './node';\nimport Call from './call';\n\nclass Variable extends Node {\n constructor(name, index, currentFileInfo) {\n super();\n\n this.name = name;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n let variable;\n let name = this.name;\n\n if (name.indexOf('@@') === 0) {\n name = `@${new Variable(name.slice(1), this.getIndex(), this.fileInfo()).eval(context).value}`;\n }\n\n if (this.evaluating) {\n throw { type: 'Name',\n message: `Recursive variable definition for ${name}`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n this.evaluating = true;\n\n variable = this.find(context.frames, frame => {\n const v = frame.variable(name);\n if (v) {\n if (v.important) {\n const importantScope = context.importantScope[context.importantScope.length - 1];\n importantScope.important = v.important;\n }\n // If in calc, wrap vars in a function call to cascade evaluate args first\n if (context.inCalc) {\n return (new Call('_SELF', [v.value])).eval(context);\n }\n else {\n return v.value.eval(context);\n }\n }\n });\n if (variable) {\n this.evaluating = false;\n return variable;\n } else {\n throw { type: 'Name',\n message: `variable ${name} is undefined`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n }\n\n find(obj, fun) {\n for (let i = 0, r; i < obj.length; i++) {\n r = fun.call(obj, obj[i]);\n if (r) { return r; }\n }\n return null;\n }\n}\n\nVariable.prototype.type = 'Variable';\nexport default Variable;\n","import Node from './node';\nimport Declaration from './declaration';\n\nclass Property extends Node {\n constructor(name, index, currentFileInfo) {\n super();\n\n this.name = name;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n let property;\n const name = this.name;\n // TODO: shorten this reference\n const mergeRules = context.pluginManager.less.visitors.ToCSSVisitor.prototype._mergeRules;\n\n if (this.evaluating) {\n throw { type: 'Name',\n message: `Recursive property reference for ${name}`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n this.evaluating = true;\n\n property = this.find(context.frames, frame => {\n let v;\n const vArr = frame.property(name);\n if (vArr) {\n for (let i = 0; i < vArr.length; i++) {\n v = vArr[i];\n\n vArr[i] = new Declaration(v.name,\n v.value,\n v.important,\n v.merge,\n v.index,\n v.currentFileInfo,\n v.inline,\n v.variable\n );\n }\n mergeRules(vArr);\n\n v = vArr[vArr.length - 1];\n if (v.important) {\n const importantScope = context.importantScope[context.importantScope.length - 1];\n importantScope.important = v.important;\n }\n v = v.value.eval(context);\n return v;\n }\n });\n if (property) {\n this.evaluating = false;\n return property;\n } else {\n throw { type: 'Name',\n message: `Property '${name}' is undefined`,\n filename: this.currentFileInfo.filename,\n index: this.index };\n }\n }\n\n find(obj, fun) {\n for (let i = 0, r; i < obj.length; i++) {\n r = fun.call(obj, obj[i]);\n if (r) { return r; }\n }\n return null;\n }\n}\n\nProperty.prototype.type = 'Property';\nexport default Property;\n","import Node from './node';\n\nclass Attribute extends Node {\n constructor(key, op, value) {\n super();\n\n this.key = key;\n this.op = op;\n this.value = value;\n }\n\n eval(context) {\n return new Attribute(this.key.eval ? this.key.eval(context) : this.key,\n this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);\n }\n\n genCSS(context, output) {\n output.add(this.toCSS(context));\n }\n\n toCSS(context) {\n let value = this.key.toCSS ? this.key.toCSS(context) : this.key;\n\n if (this.op) {\n value += this.op;\n value += (this.value.toCSS ? this.value.toCSS(context) : this.value);\n }\n\n return `[${value}]`;\n }\n}\n\nAttribute.prototype.type = 'Attribute';\nexport default Attribute;\n","import Node from './node';\nimport Variable from './variable';\nimport Property from './property';\n\n\nclass Quoted extends Node {\n constructor(str, content, escaped, index, currentFileInfo) {\n super();\n\n this.escaped = (escaped == null) ? true : escaped;\n this.value = content || '';\n this.quote = str.charAt(0);\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.variableRegex = /@\\{([\\w-]+)\\}/g;\n this.propRegex = /\\$\\{([\\w-]+)\\}/g;\n this.allowRoot = escaped;\n }\n\n genCSS(context, output) {\n if (!this.escaped) {\n output.add(this.quote, this.fileInfo(), this.getIndex());\n }\n output.add(this.value);\n if (!this.escaped) {\n output.add(this.quote);\n }\n }\n\n containsVariables() {\n return this.value.match(this.variableRegex);\n }\n\n eval(context) {\n const that = this;\n let value = this.value;\n const variableReplacement = (_, name) => {\n const v = new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context, true);\n return (v instanceof Quoted) ? v.value : v.toCSS();\n };\n const propertyReplacement = (_, name) => {\n const v = new Property(`$${name}`, that.getIndex(), that.fileInfo()).eval(context, true);\n return (v instanceof Quoted) ? v.value : v.toCSS();\n };\n function iterativeReplace(value, regexp, replacementFnc) {\n let evaluatedValue = value;\n do {\n value = evaluatedValue.toString();\n evaluatedValue = value.replace(regexp, replacementFnc);\n } while (value !== evaluatedValue);\n return evaluatedValue;\n }\n value = iterativeReplace(value, this.variableRegex, variableReplacement);\n value = iterativeReplace(value, this.propRegex, propertyReplacement);\n\n return new Quoted(this.quote + value + this.quote, value, this.escaped, this.getIndex(), this.fileInfo());\n }\n\n compare(other) {\n // when comparing quoted strings allow the quote to differ\n if (other.type === 'Quoted' && !this.escaped && !other.escaped) {\n return Node.numericCompare(this.value, other.value);\n } else {\n return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;\n }\n }\n}\n\nQuoted.prototype.type = 'Quoted';\nexport default Quoted;\n","import Node from './node';\n\nclass URL extends Node {\n constructor(val, index, currentFileInfo, isEvald) {\n super();\n\n this.value = val;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.isEvald = isEvald;\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n genCSS(context, output) {\n output.add('url(');\n this.value.genCSS(context, output);\n output.add(')');\n }\n\n eval(context) {\n const val = this.value.eval(context);\n let rootpath;\n\n if (!this.isEvald) {\n // Add the rootpath if the URL requires a rewrite\n rootpath = this.fileInfo() && this.fileInfo().rootpath;\n if (typeof rootpath === 'string' &&\n typeof val.value === 'string' &&\n context.pathRequiresRewrite(val.value)) {\n if (!val.quote) {\n rootpath = escapePath(rootpath);\n }\n val.value = context.rewritePath(val.value, rootpath);\n } else {\n val.value = context.normalizePath(val.value);\n }\n\n // Add url args if enabled\n if (context.urlArgs) {\n if (!val.value.match(/^\\s*data:/)) {\n const delimiter = val.value.indexOf('?') === -1 ? '?' : '&';\n const urlArgs = delimiter + context.urlArgs;\n if (val.value.indexOf('#') !== -1) {\n val.value = val.value.replace('#', `${urlArgs}#`);\n } else {\n val.value += urlArgs;\n }\n }\n }\n }\n\n return new URL(val, this.getIndex(), this.fileInfo(), true);\n }\n}\n\nURL.prototype.type = 'Url';\n\nfunction escapePath(path) {\n return path.replace(/[\\(\\)'\"\\s]/g, match => `\\\\${match}`);\n}\n\nexport default URL;\n","import Ruleset from './ruleset';\nimport Value from './value';\nimport Selector from './selector';\nimport Anonymous from './anonymous';\nimport Expression from './expression';\nimport AtRule from './atrule';\nimport * as utils from '../utils';\n\nclass Media extends AtRule {\n constructor(value, features, index, currentFileInfo, visibilityInfo) {\n super();\n\n this._index = index;\n this._fileInfo = currentFileInfo;\n\n const selectors = (new Selector([], null, null, this._index, this._fileInfo)).createEmptySelectors();\n\n this.features = new Value(features);\n this.rules = [new Ruleset(selectors, value)];\n this.rules[0].allowImports = true;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n this.setParent(selectors, this);\n this.setParent(this.features, this);\n this.setParent(this.rules, this);\n }\n\n isRulesetLike() {\n return true;\n }\n\n accept(visitor) {\n if (this.features) {\n this.features = visitor.visit(this.features);\n }\n if (this.rules) {\n this.rules = visitor.visitArray(this.rules);\n }\n }\n\n genCSS(context, output) {\n output.add('@media ', this._fileInfo, this._index);\n this.features.genCSS(context, output);\n this.outputRuleset(context, output, this.rules);\n }\n\n eval(context) {\n if (!context.mediaBlocks) {\n context.mediaBlocks = [];\n context.mediaPath = [];\n }\n\n const media = new Media(null, [], this._index, this._fileInfo, this.visibilityInfo());\n if (this.debugInfo) {\n this.rules[0].debugInfo = this.debugInfo;\n media.debugInfo = this.debugInfo;\n }\n \n media.features = this.features.eval(context);\n\n context.mediaPath.push(media);\n context.mediaBlocks.push(media);\n\n this.rules[0].functionRegistry = context.frames[0].functionRegistry.inherit();\n context.frames.unshift(this.rules[0]);\n media.rules = [this.rules[0].eval(context)];\n context.frames.shift();\n\n context.mediaPath.pop();\n\n return context.mediaPath.length === 0 ? media.evalTop(context) :\n media.evalNested(context);\n }\n\n evalTop(context) {\n let result = this;\n\n // Render all dependent Media blocks.\n if (context.mediaBlocks.length > 1) {\n const selectors = (new Selector([], null, null, this.getIndex(), this.fileInfo())).createEmptySelectors();\n result = new Ruleset(selectors, context.mediaBlocks);\n result.multiMedia = true;\n result.copyVisibilityInfo(this.visibilityInfo());\n this.setParent(result, this);\n }\n\n delete context.mediaBlocks;\n delete context.mediaPath;\n\n return result;\n }\n\n evalNested(context) {\n let i;\n let value;\n const path = context.mediaPath.concat([this]);\n\n // Extract the media-query conditions separated with `,` (OR).\n for (i = 0; i < path.length; i++) {\n value = path[i].features instanceof Value ?\n path[i].features.value : path[i].features;\n path[i] = Array.isArray(value) ? value : [value];\n }\n\n // Trace all permutations to generate the resulting media-query.\n //\n // (a, b and c) with nested (d, e) ->\n // a and d\n // a and e\n // b and c and d\n // b and c and e\n this.features = new Value(this.permute(path).map(path => {\n path = path.map(fragment => fragment.toCSS ? fragment : new Anonymous(fragment));\n\n for (i = path.length - 1; i > 0; i--) {\n path.splice(i, 0, new Anonymous('and'));\n }\n\n return new Expression(path);\n }));\n this.setParent(this.features, this);\n\n // Fake a tree-node that doesn't output anything.\n return new Ruleset([], []);\n }\n\n permute(arr) {\n if (arr.length === 0) {\n return [];\n } else if (arr.length === 1) {\n return arr[0];\n } else {\n const result = [];\n const rest = this.permute(arr.slice(1));\n for (let i = 0; i < rest.length; i++) {\n for (let j = 0; j < arr[0].length; j++) {\n result.push([arr[0][j]].concat(rest[i]));\n }\n }\n return result;\n }\n }\n\n bubbleSelectors(selectors) {\n if (!selectors) {\n return;\n }\n this.rules = [new Ruleset(utils.copyArray(selectors), [this.rules[0]])];\n this.setParent(this.rules, this);\n }\n}\n\nMedia.prototype.type = 'Media';\nexport default Media;\n","import Node from './node';\nimport Media from './media';\nimport URL from './url';\nimport Quoted from './quoted';\nimport Ruleset from './ruleset';\nimport Anonymous from './anonymous';\nimport * as utils from '../utils';\nimport LessError from '../less-error';\n\n//\n// CSS @import node\n//\n// The general strategy here is that we don't want to wait\n// for the parsing to be completed, before we start importing\n// the file. That's because in the context of a browser,\n// most of the time will be spent waiting for the server to respond.\n//\n// On creation, we push the import path to our import queue, though\n// `import,push`, we also pass it a callback, which it'll call once\n// the file has been fetched, and parsed.\n//\nclass Import extends Node {\n constructor(path, features, options, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.options = options;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.path = path;\n this.features = features;\n this.allowRoot = true;\n\n if (this.options.less !== undefined || this.options.inline) {\n this.css = !this.options.less || this.options.inline;\n } else {\n const pathValue = this.getPath();\n if (pathValue && /[#\\.\\&\\?]css([\\?;].*)?$/.test(pathValue)) {\n this.css = true;\n }\n }\n this.copyVisibilityInfo(visibilityInfo);\n this.setParent(this.features, this);\n this.setParent(this.path, this);\n }\n\n accept(visitor) {\n if (this.features) {\n this.features = visitor.visit(this.features);\n }\n this.path = visitor.visit(this.path);\n if (!this.options.isPlugin && !this.options.inline && this.root) {\n this.root = visitor.visit(this.root);\n }\n }\n\n genCSS(context, output) {\n if (this.css && this.path._fileInfo.reference === undefined) {\n output.add('@import ', this._fileInfo, this._index);\n this.path.genCSS(context, output);\n if (this.features) {\n output.add(' ');\n this.features.genCSS(context, output);\n }\n output.add(';');\n }\n }\n\n getPath() {\n return (this.path instanceof URL) ?\n this.path.value.value : this.path.value;\n }\n\n isVariableImport() {\n let path = this.path;\n if (path instanceof URL) {\n path = path.value;\n }\n if (path instanceof Quoted) {\n return path.containsVariables();\n }\n\n return true;\n }\n\n evalForImport(context) {\n let path = this.path;\n\n if (path instanceof URL) {\n path = path.value;\n }\n\n return new Import(path.eval(context), this.features, this.options, this._index, this._fileInfo, this.visibilityInfo());\n }\n\n evalPath(context) {\n const path = this.path.eval(context);\n const fileInfo = this._fileInfo;\n\n if (!(path instanceof URL)) {\n // Add the rootpath if the URL requires a rewrite\n const pathValue = path.value;\n if (fileInfo &&\n pathValue &&\n context.pathRequiresRewrite(pathValue)) {\n path.value = context.rewritePath(pathValue, fileInfo.rootpath);\n } else {\n path.value = context.normalizePath(path.value);\n }\n }\n\n return path;\n }\n\n eval(context) {\n const result = this.doEval(context);\n if (this.options.reference || this.blocksVisibility()) {\n if (result.length || result.length === 0) {\n result.forEach(node => {\n node.addVisibilityBlock();\n }\n );\n } else {\n result.addVisibilityBlock();\n }\n }\n return result;\n }\n\n doEval(context) {\n let ruleset;\n let registry;\n const features = this.features && this.features.eval(context);\n\n if (this.options.isPlugin) {\n if (this.root && this.root.eval) {\n try {\n this.root.eval(context);\n }\n catch (e) {\n e.message = 'Plugin error during evaluation';\n throw new LessError(e, this.root.imports, this.root.filename);\n }\n }\n registry = context.frames[0] && context.frames[0].functionRegistry;\n if ( registry && this.root && this.root.functions ) {\n registry.addMultiple( this.root.functions );\n }\n\n return [];\n }\n\n if (this.skip) {\n if (typeof this.skip === 'function') {\n this.skip = this.skip();\n }\n if (this.skip) {\n return [];\n }\n }\n if (this.options.inline) {\n const contents = new Anonymous(this.root, 0,\n {\n filename: this.importedFilename,\n reference: this.path._fileInfo && this.path._fileInfo.reference\n }, true, true);\n\n return this.features ? new Media([contents], this.features.value) : [contents];\n } else if (this.css) {\n const newImport = new Import(this.evalPath(context), features, this.options, this._index);\n if (!newImport.css && this.error) {\n throw this.error;\n }\n return newImport;\n } else {\n ruleset = new Ruleset(null, utils.copyArray(this.root.rules));\n ruleset.evalImports(context);\n\n return this.features ? new Media(ruleset.rules, this.features.value) : ruleset.rules;\n }\n }\n}\n\nImport.prototype.type = 'Import';\nexport default Import;\n","import Node from './node';\nimport Variable from './variable';\n\nclass JsEvalNode extends Node {\n evaluateJavaScript(expression, context) {\n let result;\n const that = this;\n const evalContext = {};\n\n if (!context.javascriptEnabled) {\n throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n expression = expression.replace(/@\\{([\\w-]+)\\}/g, (_, name) => that.jsify(new Variable(`@${name}`, that.getIndex(), that.fileInfo()).eval(context)));\n\n try {\n expression = new Function(`return (${expression})`);\n } catch (e) {\n throw { message: `JavaScript evaluation error: ${e.message} from \\`${expression}\\`` ,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n\n const variables = context.frames[0].variables();\n for (const k in variables) {\n if (variables.hasOwnProperty(k)) {\n /* jshint loopfunc:true */\n evalContext[k.slice(1)] = {\n value: variables[k].value,\n toJS: function () {\n return this.value.eval(context).toCSS();\n }\n };\n }\n }\n\n try {\n result = expression.call(evalContext);\n } catch (e) {\n throw { message: `JavaScript evaluation error: '${e.name}: ${e.message.replace(/[\"]/g, '\\'')}'` ,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n return result;\n }\n\n jsify(obj) {\n if (Array.isArray(obj.value) && (obj.value.length > 1)) {\n return `[${obj.value.map(v => v.toCSS()).join(', ')}]`;\n } else {\n return obj.toCSS();\n }\n }\n}\n\nexport default JsEvalNode;\n","import JsEvalNode from './js-eval-node';\nimport Dimension from './dimension';\nimport Quoted from './quoted';\nimport Anonymous from './anonymous';\n\nclass JavaScript extends JsEvalNode {\n constructor(string, escaped, index, currentFileInfo) {\n super();\n\n this.escaped = escaped;\n this.expression = string;\n this._index = index;\n this._fileInfo = currentFileInfo;\n }\n\n eval(context) {\n const result = this.evaluateJavaScript(this.expression, context);\n const type = typeof result;\n\n if (type === 'number' && !isNaN(result)) {\n return new Dimension(result);\n } else if (type === 'string') {\n return new Quoted(`\"${result}\"`, result, this.escaped, this._index);\n } else if (Array.isArray(result)) {\n return new Anonymous(result.join(', '));\n } else {\n return new Anonymous(result);\n }\n }\n}\n\nJavaScript.prototype.type = 'JavaScript';\nexport default JavaScript;\n","import Node from './node';\n\nclass Assignment extends Node {\n constructor(key, val) {\n super();\n\n this.key = key;\n this.value = val;\n }\n\n accept(visitor) {\n this.value = visitor.visit(this.value);\n }\n\n eval(context) {\n if (this.value.eval) {\n return new Assignment(this.key, this.value.eval(context));\n }\n return this;\n }\n\n genCSS(context, output) {\n output.add(`${this.key}=`);\n if (this.value.genCSS) {\n this.value.genCSS(context, output);\n } else {\n output.add(this.value);\n }\n }\n}\n\nAssignment.prototype.type = 'Assignment';\nexport default Assignment;\n","import Node from './node';\n\nclass Condition extends Node {\n constructor(op, l, r, i, negate) {\n super();\n\n this.op = op.trim();\n this.lvalue = l;\n this.rvalue = r;\n this._index = i;\n this.negate = negate;\n }\n\n accept(visitor) {\n this.lvalue = visitor.visit(this.lvalue);\n this.rvalue = visitor.visit(this.rvalue);\n }\n\n eval(context) {\n const result = ((op, a, b) => {\n switch (op) {\n case 'and': return a && b;\n case 'or': return a || b;\n default:\n switch (Node.compare(a, b)) {\n case -1:\n return op === '<' || op === '=<' || op === '<=';\n case 0:\n return op === '=' || op === '>=' || op === '=<' || op === '<=';\n case 1:\n return op === '>' || op === '>=';\n default:\n return false;\n }\n }\n })(this.op, this.lvalue.eval(context), this.rvalue.eval(context));\n\n return this.negate ? !result : result;\n }\n}\n\nCondition.prototype.type = 'Condition';\nexport default Condition;\n","import Node from './node';\n\nclass UnicodeDescriptor extends Node {\n constructor(value) {\n super();\n\n this.value = value;\n }\n}\n\nUnicodeDescriptor.prototype.type = 'UnicodeDescriptor';\n\nexport default UnicodeDescriptor;\n","import Node from './node';\nimport Operation from './operation';\nimport Dimension from './dimension';\n\nclass Negative extends Node {\n constructor(node) {\n super();\n\n this.value = node;\n }\n\n genCSS(context, output) {\n output.add('-');\n this.value.genCSS(context, output);\n }\n\n eval(context) {\n if (context.isMathOn()) {\n return (new Operation('*', [new Dimension(-1), this.value])).eval(context);\n }\n return new Negative(this.value.eval(context));\n }\n}\n\nNegative.prototype.type = 'Negative';\nexport default Negative;\n","import Node from './node';\nimport Selector from './selector';\n\nclass Extend extends Node {\n constructor(selector, option, index, currentFileInfo, visibilityInfo) {\n super();\n\n this.selector = selector;\n this.option = option;\n this.object_id = Extend.next_id++;\n this.parent_ids = [this.object_id];\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n\n switch (option) {\n case 'all':\n this.allowBefore = true;\n this.allowAfter = true;\n break;\n default:\n this.allowBefore = false;\n this.allowAfter = false;\n break;\n }\n this.setParent(this.selector, this);\n }\n\n accept(visitor) {\n this.selector = visitor.visit(this.selector);\n }\n\n eval(context) {\n return new Extend(this.selector.eval(context), this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n }\n\n clone(context) {\n return new Extend(this.selector, this.option, this.getIndex(), this.fileInfo(), this.visibilityInfo());\n }\n\n // it concatenates (joins) all selectors in selector array\n findSelfSelectors(selectors) {\n let selfElements = [];\n let i;\n let selectorElements;\n\n for (i = 0; i < selectors.length; i++) {\n selectorElements = selectors[i].elements;\n // duplicate the logic in genCSS function inside the selector node.\n // future TODO - move both logics into the selector joiner visitor\n if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {\n selectorElements[0].combinator.value = ' ';\n }\n selfElements = selfElements.concat(selectors[i].elements);\n }\n\n this.selfSelectors = [new Selector(selfElements)];\n this.selfSelectors[0].copyVisibilityInfo(this.visibilityInfo());\n }\n}\n\nExtend.next_id = 0;\n\nExtend.prototype.type = 'Extend';\nexport default Extend;\n","import Node from './node';\nimport Variable from './variable';\nimport Ruleset from './ruleset';\nimport DetachedRuleset from './detached-ruleset';\nimport LessError from '../less-error';\n\nclass VariableCall extends Node {\n constructor(variable, index, currentFileInfo) {\n super();\n\n this.variable = variable;\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.allowRoot = true;\n }\n\n eval(context) {\n let rules;\n let detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context);\n const error = new LessError({message: `Could not evaluate variable call ${this.variable}`});\n\n if (!detachedRuleset.ruleset) {\n if (detachedRuleset.rules) {\n rules = detachedRuleset;\n }\n else if (Array.isArray(detachedRuleset)) {\n rules = new Ruleset('', detachedRuleset);\n }\n else if (Array.isArray(detachedRuleset.value)) {\n rules = new Ruleset('', detachedRuleset.value);\n }\n else {\n throw error;\n }\n detachedRuleset = new DetachedRuleset(rules);\n }\n\n if (detachedRuleset.ruleset) {\n return detachedRuleset.callEval(context);\n }\n throw error;\n }\n}\n\nVariableCall.prototype.type = 'VariableCall';\nexport default VariableCall;\n","import Node from './node';\nimport Variable from './variable';\nimport Ruleset from './ruleset';\nimport Selector from './selector';\n\nclass NamespaceValue extends Node {\n constructor(ruleCall, lookups, index, fileInfo) {\n super();\n\n this.value = ruleCall;\n this.lookups = lookups;\n this._index = index;\n this._fileInfo = fileInfo;\n }\n\n eval(context) {\n let i;\n let j;\n let name;\n let rules = this.value.eval(context);\n\n for (i = 0; i < this.lookups.length; i++) {\n name = this.lookups[i];\n\n /**\n * Eval'd DRs return rulesets.\n * Eval'd mixins return rules, so let's make a ruleset if we need it.\n * We need to do this because of late parsing of values\n */\n if (Array.isArray(rules)) {\n rules = new Ruleset([new Selector()], rules);\n }\n\n if (name === '') {\n rules = rules.lastDeclaration();\n }\n else if (name.charAt(0) === '@') {\n if (name.charAt(1) === '@') {\n name = `@${new Variable(name.substr(1)).eval(context).value}`;\n }\n if (rules.variables) {\n rules = rules.variable(name);\n }\n \n if (!rules) {\n throw { type: 'Name',\n message: `variable ${name} not found`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n }\n else {\n if (name.substring(0, 2) === '$@') {\n name = `$${new Variable(name.substr(1)).eval(context).value}`;\n }\n else {\n name = name.charAt(0) === '$' ? name : `$${name}`;\n }\n if (rules.properties) {\n rules = rules.property(name);\n }\n \n if (!rules) {\n throw { type: 'Name',\n message: `property \"${name.substr(1)}\" not found`,\n filename: this.fileInfo().filename,\n index: this.getIndex() };\n }\n // Properties are an array of values, since a ruleset can have multiple props.\n // We pick the last one (the \"cascaded\" value)\n rules = rules[rules.length - 1];\n }\n\n if (rules.value) {\n rules = rules.eval(context).value;\n }\n if (rules.ruleset) {\n rules = rules.ruleset.eval(context);\n }\n }\n return rules;\n }\n}\n\nNamespaceValue.prototype.type = 'NamespaceValue';\nexport default NamespaceValue;\n","import Selector from './selector';\nimport Element from './element';\nimport Ruleset from './ruleset';\nimport Declaration from './declaration';\nimport DetachedRuleset from './detached-ruleset';\nimport Expression from './expression';\nimport contexts from '../contexts';\nimport * as utils from '../utils';\n\nclass Definition extends Ruleset {\n constructor(name, params, rules, condition, variadic, frames, visibilityInfo) {\n super();\n\n this.name = name || 'anonymous mixin';\n this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];\n this.params = params;\n this.condition = condition;\n this.variadic = variadic;\n this.arity = params.length;\n this.rules = rules;\n this._lookups = {};\n const optionalParameters = [];\n this.required = params.reduce((count, p) => {\n if (!p.name || (p.name && !p.value)) {\n return count + 1;\n }\n else {\n optionalParameters.push(p.name);\n return count;\n }\n }, 0);\n this.optionalParameters = optionalParameters;\n this.frames = frames;\n this.copyVisibilityInfo(visibilityInfo);\n this.allowRoot = true;\n }\n\n accept(visitor) {\n if (this.params && this.params.length) {\n this.params = visitor.visitArray(this.params);\n }\n this.rules = visitor.visitArray(this.rules);\n if (this.condition) {\n this.condition = visitor.visit(this.condition);\n }\n }\n\n evalParams(context, mixinEnv, args, evaldArguments) {\n /* jshint boss:true */\n const frame = new Ruleset(null, null);\n\n let varargs;\n let arg;\n const params = utils.copyArray(this.params);\n let i;\n let j;\n let val;\n let name;\n let isNamedFound;\n let argIndex;\n let argsLength = 0;\n\n if (mixinEnv.frames && mixinEnv.frames[0] && mixinEnv.frames[0].functionRegistry) {\n frame.functionRegistry = mixinEnv.frames[0].functionRegistry.inherit();\n }\n mixinEnv = new contexts.Eval(mixinEnv, [frame].concat(mixinEnv.frames));\n\n if (args) {\n args = utils.copyArray(args);\n argsLength = args.length;\n\n for (i = 0; i < argsLength; i++) {\n arg = args[i];\n if (name = (arg && arg.name)) {\n isNamedFound = false;\n for (j = 0; j < params.length; j++) {\n if (!evaldArguments[j] && name === params[j].name) {\n evaldArguments[j] = arg.value.eval(context);\n frame.prependRule(new Declaration(name, arg.value.eval(context)));\n isNamedFound = true;\n break;\n }\n }\n if (isNamedFound) {\n args.splice(i, 1);\n i--;\n continue;\n } else {\n throw { type: 'Runtime', message: `Named argument for ${this.name} ${args[i].name} not found` };\n }\n }\n }\n }\n argIndex = 0;\n for (i = 0; i < params.length; i++) {\n if (evaldArguments[i]) { continue; }\n\n arg = args && args[argIndex];\n\n if (name = params[i].name) {\n if (params[i].variadic) {\n varargs = [];\n for (j = argIndex; j < argsLength; j++) {\n varargs.push(args[j].value.eval(context));\n }\n frame.prependRule(new Declaration(name, new Expression(varargs).eval(context)));\n } else {\n val = arg && arg.value;\n if (val) {\n // This was a mixin call, pass in a detached ruleset of it's eval'd rules\n if (Array.isArray(val)) {\n val = new DetachedRuleset(new Ruleset('', val));\n }\n else {\n val = val.eval(context);\n }\n } else if (params[i].value) {\n val = params[i].value.eval(mixinEnv);\n frame.resetCache();\n } else {\n throw { type: 'Runtime', message: `wrong number of arguments for ${this.name} (${argsLength} for ${this.arity})` };\n }\n\n frame.prependRule(new Declaration(name, val));\n evaldArguments[i] = val;\n }\n }\n\n if (params[i].variadic && args) {\n for (j = argIndex; j < argsLength; j++) {\n evaldArguments[j] = args[j].value.eval(context);\n }\n }\n argIndex++;\n }\n\n return frame;\n }\n\n makeImportant() {\n const rules = !this.rules ? this.rules : this.rules.map(r => {\n if (r.makeImportant) {\n return r.makeImportant(true);\n } else {\n return r;\n }\n });\n const result = new Definition(this.name, this.params, rules, this.condition, this.variadic, this.frames);\n return result;\n }\n\n eval(context) {\n return new Definition(this.name, this.params, this.rules, this.condition, this.variadic, this.frames || utils.copyArray(context.frames));\n }\n\n evalCall(context, args, important) {\n const _arguments = [];\n const mixinFrames = this.frames ? this.frames.concat(context.frames) : context.frames;\n const frame = this.evalParams(context, new contexts.Eval(context, mixinFrames), args, _arguments);\n let rules;\n let ruleset;\n\n frame.prependRule(new Declaration('@arguments', new Expression(_arguments).eval(context)));\n\n rules = utils.copyArray(this.rules);\n\n ruleset = new Ruleset(null, rules);\n ruleset.originalRuleset = this;\n ruleset = ruleset.eval(new contexts.Eval(context, [this, frame].concat(mixinFrames)));\n if (important) {\n ruleset = ruleset.makeImportant();\n }\n return ruleset;\n }\n\n matchCondition(args, context) {\n if (this.condition && !this.condition.eval(\n new contexts.Eval(context,\n [this.evalParams(context, /* the parameter variables */\n new contexts.Eval(context, this.frames ? this.frames.concat(context.frames) : context.frames), args, [])]\n .concat(this.frames || []) // the parent namespace/mixin frames\n .concat(context.frames)))) { // the current environment frames\n return false;\n }\n return true;\n }\n\n matchArgs(args, context) {\n const allArgsCnt = (args && args.length) || 0;\n let len;\n const optionalParameters = this.optionalParameters;\n const requiredArgsCnt = !args ? 0 : args.reduce((count, p) => {\n if (optionalParameters.indexOf(p.name) < 0) {\n return count + 1;\n } else {\n return count;\n }\n }, 0);\n\n if (!this.variadic) {\n if (requiredArgsCnt < this.required) {\n return false;\n }\n if (allArgsCnt > this.params.length) {\n return false;\n }\n } else {\n if (requiredArgsCnt < (this.required - 1)) {\n return false;\n }\n }\n\n // check patterns\n len = Math.min(requiredArgsCnt, this.arity);\n\n for (let i = 0; i < len; i++) {\n if (!this.params[i].name && !this.params[i].variadic) {\n if (args[i].value.eval(context).toCSS() != this.params[i].value.eval(context).toCSS()) {\n return false;\n }\n }\n }\n return true;\n }\n}\n\nDefinition.prototype.type = 'MixinDefinition';\nDefinition.prototype.evalFirst = true;\nexport default Definition;\n","import Node from './node';\nimport Selector from './selector';\nimport MixinDefinition from './mixin-definition';\nimport defaultFunc from '../functions/default';\n\nclass MixinCall extends Node {\n constructor(elements, args, index, currentFileInfo, important) {\n super();\n\n this.selector = new Selector(elements);\n this.arguments = args || [];\n this._index = index;\n this._fileInfo = currentFileInfo;\n this.important = important;\n this.allowRoot = true;\n this.setParent(this.selector, this);\n }\n\n accept(visitor) {\n if (this.selector) {\n this.selector = visitor.visit(this.selector);\n }\n if (this.arguments.length) {\n this.arguments = visitor.visitArray(this.arguments);\n }\n }\n\n eval(context) {\n let mixins;\n let mixin;\n let mixinPath;\n const args = [];\n let arg;\n let argValue;\n const rules = [];\n let match = false;\n let i;\n let m;\n let f;\n let isRecursive;\n let isOneFound;\n const candidates = [];\n let candidate;\n const conditionResult = [];\n let defaultResult;\n const defFalseEitherCase = -1;\n const defNone = 0;\n const defTrue = 1;\n const defFalse = 2;\n let count;\n let originalRuleset;\n let noArgumentsFilter;\n\n this.selector = this.selector.eval(context);\n\n function calcDefGroup(mixin, mixinPath) {\n let f;\n let p;\n let namespace;\n\n for (f = 0; f < 2; f++) {\n conditionResult[f] = true;\n defaultFunc.value(f);\n for (p = 0; p < mixinPath.length && conditionResult[f]; p++) {\n namespace = mixinPath[p];\n if (namespace.matchCondition) {\n conditionResult[f] = conditionResult[f] && namespace.matchCondition(null, context);\n }\n }\n if (mixin.matchCondition) {\n conditionResult[f] = conditionResult[f] && mixin.matchCondition(args, context);\n }\n }\n if (conditionResult[0] || conditionResult[1]) {\n if (conditionResult[0] != conditionResult[1]) {\n return conditionResult[1] ?\n defTrue : defFalse;\n }\n\n return defNone;\n }\n return defFalseEitherCase;\n }\n\n for (i = 0; i < this.arguments.length; i++) {\n arg = this.arguments[i];\n argValue = arg.value.eval(context);\n if (arg.expand && Array.isArray(argValue.value)) {\n argValue = argValue.value;\n for (m = 0; m < argValue.length; m++) {\n args.push({value: argValue[m]});\n }\n } else {\n args.push({name: arg.name, value: argValue});\n }\n }\n\n noArgumentsFilter = rule => rule.matchArgs(null, context);\n\n for (i = 0; i < context.frames.length; i++) {\n if ((mixins = context.frames[i].find(this.selector, null, noArgumentsFilter)).length > 0) {\n isOneFound = true;\n\n // To make `default()` function independent of definition order we have two \"subpasses\" here.\n // At first we evaluate each guard *twice* (with `default() == true` and `default() == false`),\n // and build candidate list with corresponding flags. Then, when we know all possible matches,\n // we make a final decision.\n\n for (m = 0; m < mixins.length; m++) {\n mixin = mixins[m].rule;\n mixinPath = mixins[m].path;\n isRecursive = false;\n for (f = 0; f < context.frames.length; f++) {\n if ((!(mixin instanceof MixinDefinition)) && mixin === (context.frames[f].originalRuleset || context.frames[f])) {\n isRecursive = true;\n break;\n }\n }\n if (isRecursive) {\n continue;\n }\n\n if (mixin.matchArgs(args, context)) {\n candidate = {mixin, group: calcDefGroup(mixin, mixinPath)};\n\n if (candidate.group !== defFalseEitherCase) {\n candidates.push(candidate);\n }\n\n match = true;\n }\n }\n\n defaultFunc.reset();\n\n count = [0, 0, 0];\n for (m = 0; m < candidates.length; m++) {\n count[candidates[m].group]++;\n }\n\n if (count[defNone] > 0) {\n defaultResult = defFalse;\n } else {\n defaultResult = defTrue;\n if ((count[defTrue] + count[defFalse]) > 1) {\n throw { type: 'Runtime',\n message: `Ambiguous use of \\`default()\\` found when matching for \\`${this.format(args)}\\``,\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n }\n\n for (m = 0; m < candidates.length; m++) {\n candidate = candidates[m].group;\n if ((candidate === defNone) || (candidate === defaultResult)) {\n try {\n mixin = candidates[m].mixin;\n if (!(mixin instanceof MixinDefinition)) {\n originalRuleset = mixin.originalRuleset || mixin;\n mixin = new MixinDefinition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());\n mixin.originalRuleset = originalRuleset;\n }\n const newRules = mixin.evalCall(context, args, this.important).rules;\n this._setVisibilityToReplacement(newRules);\n Array.prototype.push.apply(rules, newRules);\n } catch (e) {\n throw { message: e.message, index: this.getIndex(), filename: this.fileInfo().filename, stack: e.stack };\n }\n }\n }\n\n if (match) {\n return rules;\n }\n }\n }\n if (isOneFound) {\n throw { type: 'Runtime',\n message: `No matching definition was found for \\`${this.format(args)}\\``,\n index: this.getIndex(), filename: this.fileInfo().filename };\n } else {\n throw { type: 'Name',\n message: `${this.selector.toCSS().trim()} is undefined`,\n index: this.getIndex(), filename: this.fileInfo().filename };\n }\n }\n\n _setVisibilityToReplacement(replacement) {\n let i;\n let rule;\n if (this.blocksVisibility()) {\n for (i = 0; i < replacement.length; i++) {\n rule = replacement[i];\n rule.addVisibilityBlock();\n }\n }\n }\n\n format(args) {\n return `${this.selector.toCSS().trim()}(${args ? args.map(a => {\n let argValue = '';\n if (a.name) {\n argValue += `${a.name}:`;\n }\n if (a.value.toCSS) {\n argValue += a.value.toCSS();\n } else {\n argValue += '???';\n }\n return argValue;\n }).join(', ') : ''})`;\n }\n}\n\nMixinCall.prototype.type = 'MixinCall';\nexport default MixinCall;\n","const tree = Object.create(null);\n\nimport Node from './node';\nimport Color from './color';\nimport AtRule from './atrule';\nimport DetachedRuleset from './detached-ruleset';\nimport Operation from './operation';\nimport Dimension from './dimension';\nimport Unit from './unit';\nimport Keyword from './keyword';\nimport Variable from './variable';\nimport Property from './property';\nimport Ruleset from './ruleset';\nimport Element from './element';\nimport Attribute from './attribute';\nimport Combinator from './combinator';\nimport Selector from './selector';\nimport Quoted from './quoted';\nimport Expression from './expression';\nimport Declaration from './declaration';\nimport Call from './call';\nimport URL from './url';\nimport Import from './import';\nimport Comment from './comment';\nimport Anonymous from './anonymous';\nimport Value from './value';\nimport JavaScript from './javascript';\nimport Assignment from './assignment';\nimport Condition from './condition';\nimport Paren from './paren';\nimport Media from './media';\nimport UnicodeDescriptor from './unicode-descriptor';\nimport Negative from './negative';\nimport Extend from './extend';\nimport VariableCall from './variable-call';\nimport NamespaceValue from './namespace-value';\n\n// mixins\nimport MixinCall from './mixin-call';\nimport MixinDefinition from './mixin-definition';\n\nexport default {\n Node, Color, AtRule, DetachedRuleset, Operation,\n Dimension, Unit, Keyword, Variable, Property,\n Ruleset, Element, Attribute, Combinator, Selector,\n Quoted, Expression, Declaration, Call, URL, Import,\n Comment, Anonymous, Value, JavaScript, Assignment,\n Condition, Paren, Media, UnicodeDescriptor, Negative,\n Extend, VariableCall, NamespaceValue,\n mixin: {\n Call: MixinCall,\n Definition: MixinDefinition\n }\n};","export default {\n error: function(msg) {\n this._fireEvent('error', msg);\n },\n warn: function(msg) {\n this._fireEvent('warn', msg);\n },\n info: function(msg) {\n this._fireEvent('info', msg);\n },\n debug: function(msg) {\n this._fireEvent('debug', msg);\n },\n addListener: function(listener) {\n this._listeners.push(listener);\n },\n removeListener: function(listener) {\n for (let i = 0; i < this._listeners.length; i++) {\n if (this._listeners[i] === listener) {\n this._listeners.splice(i, 1);\n return;\n }\n }\n },\n _fireEvent: function(type, msg) {\n for (let i = 0; i < this._listeners.length; i++) {\n const logFunction = this._listeners[i][type];\n if (logFunction) {\n logFunction(msg);\n }\n }\n },\n _listeners: []\n};\n","/**\n * @todo Document why this abstraction exists, and the relationship between\n * environment, file managers, and plugin manager\n */\n\nimport logger from '../logger';\n\nclass environment {\n constructor(externalEnvironment, fileManagers) {\n this.fileManagers = fileManagers || [];\n externalEnvironment = externalEnvironment || {};\n\n const optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'];\n const requiredFunctions = [];\n const functions = requiredFunctions.concat(optionalFunctions);\n\n for (let i = 0; i < functions.length; i++) {\n const propName = functions[i];\n const environmentFunc = externalEnvironment[propName];\n if (environmentFunc) {\n this[propName] = environmentFunc.bind(externalEnvironment);\n } else if (i < requiredFunctions.length) {\n this.warn(`missing required function in environment - ${propName}`);\n }\n }\n }\n\n getFileManager(filename, currentDirectory, options, environment, isSync) {\n\n if (!filename) {\n logger.warn('getFileManager called with no filename.. Please report this issue. continuing.');\n }\n if (currentDirectory == null) {\n logger.warn('getFileManager called with null directory.. Please report this issue. continuing.');\n }\n\n let fileManagers = this.fileManagers;\n if (options.pluginManager) {\n fileManagers = [].concat(fileManagers).concat(options.pluginManager.getFileManagers());\n }\n for (let i = fileManagers.length - 1; i >= 0 ; i--) {\n const fileManager = fileManagers[i];\n if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {\n return fileManager;\n }\n }\n return null;\n }\n\n addFileManager(fileManager) {\n this.fileManagers.push(fileManager);\n }\n\n clearFileManagers() {\n this.fileManagers = [];\n }\n}\n\nexport default environment;\n","class AbstractFileManager {\n getPath(filename) {\n let j = filename.lastIndexOf('?');\n if (j > 0) {\n filename = filename.slice(0, j);\n }\n j = filename.lastIndexOf('/');\n if (j < 0) {\n j = filename.lastIndexOf('\\\\');\n }\n if (j < 0) {\n return '';\n }\n return filename.slice(0, j + 1);\n }\n\n isPathWithExtension(path, ext) {\n let extPos = path.lastIndexOf(ext);\n return extPos !== -1 && extPos === path.length - ext.length\n }\n\n tryAppendExtension(path, ext) {\n if (this.isPathWithExtension(path, ext)) {\n return path;\n }\n\n return path + ext;\n }\n\n tryAppendLessExtension(path) {\n return this.tryAppendExtension(path, '.less');\n };\n\n supportsSync() { return false; }\n\n alwaysMakePathsAbsolute() { return false; }\n\n isPathAbsolute(filename) {\n return (/^(?:[a-z-]+:|\\/|\\\\|#)/i).test(filename);\n }\n // TODO: pull out / replace?\n join(basePath, laterPath) {\n if (!basePath) {\n return laterPath;\n }\n return basePath + laterPath;\n };\n\n pathDiff(url, baseUrl) {\n // diff between two paths to create a relative path\n const urlParts = this.extractUrlParts(url);\n const baseUrlParts = this.extractUrlParts(baseUrl);\n\n let i;\n let max;\n let urlDirectories;\n let baseUrlDirectories;\n let diff = '';\n if (urlParts.hostPart !== baseUrlParts.hostPart) {\n return '';\n }\n max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);\n for (i = 0; i < max; i++) {\n if (baseUrlParts.directories[i] !== urlParts.directories[i]) { break; }\n }\n baseUrlDirectories = baseUrlParts.directories.slice(i);\n urlDirectories = urlParts.directories.slice(i);\n for (i = 0; i < baseUrlDirectories.length - 1; i++) {\n diff += '../';\n }\n for (i = 0; i < urlDirectories.length - 1; i++) {\n diff += `${urlDirectories[i]}/`;\n }\n return diff;\n };\n // helper function, not part of API\n extractUrlParts(url, baseUrl) {\n // urlParts[1] = protocol://hostname/ OR /\n // urlParts[2] = / if path relative to host base\n // urlParts[3] = directories\n // urlParts[4] = filename\n // urlParts[5] = parameters\n\n const urlPartsRegex = /^((?:[a-z-]+:)?\\/{2}(?:[^\\/\\?#]*\\/)|([\\/\\\\]))?((?:[^\\/\\\\\\?#]*[\\/\\\\])*)([^\\/\\\\\\?#]*)([#\\?].*)?$/i;\n\n const urlParts = url.match(urlPartsRegex);\n const returner = {};\n let rawDirectories = [];\n const directories = [];\n let i;\n let baseUrlParts;\n\n if (!urlParts) {\n throw new Error(`Could not parse sheet href - '${url}'`);\n }\n\n // Stylesheets in IE don't always return the full path\n if (baseUrl && (!urlParts[1] || urlParts[2])) {\n baseUrlParts = baseUrl.match(urlPartsRegex);\n if (!baseUrlParts) {\n throw new Error(`Could not parse page url - '${baseUrl}'`);\n }\n urlParts[1] = urlParts[1] || baseUrlParts[1] || '';\n if (!urlParts[2]) {\n urlParts[3] = baseUrlParts[3] + urlParts[3];\n }\n }\n\n if (urlParts[3]) {\n rawDirectories = urlParts[3].replace(/\\\\/g, '/').split('/');\n\n // collapse '..' and skip '.'\n for (i = 0; i < rawDirectories.length; i++) {\n\n if (rawDirectories[i] === '..') {\n directories.pop();\n }\n else if (rawDirectories[i] !== '.') {\n directories.push(rawDirectories[i]);\n }\n \n }\n }\n\n returner.hostPart = urlParts[1];\n returner.directories = directories;\n returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');\n returner.path = (urlParts[1] || '') + directories.join('/');\n returner.filename = urlParts[4];\n returner.fileUrl = returner.path + (urlParts[4] || '');\n returner.url = returner.fileUrl + (urlParts[5] || '');\n return returner;\n };\n}\n\nexport default AbstractFileManager;\n","import functionRegistry from '../functions/function-registry';\nimport LessError from '../less-error';\n\nclass AbstractPluginLoader {\n constructor() {\n // Implemented by Node.js plugin loader\n this.require = () => null\n }\n\n evalPlugin(contents, context, imports, pluginOptions, fileInfo) {\n let loader;\n let registry;\n let pluginObj;\n let localModule;\n let pluginManager;\n let filename;\n let result;\n\n pluginManager = context.pluginManager;\n\n if (fileInfo) {\n if (typeof fileInfo === 'string') {\n filename = fileInfo;\n }\n else {\n filename = fileInfo.filename;\n }\n }\n const shortname = (new this.less.FileManager()).extractUrlParts(filename).filename;\n\n if (filename) {\n pluginObj = pluginManager.get(filename);\n\n if (pluginObj) {\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n if (result) {\n return result;\n }\n try {\n if (pluginObj.use) {\n pluginObj.use.call(this.context, pluginObj);\n }\n }\n catch (e) {\n e.message = e.message || 'Error during @plugin call';\n return new LessError(e, imports, filename);\n }\n return pluginObj;\n }\n }\n localModule = {\n exports: {},\n pluginManager,\n fileInfo\n };\n registry = functionRegistry.create();\n\n const registerPlugin = obj => {\n pluginObj = obj;\n };\n\n try {\n loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);\n loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);\n }\n catch (e) {\n return new LessError(e, imports, filename);\n }\n\n if (!pluginObj) {\n pluginObj = localModule.exports;\n }\n pluginObj = this.validatePlugin(pluginObj, filename, shortname);\n\n if (pluginObj instanceof LessError) {\n return pluginObj;\n }\n\n if (pluginObj) {\n pluginObj.imports = imports;\n pluginObj.filename = filename;\n\n // For < 3.x (or unspecified minVersion) - setOptions() before install()\n if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n\n if (result) {\n return result;\n }\n }\n\n // Run on first load\n pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);\n pluginObj.functions = registry.getLocalFunctions();\n\n // Need to call setOptions again because the pluginObj might have functions\n result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);\n if (result) {\n return result;\n }\n\n // Run every @plugin call\n try {\n if (pluginObj.use) {\n pluginObj.use.call(this.context, pluginObj);\n }\n }\n catch (e) {\n e.message = e.message || 'Error during @plugin call';\n return new LessError(e, imports, filename);\n }\n\n }\n else {\n return new LessError({ message: 'Not a valid plugin' }, imports, filename);\n }\n\n return pluginObj;\n }\n\n trySetOptions(plugin, filename, name, options) {\n if (options && !plugin.setOptions) {\n return new LessError({\n message: `Options have been provided but the plugin ${name} does not support any options.`\n });\n }\n try {\n plugin.setOptions && plugin.setOptions(options);\n }\n catch (e) {\n return new LessError(e);\n }\n }\n\n validatePlugin(plugin, filename, name) {\n if (plugin) {\n // support plugins being a function\n // so that the plugin can be more usable programmatically\n if (typeof plugin === 'function') {\n plugin = new plugin();\n }\n\n if (plugin.minVersion) {\n if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {\n return new LessError({\n message: `Plugin ${name} requires version ${this.versionToString(plugin.minVersion)}`\n });\n }\n }\n return plugin;\n }\n return null;\n }\n\n compareVersion(aVersion, bVersion) {\n if (typeof aVersion === 'string') {\n aVersion = aVersion.match(/^(\\d+)\\.?(\\d+)?\\.?(\\d+)?/);\n aVersion.shift();\n }\n for (let i = 0; i < aVersion.length; i++) {\n if (aVersion[i] !== bVersion[i]) {\n return parseInt(aVersion[i]) > parseInt(bVersion[i]) ? -1 : 1;\n }\n }\n return 0;\n }\n\n versionToString(version) {\n let versionString = '';\n for (let i = 0; i < version.length; i++) {\n versionString += (versionString ? '.' : '') + version[i];\n }\n return versionString;\n }\n\n printUsage(plugins) {\n for (let i = 0; i < plugins.length; i++) {\n const plugin = plugins[i];\n if (plugin.printUsage) {\n plugin.printUsage();\n }\n }\n }\n}\n\nexport default AbstractPluginLoader;\n\n","import tree from '../tree';\nconst _visitArgs = { visitDeeper: true };\nlet _hasIndexed = false;\n\nfunction _noop(node) {\n return node;\n}\n\nfunction indexNodeTypes(parent, ticker) {\n // add .typeIndex to tree node types for lookup table\n let key;\n\n let child;\n for (key in parent) { \n /* eslint guard-for-in: 0 */\n child = parent[key];\n switch (typeof child) {\n case 'function':\n // ignore bound functions directly on tree which do not have a prototype\n // or aren't nodes\n if (child.prototype && child.prototype.type) {\n child.prototype.typeIndex = ticker++;\n }\n break;\n case 'object':\n ticker = indexNodeTypes(child, ticker);\n break;\n \n }\n }\n return ticker;\n}\n\nclass Visitor {\n constructor(implementation) {\n this._implementation = implementation;\n this._visitInCache = {};\n this._visitOutCache = {};\n\n if (!_hasIndexed) {\n indexNodeTypes(tree, 1);\n _hasIndexed = true;\n }\n }\n\n visit(node) {\n if (!node) {\n return node;\n }\n\n const nodeTypeIndex = node.typeIndex;\n if (!nodeTypeIndex) {\n // MixinCall args aren't a node type?\n if (node.value && node.value.typeIndex) {\n this.visit(node.value);\n }\n return node;\n }\n\n const impl = this._implementation;\n let func = this._visitInCache[nodeTypeIndex];\n let funcOut = this._visitOutCache[nodeTypeIndex];\n const visitArgs = _visitArgs;\n let fnName;\n\n visitArgs.visitDeeper = true;\n\n if (!func) {\n fnName = `visit${node.type}`;\n func = impl[fnName] || _noop;\n funcOut = impl[`${fnName}Out`] || _noop;\n this._visitInCache[nodeTypeIndex] = func;\n this._visitOutCache[nodeTypeIndex] = funcOut;\n }\n\n if (func !== _noop) {\n const newNode = func.call(impl, node, visitArgs);\n if (node && impl.isReplacing) {\n node = newNode;\n }\n }\n\n if (visitArgs.visitDeeper && node) {\n if (node.length) {\n for (var i = 0, cnt = node.length; i < cnt; i++) {\n if (node[i].accept) {\n node[i].accept(this);\n }\n }\n } else if (node.accept) {\n node.accept(this);\n }\n }\n\n if (funcOut != _noop) {\n funcOut.call(impl, node);\n }\n\n return node;\n }\n\n visitArray(nodes, nonReplacing) {\n if (!nodes) {\n return nodes;\n }\n\n const cnt = nodes.length;\n let i;\n\n // Non-replacing\n if (nonReplacing || !this._implementation.isReplacing) {\n for (i = 0; i < cnt; i++) {\n this.visit(nodes[i]);\n }\n return nodes;\n }\n\n // Replacing\n const out = [];\n for (i = 0; i < cnt; i++) {\n const evald = this.visit(nodes[i]);\n if (evald === undefined) { continue; }\n if (!evald.splice) {\n out.push(evald);\n } else if (evald.length) {\n this.flatten(evald, out);\n }\n }\n return out;\n }\n\n flatten(arr, out) {\n if (!out) {\n out = [];\n }\n\n let cnt;\n let i;\n let item;\n let nestedCnt;\n let j;\n let nestedItem;\n\n for (i = 0, cnt = arr.length; i < cnt; i++) {\n item = arr[i];\n if (item === undefined) {\n continue;\n }\n if (!item.splice) {\n out.push(item);\n continue;\n }\n\n for (j = 0, nestedCnt = item.length; j < nestedCnt; j++) {\n nestedItem = item[j];\n if (nestedItem === undefined) {\n continue;\n }\n if (!nestedItem.splice) {\n out.push(nestedItem);\n } else if (nestedItem.length) {\n this.flatten(nestedItem, out);\n }\n }\n }\n\n return out;\n }\n}\n\nexport default Visitor;\n","class ImportSequencer {\n constructor(onSequencerEmpty) {\n this.imports = [];\n this.variableImports = [];\n this._onSequencerEmpty = onSequencerEmpty;\n this._currentDepth = 0;\n }\n\n addImport(callback) {\n const importSequencer = this;\n\n const importItem = {\n callback,\n args: null,\n isReady: false\n };\n\n this.imports.push(importItem);\n return function(...args) {\n importItem.args = Array.prototype.slice.call(args, 0);\n importItem.isReady = true;\n importSequencer.tryRun();\n };\n }\n\n addVariableImport(callback) {\n this.variableImports.push(callback);\n }\n\n tryRun() {\n this._currentDepth++;\n try {\n while (true) {\n while (this.imports.length > 0) {\n const importItem = this.imports[0];\n if (!importItem.isReady) {\n return;\n }\n this.imports = this.imports.slice(1);\n importItem.callback.apply(null, importItem.args);\n }\n if (this.variableImports.length === 0) {\n break;\n }\n const variableImport = this.variableImports[0];\n this.variableImports = this.variableImports.slice(1);\n variableImport();\n }\n } finally {\n this._currentDepth--;\n }\n if (this._currentDepth === 0 && this._onSequencerEmpty) {\n this._onSequencerEmpty();\n }\n }\n}\n\nexport default ImportSequencer;\n","import contexts from '../contexts';\nimport Visitor from './visitor';\nimport ImportSequencer from './import-sequencer';\nimport * as utils from '../utils';\n\nconst ImportVisitor = function(importer, finish) {\n\n this._visitor = new Visitor(this);\n this._importer = importer;\n this._finish = finish;\n this.context = new contexts.Eval();\n this.importCount = 0;\n this.onceFileDetectionMap = {};\n this.recursionDetector = {};\n this._sequencer = new ImportSequencer(this._onSequencerEmpty.bind(this));\n};\n\nImportVisitor.prototype = {\n isReplacing: false,\n run: function (root) {\n try {\n // process the contents\n this._visitor.visit(root);\n }\n catch (e) {\n this.error = e;\n }\n\n this.isFinished = true;\n this._sequencer.tryRun();\n },\n _onSequencerEmpty: function() {\n if (!this.isFinished) {\n return;\n }\n this._finish(this.error);\n },\n visitImport: function (importNode, visitArgs) {\n const inlineCSS = importNode.options.inline;\n\n if (!importNode.css || inlineCSS) {\n\n const context = new contexts.Eval(this.context, utils.copyArray(this.context.frames));\n const importParent = context.frames[0];\n\n this.importCount++;\n if (importNode.isVariableImport()) {\n this._sequencer.addVariableImport(this.processImportNode.bind(this, importNode, context, importParent));\n } else {\n this.processImportNode(importNode, context, importParent);\n }\n }\n visitArgs.visitDeeper = false;\n },\n processImportNode: function(importNode, context, importParent) {\n let evaldImportNode;\n const inlineCSS = importNode.options.inline;\n\n try {\n evaldImportNode = importNode.evalForImport(context);\n } catch (e) {\n if (!e.filename) { e.index = importNode.getIndex(); e.filename = importNode.fileInfo().filename; }\n // attempt to eval properly and treat as css\n importNode.css = true;\n // if that fails, this error will be thrown\n importNode.error = e;\n }\n\n if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) {\n if (evaldImportNode.options.multiple) {\n context.importMultiple = true;\n }\n\n // try appending if we haven't determined if it is css or not\n const tryAppendLessExtension = evaldImportNode.css === undefined;\n\n for (let i = 0; i < importParent.rules.length; i++) {\n if (importParent.rules[i] === importNode) {\n importParent.rules[i] = evaldImportNode;\n break;\n }\n }\n\n const onImported = this.onImported.bind(this, evaldImportNode, context);\n const sequencedOnImported = this._sequencer.addImport(onImported);\n\n this._importer.push(evaldImportNode.getPath(), tryAppendLessExtension, evaldImportNode.fileInfo(),\n evaldImportNode.options, sequencedOnImported);\n } else {\n this.importCount--;\n if (this.isFinished) {\n this._sequencer.tryRun();\n }\n }\n },\n onImported: function (importNode, context, e, root, importedAtRoot, fullPath) {\n if (e) {\n if (!e.filename) {\n e.index = importNode.getIndex(); e.filename = importNode.fileInfo().filename;\n }\n this.error = e;\n }\n\n const importVisitor = this;\n const inlineCSS = importNode.options.inline;\n const isPlugin = importNode.options.isPlugin;\n const isOptional = importNode.options.optional;\n const duplicateImport = importedAtRoot || fullPath in importVisitor.recursionDetector;\n\n if (!context.importMultiple) {\n if (duplicateImport) {\n importNode.skip = true;\n } else {\n importNode.skip = () => {\n if (fullPath in importVisitor.onceFileDetectionMap) {\n return true;\n }\n importVisitor.onceFileDetectionMap[fullPath] = true;\n return false;\n };\n }\n }\n\n if (!fullPath && isOptional) {\n importNode.skip = true;\n }\n\n if (root) {\n importNode.root = root;\n importNode.importedFilename = fullPath;\n\n if (!inlineCSS && !isPlugin && (context.importMultiple || !duplicateImport)) {\n importVisitor.recursionDetector[fullPath] = true;\n\n const oldContext = this.context;\n this.context = context;\n try {\n this._visitor.visit(root);\n } catch (e) {\n this.error = e;\n }\n this.context = oldContext;\n }\n }\n\n importVisitor.importCount--;\n\n if (importVisitor.isFinished) {\n importVisitor._sequencer.tryRun();\n }\n },\n visitDeclaration: function (declNode, visitArgs) {\n if (declNode.value.type === 'DetachedRuleset') {\n this.context.frames.unshift(declNode);\n } else {\n visitArgs.visitDeeper = false;\n }\n },\n visitDeclarationOut: function(declNode) {\n if (declNode.value.type === 'DetachedRuleset') {\n this.context.frames.shift();\n }\n },\n visitAtRule: function (atRuleNode, visitArgs) {\n this.context.frames.unshift(atRuleNode);\n },\n visitAtRuleOut: function (atRuleNode) {\n this.context.frames.shift();\n },\n visitMixinDefinition: function (mixinDefinitionNode, visitArgs) {\n this.context.frames.unshift(mixinDefinitionNode);\n },\n visitMixinDefinitionOut: function (mixinDefinitionNode) {\n this.context.frames.shift();\n },\n visitRuleset: function (rulesetNode, visitArgs) {\n this.context.frames.unshift(rulesetNode);\n },\n visitRulesetOut: function (rulesetNode) {\n this.context.frames.shift();\n },\n visitMedia: function (mediaNode, visitArgs) {\n this.context.frames.unshift(mediaNode.rules[0]);\n },\n visitMediaOut: function (mediaNode) {\n this.context.frames.shift();\n }\n};\nexport default ImportVisitor;\n","class SetTreeVisibilityVisitor {\n constructor(visible) {\n this.visible = visible;\n }\n\n run(root) {\n this.visit(root);\n }\n\n visitArray(nodes) {\n if (!nodes) {\n return nodes;\n }\n\n const cnt = nodes.length;\n let i;\n for (i = 0; i < cnt; i++) {\n this.visit(nodes[i]);\n }\n return nodes;\n }\n\n visit(node) {\n if (!node) {\n return node;\n }\n if (node.constructor === Array) {\n return this.visitArray(node);\n }\n\n if (!node.blocksVisibility || node.blocksVisibility()) {\n return node;\n }\n if (this.visible) {\n node.ensureVisibility();\n } else {\n node.ensureInvisibility();\n }\n\n node.accept(this);\n return node;\n }\n}\n\nexport default SetTreeVisibilityVisitor;","import tree from '../tree';\nimport Visitor from './visitor';\nimport logger from '../logger';\nimport * as utils from '../utils';\n\n/* jshint loopfunc:true */\n\nclass ExtendFinderVisitor {\n constructor() {\n this._visitor = new Visitor(this);\n this.contexts = [];\n this.allExtendsStack = [[]];\n }\n\n run(root) {\n root = this._visitor.visit(root);\n root.allExtends = this.allExtendsStack[0];\n return root;\n }\n\n visitDeclaration(declNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n if (rulesetNode.root) {\n return;\n }\n\n let i;\n let j;\n let extend;\n const allSelectorsExtendList = [];\n let extendList;\n\n // get &:extend(.a); rules which apply to all selectors in this ruleset\n const rules = rulesetNode.rules;\n\n const ruleCnt = rules ? rules.length : 0;\n for (i = 0; i < ruleCnt; i++) {\n if (rulesetNode.rules[i] instanceof tree.Extend) {\n allSelectorsExtendList.push(rules[i]);\n rulesetNode.extendOnEveryPath = true;\n }\n }\n\n // now find every selector and apply the extends that apply to all extends\n // and the ones which apply to an individual extend\n const paths = rulesetNode.paths;\n for (i = 0; i < paths.length; i++) {\n const selectorPath = paths[i];\n const selector = selectorPath[selectorPath.length - 1];\n const selExtendList = selector.extendList;\n\n extendList = selExtendList ? utils.copyArray(selExtendList).concat(allSelectorsExtendList)\n : allSelectorsExtendList;\n\n if (extendList) {\n extendList = extendList.map(allSelectorsExtend => allSelectorsExtend.clone());\n }\n\n for (j = 0; j < extendList.length; j++) {\n this.foundExtends = true;\n extend = extendList[j];\n extend.findSelfSelectors(selectorPath);\n extend.ruleset = rulesetNode;\n if (j === 0) { extend.firstExtendOnThisSelectorPath = true; }\n this.allExtendsStack[this.allExtendsStack.length - 1].push(extend);\n }\n }\n\n this.contexts.push(rulesetNode.selectors);\n }\n\n visitRulesetOut(rulesetNode) {\n if (!rulesetNode.root) {\n this.contexts.length = this.contexts.length - 1;\n }\n }\n\n visitMedia(mediaNode, visitArgs) {\n mediaNode.allExtends = [];\n this.allExtendsStack.push(mediaNode.allExtends);\n }\n\n visitMediaOut(mediaNode) {\n this.allExtendsStack.length = this.allExtendsStack.length - 1;\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n atRuleNode.allExtends = [];\n this.allExtendsStack.push(atRuleNode.allExtends);\n }\n\n visitAtRuleOut(atRuleNode) {\n this.allExtendsStack.length = this.allExtendsStack.length - 1;\n }\n}\n\nclass ProcessExtendsVisitor {\n constructor() {\n this._visitor = new Visitor(this);\n }\n\n run(root) {\n const extendFinder = new ExtendFinderVisitor();\n this.extendIndices = {};\n extendFinder.run(root);\n if (!extendFinder.foundExtends) { return root; }\n root.allExtends = root.allExtends.concat(this.doExtendChaining(root.allExtends, root.allExtends));\n this.allExtendsStack = [root.allExtends];\n const newRoot = this._visitor.visit(root);\n this.checkExtendsForNonMatched(root.allExtends);\n return newRoot;\n }\n\n checkExtendsForNonMatched(extendList) {\n const indices = this.extendIndices;\n extendList.filter(extend => !extend.hasFoundMatches && extend.parent_ids.length == 1).forEach(extend => {\n let selector = '_unknown_';\n try {\n selector = extend.selector.toCSS({});\n }\n catch (_) {}\n\n if (!indices[`${extend.index} ${selector}`]) {\n indices[`${extend.index} ${selector}`] = true;\n logger.warn(`extend '${selector}' has no matches`);\n }\n });\n }\n\n doExtendChaining(extendsList, extendsListTarget, iterationCount) {\n //\n // chaining is different from normal extension.. if we extend an extend then we are not just copying, altering\n // and pasting the selector we would do normally, but we are also adding an extend with the same target selector\n // this means this new extend can then go and alter other extends\n //\n // this method deals with all the chaining work - without it, extend is flat and doesn't work on other extend selectors\n // this is also the most expensive.. and a match on one selector can cause an extension of a selector we had already\n // processed if we look at each selector at a time, as is done in visitRuleset\n\n let extendIndex;\n\n let targetExtendIndex;\n let matches;\n const extendsToAdd = [];\n let newSelector;\n const extendVisitor = this;\n let selectorPath;\n let extend;\n let targetExtend;\n let newExtend;\n\n iterationCount = iterationCount || 0;\n\n // loop through comparing every extend with every target extend.\n // a target extend is the one on the ruleset we are looking at copy/edit/pasting in place\n // e.g. .a:extend(.b) {} and .b:extend(.c) {} then the first extend extends the second one\n // and the second is the target.\n // the separation into two lists allows us to process a subset of chains with a bigger set, as is the\n // case when processing media queries\n for (extendIndex = 0; extendIndex < extendsList.length; extendIndex++) {\n for (targetExtendIndex = 0; targetExtendIndex < extendsListTarget.length; targetExtendIndex++) {\n\n extend = extendsList[extendIndex];\n targetExtend = extendsListTarget[targetExtendIndex];\n\n // look for circular references\n if ( extend.parent_ids.indexOf( targetExtend.object_id ) >= 0 ) { continue; }\n\n // find a match in the target extends self selector (the bit before :extend)\n selectorPath = [targetExtend.selfSelectors[0]];\n matches = extendVisitor.findMatch(extend, selectorPath);\n\n if (matches.length) {\n extend.hasFoundMatches = true;\n\n // we found a match, so for each self selector..\n extend.selfSelectors.forEach(selfSelector => {\n const info = targetExtend.visibilityInfo();\n\n // process the extend as usual\n newSelector = extendVisitor.extendSelector(matches, selectorPath, selfSelector, extend.isVisible());\n\n // but now we create a new extend from it\n newExtend = new(tree.Extend)(targetExtend.selector, targetExtend.option, 0, targetExtend.fileInfo(), info);\n newExtend.selfSelectors = newSelector;\n\n // add the extend onto the list of extends for that selector\n newSelector[newSelector.length - 1].extendList = [newExtend];\n\n // record that we need to add it.\n extendsToAdd.push(newExtend);\n newExtend.ruleset = targetExtend.ruleset;\n\n // remember its parents for circular references\n newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);\n\n // only process the selector once.. if we have :extend(.a,.b) then multiple\n // extends will look at the same selector path, so when extending\n // we know that any others will be duplicates in terms of what is added to the css\n if (targetExtend.firstExtendOnThisSelectorPath) {\n newExtend.firstExtendOnThisSelectorPath = true;\n targetExtend.ruleset.paths.push(newSelector);\n }\n });\n }\n }\n }\n\n if (extendsToAdd.length) {\n // try to detect circular references to stop a stack overflow.\n // may no longer be needed.\n this.extendChainCount++;\n if (iterationCount > 100) {\n let selectorOne = '{unable to calculate}';\n let selectorTwo = '{unable to calculate}';\n try {\n selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();\n selectorTwo = extendsToAdd[0].selector.toCSS();\n }\n catch (e) {}\n throw { message: `extend circular reference detected. One of the circular extends is currently:${selectorOne}:extend(${selectorTwo})`};\n }\n\n // now process the new extends on the existing rules so that we can handle a extending b extending c extending\n // d extending e...\n return extendsToAdd.concat(extendVisitor.doExtendChaining(extendsToAdd, extendsListTarget, iterationCount + 1));\n } else {\n return extendsToAdd;\n }\n }\n\n visitDeclaration(ruleNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitSelector(selectorNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n if (rulesetNode.root) {\n return;\n }\n let matches;\n let pathIndex;\n let extendIndex;\n const allExtends = this.allExtendsStack[this.allExtendsStack.length - 1];\n const selectorsToAdd = [];\n const extendVisitor = this;\n let selectorPath;\n\n // look at each selector path in the ruleset, find any extend matches and then copy, find and replace\n\n for (extendIndex = 0; extendIndex < allExtends.length; extendIndex++) {\n for (pathIndex = 0; pathIndex < rulesetNode.paths.length; pathIndex++) {\n selectorPath = rulesetNode.paths[pathIndex];\n\n // extending extends happens initially, before the main pass\n if (rulesetNode.extendOnEveryPath) { continue; }\n const extendList = selectorPath[selectorPath.length - 1].extendList;\n if (extendList && extendList.length) { continue; }\n\n matches = this.findMatch(allExtends[extendIndex], selectorPath);\n\n if (matches.length) {\n allExtends[extendIndex].hasFoundMatches = true;\n\n allExtends[extendIndex].selfSelectors.forEach(selfSelector => {\n let extendedSelectors;\n extendedSelectors = extendVisitor.extendSelector(matches, selectorPath, selfSelector, allExtends[extendIndex].isVisible());\n selectorsToAdd.push(extendedSelectors);\n });\n }\n }\n }\n rulesetNode.paths = rulesetNode.paths.concat(selectorsToAdd);\n }\n\n findMatch(extend, haystackSelectorPath) {\n //\n // look through the haystack selector path to try and find the needle - extend.selector\n // returns an array of selector matches that can then be replaced\n //\n let haystackSelectorIndex;\n\n let hackstackSelector;\n let hackstackElementIndex;\n let haystackElement;\n let targetCombinator;\n let i;\n const extendVisitor = this;\n const needleElements = extend.selector.elements;\n const potentialMatches = [];\n let potentialMatch;\n const matches = [];\n\n // loop through the haystack elements\n for (haystackSelectorIndex = 0; haystackSelectorIndex < haystackSelectorPath.length; haystackSelectorIndex++) {\n hackstackSelector = haystackSelectorPath[haystackSelectorIndex];\n\n for (hackstackElementIndex = 0; hackstackElementIndex < hackstackSelector.elements.length; hackstackElementIndex++) {\n\n haystackElement = hackstackSelector.elements[hackstackElementIndex];\n\n // if we allow elements before our match we can add a potential match every time. otherwise only at the first element.\n if (extend.allowBefore || (haystackSelectorIndex === 0 && hackstackElementIndex === 0)) {\n potentialMatches.push({pathIndex: haystackSelectorIndex, index: hackstackElementIndex, matched: 0,\n initialCombinator: haystackElement.combinator});\n }\n\n for (i = 0; i < potentialMatches.length; i++) {\n potentialMatch = potentialMatches[i];\n\n // selectors add \" \" onto the first element. When we use & it joins the selectors together, but if we don't\n // then each selector in haystackSelectorPath has a space before it added in the toCSS phase. so we need to\n // work out what the resulting combinator will be\n targetCombinator = haystackElement.combinator.value;\n if (targetCombinator === '' && hackstackElementIndex === 0) {\n targetCombinator = ' ';\n }\n\n // if we don't match, null our match to indicate failure\n if (!extendVisitor.isElementValuesEqual(needleElements[potentialMatch.matched].value, haystackElement.value) ||\n (potentialMatch.matched > 0 && needleElements[potentialMatch.matched].combinator.value !== targetCombinator)) {\n potentialMatch = null;\n } else {\n potentialMatch.matched++;\n }\n\n // if we are still valid and have finished, test whether we have elements after and whether these are allowed\n if (potentialMatch) {\n potentialMatch.finished = potentialMatch.matched === needleElements.length;\n if (potentialMatch.finished &&\n (!extend.allowAfter &&\n (hackstackElementIndex + 1 < hackstackSelector.elements.length || haystackSelectorIndex + 1 < haystackSelectorPath.length))) {\n potentialMatch = null;\n }\n }\n // if null we remove, if not, we are still valid, so either push as a valid match or continue\n if (potentialMatch) {\n if (potentialMatch.finished) {\n potentialMatch.length = needleElements.length;\n potentialMatch.endPathIndex = haystackSelectorIndex;\n potentialMatch.endPathElementIndex = hackstackElementIndex + 1; // index after end of match\n potentialMatches.length = 0; // we don't allow matches to overlap, so start matching again\n matches.push(potentialMatch);\n }\n } else {\n potentialMatches.splice(i, 1);\n i--;\n }\n }\n }\n }\n return matches;\n }\n\n isElementValuesEqual(elementValue1, elementValue2) {\n if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {\n return elementValue1 === elementValue2;\n }\n if (elementValue1 instanceof tree.Attribute) {\n if (elementValue1.op !== elementValue2.op || elementValue1.key !== elementValue2.key) {\n return false;\n }\n if (!elementValue1.value || !elementValue2.value) {\n if (elementValue1.value || elementValue2.value) {\n return false;\n }\n return true;\n }\n elementValue1 = elementValue1.value.value || elementValue1.value;\n elementValue2 = elementValue2.value.value || elementValue2.value;\n return elementValue1 === elementValue2;\n }\n elementValue1 = elementValue1.value;\n elementValue2 = elementValue2.value;\n if (elementValue1 instanceof tree.Selector) {\n if (!(elementValue2 instanceof tree.Selector) || elementValue1.elements.length !== elementValue2.elements.length) {\n return false;\n }\n for (let i = 0; i < elementValue1.elements.length; i++) {\n if (elementValue1.elements[i].combinator.value !== elementValue2.elements[i].combinator.value) {\n if (i !== 0 || (elementValue1.elements[i].combinator.value || ' ') !== (elementValue2.elements[i].combinator.value || ' ')) {\n return false;\n }\n }\n if (!this.isElementValuesEqual(elementValue1.elements[i].value, elementValue2.elements[i].value)) {\n return false;\n }\n }\n return true;\n }\n return false;\n }\n\n extendSelector(matches, selectorPath, replacementSelector, isVisible) {\n // for a set of matches, replace each match with the replacement selector\n\n let currentSelectorPathIndex = 0;\n\n let currentSelectorPathElementIndex = 0;\n let path = [];\n let matchIndex;\n let selector;\n let firstElement;\n let match;\n let newElements;\n\n for (matchIndex = 0; matchIndex < matches.length; matchIndex++) {\n match = matches[matchIndex];\n selector = selectorPath[match.pathIndex];\n firstElement = new tree.Element(\n match.initialCombinator,\n replacementSelector.elements[0].value,\n replacementSelector.elements[0].isVariable,\n replacementSelector.elements[0].getIndex(),\n replacementSelector.elements[0].fileInfo()\n );\n\n if (match.pathIndex > currentSelectorPathIndex && currentSelectorPathElementIndex > 0) {\n path[path.length - 1].elements = path[path.length - 1]\n .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n currentSelectorPathElementIndex = 0;\n currentSelectorPathIndex++;\n }\n\n newElements = selector.elements\n .slice(currentSelectorPathElementIndex, match.index)\n .concat([firstElement])\n .concat(replacementSelector.elements.slice(1));\n\n if (currentSelectorPathIndex === match.pathIndex && matchIndex > 0) {\n path[path.length - 1].elements =\n path[path.length - 1].elements.concat(newElements);\n } else {\n path = path.concat(selectorPath.slice(currentSelectorPathIndex, match.pathIndex));\n\n path.push(new tree.Selector(\n newElements\n ));\n }\n currentSelectorPathIndex = match.endPathIndex;\n currentSelectorPathElementIndex = match.endPathElementIndex;\n if (currentSelectorPathElementIndex >= selectorPath[currentSelectorPathIndex].elements.length) {\n currentSelectorPathElementIndex = 0;\n currentSelectorPathIndex++;\n }\n }\n\n if (currentSelectorPathIndex < selectorPath.length && currentSelectorPathElementIndex > 0) {\n path[path.length - 1].elements = path[path.length - 1]\n .elements.concat(selectorPath[currentSelectorPathIndex].elements.slice(currentSelectorPathElementIndex));\n currentSelectorPathIndex++;\n }\n\n path = path.concat(selectorPath.slice(currentSelectorPathIndex, selectorPath.length));\n path = path.map(currentValue => {\n // we can re-use elements here, because the visibility property matters only for selectors\n const derived = currentValue.createDerived(currentValue.elements);\n if (isVisible) {\n derived.ensureVisibility();\n } else {\n derived.ensureInvisibility();\n }\n return derived;\n });\n return path;\n }\n\n visitMedia(mediaNode, visitArgs) {\n let newAllExtends = mediaNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, mediaNode.allExtends));\n this.allExtendsStack.push(newAllExtends);\n }\n\n visitMediaOut(mediaNode) {\n const lastIndex = this.allExtendsStack.length - 1;\n this.allExtendsStack.length = lastIndex;\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n let newAllExtends = atRuleNode.allExtends.concat(this.allExtendsStack[this.allExtendsStack.length - 1]);\n newAllExtends = newAllExtends.concat(this.doExtendChaining(newAllExtends, atRuleNode.allExtends));\n this.allExtendsStack.push(newAllExtends);\n }\n\n visitAtRuleOut(atRuleNode) {\n const lastIndex = this.allExtendsStack.length - 1;\n this.allExtendsStack.length = lastIndex;\n }\n}\n\nexport default ProcessExtendsVisitor;\n","import Visitor from './visitor';\n\nclass JoinSelectorVisitor {\n constructor() {\n this.contexts = [[]];\n this._visitor = new Visitor(this);\n }\n\n run(root) {\n return this._visitor.visit(root);\n }\n\n visitDeclaration(declNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitMixinDefinition(mixinDefinitionNode, visitArgs) {\n visitArgs.visitDeeper = false;\n }\n\n visitRuleset(rulesetNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n const paths = [];\n let selectors;\n\n this.contexts.push(paths);\n\n if (!rulesetNode.root) {\n selectors = rulesetNode.selectors;\n if (selectors) {\n selectors = selectors.filter(selector => selector.getIsOutput());\n rulesetNode.selectors = selectors.length ? selectors : (selectors = null);\n if (selectors) { rulesetNode.joinSelectors(paths, context, selectors); }\n }\n if (!selectors) { rulesetNode.rules = null; }\n rulesetNode.paths = paths;\n }\n }\n\n visitRulesetOut(rulesetNode) {\n this.contexts.length = this.contexts.length - 1;\n }\n\n visitMedia(mediaNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n mediaNode.rules[0].root = (context.length === 0 || context[0].multiMedia);\n }\n\n visitAtRule(atRuleNode, visitArgs) {\n const context = this.contexts[this.contexts.length - 1];\n if (atRuleNode.rules && atRuleNode.rules.length) {\n atRuleNode.rules[0].root = (atRuleNode.isRooted || context.length === 0 || null);\n }\n }\n}\n\nexport default JoinSelectorVisitor;\n","import tree from '../tree';\nimport Visitor from './visitor';\n\nclass CSSVisitorUtils {\n constructor(context) {\n this._visitor = new Visitor(this);\n this._context = context;\n }\n\n containsSilentNonBlockedChild(bodyRules) {\n let rule;\n if (!bodyRules) {\n return false;\n }\n for (let r = 0; r < bodyRules.length; r++) {\n rule = bodyRules[r];\n if (rule.isSilent && rule.isSilent(this._context) && !rule.blocksVisibility()) {\n // the atrule contains something that was referenced (likely by extend)\n // therefore it needs to be shown in output too\n return true;\n }\n }\n return false;\n }\n\n keepOnlyVisibleChilds(owner) {\n if (owner && owner.rules) {\n owner.rules = owner.rules.filter(thing => thing.isVisible());\n }\n }\n\n isEmpty(owner) {\n return (owner && owner.rules) \n ? (owner.rules.length === 0) : true;\n }\n\n hasVisibleSelector(rulesetNode) {\n return (rulesetNode && rulesetNode.paths)\n ? (rulesetNode.paths.length > 0) : false;\n }\n\n resolveVisibility(node, originalRules) {\n if (!node.blocksVisibility()) {\n if (this.isEmpty(node) && !this.containsSilentNonBlockedChild(originalRules)) {\n return ;\n }\n\n return node;\n }\n\n const compiledRulesBody = node.rules[0];\n this.keepOnlyVisibleChilds(compiledRulesBody);\n\n if (this.isEmpty(compiledRulesBody)) {\n return ;\n }\n\n node.ensureVisibility();\n node.removeVisibilityBlock();\n\n return node;\n }\n\n isVisibleRuleset(rulesetNode) {\n if (rulesetNode.firstRoot) {\n return true;\n }\n\n if (this.isEmpty(rulesetNode)) {\n return false;\n }\n\n if (!rulesetNode.root && !this.hasVisibleSelector(rulesetNode)) {\n return false;\n }\n\n return true;\n }\n}\n\nconst ToCSSVisitor = function(context) {\n this._visitor = new Visitor(this);\n this._context = context;\n this.utils = new CSSVisitorUtils(context);\n};\n\nToCSSVisitor.prototype = {\n isReplacing: true,\n run: function (root) {\n return this._visitor.visit(root);\n },\n\n visitDeclaration: function (declNode, visitArgs) {\n if (declNode.blocksVisibility() || declNode.variable) {\n return;\n }\n return declNode;\n },\n\n visitMixinDefinition: function (mixinNode, visitArgs) {\n // mixin definitions do not get eval'd - this means they keep state\n // so we have to clear that state here so it isn't used if toCSS is called twice\n mixinNode.frames = [];\n },\n\n visitExtend: function (extendNode, visitArgs) {\n },\n\n visitComment: function (commentNode, visitArgs) {\n if (commentNode.blocksVisibility() || commentNode.isSilent(this._context)) {\n return;\n }\n return commentNode;\n },\n\n visitMedia: function(mediaNode, visitArgs) {\n const originalRules = mediaNode.rules[0].rules;\n mediaNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n\n return this.utils.resolveVisibility(mediaNode, originalRules);\n },\n\n visitImport: function (importNode, visitArgs) {\n if (importNode.blocksVisibility()) {\n return ;\n }\n return importNode;\n },\n\n visitAtRule: function(atRuleNode, visitArgs) {\n if (atRuleNode.rules && atRuleNode.rules.length) {\n return this.visitAtRuleWithBody(atRuleNode, visitArgs);\n } else {\n return this.visitAtRuleWithoutBody(atRuleNode, visitArgs);\n }\n },\n\n visitAnonymous: function(anonymousNode, visitArgs) {\n if (!anonymousNode.blocksVisibility()) {\n anonymousNode.accept(this._visitor);\n return anonymousNode;\n }\n },\n\n visitAtRuleWithBody: function(atRuleNode, visitArgs) {\n // if there is only one nested ruleset and that one has no path, then it is\n // just fake ruleset\n function hasFakeRuleset(atRuleNode) {\n const bodyRules = atRuleNode.rules;\n return bodyRules.length === 1 && (!bodyRules[0].paths || bodyRules[0].paths.length === 0);\n }\n function getBodyRules(atRuleNode) {\n const nodeRules = atRuleNode.rules;\n if (hasFakeRuleset(atRuleNode)) {\n return nodeRules[0].rules;\n }\n\n return nodeRules;\n }\n // it is still true that it is only one ruleset in array\n // this is last such moment\n // process childs\n const originalRules = getBodyRules(atRuleNode);\n atRuleNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n\n if (!this.utils.isEmpty(atRuleNode)) {\n this._mergeRules(atRuleNode.rules[0].rules);\n }\n\n return this.utils.resolveVisibility(atRuleNode, originalRules);\n },\n\n visitAtRuleWithoutBody: function(atRuleNode, visitArgs) {\n if (atRuleNode.blocksVisibility()) {\n return;\n }\n\n if (atRuleNode.name === '@charset') {\n // Only output the debug info together with subsequent @charset definitions\n // a comment (or @media statement) before the actual @charset atrule would\n // be considered illegal css as it has to be on the first line\n if (this.charset) {\n if (atRuleNode.debugInfo) {\n const comment = new tree.Comment(`/* ${atRuleNode.toCSS(this._context).replace(/\\n/g, '')} */\\n`);\n comment.debugInfo = atRuleNode.debugInfo;\n return this._visitor.visit(comment);\n }\n return;\n }\n this.charset = true;\n }\n\n return atRuleNode;\n },\n\n checkValidNodes: function(rules, isRoot) {\n if (!rules) {\n return;\n }\n\n for (let i = 0; i < rules.length; i++) {\n const ruleNode = rules[i];\n if (isRoot && ruleNode instanceof tree.Declaration && !ruleNode.variable) {\n throw { message: 'Properties must be inside selector blocks. They cannot be in the root',\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n if (ruleNode instanceof tree.Call) {\n throw { message: `Function '${ruleNode.name}' is undefined`,\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n if (ruleNode.type && !ruleNode.allowRoot) {\n throw { message: `${ruleNode.type} node returned by a function is not valid here`,\n index: ruleNode.getIndex(), filename: ruleNode.fileInfo() && ruleNode.fileInfo().filename};\n }\n }\n },\n\n visitRuleset: function (rulesetNode, visitArgs) {\n // at this point rulesets are nested into each other\n let rule;\n\n const rulesets = [];\n\n this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot);\n\n if (!rulesetNode.root) {\n // remove invisible paths\n this._compileRulesetPaths(rulesetNode);\n\n // remove rulesets from this ruleset body and compile them separately\n const nodeRules = rulesetNode.rules;\n\n let nodeRuleCnt = nodeRules ? nodeRules.length : 0;\n for (let i = 0; i < nodeRuleCnt; ) {\n rule = nodeRules[i];\n if (rule && rule.rules) {\n // visit because we are moving them out from being a child\n rulesets.push(this._visitor.visit(rule));\n nodeRules.splice(i, 1);\n nodeRuleCnt--;\n continue;\n }\n i++;\n }\n // accept the visitor to remove rules and refactor itself\n // then we can decide nogw whether we want it or not\n // compile body\n if (nodeRuleCnt > 0) {\n rulesetNode.accept(this._visitor);\n } else {\n rulesetNode.rules = null;\n }\n visitArgs.visitDeeper = false;\n } else { // if (! rulesetNode.root) {\n rulesetNode.accept(this._visitor);\n visitArgs.visitDeeper = false;\n }\n\n if (rulesetNode.rules) {\n this._mergeRules(rulesetNode.rules);\n this._removeDuplicateRules(rulesetNode.rules);\n }\n\n // now decide whether we keep the ruleset\n if (this.utils.isVisibleRuleset(rulesetNode)) {\n rulesetNode.ensureVisibility();\n rulesets.splice(0, 0, rulesetNode);\n }\n\n if (rulesets.length === 1) {\n return rulesets[0];\n }\n return rulesets;\n },\n\n _compileRulesetPaths: function(rulesetNode) {\n if (rulesetNode.paths) {\n rulesetNode.paths = rulesetNode.paths\n .filter(p => {\n let i;\n if (p[0].elements[0].combinator.value === ' ') {\n p[0].elements[0].combinator = new(tree.Combinator)('');\n }\n for (i = 0; i < p.length; i++) {\n if (p[i].isVisible() && p[i].getIsOutput()) {\n return true;\n }\n }\n return false;\n });\n }\n },\n\n _removeDuplicateRules: function(rules) {\n if (!rules) { return; }\n\n // remove duplicates\n const ruleCache = {};\n\n let ruleList;\n let rule;\n let i;\n\n for (i = rules.length - 1; i >= 0 ; i--) {\n rule = rules[i];\n if (rule instanceof tree.Declaration) {\n if (!ruleCache[rule.name]) {\n ruleCache[rule.name] = rule;\n } else {\n ruleList = ruleCache[rule.name];\n if (ruleList instanceof tree.Declaration) {\n ruleList = ruleCache[rule.name] = [ruleCache[rule.name].toCSS(this._context)];\n }\n const ruleCSS = rule.toCSS(this._context);\n if (ruleList.indexOf(ruleCSS) !== -1) {\n rules.splice(i, 1);\n } else {\n ruleList.push(ruleCSS);\n }\n }\n }\n }\n },\n\n _mergeRules: function(rules) {\n if (!rules) {\n return; \n }\n\n const groups = {};\n const groupsArr = [];\n\n for (let i = 0; i < rules.length; i++) {\n const rule = rules[i];\n if (rule.merge) {\n const key = rule.name;\n groups[key] ? rules.splice(i--, 1) : \n groupsArr.push(groups[key] = []);\n groups[key].push(rule);\n }\n }\n\n groupsArr.forEach(group => {\n if (group.length > 0) {\n const result = group[0];\n let space = [];\n const comma = [new tree.Expression(space)];\n group.forEach(rule => {\n if ((rule.merge === '+') && (space.length > 0)) {\n comma.push(new tree.Expression(space = []));\n }\n space.push(rule.value);\n result.important = result.important || rule.important;\n });\n result.value = new tree.Value(comma);\n }\n });\n }\n};\n\nexport default ToCSSVisitor;\n","import Visitor from './visitor';\nimport ImportVisitor from './import-visitor';\nimport MarkVisibleSelectorsVisitor from './set-tree-visibility-visitor';\nimport ExtendVisitor from './extend-visitor';\nimport JoinSelectorVisitor from './join-selector-visitor';\nimport ToCSSVisitor from './to-css-visitor';\n\nexport default {\n Visitor,\n ImportVisitor,\n MarkVisibleSelectorsVisitor,\n ExtendVisitor,\n JoinSelectorVisitor,\n ToCSSVisitor\n};\n","import chunker from './chunker';\n\nexport default () => {\n let // Less input string\n input;\n\n let // current chunk\n j;\n\n const // holds state for backtracking\n saveStack = [];\n\n let // furthest index the parser has gone to\n furthest;\n\n let // if this is furthest we got to, this is the probably cause\n furthestPossibleErrorMessage;\n\n let // chunkified input\n chunks;\n\n let // current chunk\n current;\n\n let // index of current chunk, in `input`\n currentPos;\n\n const parserInput = {};\n const CHARCODE_SPACE = 32;\n const CHARCODE_TAB = 9;\n const CHARCODE_LF = 10;\n const CHARCODE_CR = 13;\n const CHARCODE_PLUS = 43;\n const CHARCODE_COMMA = 44;\n const CHARCODE_FORWARD_SLASH = 47;\n const CHARCODE_9 = 57;\n\n function skipWhitespace(length) {\n const oldi = parserInput.i;\n const oldj = j;\n const curr = parserInput.i - currentPos;\n const endIndex = parserInput.i + current.length - curr;\n const mem = (parserInput.i += length);\n const inp = input;\n let c;\n let nextChar;\n let comment;\n\n for (; parserInput.i < endIndex; parserInput.i++) {\n c = inp.charCodeAt(parserInput.i);\n\n if (parserInput.autoCommentAbsorb && c === CHARCODE_FORWARD_SLASH) {\n nextChar = inp.charAt(parserInput.i + 1);\n if (nextChar === '/') {\n comment = {index: parserInput.i, isLineComment: true};\n let nextNewLine = inp.indexOf('\\n', parserInput.i + 2);\n if (nextNewLine < 0) {\n nextNewLine = endIndex;\n }\n parserInput.i = nextNewLine;\n comment.text = inp.substr(comment.index, parserInput.i - comment.index);\n parserInput.commentStore.push(comment);\n continue;\n } else if (nextChar === '*') {\n const nextStarSlash = inp.indexOf('*/', parserInput.i + 2);\n if (nextStarSlash >= 0) {\n comment = {\n index: parserInput.i,\n text: inp.substr(parserInput.i, nextStarSlash + 2 - parserInput.i),\n isLineComment: false\n };\n parserInput.i += comment.text.length - 1;\n parserInput.commentStore.push(comment);\n continue;\n }\n }\n break;\n }\n\n if ((c !== CHARCODE_SPACE) && (c !== CHARCODE_LF) && (c !== CHARCODE_TAB) && (c !== CHARCODE_CR)) {\n break;\n }\n }\n\n current = current.slice(length + parserInput.i - mem + curr);\n currentPos = parserInput.i;\n\n if (!current.length) {\n if (j < chunks.length - 1) {\n current = chunks[++j];\n skipWhitespace(0); // skip space at the beginning of a chunk\n return true; // things changed\n }\n parserInput.finished = true;\n }\n\n return oldi !== parserInput.i || oldj !== j;\n }\n\n parserInput.save = () => {\n currentPos = parserInput.i;\n saveStack.push( { current, i: parserInput.i, j });\n };\n parserInput.restore = possibleErrorMessage => {\n\n if (parserInput.i > furthest || (parserInput.i === furthest && possibleErrorMessage && !furthestPossibleErrorMessage)) {\n furthest = parserInput.i;\n furthestPossibleErrorMessage = possibleErrorMessage;\n }\n const state = saveStack.pop();\n current = state.current;\n currentPos = parserInput.i = state.i;\n j = state.j;\n };\n parserInput.forget = () => {\n saveStack.pop();\n };\n parserInput.isWhitespace = offset => {\n const pos = parserInput.i + (offset || 0);\n const code = input.charCodeAt(pos);\n return (code === CHARCODE_SPACE || code === CHARCODE_CR || code === CHARCODE_TAB || code === CHARCODE_LF);\n };\n\n // Specialization of $(tok)\n parserInput.$re = tok => {\n if (parserInput.i > currentPos) {\n current = current.slice(parserInput.i - currentPos);\n currentPos = parserInput.i;\n }\n\n const m = tok.exec(current);\n if (!m) {\n return null;\n }\n\n skipWhitespace(m[0].length);\n if (typeof m === 'string') {\n return m;\n }\n\n return m.length === 1 ? m[0] : m;\n };\n\n parserInput.$char = tok => {\n if (input.charAt(parserInput.i) !== tok) {\n return null;\n }\n skipWhitespace(1);\n return tok;\n };\n\n parserInput.$str = tok => {\n const tokLength = tok.length;\n\n // https://jsperf.com/string-startswith/21\n for (let i = 0; i < tokLength; i++) {\n if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n return null;\n }\n }\n\n skipWhitespace(tokLength);\n return tok;\n };\n\n parserInput.$quoted = loc => {\n const pos = loc || parserInput.i;\n const startChar = input.charAt(pos);\n\n if (startChar !== '\\'' && startChar !== '\"') {\n return;\n }\n const length = input.length;\n const currentPosition = pos;\n\n for (let i = 1; i + currentPosition < length; i++) {\n const nextChar = input.charAt(i + currentPosition);\n switch (nextChar) {\n case '\\\\':\n i++;\n continue;\n case '\\r':\n case '\\n':\n break;\n case startChar:\n const str = input.substr(currentPosition, i + 1);\n if (!loc && loc !== 0) {\n skipWhitespace(i + 1);\n return str\n }\n return [startChar, str];\n default:\n }\n }\n return null;\n };\n\n /**\n * Permissive parsing. Ignores everything except matching {} [] () and quotes\n * until matching token (outside of blocks)\n */\n parserInput.$parseUntil = tok => {\n let quote = '';\n let returnVal = null;\n let inComment = false;\n let blockDepth = 0;\n const blockStack = [];\n const parseGroups = [];\n const length = input.length;\n const startPos = parserInput.i;\n let lastPos = parserInput.i;\n let i = parserInput.i;\n let loop = true;\n let testChar;\n\n if (typeof tok === 'string') {\n testChar = char => char === tok\n } else {\n testChar = char => tok.test(char)\n }\n\n do {\n let prevChar;\n let nextChar = input.charAt(i);\n if (blockDepth === 0 && testChar(nextChar)) {\n returnVal = input.substr(lastPos, i - lastPos);\n if (returnVal) {\n parseGroups.push(returnVal);\n }\n else {\n parseGroups.push(' ');\n }\n returnVal = parseGroups;\n skipWhitespace(i - startPos);\n loop = false\n } else {\n if (inComment) {\n if (nextChar === '*' && \n input.charAt(i + 1) === '/') {\n i++;\n blockDepth--;\n inComment = false;\n }\n i++;\n continue;\n }\n switch (nextChar) {\n case '\\\\':\n i++;\n nextChar = input.charAt(i);\n parseGroups.push(input.substr(lastPos, i - lastPos + 1));\n lastPos = i + 1;\n break;\n case '/':\n if (input.charAt(i + 1) === '*') {\n i++;\n inComment = true;\n blockDepth++;\n }\n break;\n case '\\'':\n case '\"':\n quote = parserInput.$quoted(i);\n if (quote) {\n parseGroups.push(input.substr(lastPos, i - lastPos), quote);\n i += quote[1].length - 1;\n lastPos = i + 1;\n }\n else {\n skipWhitespace(i - startPos);\n returnVal = nextChar;\n loop = false;\n }\n break;\n case '{':\n blockStack.push('}');\n blockDepth++;\n break;\n case '(':\n blockStack.push(')');\n blockDepth++;\n break;\n case '[':\n blockStack.push(']');\n blockDepth++;\n break;\n case '}':\n case ')':\n case ']':\n const expected = blockStack.pop();\n if (nextChar === expected) {\n blockDepth--;\n } else {\n // move the parser to the error and return expected\n skipWhitespace(i - startPos);\n returnVal = expected;\n loop = false;\n }\n }\n i++;\n if (i > length) {\n loop = false;\n }\n }\n prevChar = nextChar;\n } while (loop);\n\n return returnVal ? returnVal : null;\n }\n\n parserInput.autoCommentAbsorb = true;\n parserInput.commentStore = [];\n parserInput.finished = false;\n\n // Same as $(), but don't change the state of the parser,\n // just return the match.\n parserInput.peek = tok => {\n if (typeof tok === 'string') {\n // https://jsperf.com/string-startswith/21\n for (let i = 0; i < tok.length; i++) {\n if (input.charAt(parserInput.i + i) !== tok.charAt(i)) {\n return false;\n }\n }\n return true;\n } else {\n return tok.test(current);\n }\n };\n\n // Specialization of peek()\n // TODO remove or change some currentChar calls to peekChar\n parserInput.peekChar = tok => input.charAt(parserInput.i) === tok;\n\n parserInput.currentChar = () => input.charAt(parserInput.i);\n\n parserInput.prevChar = () => input.charAt(parserInput.i - 1);\n\n parserInput.getInput = () => input;\n\n parserInput.peekNotNumeric = () => {\n const c = input.charCodeAt(parserInput.i);\n // Is the first char of the dimension 0-9, '.', '+' or '-'\n return (c > CHARCODE_9 || c < CHARCODE_PLUS) || c === CHARCODE_FORWARD_SLASH || c === CHARCODE_COMMA;\n };\n\n parserInput.start = (str, chunkInput, failFunction) => {\n input = str;\n parserInput.i = j = currentPos = furthest = 0;\n\n // chunking apparently makes things quicker (but my tests indicate\n // it might actually make things slower in node at least)\n // and it is a non-perfect parse - it can't recognise\n // unquoted urls, meaning it can't distinguish comments\n // meaning comments with quotes or {}() in them get 'counted'\n // and then lead to parse errors.\n // In addition if the chunking chunks in the wrong place we might\n // not be able to parse a parser statement in one go\n // this is officially deprecated but can be switched on via an option\n // in the case it causes too much performance issues.\n if (chunkInput) {\n chunks = chunker(str, failFunction);\n } else {\n chunks = [str];\n }\n\n current = chunks[0];\n\n skipWhitespace(0);\n };\n\n parserInput.end = () => {\n let message;\n const isFinished = parserInput.i >= input.length;\n\n if (parserInput.i < furthest) {\n message = furthestPossibleErrorMessage;\n parserInput.i = furthest;\n }\n return {\n isFinished,\n furthest: parserInput.i,\n furthestPossibleErrorMessage: message,\n furthestReachedEnd: parserInput.i >= input.length - 1,\n furthestChar: input[parserInput.i]\n };\n };\n\n return parserInput;\n};\n","// Split the input into chunks.\nexport default (input, fail) => {\n const len = input.length;\n let level = 0;\n let parenLevel = 0;\n let lastOpening;\n let lastOpeningParen;\n let lastMultiComment;\n let lastMultiCommentEndBrace;\n const chunks = [];\n let emitFrom = 0;\n let chunkerCurrentIndex;\n let currentChunkStartIndex;\n let cc;\n let cc2;\n let matched;\n\n function emitChunk(force) {\n const len = chunkerCurrentIndex - emitFrom;\n if (((len < 512) && !force) || !len) {\n return;\n }\n chunks.push(input.slice(emitFrom, chunkerCurrentIndex + 1));\n emitFrom = chunkerCurrentIndex + 1;\n }\n\n for (chunkerCurrentIndex = 0; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc = input.charCodeAt(chunkerCurrentIndex);\n if (((cc >= 97) && (cc <= 122)) || (cc < 34)) {\n // a-z or whitespace\n continue;\n }\n\n switch (cc) {\n case 40: // (\n parenLevel++;\n lastOpeningParen = chunkerCurrentIndex;\n continue;\n case 41: // )\n if (--parenLevel < 0) {\n return fail('missing opening `(`', chunkerCurrentIndex);\n }\n continue;\n case 59: // ;\n if (!parenLevel) { emitChunk(); }\n continue;\n case 123: // {\n level++;\n lastOpening = chunkerCurrentIndex;\n continue;\n case 125: // }\n if (--level < 0) {\n return fail('missing opening `{`', chunkerCurrentIndex);\n }\n if (!level && !parenLevel) { emitChunk(); }\n continue;\n case 92: // \\\n if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }\n return fail('unescaped `\\\\`', chunkerCurrentIndex);\n case 34:\n case 39:\n case 96: // \", ' and `\n matched = 0;\n currentChunkStartIndex = chunkerCurrentIndex;\n for (chunkerCurrentIndex = chunkerCurrentIndex + 1; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if (cc2 > 96) { continue; }\n if (cc2 == cc) { matched = 1; break; }\n if (cc2 == 92) { // \\\n if (chunkerCurrentIndex == len - 1) {\n return fail('unescaped `\\\\`', chunkerCurrentIndex);\n }\n chunkerCurrentIndex++;\n }\n }\n if (matched) { continue; }\n return fail(`unmatched \\`${String.fromCharCode(cc)}\\``, currentChunkStartIndex);\n case 47: // /, check for comment\n if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }\n cc2 = input.charCodeAt(chunkerCurrentIndex + 1);\n if (cc2 == 47) {\n // //, find lnfeed\n for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if ((cc2 <= 13) && ((cc2 == 10) || (cc2 == 13))) { break; }\n }\n } else if (cc2 == 42) {\n // /*, find */\n lastMultiComment = currentChunkStartIndex = chunkerCurrentIndex;\n for (chunkerCurrentIndex = chunkerCurrentIndex + 2; chunkerCurrentIndex < len - 1; chunkerCurrentIndex++) {\n cc2 = input.charCodeAt(chunkerCurrentIndex);\n if (cc2 == 125) { lastMultiCommentEndBrace = chunkerCurrentIndex; }\n if (cc2 != 42) { continue; }\n if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }\n }\n if (chunkerCurrentIndex == len - 1) {\n return fail('missing closing `*/`', currentChunkStartIndex);\n }\n chunkerCurrentIndex++;\n }\n continue;\n case 42: // *, check for unmatched */\n if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {\n return fail('unmatched `/*`', chunkerCurrentIndex);\n }\n continue;\n }\n }\n\n if (level !== 0) {\n if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {\n return fail('missing closing `}` or `*/`', lastOpening);\n } else {\n return fail('missing closing `}`', lastOpening);\n }\n } else if (parenLevel !== 0) {\n return fail('missing closing `)`', lastOpeningParen);\n }\n\n emitChunk(true);\n return chunks;\n};\n","import LessError from '../less-error';\nimport tree from '../tree';\nimport visitors from '../visitors';\nimport getParserInput from './parser-input';\nimport * as utils from '../utils';\nimport functionRegistry from '../functions/function-registry';\n\n//\n// less.js - parser\n//\n// A relatively straight-forward predictive parser.\n// There is no tokenization/lexing stage, the input is parsed\n// in one sweep.\n//\n// To make the parser fast enough to run in the browser, several\n// optimization had to be made:\n//\n// - Matching and slicing on a huge input is often cause of slowdowns.\n// The solution is to chunkify the input into smaller strings.\n// The chunks are stored in the `chunks` var,\n// `j` holds the current chunk index, and `currentPos` holds\n// the index of the current chunk in relation to `input`.\n// This gives us an almost 4x speed-up.\n//\n// - In many cases, we don't need to match individual tokens;\n// for example, if a value doesn't hold any variables, operations\n// or dynamic references, the parser can effectively 'skip' it,\n// treating it as a literal.\n// An example would be '1px solid #000' - which evaluates to itself,\n// we don't need to know what the individual components are.\n// The drawback, of course is that you don't get the benefits of\n// syntax-checking on the CSS. This gives us a 50% speed-up in the parser,\n// and a smaller speed-up in the code-gen.\n//\n//\n// Token matching is done with the `$` function, which either takes\n// a terminal string or regexp, or a non-terminal function to call.\n// It also takes care of moving all the indices forwards.\n//\n\nconst Parser = function Parser(context, imports, fileInfo) {\n let parsers;\n const parserInput = getParserInput();\n\n function error(msg, type) {\n throw new LessError(\n {\n index: parserInput.i,\n filename: fileInfo.filename,\n type: type || 'Syntax',\n message: msg\n },\n imports\n );\n }\n\n function expect(arg, msg) {\n // some older browsers return typeof 'function' for RegExp\n const result = (arg instanceof Function) ? arg.call(parsers) : parserInput.$re(arg);\n if (result) {\n return result;\n }\n \n error(msg || (typeof arg === 'string'\n ? `expected '${arg}' got '${parserInput.currentChar()}'`\n : 'unexpected token'));\n }\n\n // Specialization of expect()\n function expectChar(arg, msg) {\n if (parserInput.$char(arg)) {\n return arg;\n }\n error(msg || `expected '${arg}' got '${parserInput.currentChar()}'`);\n }\n\n function getDebugInfo(index) {\n const filename = fileInfo.filename;\n\n return {\n lineNumber: utils.getLocation(index, parserInput.getInput()).line + 1,\n fileName: filename\n };\n }\n\n /**\n * Used after initial parsing to create nodes on the fly\n * \n * @param {String} str - string to parse \n * @param {Array} parseList - array of parsers to run input through e.g. [\"value\", \"important\"]\n * @param {Number} currentIndex - start number to begin indexing\n * @param {Object} fileInfo - fileInfo to attach to created nodes\n */\n function parseNode(str, parseList, currentIndex, fileInfo, callback) {\n let result;\n const returnNodes = [];\n const parser = parserInput;\n\n try {\n parser.start(str, false, function fail(msg, index) {\n callback({\n message: msg,\n index: index + currentIndex\n });\n });\n for (let x = 0, p, i; (p = parseList[x]); x++) {\n i = parser.i;\n result = parsers[p]();\n if (result) {\n try {\n result._index = i + currentIndex;\n result._fileInfo = fileInfo;\n } catch (e) {}\n returnNodes.push(result);\n }\n else {\n returnNodes.push(null);\n }\n }\n\n const endInfo = parser.end();\n if (endInfo.isFinished) {\n callback(null, returnNodes);\n }\n else {\n callback(true, null);\n }\n } catch (e) {\n throw new LessError({\n index: e.index + currentIndex,\n message: e.message\n }, imports, fileInfo.filename);\n }\n }\n\n //\n // The Parser\n //\n return {\n parserInput,\n imports,\n fileInfo,\n parseNode,\n //\n // Parse an input string into an abstract syntax tree,\n // @param str A string containing 'less' markup\n // @param callback call `callback` when done.\n // @param [additionalData] An optional map which can contains vars - a map (key, value) of variables to apply\n //\n parse: function (str, callback, additionalData) {\n let root;\n let error = null;\n let globalVars;\n let modifyVars;\n let ignored;\n let preText = '';\n\n globalVars = (additionalData && additionalData.globalVars) ? `${Parser.serializeVars(additionalData.globalVars)}\\n` : '';\n modifyVars = (additionalData && additionalData.modifyVars) ? `\\n${Parser.serializeVars(additionalData.modifyVars)}` : '';\n\n if (context.pluginManager) {\n const preProcessors = context.pluginManager.getPreProcessors();\n for (let i = 0; i < preProcessors.length; i++) {\n str = preProcessors[i].process(str, { context, imports, fileInfo });\n }\n }\n\n if (globalVars || (additionalData && additionalData.banner)) {\n preText = ((additionalData && additionalData.banner) ? additionalData.banner : '') + globalVars;\n ignored = imports.contentsIgnoredChars;\n ignored[fileInfo.filename] = ignored[fileInfo.filename] || 0;\n ignored[fileInfo.filename] += preText.length;\n }\n\n str = str.replace(/\\r\\n?/g, '\\n');\n // Remove potential UTF Byte Order Mark\n str = preText + str.replace(/^\\uFEFF/, '') + modifyVars;\n imports.contents[fileInfo.filename] = str;\n\n // Start with the primary rule.\n // The whole syntax tree is held under a Ruleset node,\n // with the `root` property set to true, so no `{}` are\n // output. The callback is called when the input is parsed.\n try {\n parserInput.start(str, context.chunkInput, function fail(msg, index) {\n throw new LessError({\n index,\n type: 'Parse',\n message: msg,\n filename: fileInfo.filename\n }, imports);\n });\n\n tree.Node.prototype.parse = this;\n root = new tree.Ruleset(null, this.parsers.primary());\n tree.Node.prototype.rootNode = root;\n root.root = true;\n root.firstRoot = true;\n root.functionRegistry = functionRegistry.inherit();\n \n } catch (e) {\n return callback(new LessError(e, imports, fileInfo.filename));\n }\n\n // If `i` is smaller than the `input.length - 1`,\n // it means the parser wasn't able to parse the whole\n // string, so we've got a parsing error.\n //\n // We try to extract a \\n delimited string,\n // showing the line where the parse error occurred.\n // We split it up into two parts (the part which parsed,\n // and the part which didn't), so we can color them differently.\n const endInfo = parserInput.end();\n if (!endInfo.isFinished) {\n\n let message = endInfo.furthestPossibleErrorMessage;\n\n if (!message) {\n message = 'Unrecognised input';\n if (endInfo.furthestChar === '}') {\n message += '. Possibly missing opening \\'{\\'';\n } else if (endInfo.furthestChar === ')') {\n message += '. Possibly missing opening \\'(\\'';\n } else if (endInfo.furthestReachedEnd) {\n message += '. Possibly missing something';\n }\n }\n\n error = new LessError({\n type: 'Parse',\n message,\n index: endInfo.furthest,\n filename: fileInfo.filename\n }, imports);\n }\n\n const finish = e => {\n e = error || e || imports.error;\n\n if (e) {\n if (!(e instanceof LessError)) {\n e = new LessError(e, imports, fileInfo.filename);\n }\n\n return callback(e);\n }\n else {\n return callback(null, root);\n }\n };\n\n if (context.processImports !== false) {\n new visitors.ImportVisitor(imports, finish)\n .run(root);\n } else {\n return finish();\n }\n },\n\n //\n // Here in, the parsing rules/functions\n //\n // The basic structure of the syntax tree generated is as follows:\n //\n // Ruleset -> Declaration -> Value -> Expression -> Entity\n //\n // Here's some Less code:\n //\n // .class {\n // color: #fff;\n // border: 1px solid #000;\n // width: @w + 4px;\n // > .child {...}\n // }\n //\n // And here's what the parse tree might look like:\n //\n // Ruleset (Selector '.class', [\n // Declaration (\"color\", Value ([Expression [Color #fff]]))\n // Declaration (\"border\", Value ([Expression [Dimension 1px][Keyword \"solid\"][Color #000]]))\n // Declaration (\"width\", Value ([Expression [Operation \" + \" [Variable \"@w\"][Dimension 4px]]]))\n // Ruleset (Selector [Element '>', '.child'], [...])\n // ])\n //\n // In general, most rules will try to parse a token with the `$re()` function, and if the return\n // value is truly, will return a new node, of the relevant type. Sometimes, we need to check\n // first, before parsing, that's when we use `peek()`.\n //\n parsers: parsers = {\n //\n // The `primary` rule is the *entry* and *exit* point of the parser.\n // The rules here can appear at any level of the parse tree.\n //\n // The recursive nature of the grammar is an interplay between the `block`\n // rule, which represents `{ ... }`, the `ruleset` rule, and this `primary` rule,\n // as represented by this simplified grammar:\n //\n // primary → (ruleset | declaration)+\n // ruleset → selector+ block\n // block → '{' primary '}'\n //\n // Only at one point is the primary rule not called from the\n // block rule: at the root level.\n //\n primary: function () {\n const mixin = this.mixin;\n let root = [];\n let node;\n\n while (true) {\n while (true) {\n node = this.comment();\n if (!node) { break; }\n root.push(node);\n }\n // always process comments before deciding if finished\n if (parserInput.finished) {\n break;\n }\n if (parserInput.peek('}')) {\n break;\n }\n\n node = this.extendRule();\n if (node) {\n root = root.concat(node);\n continue;\n }\n\n node = mixin.definition() || this.declaration() || mixin.call(false, false) || \n this.ruleset() || this.variableCall() || this.entities.call() || this.atrule();\n if (node) {\n root.push(node);\n } else {\n let foundSemiColon = false;\n while (parserInput.$char(';')) {\n foundSemiColon = true;\n }\n if (!foundSemiColon) {\n break;\n }\n }\n }\n\n return root;\n },\n\n // comments are collected by the main parsing mechanism and then assigned to nodes\n // where the current structure allows it\n comment: function () {\n if (parserInput.commentStore.length) {\n const comment = parserInput.commentStore.shift();\n return new(tree.Comment)(comment.text, comment.isLineComment, comment.index, fileInfo);\n }\n },\n\n //\n // Entities are tokens which can be found inside an Expression\n //\n entities: {\n mixinLookup: function() {\n return parsers.mixin.call(true, true);\n },\n //\n // A string, which supports escaping \" and '\n //\n // \"milky way\" 'he\\'s the one!'\n //\n quoted: function (forceEscaped) {\n let str;\n const index = parserInput.i;\n let isEscaped = false;\n\n parserInput.save();\n if (parserInput.$char('~')) {\n isEscaped = true;\n } else if (forceEscaped) {\n parserInput.restore();\n return;\n }\n\n str = parserInput.$quoted();\n if (!str) {\n parserInput.restore();\n return;\n }\n parserInput.forget();\n\n return new(tree.Quoted)(str.charAt(0), str.substr(1, str.length - 2), isEscaped, index, fileInfo);\n },\n\n //\n // A catch-all word, such as:\n //\n // black border-collapse\n //\n keyword: function () {\n const k = parserInput.$char('%') || parserInput.$re(/^\\[?(?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+\\]?/);\n if (k) {\n return tree.Color.fromKeyword(k) || new(tree.Keyword)(k);\n }\n },\n\n //\n // A function call\n //\n // rgb(255, 0, 255)\n //\n // The arguments are parsed with the `entities.arguments` parser.\n //\n call: function () {\n let name;\n let args;\n let func;\n const index = parserInput.i;\n\n // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n if (parserInput.peek(/^url\\(/i)) {\n return;\n }\n\n parserInput.save();\n\n name = parserInput.$re(/^([\\w-]+|%|progid:[\\w\\.]+)\\(/);\n if (!name) {\n parserInput.forget(); \n return;\n }\n\n name = name[1];\n func = this.customFuncCall(name);\n if (func) {\n args = func.parse();\n if (args && func.stop) {\n parserInput.forget();\n return args;\n }\n }\n\n args = this.arguments(args);\n\n if (!parserInput.$char(')')) {\n parserInput.restore('Could not parse call arguments or missing \\')\\'');\n return;\n }\n\n parserInput.forget();\n\n return new(tree.Call)(name, args, index, fileInfo);\n },\n \n //\n // Parsing rules for functions with non-standard args, e.g.:\n //\n // boolean(not(2 > 1))\n //\n // This is a quick prototype, to be modified/improved when\n // more custom-parsed funcs come (e.g. `selector(...)`)\n //\n\n customFuncCall: function (name) {\n /* Ideally the table is to be moved out of here for faster perf.,\n but it's quite tricky since it relies on all these `parsers`\n and `expect` available only here */\n return {\n alpha: f(parsers.ieAlpha, true),\n boolean: f(condition),\n 'if': f(condition)\n }[name.toLowerCase()];\n\n function f(parse, stop) {\n return {\n parse, // parsing function\n stop // when true - stop after parse() and return its result, \n // otherwise continue for plain args\n };\n }\n \n function condition() {\n return [expect(parsers.condition, 'expected condition')];\n }\n },\n\n arguments: function (prevArgs) {\n let argsComma = prevArgs || [];\n const argsSemiColon = [];\n let isSemiColonSeparated;\n let value;\n\n parserInput.save();\n\n while (true) {\n if (prevArgs) {\n prevArgs = false;\n } else {\n value = parsers.detachedRuleset() || this.assignment() || parsers.expression();\n if (!value) {\n break;\n }\n\n if (value.value && value.value.length == 1) {\n value = value.value[0];\n }\n\n argsComma.push(value);\n }\n\n if (parserInput.$char(',')) {\n continue;\n }\n\n if (parserInput.$char(';') || isSemiColonSeparated) {\n isSemiColonSeparated = true;\n value = (argsComma.length < 1) ? argsComma[0]\n : new tree.Value(argsComma);\n argsSemiColon.push(value);\n argsComma = [];\n }\n }\n\n parserInput.forget();\n return isSemiColonSeparated ? argsSemiColon : argsComma;\n },\n literal: function () {\n return this.dimension() ||\n this.color() ||\n this.quoted() ||\n this.unicodeDescriptor();\n },\n\n // Assignments are argument entities for calls.\n // They are present in ie filter properties as shown below.\n //\n // filter: progid:DXImageTransform.Microsoft.Alpha( *opacity=50* )\n //\n\n assignment: function () {\n let key;\n let value;\n parserInput.save();\n key = parserInput.$re(/^\\w+(?=\\s?=)/i);\n if (!key) {\n parserInput.restore();\n return;\n }\n if (!parserInput.$char('=')) {\n parserInput.restore();\n return;\n }\n value = parsers.entity();\n if (value) {\n parserInput.forget();\n return new(tree.Assignment)(key, value);\n } else {\n parserInput.restore();\n }\n },\n\n //\n // Parse url() tokens\n //\n // We use a specific rule for urls, because they don't really behave like\n // standard function calls. The difference is that the argument doesn't have\n // to be enclosed within a string, so it can't be parsed as an Expression.\n //\n url: function () {\n let value;\n const index = parserInput.i;\n\n parserInput.autoCommentAbsorb = false;\n\n if (!parserInput.$str('url(')) {\n parserInput.autoCommentAbsorb = true;\n return;\n }\n\n value = this.quoted() || this.variable() || this.property() ||\n parserInput.$re(/^(?:(?:\\\\[\\(\\)'\"])|[^\\(\\)'\"])+/) || '';\n\n parserInput.autoCommentAbsorb = true;\n\n expectChar(')');\n\n return new(tree.URL)((value.value != null || \n value instanceof tree.Variable || \n value instanceof tree.Property) ?\n value : new(tree.Anonymous)(value, index), index, fileInfo);\n },\n\n //\n // A Variable entity, such as `@fink`, in\n //\n // width: @fink + 2px\n //\n // We use a different parser for variable definitions,\n // see `parsers.variable`.\n //\n variable: function () {\n let ch;\n let name;\n const index = parserInput.i;\n\n parserInput.save();\n if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^@@?[\\w-]+/))) {\n ch = parserInput.currentChar();\n if (ch === '(' || ch === '[' && !parserInput.prevChar().match(/^\\s/)) {\n // this may be a VariableCall lookup\n const result = parsers.variableCall(name);\n if (result) {\n parserInput.forget();\n return result;\n }\n }\n parserInput.forget();\n return new(tree.Variable)(name, index, fileInfo);\n }\n parserInput.restore();\n },\n\n // A variable entity using the protective {} e.g. @{var}\n variableCurly: function () {\n let curly;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '@' && (curly = parserInput.$re(/^@\\{([\\w-]+)\\}/))) {\n return new(tree.Variable)(`@${curly[1]}`, index, fileInfo);\n }\n },\n //\n // A Property accessor, such as `$color`, in\n //\n // background-color: $color\n //\n property: function () {\n let name;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '$' && (name = parserInput.$re(/^\\$[\\w-]+/))) {\n return new(tree.Property)(name, index, fileInfo);\n }\n },\n\n // A property entity useing the protective {} e.g. ${prop}\n propertyCurly: function () {\n let curly;\n const index = parserInput.i;\n\n if (parserInput.currentChar() === '$' && (curly = parserInput.$re(/^\\$\\{([\\w-]+)\\}/))) {\n return new(tree.Property)(`$${curly[1]}`, index, fileInfo);\n }\n },\n //\n // A Hexadecimal color\n //\n // #4F3C2F\n //\n // `rgb` and `hsl` colors are parsed through the `entities.call` parser.\n //\n color: function () {\n let rgb;\n parserInput.save();\n\n if (parserInput.currentChar() === '#' && (rgb = parserInput.$re(/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})([\\w.#\\[])?/))) {\n if (!rgb[2]) {\n parserInput.forget();\n return new(tree.Color)(rgb[1], undefined, rgb[0]);\n } \n }\n parserInput.restore();\n },\n\n colorKeyword: function () {\n parserInput.save();\n const autoCommentAbsorb = parserInput.autoCommentAbsorb;\n parserInput.autoCommentAbsorb = false;\n const k = parserInput.$re(/^[_A-Za-z-][_A-Za-z0-9-]+/);\n parserInput.autoCommentAbsorb = autoCommentAbsorb;\n if (!k) {\n parserInput.forget();\n return;\n }\n parserInput.restore();\n const color = tree.Color.fromKeyword(k);\n if (color) {\n parserInput.$str(k);\n return color;\n }\n },\n\n //\n // A Dimension, that is, a number and a unit\n //\n // 0.5em 95%\n //\n dimension: function () {\n if (parserInput.peekNotNumeric()) {\n return;\n }\n\n const value = parserInput.$re(/^([+-]?\\d*\\.?\\d+)(%|[a-z_]+)?/i);\n if (value) {\n return new(tree.Dimension)(value[1], value[2]);\n }\n },\n\n //\n // A unicode descriptor, as is used in unicode-range\n //\n // U+0?? or U+00A1-00A9\n //\n unicodeDescriptor: function () {\n let ud;\n\n ud = parserInput.$re(/^U\\+[0-9a-fA-F?]+(\\-[0-9a-fA-F?]+)?/);\n if (ud) {\n return new(tree.UnicodeDescriptor)(ud[0]);\n }\n },\n\n //\n // JavaScript code to be evaluated\n //\n // `window.location.href`\n //\n javascript: function () {\n let js;\n const index = parserInput.i;\n\n parserInput.save();\n\n const escape = parserInput.$char('~');\n const jsQuote = parserInput.$char('`');\n\n if (!jsQuote) {\n parserInput.restore();\n return;\n }\n\n js = parserInput.$re(/^[^`]*`/);\n if (js) {\n parserInput.forget();\n return new(tree.JavaScript)(js.substr(0, js.length - 1), Boolean(escape), index, fileInfo);\n }\n parserInput.restore('invalid javascript definition');\n }\n },\n\n //\n // The variable part of a variable definition. Used in the `rule` parser\n //\n // @fink:\n //\n variable: function () {\n let name;\n\n if (parserInput.currentChar() === '@' && (name = parserInput.$re(/^(@[\\w-]+)\\s*:/))) { return name[1]; }\n },\n\n //\n // Call a variable value to retrieve a detached ruleset\n // or a value from a detached ruleset's rules.\n //\n // @fink();\n // @fink;\n // color: @fink[@color];\n //\n variableCall: function (parsedName) {\n let lookups;\n const i = parserInput.i;\n const inValue = !!parsedName;\n let name = parsedName;\n\n parserInput.save();\n\n if (name || (parserInput.currentChar() === '@'\n && (name = parserInput.$re(/^(@[\\w-]+)(\\(\\s*\\))?/)))) {\n\n lookups = this.mixin.ruleLookups();\n\n if (!lookups && ((inValue && parserInput.$str('()') !== '()') || (name[2] !== '()'))) {\n parserInput.restore('Missing \\'[...]\\' lookup in variable call');\n return;\n }\n\n if (!inValue) {\n name = name[1];\n }\n\n const call = new tree.VariableCall(name, i, fileInfo);\n if (!inValue && parsers.end()) {\n parserInput.forget();\n return call;\n }\n else {\n parserInput.forget();\n return new tree.NamespaceValue(call, lookups, i, fileInfo);\n }\n }\n\n parserInput.restore();\n },\n\n //\n // extend syntax - used to extend selectors\n //\n extend: function(isRule) {\n let elements;\n let e;\n const index = parserInput.i;\n let option;\n let extendList;\n let extend;\n\n if (!parserInput.$str(isRule ? '&:extend(' : ':extend(')) {\n return;\n }\n\n do {\n option = null;\n elements = null;\n while (!(option = parserInput.$re(/^(all)(?=\\s*(\\)|,))/))) {\n e = this.element();\n if (!e) {\n break;\n }\n if (elements) {\n elements.push(e);\n } else {\n elements = [ e ];\n }\n }\n\n option = option && option[1];\n if (!elements) {\n error('Missing target selector for :extend().');\n }\n extend = new(tree.Extend)(new(tree.Selector)(elements), option, index, fileInfo);\n if (extendList) {\n extendList.push(extend);\n } else {\n extendList = [ extend ];\n }\n } while (parserInput.$char(','));\n\n expect(/^\\)/);\n\n if (isRule) {\n expect(/^;/);\n }\n\n return extendList;\n },\n\n //\n // extendRule - used in a rule to extend all the parent selectors\n //\n extendRule: function() {\n return this.extend(true);\n },\n\n //\n // Mixins\n //\n mixin: {\n //\n // A Mixin call, with an optional argument list\n //\n // #mixins > .square(#fff);\n // #mixins.square(#fff);\n // .rounded(4px, black);\n // .button;\n //\n // We can lookup / return a value using the lookup syntax:\n //\n // color: #mixin.square(#fff)[@color];\n //\n // The `while` loop is there because mixins can be\n // namespaced, but we only support the child and descendant\n // selector for now.\n //\n call: function (inValue, getLookup) {\n const s = parserInput.currentChar();\n let important = false;\n let lookups;\n const index = parserInput.i;\n let elements;\n let args;\n let hasParens;\n\n if (s !== '.' && s !== '#') { return; }\n\n parserInput.save(); // stop us absorbing part of an invalid selector\n\n elements = this.elements();\n\n if (elements) {\n if (parserInput.$char('(')) {\n args = this.args(true).args;\n expectChar(')');\n hasParens = true;\n }\n\n if (getLookup !== false) {\n lookups = this.ruleLookups();\n }\n if (getLookup === true && !lookups) {\n parserInput.restore();\n return;\n }\n\n if (inValue && !lookups && !hasParens) {\n // This isn't a valid in-value mixin call\n parserInput.restore();\n return;\n }\n\n if (!inValue && parsers.important()) {\n important = true;\n }\n\n if (inValue || parsers.end()) {\n parserInput.forget();\n const mixin = new(tree.mixin.Call)(elements, args, index, fileInfo, !lookups && important);\n if (lookups) {\n return new tree.NamespaceValue(mixin, lookups);\n }\n else {\n return mixin;\n }\n }\n }\n\n parserInput.restore();\n },\n /**\n * Matching elements for mixins\n * (Start with . or # and can have > )\n */\n elements: function() {\n let elements;\n let e;\n let c;\n let elem;\n let elemIndex;\n const re = /^[#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/;\n while (true) {\n elemIndex = parserInput.i;\n e = parserInput.$re(re);\n \n if (!e) {\n break;\n }\n elem = new(tree.Element)(c, e, false, elemIndex, fileInfo);\n if (elements) {\n elements.push(elem);\n } else {\n elements = [ elem ];\n }\n c = parserInput.$char('>');\n }\n return elements;\n },\n args: function (isCall) {\n const entities = parsers.entities;\n const returner = { args:null, variadic: false };\n let expressions = [];\n const argsSemiColon = [];\n const argsComma = [];\n let isSemiColonSeparated;\n let expressionContainsNamed;\n let name;\n let nameLoop;\n let value;\n let arg;\n let expand;\n let hasSep = true;\n\n parserInput.save();\n\n while (true) {\n if (isCall) {\n arg = parsers.detachedRuleset() || parsers.expression();\n } else {\n parserInput.commentStore.length = 0;\n if (parserInput.$str('...')) {\n returner.variadic = true;\n if (parserInput.$char(';') && !isSemiColonSeparated) {\n isSemiColonSeparated = true;\n }\n (isSemiColonSeparated ? argsSemiColon : argsComma)\n .push({ variadic: true });\n break;\n }\n arg = entities.variable() || entities.property() || entities.literal() || entities.keyword() || this.call(true);\n }\n\n if (!arg || !hasSep) {\n break;\n }\n\n nameLoop = null;\n if (arg.throwAwayComments) {\n arg.throwAwayComments();\n }\n value = arg;\n let val = null;\n\n if (isCall) {\n // Variable\n if (arg.value && arg.value.length == 1) {\n val = arg.value[0];\n }\n } else {\n val = arg;\n }\n\n if (val && (val instanceof tree.Variable || val instanceof tree.Property)) {\n if (parserInput.$char(':')) {\n if (expressions.length > 0) {\n if (isSemiColonSeparated) {\n error('Cannot mix ; and , as delimiter types');\n }\n expressionContainsNamed = true;\n }\n\n value = parsers.detachedRuleset() || parsers.expression();\n\n if (!value) {\n if (isCall) {\n error('could not understand value for named argument');\n } else {\n parserInput.restore();\n returner.args = [];\n return returner;\n }\n }\n nameLoop = (name = val.name);\n } else if (parserInput.$str('...')) {\n if (!isCall) {\n returner.variadic = true;\n if (parserInput.$char(';') && !isSemiColonSeparated) {\n isSemiColonSeparated = true;\n }\n (isSemiColonSeparated ? argsSemiColon : argsComma)\n .push({ name: arg.name, variadic: true });\n break;\n } else {\n expand = true;\n }\n } else if (!isCall) {\n name = nameLoop = val.name;\n value = null;\n }\n }\n\n if (value) {\n expressions.push(value);\n }\n\n argsComma.push({ name:nameLoop, value, expand });\n\n if (parserInput.$char(',')) {\n hasSep = true;\n continue;\n }\n hasSep = parserInput.$char(';') === ';';\n\n if (hasSep || isSemiColonSeparated) {\n\n if (expressionContainsNamed) {\n error('Cannot mix ; and , as delimiter types');\n }\n\n isSemiColonSeparated = true;\n\n if (expressions.length > 1) {\n value = new(tree.Value)(expressions);\n }\n argsSemiColon.push({ name, value, expand });\n\n name = null;\n expressions = [];\n expressionContainsNamed = false;\n }\n }\n\n parserInput.forget();\n returner.args = isSemiColonSeparated ? argsSemiColon : argsComma;\n return returner;\n },\n //\n // A Mixin definition, with a list of parameters\n //\n // .rounded (@radius: 2px, @color) {\n // ...\n // }\n //\n // Until we have a finer grained state-machine, we have to\n // do a look-ahead, to make sure we don't have a mixin call.\n // See the `rule` function for more information.\n //\n // We start by matching `.rounded (`, and then proceed on to\n // the argument list, which has optional default values.\n // We store the parameters in `params`, with a `value` key,\n // if there is a value, such as in the case of `@radius`.\n //\n // Once we've got our params list, and a closing `)`, we parse\n // the `{...}` block.\n //\n definition: function () {\n let name;\n let params = [];\n let match;\n let ruleset;\n let cond;\n let variadic = false;\n if ((parserInput.currentChar() !== '.' && parserInput.currentChar() !== '#') ||\n parserInput.peek(/^[^{]*\\}/)) {\n return;\n }\n\n parserInput.save();\n\n match = parserInput.$re(/^([#.](?:[\\w-]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+)\\s*\\(/);\n if (match) {\n name = match[1];\n\n const argInfo = this.args(false);\n params = argInfo.args;\n variadic = argInfo.variadic;\n\n // .mixincall(\"@{a}\");\n // looks a bit like a mixin definition..\n // also\n // .mixincall(@a: {rule: set;});\n // so we have to be nice and restore\n if (!parserInput.$char(')')) {\n parserInput.restore('Missing closing \\')\\'');\n return;\n }\n\n parserInput.commentStore.length = 0;\n\n if (parserInput.$str('when')) { // Guard\n cond = expect(parsers.conditions, 'expected condition');\n }\n\n ruleset = parsers.block();\n\n if (ruleset) {\n parserInput.forget();\n return new(tree.mixin.Definition)(name, params, ruleset, cond, variadic);\n } else {\n parserInput.restore();\n }\n } else {\n parserInput.restore();\n }\n },\n \n ruleLookups: function() {\n let rule;\n let args;\n const lookups = [];\n\n if (parserInput.currentChar() !== '[') { \n return;\n }\n\n while (true) {\n parserInput.save();\n args = null;\n rule = this.lookupValue();\n if (!rule && rule !== '') {\n parserInput.restore();\n break;\n }\n lookups.push(rule);\n parserInput.forget();\n }\n if (lookups.length > 0) {\n return lookups;\n }\n },\n \n lookupValue: function() {\n parserInput.save();\n \n if (!parserInput.$char('[')) { \n parserInput.restore();\n return;\n }\n \n const name = parserInput.$re(/^(?:[@$]{0,2})[_a-zA-Z0-9-]*/);\n \n if (!parserInput.$char(']')) {\n parserInput.restore();\n return;\n } \n\n if (name || name === '') {\n parserInput.forget();\n return name;\n }\n \n parserInput.restore();\n }\n },\n //\n // Entities are the smallest recognized token,\n // and can be found inside a rule's value.\n //\n entity: function () {\n const entities = this.entities;\n\n return this.comment() || entities.literal() || entities.variable() || entities.url() ||\n entities.property() || entities.call() || entities.keyword() || this.mixin.call(true) ||\n entities.javascript();\n },\n\n //\n // A Declaration terminator. Note that we use `peek()` to check for '}',\n // because the `block` rule will be expecting it, but we still need to make sure\n // it's there, if ';' was omitted.\n //\n end: function () {\n return parserInput.$char(';') || parserInput.peek('}');\n },\n\n //\n // IE's alpha function\n //\n // alpha(opacity=88)\n //\n ieAlpha: function () {\n let value;\n\n // http://jsperf.com/case-insensitive-regex-vs-strtolower-then-regex/18\n if (!parserInput.$re(/^opacity=/i)) { return; }\n value = parserInput.$re(/^\\d+/);\n if (!value) {\n value = expect(parsers.entities.variable, 'Could not parse alpha');\n value = `@{${value.name.slice(1)}}`;\n }\n expectChar(')');\n return new tree.Quoted('', `alpha(opacity=${value})`);\n },\n\n //\n // A Selector Element\n //\n // div\n // + h1\n // #socks\n // input[type=\"text\"]\n //\n // Elements are the building blocks for Selectors,\n // they are made out of a `Combinator` (see combinator rule),\n // and an element name, such as a tag a class, or `*`.\n //\n element: function () {\n let e;\n let c;\n let v;\n const index = parserInput.i;\n\n c = this.combinator();\n\n e = parserInput.$re(/^(?:\\d+\\.\\d+|\\d+)%/) ||\n parserInput.$re(/^(?:[.#]?|:*)(?:[\\w-]|[^\\x00-\\x9f]|\\\\(?:[A-Fa-f0-9]{1,6} ?|[^A-Fa-f0-9]))+/) ||\n parserInput.$char('*') || parserInput.$char('&') || this.attribute() ||\n parserInput.$re(/^\\([^&()@]+\\)/) || parserInput.$re(/^[\\.#:](?=@)/) ||\n this.entities.variableCurly();\n\n if (!e) {\n parserInput.save();\n if (parserInput.$char('(')) {\n if ((v = this.selector(false)) && parserInput.$char(')')) {\n e = new(tree.Paren)(v);\n parserInput.forget();\n } else {\n parserInput.restore('Missing closing \\')\\'');\n }\n } else {\n parserInput.forget();\n }\n }\n\n if (e) { return new(tree.Element)(c, e, e instanceof tree.Variable, index, fileInfo); }\n },\n\n //\n // Combinators combine elements together, in a Selector.\n //\n // Because our parser isn't white-space sensitive, special care\n // has to be taken, when parsing the descendant combinator, ` `,\n // as it's an empty space. We have to check the previous character\n // in the input, to see if it's a ` ` character. More info on how\n // we deal with this in *combinator.js*.\n //\n combinator: function () {\n let c = parserInput.currentChar();\n\n if (c === '/') {\n parserInput.save();\n const slashedCombinator = parserInput.$re(/^\\/[a-z]+\\//i);\n if (slashedCombinator) {\n parserInput.forget();\n return new(tree.Combinator)(slashedCombinator);\n }\n parserInput.restore();\n }\n\n if (c === '>' || c === '+' || c === '~' || c === '|' || c === '^') {\n parserInput.i++;\n if (c === '^' && parserInput.currentChar() === '^') {\n c = '^^';\n parserInput.i++;\n }\n while (parserInput.isWhitespace()) { parserInput.i++; }\n return new(tree.Combinator)(c);\n } else if (parserInput.isWhitespace(-1)) {\n return new(tree.Combinator)(' ');\n } else {\n return new(tree.Combinator)(null);\n }\n },\n //\n // A CSS Selector\n // with less extensions e.g. the ability to extend and guard\n //\n // .class > div + h1\n // li a:hover\n //\n // Selectors are made out of one or more Elements, see above.\n //\n selector: function (isLess) {\n const index = parserInput.i;\n let elements;\n let extendList;\n let c;\n let e;\n let allExtends;\n let when;\n let condition;\n isLess = isLess !== false;\n while ((isLess && (extendList = this.extend())) || (isLess && (when = parserInput.$str('when'))) || (e = this.element())) {\n if (when) {\n condition = expect(this.conditions, 'expected condition');\n } else if (condition) {\n error('CSS guard can only be used at the end of selector');\n } else if (extendList) {\n if (allExtends) {\n allExtends = allExtends.concat(extendList);\n } else {\n allExtends = extendList;\n }\n } else {\n if (allExtends) { error('Extend can only be used at the end of selector'); }\n c = parserInput.currentChar();\n if (elements) {\n elements.push(e);\n } else {\n elements = [ e ];\n }\n e = null;\n }\n if (c === '{' || c === '}' || c === ';' || c === ',' || c === ')') {\n break;\n }\n }\n\n if (elements) { return new(tree.Selector)(elements, allExtends, condition, index, fileInfo); }\n if (allExtends) { error('Extend must be used to extend a selector, it cannot be used on its own'); }\n },\n selectors: function () {\n let s;\n let selectors;\n while (true) {\n s = this.selector();\n if (!s) {\n break;\n }\n if (selectors) {\n selectors.push(s);\n } else {\n selectors = [ s ];\n }\n parserInput.commentStore.length = 0;\n if (s.condition && selectors.length > 1) {\n error(\"Guards are only currently allowed on a single selector.\");\n }\n if (!parserInput.$char(',')) { break; }\n if (s.condition) {\n error(\"Guards are only currently allowed on a single selector.\");\n }\n parserInput.commentStore.length = 0;\n }\n return selectors;\n },\n attribute: function () {\n if (!parserInput.$char('[')) { return; }\n\n const entities = this.entities;\n let key;\n let val;\n let op;\n\n if (!(key = entities.variableCurly())) {\n key = expect(/^(?:[_A-Za-z0-9-\\*]*\\|)?(?:[_A-Za-z0-9-]|\\\\.)+/);\n }\n\n op = parserInput.$re(/^[|~*$^]?=/);\n if (op) {\n val = entities.quoted() || parserInput.$re(/^[0-9]+%/) || parserInput.$re(/^[\\w-]+/) || entities.variableCurly();\n }\n\n expectChar(']');\n\n return new(tree.Attribute)(key, op, val);\n },\n\n //\n // The `block` rule is used by `ruleset` and `mixin.definition`.\n // It's a wrapper around the `primary` rule, with added `{}`.\n //\n block: function () {\n let content;\n if (parserInput.$char('{') && (content = this.primary()) && parserInput.$char('}')) {\n return content;\n }\n },\n\n blockRuleset: function() {\n let block = this.block();\n\n if (block) {\n block = new tree.Ruleset(null, block);\n }\n return block;\n },\n\n detachedRuleset: function() {\n let argInfo;\n let params;\n let variadic;\n\n parserInput.save();\n if (parserInput.$re(/^[.#]\\(/)) {\n /**\n * DR args currently only implemented for each() function, and not \n * yet settable as `@dr: #(@arg) {}`\n * This should be done when DRs are merged with mixins.\n * See: https://github.com/less/less-meta/issues/16\n */\n argInfo = this.mixin.args(false);\n params = argInfo.args;\n variadic = argInfo.variadic;\n if (!parserInput.$char(')')) {\n parserInput.restore();\n return;\n }\n }\n const blockRuleset = this.blockRuleset();\n if (blockRuleset) {\n parserInput.forget();\n if (params) {\n return new tree.mixin.Definition(null, params, blockRuleset, null, variadic);\n }\n return new tree.DetachedRuleset(blockRuleset);\n }\n parserInput.restore();\n },\n\n //\n // div, .class, body > p {...}\n //\n ruleset: function () {\n let selectors;\n let rules;\n let debugInfo;\n\n parserInput.save();\n\n if (context.dumpLineNumbers) {\n debugInfo = getDebugInfo(parserInput.i);\n }\n\n selectors = this.selectors();\n\n if (selectors && (rules = this.block())) {\n parserInput.forget();\n const ruleset = new(tree.Ruleset)(selectors, rules, context.strictImports);\n if (context.dumpLineNumbers) {\n ruleset.debugInfo = debugInfo;\n }\n return ruleset;\n } else {\n parserInput.restore();\n }\n },\n declaration: function () {\n let name;\n let value;\n const index = parserInput.i;\n let hasDR;\n const c = parserInput.currentChar();\n let important;\n let merge;\n let isVariable;\n\n if (c === '.' || c === '#' || c === '&' || c === ':') { return; }\n\n parserInput.save();\n\n name = this.variable() || this.ruleProperty();\n if (name) {\n isVariable = typeof name === 'string';\n\n if (isVariable) {\n value = this.detachedRuleset();\n if (value) {\n hasDR = true;\n }\n }\n\n parserInput.commentStore.length = 0;\n if (!value) {\n // a name returned by this.ruleProperty() is always an array of the form:\n // [string-1, ..., string-n, \"\"] or [string-1, ..., string-n, \"+\"]\n // where each item is a tree.Keyword or tree.Variable\n merge = !isVariable && name.length > 1 && name.pop().value;\n\n // Custom property values get permissive parsing\n if (name[0].value && name[0].value.slice(0, 2) === '--') {\n value = this.permissiveValue();\n }\n // Try to store values as anonymous\n // If we need the value later we'll re-parse it in ruleset.parseValue\n else {\n value = this.anonymousValue();\n }\n if (value) {\n parserInput.forget();\n // anonymous values absorb the end ';' which is required for them to work\n return new(tree.Declaration)(name, value, false, merge, index, fileInfo);\n }\n\n if (!value) {\n value = this.value();\n }\n\n if (value) {\n important = this.important();\n } else if (isVariable) {\n // As a last resort, try permissiveValue\n value = this.permissiveValue();\n }\n }\n\n if (value && (this.end() || hasDR)) {\n parserInput.forget();\n return new(tree.Declaration)(name, value, important, merge, index, fileInfo);\n }\n else {\n parserInput.restore();\n }\n } else {\n parserInput.restore();\n }\n },\n anonymousValue: function () {\n const index = parserInput.i;\n const match = parserInput.$re(/^([^.#@\\$+\\/'\"*`(;{}-]*);/);\n if (match) {\n return new(tree.Anonymous)(match[1], index);\n }\n },\n /**\n * Used for custom properties, at-rules, and variables (as fallback)\n * Parses almost anything inside of {} [] () \"\" blocks\n * until it reaches outer-most tokens.\n * \n * First, it will try to parse comments and entities to reach\n * the end. This is mostly like the Expression parser except no\n * math is allowed.\n */\n permissiveValue: function (untilTokens) {\n let i;\n let e;\n let done;\n let value;\n const tok = untilTokens || ';';\n const index = parserInput.i;\n const result = [];\n\n function testCurrentChar() {\n const char = parserInput.currentChar();\n if (typeof tok === 'string') {\n return char === tok;\n } else {\n return tok.test(char);\n }\n }\n if (testCurrentChar()) {\n return;\n }\n value = [];\n do {\n e = this.comment();\n if (e) {\n value.push(e);\n continue;\n }\n e = this.entity();\n if (e) {\n value.push(e);\n }\n } while (e);\n\n done = testCurrentChar();\n\n if (value.length > 0) {\n value = new(tree.Expression)(value);\n if (done) {\n return value;\n }\n else {\n result.push(value);\n }\n // Preserve space before $parseUntil as it will not\n if (parserInput.prevChar() === ' ') {\n result.push(new tree.Anonymous(' ', index));\n }\n }\n parserInput.save();\n\n value = parserInput.$parseUntil(tok);\n\n if (value) {\n if (typeof value === 'string') {\n error(`Expected '${value}'`, 'Parse');\n }\n if (value.length === 1 && value[0] === ' ') {\n parserInput.forget();\n return new tree.Anonymous('', index);\n }\n let item;\n for (i = 0; i < value.length; i++) {\n item = value[i];\n if (Array.isArray(item)) {\n // Treat actual quotes as normal quoted values\n result.push(new tree.Quoted(item[0], item[1], true, index, fileInfo));\n }\n else {\n if (i === value.length - 1) {\n item = item.trim();\n }\n // Treat like quoted values, but replace vars like unquoted expressions\n const quote = new tree.Quoted('\\'', item, true, index, fileInfo);\n quote.variableRegex = /@([\\w-]+)/g;\n quote.propRegex = /\\$([\\w-]+)/g;\n result.push(quote);\n }\n }\n parserInput.forget();\n return new tree.Expression(result, true);\n }\n parserInput.restore();\n },\n\n //\n // An @import atrule\n //\n // @import \"lib\";\n //\n // Depending on our environment, importing is done differently:\n // In the browser, it's an XHR request, in Node, it would be a\n // file-system operation. The function used for importing is\n // stored in `import`, which we pass to the Import constructor.\n //\n 'import': function () {\n let path;\n let features;\n const index = parserInput.i;\n\n const dir = parserInput.$re(/^@import?\\s+/);\n\n if (dir) {\n const options = (dir ? this.importOptions() : null) || {};\n\n if ((path = this.entities.quoted() || this.entities.url())) {\n features = this.mediaFeatures();\n\n if (!parserInput.$char(';')) {\n parserInput.i = index;\n error('missing semi-colon or unrecognised media features on import');\n }\n features = features && new(tree.Value)(features);\n return new(tree.Import)(path, features, options, index, fileInfo);\n }\n else {\n parserInput.i = index;\n error('malformed import statement');\n }\n }\n },\n\n importOptions: function() {\n let o;\n const options = {};\n let optionName;\n let value;\n\n // list of options, surrounded by parens\n if (!parserInput.$char('(')) { return null; }\n do {\n o = this.importOption();\n if (o) {\n optionName = o;\n value = true;\n switch (optionName) {\n case 'css':\n optionName = 'less';\n value = false;\n break;\n case 'once':\n optionName = 'multiple';\n value = false;\n break;\n }\n options[optionName] = value;\n if (!parserInput.$char(',')) { break; }\n }\n } while (o);\n expectChar(')');\n return options;\n },\n\n importOption: function() {\n const opt = parserInput.$re(/^(less|css|multiple|once|inline|reference|optional)/);\n if (opt) {\n return opt[1];\n }\n },\n\n mediaFeature: function () {\n const entities = this.entities;\n const nodes = [];\n let e;\n let p;\n parserInput.save();\n do {\n e = entities.keyword() || entities.variable() || entities.mixinLookup();\n if (e) {\n nodes.push(e);\n } else if (parserInput.$char('(')) {\n p = this.property();\n e = this.value();\n if (parserInput.$char(')')) {\n if (p && e) {\n nodes.push(new(tree.Paren)(new(tree.Declaration)(p, e, null, null, parserInput.i, fileInfo, true)));\n } else if (e) {\n nodes.push(new(tree.Paren)(e));\n } else {\n error('badly formed media feature definition');\n }\n } else {\n error('Missing closing \\')\\'', 'Parse');\n }\n }\n } while (e);\n\n parserInput.forget();\n if (nodes.length > 0) {\n return new(tree.Expression)(nodes);\n }\n },\n\n mediaFeatures: function () {\n const entities = this.entities;\n const features = [];\n let e;\n do {\n e = this.mediaFeature();\n if (e) {\n features.push(e);\n if (!parserInput.$char(',')) { break; }\n } else {\n e = entities.variable() || entities.mixinLookup();\n if (e) {\n features.push(e);\n if (!parserInput.$char(',')) { break; }\n }\n }\n } while (e);\n\n return features.length > 0 ? features : null;\n },\n\n media: function () {\n let features;\n let rules;\n let media;\n let debugInfo;\n const index = parserInput.i;\n\n if (context.dumpLineNumbers) {\n debugInfo = getDebugInfo(index);\n }\n\n parserInput.save();\n\n if (parserInput.$str('@media')) {\n features = this.mediaFeatures();\n\n rules = this.block();\n\n if (!rules) {\n error('media definitions require block statements after any features');\n }\n\n parserInput.forget();\n\n media = new(tree.Media)(rules, features, index, fileInfo);\n if (context.dumpLineNumbers) {\n media.debugInfo = debugInfo;\n }\n\n return media;\n }\n\n parserInput.restore();\n },\n\n //\n\n // A @plugin directive, used to import plugins dynamically.\n //\n // @plugin (args) \"lib\";\n //\n plugin: function () {\n let path;\n let args;\n let options;\n const index = parserInput.i;\n const dir = parserInput.$re(/^@plugin?\\s+/);\n\n if (dir) {\n args = this.pluginArgs();\n\n if (args) {\n options = {\n pluginArgs: args,\n isPlugin: true\n };\n }\n else {\n options = { isPlugin: true };\n }\n\n if ((path = this.entities.quoted() || this.entities.url())) {\n\n if (!parserInput.$char(';')) {\n parserInput.i = index;\n error('missing semi-colon on @plugin');\n }\n return new(tree.Import)(path, null, options, index, fileInfo);\n }\n else {\n parserInput.i = index;\n error('malformed @plugin statement');\n }\n }\n },\n\n pluginArgs: function() {\n // list of options, surrounded by parens\n parserInput.save();\n if (!parserInput.$char('(')) {\n parserInput.restore();\n return null;\n }\n const args = parserInput.$re(/^\\s*([^\\);]+)\\)\\s*/);\n if (args[1]) {\n parserInput.forget();\n return args[1].trim();\n }\n else { \n parserInput.restore();\n return null;\n }\n },\n\n //\n // A CSS AtRule\n //\n // @charset \"utf-8\";\n //\n atrule: function () {\n const index = parserInput.i;\n let name;\n let value;\n let rules;\n let nonVendorSpecificName;\n let hasIdentifier;\n let hasExpression;\n let hasUnknown;\n let hasBlock = true;\n let isRooted = true;\n\n if (parserInput.currentChar() !== '@') { return; }\n\n value = this['import']() || this.plugin() || this.media();\n if (value) {\n return value;\n }\n\n parserInput.save();\n\n name = parserInput.$re(/^@[a-z-]+/);\n\n if (!name) { return; }\n\n nonVendorSpecificName = name;\n if (name.charAt(1) == '-' && name.indexOf('-', 2) > 0) {\n nonVendorSpecificName = `@${name.slice(name.indexOf('-', 2) + 1)}`;\n }\n\n switch (nonVendorSpecificName) {\n case '@charset':\n hasIdentifier = true;\n hasBlock = false;\n break;\n case '@namespace':\n hasExpression = true;\n hasBlock = false;\n break;\n case '@keyframes':\n case '@counter-style':\n hasIdentifier = true;\n break;\n case '@document':\n case '@supports':\n hasUnknown = true;\n isRooted = false;\n break;\n default:\n hasUnknown = true;\n break;\n }\n\n parserInput.commentStore.length = 0;\n\n if (hasIdentifier) {\n value = this.entity();\n if (!value) {\n error(`expected ${name} identifier`);\n }\n } else if (hasExpression) {\n value = this.expression();\n if (!value) {\n error(`expected ${name} expression`);\n }\n } else if (hasUnknown) {\n value = this.permissiveValue(/^[{;]/);\n hasBlock = (parserInput.currentChar() === '{');\n if (!value) {\n if (!hasBlock && parserInput.currentChar() !== ';') {\n error(`${name} rule is missing block or ending semi-colon`);\n }\n }\n else if (!value.value) {\n value = null;\n }\n }\n\n if (hasBlock) {\n rules = this.blockRuleset();\n }\n\n if (rules || (!hasBlock && value && parserInput.$char(';'))) {\n parserInput.forget();\n return new(tree.AtRule)(name, value, rules, index, fileInfo,\n context.dumpLineNumbers ? getDebugInfo(index) : null,\n isRooted\n );\n }\n\n parserInput.restore('at-rule options not recognised');\n },\n\n //\n // A Value is a comma-delimited list of Expressions\n //\n // font-family: Baskerville, Georgia, serif;\n //\n // In a Rule, a Value represents everything after the `:`,\n // and before the `;`.\n //\n value: function () {\n let e;\n const expressions = [];\n const index = parserInput.i;\n\n do {\n e = this.expression();\n if (e) {\n expressions.push(e);\n if (!parserInput.$char(',')) { break; }\n }\n } while (e);\n\n if (expressions.length > 0) {\n return new(tree.Value)(expressions, index);\n }\n },\n important: function () {\n if (parserInput.currentChar() === '!') {\n return parserInput.$re(/^! *important/);\n }\n },\n sub: function () {\n let a;\n let e;\n\n parserInput.save();\n if (parserInput.$char('(')) {\n a = this.addition();\n if (a && parserInput.$char(')')) {\n parserInput.forget();\n e = new(tree.Expression)([a]);\n e.parens = true;\n return e;\n }\n parserInput.restore('Expected \\')\\'');\n return;\n }\n parserInput.restore();\n },\n multiplication: function () {\n let m;\n let a;\n let op;\n let operation;\n let isSpaced;\n m = this.operand();\n if (m) {\n isSpaced = parserInput.isWhitespace(-1);\n while (true) {\n if (parserInput.peek(/^\\/[*\\/]/)) {\n break;\n }\n\n parserInput.save();\n\n op = parserInput.$char('/') || parserInput.$char('*') || parserInput.$str('./');\n\n if (!op) { parserInput.forget(); break; }\n\n a = this.operand();\n\n if (!a) { parserInput.restore(); break; }\n parserInput.forget();\n\n m.parensInOp = true;\n a.parensInOp = true;\n operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n isSpaced = parserInput.isWhitespace(-1);\n }\n return operation || m;\n }\n },\n addition: function () {\n let m;\n let a;\n let op;\n let operation;\n let isSpaced;\n m = this.multiplication();\n if (m) {\n isSpaced = parserInput.isWhitespace(-1);\n while (true) {\n op = parserInput.$re(/^[-+]\\s+/) || (!isSpaced && (parserInput.$char('+') || parserInput.$char('-')));\n if (!op) {\n break;\n }\n a = this.multiplication();\n if (!a) {\n break;\n }\n\n m.parensInOp = true;\n a.parensInOp = true;\n operation = new(tree.Operation)(op, [operation || m, a], isSpaced);\n isSpaced = parserInput.isWhitespace(-1);\n }\n return operation || m;\n }\n },\n conditions: function () {\n let a;\n let b;\n const index = parserInput.i;\n let condition;\n\n a = this.condition(true);\n if (a) {\n while (true) {\n if (!parserInput.peek(/^,\\s*(not\\s*)?\\(/) || !parserInput.$char(',')) {\n break;\n }\n b = this.condition(true);\n if (!b) {\n break;\n }\n condition = new(tree.Condition)('or', condition || a, b, index);\n }\n return condition || a;\n }\n },\n condition: function (needsParens) {\n let result;\n let logical;\n let next;\n function or() {\n return parserInput.$str('or');\n }\n\n result = this.conditionAnd(needsParens);\n if (!result) {\n return ;\n }\n logical = or();\n if (logical) {\n next = this.condition(needsParens);\n if (next) {\n result = new(tree.Condition)(logical, result, next);\n } else {\n return ;\n }\n }\n return result;\n },\n conditionAnd: function (needsParens) {\n let result;\n let logical;\n let next;\n const self = this;\n function insideCondition() {\n const cond = self.negatedCondition(needsParens) || self.parenthesisCondition(needsParens);\n if (!cond && !needsParens) {\n return self.atomicCondition(needsParens);\n }\n return cond;\n }\n function and() {\n return parserInput.$str('and');\n }\n\n result = insideCondition();\n if (!result) {\n return ;\n }\n logical = and();\n if (logical) {\n next = this.conditionAnd(needsParens);\n if (next) {\n result = new(tree.Condition)(logical, result, next);\n } else {\n return ;\n }\n }\n return result;\n },\n negatedCondition: function (needsParens) {\n if (parserInput.$str('not')) {\n const result = this.parenthesisCondition(needsParens);\n if (result) {\n result.negate = !result.negate;\n }\n return result;\n }\n },\n parenthesisCondition: function (needsParens) {\n function tryConditionFollowedByParenthesis(me) {\n let body;\n parserInput.save();\n body = me.condition(needsParens);\n if (!body) {\n parserInput.restore();\n return ;\n }\n if (!parserInput.$char(')')) {\n parserInput.restore();\n return ;\n }\n parserInput.forget();\n return body;\n }\n\n let body;\n parserInput.save();\n if (!parserInput.$str('(')) {\n parserInput.restore();\n return ;\n }\n body = tryConditionFollowedByParenthesis(this);\n if (body) {\n parserInput.forget();\n return body;\n }\n\n body = this.atomicCondition(needsParens);\n if (!body) {\n parserInput.restore();\n return ;\n }\n if (!parserInput.$char(')')) {\n parserInput.restore(`expected ')' got '${parserInput.currentChar()}'`);\n return ;\n }\n parserInput.forget();\n return body;\n },\n atomicCondition: function (needsParens) {\n const entities = this.entities;\n const index = parserInput.i;\n let a;\n let b;\n let c;\n let op;\n\n function cond() {\n return this.addition() || entities.keyword() || entities.quoted() || entities.mixinLookup();\n }\n cond = cond.bind(this);\n\n a = cond();\n if (a) {\n if (parserInput.$char('>')) {\n if (parserInput.$char('=')) {\n op = '>=';\n } else {\n op = '>';\n }\n } else\n if (parserInput.$char('<')) {\n if (parserInput.$char('=')) {\n op = '<=';\n } else {\n op = '<';\n }\n } else\n if (parserInput.$char('=')) {\n if (parserInput.$char('>')) {\n op = '=>';\n } else if (parserInput.$char('<')) {\n op = '=<';\n } else {\n op = '=';\n }\n }\n if (op) {\n b = cond();\n if (b) {\n c = new(tree.Condition)(op, a, b, index, false);\n } else {\n error('expected expression');\n }\n } else {\n c = new(tree.Condition)('=', a, new(tree.Keyword)('true'), index, false);\n }\n return c;\n }\n },\n\n //\n // An operand is anything that can be part of an operation,\n // such as a Color, or a Variable\n //\n operand: function () {\n const entities = this.entities;\n let negate;\n\n if (parserInput.peek(/^-[@\\$\\(]/)) {\n negate = parserInput.$char('-');\n }\n\n let o = this.sub() || entities.dimension() ||\n entities.color() || entities.variable() ||\n entities.property() || entities.call() ||\n entities.quoted(true) || entities.colorKeyword() ||\n entities.mixinLookup();\n\n if (negate) {\n o.parensInOp = true;\n o = new(tree.Negative)(o);\n }\n\n return o;\n },\n\n //\n // Expressions either represent mathematical operations,\n // or white-space delimited Entities.\n //\n // 1px solid black\n // @var * 2\n //\n expression: function () {\n const entities = [];\n let e;\n let delim;\n const index = parserInput.i;\n\n do {\n e = this.comment();\n if (e) {\n entities.push(e);\n continue;\n }\n e = this.addition() || this.entity();\n if (e) {\n entities.push(e);\n // operations do not allow keyword \"/\" dimension (e.g. small/20px) so we support that here\n if (!parserInput.peek(/^\\/[\\/*]/)) {\n delim = parserInput.$char('/');\n if (delim) {\n entities.push(new(tree.Anonymous)(delim, index));\n }\n }\n }\n } while (e);\n if (entities.length > 0) {\n return new(tree.Expression)(entities);\n }\n },\n property: function () {\n const name = parserInput.$re(/^(\\*?-?[_a-zA-Z0-9-]+)\\s*:/);\n if (name) {\n return name[1];\n }\n },\n ruleProperty: function () {\n let name = [];\n const index = [];\n let s;\n let k;\n\n parserInput.save();\n\n const simpleProperty = parserInput.$re(/^([_a-zA-Z0-9-]+)\\s*:/);\n if (simpleProperty) {\n name = [new(tree.Keyword)(simpleProperty[1])];\n parserInput.forget();\n return name;\n }\n\n function match(re) {\n const i = parserInput.i;\n const chunk = parserInput.$re(re);\n if (chunk) {\n index.push(i);\n return name.push(chunk[1]);\n }\n }\n\n match(/^(\\*?)/);\n while (true) {\n if (!match(/^((?:[\\w-]+)|(?:[@\\$]\\{[\\w-]+\\}))/)) {\n break;\n }\n }\n\n if ((name.length > 1) && match(/^((?:\\+_|\\+)?)\\s*:/)) {\n parserInput.forget();\n\n // at last, we have the complete match now. move forward,\n // convert name particles to tree objects and return:\n if (name[0] === '') {\n name.shift();\n index.shift();\n }\n for (k = 0; k < name.length; k++) {\n s = name[k];\n name[k] = (s.charAt(0) !== '@' && s.charAt(0) !== '$') ?\n new(tree.Keyword)(s) :\n (s.charAt(0) === '@' ?\n new(tree.Variable)(`@${s.slice(2, -1)}`, index[k], fileInfo) :\n new(tree.Property)(`$${s.slice(2, -1)}`, index[k], fileInfo));\n }\n return name;\n }\n parserInput.restore();\n }\n }\n };\n};\nParser.serializeVars = vars => {\n let s = '';\n\n for (const name in vars) {\n if (Object.hasOwnProperty.call(vars, name)) {\n const value = vars[name];\n s += `${((name[0] === '@') ? '' : '@') + name}: ${value}${(String(value).slice(-1) === ';') ? '' : ';'}`;\n }\n }\n\n return s;\n};\n\nexport default Parser;\n","import Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nlet colorFunctions;\n\nfunction clamp(val) {\n return Math.min(1, Math.max(0, val));\n}\nfunction hsla(origColor, hsl) {\n const color = colorFunctions.hsla(hsl.h, hsl.s, hsl.l, hsl.a);\n if (color) {\n if (origColor.value && \n /^(rgb|hsl)/.test(origColor.value)) {\n color.value = origColor.value;\n } else {\n color.value = 'rgb';\n }\n return color;\n }\n}\nfunction toHSL(color) {\n if (color.toHSL) {\n return color.toHSL();\n } else {\n throw new Error('Argument cannot be evaluated to a color');\n }\n}\n\nfunction toHSV(color) {\n if (color.toHSV) {\n return color.toHSV();\n } else {\n throw new Error('Argument cannot be evaluated to a color');\n }\n}\n\nfunction number(n) {\n if (n instanceof Dimension) {\n return parseFloat(n.unit.is('%') ? n.value / 100 : n.value);\n } else if (typeof n === 'number') {\n return n;\n } else {\n throw {\n type: 'Argument',\n message: 'color functions take numbers as parameters'\n };\n }\n}\nfunction scaled(n, size) {\n if (n instanceof Dimension && n.unit.is('%')) {\n return parseFloat(n.value * size / 100);\n } else {\n return number(n);\n }\n}\ncolorFunctions = {\n rgb: function (r, g, b) {\n const color = colorFunctions.rgba(r, g, b, 1.0);\n if (color) {\n color.value = 'rgb';\n return color;\n }\n },\n rgba: function (r, g, b, a) {\n try {\n if (r instanceof Color) {\n if (g) {\n a = number(g);\n } else {\n a = r.alpha;\n }\n return new Color(r.rgb, a, 'rgba');\n }\n const rgb = [r, g, b].map(c => scaled(c, 255));\n a = number(a);\n return new Color(rgb, a, 'rgba');\n }\n catch (e) {}\n },\n hsl: function (h, s, l) {\n const color = colorFunctions.hsla(h, s, l, 1.0);\n if (color) {\n color.value = 'hsl';\n return color;\n }\n },\n hsla: function (h, s, l, a) {\n try {\n if (h instanceof Color) {\n if (s) {\n a = number(s);\n } else {\n a = h.alpha;\n }\n return new Color(h.rgb, a, 'hsla');\n }\n\n let m1;\n let m2;\n\n function hue(h) {\n h = h < 0 ? h + 1 : (h > 1 ? h - 1 : h);\n if (h * 6 < 1) {\n return m1 + (m2 - m1) * h * 6;\n }\n else if (h * 2 < 1) {\n return m2;\n }\n else if (h * 3 < 2) {\n return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n }\n else {\n return m1;\n }\n }\n\n h = (number(h) % 360) / 360;\n s = clamp(number(s));l = clamp(number(l));a = clamp(number(a));\n\n m2 = l <= 0.5 ? l * (s + 1) : l + s - l * s;\n m1 = l * 2 - m2;\n\n const rgb = [\n hue(h + 1 / 3) * 255,\n hue(h) * 255,\n hue(h - 1 / 3) * 255\n ];\n a = number(a);\n return new Color(rgb, a, 'hsla');\n }\n catch (e) {}\n },\n\n hsv: function(h, s, v) {\n return colorFunctions.hsva(h, s, v, 1.0);\n },\n\n hsva: function(h, s, v, a) {\n h = ((number(h) % 360) / 360) * 360;\n s = number(s);v = number(v);a = number(a);\n\n let i;\n let f;\n i = Math.floor((h / 60) % 6);\n f = (h / 60) - i;\n\n const vs = [v,\n v * (1 - s),\n v * (1 - f * s),\n v * (1 - (1 - f) * s)];\n const perm = [[0, 3, 1],\n [2, 0, 1],\n [1, 0, 3],\n [1, 2, 0],\n [3, 1, 0],\n [0, 1, 2]];\n\n return colorFunctions.rgba(vs[perm[i][0]] * 255,\n vs[perm[i][1]] * 255,\n vs[perm[i][2]] * 255,\n a);\n },\n\n hue: function (color) {\n return new Dimension(toHSL(color).h);\n },\n saturation: function (color) {\n return new Dimension(toHSL(color).s * 100, '%');\n },\n lightness: function (color) {\n return new Dimension(toHSL(color).l * 100, '%');\n },\n hsvhue: function(color) {\n return new Dimension(toHSV(color).h);\n },\n hsvsaturation: function (color) {\n return new Dimension(toHSV(color).s * 100, '%');\n },\n hsvvalue: function (color) {\n return new Dimension(toHSV(color).v * 100, '%');\n },\n red: function (color) {\n return new Dimension(color.rgb[0]);\n },\n green: function (color) {\n return new Dimension(color.rgb[1]);\n },\n blue: function (color) {\n return new Dimension(color.rgb[2]);\n },\n alpha: function (color) {\n return new Dimension(toHSL(color).a);\n },\n luma: function (color) {\n return new Dimension(color.luma() * color.alpha * 100, '%');\n },\n luminance: function (color) {\n const luminance =\n (0.2126 * color.rgb[0] / 255) +\n (0.7152 * color.rgb[1] / 255) +\n (0.0722 * color.rgb[2] / 255);\n\n return new Dimension(luminance * color.alpha * 100, '%');\n },\n saturate: function (color, amount, method) {\n // filter: saturate(3.2);\n // should be kept as is, so check for color\n if (!color.rgb) {\n return null;\n }\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.s += hsl.s * amount.value / 100;\n }\n else {\n hsl.s += amount.value / 100;\n }\n hsl.s = clamp(hsl.s);\n return hsla(color, hsl);\n },\n desaturate: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.s -= hsl.s * amount.value / 100;\n }\n else {\n hsl.s -= amount.value / 100;\n }\n hsl.s = clamp(hsl.s);\n return hsla(color, hsl);\n },\n lighten: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.l += hsl.l * amount.value / 100;\n }\n else {\n hsl.l += amount.value / 100;\n }\n hsl.l = clamp(hsl.l);\n return hsla(color, hsl);\n },\n darken: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.l -= hsl.l * amount.value / 100;\n }\n else {\n hsl.l -= amount.value / 100;\n }\n hsl.l = clamp(hsl.l);\n return hsla(color, hsl);\n },\n fadein: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.a += hsl.a * amount.value / 100;\n }\n else {\n hsl.a += amount.value / 100;\n }\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n fadeout: function (color, amount, method) {\n const hsl = toHSL(color);\n\n if (typeof method !== 'undefined' && method.value === 'relative') {\n hsl.a -= hsl.a * amount.value / 100;\n }\n else {\n hsl.a -= amount.value / 100;\n }\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n fade: function (color, amount) {\n const hsl = toHSL(color);\n\n hsl.a = amount.value / 100;\n hsl.a = clamp(hsl.a);\n return hsla(color, hsl);\n },\n spin: function (color, amount) {\n const hsl = toHSL(color);\n const hue = (hsl.h + amount.value) % 360;\n\n hsl.h = hue < 0 ? 360 + hue : hue;\n\n return hsla(color, hsl);\n },\n //\n // Copyright (c) 2006-2009 Hampton Catlin, Natalie Weizenbaum, and Chris Eppstein\n // http://sass-lang.com\n //\n mix: function (color1, color2, weight) {\n if (!weight) {\n weight = new Dimension(50);\n }\n const p = weight.value / 100.0;\n const w = p * 2 - 1;\n const a = toHSL(color1).a - toHSL(color2).a;\n\n const w1 = (((w * a == -1) ? w : (w + a) / (1 + w * a)) + 1) / 2.0;\n const w2 = 1 - w1;\n\n const rgb = [color1.rgb[0] * w1 + color2.rgb[0] * w2,\n color1.rgb[1] * w1 + color2.rgb[1] * w2,\n color1.rgb[2] * w1 + color2.rgb[2] * w2];\n\n const alpha = color1.alpha * p + color2.alpha * (1 - p);\n\n return new Color(rgb, alpha);\n },\n greyscale: function (color) {\n return colorFunctions.desaturate(color, new Dimension(100));\n },\n contrast: function (color, dark, light, threshold) {\n // filter: contrast(3.2);\n // should be kept as is, so check for color\n if (!color.rgb) {\n return null;\n }\n if (typeof light === 'undefined') {\n light = colorFunctions.rgba(255, 255, 255, 1.0);\n }\n if (typeof dark === 'undefined') {\n dark = colorFunctions.rgba(0, 0, 0, 1.0);\n }\n // Figure out which is actually light and dark:\n if (dark.luma() > light.luma()) {\n const t = light;\n light = dark;\n dark = t;\n }\n if (typeof threshold === 'undefined') {\n threshold = 0.43;\n } else {\n threshold = number(threshold);\n }\n if (color.luma() < threshold) {\n return light;\n } else {\n return dark;\n }\n },\n // Changes made in 2.7.0 - Reverted in 3.0.0\n // contrast: function (color, color1, color2, threshold) {\n // // Return which of `color1` and `color2` has the greatest contrast with `color`\n // // according to the standard WCAG contrast ratio calculation.\n // // http://www.w3.org/TR/WCAG20/#contrast-ratiodef\n // // The threshold param is no longer used, in line with SASS.\n // // filter: contrast(3.2);\n // // should be kept as is, so check for color\n // if (!color.rgb) {\n // return null;\n // }\n // if (typeof color1 === 'undefined') {\n // color1 = colorFunctions.rgba(0, 0, 0, 1.0);\n // }\n // if (typeof color2 === 'undefined') {\n // color2 = colorFunctions.rgba(255, 255, 255, 1.0);\n // }\n // var contrast1, contrast2;\n // var luma = color.luma();\n // var luma1 = color1.luma();\n // var luma2 = color2.luma();\n // // Calculate contrast ratios for each color\n // if (luma > luma1) {\n // contrast1 = (luma + 0.05) / (luma1 + 0.05);\n // } else {\n // contrast1 = (luma1 + 0.05) / (luma + 0.05);\n // }\n // if (luma > luma2) {\n // contrast2 = (luma + 0.05) / (luma2 + 0.05);\n // } else {\n // contrast2 = (luma2 + 0.05) / (luma + 0.05);\n // }\n // if (contrast1 > contrast2) {\n // return color1;\n // } else {\n // return color2;\n // }\n // },\n argb: function (color) {\n return new Anonymous(color.toARGB());\n },\n color: function(c) {\n if ((c instanceof Quoted) &&\n (/^#([A-Fa-f0-9]{8}|[A-Fa-f0-9]{6}|[A-Fa-f0-9]{3,4})$/i.test(c.value))) {\n const val = c.value.slice(1);\n return new Color(val, undefined, `#${val}`);\n }\n if ((c instanceof Color) || (c = Color.fromKeyword(c.value))) {\n c.value = undefined;\n return c;\n }\n throw {\n type: 'Argument',\n message: 'argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF'\n };\n },\n tint: function(color, amount) {\n return colorFunctions.mix(colorFunctions.rgb(255, 255, 255), color, amount);\n },\n shade: function(color, amount) {\n return colorFunctions.mix(colorFunctions.rgb(0, 0, 0), color, amount);\n }\n};\n\nexport default colorFunctions;\n","import Anonymous from '../tree/anonymous';\nimport Keyword from '../tree/keyword';\n\nfunction boolean(condition) {\n return condition ? Keyword.True : Keyword.False;\n}\n\nfunction If(condition, trueValue, falseValue) {\n return condition ? trueValue\n : (falseValue || new Anonymous);\n}\n\nexport default { boolean, 'if': If };\n","import Color from '../tree/color';\n\n// Color Blending\n// ref: http://www.w3.org/TR/compositing-1\n\nfunction colorBlend(mode, color1, color2) {\n const ab = color1.alpha; // result\n\n let // backdrop\n cb;\n\n const as = color2.alpha;\n\n let // source\n cs;\n\n let ar;\n let cr;\n const r = [];\n\n ar = as + ab * (1 - as);\n for (let i = 0; i < 3; i++) {\n cb = color1.rgb[i] / 255;\n cs = color2.rgb[i] / 255;\n cr = mode(cb, cs);\n if (ar) {\n cr = (as * cs + ab * (cb -\n as * (cb + cs - cr))) / ar;\n }\n r[i] = cr * 255;\n }\n\n return new Color(r, ar);\n}\n\nconst colorBlendModeFunctions = {\n multiply: function(cb, cs) {\n return cb * cs;\n },\n screen: function(cb, cs) {\n return cb + cs - cb * cs;\n },\n overlay: function(cb, cs) {\n cb *= 2;\n return (cb <= 1) ?\n colorBlendModeFunctions.multiply(cb, cs) :\n colorBlendModeFunctions.screen(cb - 1, cs);\n },\n softlight: function(cb, cs) {\n let d = 1;\n let e = cb;\n if (cs > 0.5) {\n e = 1;\n d = (cb > 0.25) ? Math.sqrt(cb)\n : ((16 * cb - 12) * cb + 4) * cb;\n }\n return cb - (1 - 2 * cs) * e * (d - cb);\n },\n hardlight: function(cb, cs) {\n return colorBlendModeFunctions.overlay(cs, cb);\n },\n difference: function(cb, cs) {\n return Math.abs(cb - cs);\n },\n exclusion: function(cb, cs) {\n return cb + cs - 2 * cb * cs;\n },\n\n // non-w3c functions:\n average: function(cb, cs) {\n return (cb + cs) / 2;\n },\n negation: function(cb, cs) {\n return 1 - Math.abs(cb + cs - 1);\n }\n};\n\nfor (const f in colorBlendModeFunctions) {\n if (colorBlendModeFunctions.hasOwnProperty(f)) {\n colorBlend[f] = colorBlend.bind(null, colorBlendModeFunctions[f]);\n }\n}\n\nexport default colorBlend;\n","import Comment from '../tree/comment';\nimport Dimension from '../tree/dimension';\nimport Declaration from '../tree/declaration';\nimport Expression from '../tree/expression';\nimport Ruleset from '../tree/ruleset';\nimport Selector from '../tree/selector';\nimport Element from '../tree/element';\nimport Quote from '../tree/quoted';\n\nconst getItemsFromNode = node => {\n // handle non-array values as an array of length 1\n // return 'undefined' if index is invalid\n const items = Array.isArray(node.value) ?\n node.value : Array(node);\n\n return items;\n};\n\nexport default {\n _SELF: function(n) {\n return n;\n },\n extract: function(values, index) {\n // (1-based index)\n index = index.value - 1;\n\n return getItemsFromNode(values)[index];\n },\n length: function(values) {\n return new Dimension(getItemsFromNode(values).length);\n },\n /**\n * Creates a Less list of incremental values.\n * Modeled after Lodash's range function, also exists natively in PHP\n * \n * @param {Dimension} [start=1]\n * @param {Dimension} end - e.g. 10 or 10px - unit is added to output\n * @param {Dimension} [step=1] \n */\n range: function(start, end, step) {\n let from;\n let to;\n let stepValue = 1;\n const list = [];\n if (end) {\n to = end;\n from = start.value;\n if (step) {\n stepValue = step.value;\n }\n }\n else {\n from = 1;\n to = start;\n }\n\n for (let i = from; i <= to.value; i += stepValue) {\n list.push(new Dimension(i, to.unit));\n }\n\n return new Expression(list);\n },\n each: function(list, rs) {\n const rules = [];\n let newRules;\n let iterator;\n\n if (list.value && !(list instanceof Quote)) {\n if (Array.isArray(list.value)) {\n iterator = list.value;\n } else {\n iterator = [list.value];\n }\n } else if (list.ruleset) {\n iterator = list.ruleset.rules;\n } else if (list.rules) {\n iterator = list.rules;\n } else if (Array.isArray(list)) {\n iterator = list;\n } else {\n iterator = [list];\n }\n\n let valueName = '@value';\n let keyName = '@key';\n let indexName = '@index';\n\n if (rs.params) {\n valueName = rs.params[0] && rs.params[0].name;\n keyName = rs.params[1] && rs.params[1].name;\n indexName = rs.params[2] && rs.params[2].name;\n rs = rs.rules;\n } else {\n rs = rs.ruleset;\n }\n\n for (let i = 0; i < iterator.length; i++) {\n let key;\n let value;\n const item = iterator[i];\n if (item instanceof Declaration) {\n key = typeof item.name === 'string' ? item.name : item.name[0].value;\n value = item.value;\n } else {\n key = new Dimension(i + 1);\n value = item;\n }\n\n if (item instanceof Comment) {\n continue;\n }\n\n newRules = rs.rules.slice(0);\n if (valueName) {\n newRules.push(new Declaration(valueName,\n value,\n false, false, this.index, this.currentFileInfo));\n }\n if (indexName) {\n newRules.push(new Declaration(indexName,\n new Dimension(i + 1),\n false, false, this.index, this.currentFileInfo));\n }\n if (keyName) {\n newRules.push(new Declaration(keyName,\n key,\n false, false, this.index, this.currentFileInfo));\n }\n\n rules.push(new Ruleset([ new(Selector)([ new Element(\"\", '&') ]) ],\n newRules,\n rs.strictImports,\n rs.visibilityInfo()\n ));\n }\n\n return new Ruleset([ new(Selector)([ new Element(\"\", '&') ]) ],\n rules,\n rs.strictImports,\n rs.visibilityInfo()\n ).eval(this.context);\n }\n};\n","import Dimension from '../tree/dimension';\n\nconst MathHelper = (fn, unit, n) => {\n if (!(n instanceof Dimension)) {\n throw { type: 'Argument', message: 'argument must be a number' };\n }\n if (unit == null) {\n unit = n.unit;\n } else {\n n = n.unify();\n }\n return new Dimension(fn(parseFloat(n.value)), unit);\n};\n\nexport default MathHelper;","import mathHelper from './math-helper.js';\n\nconst mathFunctions = {\n // name, unit\n ceil: null,\n floor: null,\n sqrt: null,\n abs: null,\n tan: '',\n sin: '',\n cos: '',\n atan: 'rad',\n asin: 'rad',\n acos: 'rad'\n};\n\nfor (const f in mathFunctions) {\n if (mathFunctions.hasOwnProperty(f)) {\n mathFunctions[f] = mathHelper.bind(null, Math[f], mathFunctions[f]);\n }\n}\n\nmathFunctions.round = (n, f) => {\n const fraction = typeof f === 'undefined' ? 0 : f.value;\n return mathHelper(num => num.toFixed(fraction), null, n);\n};\n\nexport default mathFunctions;\n","import Dimension from '../tree/dimension';\nimport Anonymous from '../tree/anonymous';\nimport mathHelper from './math-helper.js';\n\nconst minMax = function (isMin, args) {\n args = Array.prototype.slice.call(args);\n switch (args.length) {\n case 0: throw { type: 'Argument', message: 'one or more arguments required' };\n }\n let i; // key is the unit.toString() for unified Dimension values,\n let j;\n let current;\n let currentUnified;\n let referenceUnified;\n let unit;\n let unitStatic;\n let unitClone;\n\n const // elems only contains original argument values.\n order = [];\n\n const values = {};\n // value is the index into the order array.\n for (i = 0; i < args.length; i++) {\n current = args[i];\n if (!(current instanceof Dimension)) {\n if (Array.isArray(args[i].value)) {\n Array.prototype.push.apply(args, Array.prototype.slice.call(args[i].value));\n }\n continue;\n }\n currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();\n unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();\n unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;\n unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;\n j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];\n if (j === undefined) {\n if (unitStatic !== undefined && unit !== unitStatic) {\n throw { type: 'Argument', message: 'incompatible types' };\n }\n values[unit] = order.length;\n order.push(current);\n continue;\n }\n referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();\n if ( isMin && currentUnified.value < referenceUnified.value ||\n !isMin && currentUnified.value > referenceUnified.value) {\n order[j] = current;\n }\n }\n if (order.length == 1) {\n return order[0];\n }\n args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');\n return new Anonymous(`${isMin ? 'min' : 'max'}(${args})`);\n};\n\nexport default {\n min: function(...args) {\n return minMax(true, args);\n },\n max: function(...args) {\n return minMax(false, args);\n },\n convert: function (val, unit) {\n return val.convertTo(unit.value);\n },\n pi: function () {\n return new Dimension(Math.PI);\n },\n mod: function(a, b) {\n return new Dimension(a.value % b.value, a.unit);\n },\n pow: function(x, y) {\n if (typeof x === 'number' && typeof y === 'number') {\n x = new Dimension(x);\n y = new Dimension(y);\n } else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {\n throw { type: 'Argument', message: 'arguments must be numbers' };\n }\n\n return new Dimension(Math.pow(x.value, y.value), x.unit);\n },\n percentage: function (n) {\n const result = mathHelper(num => num * 100, '%', n);\n\n return result;\n }\n};\n","/**\n * Plugin Manager\n */\nclass PluginManager {\n constructor(less) {\n this.less = less;\n this.visitors = [];\n this.preProcessors = [];\n this.postProcessors = [];\n this.installedPlugins = [];\n this.fileManagers = [];\n this.iterator = -1;\n this.pluginCache = {};\n this.Loader = new less.PluginLoader(less);\n }\n\n /**\n * Adds all the plugins in the array\n * @param {Array} plugins\n */\n addPlugins(plugins) {\n if (plugins) {\n for (let i = 0; i < plugins.length; i++) {\n this.addPlugin(plugins[i]);\n }\n }\n }\n\n /**\n *\n * @param plugin\n * @param {String} filename\n */\n addPlugin(plugin, filename, functionRegistry) {\n this.installedPlugins.push(plugin);\n if (filename) {\n this.pluginCache[filename] = plugin;\n }\n if (plugin.install) {\n plugin.install(this.less, this, functionRegistry || this.less.functions.functionRegistry);\n }\n }\n\n /**\n *\n * @param filename\n */\n get(filename) {\n return this.pluginCache[filename];\n }\n\n /**\n * Adds a visitor. The visitor object has options on itself to determine\n * when it should run.\n * @param visitor\n */\n addVisitor(visitor) {\n this.visitors.push(visitor);\n }\n\n /**\n * Adds a pre processor object\n * @param {object} preProcessor\n * @param {number} priority - guidelines 1 = before import, 1000 = import, 2000 = after import\n */\n addPreProcessor(preProcessor, priority) {\n let indexToInsertAt;\n for (indexToInsertAt = 0; indexToInsertAt < this.preProcessors.length; indexToInsertAt++) {\n if (this.preProcessors[indexToInsertAt].priority >= priority) {\n break;\n }\n }\n this.preProcessors.splice(indexToInsertAt, 0, {preProcessor, priority});\n }\n\n /**\n * Adds a post processor object\n * @param {object} postProcessor\n * @param {number} priority - guidelines 1 = before compression, 1000 = compression, 2000 = after compression\n */\n addPostProcessor(postProcessor, priority) {\n let indexToInsertAt;\n for (indexToInsertAt = 0; indexToInsertAt < this.postProcessors.length; indexToInsertAt++) {\n if (this.postProcessors[indexToInsertAt].priority >= priority) {\n break;\n }\n }\n this.postProcessors.splice(indexToInsertAt, 0, {postProcessor, priority});\n }\n\n /**\n *\n * @param manager\n */\n addFileManager(manager) {\n this.fileManagers.push(manager);\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getPreProcessors() {\n const preProcessors = [];\n for (let i = 0; i < this.preProcessors.length; i++) {\n preProcessors.push(this.preProcessors[i].preProcessor);\n }\n return preProcessors;\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getPostProcessors() {\n const postProcessors = [];\n for (let i = 0; i < this.postProcessors.length; i++) {\n postProcessors.push(this.postProcessors[i].postProcessor);\n }\n return postProcessors;\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getVisitors() {\n return this.visitors;\n }\n\n visitor() {\n const self = this;\n return {\n first: function() {\n self.iterator = -1;\n return self.visitors[self.iterator];\n },\n get: function() {\n self.iterator += 1;\n return self.visitors[self.iterator];\n }\n };\n }\n\n /**\n *\n * @returns {Array}\n * @private\n */\n getFileManagers() {\n return this.fileManagers;\n }\n}\n\nlet pm;\n\nfunction PluginManagerFactory(less, newFactory) {\n if (newFactory || !pm) {\n pm = new PluginManager(less);\n }\n return pm;\n};\n\n//\nexport default PluginManagerFactory;\n","import Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nimport JavaScript from '../tree/javascript';\n\nexport default {\n e: function (str) {\n return new Quoted('\"', str instanceof JavaScript ? str.evaluated : str.value, true);\n },\n escape: function (str) {\n return new Anonymous(\n encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')\n .replace(/\\(/g, '%28').replace(/\\)/g, '%29'));\n },\n replace: function (string, pattern, replacement, flags) {\n let result = string.value;\n replacement = (replacement.type === 'Quoted') ?\n replacement.value : replacement.toCSS();\n result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);\n return new Quoted(string.quote || '', result, string.escaped);\n },\n '%': function (string /* arg, arg, ... */) {\n const args = Array.prototype.slice.call(arguments, 1);\n let result = string.value;\n\n for (let i = 0; i < args.length; i++) {\n /* jshint loopfunc:true */\n result = result.replace(/%[sda]/i, token => {\n const value = ((args[i].type === 'Quoted') &&\n token.match(/s/i)) ? args[i].value : args[i].toCSS();\n return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;\n });\n }\n result = result.replace(/%%/g, '%');\n return new Quoted(string.quote || '', result, string.escaped);\n }\n};\n","import Keyword from '../tree/keyword';\nimport DetachedRuleset from '../tree/detached-ruleset';\nimport Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Quoted from '../tree/quoted';\nimport Anonymous from '../tree/anonymous';\nimport URL from '../tree/url';\nimport Operation from '../tree/operation';\n\nconst isa = (n, Type) => (n instanceof Type) ? Keyword.True : Keyword.False;\nconst isunit = (n, unit) => {\n if (unit === undefined) {\n throw { type: 'Argument', message: 'missing the required second argument to isunit.' };\n }\n unit = typeof unit.value === 'string' ? unit.value : unit;\n if (typeof unit !== 'string') {\n throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };\n }\n return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;\n};\n\nexport default {\n isruleset: function (n) {\n return isa(n, DetachedRuleset);\n },\n iscolor: function (n) {\n return isa(n, Color);\n },\n isnumber: function (n) {\n return isa(n, Dimension);\n },\n isstring: function (n) {\n return isa(n, Quoted);\n },\n iskeyword: function (n) {\n return isa(n, Keyword);\n },\n isurl: function (n) {\n return isa(n, URL);\n },\n ispixel: function (n) {\n return isunit(n, 'px');\n },\n ispercentage: function (n) {\n return isunit(n, '%');\n },\n isem: function (n) {\n return isunit(n, 'em');\n },\n isunit,\n unit: function (val, unit) {\n if (!(val instanceof Dimension)) {\n throw { type: 'Argument',\n message: `the first argument to unit must be a number${val instanceof Operation ? '. Have you forgotten parenthesis?' : ''}` };\n }\n if (unit) {\n if (unit instanceof Keyword) {\n unit = unit.value;\n } else {\n unit = unit.toCSS();\n }\n } else {\n unit = '';\n }\n return new Dimension(val.value, unit);\n },\n 'get-unit': function (n) {\n return new Anonymous(n.unit);\n }\n};\n","import functionRegistry from './function-registry';\nimport functionCaller from './function-caller';\n\nimport boolean from './boolean';\nimport defaultFunc from './default';\nimport color from './color';\nimport colorBlending from './color-blending';\nimport dataUri from './data-uri';\nimport list from './list';\nimport math from './math';\nimport number from './number';\nimport string from './string';\nimport svg from './svg';\nimport types from './types';\n\nexport default environment => {\n const functions = { functionRegistry, functionCaller };\n\n // register functions\n functionRegistry.addMultiple(boolean);\n functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));\n functionRegistry.addMultiple(color);\n functionRegistry.addMultiple(colorBlending);\n functionRegistry.addMultiple(dataUri(environment));\n functionRegistry.addMultiple(list);\n functionRegistry.addMultiple(math);\n functionRegistry.addMultiple(number);\n functionRegistry.addMultiple(string);\n functionRegistry.addMultiple(svg(environment));\n functionRegistry.addMultiple(types);\n\n return functions;\n};\n","import Quoted from '../tree/quoted';\nimport URL from '../tree/url';\nimport * as utils from '../utils';\nimport logger from '../logger';\n\nexport default environment => {\n \n const fallback = (functionThis, node) => new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context); \n\n return { 'data-uri': function(mimetypeNode, filePathNode) {\n\n if (!filePathNode) {\n filePathNode = mimetypeNode;\n mimetypeNode = null;\n }\n\n let mimetype = mimetypeNode && mimetypeNode.value;\n let filePath = filePathNode.value;\n const currentFileInfo = this.currentFileInfo;\n const currentDirectory = currentFileInfo.rewriteUrls ?\n currentFileInfo.currentDirectory : currentFileInfo.entryPath;\n\n const fragmentStart = filePath.indexOf('#');\n let fragment = '';\n if (fragmentStart !== -1) {\n fragment = filePath.slice(fragmentStart);\n filePath = filePath.slice(0, fragmentStart);\n }\n const context = utils.clone(this.context);\n context.rawBuffer = true;\n\n const fileManager = environment.getFileManager(filePath, currentDirectory, context, environment, true);\n\n if (!fileManager) {\n return fallback(this, filePathNode);\n }\n\n let useBase64 = false;\n\n // detect the mimetype if not given\n if (!mimetypeNode) {\n\n mimetype = environment.mimeLookup(filePath);\n\n if (mimetype === 'image/svg+xml') {\n useBase64 = false;\n } else {\n // use base 64 unless it's an ASCII or UTF-8 format\n const charset = environment.charsetLookup(mimetype);\n useBase64 = ['US-ASCII', 'UTF-8'].indexOf(charset) < 0;\n }\n if (useBase64) { mimetype += ';base64'; }\n }\n else {\n useBase64 = /;base64$/.test(mimetype);\n }\n\n const fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);\n if (!fileSync.contents) {\n logger.warn(`Skipped data-uri embedding of ${filePath} because file not found`);\n return fallback(this, filePathNode || mimetypeNode);\n }\n let buf = fileSync.contents;\n if (useBase64 && !environment.encodeBase64) {\n return fallback(this, filePathNode);\n }\n\n buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);\n\n const uri = `data:${mimetype},${buf}${fragment}`;\n\n return new URL(new Quoted(`\"${uri}\"`, uri, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n }};\n};\n","import Dimension from '../tree/dimension';\nimport Color from '../tree/color';\nimport Expression from '../tree/expression';\nimport Quoted from '../tree/quoted';\nimport URL from '../tree/url';\n\nexport default environment => {\n return { 'svg-gradient': function(direction) {\n let stops;\n let gradientDirectionSvg;\n let gradientType = 'linear';\n let rectangleDimension = 'x=\"0\" y=\"0\" width=\"1\" height=\"1\"';\n const renderEnv = {compress: false};\n let returner;\n const directionValue = direction.toCSS(renderEnv);\n let i;\n let color;\n let position;\n let positionValue;\n let alpha;\n\n function throwArgumentDescriptor() {\n throw { type: 'Argument',\n message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +\n ' end_color [end_position] or direction, color list' };\n }\n\n if (arguments.length == 2) {\n if (arguments[1].value.length < 2) {\n throwArgumentDescriptor();\n }\n stops = arguments[1].value;\n } else if (arguments.length < 3) {\n throwArgumentDescriptor();\n } else {\n stops = Array.prototype.slice.call(arguments, 1);\n }\n\n switch (directionValue) {\n case 'to bottom':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\"';\n break;\n case 'to right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"0%\"';\n break;\n case 'to bottom right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"0%\" x2=\"100%\" y2=\"100%\"';\n break;\n case 'to top right':\n gradientDirectionSvg = 'x1=\"0%\" y1=\"100%\" x2=\"100%\" y2=\"0%\"';\n break;\n case 'ellipse':\n case 'ellipse at center':\n gradientType = 'radial';\n gradientDirectionSvg = 'cx=\"50%\" cy=\"50%\" r=\"75%\"';\n rectangleDimension = 'x=\"-50\" y=\"-50\" width=\"101\" height=\"101\"';\n break;\n default:\n throw { type: 'Argument', message: 'svg-gradient direction must be \\'to bottom\\', \\'to right\\',' +\n ' \\'to bottom right\\', \\'to top right\\' or \\'ellipse at center\\'' };\n }\n returner = `<${gradientType}Gradient id=\"g\" ${gradientDirectionSvg}>`;\n\n for (i = 0; i < stops.length; i += 1) {\n if (stops[i] instanceof Expression) {\n color = stops[i].value[0];\n position = stops[i].value[1];\n } else {\n color = stops[i];\n position = undefined;\n }\n\n if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {\n throwArgumentDescriptor();\n }\n positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';\n alpha = color.alpha;\n returner += ``;\n }\n returner += ``;\n\n returner = encodeURIComponent(returner);\n\n returner = `data:image/svg+xml,${returner}`;\n return new URL(new Quoted(`'${returner}'`, returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);\n }};\n};\n","import contexts from './contexts';\nimport visitor from './visitors';\nimport tree from './tree';\n\nexport default (root, options = {}) => {\n let evaldRoot;\n let variables = options.variables;\n const evalEnv = new contexts.Eval(options);\n\n //\n // Allows setting variables with a hash, so:\n //\n // `{ color: new tree.Color('#f01') }` will become:\n //\n // new tree.Declaration('@color',\n // new tree.Value([\n // new tree.Expression([\n // new tree.Color('#f01')\n // ])\n // ])\n // )\n //\n if (typeof variables === 'object' && !Array.isArray(variables)) {\n variables = Object.keys(variables).map(k => {\n let value = variables[k];\n\n if (!(value instanceof tree.Value)) {\n if (!(value instanceof tree.Expression)) {\n value = new tree.Expression([value]);\n }\n value = new tree.Value([value]);\n }\n return new tree.Declaration(`@${k}`, value, false, null, 0);\n });\n evalEnv.frames = [new tree.Ruleset(null, variables)];\n }\n\n const visitors = [\n new visitor.JoinSelectorVisitor(),\n new visitor.MarkVisibleSelectorsVisitor(true),\n new visitor.ExtendVisitor(),\n new visitor.ToCSSVisitor({compress: Boolean(options.compress)})\n ];\n\n const preEvalVisitors = [];\n let v;\n let visitorIterator;\n\n /**\n * first() / get() allows visitors to be added while visiting\n * \n * @todo Add scoping for visitors just like functions for @plugin; right now they're global\n */\n if (options.pluginManager) {\n visitorIterator = options.pluginManager.visitor();\n for (var i = 0; i < 2; i++) {\n visitorIterator.first();\n while ((v = visitorIterator.get())) {\n if (v.isPreEvalVisitor) {\n if (i === 0 || preEvalVisitors.indexOf(v) === -1) {\n preEvalVisitors.push(v);\n v.run(root);\n }\n }\n else {\n if (i === 0 || visitors.indexOf(v) === -1) {\n if (v.isPreVisitor) {\n visitors.unshift(v);\n }\n else {\n visitors.push(v);\n }\n }\n }\n }\n }\n }\n\n evaldRoot = root.eval(evalEnv);\n\n for (var i = 0; i < visitors.length; i++) {\n visitors[i].run(evaldRoot);\n }\n\n // Run any remaining visitors added after eval pass\n if (options.pluginManager) {\n visitorIterator.first();\n while ((v = visitorIterator.get())) {\n if (visitors.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {\n v.run(evaldRoot);\n }\n }\n }\n\n return evaldRoot;\n};\n","/* global window, XMLHttpRequest */\n\nimport AbstractFileManager from '../less/environment/abstract-file-manager.js';\n\nlet options;\nlet logger;\nlet fileCache = {};\n\n// TODOS - move log somewhere. pathDiff and doing something similar in node. use pathDiff in the other browser file for the initial load\nclass FileManager extends AbstractFileManager {\n alwaysMakePathsAbsolute() {\n return true;\n }\n\n getPossibleFileExtensions(path, ext) {\n if (this.isPathWithExtension(path, ext)) {\n return [''];\n }\n\n // if file doesn't have dot in name it require extention\n if (path.indexOf(\".\") === -1) {\n return [ext];\n }\n\n // path has dots in name it might be with or without extention (like .css)\n return [ext, ''];\n }\n\n join(basePath, laterPath) {\n if (!basePath) {\n return laterPath;\n }\n return this.extractUrlParts(laterPath, basePath).path;\n }\n\n doXHR(url, type, callback, errback) {\n const xhr = new XMLHttpRequest();\n const async = options.isFileProtocol ? options.fileAsync : true;\n\n if (typeof xhr.overrideMimeType === 'function') {\n xhr.overrideMimeType('text/css');\n }\n logger.debug(`XHR: Getting '${url}'`);\n xhr.open('GET', url, async);\n xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');\n xhr.send(null);\n\n function handleResponse(xhr, callback, errback) {\n if (xhr.status >= 200 && xhr.status < 300) {\n callback(xhr.responseText,\n xhr.getResponseHeader('Last-Modified'));\n } else if (typeof errback === 'function') {\n errback(xhr.status, url);\n }\n }\n\n if (options.isFileProtocol && !options.fileAsync) {\n if (xhr.status === 0 || (xhr.status >= 200 && xhr.status < 300)) {\n callback(xhr.responseText);\n } else {\n errback(xhr.status, url);\n }\n } else if (async) {\n xhr.onreadystatechange = () => {\n if (xhr.readyState == 4) {\n handleResponse(xhr, callback, errback);\n }\n };\n } else {\n handleResponse(xhr, callback, errback);\n }\n }\n\n tryToLoad(href) {\n return new Promise((resolve, reject) => {\n if (options.useFileCache && fileCache[href]) {\n try {\n const lessText = fileCache[href];\n return resolve({ contents: lessText, filename: href, webInfo: { lastModified: new Date() }});\n } catch (e) {\n return reject({ filename: href, message: `Error loading file ${href} error was ${e.message}` });\n }\n }\n\n this.doXHR(href, options.mime, function doXHRCallback(data, lastModified) {\n // per file cache\n fileCache[href] = data;\n\n // Use remote copy (re-parse)\n resolve({ contents: data, filename: href, webInfo: { lastModified }});\n }, function doXHRError(status, url) {\n reject({ type: 'File', message: `'${url}' wasn't found (${status})`, href });\n });\n });\n }\n\n supports() {\n return true;\n }\n\n clearFileCache() {\n fileCache = {};\n }\n\n loadFile(filename, currentDirectory, options, environment) {\n // TODO: Add prefix support like less-node?\n // What about multiple paths?\n\n if (currentDirectory && !this.isPathAbsolute(filename)) {\n filename = currentDirectory + filename;\n }\n\n const extensions = this.getPossibleFileExtensions(filename, options.ext || '');\n\n options = options || {};\n\n // sheet may be set to the stylesheet for the initial load or a collection of properties including\n // some context variables for imports\n const hrefParts = this.extractUrlParts(filename, window.location.href);\n const href = hrefParts.url;\n const hrefs = extensions.map(ext => this.tryAppendExtension(href, ext))\n\n return hrefs.reduce(\n (prev, href) => prev.catch(() => this.tryToLoad(href)),\n this.tryToLoad(hrefs.shift())\n );\n }\n}\n\nexport default (opts, log) => {\n options = opts;\n logger = log;\n return FileManager;\n}\n","import data from './data';\nimport tree from './tree';\nimport Environment from './environment/environment';\nimport AbstractFileManager from './environment/abstract-file-manager';\nimport AbstractPluginLoader from './environment/abstract-plugin-loader';\nimport visitors from './visitors';\nimport Parser from './parser/parser';\nimport Functions from './functions';\nimport contexts from './contexts';\nimport sourceMapOutput from './source-map-output';\nimport sourceMapBuilder from './source-map-builder';\nimport parseTree from './parse-tree';\nimport importManager from './import-manager';\nimport Render from './render';\nimport Parse from './parse';\nimport LessError from './less-error';\nimport transformTree from './transform-tree';\nimport * as utils from './utils';\nimport PluginManager from './plugin-manager';\nimport logger from './logger';\n\nexport default (environment, fileManagers) => {\n /**\n * @todo\n * This original code could be improved quite a bit.\n * Many classes / modules currently add side-effects / mutations to passed in objects,\n * which makes it hard to refactor and reason about. \n */\n environment = new Environment(environment, fileManagers);\n\n const SourceMapOutput = sourceMapOutput(environment);\n const SourceMapBuilder = sourceMapBuilder(SourceMapOutput, environment);\n const ParseTree = parseTree(SourceMapBuilder);\n const ImportManager = importManager(environment);\n const render = Render(environment, ParseTree, ImportManager);\n const parse = Parse(environment, ParseTree, ImportManager);\n const functions = Functions(environment);\n\n /**\n * @todo\n * This root properties / methods need to be organized.\n * It's not clear what should / must be public and why.\n */\n const initial = {\n version: [3, 11, 0],\n data,\n tree,\n Environment,\n AbstractFileManager,\n AbstractPluginLoader,\n environment,\n visitors,\n Parser,\n functions,\n contexts,\n SourceMapOutput,\n SourceMapBuilder,\n ParseTree,\n ImportManager,\n render,\n parse,\n LessError,\n transformTree,\n utils,\n PluginManager,\n logger\n };\n\n // Create a public API\n const ctor = t => function (...args) {\n return new t(...args);\n };\n\n let t;\n const api = Object.create(initial);\n for (const n in initial.tree) {\n /* eslint guard-for-in: 0 */\n t = initial.tree[n];\n if (typeof t === 'function') {\n api[n.toLowerCase()] = ctor(t);\n }\n else {\n api[n] = Object.create(null);\n for (const o in t) {\n /* eslint guard-for-in: 0 */\n api[n][o.toLowerCase()] = ctor(t[o]);\n }\n }\n }\n\n return api;\n};\n","export default environment => {\n class SourceMapOutput {\n constructor(options) {\n this._css = [];\n this._rootNode = options.rootNode;\n this._contentsMap = options.contentsMap;\n this._contentsIgnoredCharsMap = options.contentsIgnoredCharsMap;\n if (options.sourceMapFilename) {\n this._sourceMapFilename = options.sourceMapFilename.replace(/\\\\/g, '/');\n }\n this._outputFilename = options.outputFilename;\n this.sourceMapURL = options.sourceMapURL;\n if (options.sourceMapBasepath) {\n this._sourceMapBasepath = options.sourceMapBasepath.replace(/\\\\/g, '/');\n }\n if (options.sourceMapRootpath) {\n this._sourceMapRootpath = options.sourceMapRootpath.replace(/\\\\/g, '/');\n if (this._sourceMapRootpath.charAt(this._sourceMapRootpath.length - 1) !== '/') {\n this._sourceMapRootpath += '/';\n }\n } else {\n this._sourceMapRootpath = '';\n }\n this._outputSourceFiles = options.outputSourceFiles;\n this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();\n\n this._lineNumber = 0;\n this._column = 0;\n }\n\n removeBasepath(path) {\n if (this._sourceMapBasepath && path.indexOf(this._sourceMapBasepath) === 0) {\n path = path.substring(this._sourceMapBasepath.length);\n if (path.charAt(0) === '\\\\' || path.charAt(0) === '/') {\n path = path.substring(1);\n }\n }\n\n return path;\n }\n\n normalizeFilename(filename) {\n filename = filename.replace(/\\\\/g, '/');\n filename = this.removeBasepath(filename);\n return (this._sourceMapRootpath || '') + filename;\n }\n\n add(chunk, fileInfo, index, mapLines) {\n // ignore adding empty strings\n if (!chunk) {\n return;\n }\n\n let lines;\n let sourceLines;\n let columns;\n let sourceColumns;\n let i;\n\n if (fileInfo && fileInfo.filename) {\n let inputSource = this._contentsMap[fileInfo.filename];\n\n // remove vars/banner added to the top of the file\n if (this._contentsIgnoredCharsMap[fileInfo.filename]) {\n // adjust the index\n index -= this._contentsIgnoredCharsMap[fileInfo.filename];\n if (index < 0) { index = 0; }\n // adjust the source\n inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);\n }\n\n // ignore empty content\n if (inputSource === undefined) {\n return;\n }\n\n inputSource = inputSource.substring(0, index);\n sourceLines = inputSource.split('\\n');\n sourceColumns = sourceLines[sourceLines.length - 1];\n }\n\n lines = chunk.split('\\n');\n columns = lines[lines.length - 1];\n\n if (fileInfo && fileInfo.filename) {\n if (!mapLines) {\n this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + 1, column: this._column},\n original: { line: sourceLines.length, column: sourceColumns.length},\n source: this.normalizeFilename(fileInfo.filename)});\n } else {\n for (i = 0; i < lines.length; i++) {\n this._sourceMapGenerator.addMapping({ generated: { line: this._lineNumber + i + 1, column: i === 0 ? this._column : 0},\n original: { line: sourceLines.length + i, column: i === 0 ? sourceColumns.length : 0},\n source: this.normalizeFilename(fileInfo.filename)});\n }\n }\n }\n\n if (lines.length === 1) {\n this._column += columns.length;\n } else {\n this._lineNumber += lines.length - 1;\n this._column = columns.length;\n }\n\n this._css.push(chunk);\n }\n\n isEmpty() {\n return this._css.length === 0;\n }\n\n toCSS(context) {\n this._sourceMapGenerator = new this._sourceMapGeneratorConstructor({ file: this._outputFilename, sourceRoot: null });\n\n if (this._outputSourceFiles) {\n for (const filename in this._contentsMap) {\n if (this._contentsMap.hasOwnProperty(filename)) {\n let source = this._contentsMap[filename];\n if (this._contentsIgnoredCharsMap[filename]) {\n source = source.slice(this._contentsIgnoredCharsMap[filename]);\n }\n this._sourceMapGenerator.setSourceContent(this.normalizeFilename(filename), source);\n }\n }\n }\n\n this._rootNode.genCSS(context, this);\n\n if (this._css.length > 0) {\n let sourceMapURL;\n const sourceMapContent = JSON.stringify(this._sourceMapGenerator.toJSON());\n\n if (this.sourceMapURL) {\n sourceMapURL = this.sourceMapURL;\n } else if (this._sourceMapFilename) {\n sourceMapURL = this._sourceMapFilename;\n }\n this.sourceMapURL = sourceMapURL;\n\n this.sourceMap = sourceMapContent;\n }\n\n return this._css.join('');\n }\n }\n\n return SourceMapOutput;\n};\n","export default (SourceMapOutput, environment) => {\n class SourceMapBuilder {\n constructor(options) {\n this.options = options;\n }\n\n toCSS(rootNode, options, imports) {\n const sourceMapOutput = new SourceMapOutput(\n {\n contentsIgnoredCharsMap: imports.contentsIgnoredChars,\n rootNode,\n contentsMap: imports.contents,\n sourceMapFilename: this.options.sourceMapFilename,\n sourceMapURL: this.options.sourceMapURL,\n outputFilename: this.options.sourceMapOutputFilename,\n sourceMapBasepath: this.options.sourceMapBasepath,\n sourceMapRootpath: this.options.sourceMapRootpath,\n outputSourceFiles: this.options.outputSourceFiles,\n sourceMapGenerator: this.options.sourceMapGenerator,\n sourceMapFileInline: this.options.sourceMapFileInline\n });\n\n const css = sourceMapOutput.toCSS(options);\n this.sourceMap = sourceMapOutput.sourceMap;\n this.sourceMapURL = sourceMapOutput.sourceMapURL;\n if (this.options.sourceMapInputFilename) {\n this.sourceMapInputFilename = sourceMapOutput.normalizeFilename(this.options.sourceMapInputFilename);\n }\n if (this.options.sourceMapBasepath !== undefined && this.sourceMapURL !== undefined) {\n this.sourceMapURL = sourceMapOutput.removeBasepath(this.sourceMapURL);\n }\n return css + this.getCSSAppendage();\n }\n\n getCSSAppendage() {\n\n let sourceMapURL = this.sourceMapURL;\n if (this.options.sourceMapFileInline) {\n if (this.sourceMap === undefined) {\n return '';\n }\n sourceMapURL = `data:application/json;base64,${environment.encodeBase64(this.sourceMap)}`;\n }\n\n if (sourceMapURL) {\n return `/*# sourceMappingURL=${sourceMapURL} */`;\n }\n return '';\n }\n\n getExternalSourceMap() {\n return this.sourceMap;\n }\n\n setExternalSourceMap(sourceMap) {\n this.sourceMap = sourceMap;\n }\n\n isInline() {\n return this.options.sourceMapFileInline;\n }\n\n getSourceMapURL() {\n return this.sourceMapURL;\n }\n\n getOutputFilename() {\n return this.options.sourceMapOutputFilename;\n }\n\n getInputFilename() {\n return this.sourceMapInputFilename;\n }\n }\n\n return SourceMapBuilder;\n};\n","import LessError from './less-error';\nimport transformTree from './transform-tree';\nimport logger from './logger';\n\nexport default SourceMapBuilder => {\n class ParseTree {\n constructor(root, imports) {\n this.root = root;\n this.imports = imports;\n }\n\n toCSS(options) {\n let evaldRoot;\n const result = {};\n let sourceMapBuilder;\n try {\n evaldRoot = transformTree(this.root, options);\n } catch (e) {\n throw new LessError(e, this.imports);\n }\n\n try {\n const compress = Boolean(options.compress);\n if (compress) {\n logger.warn('The compress option has been deprecated. ' + \n 'We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');\n }\n\n const toCSSOptions = {\n compress,\n dumpLineNumbers: options.dumpLineNumbers,\n strictUnits: Boolean(options.strictUnits),\n numPrecision: 8};\n\n if (options.sourceMap) {\n sourceMapBuilder = new SourceMapBuilder(options.sourceMap);\n result.css = sourceMapBuilder.toCSS(evaldRoot, toCSSOptions, this.imports);\n } else {\n result.css = evaldRoot.toCSS(toCSSOptions);\n }\n } catch (e) {\n throw new LessError(e, this.imports);\n }\n\n if (options.pluginManager) {\n const postProcessors = options.pluginManager.getPostProcessors();\n for (let i = 0; i < postProcessors.length; i++) {\n result.css = postProcessors[i].process(result.css, { sourceMap: sourceMapBuilder, options, imports: this.imports });\n }\n }\n if (options.sourceMap) {\n result.map = sourceMapBuilder.getExternalSourceMap();\n }\n\n result.imports = [];\n for (const file in this.imports.files) {\n if (this.imports.files.hasOwnProperty(file) && file !== this.imports.rootFilename) {\n result.imports.push(file);\n }\n }\n return result;\n }\n }\n\n return ParseTree;\n};\n","import contexts from './contexts';\nimport Parser from './parser/parser';\nimport LessError from './less-error';\nimport * as utils from './utils';\nimport logger from './logger';\n\nexport default environment => {\n // FileInfo = {\n // 'rewriteUrls' - option - whether to adjust URL's to be relative\n // 'filename' - full resolved filename of current file\n // 'rootpath' - path to append to normal URLs for this node\n // 'currentDirectory' - path to the current file, absolute\n // 'rootFilename' - filename of the base file\n // 'entryPath' - absolute path to the entry file\n // 'reference' - whether the file should not be output and only output parts that are referenced\n\n class ImportManager {\n constructor(less, context, rootFileInfo) {\n this.less = less;\n this.rootFilename = rootFileInfo.filename;\n this.paths = context.paths || []; // Search paths, when importing\n this.contents = {}; // map - filename to contents of all the files\n this.contentsIgnoredChars = {}; // map - filename to lines at the beginning of each file to ignore\n this.mime = context.mime;\n this.error = null;\n this.context = context;\n // Deprecated? Unused outside of here, could be useful.\n this.queue = []; // Files which haven't been imported yet\n this.files = {}; // Holds the imported parse trees.\n }\n\n /**\n * Add an import to be imported\n * @param path - the raw path\n * @param tryAppendExtension - whether to try appending a file extension (.less or .js if the path has no extension)\n * @param currentFileInfo - the current file info (used for instance to work out relative paths)\n * @param importOptions - import options\n * @param callback - callback for when it is imported\n */\n push(path, tryAppendExtension, currentFileInfo, importOptions, callback) {\n const importManager = this;\n const pluginLoader = this.context.pluginManager.Loader;\n\n this.queue.push(path);\n\n const fileParsedFunc = (e, root, fullPath) => {\n importManager.queue.splice(importManager.queue.indexOf(path), 1); // Remove the path from the queue\n\n const importedEqualsRoot = fullPath === importManager.rootFilename;\n if (importOptions.optional && e) {\n callback(null, {rules:[]}, false, null);\n logger.info(`The file ${fullPath} was skipped because it was not found and the import was marked optional.`);\n }\n else {\n // Inline imports aren't cached here.\n // If we start to cache them, please make sure they won't conflict with non-inline imports of the\n // same name as they used to do before this comment and the condition below have been added.\n if (!importManager.files[fullPath] && !importOptions.inline) {\n importManager.files[fullPath] = { root, options: importOptions };\n }\n if (e && !importManager.error) { importManager.error = e; }\n callback(e, root, importedEqualsRoot, fullPath);\n }\n };\n\n const newFileInfo = {\n rewriteUrls: this.context.rewriteUrls,\n entryPath: currentFileInfo.entryPath,\n rootpath: currentFileInfo.rootpath,\n rootFilename: currentFileInfo.rootFilename\n };\n\n const fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);\n\n if (!fileManager) {\n fileParsedFunc({ message: `Could not find a file-manager for ${path}` });\n return;\n }\n\n const loadFileCallback = loadedFile => {\n let plugin;\n const resolvedFilename = loadedFile.filename;\n const contents = loadedFile.contents.replace(/^\\uFEFF/, '');\n\n // Pass on an updated rootpath if path of imported file is relative and file\n // is in a (sub|sup) directory\n //\n // Examples:\n // - If path of imported file is 'module/nav/nav.less' and rootpath is 'less/',\n // then rootpath should become 'less/module/nav/'\n // - If path of imported file is '../mixins.less' and rootpath is 'less/',\n // then rootpath should become 'less/../'\n newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);\n if (newFileInfo.rewriteUrls) {\n newFileInfo.rootpath = fileManager.join(\n (importManager.context.rootpath || ''),\n fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));\n\n if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {\n newFileInfo.rootpath = fileManager.join(newFileInfo.entryPath, newFileInfo.rootpath);\n }\n }\n newFileInfo.filename = resolvedFilename;\n\n const newEnv = new contexts.Parse(importManager.context);\n\n newEnv.processImports = false;\n importManager.contents[resolvedFilename] = contents;\n\n if (currentFileInfo.reference || importOptions.reference) {\n newFileInfo.reference = true;\n }\n\n if (importOptions.isPlugin) {\n plugin = pluginLoader.evalPlugin(contents, newEnv, importManager, importOptions.pluginArgs, newFileInfo);\n if (plugin instanceof LessError) {\n fileParsedFunc(plugin, null, resolvedFilename);\n }\n else {\n fileParsedFunc(null, plugin, resolvedFilename);\n }\n } else if (importOptions.inline) {\n fileParsedFunc(null, contents, resolvedFilename);\n } else {\n\n // import (multiple) parse trees apparently get altered and can't be cached.\n // TODO: investigate why this is\n if (importManager.files[resolvedFilename]\n && !importManager.files[resolvedFilename].options.multiple\n && !importOptions.multiple) {\n\n fileParsedFunc(null, importManager.files[resolvedFilename].root, resolvedFilename);\n }\n else {\n new Parser(newEnv, importManager, newFileInfo).parse(contents, (e, root) => {\n fileParsedFunc(e, root, resolvedFilename);\n });\n }\n }\n };\n let promise;\n const context = utils.clone(this.context);\n\n if (tryAppendExtension) {\n context.ext = importOptions.isPlugin ? '.js' : '.less';\n }\n\n if (importOptions.isPlugin) {\n context.mime = 'application/javascript';\n promise = pluginLoader.loadPlugin(path, currentFileInfo.currentDirectory, context, environment, fileManager);\n }\n else {\n promise = fileManager.loadFile(path, currentFileInfo.currentDirectory, context, environment,\n (err, loadedFile) => {\n if (err) {\n fileParsedFunc(err);\n } else {\n loadFileCallback(loadedFile);\n }\n });\n }\n if (promise) {\n promise.then(loadFileCallback, fileParsedFunc);\n }\n }\n }\n\n return ImportManager;\n};\n","let PromiseConstructor;\nimport * as utils from './utils';\n\nexport default (environment, ParseTree, ImportManager) => {\n const render = function (input, options, callback) {\n if (typeof options === 'function') {\n callback = options;\n options = utils.copyOptions(this.options, {});\n }\n else {\n options = utils.copyOptions(this.options, options || {});\n }\n\n if (!callback) {\n const self = this;\n return new Promise((resolve, reject) => {\n render.call(self, input, options, (err, output) => {\n if (err) {\n reject(err);\n } else {\n resolve(output);\n }\n });\n });\n } else {\n this.parse(input, options, (err, root, imports, options) => {\n if (err) { return callback(err); }\n\n let result;\n try {\n const parseTree = new ParseTree(root, imports);\n result = parseTree.toCSS(options);\n }\n catch (err) { return callback(err); }\n\n callback(null, result);\n });\n }\n };\n\n return render;\n};\n","let PromiseConstructor;\nimport contexts from './contexts';\nimport Parser from './parser/parser';\nimport PluginManager from './plugin-manager';\nimport LessError from './less-error';\nimport * as utils from './utils';\n\nexport default (environment, ParseTree, ImportManager) => {\n const parse = function (input, options, callback) {\n\n if (typeof options === 'function') {\n callback = options;\n options = utils.copyOptions(this.options, {});\n }\n else {\n options = utils.copyOptions(this.options, options || {});\n }\n\n if (!callback) {\n const self = this;\n return new Promise((resolve, reject) => {\n parse.call(self, input, options, (err, output) => {\n if (err) {\n reject(err);\n } else {\n resolve(output);\n }\n });\n });\n } else {\n let context;\n let rootFileInfo;\n const pluginManager = new PluginManager(this, !options.reUsePluginManager);\n\n options.pluginManager = pluginManager;\n\n context = new contexts.Parse(options);\n\n if (options.rootFileInfo) {\n rootFileInfo = options.rootFileInfo;\n } else {\n const filename = options.filename || 'input';\n const entryPath = filename.replace(/[^\\/\\\\]*$/, '');\n rootFileInfo = {\n filename,\n rewriteUrls: context.rewriteUrls,\n rootpath: context.rootpath || '',\n currentDirectory: entryPath,\n entryPath,\n rootFilename: filename\n };\n // add in a missing trailing slash\n if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {\n rootFileInfo.rootpath += '/';\n }\n }\n\n const imports = new ImportManager(this, context, rootFileInfo);\n this.importManager = imports;\n\n // TODO: allow the plugins to be just a list of paths or names\n // Do an async plugin queue like lessc\n\n if (options.plugins) {\n options.plugins.forEach(plugin => {\n let evalResult;\n let contents;\n if (plugin.fileContent) {\n contents = plugin.fileContent.replace(/^\\uFEFF/, '');\n evalResult = pluginManager.Loader.evalPlugin(contents, context, imports, plugin.options, plugin.filename);\n if (evalResult instanceof LessError) {\n return callback(evalResult);\n }\n }\n else {\n pluginManager.addPlugin(plugin);\n }\n });\n }\n\n new Parser(context, imports, rootFileInfo)\n .parse(input, (e, root) => {\n if (e) { return callback(e); }\n callback(null, root, imports, options);\n }, options);\n }\n };\n return parse;\n};\n","// TODO: Add tests for browser @plugin\n/* global window */\n\nimport AbstractPluginLoader from '../less/environment/abstract-plugin-loader.js';\n\n/**\n * Browser Plugin Loader\n */\nclass PluginLoader extends AbstractPluginLoader {\n constructor(less) {\n super();\n\n this.less = less;\n // Should we shim this.require for browser? Probably not?\n }\n\n loadPlugin(filename, basePath, context, environment, fileManager) {\n return new Promise((fulfill, reject) => {\n fileManager.loadFile(filename, basePath, context, environment)\n .then(fulfill).catch(reject);\n });\n }\n}\n\nexport default PluginLoader;\n\n","import * as utils from './utils';\nimport browser from './browser';\n\nexport default (window, less, options) => {\n\n function errorHTML(e, rootHref) {\n const id = `less-error-message:${utils.extractId(rootHref || '')}`;\n const template = '
  • {content}
  • ';\n const elem = window.document.createElement('div');\n let timer;\n let content;\n const errors = [];\n const filename = e.filename || rootHref;\n const filenameNoPath = filename.match(/([^\\/]+(\\?.*)?)$/)[1];\n\n elem.id = id;\n elem.className = 'less-error-message';\n\n content = `

    ${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'}` + \n `

    in ${filenameNoPath} `;\n\n const errorline = (e, i, classname) => {\n if (e.extract[i] !== undefined) {\n errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n .replace(/\\{class\\}/, classname)\n .replace(/\\{content\\}/, e.extract[i]));\n }\n };\n\n if (e.line) {\n errorline(e, 0, '');\n errorline(e, 1, 'line');\n errorline(e, 2, '');\n content += `on line ${e.line}, column ${e.column + 1}:

      ${errors.join('')}
    `;\n }\n if (e.stack && (e.extract || options.logLevel >= 4)) {\n content += `
    Stack Trace
    ${e.stack.split('\\n').slice(1).join('
    ')}`;\n }\n elem.innerHTML = content;\n\n // CSS for error messages\n browser.createCSS(window.document, [\n '.less-error-message ul, .less-error-message li {',\n 'list-style-type: none;',\n 'margin-right: 15px;',\n 'padding: 4px 0;',\n 'margin: 0;',\n '}',\n '.less-error-message label {',\n 'font-size: 12px;',\n 'margin-right: 15px;',\n 'padding: 4px 0;',\n 'color: #cc7777;',\n '}',\n '.less-error-message pre {',\n 'color: #dd6666;',\n 'padding: 4px 0;',\n 'margin: 0;',\n 'display: inline-block;',\n '}',\n '.less-error-message pre.line {',\n 'color: #ff0000;',\n '}',\n '.less-error-message h3 {',\n 'font-size: 20px;',\n 'font-weight: bold;',\n 'padding: 15px 0 5px 0;',\n 'margin: 0;',\n '}',\n '.less-error-message a {',\n 'color: #10a',\n '}',\n '.less-error-message .error {',\n 'color: red;',\n 'font-weight: bold;',\n 'padding-bottom: 2px;',\n 'border-bottom: 1px dashed red;',\n '}'\n ].join('\\n'), { title: 'error-message' });\n\n elem.style.cssText = [\n 'font-family: Arial, sans-serif',\n 'border: 1px solid #e00',\n 'background-color: #eee',\n 'border-radius: 5px',\n '-webkit-border-radius: 5px',\n '-moz-border-radius: 5px',\n 'color: #e00',\n 'padding: 15px',\n 'margin-bottom: 15px'\n ].join(';');\n\n if (options.env === 'development') {\n timer = setInterval(() => {\n const document = window.document;\n const body = document.body;\n if (body) {\n if (document.getElementById(id)) {\n body.replaceChild(elem, document.getElementById(id));\n } else {\n body.insertBefore(elem, body.firstChild);\n }\n clearInterval(timer);\n }\n }, 10);\n }\n }\n\n function removeErrorHTML(path) {\n const node = window.document.getElementById(`less-error-message:${utils.extractId(path)}`);\n if (node) {\n node.parentNode.removeChild(node);\n }\n }\n\n function removeErrorConsole(path) {\n // no action\n }\n\n function removeError(path) {\n if (!options.errorReporting || options.errorReporting === 'html') {\n removeErrorHTML(path);\n } else if (options.errorReporting === 'console') {\n removeErrorConsole(path);\n } else if (typeof options.errorReporting === 'function') {\n options.errorReporting('remove', path);\n }\n }\n\n function errorConsole(e, rootHref) {\n const template = '{line} {content}';\n const filename = e.filename || rootHref;\n const errors = [];\n let content = `${e.type || 'Syntax'}Error: ${e.message || 'There is an error in your .less file'} in ${filename}`;\n\n const errorline = (e, i, classname) => {\n if (e.extract[i] !== undefined) {\n errors.push(template.replace(/\\{line\\}/, (parseInt(e.line, 10) || 0) + (i - 1))\n .replace(/\\{class\\}/, classname)\n .replace(/\\{content\\}/, e.extract[i]));\n }\n };\n\n if (e.line) {\n errorline(e, 0, '');\n errorline(e, 1, 'line');\n errorline(e, 2, '');\n content += ` on line ${e.line}, column ${e.column + 1}:\\n${errors.join('\\n')}`;\n }\n if (e.stack && (e.extract || options.logLevel >= 4)) {\n content += `\\nStack Trace\\n${e.stack}`;\n }\n less.logger.error(content);\n }\n\n function error(e, rootHref) {\n if (!options.errorReporting || options.errorReporting === 'html') {\n errorHTML(e, rootHref);\n } else if (options.errorReporting === 'console') {\n errorConsole(e, rootHref);\n } else if (typeof options.errorReporting === 'function') {\n options.errorReporting('add', e, rootHref);\n }\n }\n\n return {\n add: error,\n remove: removeError\n };\n};\n","/**\n * Kicks off less and compiles any stylesheets\n * used in the browser distributed version of less\n * to kick-start less using the browser api\n */\n/* global window, document */\n\nimport defaultOptions from '../less/default-options';\nimport addDefaultOptions from './add-default-options';\nimport root from './index';\n\nconst options = defaultOptions();\n\nif (window.less) {\n for (const key in window.less) {\n if (window.less.hasOwnProperty(key)) {\n options[key] = window.less[key];\n }\n }\n}\naddDefaultOptions(window, options);\n\noptions.plugins = options.plugins || [];\n\nif (window.LESS_PLUGINS) {\n options.plugins = options.plugins.concat(window.LESS_PLUGINS);\n}\n\nconst less = root(window, options);\nexport default less;\n\nwindow.less = less;\n\nlet css;\nlet head;\nlet style;\n\n// Always restore page visibility\nfunction resolveOrReject(data) {\n if (data.filename) {\n console.warn(data);\n }\n if (!options.async) {\n head.removeChild(style);\n }\n}\n\nif (options.onReady) {\n if (/!watch/.test(window.location.hash)) {\n less.watch();\n }\n // Simulate synchronous stylesheet loading by hiding page rendering\n if (!options.async) {\n css = 'body { display: none !important }';\n head = document.head || document.getElementsByTagName('head')[0];\n style = document.createElement('style');\n\n style.type = 'text/css';\n if (style.styleSheet) {\n style.styleSheet.cssText = css;\n } else {\n style.appendChild(document.createTextNode(css));\n }\n\n head.appendChild(style);\n }\n less.registerStylesheetsImmediately();\n less.pageLoadFinished = less.refresh(less.env === 'development').then(resolveOrReject, resolveOrReject);\n}\n","// Export a new default each time\nexport default () => ({\n /* Inline Javascript - @plugin still allowed */\n javascriptEnabled: false,\n\n /* Outputs a makefile import dependency list to stdout. */\n depends: false,\n\n /* (DEPRECATED) Compress using less built-in compression. \n * This does an okay job but does not utilise all the tricks of \n * dedicated css compression. */\n compress: false,\n\n /* Runs the less parser and just reports errors without any output. */\n lint: false,\n\n /* Sets available include paths.\n * If the file in an @import rule does not exist at that exact location, \n * less will look for it at the location(s) passed to this option. \n * You might use this for instance to specify a path to a library which \n * you want to be referenced simply and relatively in the less files. */\n paths: [],\n\n /* color output in the terminal */\n color: true,\n\n /* The strictImports controls whether the compiler will allow an @import inside of either \n * @media blocks or (a later addition) other selector blocks.\n * See: https://github.com/less/less.js/issues/656 */\n strictImports: false,\n\n /* Allow Imports from Insecure HTTPS Hosts */\n insecure: false,\n\n /* Allows you to add a path to every generated import and url in your css. \n * This does not affect less import statements that are processed, just ones \n * that are left in the output css. */\n rootpath: '',\n\n /* By default URLs are kept as-is, so if you import a file in a sub-directory \n * that references an image, exactly the same URL will be output in the css. \n * This option allows you to re-write URL's in imported files so that the \n * URL is always relative to the base imported file */\n rewriteUrls: false,\n\n /* How to process math \n * 0 always - eagerly try to solve all operations\n * 1 parens-division - require parens for division \"/\"\n * 2 parens | strict - require parens for all operations\n * 3 strict-legacy - legacy strict behavior (super-strict)\n */\n math: 0,\n\n /* Without this option, less attempts to guess at the output unit when it does maths. */\n strictUnits: false,\n\n /* Effectively the declaration is put at the top of your base Less file, \n * meaning it can be used but it also can be overridden if this variable \n * is defined in the file. */\n globalVars: null,\n\n /* As opposed to the global variable option, this puts the declaration at the\n * end of your base file, meaning it will override anything defined in your Less file. */\n modifyVars: null,\n\n /* This option allows you to specify a argument to go on to every URL. */\n urlArgs: ''\n});","import {addDataAttr} from './utils';\nimport browser from './browser';\n\nexport default (window, options) => {\n\n // use options from the current script tag data attribues\n addDataAttr(options, browser.currentScript(window));\n\n if (options.isFileProtocol === undefined) {\n options.isFileProtocol = /^(file|(chrome|safari)(-extension)?|resource|qrc|app):/.test(window.location.protocol);\n }\n\n // Load styles asynchronously (default: false)\n //\n // This is set to `false` by default, so that the body\n // doesn't start loading before the stylesheets are parsed.\n // Setting this to `true` can result in flickering.\n //\n options.async = options.async || false;\n options.fileAsync = options.fileAsync || false;\n\n // Interval between watch polls\n options.poll = options.poll || (options.isFileProtocol ? 1000 : 1500);\n\n options.env = options.env || (window.location.hostname == '127.0.0.1' ||\n window.location.hostname == '0.0.0.0' ||\n window.location.hostname == 'localhost' ||\n (window.location.port &&\n window.location.port.length > 0) ||\n options.isFileProtocol ? 'development'\n : 'production');\n\n const dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(window.location.hash);\n if (dumpLineNumbers) {\n options.dumpLineNumbers = dumpLineNumbers[1];\n }\n\n if (options.useFileCache === undefined) {\n options.useFileCache = true;\n }\n\n if (options.onReady === undefined) {\n options.onReady = true;\n }\n\n if (options.relativeUrls) {\n options.rewriteUrls = 'all';\n }\n};\n","//\n// index.js\n// Should expose the additional browser functions on to the less object\n//\nimport {addDataAttr} from './utils';\nimport lessRoot from '../less';\nimport browser from './browser';\nimport FM from './file-manager';\nimport PluginLoader from './plugin-loader';\nimport LogListener from './log-listener';\nimport ErrorReporting from './error-reporting';\nimport Cache from './cache';\nimport ImageSize from './image-size';\n\nexport default (window, options) => {\n const document = window.document;\n const less = lessRoot();\n\n less.options = options;\n const environment = less.environment;\n const FileManager = FM(options, less.logger);\n const fileManager = new FileManager();\n environment.addFileManager(fileManager);\n less.FileManager = FileManager;\n less.PluginLoader = PluginLoader;\n\n LogListener(less, options);\n const errors = ErrorReporting(window, less, options);\n const cache = less.cache = options.cache || Cache(window, options, less.logger);\n ImageSize(less.environment);\n\n // Setup user functions - Deprecate?\n if (options.functions) {\n less.functions.functionRegistry.addMultiple(options.functions);\n }\n\n const typePattern = /^text\\/(x-)?less$/;\n\n function clone(obj) {\n const cloned = {};\n for (const prop in obj) {\n if (obj.hasOwnProperty(prop)) {\n cloned[prop] = obj[prop];\n }\n }\n return cloned;\n }\n\n // only really needed for phantom\n function bind(func, thisArg) {\n const curryArgs = Array.prototype.slice.call(arguments, 2);\n return function() {\n const args = curryArgs.concat(Array.prototype.slice.call(arguments, 0));\n return func.apply(thisArg, args);\n };\n }\n\n function loadStyles(modifyVars) {\n const styles = document.getElementsByTagName('style');\n let style;\n\n for (let i = 0; i < styles.length; i++) {\n style = styles[i];\n if (style.type.match(typePattern)) {\n const instanceOptions = clone(options);\n instanceOptions.modifyVars = modifyVars;\n const lessText = style.innerHTML || '';\n instanceOptions.filename = document.location.href.replace(/#.*$/, '');\n\n /* jshint loopfunc:true */\n // use closure to store current style\n less.render(lessText, instanceOptions,\n bind((style, e, result) => {\n if (e) {\n errors.add(e, 'inline');\n } else {\n style.type = 'text/css';\n if (style.styleSheet) {\n style.styleSheet.cssText = result.css;\n } else {\n style.innerHTML = result.css;\n }\n }\n }, null, style));\n }\n }\n }\n\n function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {\n\n const instanceOptions = clone(options);\n addDataAttr(instanceOptions, sheet);\n instanceOptions.mime = sheet.type;\n\n if (modifyVars) {\n instanceOptions.modifyVars = modifyVars;\n }\n\n function loadInitialFileCallback(loadedFile) {\n const data = loadedFile.contents;\n const path = loadedFile.filename;\n const webInfo = loadedFile.webInfo;\n\n const newFileInfo = {\n currentDirectory: fileManager.getPath(path),\n filename: path,\n rootFilename: path,\n rewriteUrls: instanceOptions.rewriteUrls\n };\n\n newFileInfo.entryPath = newFileInfo.currentDirectory;\n newFileInfo.rootpath = instanceOptions.rootpath || newFileInfo.currentDirectory;\n\n if (webInfo) {\n webInfo.remaining = remaining;\n\n const css = cache.getCSS(path, webInfo, instanceOptions.modifyVars);\n if (!reload && css) {\n webInfo.local = true;\n callback(null, css, data, sheet, webInfo, path);\n return;\n }\n\n }\n\n // TODO add tests around how this behaves when reloading\n errors.remove(path);\n\n instanceOptions.rootFileInfo = newFileInfo;\n less.render(data, instanceOptions, (e, result) => {\n if (e) {\n e.href = path;\n callback(e);\n } else {\n cache.setCSS(sheet.href, webInfo.lastModified, instanceOptions.modifyVars, result.css);\n callback(null, result.css, data, sheet, webInfo, path);\n }\n });\n }\n\n fileManager.loadFile(sheet.href, null, instanceOptions, environment)\n .then(loadedFile => {\n loadInitialFileCallback(loadedFile);\n }).catch(err => {\n console.log(err);\n callback(err);\n });\n\n }\n\n function loadStyleSheets(callback, reload, modifyVars) {\n for (let i = 0; i < less.sheets.length; i++) {\n loadStyleSheet(less.sheets[i], callback, reload, less.sheets.length - (i + 1), modifyVars);\n }\n }\n\n function initRunningMode() {\n if (less.env === 'development') {\n less.watchTimer = setInterval(() => {\n if (less.watchMode) {\n fileManager.clearFileCache();\n loadStyleSheets((e, css, _, sheet, webInfo) => {\n if (e) {\n errors.add(e, e.href || sheet.href);\n } else if (css) {\n browser.createCSS(window.document, css, sheet);\n }\n });\n }\n }, options.poll);\n }\n }\n\n //\n // Watch mode\n //\n less.watch = function () {\n if (!less.watchMode ) {\n less.env = 'development';\n initRunningMode();\n }\n this.watchMode = true;\n return true;\n };\n\n less.unwatch = function () {clearInterval(less.watchTimer); this.watchMode = false; return false; };\n\n //\n // Synchronously get all tags with the 'rel' attribute set to\n // \"stylesheet/less\".\n //\n less.registerStylesheetsImmediately = () => {\n const links = document.getElementsByTagName('link');\n less.sheets = [];\n\n for (let i = 0; i < links.length; i++) {\n if (links[i].rel === 'stylesheet/less' || (links[i].rel.match(/stylesheet/) &&\n (links[i].type.match(typePattern)))) {\n less.sheets.push(links[i]);\n }\n }\n };\n\n //\n // Asynchronously get all tags with the 'rel' attribute set to\n // \"stylesheet/less\", returning a Promise.\n //\n less.registerStylesheets = () => new Promise((resolve, reject) => {\n less.registerStylesheetsImmediately();\n resolve();\n });\n\n //\n // With this function, it's possible to alter variables and re-render\n // CSS without reloading less-files\n //\n less.modifyVars = record => less.refresh(true, record, false);\n\n less.refresh = (reload, modifyVars, clearFileCache) => {\n if ((reload || clearFileCache) && clearFileCache !== false) {\n fileManager.clearFileCache();\n }\n return new Promise((resolve, reject) => {\n let startTime;\n let endTime;\n let totalMilliseconds;\n let remainingSheets;\n startTime = endTime = new Date();\n\n // Set counter for remaining unprocessed sheets\n remainingSheets = less.sheets.length;\n\n if (remainingSheets === 0) {\n\n endTime = new Date();\n totalMilliseconds = endTime - startTime;\n less.logger.info('Less has finished and no sheets were loaded.');\n resolve({\n startTime,\n endTime,\n totalMilliseconds,\n sheets: less.sheets.length\n });\n\n } else {\n // Relies on less.sheets array, callback seems to be guaranteed to be called for every element of the array\n loadStyleSheets((e, css, _, sheet, webInfo) => {\n if (e) {\n errors.add(e, e.href || sheet.href);\n reject(e);\n return;\n }\n if (webInfo.local) {\n less.logger.info(`Loading ${sheet.href} from cache.`);\n } else {\n less.logger.info(`Rendered ${sheet.href} successfully.`);\n }\n browser.createCSS(window.document, css, sheet);\n less.logger.info(`CSS for ${sheet.href} generated in ${new Date() - endTime}ms`);\n\n // Count completed sheet\n remainingSheets--;\n\n // Check if the last remaining sheet was processed and then call the promise\n if (remainingSheets === 0) {\n totalMilliseconds = new Date() - startTime;\n less.logger.info(`Less has finished. CSS generated in ${totalMilliseconds}ms`);\n resolve({\n startTime,\n endTime,\n totalMilliseconds,\n sheets: less.sheets.length\n });\n }\n endTime = new Date();\n }, reload, modifyVars);\n }\n\n loadStyles(modifyVars);\n });\n };\n\n less.refreshStyles = loadStyles;\n return less;\n};\n","export default (less, options) => {\n const logLevel_debug = 4;\n const logLevel_info = 3;\n const logLevel_warn = 2;\n const logLevel_error = 1;\n\n // The amount of logging in the javascript console.\n // 3 - Debug, information and errors\n // 2 - Information and errors\n // 1 - Errors\n // 0 - None\n // Defaults to 2\n options.logLevel = typeof options.logLevel !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_info : logLevel_error);\n\n if (!options.loggers) {\n options.loggers = [{\n debug: function(msg) {\n if (options.logLevel >= logLevel_debug) {\n console.log(msg);\n }\n },\n info: function(msg) {\n if (options.logLevel >= logLevel_info) {\n console.log(msg);\n }\n },\n warn: function(msg) {\n if (options.logLevel >= logLevel_warn) {\n console.warn(msg);\n }\n },\n error: function(msg) {\n if (options.logLevel >= logLevel_error) {\n console.error(msg);\n }\n }\n }];\n }\n for (let i = 0; i < options.loggers.length; i++) {\n less.logger.addListener(options.loggers[i]);\n }\n};\n","// Cache system is a bit outdated and could do with work\n\nexport default (window, options, logger) => {\n let cache = null;\n if (options.env !== 'development') {\n try {\n cache = (typeof window.localStorage === 'undefined') ? null : window.localStorage;\n } catch (_) {}\n }\n return {\n setCSS: function(path, lastModified, modifyVars, styles) {\n if (cache) {\n logger.info(`saving ${path} to cache.`);\n try {\n cache.setItem(path, styles);\n cache.setItem(`${path}:timestamp`, lastModified);\n if (modifyVars) {\n cache.setItem(`${path}:vars`, JSON.stringify(modifyVars));\n }\n } catch (e) {\n // TODO - could do with adding more robust error handling\n logger.error(`failed to save \"${path}\" to local storage for caching.`);\n }\n }\n },\n getCSS: function(path, webInfo, modifyVars) {\n const css = cache && cache.getItem(path);\n const timestamp = cache && cache.getItem(`${path}:timestamp`);\n let vars = cache && cache.getItem(`${path}:vars`);\n\n modifyVars = modifyVars || {};\n vars = vars || \"{}\"; // if not set, treat as the JSON representation of an empty object\n\n if (timestamp && webInfo.lastModified &&\n (new Date(webInfo.lastModified).valueOf() ===\n new Date(timestamp).valueOf()) &&\n JSON.stringify(modifyVars) === vars) {\n // Use local copy\n return css;\n }\n }\n };\n};\n","\nimport functionRegistry from './../less/functions/function-registry';\n\nexport default () => {\n function imageSize() {\n throw {\n type: 'Runtime',\n message: 'Image size functions are not supported in browser version of less'\n };\n }\n\n const imageFunctions = {\n 'image-size': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n },\n 'image-width': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n },\n 'image-height': function(filePathNode) {\n imageSize(this, filePathNode);\n return -1;\n }\n };\n\n functionRegistry.addMultiple(imageFunctions);\n};\n"],"names":["extractId","href","replace","addDataAttr","options","tag","opt","dataset","hasOwnProperty","JSON","parse","_","document","styles","sheet","id","title","utils.extractId","oldStyleNode","getElementById","keepOldStyleNode","styleNode","createElement","setAttribute","media","styleSheet","appendChild","createTextNode","childNodes","length","firstChild","nodeValue","head","getElementsByTagName","nextEl","nextSibling","parentNode","insertBefore","removeChild","cssText","e","Error","window","scripts","currentScript","aliceblue","antiquewhite","aqua","aquamarine","azure","beige","bisque","black","blanchedalmond","blue","blueviolet","brown","burlywood","cadetblue","chartreuse","chocolate","coral","cornflowerblue","cornsilk","crimson","cyan","darkblue","darkcyan","darkgoldenrod","darkgray","darkgrey","darkgreen","darkkhaki","darkmagenta","darkolivegreen","darkorange","darkorchid","darkred","darksalmon","darkseagreen","darkslateblue","darkslategray","darkslategrey","darkturquoise","darkviolet","deeppink","deepskyblue","dimgray","dimgrey","dodgerblue","firebrick","floralwhite","forestgreen","fuchsia","gainsboro","ghostwhite","gold","goldenrod","gray","grey","green","greenyellow","honeydew","hotpink","indianred","indigo","ivory","khaki","lavender","lavenderblush","lawngreen","lemonchiffon","lightblue","lightcoral","lightcyan","lightgoldenrodyellow","lightgray","lightgrey","lightgreen","lightpink","lightsalmon","lightseagreen","lightskyblue","lightslategray","lightslategrey","lightsteelblue","lightyellow","lime","limegreen","linen","magenta","maroon","mediumaquamarine","mediumblue","mediumorchid","mediumpurple","mediumseagreen","mediumslateblue","mediumspringgreen","mediumturquoise","mediumvioletred","midnightblue","mintcream","mistyrose","moccasin","navajowhite","navy","oldlace","olive","olivedrab","orange","orangered","orchid","palegoldenrod","palegreen","paleturquoise","palevioletred","papayawhip","peachpuff","peru","pink","plum","powderblue","purple","rebeccapurple","red","rosybrown","royalblue","saddlebrown","salmon","sandybrown","seagreen","seashell","sienna","silver","skyblue","slateblue","slategray","slategrey","snow","springgreen","steelblue","tan","teal","thistle","tomato","turquoise","violet","wheat","white","whitesmoke","yellow","yellowgreen","m","cm","mm","in","px","pt","pc","duration","s","ms","angle","rad","Math","PI","deg","grad","turn","colors","unitConversions","this","parent","visibilityBlocks","undefined","nodeVisible","rootNode","parsed","self","Object","defineProperty","get","fileInfo","getIndex","Node","nodes","set","node","Array","isArray","forEach","_index","_fileInfo","context","strs","genCSS","add","chunk","index","push","isEmpty","join","output","value","visitor","visit","op","a","b","precision","numPrecision","Number","toFixed","info","compare","type","i_1","numericCompare","rgb","originalForm","_super","_this","match","map","c","i","parseInt","alpha","split","__extends","Color","r","g","pow","toCSS","doNotCompress","color","colorFunction","compress","args","fround","indexOf","clamp","round","concat","toHSL","h","l","toRGB","splitcolor","other","_operate","toHex","max","min","d","v","x","toString","prototype","fromKeyword","keyword","key","toLowerCase","slice","Paren","eval","_noSpaceCombinators"," ","|","emptyOrWhitespace","trim","Combinator","spaceOrEmpty","combinator","isVariable","currentFileInfo","visibilityInfo","copyVisibilityInfo","setParent","Element","firstSelector","charAt","ALWAYS","PARENS_DIVISION","PARENS","STRICT_LEGACY","RewriteUrls","clone","_instanceof","obj","nativeMap","nativeSet","nativePromise","Map","Set","Promise","circular","depth","includeNonEnumerable","allParents","allChildren","useBuffer","Buffer","Infinity","_clone","child","proto","resolve","reject","then","err","__isArray","__isRegExp","RegExp","source","__getRegExpFlags","lastIndex","__isDate","Date","getTime","isBuffer","allocUnsafe","copy","create","getPrototypeOf","keyChild","valueChild","entryChild","attrs","getOwnPropertyDescriptor","getOwnPropertySymbols","symbols","symbol","descriptor","enumerable","allPropertyNames","getOwnPropertyNames","propertyName","__objToStr","o","call","re","flags","global","ignoreCase","multiline","clonePrototype","module","exports","getLocation","inputStream","n","line","column","copyArray","arr","cloned","prop","defaults","obj1","obj2","newObj","_defaults","defaults_1","CloneHelper","assign","copyOptions","opts","strictMath","math","Constants.Math","relativeUrls","rewriteUrls","Constants.RewriteUrls","flattenArray","result","length_1","anonymousFunc","LessError","fileContentMap","currentFilename","filename","message","stack","input","contents","loc","utils.getLocation","col","callLine","lines","found","func","Function","lineAdjust","callExtract","extract","F","constructor","error","stylize","str","errorTxt","substr","elements","extendList","condition","evaldCondition","getElements","mixinElements_","Selector","visitArray","newSelector","mediaEmpty","els","parseNode","imports","sels","olen","len","mixinElements","shift","extend","createDerived","Value","Keyword","True","False","mapLines","rulesetLike","allowRoot","Anonymous","Boolean","MATH","name","important","merge","inline","variable","Declaration","lastRule","prevMath","evaldValue","mathBypass","evalName","importantScope","importantResult","pop","debugInfo","ctx","lineSeparator","dumpLineNumbers","asComment","asMediaQuery","lineNumber","fileName","filenameWithProtocol","test","isLineComment","Comment","getDebugInfo","isCompressed","contexts","copyFromOriginal","original","destination","propertiesToCopy","parseCopyProperties","Parse","paths","evalCopyProperties","isPathRelative","path","isPathLocalRelative","Eval","frames","inCalc","mathOn","calcStack","parensStack","rootpath","newPath","normalizePath","segment","segments","reverse","makeRegistry","base","_data","addMultiple","functions","keys","getLocalFunctions","inherit","defaultFunc","value_","error_","reset","selectors","rules","strictImports","_lookups","_variables","_properties","Ruleset","selCnt","selector","hasVariable","hasOnePassingSelector","j","toParseSelectors","utils.flattenArray","rule","subRule","utils.copyArray","ruleset","originalRuleset","root","firstRoot","allowImports","functionRegistry","globalFunctionRegistry","ctxFrames","unshift","ctxSelectors","evalImports","rsRules","evalFirst","mediaBlockCount","mediaBlocks","filter","splice","resetCache","isJustParentSelector","bubbleSelectors","importRules","makeImportant","lastSelector","_rulesets","reduce","hash","variables","vars","name_1","name_2","decl","parseValue","properties","toParse","transformDeclaration","nodes_1","filtRules","isRuleset","foundMixins","rulesets","find","i_2","apply","ruleNodes","tabLevel","sep","tabRuleStr","tabSetStr","charsetNodeIndex","importNodeIndex","isCharset","pathCnt","pathSubCnt","currentLastRule","isRulesetLike","isVisible","joinSelector","createParenthesis","elementsToPak","originalElement","replacementParen","insideParent","createSelector","containedElement","element","addReplacementIntoPath","beginningPath","addPath","replacedElement","originalSelector","newSelectorPath","newJoinedSelector","parentEl","restOfPath","addAllReplacementsIntoPath","addPaths","mergeElementsOnToSelectors","sel","deriveSelector","deriveFrom","newPaths","replaceParentSelector","inSelector","k","currentElements","newSelectors","selectorsMultiplied","el","maybeSelector","hadParentSelector","nestedSelector","replaced","nestedPaths","replacedNewSelectors","concatenated","bind","isRooted","createEmptySelectors","AtRule","outputRuleset","mediaPathBackup","mediaBlocksBackup","mediaPath","_i","ruleCnt","DetachedRuleset","numerator","denominator","backupUnit","sort","Unit","strictUnits","returnStr","is","unitString","toUpperCase","callback","group","mapUnit","groupName","atomicUnit","counter","count","unit","parseFloat","isNaN","Dimension","isSingular","strValue","String","isLength","convertTo","usedUnits","cancel","unify","conversions","targetUnit","applyUnit","derivedConversions","operands","isSpaced","Operation","isMathOn","toColor","operate","noSpacing","Expression","returnValue","inParenthesis","parens","parensInOp","doubleParen","outOfParenthesis","functionCaller","item","subNodes","calc","Call","currentMathContext","enterCalc","exitCalc","funcCaller","FunctionCaller","isValid","columnNumber","Variable","evaluating","frame","fun","Property","property","mergeRules","pluginManager","less","visitors","ToCSSVisitor","_mergeRules","vArr","Attribute","content","escaped","quote","variableRegex","propRegex","Quoted","that","iterativeReplace","regexp","replacementFnc","evaluatedValue","val","isEvald","URL","pathRequiresRewrite","rewritePath","urlArgs","features","Media","evalTop","evalNested","multiMedia","permute","fragment","rest","css","pathValue","getPath","Import","isPlugin","reference","containsVariables","doEval","blocksVisibility","addVisibilityBlock","registry","skip","importedFilename","newImport","evalPath","string","expression","JavaScript","evaluateJavaScript","JsEvalNode","evalContext","javascriptEnabled","jsify","toJS","Assignment","negate","lvalue","rvalue","Condition","UnicodeDescriptor","Negative","option","object_id","Extend","next_id","parent_ids","allowBefore","allowAfter","selectorElements","selfElements","selfSelectors","VariableCall","detachedRuleset","callEval","ruleCall","lookups","NamespaceValue","lastDeclaration","substring","params","variadic","arity","optionalParameters","required","p","Definition","mixinEnv","evaldArguments","varargs","arg","isNamedFound","argIndex","argsLength","prependRule","_arguments","mixinFrames","evalParams","allArgsCnt","requiredArgsCnt","arguments","MixinCall","mixins","mixin","mixinPath","argValue","f","isRecursive","isOneFound","candidate","defaultResult","noArgumentsFilter","candidates","conditionResult","calcDefGroup","namespace","matchCondition","expand","matchArgs","MixinDefinition","format","newRules","evalCall","_setVisibilityToReplacement","replacement","msg","_fireEvent","warn","debug","addListener","listener","_listeners","removeListener","logFunction","externalEnvironment","fileManagers","requiredFunctions","propName","environmentFunc","environment","currentDirectory","isSync","logger","getFileManagers","fileManager","AbstractFileManager","lastIndexOf","ext","extPos","isPathWithExtension","tryAppendExtension","basePath","laterPath","url","baseUrl","urlDirectories","baseUrlDirectories","urlParts","extractUrlParts","baseUrlParts","diff","hostPart","directories","urlPartsRegex","returner","rawDirectories","rawPath","fileUrl","require","AbstractPluginLoader","pluginOptions","pluginObj","localModule","shortname","FileManager","trySetOptions","use","loader","tree","validatePlugin","minVersion","compareVersion","addPlugin","plugin","setOptions","version","versionToString","aVersion","bVersion","versionString","plugins","i_3","printUsage","_visitArgs","visitDeeper","_hasIndexed","_noop","implementation","_implementation","_visitInCache","_visitOutCache","indexNodeTypes","ticker","typeIndex","Visitor","nodeTypeIndex","fnName","impl","funcOut","visitArgs","newNode","isReplacing","cnt","accept","nonReplacing","out","evald","flatten","nestedCnt","nestedItem","onSequencerEmpty","variableImports","_onSequencerEmpty","_currentDepth","ImportSequencer","importSequencer","importItem","isReady","tryRun","variableImport","ImportVisitor","importer","finish","_visitor","_importer","_finish","importCount","onceFileDetectionMap","recursionDetector","_sequencer","run","isFinished","visitImport","importNode","inlineCSS","importParent","isVariableImport","addVariableImport","processImportNode","evaldImportNode","evalForImport","multiple","importMultiple","tryAppendLessExtension","onImported","sequencedOnImported","addImport","importedAtRoot","fullPath","importVisitor","isOptional","optional","duplicateImport","oldContext","visitDeclaration","declNode","visitDeclarationOut","visitAtRule","atRuleNode","visitAtRuleOut","visitMixinDefinition","mixinDefinitionNode","visitMixinDefinitionOut","visitRuleset","rulesetNode","visitRulesetOut","visitMedia","mediaNode","visitMediaOut","visible","SetTreeVisibilityVisitor","ensureVisibility","ensureInvisibility","allExtendsStack","ExtendFinderVisitor","allExtends","allSelectorsExtendList","extendOnEveryPath","selectorPath","selExtendList","allSelectorsExtend","foundExtends","findSelfSelectors","firstExtendOnThisSelectorPath","ProcessExtendsVisitor","extendFinder","extendIndices","doExtendChaining","newRoot","checkExtendsForNonMatched","indices","hasFoundMatches","extendsList","extendsListTarget","iterationCount","extendIndex","targetExtendIndex","matches","targetExtend","newExtend","extendsToAdd","extendVisitor","findMatch","selfSelector","extendSelector","extendChainCount","selectorOne","selectorTwo","ruleNode","selectorNode","pathIndex","selectorsToAdd","extendedSelectors","haystackSelectorPath","haystackSelectorIndex","hackstackSelector","hackstackElementIndex","haystackElement","targetCombinator","potentialMatch","needleElements","potentialMatches","matched","initialCombinator","isElementValuesEqual","finished","endPathIndex","endPathElementIndex","elementValue1","elementValue2","replacementSelector","matchIndex","firstElement","newElements","currentSelectorPathIndex","currentSelectorPathElementIndex","currentValue","derived","newAllExtends","JoinSelectorVisitor","getIsOutput","joinSelectors","_context","CSSVisitorUtils","bodyRules","isSilent","owner","thing","originalRules","containsSilentNonBlockedChild","compiledRulesBody","keepOnlyVisibleChilds","removeVisibilityBlock","hasVisibleSelector","utils","mixinNode","visitExtend","extendNode","visitComment","commentNode","resolveVisibility","visitAtRuleWithBody","visitAtRuleWithoutBody","visitAnonymous","anonymousNode","nodeRules","hasFakeRuleset","getBodyRules","charset","comment","checkValidNodes","isRoot","_compileRulesetPaths","nodeRuleCnt","_removeDuplicateRules","isVisibleRuleset","ruleList","ruleCache","ruleCSS","groups","groupsArr","result_1","space_1","comma_1","MarkVisibleSelectorsVisitor","ExtendVisitor","furthest","furthestPossibleErrorMessage","chunks","current","currentPos","saveStack","parserInput","skipWhitespace","nextChar","oldi","oldj","curr","endIndex","mem","inp","charCodeAt","autoCommentAbsorb","nextNewLine","text","commentStore","nextStarSlash","save","restore","possibleErrorMessage","state","forget","isWhitespace","offset","pos","code","$re","tok","exec","$char","$str","tokLength","$quoted","startChar","currentPosition","$parseUntil","testChar","returnVal","inComment","blockDepth","blockStack","parseGroups","startPos","lastPos","loop","char","expected","peek","peekChar","currentChar","prevChar","getInput","peekNotNumeric","start","chunkInput","failFunction","fail","lastOpening","lastOpeningParen","lastMultiComment","lastMultiCommentEndBrace","chunkerCurrentIndex","currentChunkStartIndex","cc","cc2","level","parenLevel","emitFrom","emitChunk","force","fromCharCode","chunker","end","furthestReachedEnd","furthestChar","Parser","parsers","getParserInput","expect","expectChar","parseList","currentIndex","returnNodes","parser","additionalData","globalVars","modifyVars","ignored","preText","serializeVars","preProcessors","getPreProcessors","process","banner","contentsIgnoredChars","primary","endInfo","processImports","extendRule","definition","declaration","variableCall","entities","atrule","foundSemiColon","mixinLookup","quoted","forceEscaped","isEscaped","customFuncCall","stop","ieAlpha","boolean","if","prevArgs","isSemiColonSeparated","argsComma","argsSemiColon","assignment","literal","dimension","unicodeDescriptor","entity","ch","variableCurly","curly","propertyCurly","colorKeyword","ud","javascript","js","escape","parsedName","inValue","ruleLookups","isRule","getLookup","hasParens","elem","elemIndex","isCall","expressionContainsNamed","nameLoop","expressions","hasSep","throwAwayComments","cond","argInfo","conditions","block","lookupValue","attribute","slashedCombinator","isLess","when","blockRuleset","hasDR","ruleProperty","permissiveValue","anonymousValue","untilTokens","done","testCurrentChar","import","dir","options_1","importOptions","mediaFeatures","optionName","importOption","mediaFeature","pluginArgs","nonVendorSpecificName","hasIdentifier","hasExpression","hasUnknown","hasBlock","sub","addition","multiplication","operation","operand","needsParens","logical","next","conditionAnd","negatedCondition","parenthesisCondition","atomicCondition","body","me","tryConditionFollowedByParenthesis","delim","simpleProperty","colorFunctions","trueValue","falseValue","hsla","origColor","hsl","toHSV","number","rgba","size","m1_1","m2_1","hue","hsv","hsva","vs","floor","perm","saturation","lightness","hsvhue","hsvsaturation","hsvvalue","luma","luminance","saturate","amount","method","desaturate","lighten","darken","fadein","fadeout","fade","spin","mix","color1","color2","weight","w","w1","w2","greyscale","contrast","dark","light","threshold","t","argb","toARGB","tint","shade","colorBlend","mode","cb","cs","ar","cr","ab","as","colorBlendModeFunctions","multiply","screen","overlay","softlight","sqrt","hardlight","difference","abs","exclusion","average","negation","getItemsFromNode","_SELF","values","range","step","from","to","stepValue","list","each","rs","iterator","Quote","valueName","keyName","indexName","MathHelper","fn","mathFunctions","ceil","sin","cos","atan","asin","acos","mathHelper","fraction","num","pm","minMax","isMin","currentUnified","referenceUnified","unitStatic","unitClone","order","convert","pi","mod","y","percentage","evaluated","encodeURI","pattern","%","token","encodeURIComponent","isa","Type","isunit","isruleset","iscolor","isnumber","isstring","iskeyword","isurl","ispixel","ispercentage","isem","get-unit","colorBlending","fallback","functionThis","data-uri","mimetypeNode","filePathNode","mimetype","filePath","entryPath","fragmentStart","utils.clone","rawBuffer","getFileManager","useBase64","mimeLookup","charsetLookup","fileSync","loadFileSync","buf","encodeBase64","uri","dataUri","svg-gradient","direction","stops","gradientDirectionSvg","position","positionValue","gradientType","rectangleDimension","renderEnv","directionValue","throwArgumentDescriptor","types","evaldRoot","evalEnv","visitorIterator","preEvalVisitors","first","isPreEvalVisitor","isPreVisitor","postProcessors","installedPlugins","pluginCache","Loader","PluginLoader","PluginManager","install","preProcessor","priority","indexToInsertAt","postProcessor","manager","PluginManagerFactory","newFactory","SourceMapOutput","_css","_rootNode","_contentsMap","contentsMap","_contentsIgnoredCharsMap","contentsIgnoredCharsMap","sourceMapFilename","_sourceMapFilename","_outputFilename","outputFilename","sourceMapURL","sourceMapBasepath","_sourceMapBasepath","sourceMapRootpath","_sourceMapRootpath","_outputSourceFiles","outputSourceFiles","_sourceMapGeneratorConstructor","getSourceMapGenerator","_lineNumber","_column","removeBasepath","sourceLines","columns","sourceColumns","inputSource","_sourceMapGenerator","addMapping","generated","normalizeFilename","file","sourceRoot","setSourceContent","sourceMapContent","stringify","toJSON","sourceMap","sourceMapOutput","Environment","SourceMapBuilder","sourceMapOutputFilename","sourceMapGenerator","sourceMapFileInline","sourceMapInputFilename","getCSSAppendage","sourceMapBuilder","ParseTree","transformTree","toCSSOptions","getPostProcessors","file_1","getExternalSourceMap","files","rootFilename","parseTree","ImportManager","rootFileInfo","mime","queue","importManager","pluginLoader","fileParsedFunc","importedEqualsRoot","newFileInfo","promise","loadFileCallback","loadedFile","resolvedFilename","pathDiff","isPathAbsolute","alwaysMakePathsAbsolute","newEnv","evalPlugin","loadPlugin","loadFile","render","utils.copyOptions","self_1","Render","context_1","pluginManager_1","reUsePluginManager","imports_1","evalResult","fileContent","Functions","initial","data","ctor","api","fileCache","errback","xhr","XMLHttpRequest","async","isFileProtocol","fileAsync","handleResponse","status","responseText","getResponseHeader","overrideMimeType","open","setRequestHeader","send","onreadystatechange","readyState","useFileCache","lessText_1","webInfo","lastModified","doXHR","extensions","getPossibleFileExtensions","location","hrefs","prev","catch","tryToLoad","log","fulfill","rootHref","errorReporting","errors","errorline","classname","logLevel","errorConsole","timer","filenameNoPath","className","innerHTML","browser","style","env","setInterval","replaceChild","clearInterval","errorHTML","remove","removeErrorHTML","depends","lint","insecure","protocol","poll","hostname","port","onReady","addDefaultOptions","LESS_PLUGINS","lessRoot","FM","addFileManager","loggers","console","LogListener","ErrorReporting","cache","localStorage","setCSS","setItem","getCSS","getItem","timestamp","valueOf","Cache","imageSize","imageFunctions","image-size","image-width","image-height","ImageSize","typePattern","thisArg","curryArgs","loadStyles","instanceOptions","loadStyleSheet","reload","remaining","local","loadInitialFileCallback","loadStyleSheets","sheets","watch","watchMode","watchTimer","clearFileCache","unwatch","registerStylesheetsImmediately","links","rel","registerStylesheets","record","refresh","startTime","endTime","totalMilliseconds","remainingSheets","refreshStyles","resolveOrReject","pageLoadFinished"],"mappings":"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"} \ No newline at end of file diff --git a/lib/less-node/file-manager.js b/lib/less-node/file-manager.js index db01b8179..d799e4081 100644 --- a/lib/less-node/file-manager.js +++ b/lib/less-node/file-manager.js @@ -29,7 +29,6 @@ class FileManager extends AbstractFileManager { let fullFilename; const isAbsoluteFilename = this.isPathAbsolute(filename); const filenamesTried = []; - const self = this; const prefix = filename.slice(0, 1); const explicit = prefix === '.' || prefix === '/'; let result = null; @@ -97,52 +96,30 @@ class FileManager extends AbstractFileManager { filenamesTried.push(npmPrefix + fullFilename); } } - - let modified = false; - - if (self.contents[fullFilename]) { + + const readFileArgs = [fullFilename]; + if (!options.rawBuffer) { + readFileArgs.push('utf-8'); + } + if (options.syncImport) { try { - var stat = fs.statSync.apply(this, [fullFilename]); - if (stat.mtime.getTime() === self.contents[fullFilename].mtime.getTime()) { - fulfill({ contents: self.contents[fullFilename].data, filename: fullFilename}); - } - else { - modified = true; - } + const data = fs.readFileSync.apply(this, readFileArgs); + fulfill({ contents: data, filename: fullFilename}); } catch (e) { - modified = true; + filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); + return tryExtension(k + 1); } } - if (modified || !self.contents[fullFilename]) { - const readFileArgs = [fullFilename]; - if (!options.rawBuffer) { - readFileArgs.push('utf-8'); - } - if (options.syncImport) { - try { - const data = fs.readFileSync.apply(this, readFileArgs); - var stat = fs.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { data, mtime: stat.mtime }; - fulfill({ contents: data, filename: fullFilename}); - } - catch (e) { + else { + readFileArgs.push(function(e, data) { + if (e) { filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); return tryExtension(k + 1); - } - } - else { - readFileArgs.push(function(e, data) { - if (e) { - filenamesTried.push(isNodeModule ? npmPrefix + fullFilename : fullFilename); - return tryExtension(k + 1); - } - const stat = fs.statSync.apply(this, [fullFilename]); - self.contents[fullFilename] = { data, mtime: stat.mtime }; - fulfill({ contents: data, filename: fullFilename}); - }); - fs.readFile.apply(this, readFileArgs); - } + } + fulfill({ contents: data, filename: fullFilename}); + }); + fs.readFile.apply(this, readFileArgs); } } else { @@ -167,4 +144,4 @@ class FileManager extends AbstractFileManager { } } -export default FileManager; +export default FileManager; \ No newline at end of file diff --git a/lib/less/index.js b/lib/less/index.js index 7749fb9ed..260b63f75 100644 --- a/lib/less/index.js +++ b/lib/less/index.js @@ -42,7 +42,7 @@ export default (environment, fileManagers) => { * It's not clear what should / must be public and why. */ const initial = { - version: [3, 10, 3], + version: [3, 11, 0], data, tree, Environment, diff --git a/lib/less/less-error.js b/lib/less/less-error.js index a9a0f2f19..e4100c82e 100644 --- a/lib/less/less-error.js +++ b/lib/less/less-error.js @@ -1,4 +1,7 @@ import * as utils from './utils'; + +const anonymousFunc = /(|Function):(\d+):(\d+)/; + /** * This is a centralized class of any error that could be thrown internally (mostly by the parser). * Besides standard .message it keeps some additional data like a path to the file where the error @@ -44,11 +47,28 @@ const LessError = function LessError(e, fileContentMap, currentFilename) { this.column = col; if (!this.line && this.stack) { - const found = this.stack.match(/(|Function):(\d+):(\d+)/); + const found = this.stack.match(anonymousFunc); + + /** + * We have to figure out how this environment stringifies anonymous functions + * so we can correctly map plugin errors. + * + * Note, in Node 8, the output of anonymous funcs varied based on parameters + * being present or not, so we inject dummy params. + */ + const func = new Function('a', 'throw new Error()'); + let lineAdjust = 0; + try { + func(); + } catch (e) { + const match = e.stack.match(anonymousFunc); + const line = parseInt(match[2]); + lineAdjust = 1 - line; + } if (found) { if (found[2]) { - this.line = parseInt(found[2]) - 2; + this.line = parseInt(found[2]) + lineAdjust; } if (found[3]) { this.column = parseInt(found[3]); diff --git a/lib/lessc.js b/lib/lessc.js index efa6cc93f..a3b4e35e3 100755 --- a/lib/lessc.js +++ b/lib/lessc.js @@ -1,6 +1,6 @@ -import path from 'path'; +import * as path from 'path'; import fs from './less-node/fs'; -import os from 'os'; +import * as os from 'os'; import * as utils from './less/utils'; import * as Constants from './less/constants'; let errno; @@ -28,25 +28,6 @@ options.reUsePluginManager = true; const sourceMapOptions = {}; let continueProcessing = true; -// Calling process.exit does not flush stdout always. Instead of exiting the process, we set the process' exitCode, -// close all handles and wait for the event loop to exit the process. -// @see https://github.com/nodejs/node/issues/6409 -// Unfortunately, node 0.10.x does not support setting process.exitCode, so we need to call reallyExit() explicitly. -// @see https://nodejs.org/api/process.html#process_process_exitcode -// Additionally we also need to make sure that uncaughtExceptions are never swallowed. -// @see https://github.com/less/less.js/issues/2881 -// This code can safely be removed if node 0.10.x is not supported anymore. -process.on('exit', () => { process.reallyExit(process.exitCode); }); -process.on('uncaughtException', err => { - console.error(err); - process.exitCode = 1; -}); -// This code will still be required because otherwise rejected promises would not be reported to the user -process.on('unhandledRejection', err => { - console.error(err); - process.exitCode = 1; -}); - const checkArgFunc = (arg, option) => { if (!option) { console.error(`${arg} option requires a parameter`); diff --git a/package.json b/package.json index 144b9e251..cf253058a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "less", - "version": "3.10.3", + "version": "3.11.0", "description": "Leaner CSS", "homepage": "http://lesscss.org", "author": { @@ -49,42 +49,44 @@ "source-map": "~0.6.0" }, "devDependencies": { - "@babel/cli": "^7.5.5", - "@babel/core": "^7.5.5", - "@babel/node": "^7.5.5", - "@babel/preset-env": "^7.5.5", - "@typescript-eslint/eslint-plugin": "^1.13.0", - "@typescript-eslint/parser": "^1.13.0", + "@typescript-eslint/eslint-plugin": "^2.3.3", + "@typescript-eslint/parser": "^2.3.3", + "benny": "^3.6.12", "bootstrap-less-port": "0.3.0", + "chai": "^4.2.0", "diff": "^3.2.0", + "fs-extra": "^8.1.0", "git-rev": "^0.2.1", + "globby": "^10.0.1", "grunt": "^1.0.4", "grunt-cli": "^1.3.2", "grunt-contrib-clean": "^1.0.0", "grunt-contrib-connect": "^1.0.2", - "grunt-contrib-jasmine": "^1.2.0", "grunt-eslint": "^21.1.0", - "grunt-saucelabs": "^9.0.0", + "grunt-saucelabs": "^9.0.1", "grunt-shell": "^1.3.0", + "html-template-tag": "^3.2.0", "import-module": "file:test/import-module", "jit-grunt": "^0.10.0", "less-plugin-autoprefix": "^1.5.1", "less-plugin-clean-css": "^1.5.1", "minimist": "^1.2.0", + "mocha": "^6.2.1", + "mocha-headless-chrome": "^2.0.3", + "mocha-teamcity-reporter": "^3.0.0", "performance-now": "^0.2.0", - "phantomjs-polyfill-object-assign": "0.0.2", - "phantomjs-prebuilt": "^2.1.16", "phin": "^2.2.3", "promise": "^7.1.1", "read-glob": "^3.0.0", "rollup": "^1.17.0", - "rollup-plugin-babel": "^4.3.3", "rollup-plugin-commonjs": "^10.0.1", "rollup-plugin-node-resolve": "^5.2.0", "rollup-plugin-terser": "^5.1.1", + "rollup-plugin-typescript2": "^0.24.3", "semver": "^6.3.0", "time-grunt": "^1.3.0", - "typescript": "^3.5.3", + "ts-node": "^8.4.1", + "typescript": "^3.6.3", "uikit": "2.27.4" }, "keywords": [ diff --git a/test/browser/common.js b/test/browser/common.js index 1b98fe577..3bf408260 100644 --- a/test/browser/common.js +++ b/test/browser/common.js @@ -1,44 +1,3 @@ -/* Add js reporter for sauce */ -jasmine.getEnv().addReporter(new jasmine.JSReporter2()); -jasmine.getEnv().defaultTimeoutInterval = 3000; - -// From https://github.com/axemclion/grunt-saucelabs/issues/109#issuecomment-166767282 -// (function () { -// var oldJSReport = window.jasmine.getJSReport; -// window.jasmine.getJSReport = function () { -// var results = oldJSReport(); -// if (results) { -// return { -// durationSec: results.durationSec, -// suites: removePassingTests(results.suites), -// passed: results.passed -// }; -// } else { -// return null; -// } -// }; - -// function removePassingTests (suites) { -// return suites.filter(specFailed) -// .map(mapSuite); -// } - -// function mapSuite (suite) { -// var result = {}; -// for (var s in suite) { -// result[s] = suite[s]; -// } -// result.specs = suite.specs.filter(specFailed); -// result.suites = removePassingTests(suite.suites); -// return result; -// } - -// function specFailed (item) { -// return !item.passed; -// } -// })(); -/* record log messages for testing */ - var logMessages = []; window.less = window.less || {}; @@ -140,13 +99,15 @@ testSheet = function (sheet) { window.navigator.userAgent.indexOf('Trident/') >= 0) { text = ieFormat(text); } - expect(lessOutput).toEqual(text); + expect(lessOutput).to.equal(text); done(); + }) + .catch(function(err) { + done(err); }); }) .catch(function(err) { - console.log(err); - done(); + done(err); }); }); }; @@ -213,11 +174,14 @@ testErrorSheet = function (sheet) { .replace(/\{node\}[\s\S]*\{\/node\}/g, '') .replace(/\n$/, '') .trim(); - expect(actualErrorMsg).toEqual(errorTxt); + expect(actualErrorMsg).to.equal(errorTxt); if (errorTxt == actualErrorMsg) { actualErrorElement.style.display = 'none'; } done(); + }) + .catch(function (err) { + done(err); }); }); }); @@ -234,7 +198,7 @@ testErrorSheetConsole = function (sheet) { .replace(/\nStack Trace\n[\s\S]*/, ''); describe('the error', function () { - expect(actualErrorElement).toBe(null); + expect(actualErrorElement).to.be.null; }); errorFile @@ -246,7 +210,7 @@ testErrorSheetConsole = function (sheet) { .replace(/\{404status\}/g, ' (404)') .replace(/\{node\}.*\{\/node\}/g, '') .trim(); - expect(actualErrorMsg).toEqual(errorTxt); + expect(actualErrorMsg).to.equal(errorTxt); done(); }); }); @@ -264,5 +228,3 @@ loadFile = function (href) { request.send(null); }); }; - -jasmine.DEFAULT_TIMEOUT_INTERVAL = 90000; diff --git a/test/browser/generator/benchmark.config.js b/test/browser/generator/benchmark.config.js new file mode 100644 index 000000000..9e4d71e0c --- /dev/null +++ b/test/browser/generator/benchmark.config.js @@ -0,0 +1,50 @@ + +module.exports = { + current: { + // src is used to build list of less files to compile + src: [ + "benchmark/benchmark.less" + ], + options: { + helpers: "benchmark/browseroptions.js", + specs: "benchmark/browserspec.js", + outfile: "tmp/browser/test-runner-benchmark-current.html" + } + }, + v3_10_3: { + // src is used to build list of less files to compile + src: [ + "benchmark/benchmark.less" + ], + options: { + helpers: "benchmark/browseroptions.js", + specs: "benchmark/browserspec.js", + outfile: "tmp/browser/test-runner-benchmark-v3_10_3.html", + less: "https://cdnjs.cloudflare.com/ajax/libs/less.js/3.10.3/less.min.js" + } + }, + v3_9_0: { + // src is used to build list of less files to compile + src: [ + "benchmark/benchmark.less" + ], + options: { + helpers: "benchmark/browseroptions.js", + specs: "benchmark/browserspec.js", + outfile: "tmp/browser/test-runner-benchmark-v3_9_0.html", + less: "https://cdnjs.cloudflare.com/ajax/libs/less.js/3.9.0/less.min.js" + } + }, + v2_7_3: { + // src is used to build list of less files to compile + src: [ + "benchmark/benchmark.less" + ], + options: { + helpers: "benchmark/browseroptions.js", + specs: "benchmark/browserspec.js", + outfile: "tmp/browser/test-runner-benchmark-v2_7_3.html", + less: "https://cdnjs.cloudflare.com/ajax/libs/less.js/2.7.3/less.min.js" + } + } +} \ No newline at end of file diff --git a/test/browser/generator/generate.js b/test/browser/generator/generate.js new file mode 100644 index 000000000..c1dbc8765 --- /dev/null +++ b/test/browser/generator/generate.js @@ -0,0 +1,78 @@ +const template = require('./template') +let config +const fs = require('fs-extra') +const path = require('path') +const globby = require('globby') +const { runner } = require('mocha-headless-chrome') + + +if (process.argv[2]) { + config = require(`./${process.argv[2]}.config`) +} else { + config = require('./runner.config') +} + +/** + * Generate templates and run tests + */ +const tests = [] +const cwd = process.cwd() +const tmpDir = path.join(cwd, 'tmp', 'browser') +fs.ensureDirSync(tmpDir) +fs.copySync(path.join(cwd, 'test', 'browser', 'common.js'), path.join(tmpDir, 'common.js')) + +let numTests = 0 +let passedTests = 0 +let failedTests = 0 + +/** Will run the runners in a series */ +function runSerial(tasks) { + var result = Promise.resolve() + start = Date.now() + tasks.forEach(task => { + result = result.then(result => { + if (result && result.result && result.result.stats) { + const stats = result.result.stats + numTests += stats.tests + passedTests += stats.passes + failedTests += stats.failures + } + return task() + }, err => { + console.log(err) + failedTests += 1 + }) + }) + return result +} + +Object.entries(config).forEach(entry => { + const test = entry[1] + const paths = globby.sync(test.src) + const templateString = template(paths, test.options.helpers, test.options.specs) + fs.writeFileSync(path.join(cwd, test.options.outfile), templateString) + tests.push(() => { + const file = 'http://localhost:8081/' + test.options.outfile + console.log(file) + return runner({ + file, + timeout: 2000, + args: ['disable-web-security'] + }) + }) +}) + +module.exports = () => runSerial(tests).then(() => { + if (failedTests > 0) { + process.stderr.write(failedTests + ' Failed, ' + passedTests + ' passed\n'); + } else { + process.stdout.write('All Passed ' + passedTests + ' run\n'); + } + if (failedTests) { + process.on('exit', function() { process.reallyExit(1); }); + } + process.exit() +}, err => { + process.stderr.write(err.message); + process.exit() +}) diff --git a/test/browser/generator/runner.config.js b/test/browser/generator/runner.config.js new file mode 100644 index 000000000..c2670a5f1 --- /dev/null +++ b/test/browser/generator/runner.config.js @@ -0,0 +1,180 @@ + +module.exports = { + main: { + // src is used to build list of less files to compile + src: [ + "test/less/*.less", + "!test/less/plugin-preeval.less", // uses ES6 syntax + // Don't test NPM import, obviously + "!test/less/plugin-module.less", + "!test/less/import-module.less", + "!test/less/javascript.less", + "!test/less/urls.less", + "!test/less/empty.less" + ], + options: { + helpers: "test/browser/runner-main-options.js", + specs: "test/browser/runner-main-spec.js", + outfile: "tmp/browser/test-runner-main.html" + } + }, + legacy: { + src: ["test/less/legacy/*.less"], + options: { + helpers: "test/browser/runner-legacy-options.js", + specs: "test/browser/runner-legacy-spec.js", + outfile: "tmp/browser/test-runner-legacy.html" + } + }, + strictUnits: { + src: ["test/less/strict-units/*.less"], + options: { + helpers: "test/browser/runner-strict-units-options.js", + specs: "test/browser/runner-strict-units-spec.js", + outfile: "tmp/browser/test-runner-strict-units.html" + } + }, + errors: { + src: [ + "test/less/errors/*.less", + "!test/less/errors/javascript-error.less", + "test/browser/less/errors/*.less" + ], + options: { + timeout: 20000, + helpers: "test/browser/runner-errors-options.js", + specs: "test/browser/runner-errors-spec.js", + outfile: "tmp/browser/test-runner-errors.html" + } + }, + noJsErrors: { + src: ["test/less/no-js-errors/*.less"], + options: { + helpers: "test/browser/runner-no-js-errors-options.js", + specs: "test/browser/runner-no-js-errors-spec.js", + outfile: "tmp/browser/test-runner-no-js-errors.html" + } + }, + browser: { + src: [ + "test/browser/less/*.less", + "test/browser/less/plugin/*.less" + ], + options: { + helpers: "test/browser/runner-browser-options.js", + specs: "test/browser/runner-browser-spec.js", + outfile: "tmp/browser/test-runner-browser.html" + } + }, + relativeUrls: { + src: ["test/browser/less/relative-urls/*.less"], + options: { + helpers: "test/browser/runner-relative-urls-options.js", + specs: "test/browser/runner-relative-urls-spec.js", + outfile: "tmp/browser/test-runner-relative-urls.html" + } + }, + rewriteUrls: { + src: ["test/browser/less/rewrite-urls/*.less"], + options: { + helpers: "test/browser/runner-rewrite-urls-options.js", + specs: "test/browser/runner-rewrite-urls-spec.js", + outfile: "tmp/browser/test-runner-rewrite-urls.html" + } + }, + rootpath: { + src: ["test/browser/less/rootpath/*.less"], + options: { + helpers: "test/browser/runner-rootpath-options.js", + specs: "test/browser/runner-rootpath-spec.js", + outfile: "tmp/browser/test-runner-rootpath.html" + } + }, + rootpathRelative: { + src: ["test/browser/less/rootpath-relative/*.less"], + options: { + helpers: "test/browser/runner-rootpath-relative-options.js", + specs: "test/browser/runner-rootpath-relative-spec.js", + outfile: "tmp/browser/test-runner-rootpath-relative.html" + } + }, + rootpathRewriteUrls: { + src: ["test/browser/less/rootpath-rewrite-urls/*.less"], + options: { + helpers: + "test/browser/runner-rootpath-rewrite-urls-options.js", + specs: "test/browser/runner-rootpath-rewrite-urls-spec.js", + outfile: + "tmp/browser/test-runner-rootpath-rewrite-urls.html" + } + }, + production: { + src: ["test/browser/less/production/*.less"], + options: { + helpers: "test/browser/runner-production-options.js", + specs: "test/browser/runner-production-spec.js", + outfile: "tmp/browser/test-runner-production.html" + } + }, + modifyVars: { + src: ["test/browser/less/modify-vars/*.less"], + options: { + helpers: "test/browser/runner-modify-vars-options.js", + specs: "test/browser/runner-modify-vars-spec.js", + outfile: "tmp/browser/test-runner-modify-vars.html" + } + }, + globalVars: { + src: ["test/browser/less/global-vars/*.less"], + options: { + helpers: "test/browser/runner-global-vars-options.js", + specs: "test/browser/runner-global-vars-spec.js", + outfile: "tmp/browser/test-runner-global-vars.html" + } + }, + postProcessorPlugin: { + src: ["test/less/postProcessorPlugin/*.less"], + options: { + helpers: [ + "test/plugins/postprocess/index.js", + "test/browser/runner-postProcessorPlugin-options.js" + ], + specs: "test/browser/runner-postProcessorPlugin.js", + outfile: + "tmp/browser/test-runner-post-processor-plugin.html" + } + }, + preProcessorPlugin: { + src: ["test/less/preProcessorPlugin/*.less"], + options: { + helpers: [ + "test/plugins/preprocess/index.js", + "test/browser/runner-preProcessorPlugin-options.js" + ], + specs: "test/browser/runner-preProcessorPlugin.js", + outfile: "tmp/browser/test-runner-pre-processor-plugin.html" + } + }, + visitorPlugin: { + src: ["test/less/visitorPlugin/*.less"], + options: { + helpers: [ + "test/plugins/visitor/index.js", + "test/browser/runner-VisitorPlugin-options.js" + ], + specs: "test/browser/runner-VisitorPlugin.js", + outfile: "tmp/browser/test-runner-visitor-plugin.html" + } + }, + filemanagerPlugin: { + src: ["test/less/filemanagerPlugin/*.less"], + options: { + helpers: [ + "test/plugins/filemanager/index.js", + "test/browser/runner-filemanagerPlugin-options.js" + ], + specs: "test/browser/runner-filemanagerPlugin.js", + outfile: "tmp/browser/test-runner-filemanager-plugin.html" + } + } +} \ No newline at end of file diff --git a/test/browser/generator/runner.js b/test/browser/generator/runner.js new file mode 100644 index 000000000..25c846036 --- /dev/null +++ b/test/browser/generator/runner.js @@ -0,0 +1,2 @@ +const runner = require('./generate') +runner() \ No newline at end of file diff --git a/test/browser/generator/template.js b/test/browser/generator/template.js new file mode 100644 index 000000000..4ad7488d4 --- /dev/null +++ b/test/browser/generator/template.js @@ -0,0 +1,83 @@ +const html = require('html-template-tag') + +/** + * Generates HTML templates from list of test sheets + */ +module.exports = (stylesheets, helpers, spec, less) => { + if (!Array.isArray(helpers)) { + helpers = [helpers] + } + return html` + + + + + + Less.js Spec Runner + + + $${stylesheets.map(function(fullLessName) { + var pathParts = fullLessName.split('/'); + var fullCssName = fullLessName.replace(/less/g, 'css'); + var lessName = pathParts[pathParts.length - 1]; + var name = lessName.split('.')[0]; + return ` + + + + ` }).join('')} + + $${helpers.map(helper => ` + + `).join('')} + + + + + + +
    + + + + + + + + + + +` +} \ No newline at end of file diff --git a/test/browser/onload.js b/test/browser/onload.js deleted file mode 100644 index 79223c8b7..000000000 --- a/test/browser/onload.js +++ /dev/null @@ -1,13 +0,0 @@ -(function() { - window.DEFER = [window.onload]; - Object.defineProperty(window, 'onload', { - get: function() { - return function() {}; - }, - set: function(fn) { - window.DEFER.push(fn); - }, - enumerable: true, - configurable: true - }); -})(); \ No newline at end of file diff --git a/test/browser/runner-browser-options.js b/test/browser/runner-browser-options.js index c59590a1d..a1fb09abb 100644 --- a/test/browser/runner-browser-options.js +++ b/test/browser/runner-browser-options.js @@ -5,12 +5,6 @@ var less = { math: 'always' }; -// There originally run inside describe method. However, since they have not -// been inside it, they run at jasmine compile time (not runtime). It all -// worked cause less.js was in async mode and custom phantom runner had -// different setup then grunt-contrib-jasmine. They have been created before -// less.js run, even as they have been defined in spec. - // test inline less in style tags by grabbing an assortment of less files and doing `@import`s var testFiles = ['charsets', 'colors', 'comments', 'css-3', 'strings', 'media', 'mixins'], testSheets = []; diff --git a/test/browser/runner-browser-spec.js b/test/browser/runner-browser-spec.js index 95c057cc0..bfe60d520 100644 --- a/test/browser/runner-browser-spec.js +++ b/test/browser/runner-browser-spec.js @@ -2,7 +2,7 @@ describe('less.js browser behaviour', function() { testLessEqualsInDocument(); it('has some log messages', function() { - expect(logMessages.length).toBeGreaterThan(0); + expect(logMessages.length).to.be.above(0); }); for (var i = 0; i < testFiles.length; i++) { diff --git a/test/browser/runner-main-spec.js b/test/browser/runner-main-spec.js index 0cb1adfee..a60b6363d 100644 --- a/test/browser/runner-main-spec.js +++ b/test/browser/runner-main-spec.js @@ -2,6 +2,6 @@ console.warn('start spec'); describe('less.js main tests', function() { testLessEqualsInDocument(); it('the global environment', function() { - expect(window.require).toBe(undefined); + expect(window.require).to.be.undefined; }); }); diff --git a/test/browser/runner-modify-vars-spec.js b/test/browser/runner-modify-vars-spec.js index 935c8d591..cad22bbdf 100644 --- a/test/browser/runner-modify-vars-spec.js +++ b/test/browser/runner-modify-vars-spec.js @@ -27,7 +27,7 @@ describe('less.js modify vars', function () { var xhrLogMessages = logMessages.filter(function (item) { return (/XHR: Getting '/).test(item); }); - expect(xhrLogMessages.length).toEqual(2); + expect(xhrLogMessages.length).to.equal(2); done(); }); }); diff --git a/test/browser/runner-production-spec.js b/test/browser/runner-production-spec.js index ba4a7244b..ee042d8be 100644 --- a/test/browser/runner-production-spec.js +++ b/test/browser/runner-production-spec.js @@ -1,5 +1,5 @@ describe('less.js production behaviour', function() { it('doesn\'t log any messages', function() { - expect(logMessages.length).toEqual(0); + expect(logMessages.length).to.equal(0); }); }); diff --git a/test/browser/test-runner-template.tmpl b/test/browser/test-runner-template.tmpl deleted file mode 100644 index 7b7df9969..000000000 --- a/test/browser/test-runner-template.tmpl +++ /dev/null @@ -1,105 +0,0 @@ - - - - - - Jasmine Spec Runner - - - <% scripts.src.forEach(function(fullLessName) { - var pathParts = fullLessName.split('/'); - var fullCssName = fullLessName.replace(/less/g, 'css'); - var lessName = pathParts[pathParts.length - 1]; - var name = lessName.split('.')[0]; %> - - - - <% }); %> - - - <% css.forEach(function(style){ %> - - <% }) %> - - - <% - - var generateScriptTags = function(allScripts) { - allScripts.forEach(function(script){ - if (script.indexOf('boot.js') > -1) { - script = '../../test/browser/vendor/boot.js' - } - %> <% - }); - }; - - generateScriptTags(scripts.polyfills); - generateScriptTags(scripts.jasmine); - generateScriptTags(scripts.boot); - generateScriptTags(scripts.helpers); - generateScriptTags(scripts.vendor); - - %> - - - <% var toArray = function(scripts) { - %>[<% - scripts.forEach(function(scriptUrl, index){ - %>"<%= scriptUrl %>"<% - if (index !== scripts.length -1) { - %>,<% - } - }); - %>]<% - }; %> - - - - - - - - - - \ No newline at end of file diff --git a/test/browser/vendor/boot.js b/test/browser/vendor/boot.js deleted file mode 100644 index abe9fba07..000000000 --- a/test/browser/vendor/boot.js +++ /dev/null @@ -1,148 +0,0 @@ -// Modified from grunt-contrib-jasmine - -/* -Copyright (c) 2008-2015 Pivotal Labs - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -*/ -/** - Starting with version 2.0, this file "boots" Jasmine, performing all of the necessary initialization before executing the loaded environment and all of a project's specs. This file should be loaded after `jasmine.js` and `jasmine_html.js`, but before any project source files or spec files are loaded. Thus this file can also be used to customize Jasmine for a project. - - If a project is using Jasmine via the standalone distribution, this file can be customized directly. If a project is using Jasmine via the [Ruby gem][jasmine-gem], this file can be copied into the support directory via `jasmine copy_boot_js`. Other environments (e.g., Python) will have different mechanisms. - - The location of `boot.js` can be specified and/or overridden in `jasmine.yml`. - - [jasmine-gem]: http://github.com/pivotal/jasmine-gem - */ - -(function() { - - /** - * ## Require & Instantiate - * - * Require Jasmine's core files. Specifically, this requires and attaches all of Jasmine's code to the `jasmine` reference. - */ - window.jasmine = jasmineRequire.core(jasmineRequire); - - /** - * Since this is being run in a browser and the results should populate to an HTML page, require the HTML-specific Jasmine code, injecting the same reference. - */ - jasmineRequire.html(jasmine); - - /** - * Create the Jasmine environment. This is used to run all specs in a project. - */ - var env = jasmine.getEnv(); - - /** - * ## The Global Interface - * - * Build up the functions that will be exposed as the Jasmine public interface. A project can customize, rename or alias any of these functions as desired, provided the implementation remains unchanged. - */ - var jasmineInterface = jasmineRequire.interface(jasmine, env); - - /** - * Add all of the Jasmine global/public interface to the global scope, so a project can use the public interface directly. For example, calling `describe` in specs instead of `jasmine.getEnv().describe`. - */ - extend(window, jasmineInterface); - - /** - * ## Runner Parameters - * - * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface. - */ - - var queryString = new jasmine.QueryString({ - getWindowLocation: function() { return window.location; } - }); - - var catchingExceptions = queryString.getParam("catch"); - env.catchExceptions(typeof catchingExceptions === "undefined" ? true : catchingExceptions); - - var throwingExpectationFailures = queryString.getParam("throwFailures"); - env.throwOnExpectationFailure(throwingExpectationFailures); - - var random = queryString.getParam("random"); - env.randomizeTests(random); - - var seed = queryString.getParam("seed"); - if (seed) { - env.seed(seed); - } - - /** - * ## Reporters - * The `HtmlReporter` builds all of the HTML UI for the runner page. This reporter paints the dots, stars, and x's for specs, as well as all spec names and all failures (if any). - */ - var htmlReporter = new jasmine.HtmlReporter({ - env: env, - onRaiseExceptionsClick: function() { queryString.navigateWithNewParam("catch", !env.catchingExceptions()); }, - onThrowExpectationsClick: function() { queryString.navigateWithNewParam("throwFailures", !env.throwingExpectationFailures()); }, - onRandomClick: function() { queryString.navigateWithNewParam("random", !env.randomTests()); }, - addToExistingQueryString: function(key, value) { return queryString.fullStringWithNewParam(key, value); }, - getContainer: function() { return document.body; }, - createElement: function() { return document.createElement.apply(document, arguments); }, - createTextNode: function() { return document.createTextNode.apply(document, arguments); }, - timer: new jasmine.Timer() - }); - - /** - * The `jsApiReporter` also receives spec results, and is used by any environment that needs to extract the results from JavaScript. - */ - env.addReporter(jasmineInterface.jsApiReporter); - env.addReporter(htmlReporter); - - /** - * Filter which specs will be run by matching the start of the full name against the `spec` query param. - */ - var specFilter = new jasmine.HtmlSpecFilter({ - filterString: function() { return queryString.getParam("spec"); } - }); - - env.specFilter = function(spec) { - return specFilter.matches(spec.getFullName()); - }; - - /** - * Setting up timing functions to be able to be overridden. Certain browsers (Safari, IE 8, phantomjs) require this hack. - */ - window.setTimeout = window.setTimeout; - window.setInterval = window.setInterval; - window.clearTimeout = window.clearTimeout; - window.clearInterval = window.clearInterval; - - /** - * Customized for Less.js - */ - - window.DEFER = function() { - htmlReporter.initialize(); - env.execute(); - }; - - /** - * Helper function for readability above. - */ - function extend(destination, source) { - for (var property in source) destination[property] = source[property]; - return destination; - } - -}()); diff --git a/test/browser/vendor/jasmine-jsreporter.js b/test/browser/vendor/jasmine-jsreporter.js deleted file mode 100644 index 9a14e32c7..000000000 --- a/test/browser/vendor/jasmine-jsreporter.js +++ /dev/null @@ -1,391 +0,0 @@ -/* - This file is part of the Jasmine JSReporter project from Ivan De Marino. - - Copyright (C) 2011-2014 Ivan De Marino - Copyright (C) 2014 Alex Treppass - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - * Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - * Neither the name of the nor the - names of its contributors may be used to endorse or promote products - derived from this software without specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL IVAN DE MARINO BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -(function (jasmine) { - - if (!jasmine) { - throw new Error("[Jasmine JSReporter] 'Jasmine' library not found"); - } - - // ------------------------------------------------------------------------ - // Jasmine JSReporter for Jasmine 1.x - // ------------------------------------------------------------------------ - - /** - * Calculate elapsed time, in Seconds. - * @param startMs Start time in Milliseconds - * @param finishMs Finish time in Milliseconds - * @return Elapsed time in Seconds */ - function elapsedSec(startMs, finishMs) { - return (finishMs - startMs) / 1000; - } - - /** - * Round an amount to the given number of Digits. - * If no number of digits is given, than '2' is assumed. - * @param amount Amount to round - * @param numOfDecDigits Number of Digits to round to. Default value is '2'. - * @return Rounded amount */ - function round(amount, numOfDecDigits) { - numOfDecDigits = numOfDecDigits || 2; - return Math.round(amount * Math.pow(10, numOfDecDigits)) / Math.pow(10, numOfDecDigits); - } - - /** - * Create a new array which contains only the failed items. - * @param items Items which will be filtered - * @returns {Array} of failed items */ - function failures(items) { - var fs = [], i, v; - for (i = 0; i < items.length; i += 1) { - v = items[i]; - if (!v.passed_) { - fs.push(v); - } - } - return fs; - } - - /** - * Collect information about a Suite, recursively, and return a JSON result. - * @param suite The Jasmine Suite to get data from - */ - function getSuiteData(suite) { - var suiteData = { - description : suite.description, - durationSec : 0, - specs: [], - suites: [], - passed: true - }, - specs = suite.specs(), - suites = suite.suites(), - i, ilen; - - // Loop over all the Suite's Specs - for (i = 0, ilen = specs.length; i < ilen; ++i) { - suiteData.specs[i] = { - description : specs[i].description, - durationSec : specs[i].durationSec, - passed : specs[i].results().passedCount === specs[i].results().totalCount, - skipped : specs[i].results().skipped, - passedCount : specs[i].results().passedCount, - failedCount : specs[i].results().failedCount, - totalCount : specs[i].results().totalCount, - failures: failures(specs[i].results().getItems()) - }; - suiteData.passed = !suiteData.specs[i].passed ? false : suiteData.passed; - suiteData.durationSec += suiteData.specs[i].durationSec; - } - - // Loop over all the Suite's sub-Suites - for (i = 0, ilen = suites.length; i < ilen; ++i) { - suiteData.suites[i] = getSuiteData(suites[i]); //< recursive population - suiteData.passed = !suiteData.suites[i].passed ? false : suiteData.passed; - suiteData.durationSec += suiteData.suites[i].durationSec; - } - - // Rounding duration numbers to 3 decimal digits - suiteData.durationSec = round(suiteData.durationSec, 4); - - return suiteData; - } - - var JSReporter = function () { - }; - - JSReporter.prototype = { - reportRunnerStarting: function (runner) { - // Nothing to do - }, - - reportSpecStarting: function (spec) { - // Start timing this spec - spec.startedAt = new Date(); - }, - - reportSpecResults: function (spec) { - // Finish timing this spec and calculate duration/delta (in sec) - spec.finishedAt = new Date(); - // If the spec was skipped, reportSpecStarting is never called and spec.startedAt is undefined - spec.durationSec = spec.startedAt ? elapsedSec(spec.startedAt.getTime(), spec.finishedAt.getTime()) : 0; - }, - - reportSuiteResults: function (suite) { - // Nothing to do - }, - - reportRunnerResults: function (runner) { - var suites = runner.suites(), - i, j, ilen; - - // Attach results to the "jasmine" object to make those results easy to scrap/find - jasmine.runnerResults = { - suites: [], - durationSec : 0, - passed : true - }; - - // Loop over all the Suites - for (i = 0, ilen = suites.length, j = 0; i < ilen; ++i) { - if (suites[i].parentSuite === null) { - jasmine.runnerResults.suites[j] = getSuiteData(suites[i]); - // If 1 suite fails, the whole runner fails - jasmine.runnerResults.passed = !jasmine.runnerResults.suites[j].passed ? false : jasmine.runnerResults.passed; - // Add up all the durations - jasmine.runnerResults.durationSec += jasmine.runnerResults.suites[j].durationSec; - j++; - } - } - - // Decorate the 'jasmine' object with getters - jasmine.getJSReport = function () { - if (jasmine.runnerResults) { - return jasmine.runnerResults; - } - return null; - }; - jasmine.getJSReportAsString = function () { - return JSON.stringify(jasmine.getJSReport()); - }; - } - }; - - // export public - jasmine.JSReporter = JSReporter; - - // ------------------------------------------------------------------------ - // Jasmine JSReporter for Jasmine 2.0 - // ------------------------------------------------------------------------ - - /* - Simple timer implementation - */ - var Timer = function () {}; - - Timer.prototype.start = function () { - this.startTime = new Date().getTime(); - return this; - }; - - Timer.prototype.elapsed = function () { - if (this.startTime == null) { - return -1; - } - return new Date().getTime() - this.startTime; - }; - - /* - Utility methods - */ - var _extend = function (obj1, obj2) { - for (var prop in obj2) { - obj1[prop] = obj2[prop]; - } - return obj1; - }; - var _clone = function (obj) { - if (obj !== Object(obj)) { - return obj; - } - return _extend({}, obj); - }; - - jasmine.JSReporter2 = function () { - this.specs = {}; - this.suites = {}; - this.rootSuites = []; - this.suiteStack = []; - - // export methods under jasmine namespace - jasmine.getJSReport = this.getJSReport; - jasmine.getJSReportAsString = this.getJSReportAsString; - }; - - var JSR = jasmine.JSReporter2.prototype; - - // Reporter API methods - // -------------------- - - JSR.suiteStarted = function (suite) { - suite = this._cacheSuite(suite); - // build up suite tree as we go - suite.specs = []; - suite.suites = []; - suite.passed = true; - suite.parentId = this.suiteStack.slice(this.suiteStack.length - 1)[0]; - if (suite.parentId) { - this.suites[suite.parentId].suites.push(suite); - } else { - this.rootSuites.push(suite.id); - } - this.suiteStack.push(suite.id); - suite.timer = new Timer().start(); - }; - - JSR.suiteDone = function (suite) { - suite = this._cacheSuite(suite); - suite.duration = suite.timer.elapsed(); - suite.durationSec = suite.duration / 1000; - this.suiteStack.pop(); - - // maintain parent suite state - var parent = this.suites[suite.parentId]; - if (parent) { - parent.passed = parent.passed && suite.passed; - } - - // keep report representation clean - delete suite.timer; - delete suite.id; - delete suite.parentId; - delete suite.fullName; - }; - - JSR.specStarted = function (spec) { - spec = this._cacheSpec(spec); - spec.timer = new Timer().start(); - // build up suites->spec tree as we go - spec.suiteId = this.suiteStack.slice(this.suiteStack.length - 1)[0]; - this.suites[spec.suiteId].specs.push(spec); - }; - - JSR.specDone = function (spec) { - spec = this._cacheSpec(spec); - - spec.duration = spec.timer.elapsed(); - spec.durationSec = spec.duration / 1000; - - spec.skipped = spec.status === 'pending'; - spec.passed = spec.skipped || spec.status === 'passed'; - - spec.totalCount = spec.passedExpectations.length + spec.failedExpectations.length; - spec.passedCount = spec.passedExpectations.length; - spec.failedCount = spec.failedExpectations.length; - spec.failures = []; - - for (var i = 0, j = spec.failedExpectations.length; i < j; i++) { - var fail = spec.failedExpectations[i]; - spec.failures.push({ - type: 'expect', - expected: fail.expected, - passed: false, - message: fail.message, - matcherName: fail.matcherName, - trace: { - stack: fail.stack - } - }); - } - - // maintain parent suite state - var parent = this.suites[spec.suiteId]; - if (spec.failed) { - parent.failingSpecs.push(spec); - } - parent.passed = parent.passed && spec.passed; - - // keep report representation clean - delete spec.timer; - delete spec.totalExpectations; - delete spec.passedExpectations; - delete spec.suiteId; - delete spec.fullName; - delete spec.id; - delete spec.status; - delete spec.failedExpectations; - }; - - JSR.jasmineDone = function () { - this._buildReport(); - }; - - JSR.getJSReport = function () { - if (jasmine.jsReport) { - return jasmine.jsReport; - } - }; - - JSR.getJSReportAsString = function () { - if (jasmine.jsReport) { - return JSON.stringify(jasmine.jsReport); - } - }; - - // Private methods - // --------------- - - JSR._haveSpec = function (spec) { - return this.specs[spec.id] != null; - }; - - JSR._cacheSpec = function (spec) { - var existing = this.specs[spec.id]; - if (existing == null) { - existing = this.specs[spec.id] = _clone(spec); - } else { - _extend(existing, spec); - } - return existing; - }; - - JSR._haveSuite = function (suite) { - return this.suites[suite.id] != null; - }; - - JSR._cacheSuite = function (suite) { - var existing = this.suites[suite.id]; - if (existing == null) { - existing = this.suites[suite.id] = _clone(suite); - } else { - _extend(existing, suite); - } - return existing; - }; - - JSR._buildReport = function () { - var overallDuration = 0; - var overallPassed = true; - var overallSuites = []; - - for (var i = 0, j = this.rootSuites.length; i < j; i++) { - var suite = this.suites[this.rootSuites[i]]; - overallDuration += suite.duration; - overallPassed = overallPassed && suite.passed; - overallSuites.push(suite); - } - - jasmine.jsReport = { - passed: overallPassed, - durationSec: overallDuration / 1000, - suites: overallSuites - }; - }; - -})(jasmine); diff --git a/test/browser/vendor/promise.js b/test/browser/vendor/promise.js deleted file mode 100644 index 9ba768264..000000000 --- a/test/browser/vendor/promise.js +++ /dev/null @@ -1,2 +0,0 @@ -!function n(t,e,r){function o(u,f){if(!e[u]){if(!t[u]){var c="function"==typeof require&&require;if(!f&&c)return c(u,!0);if(i)return i(u,!0);var s=new Error("Cannot find module '"+u+"'");throw s.code="MODULE_NOT_FOUND",s}var l=e[u]={exports:{}};t[u][0].call(l.exports,function(n){var e=t[u][1][n];return o(e?e:n)},l,l.exports,n,t,e,r)}return e[u].exports}for(var i="function"==typeof require&&require,u=0;ul){for(var t=0,e=f.length-s;e>t;t++)f[t]=f[t+s];f.length-=s,s=0}}f.length=0,s=0,c=!1}function o(n){var t=1,e=new a(n),r=document.createTextNode("");return e.observe(r,{characterData:!0}),function(){t=-t,r.data=t}}function i(n){return function(){function t(){clearTimeout(e),clearInterval(r),n()}var e=setTimeout(t,0),r=setInterval(t,50)}}t.exports=e;var u,f=[],c=!1,s=0,l=1024,a=n.MutationObserver||n.WebKitMutationObserver;u="function"==typeof a?o(r):i(r),e.requestFlush=u,e.makeRequestCallFromTimer=i}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{}],5:[function(n,t,e){"function"!=typeof Promise.prototype.done&&(Promise.prototype.done=function(n,t){var e=arguments.length?this.then.apply(this,arguments):this;e.then(null,function(n){setTimeout(function(){throw n},0)})})},{}],6:[function(n,t,e){n("asap");"undefined"==typeof Promise&&(Promise=n("./lib/core.js"),n("./lib/es6-extensions.js")),n("./polyfill-done.js")},{"./lib/core.js":1,"./lib/es6-extensions.js":2,"./polyfill-done.js":5,asap:3}]},{},[6]); -//# sourceMappingURL=/polyfills/promise-7.0.4.min.js.map \ No newline at end of file diff --git a/test/css/comments.css b/test/css/comments.css index c8475cd9e..3a24255a1 100644 --- a/test/css/comments.css +++ b/test/css/comments.css @@ -52,7 +52,7 @@ -webkit-border-radius: 2px /* webkit only */; -moz-border-radius: 8px /* moz only with operation */; } -.test { +.test-rule { color: 1px; } .sr-only-focusable { diff --git a/test/css/css-3.css b/test/css/css-3.css index 5a14773a6..046190a35 100644 --- a/test/css/css-3.css +++ b/test/css/css-3.css @@ -18,21 +18,21 @@ p:not([class*="lead"]) { color: black; } input[type="text"].class#id[attr=32]:not(1) { - color: white; + color: inherit; } div#id.class[a=1][b=2].class:not(1) { - color: white; + color: inherit; } ul.comma > li:not(:only-child)::after { - color: white; + color: inherit; } ol.comma > li:nth-last-child(2)::after { - color: white; + color: inherit; } li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(-n+2) { - color: white; + color: inherit; } a[href^="http://"] { color: black; diff --git a/test/css/css-guards.css b/test/css/css-guards.css index f4b8a1087..fe5e2809d 100644 --- a/test/css/css-guards.css +++ b/test/css/css-guards.css @@ -10,7 +10,7 @@ .multiple-conditions-1 { color: red; } -.inheritance .test { +.inheritance .test-rule { color: black; } .inheritance:hover { diff --git a/test/css/debug/linenumbers-all.css b/test/css/debug/linenumbers-all.css index 87022aecc..fe107c958 100644 --- a/test/css/debug/linenumbers-all.css +++ b/test/css/debug/linenumbers-all.css @@ -9,12 +9,12 @@ } /* line 15, {path}linenumbers.less */ @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { +.test-rule1 { color: black; } /* line 6, {path}linenumbers.less */ @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { +.test-rule2 { color: red; } @media all { @@ -33,17 +33,17 @@ /* line 9, {pathimport}test.less */ @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} .tst .tst3 { - color: white; + color: inherit; } } /* line 18, {pathimport}test.less */ @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} .tst2 { - color: white; + color: inherit; } /* line 27, {path}linenumbers.less */ @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000327}} -.test { +.test-rule { color: red; width: 2; } diff --git a/test/css/debug/linenumbers-comments.css b/test/css/debug/linenumbers-comments.css index e5d6bb385..083d93ee6 100644 --- a/test/css/debug/linenumbers-comments.css +++ b/test/css/debug/linenumbers-comments.css @@ -6,11 +6,11 @@ color: grey; } /* line 15, {path}linenumbers.less */ -.test1 { +.test-rule1 { color: black; } /* line 6, {path}linenumbers.less */ -.test2 { +.test-rule2 { color: red; } @media all { @@ -26,15 +26,15 @@ } /* line 9, {pathimport}test.less */ .tst .tst3 { - color: white; + color: inherit; } } /* line 18, {pathimport}test.less */ .tst2 { - color: white; + color: inherit; } /* line 27, {path}linenumbers.less */ -.test { +.test-rule { color: red; width: 2; } diff --git a/test/css/debug/linenumbers-mediaquery.css b/test/css/debug/linenumbers-mediaquery.css index e252ab3c2..488b29e5a 100644 --- a/test/css/debug/linenumbers-mediaquery.css +++ b/test/css/debug/linenumbers-mediaquery.css @@ -6,11 +6,11 @@ color: grey; } @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000315}} -.test1 { +.test-rule1 { color: black; } @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\000036}} -.test2 { +.test-rule2 { color: red; } @media all { @@ -26,15 +26,15 @@ } @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\000039}} .tst .tst3 { - color: white; + color: inherit; } } @media -sass-debug-info{filename{font-family:file\:\/\/{pathimportesc}test\.less}line{font-family:\0000318}} .tst2 { - color: white; + color: inherit; } @media -sass-debug-info{filename{font-family:file\:\/\/{pathesc}linenumbers\.less}line{font-family:\0000327}} -.test { +.test-rule { color: red; width: 2; } diff --git a/test/css/extend-chaining.css b/test/css/extend-chaining.css index 820e134f0..15028167d 100644 --- a/test/css/extend-chaining.css +++ b/test/css/extend-chaining.css @@ -15,7 +15,7 @@ } .i.j, .k.j { - color: white; + color: inherit; } .l, .m, @@ -58,7 +58,7 @@ } .vb, .vc { - color: white; + color: inherit; } @media tv { .ma, @@ -70,7 +70,7 @@ .ma, .mb, .mc { - color: white; + color: inherit; } } @media tv and plasma { diff --git a/test/css/extend-media.css b/test/css/extend-media.css index 23bd7b85c..0fbaed9c6 100644 --- a/test/css/extend-media.css +++ b/test/css/extend-media.css @@ -6,7 +6,7 @@ .ext1 .ext3, .tv-lowres .ext3, .all .ext3 { - color: white; + color: inherit; } .tv-lowres { background: blue; diff --git a/test/css/extend-nest.css b/test/css/extend-nest.css index 2c3905d95..e4b48a4be 100644 --- a/test/css/extend-nest.css +++ b/test/css/extend-nest.css @@ -28,7 +28,7 @@ } .button:hover, .submit:hover { - color: white; + color: inherit; } .button2 :hover { nested: white; diff --git a/test/css/filemanagerPlugin/filemanager.css b/test/css/filemanagerPlugin/filemanager.css index 6446ebfd4..aa9930dbf 100644 --- a/test/css/filemanagerPlugin/filemanager.css +++ b/test/css/filemanagerPlugin/filemanager.css @@ -1,3 +1,3 @@ -.test { +.test-rule { color: red; } diff --git a/test/css/functions-each.css b/test/css/functions-each.css index 89b90f30b..782dc3277 100644 --- a/test/css/functions-each.css +++ b/test/css/functions-each.css @@ -70,7 +70,7 @@ -less-log: c; -less-log: d; } -.test { +.test-rule { color: blue; color: red; } diff --git a/test/css/import-once.css b/test/css/import-once.css index 5c76f7329..a890f8aa0 100644 --- a/test/css/import-once.css +++ b/test/css/import-once.css @@ -7,12 +7,12 @@ body { width: 100%; } -.test-f { +.test-rule-f { height: 10px; } body { width: 100%; } -.test-f { +.test-rule-f { height: 10px; } diff --git a/test/css/import-reference-issues.css b/test/css/import-reference-issues.css index 34f481049..92daa29aa 100644 --- a/test/css/import-reference-issues.css +++ b/test/css/import-reference-issues.css @@ -1,4 +1,4 @@ -.test-c { +.test-rule-c { background-color: green; } .theOnlySelector { diff --git a/test/css/import-reference.css b/test/css/import-reference.css index f3d3b8763..a0d712457 100644 --- a/test/css/import-reference.css +++ b/test/css/import-reference.css @@ -1,8 +1,8 @@ input[type="text"].class#id[attr=32]:not(1) { - color: white; + color: inherit; } div#id.class[a=1][b=2].class:not(1) { - color: white; + color: inherit; } @media print { .class { @@ -65,19 +65,19 @@ div#id.class[a=1][b=2].class:not(1) { .visible { extend: test; } -.test-mediaq-import { +.test-rule-mediaq-import { color: green; test: 340px; } @media (max-size: 450px) { - .test-mediaq-import { + .test-rule-mediaq-import { color: red; } } -.test { +.test-rule { color: red; } -.test:first-child { +.test-rule:first-child { color: blue; } @keyframes some-name { diff --git a/test/css/import.css b/test/css/import.css index c991ca4ce..dafecc2f8 100644 --- a/test/css/import.css +++ b/test/css/import.css @@ -20,7 +20,7 @@ height: 10px; color: red; } -.test-f { +.test-rule-f { height: 10px; } .deep-import-url { diff --git a/test/css/javascript.css b/test/css/javascript.css index 9e33ac777..a0df43b72 100644 --- a/test/css/javascript.css +++ b/test/css/javascript.css @@ -22,7 +22,7 @@ ary: "1, 2, 3"; ary1: "1, 2, 3"; } -.test-tran { +.test-rule-tran { 1: opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear; 2: [opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear]; 3: opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear; diff --git a/test/css/legacy/legacy.css b/test/css/legacy/legacy.css index bd675a85b..8d24387b1 100644 --- a/test/css/legacy/legacy.css +++ b/test/css/legacy/legacy.css @@ -1,5 +1,5 @@ @media (-o-min-device-pixel-ratio: 2) { - .test-math-and-units { + .test-rule-math-and-units { font: ignores 0/0 rules; test-division: 7em; simple: 2px; diff --git a/test/css/math/parens-division/mixins-args.css b/test/css/math/parens-division/mixins-args.css index d95021eef..ca82850f1 100644 --- a/test/css/math/parens-division/mixins-args.css +++ b/test/css/math/parens-division/mixins-args.css @@ -104,7 +104,7 @@ body { four: a, 11, 12, 13; four: a, 21, 22, 23; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { defaults: 1px 1px 1px; defaults: 2px 2px 2px; } diff --git a/test/css/math/parens-division/parens.css b/test/css/math/parens-division/parens.css index 5e61728b6..86c9cbc96 100644 --- a/test/css/math/parens-division/parens.css +++ b/test/css/math/parens-division/parens.css @@ -32,6 +32,6 @@ margin: 2px 4em 1 5pc; padding: 6px 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: (; } diff --git a/test/css/math/strict-legacy/mixins-args.css b/test/css/math/strict-legacy/mixins-args.css index c97232b76..f5d37b20f 100644 --- a/test/css/math/strict-legacy/mixins-args.css +++ b/test/css/math/strict-legacy/mixins-args.css @@ -98,7 +98,7 @@ body { four: a, 11, 12, 13; four: a, 21, 22, 23; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { defaults: 1px 1px 1px; defaults: 2px 2px 2px; } diff --git a/test/css/math/strict-legacy/parens.css b/test/css/math/strict-legacy/parens.css index f880872fb..89fe108a3 100644 --- a/test/css/math/strict-legacy/parens.css +++ b/test/css/math/strict-legacy/parens.css @@ -35,6 +35,6 @@ margin: 2px 4em 1 5pc; padding: 6px 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: (; } diff --git a/test/css/math/strict/mixins-args.css b/test/css/math/strict/mixins-args.css index 82a3fd14b..138ce0ae3 100644 --- a/test/css/math/strict/mixins-args.css +++ b/test/css/math/strict/mixins-args.css @@ -104,7 +104,7 @@ body { four: a, 11, 12, 13; four: a, 21, 22, 23; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { defaults: 1px 1px 1px; defaults: 2px 2px 2px; } diff --git a/test/css/math/strict/parens.css b/test/css/math/strict/parens.css index f7b8f9776..c234b7bda 100644 --- a/test/css/math/strict/parens.css +++ b/test/css/math/strict/parens.css @@ -32,6 +32,6 @@ margin: 2px 4em 1 5pc; padding: 6px 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: (; } diff --git a/test/css/media.css b/test/css/media.css index 1e8e039a4..5c9a3cb9b 100644 --- a/test/css/media.css +++ b/test/css/media.css @@ -11,12 +11,12 @@ } } @media screen { - body { + .body { max-width: 480; } } @media all and (device-aspect-ratio: 16 / 9) { - body { + .body { max-width: 800px; } } @@ -26,20 +26,20 @@ } } @media handheld and (min-width: 42), screen and (min-width: 20em) { - body { + .body { max-width: 480px; } } @media print { - body { + .body { padding: 20px; } - body header { + .body header { background-color: red; } } @media print and (orientation: landscape) { - body { + .body { margin-left: 20px; } } @@ -67,12 +67,12 @@ } } @media a, b and c { - body { + .body { width: 95%; } } @media a and x, b and c and x, a and y, b and c and y { - body { + .body { width: 100%; } } @@ -103,7 +103,7 @@ } } @media only screen and (max-width: 200px) { - body { + .body { width: 480px; } } @@ -174,22 +174,22 @@ background: red; } } -body { +.body { background: red; } @media (max-width: 500px) { - body { + .body { background: green; } } @media (max-width: 1000px) { - body { + .body { background: red; background: blue; } } @media (max-width: 1000px) and (max-width: 500px) { - body { + .body { background: green; } } @@ -197,7 +197,7 @@ body { /* a comment */ } @media (max-width: 1200px) and (max-width: 900px) { - body { + .body { font-size: 11px; } } diff --git a/test/css/merge.css b/test/css/merge.css index b5d079b58..e02ff6300 100644 --- a/test/css/merge.css +++ b/test/css/merge.css @@ -1,35 +1,35 @@ -.test1 { +.test-rule1 { transform: rotate(90deg), skew(30deg), scale(2, 4); } -.test2 { +.test-rule2 { transform: rotate(90deg), skew(30deg); transform: scaleX(45deg); } -.test3 { +.test-rule3 { transform: scaleX(45deg); background: url(data://img1.png); } -.test4 { +.test-rule4 { transform: rotate(90deg), skew(30deg), scale(2, 4) !important; } -.test5 { +.test-rule5 { transform: rotate(90deg), skew(30deg), scale(2, 4) !important; } -.test6 { +.test-rule6 { transform: scale(2, 4); } -.test7 { +.test-rule7 { transform: scale(2, 4), scale(2, 4), scale(2, 4) !important; } -.test-interleaved { +.test-rule-interleaved { transform: t1, t2, t3; background: b1, b2, b3; } -.test-spaced { +.test-rule-spaced { transform: t1 t2 t3; background: b1 b2, b3; } -.test-interleaved-with-spaced { +.test-rule-interleaved-with-spaced { transform: t1s, t2 t3s, t4 t5s t6s; background: b1 b2s, b3, b4; } diff --git a/test/css/mixins-guards.css b/test/css/mixins-guards.css index 3b749af12..c54eca77e 100644 --- a/test/css/mixins-guards.css +++ b/test/css/mixins-guards.css @@ -1,5 +1,5 @@ .light1 { - color: white; + color: inherit; margin: 1px; } .light2 { @@ -32,19 +32,19 @@ .default1 { content: default; } -.test1 { +.test-rule1 { content: "true."; } -.test2 { +.test-rule2 { content: "false."; } -.test3 { +.test-rule3 { content: "false."; } -.test4 { +.test-rule4 { content: "false."; } -.test5 { +.test-rule5 { content: "false."; } .bool1 { diff --git a/test/css/mixins.css b/test/css/mixins.css index 4d9824f5c..c9087c0a7 100644 --- a/test/css/mixins.css +++ b/test/css/mixins.css @@ -29,7 +29,7 @@ background-color: grey; } #header .milk { - color: white; + color: inherit; border: 1px solid black; background-color: grey; } @@ -133,7 +133,7 @@ h3 + * { background-image: "/a.png"; background-position: center center; } -.test-rec .recursion { +.test-rule-rec .recursion { color: black; } .button { diff --git a/test/css/namespacing/namespacing-3.css b/test/css/namespacing/namespacing-3.css index bf74b37dd..d56f639f9 100644 --- a/test/css/namespacing/namespacing-3.css +++ b/test/css/namespacing/namespacing-3.css @@ -3,7 +3,7 @@ width: 400px; height: 200px; background: red; - color: white; + color: inherit; } } .cell { diff --git a/test/css/namespacing/namespacing-4.css b/test/css/namespacing/namespacing-4.css index 4820798f0..a0f0dddf7 100644 --- a/test/css/namespacing/namespacing-4.css +++ b/test/css/namespacing/namespacing-4.css @@ -1,5 +1,5 @@ .foo { width: 20px; background: rebeccapurple; - color: white; + color: inherit; } diff --git a/test/css/no-strict-math/mixins-guards.css b/test/css/no-strict-math/mixins-guards.css index 81a2d7f9e..755619937 100644 --- a/test/css/no-strict-math/mixins-guards.css +++ b/test/css/no-strict-math/mixins-guards.css @@ -1,4 +1,4 @@ -.test-2798 { +.test-rule-2798 { regression: fixed; } .conditions-parser-1 { diff --git a/test/css/permissive-parse.css b/test/css/permissive-parse.css index 00b9772fd..58eb55e60 100644 --- a/test/css/permissive-parse.css +++ b/test/css/permissive-parse.css @@ -31,7 +31,7 @@ foo[attr="blah"] { this: works; } } -.test-comment { +.test-rule-comment { --value: a /* { ; } */; --comment-within: ( /* okay?; comment; */ ); } diff --git a/test/css/plugin.css b/test/css/plugin.css index 9dafc4390..0201704ad 100644 --- a/test/css/plugin.css +++ b/test/css/plugin.css @@ -26,7 +26,7 @@ class-local: test-local(); } @media screen { - .test { + .test-rule { result: global; } } @@ -34,36 +34,36 @@ result: global; } @media screen and (min-width: 100px) and (max-width: 400px) { - .test { + .test-rule { result: global; } } @media screen { - .test { + .test-rule { result: local; } } .root { prop: value; } -.test-empty { +.test-rule-empty { val1: foo; val2: foo; } -.test-simple { +.test-rule-simple { value: 3.141592653589793; value: 6.28318531; } -.test-conflicts { +.test-rule-conflicts { value: foo; } -.test-conflicts { +.test-rule-conflicts { value: bar; } -.test-conflicts { +.test-rule-conflicts { value: foo; } -.test-collection { +.test-rule-collection { list: 32, 5, "bird"; } @arbitrary value after (); diff --git a/test/css/postProcessorPlugin/postProcessor.css b/test/css/postProcessorPlugin/postProcessor.css index 8e5489486..1b2413ac4 100644 --- a/test/css/postProcessorPlugin/postProcessor.css +++ b/test/css/postProcessorPlugin/postProcessor.css @@ -1,4 +1,4 @@ hr {height:50px;} -.test { - color: white; +.test-rule { + color: inherit; } diff --git a/test/css/preProcessorPlugin/preProcessor.css b/test/css/preProcessorPlugin/preProcessor.css index 6446ebfd4..aa9930dbf 100644 --- a/test/css/preProcessorPlugin/preProcessor.css +++ b/test/css/preProcessorPlugin/preProcessor.css @@ -1,3 +1,3 @@ -.test { +.test-rule { color: red; } diff --git a/test/css/selectors.css b/test/css/selectors.css index f0992a5cd..046e59a77 100644 --- a/test/css/selectors.css +++ b/test/css/selectors.css @@ -125,10 +125,10 @@ p a span { :nth-child(3) { selector: interpolated; } -.test:nth-child(3) { +.test-rule:nth-child(3) { selector: interpolated; } -.test:nth-child(odd):not(:nth-child(3)) { +.test-rule:nth-child(odd):not(:nth-child(3)) { color: #ff0000; } [prop], diff --git a/test/css/variables.css b/test/css/variables.css index b99d779ed..fa03b1eb7 100644 --- a/test/css/variables.css +++ b/test/css/variables.css @@ -37,7 +37,7 @@ .alpha { filter: alpha(opacity=42); } -.testPollution { +.test-rulePollution { a: 'no-pollution'; } .units { diff --git a/test/css/visitorPlugin/visitor.css b/test/css/visitorPlugin/visitor.css index 6446ebfd4..aa9930dbf 100644 --- a/test/css/visitorPlugin/visitor.css +++ b/test/css/visitorPlugin/visitor.css @@ -1,3 +1,3 @@ -.test { +.test-rule { color: red; } diff --git a/test/less/comments.less b/test/less/comments.less index f33bd6773..900d77da3 100644 --- a/test/less/comments.less +++ b/test/less/comments.less @@ -71,7 +71,7 @@ @b: 1px //put in @b - causes problems! ---> ) // the when (@a = white) { - .test { + .test-rule { color: @b; } } diff --git a/test/less/css-3.less b/test/less/css-3.less index 999e8019b..480a98826 100644 --- a/test/less/css-3.less +++ b/test/less/css-3.less @@ -20,25 +20,25 @@ p:not([class*="lead"]) { } input[type="text"].class#id[attr=32]:not(1) { - color: white; + color: inherit; } div#id.class[a=1][b=2].class:not(1) { - color: white; + color: inherit; } ul.comma > li:not(:only-child)::after { - color: white; + color: inherit; } ol.comma > li:nth-last-child(2)::after { - color: white; + color: inherit; } li:nth-child(4n+1), li:nth-child(-5n), li:nth-child(-n+2) { - color: white; + color: inherit; } a[href^="http://"] { diff --git a/test/less/css-guards.less b/test/less/css-guards.less index cabd52a5b..95cd3d60b 100644 --- a/test/less/css-guards.less +++ b/test/less/css-guards.less @@ -31,7 +31,7 @@ @d: 3; .inheritance when (@b = 2) { - .test { + .test-rule { color: black; } &:hover { @@ -46,7 +46,7 @@ } .hideme when (@b = 1) { - .test { + .test-rule { color: black; } &:hover { diff --git a/test/less/debug/import/test.less b/test/less/debug/import/test.less index 795082f5a..ce3dfac0f 100644 --- a/test/less/debug/import/test.less +++ b/test/less/debug/import/test.less @@ -7,7 +7,7 @@ @media screen { color: red; .tst3 { - color: white; + color: inherit; } } } @@ -16,7 +16,7 @@ .mixin_import2() { .tst2 { - color: white; + color: inherit; } } diff --git a/test/less/debug/linenumbers.less b/test/less/debug/linenumbers.less index 3bcaed014..b3760d40f 100644 --- a/test/less/debug/linenumbers.less +++ b/test/less/debug/linenumbers.less @@ -3,7 +3,7 @@ @import "import/test.less"; .start() { - .test2 { + .test-rule2 { color: red; } } @@ -12,7 +12,7 @@ color: black; } -.test1 { +.test-rule1 { .mix(); } @@ -24,7 +24,7 @@ @debug: 1; & when (@debug = 1) { - .test { + .test-rule { color: red; & when (@debug = 1) { width: 2; diff --git a/test/less/errors/color-func-invalid-color.less b/test/less/errors/color-func-invalid-color.less index 5a1edd011..5b7c8084f 100644 --- a/test/less/errors/color-func-invalid-color.less +++ b/test/less/errors/color-func-invalid-color.less @@ -1,3 +1,3 @@ -.test { +.test-rule { color: color("NOT A COLOR"); } \ No newline at end of file diff --git a/test/less/errors/color-func-invalid-color.txt b/test/less/errors/color-func-invalid-color.txt index e5d916c68..c96013034 100644 --- a/test/less/errors/color-func-invalid-color.txt +++ b/test/less/errors/color-func-invalid-color.txt @@ -1,4 +1,4 @@ ArgumentError: error evaluating function `color`: argument must be a color keyword or 3|4|6|8 digit hex e.g. #FFF in {path}color-func-invalid-color.less on line 2, column 10: -1 .test { +1 .test-rule { 2 color: color("NOT A COLOR"); 3 } diff --git a/test/less/errors/plugin-1.txt b/test/less/errors/plugin-1.txt index bc4dae7bf..66a2bb163 100644 --- a/test/less/errors/plugin-1.txt +++ b/test/less/errors/plugin-1.txt @@ -1,2 +1,2 @@ -SyntaxError: Error in {path}plugin-error.js{node} on line 1, column 8: -1 throw new Error('Error');{/node} +SyntaxError: Error in {path}plugin-error.js on line 1, column 8: +1 throw new Error('Error'); diff --git a/test/less/errors/plugin-2.txt b/test/less/errors/plugin-2.txt index 13bc2e00f..61a838984 100644 --- a/test/less/errors/plugin-2.txt +++ b/test/less/errors/plugin-2.txt @@ -1,5 +1,4 @@ -SyntaxError: An error was here. in {path}plugin-error-2.js{node} on line 3, column 16: +SyntaxError: An error was here. in {path}plugin-error-2.js on line 3, column 16: 2 use: function() { 3 throw new Error('An error was here.') 4 } -{/node} \ No newline at end of file diff --git a/test/less/errors/plugin-3.txt b/test/less/errors/plugin-3.txt index 10bddea70..167218437 100644 --- a/test/less/errors/plugin-3.txt +++ b/test/less/errors/plugin-3.txt @@ -1,5 +1,4 @@ -SyntaxError: Plugin error during evaluation in {path}plugin-error-3.js{node} on line 3, column 16: +SyntaxError: Plugin error during evaluation in {path}plugin-error-3.js on line 3, column 16: 2 eval: function() { 3 throw new Error('An error was here.') 4 } -{/node} \ No newline at end of file diff --git a/test/less/errors/property-ie5-hack.less b/test/less/errors/property-ie5-hack.less index 51bf6e397..bf0fe0d90 100644 --- a/test/less/errors/property-ie5-hack.less +++ b/test/less/errors/property-ie5-hack.less @@ -1,3 +1,3 @@ -.test { +.test-rule { display/*/: block; /*sorry for IE5*/ } \ No newline at end of file diff --git a/test/less/extend-chaining.less b/test/less/extend-chaining.less index ac8a475b1..e62b67651 100644 --- a/test/less/extend-chaining.less +++ b/test/less/extend-chaining.less @@ -19,7 +19,7 @@ color: black; } .i.j:extend(.g all) { - color: white; + color: inherit; } .k:extend(.i all) {} @@ -65,7 +65,7 @@ } .vb { &:extend(.va); - color: white; + color: inherit; } .vc { &:extend(.vb); @@ -78,7 +78,7 @@ color: black; } .md { - color: white; + color: inherit; } @media plasma { .me, .mf { diff --git a/test/less/extend-media.less b/test/less/extend-media.less index 1b22c3faf..b54427363 100644 --- a/test/less/extend-media.less +++ b/test/less/extend-media.less @@ -4,7 +4,7 @@ @media tv { .ext1 .ext3 { - color: white; + color: inherit; } .tv-lowres :extend(.ext1 all) { background: blue; diff --git a/test/less/extend-nest.less b/test/less/extend-nest.less index 9d4d27bbc..67243bfe4 100644 --- a/test/less/extend-nest.less +++ b/test/less/extend-nest.less @@ -31,7 +31,7 @@ .button { color: black; &:hover { - color: white; + color: inherit; } } .submit { diff --git a/test/less/filemanagerPlugin/filemanager.less b/test/less/filemanagerPlugin/filemanager.less index 1a35c67ab..36e8db86d 100644 --- a/test/less/filemanagerPlugin/filemanager.less +++ b/test/less/filemanagerPlugin/filemanager.less @@ -1,4 +1,4 @@ @import "test.test"; -.test { +.test-rule { color: @color; } diff --git a/test/less/functions-each.less b/test/less/functions-each.less index 6d800c4f1..d15b35587 100644 --- a/test/less/functions-each.less +++ b/test/less/functions-each.less @@ -110,7 +110,7 @@ each(range(10px, 30px, 10px), .(@val, @index) { @color: red; } } -.test { +.test-rule { each(primary secondary, .(@color-name) { @scheme: @color-schemes[@@color-name]; // e.g. @color-name = primary color: @scheme[@color]; diff --git a/test/less/import-reference-issues.less b/test/less/import-reference-issues.less index 74e02ce75..f35e90feb 100644 --- a/test/less/import-reference-issues.less +++ b/test/less/import-reference-issues.less @@ -32,8 +32,8 @@ show-all-content { // #1851: Extend within (reference) imported files // test-b is in global-scope-import.less file -.test-c { - &:extend(.test-b all); +.test-rule-c { + &:extend(.test-rule-b all); } // #1968: When using an @import (reference), mixins that contain an & selector get added to the compiled output improperly diff --git a/test/less/import-reference-issues/global-scope-import.less b/test/less/import-reference-issues/global-scope-import.less index a7f8c854f..8a2168b55 100644 --- a/test/less/import-reference-issues/global-scope-import.less +++ b/test/less/import-reference-issues/global-scope-import.less @@ -7,7 +7,7 @@ @import (reference) "global-scope-nested.less"; -.test-b { +.test-rule-b { background-color: green; - &:extend(.test-a all); + &:extend(.test-rule-a all); } diff --git a/test/less/import-reference-issues/global-scope-nested.less b/test/less/import-reference-issues/global-scope-nested.less index afc6ab043..93e1309a5 100644 --- a/test/less/import-reference-issues/global-scope-nested.less +++ b/test/less/import-reference-issues/global-scope-nested.less @@ -1,3 +1,3 @@ -.test-a { +.test-rule-a { color: red; } diff --git a/test/less/import-reference.less b/test/less/import-reference.less index 1ad02f415..9625cc527 100644 --- a/test/less/import-reference.less +++ b/test/less/import-reference.less @@ -14,7 +14,7 @@ extend: test; } -.test-mediaq-import { +.test-rule-mediaq-import { .mixin-with-mediaq(340px); } diff --git a/test/less/import/import-reference.less b/test/less/import/import-reference.less index fe595e1be..c545f2667 100644 --- a/test/less/import/import-reference.less +++ b/test/less/import/import-reference.less @@ -65,7 +65,7 @@ } //https://github.com/less/less.js/issues/1979 .mixin-with-nested-selectors() { - .test { + .test-rule { color: red; &:first-child { color: blue; diff --git a/test/less/import/import-test-f.less b/test/less/import/import-test-f.less index fad630f9c..f7bd660d1 100644 --- a/test/less/import/import-test-f.less +++ b/test/less/import/import-test-f.less @@ -1,5 +1,5 @@ @import "import-test-e"; -.test-f { +.test-rule-f { height: 10px; } diff --git a/test/less/javascript.less b/test/less/javascript.less index 505090cdb..61049dbb0 100644 --- a/test/less/javascript.less +++ b/test/less/javascript.less @@ -34,6 +34,6 @@ 2: ~`"@{arguments}"`; // rounded to integers 3: @arguments; // OK } -.test-tran { +.test-rule-tran { .transitions(opacity 0.3s ease-in 0.3s, max-height 0.6s linear, margin-bottom 0.4s linear;); } diff --git a/test/less/legacy/legacy.less b/test/less/legacy/legacy.less index 654b2040d..b4502d343 100644 --- a/test/less/legacy/legacy.less +++ b/test/less/legacy/legacy.less @@ -1,5 +1,5 @@ @media (-o-min-device-pixel-ratio: 2) { - .test-math-and-units { + .test-rule-math-and-units { font: ignores 0/0 rules; test-division: 4 / 2 + 5em; simple: 1px + 1px; diff --git a/test/less/math/parens-division/mixins-args.less b/test/less/math/parens-division/mixins-args.less index 7b1bef0e0..fe006de9e 100644 --- a/test/less/math/parens-division/mixins-args.less +++ b/test/less/math/parens-division/mixins-args.less @@ -181,7 +181,7 @@ body { defaults: 2px 2px 2px; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { .mixin-default-arg(); .mixin-default-arg(2px); } @@ -205,14 +205,14 @@ body { .mixin-comma-default3(4,2,2,2); } -.test-calling-one-arg-mixin(@a) { +.test-rule-calling-one-arg-mixin(@a) { } -.test-calling-one-arg-mixin(@a, @b, @rest...) { +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { } div { - .test-calling-one-arg-mixin(1); + .test-rule-calling-one-arg-mixin(1); } mixins-args-expand-op- { diff --git a/test/less/math/parens-division/parens.less b/test/less/math/parens-division/parens.less index becbd04e6..947a2c14f 100644 --- a/test/less/math/parens-division/parens.less +++ b/test/less/math/parens-division/parens.less @@ -41,6 +41,6 @@ padding: (2px + 4px) 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: ~"("; } diff --git a/test/less/math/strict-legacy/mixins-args.less b/test/less/math/strict-legacy/mixins-args.less index 57f5a5b45..1bc868a59 100644 --- a/test/less/math/strict-legacy/mixins-args.less +++ b/test/less/math/strict-legacy/mixins-args.less @@ -180,7 +180,7 @@ body { defaults: 2px 2px 2px; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { .mixin-default-arg(); .mixin-default-arg(2px); } @@ -204,14 +204,14 @@ body { .mixin-comma-default3(4,2,2,2); } -.test-calling-one-arg-mixin(@a) { +.test-rule-calling-one-arg-mixin(@a) { } -.test-calling-one-arg-mixin(@a, @b, @rest...) { +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { } div { - .test-calling-one-arg-mixin(1); + .test-rule-calling-one-arg-mixin(1); } mixins-args-expand-op- { diff --git a/test/less/math/strict-legacy/parens.less b/test/less/math/strict-legacy/parens.less index 012142545..4520119fc 100644 --- a/test/less/math/strict-legacy/parens.less +++ b/test/less/math/strict-legacy/parens.less @@ -45,6 +45,6 @@ padding: (2px + 4px) 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: ~"("; } diff --git a/test/less/math/strict/mixins-args.less b/test/less/math/strict/mixins-args.less index 7b1bef0e0..fe006de9e 100644 --- a/test/less/math/strict/mixins-args.less +++ b/test/less/math/strict/mixins-args.less @@ -181,7 +181,7 @@ body { defaults: 2px 2px 2px; } -.test-mixin-default-arg { +.test-rule-mixin-default-arg { .mixin-default-arg(); .mixin-default-arg(2px); } @@ -205,14 +205,14 @@ body { .mixin-comma-default3(4,2,2,2); } -.test-calling-one-arg-mixin(@a) { +.test-rule-calling-one-arg-mixin(@a) { } -.test-calling-one-arg-mixin(@a, @b, @rest...) { +.test-rule-calling-one-arg-mixin(@a, @b, @rest...) { } div { - .test-calling-one-arg-mixin(1); + .test-rule-calling-one-arg-mixin(1); } mixins-args-expand-op- { diff --git a/test/less/math/strict/parens.less b/test/less/math/strict/parens.less index becbd04e6..947a2c14f 100644 --- a/test/less/math/strict/parens.less +++ b/test/less/math/strict/parens.less @@ -41,6 +41,6 @@ padding: (2px + 4px) 1em 2px 2; } -.test-false-negatives { +.test-rule-false-negatives { a: ~"("; } diff --git a/test/less/media.less b/test/less/media.less index f727d59e5..e5eb3022c 100644 --- a/test/less/media.less +++ b/test/less/media.less @@ -17,14 +17,14 @@ @media screen { @base: 8; - body { max-width: (@base * 60); } + .body { max-width: (@base * 60); } } @ratio_large: 16; @ratio_small: 9; @media all and (device-aspect-ratio: ~'@{ratio_large} / @{ratio_small}') { - body { max-width: 800px; } + .body { max-width: 800px; } } @media all and (orientation:portrait) { @@ -32,12 +32,12 @@ } @media handheld and (min-width: @var), screen and (min-width: 20em) { - body { + .body { max-width: 480px; } } -body { +.body { @media print { padding: 20px; @@ -78,7 +78,7 @@ body { } } -body { +.body { @media a, b and c { width: 95%; @@ -109,7 +109,7 @@ body { } @smartphone: ~"only screen and (max-width: 200px)"; @media @smartphone { - body { + .body { width: 480px; } } @@ -191,13 +191,13 @@ body { } } -body { +.body { .bg(); } @bpMedium: 1000px; @media (max-width: @bpMedium) { - body { + .body { .bg(); background: blue; } @@ -207,7 +207,7 @@ body { /* a comment */ @media (max-width: 900px) { - body { font-size: 11px; } + .body { font-size: 11px; } } } diff --git a/test/less/merge.less b/test/less/merge.less index 7cac833b6..d7f7cc5e5 100644 --- a/test/less/merge.less +++ b/test/less/merge.less @@ -20,40 +20,40 @@ background+: url(data://img2.png); } -.test1 { +.test-rule1 { // Can merge values .first-transform(); .second-transform(); } -.test2 { +.test-rule2 { // Won't merge values without +: merge directive, for backwards compatibility with css .first-transform(); .third-transform(); } -.test3 { +.test-rule3 { // Won't merge values from two sources with different properties .fourth-transform(); .first-background(); } -.test4 { +.test-rule4 { .first-transform(); .fifth-transform(); } -.test5 { +.test-rule5 { .first-transform(); .second-transform() !important; } -.test6 { +.test-rule6 { .second-transform(); } -.test7 { +.test-rule7 { // inherit !important from merged subrules .second-transform(); .second-transform() !important; .second-transform(); } -.test-interleaved { +.test-rule-interleaved { transform+: t1; background+: b1; transform+: t2; @@ -61,7 +61,7 @@ transform+: t3; } -.test-spaced { +.test-rule-spaced { transform+_: t1; background+_: b1; transform+_: t2; @@ -69,7 +69,7 @@ transform+_: t3; } -.test-interleaved-with-spaced { +.test-rule-interleaved-with-spaced { transform+_: t1s; transform+: t2; background+: b1; diff --git a/test/less/mixins-guards.less b/test/less/mixins-guards.less index 31ad088e4..338ece786 100644 --- a/test/less/mixins-guards.less +++ b/test/less/mixins-guards.less @@ -2,7 +2,7 @@ // Stacking, functions.. .light (@a) when (lightness(@a) > 50%) { - color: white; + color: inherit; } .light (@a) when (lightness(@a) < 50%) { color: black; @@ -63,18 +63,18 @@ .default1 { .default } // true & false keywords -.test (@a) when (@a) { +.test-rule (@a) when (@a) { content: "true."; } -.test (@a) when not (@a) { +.test-rule (@a) when not (@a) { content: "false."; } -.test1 { .test(true) } -.test2 { .test(false) } -.test3 { .test(1) } -.test4 { .test(boo) } -.test5 { .test("true") } +.test-rule1 { .test-rule(true) } +.test-rule2 { .test-rule(false) } +.test-rule3 { .test-rule(1) } +.test-rule4 { .test-rule(boo) } +.test-rule5 { .test-rule("true") } // Boolean expressions diff --git a/test/less/mixins-important.less b/test/less/mixins-important.less index 9f60efff9..ecdb29234 100644 --- a/test/less/mixins-important.less +++ b/test/less/mixins-important.less @@ -35,7 +35,7 @@ .when-calling-nested-with-param-issue-2394 { .size(10px) !important; } -.testMixin-2421 () { +.test-ruleMixin-2421 () { .topCheck-2421 () { .nestedCheck-2421() { margin: 5px; @@ -45,9 +45,9 @@ .topCheck-2421(); } .class1-2421 { - .testMixin-2421() !important; + .test-ruleMixin-2421() !important; } .class2-2421 { - .testMixin-2421(); + .test-ruleMixin-2421(); } diff --git a/test/less/mixins.less b/test/less/mixins.less index 15d511f63..7ffa9dacc 100644 --- a/test/less/mixins.less +++ b/test/less/mixins.less @@ -28,7 +28,7 @@ #header { .milk { - color: white; + color: inherit; .mixin; #theme > .mixin; } @@ -119,7 +119,7 @@ h3 { .margin_between(15px, 5px); } .recursion() { color: black; } -.test-rec { +.test-rule-rec { .recursion { .recursion(); } diff --git a/test/less/namespacing/namespacing-3.less b/test/less/namespacing/namespacing-3.less index 17ec101f2..f184f6904 100644 --- a/test/less/namespacing/namespacing-3.less +++ b/test/less/namespacing/namespacing-3.less @@ -2,7 +2,7 @@ @width: 400px; @colors: { toolbar-background: red; - toolbar-foreground: white; + toolbar-foreground: inherit; } }; diff --git a/test/less/namespacing/namespacing-4.less b/test/less/namespacing/namespacing-4.less index cee882daf..cbd32a277 100644 --- a/test/less/namespacing/namespacing-4.less +++ b/test/less/namespacing/namespacing-4.less @@ -12,7 +12,7 @@ .core() { .colors() { primary: blue; - foreground: white; + foreground: inherit; } } } diff --git a/test/less/namespacing/namespacing-5.less b/test/less/namespacing/namespacing-5.less index efacbd929..5a8391477 100644 --- a/test/less/namespacing/namespacing-5.less +++ b/test/less/namespacing/namespacing-5.less @@ -8,7 +8,7 @@ primary: black; secondary: grey; } - .test() { + .test-rule() { val: output; } } @@ -16,7 +16,7 @@ .my-navbar { #theme.dark.navbar(); background: .colors[primary]; - .test(); + .test-rule(); } .another-navbar { diff --git a/test/less/no-strict-math/mixins-guards.less b/test/less/no-strict-math/mixins-guards.less index aa2a00588..9774e117e 100644 --- a/test/less/no-strict-math/mixins-guards.less +++ b/test/less/no-strict-math/mixins-guards.less @@ -1,8 +1,8 @@ // https://github.com/less/less.js/issues/2798 -.test-2798 when ((8+4) < 13) { +.test-rule-2798 when ((8+4) < 13) { regression: fixed; } -.test-2798 when ((8+6) < 13) { +.test-rule-2798 when ((8+6) < 13) { regression: should not be visible; } .conditions-parser-1 when (8+4 < 13) { diff --git a/test/less/permissive-parse.less b/test/less/permissive-parse.less index db2909ba7..67b1b4211 100644 --- a/test/less/permissive-parse.less +++ b/test/less/permissive-parse.less @@ -44,7 +44,7 @@ } } // @todo - fix comment absorption after property -.test-comment { +.test-rule-comment { --value: a/* { ; } */; --comment-within: ( /* okay?; comment; */ ); } \ No newline at end of file diff --git a/test/less/plugin.less b/test/less/plugin.less index 0d86bc8d7..19b02edaa 100644 --- a/test/less/plugin.less +++ b/test/less/plugin.less @@ -57,7 +57,7 @@ // `test-global` function should propagate into directive scope @media screen { - .test { + .test-rule { result : test-global(); } } @@ -68,13 +68,13 @@ // `test-global` function should propagate into nested directive scopes @media screen and (min-width:100px) { @media (max-width:400px) { - .test { + .test-rule { result : test-global(); } } } -.test { +.test-rule { @media screen { @plugin "./plugin/plugin-local"; result : test-local(); @@ -86,29 +86,29 @@ .root { @ruleset2(); } -.test-empty { +.test-rule-empty { val1: foo; test-collapse(); val2: foo; } -.test-simple { +.test-rule-simple { @plugin "./plugin/plugin-simple"; value: pi-anon(); value: (pi() * 2); } -.test-conflicts { +.test-rule-conflicts { @plugin "./plugin/plugin-scope1"; value: foo(); } -.test-conflicts { +.test-rule-conflicts { @plugin "./plugin/plugin-scope2"; value: foo(); } -.test-conflicts { +.test-rule-conflicts { @plugin "./plugin/plugin-scope1"; value: foo(); } -.test-collection { +.test-rule-collection { @plugin "./plugin/plugin-collection"; @var: 32; store(@var); diff --git a/test/less/postProcessorPlugin/postProcessor.less b/test/less/postProcessorPlugin/postProcessor.less index 0d4c0304d..143ad879a 100644 --- a/test/less/postProcessorPlugin/postProcessor.less +++ b/test/less/postProcessorPlugin/postProcessor.less @@ -1,4 +1,4 @@ -@color: white; -.test { +@color: inherit; +.test-rule { color: @color; } diff --git a/test/less/preProcessorPlugin/preProcessor.less b/test/less/preProcessorPlugin/preProcessor.less index 50183ea28..d2db12596 100644 --- a/test/less/preProcessorPlugin/preProcessor.less +++ b/test/less/preProcessorPlugin/preProcessor.less @@ -1,3 +1,3 @@ -.test { +.test-rule { color: @color; } diff --git a/test/less/selectors.less b/test/less/selectors.less index 45b2e9afa..1b3cf769e 100644 --- a/test/less/selectors.less +++ b/test/less/selectors.less @@ -125,7 +125,7 @@ a { :nth-child(@{num}) { selector: interpolated; } -.test { +.test-rule { &:nth-child(@{num}) { selector: interpolated; } diff --git a/test/less/sourcemaps/imported.css b/test/less/sourcemaps/imported.css index 2ee35f066..eec262eef 100644 --- a/test/less/sourcemaps/imported.css +++ b/test/less/sourcemaps/imported.css @@ -1,6 +1,6 @@ /*comments*/ .unused-css { - color: white; + color: inherit; } .imported { color: black; diff --git a/test/less/variables.less b/test/less/variables.less index 465311655..ae8c9be45 100644 --- a/test/less/variables.less +++ b/test/less/variables.less @@ -86,7 +86,7 @@ .polluteMixin() { @a: 'pollution'; } -.testPollution { +.test-rulePollution { @a: 'no-pollution'; a: @a; .polluteMixin(); diff --git a/test/less/visitorPlugin/visitor.less b/test/less/visitorPlugin/visitor.less index bd2da3e8e..2f7b1bd54 100644 --- a/test/less/visitorPlugin/visitor.less +++ b/test/less/visitorPlugin/visitor.less @@ -1,4 +1,4 @@ -.test { +.test-rule { color: red; -some-aribitrary-property: value; }