[
  {
    "path": ".editorconfig",
    "content": "root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\nindent_style = tab\ninsert_final_newline = true\ntrim_trailing_whitespace = true\n\n[*.md]\ntrim_trailing_whitespace = false\n\n[*.{json,md,yml}]\nindent_size = 2\nindent_style = space\n"
  },
  {
    "path": ".gitignore",
    "content": "node_modules\nindex.*.*\npackage-lock.json\n*.log*\n*.result.css\n.*\n!.editorconfig\n!.gitignore\n!.rollup.js\n!.tape.js\n!.travis.yml\n"
  },
  {
    "path": ".rollup.js",
    "content": "import babel from '@rollup/plugin-babel';\n\nexport default {\n\tinput: 'index.js',\n\toutput: [\n\t\t{ file: 'index.cjs.js', format: 'cjs', sourcemap: true, exports: 'default' },\n\t\t{ file: 'index.es.mjs', format: 'es', sourcemap: true, exports: 'default' }\n\t],\n\tplugins: [\n\t\tbabel({\n\t\t\tbabelHelpers: 'bundled',\n\t\t\tplugins: [\n\t\t\t\t'@babel/plugin-syntax-dynamic-import'\n\t\t\t],\n\t\t\tpresets: [\n\t\t\t\t['@babel/env', { modules: false, targets: { node: 10 } }]\n\t\t\t]\n\t\t})\n\t]\n};\n"
  },
  {
    "path": ".tape.js",
    "content": "module.exports = {\n\t'basic': {\n\t\tmessage: 'supports basic usage'\n\t},\n\t'basic:preserve': {\n\t\tmessage: 'supports { preserve: true } usage',\n\t\toptions: {\n\t\t\tpreserve: true\n\t\t}\n\t},\n\t'import': {\n\t\tmessage: 'supports { importFrom: { customMedia: { ... } } } usage',\n\t\toptions: {\n\t\t\timportFrom: {\n\t\t\t\tcustomMedia: {\n\t\t\t\t\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t\t\t\t\t'--not-mq-a': 'not all and (--mq-a)'\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\t'import:import-fn': {\n\t\tmessage: 'supports { importFrom() } usage',\n\t\toptions: {\n\t\t\timportFrom() {\n\t\t\t\treturn {\n\t\t\t\t\tcustomMedia: {\n\t\t\t\t\t\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t\t\t\t\t\t'--not-mq-a': 'not all and (--mq-a)'\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t}\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:import-fn-promise': {\n\t\tmessage: 'supports { async importFrom() } usage',\n\t\toptions: {\n\t\t\timportFrom() {\n\t\t\t\treturn new Promise(resolve => {\n\t\t\t\t\tresolve({\n\t\t\t\t\t\tcustomMedia: {\n\t\t\t\t\t\t\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t\t\t\t\t\t\t'--not-mq-a': 'not all and (--mq-a)'\n\t\t\t\t\t\t}\n\t\t\t\t\t})\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:json': {\n\t\tmessage: 'supports { importFrom: \"test/import-media.json\" } usage',\n\t\toptions: {\n\t\t\timportFrom: 'test/import-media.json'\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:js': {\n\t\tmessage: 'supports { importFrom: \"test/import-media.js\" } usage',\n\t\toptions: {\n\t\t\timportFrom: 'test/import-media.js'\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:css': {\n\t\tmessage: 'supports { importFrom: \"test/import-media.css\" } usage',\n\t\toptions: {\n\t\t\timportFrom: 'test/import-media.css'\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:css-from': {\n\t\tmessage: 'supports { importFrom: { from: \"test/import-media.css\" } } usage',\n\t\toptions: {\n\t\t\timportFrom: { from: 'test/import-media.css' }\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:css-from-type': {\n\t\tmessage: 'supports { importFrom: [ { from: \"test/import-media.css\", type: \"css\" } ] } usage',\n\t\toptions: {\n\t\t\timportFrom: [ { from: 'test/import-media.css', type: 'css' } ]\n\t\t},\n\t\texpect: 'import.expect.css',\n\t\tresult: 'import.result.css'\n\t},\n\t'import:empty': {\n\t\tmessage: 'supports { importFrom: {} } usage',\n\t\toptions: {\n\t\t\timportFrom: {}\n\t\t}\n\t},\n\t'basic:export': {\n\t\tmessage: 'supports { exportTo: { customMedia: { ... } } } usage',\n\t\toptions: {\n\t\t\texportTo: (global.__exportMediaObject = global.__exportMediaObject || {\n\t\t\t\tcustomMedia: null\n\t\t\t})\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tafter() {\n\t\t\tif (__exportMediaObject.customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') {\n\t\t\t\tthrow new Error('The exportTo function failed');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-fn': {\n\t\tmessage: 'supports { exportTo() } usage',\n\t\toptions: {\n\t\t\texportTo(customMedia) {\n\t\t\t\tif (customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') {\n\t\t\t\t\tthrow new Error('The exportTo function failed');\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css'\n\t},\n\t'basic:export-fn-promise': {\n\t\tmessage: 'supports { async exportTo() } usage',\n\t\toptions: {\n\t\t\texportTo(customMedia) {\n\t\t\t\treturn new Promise((resolve, reject) => {\n\t\t\t\t\tif (customMedia['--mq-a'] !== '(max-width: 30em), (max-height: 30em)') {\n\t\t\t\t\t\treject('The exportTo function failed');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tresolve();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css'\n\t},\n\t'basic:export-json': {\n\t\tmessage: 'supports { exportTo: \"test/export-media.json\" } usage',\n\t\toptions: {\n\t\t\texportTo: 'test/export-media.json'\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.json', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.json', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-js': {\n\t\tmessage: 'supports { exportTo: \"test/export-media.js\" } usage',\n\t\toptions: {\n\t\t\texportTo: 'test/export-media.js'\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.js', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.js', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-mjs': {\n\t\tmessage: 'supports { exportTo: \"test/export-media.mjs\" } usage',\n\t\toptions: {\n\t\t\texportTo: 'test/export-media.mjs'\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.mjs', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.mjs', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-css': {\n\t\tmessage: 'supports { exportTo: \"test/export-media.css\" } usage',\n\t\toptions: {\n\t\t\texportTo: 'test/export-media.css'\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-css-to': {\n\t\tmessage: 'supports { exportTo: { to: \"test/export-media.css\" } } usage',\n\t\toptions: {\n\t\t\texportTo: { to: 'test/export-media.css' }\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t},\n\t'basic:export-css-to-type': {\n\t\tmessage: 'supports { exportTo: { to: \"test/export-media.css\", type: \"css\" } } usage',\n\t\toptions: {\n\t\t\texportTo: { to: 'test/export-media.css', type: 'css' }\n\t\t},\n\t\texpect: 'basic.expect.css',\n\t\tresult: 'basic.result.css',\n\t\tbefore() {\n\t\t\tglobal.__exportMediaString = require('fs').readFileSync('test/export-media.css', 'utf8');\n\t\t},\n\t\tafter() {\n\t\t\tif (global.__exportMediaString !== require('fs').readFileSync('test/export-media.css', 'utf8')) {\n\t\t\t\tthrow new Error('The original file did not match the freshly exported copy');\n\t\t\t}\n\t\t}\n\t}\n};\n"
  },
  {
    "path": ".travis.yml",
    "content": "# https://docs.travis-ci.com/user/travis-lint\n\nlanguage: node_js\n\nnode_js:\n  - 14\n  - 12\n  - 10\n\ninstall:\n  - npm install --ignore-scripts\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "# Changes to PostCSS Custom Media\n\n### 8.0.0 (January 12, 2021)\n\n- Added: Support for PostCSS v8\n\n### 7.0.8 (March 30, 2019)\n\n- Fixed: Issue importing from `.pcss` files\n- Updated: `postcss` to 7.0.14 (patch)\n\n### 7.0.7 (October 19, 2018)\n\n- Fixed: Issue combining custom media media queries with `and`\n\n### 7.0.6 (October 12, 2018)\n\n- Fixed: Issue combining multiple custom media\n\n### 7.0.5 (October 5, 2018)\n\n- Fixed: Possible issues resolving paths to imports and exports\n- Added: Imports from `customMedia` and `custom-media` simultaneously\n- Updated: `postcss` to 7.0.5\n\n### 7.0.4 (September 23, 2018)\n\n- Added: `importFromPlugins` option to process imports\n\n### 7.0.3 (September 20, 2018)\n\n- Fixed: Do not break on an empty `importFrom` object\n\n### 7.0.2 (September 15, 2018)\n\n- Fixed: An issue with re-assigning params as a non-string\n\n### 7.0.1 (September 14, 2018)\n\n- Fixed: An issue with how opposing queries are resolved.\n\n### 7.0.0 (September 14, 2018)\n\n- Added: New `preserve` option to preserve custom media and atrules using them\n- Added: New `exportTo` function to specify where to export custom media\n- Added: New `importFrom` option to specify where to import custom media\n- Added: Support for PostCSS v7\n- Added: Support for Node v6+\n\n# 6.0.0 (May 12, 2017)\n\n- Added: compatibility with postcss v6.x\n\n# 5.0.1 (February 3, 2016)\n\n- Fixed: circular dependencies are properly detected\n([#17](https://github.com/postcss/postcss-custom-media/pull/17))\n\n# 5.0.0 (August 25, 2015)\n\n- Removed: compatibility with postcss v4.x\n- Added: compatibility with postcss v5.x\n\n# 4.1.0 (06 30, 2015)\n\n- Added: Allow custom media to reference each other\n([#10](https://github.com/postcss/postcss-custom-media/pull/10))\n\n# 4.0.0 (May 17, 2015)\n\n- Changed: warning messages are now sent via postcss messages api (^4.1.0)\n- Added: automatic custom media `--` prefixing\n([#11](https://github.com/postcss/postcss-custom-media/issues/11))\n- Added: `preserve` allows you to preserve custom media query defintions\n- Added: `appendExtensions` allows you (when `preserve` is truthy) to append your extensions as media queries\n\n# 3.0.0 (January 29, 2015)\n\n- Added: compatibility with postcss v4.x\n- Removed: compatibility with postcss v3.x\n\n# 2.0.0 [Yanked]\n\n_You never saw this version (this is a bad release that points to 1.0.0)._\n\n# 1.3.0 (November 25, 2014)\n\n- Changed: better gnu message\n\n# 1.2.1 (October 9, 2014)\n\n- Fixed: npm description\n\n# 1.2.0 (October 1, 2014)\n\n- Added: support for multiples media in query list (ref [#rework-custom-media/5](https://github.com/reworkcss/rework-custom-media/pull/5))\n\n# 1.1.0 (September 30, 2014)\n\n- Added: support for js-defined media queries (fix [#3](https://github.com/postcss/postcss-custom-media/issues/3))\n\n# 1.0.1 (September 16, 2014)\n\n- Added: Allow whitespace around custom media name (fix [#2](https://github.com/postcss/postcss-custom-media/issues/2))\n\n# 1.0.0 (August 12, 2014)\n\n✨ First release based on [rework-custom-media](https://github.com/reworkcss/rework-custom-media) v0.1.1\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing to PostCSS Custom Media\n\nYou want to help? You rock! Now, take a moment to be sure your contributions\nmake sense to everyone else.\n\n## Reporting Issues\n\nFound a problem? Want a new feature?\n\n- See if your issue or idea has [already been reported].\n- Provide a [reduced test case] or a [live example].\n\nRemember, a bug is a _demonstrable problem_ caused by _our_ code.\n\n## Submitting Pull Requests\n\nPull requests are the greatest contributions, so be sure they are focused in\nscope and avoid unrelated commits.\n\n1. To begin; [fork this project], clone your fork, and add our upstream.\n   ```bash\n   # Clone your fork of the repo into the current directory\n   git clone git@github.com:YOUR_USER/postcss-custom-media.git\n\n   # Navigate to the newly cloned directory\n   cd postcss-custom-media\n\n   # Assign the original repo to a remote called \"upstream\"\n   git remote add upstream git@github.com:postcss/postcss-custom-media.git\n\n   # Install the tools necessary for testing\n   npm install\n   ```\n\n2. Create a branch for your feature or fix:\n   ```bash\n   # Move into a new branch for your feature\n   git checkout -b feature/thing\n   ```\n   ```bash\n   # Move into a new branch for your fix\n   git checkout -b fix/something\n   ```\n\n3. If your code follows our practices, then push your feature branch:\n   ```bash\n   # Test current code\n   npm test\n   ```\n   ```bash\n   # Push the branch for your new feature\n   git push origin feature/thing\n   ```\n   ```bash\n   # Or, push the branch for your update\n   git push origin update/something\n   ```\n\nThat’s it! Now [open a pull request] with a clear title and description.\n\n[already been reported]: issues\n[fork this project]:     fork\n[live example]:          https://codepen.io/pen\n[open a pull request]:   https://help.github.com/articles/using-pull-requests/\n[reduced test case]:     https://css-tricks.com/reduced-test-cases/\n"
  },
  {
    "path": "INSTALL.md",
    "content": "# Installing PostCSS Custom Media\n\n[PostCSS Custom Media] runs in all Node environments, with special instructions for:\n\n| [Node](#node) | [PostCSS CLI](#postcss-cli) | [Webpack](#webpack) | [Create React App](#create-react-app) | [Gulp](#gulp) | [Grunt](#grunt) |\n| --- | --- | --- | --- | --- | --- |\n\n## Node\n\nAdd [PostCSS Custom Media] to your project:\n\n```bash\nnpm install postcss-custom-media --save-dev\n```\n\nUse [PostCSS Custom Media] to process your CSS:\n\n```js\nconst postcssCustomMedia = require('postcss-custom-media');\n\npostcssCustomMedia.process(YOUR_CSS /*, processOptions, pluginOptions */);\n```\n\nOr use it as a [PostCSS] plugin:\n\n```js\nconst postcss = require('postcss');\nconst postcssCustomMedia = require('postcss-custom-media');\n\npostcss([\n  postcssCustomMedia(/* pluginOptions */)\n]).process(YOUR_CSS /*, processOptions */);\n```\n\n## PostCSS CLI\n\nAdd [PostCSS CLI] to your project:\n\n```bash\nnpm install postcss-cli --save-dev\n```\n\nUse [PostCSS Custom Media] in your `postcss.config.js` configuration file:\n\n```js\nconst postcssCustomMedia = require('postcss-custom-media');\n\nmodule.exports = {\n  plugins: [\n    postcssCustomMedia(/* pluginOptions */)\n  ]\n}\n```\n\n## Webpack\n\nAdd [PostCSS Loader] to your project:\n\n```bash\nnpm install postcss-loader --save-dev\n```\n\nUse [PostCSS Custom Media] in your Webpack configuration:\n\n```js\nconst postcssCustomMedia = require('postcss-custom-media');\n\nmodule.exports = {\n  module: {\n    rules: [\n      {\n        test: /\\.css$/,\n        use: [\n          'style-loader',\n          { loader: 'css-loader', options: { importLoaders: 1 } },\n          { loader: 'postcss-loader', options: {\n            ident: 'postcss',\n            plugins: () => [\n              postcssCustomMedia(/* pluginOptions */)\n            ]\n          } }\n        ]\n      }\n    ]\n  }\n}\n```\n\n## Create React App\n\nAdd [React App Rewired] and [React App Rewire PostCSS] to your project:\n\n```bash\nnpm install react-app-rewired react-app-rewire-postcss --save-dev\n```\n\nUse [React App Rewire PostCSS] and [PostCSS Custom Media] in your\n`config-overrides.js` file:\n\n```js\nconst reactAppRewirePostcss = require('react-app-rewire-postcss');\nconst postcssCustomMedia = require('postcss-custom-media');\n\nmodule.exports = config => reactAppRewirePostcss(config, {\n  plugins: () => [\n    postcssCustomMedia(/* pluginOptions */)\n  ]\n});\n```\n\n## Gulp\n\nAdd [Gulp PostCSS] to your project:\n\n```bash\nnpm install gulp-postcss --save-dev\n```\n\nUse [PostCSS Custom Media] in your Gulpfile:\n\n```js\nconst postcss = require('gulp-postcss');\nconst postcssCustomMedia = require('postcss-custom-media');\n\ngulp.task('css', () => gulp.src('./src/*.css').pipe(\n  postcss([\n    postcssCustomMedia(/* pluginOptions */)\n  ])\n).pipe(\n  gulp.dest('.')\n));\n```\n\n## Grunt\n\nAdd [Grunt PostCSS] to your project:\n\n```bash\nnpm install grunt-postcss --save-dev\n```\n\nUse [PostCSS Custom Media] in your Gruntfile:\n\n```js\nconst postcssCustomMedia = require('postcss-custom-media');\n\ngrunt.loadNpmTasks('grunt-postcss');\n\ngrunt.initConfig({\n  postcss: {\n    options: {\n      use: [\n       postcssCustomMedia(/* pluginOptions */)\n      ]\n    },\n    dist: {\n      src: '*.css'\n    }\n  }\n});\n```\n\n[Gulp PostCSS]: https://github.com/postcss/gulp-postcss\n[Grunt PostCSS]: https://github.com/nDmitry/grunt-postcss\n[PostCSS]: https://github.com/postcss/postcss\n[PostCSS CLI]: https://github.com/postcss/postcss-cli\n[PostCSS Loader]: https://github.com/postcss/postcss-loader\n[PostCSS Custom Media]: https://github.com/postcss/postcss-custom-media\n[React App Rewire PostCSS]: https://github.com/csstools/react-app-rewire-postcss\n[React App Rewired]: https://github.com/timarney/react-app-rewired\n"
  },
  {
    "path": "LICENSE.md",
    "content": "# The MIT License (MIT)\n\nCopyright © PostCSS\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of\nthis software and associated documentation files (the \"Software\"), to deal in\nthe Software without restriction, including without limitation the rights to\nuse, copy, modify, merge, publish, distribute, sublicense, and/or sell copies\nof the Software, and to permit persons to whom the Software is furnished to do\nso, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">⚠️ PostCSS Custom Media was moved to <a href=\"https://github.com/csstools/postcss-plugins/tree/main/plugins/postcss-custom-media\">@csstools/postcss-plugins</a>. ⚠️ <br>\n<a href=\"https://github.com/csstools/postcss-plugins/discussions/75\">Read the announcement</a></div>\n\n# PostCSS Custom Media [<img src=\"https://postcss.github.io/postcss/logo.svg\" alt=\"PostCSS\" width=\"90\" height=\"90\" align=\"right\">][postcss]\n\n[![NPM Version][npm-img]][npm-url]\n[![CSS Standard Status][css-img]][css-url]\n[![Build Status][cli-img]][cli-url]\n[![Support Chat][git-img]][git-url]\n\n[PostCSS Custom Media] lets you use Custom Media Queries in CSS, following the\n[CSS Media Queries] specification.\n\n```pcss\n@custom-media --small-viewport (max-width: 30em);\n\n@media (--small-viewport) {\n  /* styles for small viewport */\n}\n\n/* becomes */\n\n@media (max-width: 30em) {\n  /* styles for small viewport */\n}\n```\n\n## Usage\n\nAdd [PostCSS Custom Media] to your project:\n\n```bash\nnpm install postcss-custom-media --save-dev\n```\n\nUse [PostCSS Custom Media] to process your CSS:\n\n```js\nconst postcssCustomMedia = require('postcss-custom-media');\n\npostcssCustomMedia.process(YOUR_CSS /*, processOptions, pluginOptions */);\n```\n\nOr use it as a [PostCSS] plugin:\n\n```js\nconst postcss = require('postcss');\nconst postcssCustomMedia = require('postcss-custom-media');\n\npostcss([\n  postcssCustomMedia(/* pluginOptions */)\n]).process(YOUR_CSS /*, processOptions */);\n```\n\n[PostCSS Custom Media] runs in all Node environments, with special instructions for:\n\n| [Node](INSTALL.md#node) | [PostCSS CLI](INSTALL.md#postcss-cli) | [Webpack](INSTALL.md#webpack) | [Create React App](INSTALL.md#create-react-app) | [Gulp](INSTALL.md#gulp) | [Grunt](INSTALL.md#grunt) |\n| --- | --- | --- | --- | --- | --- |\n\n## Options\n\n### preserve\n\nThe `preserve` option determines whether custom media and atrules using custom\nmedia should be preserved in their original form.\n\n```pcss\n@custom-media --small-viewport (max-width: 30em);\n\n@media (--small-viewport) {\n  /* styles for small viewport */\n}\n\n/* becomes */\n\n@custom-media --small-viewport (max-width: 30em);\n\n@media (max-width: 30em) {\n  /* styles for small viewport */\n}\n\n@media (--small-viewport) {\n  /* styles for small viewport */\n}\n```\n\n### importFrom\n\nThe `importFrom` option specifies sources where custom media can be imported\nfrom, which might be CSS, JS, and JSON files, functions, and directly passed\nobjects.\n\n```js\npostcssCustomMedia({\n  importFrom: 'path/to/file.css' // => @custom-selector --small-viewport (max-width: 30em);\n});\n```\n\n```pcss\n@media (max-width: 30em) {\n  /* styles for small viewport */\n}\n\n@media (--small-viewport) {\n  /* styles for small viewport */\n}\n```\n\nMultiple sources can be passed into this option, and they will be parsed in the\norder they are received. JavaScript files, JSON files, functions, and objects\nwill need to namespace custom media using the `customMedia` or\n`custom-media` key.\n\n```js\npostcssCustomMedia({\n  importFrom: [\n    'path/to/file.css',\n    'and/then/this.js',\n    'and/then/that.json',\n    {\n      customMedia: { '--small-viewport': '(max-width: 30em)' }\n    },\n    () => {\n      const customMedia = { '--small-viewport': '(max-width: 30em)' };\n\n      return { customMedia };\n    }\n  ]\n});\n```\n\n### exportTo\n\nThe `exportTo` option specifies destinations where custom media can be exported\nto, which might be CSS, JS, and JSON files, functions, and directly passed\nobjects.\n\n```js\npostcssCustomMedia({\n  exportTo: 'path/to/file.css' // @custom-media --small-viewport (max-width: 30em);\n});\n```\n\nMultiple destinations can be passed into this option, and they will be parsed\nin the order they are received. JavaScript files, JSON files, and objects will\nneed to namespace custom media using the `customMedia` or\n`custom-media` key.\n\n```js\nconst cachedObject = { customMedia: {} };\n\npostcssCustomMedia({\n  exportTo: [\n    'path/to/file.css',   // @custom-media --small-viewport (max-width: 30em);\n    'and/then/this.js',   // module.exports = { customMedia: { '--small-viewport': '(max-width: 30em)' } }\n    'and/then/this.mjs',  // export const customMedia = { '--small-viewport': '(max-width: 30em)' } }\n    'and/then/that.json', // { \"custom-media\": { \"--small-viewport\": \"(max-width: 30em)\" } }\n    cachedObject,\n    customMedia => {\n      customMedia    // { '--small-viewport': '(max-width: 30em)' }\n    }\n  ]\n});\n```\n\nSee example exports written to [CSS](test/export-media.css),\n[JS](test/export-media.js), [MJS](test/export-media.mjs), and\n[JSON](test/export-media.json).\n\n[cli-img]: https://img.shields.io/travis/postcss/postcss-custom-media/master.svg\n[cli-url]: https://travis-ci.org/postcss/postcss-custom-media\n[css-img]: https://cssdb.org/badge/custom-media-queries.svg\n[css-url]: https://cssdb.org/#custom-media-queries\n[git-img]: https://img.shields.io/badge/support-chat-blue.svg\n[git-url]: https://gitter.im/postcss/postcss\n[npm-img]: https://img.shields.io/npm/v/postcss-custom-media.svg\n[npm-url]: https://www.npmjs.com/package/postcss-custom-media\n\n[CSS Media Queries]: https://drafts.csswg.org/mediaqueries-5/#custom-mq\n[PostCSS]: https://github.com/postcss/postcss\n[PostCSS Custom Media]: https://github.com/postcss/postcss-custom-media\n"
  },
  {
    "path": "index.js",
    "content": "import getCustomMediaFromRoot from './lib/custom-media-from-root';\nimport getCustomMediaFromImports from './lib/get-custom-media-from-imports';\nimport transformAtrules from './lib/transform-atrules';\nimport writeCustomMediaToExports from './lib/write-custom-media-to-exports';\n\nconst creator = opts => {\n\t// whether to preserve custom media and at-rules using them\n\tconst preserve = 'preserve' in Object(opts) ? Boolean(opts.preserve) : false;\n\n\t// sources to import custom media from\n\tconst importFrom = [].concat(Object(opts).importFrom || []);\n\n\t// destinations to export custom media to\n\tconst exportTo = [].concat(Object(opts).exportTo || []);\n\n\t// promise any custom media are imported\n\tconst customMediaImportsPromise = getCustomMediaFromImports(importFrom);\n\n\treturn {\n\t\tpostcssPlugin: 'postcss-custom-media',\n\t\tOnce: async (root, helpers) => {\n\n\t\t\t// combine rules from root and from imports\n\t\t\thelpers.customMedia = Object.assign(\n\t\t\t\tawait customMediaImportsPromise,\n\t\t\t\tgetCustomMediaFromRoot(root, { preserve })\n\t\t\t);\n\n\t\t\tawait writeCustomMediaToExports(helpers.customMedia, exportTo);\n\t\t},\n\t\tAtRule: {\n\t\t\tmedia: (atrule, helpers) => {\n\t\t\t\ttransformAtrules(atrule, {preserve}, helpers)\n\t\t\t}\n\t\t}\n\t}\n}\n\ncreator.postcss = true\n\nexport default creator\n"
  },
  {
    "path": "lib/custom-media-from-root.js",
    "content": "import mediaASTFromString from './media-ast-from-string';\n\n// return custom selectors from the css root, conditionally removing them\nexport default (root, opts) => {\n\t// initialize custom selectors\n\tconst customMedias = {};\n\n\t// for each custom selector atrule that is a child of the css root\n\troot.nodes.slice().forEach(node => {\n\t\tif (isCustomMedia(node)) {\n\t\t\t// extract the name and selectors from the params of the custom selector\n\t\t\tconst [, name, selectors] = node.params.match(customMediaParamsRegExp);\n\n\t\t\t// write the parsed selectors to the custom selector\n\t\t\tcustomMedias[name] = mediaASTFromString(selectors);\n\n\t\t\t// conditionally remove the custom selector atrule\n\t\t\tif (!Object(opts).preserve) {\n\t\t\t\tnode.remove();\n\t\t\t}\n\t\t}\n\t});\n\n\treturn customMedias;\n};\n\n// match the custom selector name\nconst customMediaNameRegExp = /^custom-media$/i;\n\n// match the custom selector params\nconst customMediaParamsRegExp = /^(--[A-z][\\w-]*)\\s+([\\W\\w]+)\\s*$/;\n\n// whether the atrule is a custom selector\nconst isCustomMedia = node => node.type === 'atrule' && customMediaNameRegExp.test(node.name) && customMediaParamsRegExp.test(node.params);\n"
  },
  {
    "path": "lib/get-custom-media-from-imports.js",
    "content": "import fs from 'fs';\nimport path from 'path';\nimport { parse } from 'postcss';\nimport getMediaAstFromMediaString from './media-ast-from-string';\nimport getCustomMedia from './custom-media-from-root';\n\n/* Get Custom Media from CSS File\n/* ========================================================================== */\n\nasync function getCustomMediaFromCSSFile(from) {\n\tconst css = await readFile(from);\n\tconst root = parse(css, { from });\n\n\treturn getCustomMedia(root, { preserve: true });\n}\n\n/* Get Custom Media from Object\n/* ========================================================================== */\n\nfunction getCustomMediaFromObject(object) {\n\tconst customMedia = Object.assign(\n\t\t{},\n\t\tObject(object).customMedia,\n\t\tObject(object)['custom-media']\n\t);\n\n\tfor (const key in customMedia) {\n\t\tcustomMedia[key] = getMediaAstFromMediaString(customMedia[key]);\n\t}\n\n\treturn customMedia;\n}\n\n/* Get Custom Media from JSON file\n/* ========================================================================== */\n\nasync function getCustomMediaFromJSONFile(from) {\n\tconst object = await readJSON(from);\n\n\treturn getCustomMediaFromObject(object);\n}\n\n/* Get Custom Media from JS file\n/* ========================================================================== */\n\nasync function getCustomMediaFromJSFile(from) {\n\tconst object = await import(from);\n\n\treturn getCustomMediaFromObject(object);\n}\n\n/* Get Custom Media from Sources\n/* ========================================================================== */\n\nexport default function getCustomMediaFromSources(sources) {\n\treturn sources.map(source => {\n\t\tif (source instanceof Promise) {\n\t\t\treturn source;\n\t\t} else if (source instanceof Function) {\n\t\t\treturn source();\n\t\t}\n\n\t\t// read the source as an object\n\t\tconst opts = source === Object(source) ? source : { from: String(source) };\n\n\t\t// skip objects with custom media\n\t\tif (Object(opts).customMedia || Object(opts)['custom-media']) {\n\t\t\treturn opts\n\t\t}\n\n\t\t// source pathname\n\t\tconst from = path.resolve(String(opts.from || ''));\n\n\t\t// type of file being read from\n\t\tconst type = (opts.type || path.extname(from).slice(1)).toLowerCase();\n\n\t\treturn { type, from };\n\t}).reduce(async (customMedia, source) => {\n\t\tconst { type, from } = await source;\n\n\t\tif (type === 'css' || type === 'pcss') {\n\t\t\treturn Object.assign(await customMedia, await getCustomMediaFromCSSFile(from));\n\t\t}\n\n\t\tif (type === 'js') {\n\t\t\treturn Object.assign(await customMedia, await getCustomMediaFromJSFile(from));\n\t\t}\n\n\t\tif (type === 'json') {\n\t\t\treturn Object.assign(await customMedia, await getCustomMediaFromJSONFile(from));\n\t\t}\n\n\t\treturn Object.assign(await customMedia, getCustomMediaFromObject(await source));\n\t}, {});\n}\n\n/* Helper utilities\n/* ========================================================================== */\n\nconst readFile = from => new Promise((resolve, reject) => {\n\tfs.readFile(from, 'utf8', (error, result) => {\n\t\tif (error) {\n\t\t\treject(error);\n\t\t} else {\n\t\t\tresolve(result);\n\t\t}\n\t});\n});\n\nconst readJSON = async from => JSON.parse(await readFile(from));\n"
  },
  {
    "path": "lib/media-ast-from-string.js",
    "content": "function parse(string, splitByAnd) {\n\tconst array = [];\n\tlet buffer = '';\n\tlet split = false;\n\tlet func = 0;\n\tlet i = -1;\n\n\twhile (++i < string.length) {\n\t\tconst char = string[i];\n\n\t\tif (char === '(') {\n\t\t\tfunc += 1;\n\t\t} else if (char === ')') {\n\t\t\tif (func > 0) {\n\t\t\t\tfunc -= 1;\n\t\t\t}\n\t\t} else if (func === 0) {\n\t\t\tif (splitByAnd && andRegExp.test(buffer + char)) {\n\t\t\t\tsplit = true;\n\t\t\t} else if (!splitByAnd && char === ',') {\n\t\t\t\tsplit = true;\n\t\t\t}\n\t\t}\n\n\t\tif (split) {\n\t\t\tarray.push(splitByAnd ? new MediaExpression(buffer + char) : new MediaQuery(buffer));\n\n\t\t\tbuffer = '';\n\t\t\tsplit = false;\n\t\t} else {\n\t\t\tbuffer += char\n\t\t}\n\t}\n\n\tif (buffer !== '') {\n\t\tarray.push(splitByAnd ? new MediaExpression(buffer) : new MediaQuery(buffer));\n\t}\n\n\treturn array;\n}\n\nclass MediaQueryList {\n\tconstructor(string) {\n\t\tthis.nodes = parse(string);\n\t}\n\n\tinvert() {\n\t\tthis.nodes.forEach(node => {\n\t\t\tnode.invert();\n\t\t})\n\n\t\treturn this;\n\t}\n\n\tclone() {\n\t\treturn new MediaQueryList(String(this));\n\t}\n\n\ttoString() {\n\t\treturn this.nodes.join(',');\n\t}\n}\n\nclass MediaQuery {\n\tconstructor(string) {\n\t\tconst [, before, media, after ] = string.match(spaceWrapRegExp);\n\t\tconst [, modifier = '', afterModifier = ' ', type = '', beforeAnd = '', and = '', beforeExpression = '', expression1 = '', expression2 = ''] = media.match(mediaRegExp) || [];\n\t\tconst raws = { before, after, afterModifier, originalModifier: modifier || '', beforeAnd, and, beforeExpression };\n\t\tconst nodes = parse(expression1 || expression2, true);\n\n\t\tObject.assign(this, {\n\t\t\tmodifier,\n\t\t\ttype,\n\t\t\traws,\n\t\t\tnodes\n\t\t});\n\t}\n\n\tclone(overrides) {\n\t\tconst instance = new MediaQuery(String(this));\n\n\t\tObject.assign(instance, overrides);\n\n\t\treturn instance;\n\t}\n\n\tinvert() {\n\t\tthis.modifier = this.modifier ? '' : this.raws.originalModifier;\n\n\t\treturn this;\n\t}\n\n\ttoString() {\n\t\tconst { raws } = this;\n\n\t\treturn `${raws.before}${this.modifier}${this.modifier ? `${raws.afterModifier}` : ''}${this.type}${raws.beforeAnd}${raws.and}${raws.beforeExpression}${this.nodes.join('')}${this.raws.after}`;\n\t}\n}\n\nclass MediaExpression {\n\tconstructor(string) {\n\t\tconst [, value, after = '', and = '', afterAnd = '' ] = string.match(andRegExp) || [null, string];\n\t\tconst raws = { after, and, afterAnd };\n\n\t\tObject.assign(this, { value, raws });\n\t}\n\n\tclone(overrides) {\n\t\tconst instance = new MediaExpression(String(this));\n\n\t\tObject.assign(instance, overrides);\n\n\t\treturn instance;\n\t}\n\n\ttoString() {\n\t\tconst { raws } = this;\n\n\t\treturn `${this.value}${raws.after}${raws.and}${raws.afterAnd}`;\n\t}\n}\n\nconst modifierRE = '(not|only)';\nconst typeRE = '(all|print|screen|speech)';\nconst noExpressionRE = '([\\\\W\\\\w]*)';\nconst expressionRE = '([\\\\W\\\\w]+)';\nconst noSpaceRE = '(\\\\s*)';\nconst spaceRE = '(\\\\s+)';\nconst andRE = '(?:(\\\\s+)(and))';\nconst andRegExp = new RegExp(`^${expressionRE}(?:${andRE}${spaceRE})$`, 'i');\nconst spaceWrapRegExp = new RegExp(`^${noSpaceRE}${noExpressionRE}${noSpaceRE}$`);\nconst mediaRegExp = new RegExp(`^(?:${modifierRE}${spaceRE})?(?:${typeRE}(?:${andRE}${spaceRE}${expressionRE})?|${expressionRE})$`, 'i');\n\nexport default string => new MediaQueryList(string);\n"
  },
  {
    "path": "lib/transform-atrules.js",
    "content": "import transformMediaList from \"./transform-media-list\";\nimport mediaASTFromString from \"./media-ast-from-string\";\n\n// transform custom pseudo selectors with custom selectors\nexport default (atrule, { preserve }, { customMedia }) => {\n\tif (customPseudoRegExp.test(atrule.params)) {\n\t\t// prevent infinite loops when using 'preserve' option\n\t\tif (!atrule[visitedFlag]) {\n\t\t\tatrule[visitedFlag] = true;\n\n\t\t\tconst mediaAST = mediaASTFromString(atrule.params);\n\t\t\tconst params = String(transformMediaList(mediaAST, customMedia));\n\n\t\t\tif (preserve) {\n\t\t\t\t// keep an original copy\n\t\t\t\tconst node = atrule.cloneAfter();\n\t\t\t\tnode[visitedFlag] = true;\n\t\t\t}\n\t\t\t// replace the variable with the params from @custom-media rule\n\t\t\t// skip if the variable is undefined\n\t\t\tif (params != null) {\n\t\t\t\tatrule.params = params;\n\t\t\t}\n\t\t}\n\t}\n};\n\nconst visitedFlag = Symbol(\"customMediaVisited\");\nconst customPseudoRegExp = /\\(--[A-z][\\w-]*\\)/;\n"
  },
  {
    "path": "lib/transform-media-list.js",
    "content": "// return transformed medias, replacing custom pseudo medias with custom medias\nexport default function transformMediaList(mediaList, customMedias) {\n\tlet index = mediaList.nodes.length - 1;\n\n\twhile (index >= 0) {\n\t\tconst transformedMedias = transformMedia(mediaList.nodes[index], customMedias);\n\n\t\tif (transformedMedias.length) {\n\t\t\tmediaList.nodes.splice(index, 1, ...transformedMedias);\n\t\t}\n\n\t\t--index;\n\t}\n\n\treturn mediaList;\n}\n\n// return custom pseudo medias replaced with custom medias\nfunction transformMedia(media, customMedias) {\n\tconst transpiledMedias = [];\n\n\tfor (const index in media.nodes) {\n\t\tconst { value, nodes } = media.nodes[index];\n\t\tconst key = value.replace(customPseudoRegExp, '$1');\n\n\t\tif (key in customMedias) {\n\t\t\tfor (const replacementMedia of customMedias[key].nodes) {\n\t\t\t\t// use the first available modifier unless they cancel each other out\n\t\t\t\tconst modifier = media.modifier !== replacementMedia.modifier\n\t\t\t\t\t? media.modifier || replacementMedia.modifier\n\t\t\t\t: '';\n\t\t\t\tconst mediaClone = media.clone({\n\t\t\t\t\tmodifier,\n\t\t\t\t\t// conditionally use the raws from the first available modifier\n\t\t\t\t\traws: !modifier || media.modifier\n\t\t\t\t\t\t? { ...media.raws }\n\t\t\t\t\t: { ...replacementMedia.raws },\n\t\t\t\t\ttype: media.type || replacementMedia.type,\n\t\t\t\t});\n\n\t\t\t\t// conditionally include more replacement raws when the type is present\n\t\t\t\tif (mediaClone.type === replacementMedia.type) {\n\t\t\t\t\tObject.assign(mediaClone.raws, {\n\t\t\t\t\t\tand: replacementMedia.raws.and,\n\t\t\t\t\t\tbeforeAnd: replacementMedia.raws.beforeAnd,\n\t\t\t\t\t\tbeforeExpression: replacementMedia.raws.beforeExpression\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tmediaClone.nodes.splice(index, 1, ...replacementMedia.clone().nodes.map(node => {\n\t\t\t\t\t// use raws and spacing from the current usage\n\t\t\t\t\tif (media.nodes[index].raws.and) {\n\t\t\t\t\t\tnode.raws = { ...media.nodes[index].raws };\n\t\t\t\t\t}\n\n\t\t\t\t\tnode.spaces = { ...media.nodes[index].spaces };\n\n\t\t\t\t\treturn node;\n\t\t\t\t}));\n\n\t\t\t\t// remove the currently transformed key to prevent recursion\n\t\t\t\tconst nextCustomMedia = getCustomMediasWithoutKey(customMedias, key);\n\t\t\t\tconst retranspiledMedias = transformMedia(mediaClone, nextCustomMedia);\n\n\t\t\t\tif (retranspiledMedias.length) {\n\t\t\t\t\ttranspiledMedias.push(...retranspiledMedias);\n\t\t\t\t} else {\n\t\t\t\t\ttranspiledMedias.push(mediaClone);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn transpiledMedias;\n\t\t} else if (nodes && nodes.length) {\n\t\t\ttransformMediaList(media.nodes[index], customMedias);\n\t\t}\n\t}\n\n\treturn transpiledMedias;\n}\n\nconst customPseudoRegExp = /\\((--[A-z][\\w-]*)\\)/;\n\nconst getCustomMediasWithoutKey = (customMedias, key) => {\n\tconst nextCustomMedias = Object.assign({}, customMedias);\n\n\tdelete nextCustomMedias[key];\n\n\treturn nextCustomMedias;\n};\n"
  },
  {
    "path": "lib/write-custom-media-to-exports.js",
    "content": "import fs from 'fs';\nimport path from 'path';\n\n/* Write Custom Media from CSS File\n/* ========================================================================== */\n\nasync function writeCustomMediaToCssFile(to, customMedia) {\n\tconst cssContent = Object.keys(customMedia).reduce((cssLines, name) => {\n\t\tcssLines.push(`@custom-media ${name} ${customMedia[name]};`);\n\n\t\treturn cssLines;\n\t}, []).join('\\n');\n\tconst css = `${cssContent}\\n`;\n\n\tawait writeFile(to, css);\n}\n\n/* Write Custom Media from JSON file\n/* ========================================================================== */\n\nasync function writeCustomMediaToJsonFile(to, customMedia) {\n\tconst jsonContent = JSON.stringify({\n\t\t'custom-media': customMedia\n\t}, null, '  ');\n\tconst json = `${jsonContent}\\n`;\n\n\tawait writeFile(to, json);\n}\n\n/* Write Custom Media from Common JS file\n/* ========================================================================== */\n\nasync function writeCustomMediaToCjsFile(to, customMedia) {\n\tconst jsContents = Object.keys(customMedia).reduce((jsLines, name) => {\n\t\tjsLines.push(`\\t\\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`);\n\n\t\treturn jsLines;\n\t}, []).join(',\\n');\n\tconst js = `module.exports = {\\n\\tcustomMedia: {\\n${jsContents}\\n\\t}\\n};\\n`;\n\n\tawait writeFile(to, js);\n}\n\n/* Write Custom Media from Module JS file\n/* ========================================================================== */\n\nasync function writeCustomMediaToMjsFile(to, customMedia) {\n\tconst mjsContents = Object.keys(customMedia).reduce((mjsLines, name) => {\n\t\tmjsLines.push(`\\t'${escapeForJS(name)}': '${escapeForJS(customMedia[name])}'`);\n\n\t\treturn mjsLines;\n\t}, []).join(',\\n');\n\tconst mjs = `export const customMedia = {\\n${mjsContents}\\n};\\n`;\n\n\tawait writeFile(to, mjs);\n}\n\n/* Write Custom Media to Exports\n/* ========================================================================== */\n\nexport default function writeCustomMediaToExports(customMedia, destinations) {\n\treturn Promise.all(destinations.map(async destination => {\n\t\tif (destination instanceof Function) {\n\t\t\tawait destination(defaultCustomMediaToJSON(customMedia));\n\t\t} else {\n\t\t\t// read the destination as an object\n\t\t\tconst opts = destination === Object(destination) ? destination : { to: String(destination) };\n\n\t\t\t// transformer for custom media into a JSON-compatible object\n\t\t\tconst toJSON = opts.toJSON || defaultCustomMediaToJSON;\n\n\t\t\tif ('customMedia' in opts) {\n\t\t\t\t// write directly to an object as customMedia\n\t\t\t\topts.customMedia = toJSON(customMedia);\n\t\t\t} else if ('custom-media' in opts) {\n\t\t\t\t// write directly to an object as custom-media\n\t\t\t\topts['custom-media'] = toJSON(customMedia);\n\t\t\t} else {\n\t\t\t\t// destination pathname\n\t\t\t\tconst to = String(opts.to || '');\n\n\t\t\t\t// type of file being written to\n\t\t\t\tconst type = (opts.type || path.extname(to).slice(1)).toLowerCase();\n\n\t\t\t\t// transformed custom media\n\t\t\t\tconst customMediaJSON = toJSON(customMedia);\n\n\t\t\t\tif (type === 'css') {\n\t\t\t\t\tawait writeCustomMediaToCssFile(to, customMediaJSON);\n\t\t\t\t}\n\n\t\t\t\tif (type === 'js') {\n\t\t\t\t\tawait writeCustomMediaToCjsFile(to, customMediaJSON);\n\t\t\t\t}\n\n\t\t\t\tif (type === 'json') {\n\t\t\t\t\tawait writeCustomMediaToJsonFile(to, customMediaJSON);\n\t\t\t\t}\n\n\t\t\t\tif (type === 'mjs') {\n\t\t\t\t\tawait writeCustomMediaToMjsFile(to, customMediaJSON);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}));\n}\n\n/* Helper utilities\n/* ========================================================================== */\n\nconst defaultCustomMediaToJSON = customMedia => {\n\treturn Object.keys(customMedia).reduce((customMediaJSON, key) => {\n\t\tcustomMediaJSON[key] = String(customMedia[key]);\n\n\t\treturn customMediaJSON;\n\t}, {});\n};\n\nconst writeFile = (to, text) => new Promise((resolve, reject) => {\n\tfs.writeFile(to, text, error => {\n\t\tif (error) {\n\t\t\treject(error);\n\t\t} else {\n\t\t\tresolve();\n\t\t}\n\t});\n});\n\nconst escapeForJS = string => string.replace(/\\\\([\\s\\S])|(')/g, '\\\\$1$2').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r');\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"postcss-custom-media\",\n  \"version\": \"8.0.0\",\n  \"description\": \"Use Custom Media Queries in CSS\",\n  \"author\": \"Jonathan Neal <jonathantneal@hotmail.com>\",\n  \"contributors\": [\n    \"Maxime Thirouin\"\n  ],\n  \"license\": \"MIT\",\n  \"repository\": \"postcss/postcss-custom-media\",\n  \"homepage\": \"https://github.com/postcss/postcss-custom-media#readme\",\n  \"bugs\": \"https://github.com/postcss/postcss-custom-media/issues\",\n  \"main\": \"index.cjs.js\",\n  \"module\": \"index.es.mjs\",\n  \"files\": [\n    \"index.cjs.js\",\n    \"index.es.mjs\"\n  ],\n  \"scripts\": {\n    \"prepublishOnly\": \"npm test\",\n    \"pretest\": \"rollup -c .rollup.js --silent\",\n    \"test\": \"echo 'Running tests...'; npm run test:js && npm run test:tape\",\n    \"test:js\": \"eslint *.js lib/*.js --cache --ignore-path .gitignore --quiet\",\n    \"test:tape\": \"postcss-tape\"\n  },\n  \"engines\": {\n    \"node\": \">=10.0.0\"\n  },\n  \"peerDependencies\": {\n    \"postcss\": \"^8.1.0\"\n  },\n  \"devDependencies\": {\n    \"@babel/core\": \"^7.11.6\",\n    \"@babel/plugin-syntax-dynamic-import\": \"^7.8.3\",\n    \"@babel/preset-env\": \"^7.11.5\",\n    \"@rollup/plugin-babel\": \"^5.2.1\",\n    \"babel-eslint\": \"^10.1.0\",\n    \"eslint\": \"^7.10.0\",\n    \"postcss\": \"^8.1.0\",\n    \"postcss-tape\": \"^6.0.0\",\n    \"pre-commit\": \"^1.2.2\",\n    \"rollup\": \"^2.28.2\"\n  },\n  \"eslintConfig\": {\n    \"env\": {\n      \"browser\": true,\n      \"es6\": true,\n      \"node\": true\n    },\n    \"extends\": \"eslint:recommended\",\n    \"parser\": \"babel-eslint\",\n    \"parserOptions\": {\n      \"ecmaVersion\": 2018,\n      \"impliedStrict\": true,\n      \"sourceType\": \"module\"\n    }\n  },\n  \"keywords\": [\n    \"postcss\",\n    \"css\",\n    \"postcss-plugin\",\n    \"custom\",\n    \"media\",\n    \"query\",\n    \"queries\",\n    \"w3c\",\n    \"csswg\",\n    \"atrule\",\n    \"at-rule\",\n    \"specification\"\n  ]\n}\n"
  },
  {
    "path": "test/basic.css",
    "content": "@custom-media --mq-a (max-width: 30em), (max-height: 30em);\n@custom-media --mq-b screen and (max-width: 30em);\n@custom-media --not-mq-a not all and (--mq-a);\n\n@media (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-b) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-a), (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media (--not-mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--not-mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@custom-media --circular-mq-a (--circular-mq-b);\n@custom-media --circular-mq-b (--circular-mq-a);\n\n@media (--circular-mq-a) {\n\tbody {\n\t\torder: 3;\n\t}\n}\n\n@media (--circular-mq-b) {\n\tbody {\n\t\torder: 4;\n\t}\n}\n\n@media (--unresolved-mq) {\n\tbody {\n\t\torder: 5;\n\t}\n}\n\n@custom-media --min (min-width: 320px);\n@custom-media --max (max-width: 640px);\n\n@media (--min) and (--max) {\n\tbody {\n\t\torder: 6;\n\t}\n}\n\n@custom-media --concat (min-width: 320px) and (max-width: 640px);\n\n@media (--concat) {\n\tbody {\n\t\torder: 7;\n\t}\n}\n\n@media (--concat) and (min-aspect-ratio: 16/9) {\n\tbody {\n\t\torder: 8;\n\t}\n}\n"
  },
  {
    "path": "test/basic.expect.css",
    "content": "@media (max-width: 30em),(max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media screen and (max-width: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media all and (max-width: 30em),all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media (--circular-mq-a) {\n\tbody {\n\t\torder: 3;\n\t}\n}\n\n@media (--circular-mq-b) {\n\tbody {\n\t\torder: 4;\n\t}\n}\n\n@media (--unresolved-mq) {\n\tbody {\n\t\torder: 5;\n\t}\n}\n\n@media (min-width: 320px) and (max-width: 640px) {\n\tbody {\n\t\torder: 6;\n\t}\n}\n\n@media (min-width: 320px) and (max-width: 640px) {\n\tbody {\n\t\torder: 7;\n\t}\n}\n\n@media (min-width: 320px) and (max-width: 640px) and (min-aspect-ratio: 16/9) {\n\tbody {\n\t\torder: 8;\n\t}\n}\n"
  },
  {
    "path": "test/basic.import.expect.css",
    "content": ""
  },
  {
    "path": "test/basic.preserve.expect.css",
    "content": "@custom-media --mq-a (max-width: 30em), (max-height: 30em);\n@custom-media --mq-b screen and (max-width: 30em);\n@custom-media --not-mq-a not all and (--mq-a);\n\n@media (max-width: 30em),(max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media screen and (max-width: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-b) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-a), (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (--mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--not-mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media all and (max-width: 30em),all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (--not-mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@custom-media --circular-mq-a (--circular-mq-b);\n@custom-media --circular-mq-b (--circular-mq-a);\n\n@media (--circular-mq-a) {\n\tbody {\n\t\torder: 3;\n\t}\n}\n\n@media (--circular-mq-a) {\n\tbody {\n\t\torder: 3;\n\t}\n}\n\n@media (--circular-mq-b) {\n\tbody {\n\t\torder: 4;\n\t}\n}\n\n@media (--circular-mq-b) {\n\tbody {\n\t\torder: 4;\n\t}\n}\n\n@media (--unresolved-mq) {\n\tbody {\n\t\torder: 5;\n\t}\n}\n\n@media (--unresolved-mq) {\n\tbody {\n\t\torder: 5;\n\t}\n}\n\n@custom-media --min (min-width: 320px);\n@custom-media --max (max-width: 640px);\n\n@media (min-width: 320px) and (max-width: 640px) {\n\tbody {\n\t\torder: 6;\n\t}\n}\n\n@media (--min) and (--max) {\n\tbody {\n\t\torder: 6;\n\t}\n}\n\n@custom-media --concat (min-width: 320px) and (max-width: 640px);\n\n@media (min-width: 320px) and (max-width: 640px) {\n\tbody {\n\t\torder: 7;\n\t}\n}\n\n@media (--concat) {\n\tbody {\n\t\torder: 7;\n\t}\n}\n\n@media (min-width: 320px) and (max-width: 640px) and (min-aspect-ratio: 16/9) {\n\tbody {\n\t\torder: 8;\n\t}\n}\n\n@media (--concat) and (min-aspect-ratio: 16/9) {\n\tbody {\n\t\torder: 8;\n\t}\n}\n"
  },
  {
    "path": "test/export-media.css",
    "content": "@custom-media --mq-a (max-width: 30em), (max-height: 30em);\n@custom-media --mq-b screen and (max-width: 30em);\n@custom-media --not-mq-a not all and (--mq-a);\n@custom-media --circular-mq-a (--circular-mq-b);\n@custom-media --circular-mq-b (--circular-mq-a);\n@custom-media --min (min-width: 320px);\n@custom-media --max (max-width: 640px);\n@custom-media --concat (min-width: 320px) and (max-width: 640px);\n"
  },
  {
    "path": "test/export-media.js",
    "content": "module.exports = {\n\tcustomMedia: {\n\t\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t\t'--mq-b': 'screen and (max-width: 30em)',\n\t\t'--not-mq-a': 'not all and (--mq-a)',\n\t\t'--circular-mq-a': '(--circular-mq-b)',\n\t\t'--circular-mq-b': '(--circular-mq-a)',\n\t\t'--min': '(min-width: 320px)',\n\t\t'--max': '(max-width: 640px)',\n\t\t'--concat': '(min-width: 320px) and (max-width: 640px)'\n\t}\n};\n"
  },
  {
    "path": "test/export-media.json",
    "content": "{\n  \"custom-media\": {\n    \"--mq-a\": \"(max-width: 30em), (max-height: 30em)\",\n    \"--mq-b\": \"screen and (max-width: 30em)\",\n    \"--not-mq-a\": \"not all and (--mq-a)\",\n    \"--circular-mq-a\": \"(--circular-mq-b)\",\n    \"--circular-mq-b\": \"(--circular-mq-a)\",\n    \"--min\": \"(min-width: 320px)\",\n    \"--max\": \"(max-width: 640px)\",\n    \"--concat\": \"(min-width: 320px) and (max-width: 640px)\"\n  }\n}\n"
  },
  {
    "path": "test/export-media.mjs",
    "content": "export const customMedia = {\n\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t'--mq-b': 'screen and (max-width: 30em)',\n\t'--not-mq-a': 'not all and (--mq-a)',\n\t'--circular-mq-a': '(--circular-mq-b)',\n\t'--circular-mq-b': '(--circular-mq-a)',\n\t'--min': '(min-width: 320px)',\n\t'--max': '(max-width: 640px)',\n\t'--concat': '(min-width: 320px) and (max-width: 640px)'\n};\n"
  },
  {
    "path": "test/import-css.css",
    "content": ""
  },
  {
    "path": "test/import-media.css",
    "content": "@custom-media --mq-a (max-width: 30em), (max-height: 30em);\n@custom-media --not-mq-a not all and (--mq-a);\n"
  },
  {
    "path": "test/import-media.js",
    "content": "module.exports = {\n\tcustomMedia: {\n\t\t'--mq-a': '(max-width: 30em), (max-height: 30em)',\n\t\t'--not-mq-a': 'not all and (--mq-a)'\n\t}\n}\n"
  },
  {
    "path": "test/import-media.json",
    "content": "{\n  \"customMedia\": {\n    \"--mq-a\": \"(max-width: 30em), (max-height: 30em)\",\n    \"--not-mq-a\": \"not all and (--mq-a)\"\n  }\n}\n"
  },
  {
    "path": "test/import.css",
    "content": "@media (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-a), (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media (--not-mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--not-mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n"
  },
  {
    "path": "test/import.empty.expect.css",
    "content": "@media (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (--mq-a), (--mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media (--not-mq-a) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (--not-mq-a) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n"
  },
  {
    "path": "test/import.expect.css",
    "content": "@media (max-width: 30em),(max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media all and (max-width: 30em),all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n"
  },
  {
    "path": "test/import.plugin.expect.css",
    "content": "@media (max-width: 30em),(max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media (max-width: 30em),(max-height: 30em), (max-width: 30em), (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n\n@media not all and (max-width: 30em),not all and (max-height: 30em) {\n\tbody {\n\t\torder: 1;\n\t}\n}\n\n@media all and (max-width: 30em),all and (max-height: 30em) {\n\tbody {\n\t\torder: 2;\n\t}\n}\n"
  }
]