aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore4
-rw-r--r--.stylelintrc.json25
-rw-r--r--package.json22
-rw-r--r--pnpm-lock.yaml3399
-rw-r--r--src/_contexts.scss217
-rw-r--r--src/_easing.scss217
-rw-r--r--src/_functions.scss316
-rw-r--r--src/_gradients.scss643
-rw-r--r--src/_harmony.scss65
-rw-r--r--src/_iro-sass.scss (renamed from src/index.scss)10
-rw-r--r--src/_props.scss508
-rw-r--r--src/_responsive.scss391
-rw-r--r--src/bem/_block.scss216
-rw-r--r--src/bem/_debug.scss15
-rw-r--r--src/bem/_element.scss483
-rw-r--r--src/bem/_functions.scss27
-rw-r--r--src/bem/_modifier.scss227
-rw-r--r--src/bem/_multi.scss102
-rw-r--r--src/bem/_state.scss84
-rw-r--r--src/bem/_suffix.scss95
-rw-r--r--src/bem/_theme.scss57
-rw-r--r--src/bem/_validators.scss137
-rw-r--r--src/bem/_vars.scss28
-rw-r--r--test/_bem.scss32
-rw-r--r--test/_contexts.scss90
-rw-r--r--test/_functions.scss84
-rw-r--r--test/_gradients.scss392
-rw-r--r--test/_harmony.scss386
-rw-r--r--test/_props.scss479
-rw-r--r--test/_responsive.scss12
-rw-r--r--test/bem/_at-theme.scss80
-rw-r--r--test/bem/_block.scss139
-rw-r--r--test/bem/_composed-of.scss237
-rw-r--r--test/bem/_element.scss792
-rw-r--r--test/bem/_examples.scss352
-rw-r--r--test/bem/_modifier.scss1066
-rw-r--r--test/bem/_multi.scss948
-rw-r--r--test/bem/_next-twin-element.scss248
-rw-r--r--test/bem/_related-element.scss752
-rw-r--r--test/bem/_state.scss280
-rw-r--r--test/bem/_suffix.scss146
-rw-r--r--test/test.js4
-rw-r--r--test/test.scss2
43 files changed, 8499 insertions, 5310 deletions
diff --git a/.gitignore b/.gitignore
index dc8af33..92beb11 100644
--- a/.gitignore
+++ b/.gitignore
@@ -2,4 +2,6 @@ node_modules
2sassdoc 2sassdoc
3.sassdoc 3.sassdoc
4test/**/*.css 4test/**/*.css
5yarn-error.log \ No newline at end of file 5yarn-error.log
6
7.idea \ No newline at end of file
diff --git a/.stylelintrc.json b/.stylelintrc.json
index 8a9a924..fa2128b 100644
--- a/.stylelintrc.json
+++ b/.stylelintrc.json
@@ -1,23 +1,16 @@
1{ 1{
2 "extends": "stylelint-config-sass-guidelines", 2 "extends": "stylelint-config-sass-guidelines",
3 "rules": { 3 "rules": {
4 "indentation": 4, 4 "@stylistic/indentation": "tab",
5 "number-leading-zero": "never", 5 "@stylistic/number-leading-zero": "never",
6 "max-nesting-depth": 10, 6 "@stylistic/declaration-colon-space-after": null,
7 "max-nesting-depth": 9,
7 "selector-class-pattern": [ 8 "selector-class-pattern": [
8 "^[closut](-[a-z0-9]+)+(__[a-z0-9]+(-[a-z0-9]+)*)*(--[a-z0-9]+(-[a-z0-9]+)*)*(\\@[a-z0-9]+(-[a-z0-9]+)*)?$", 9 "^[closut](-[a-z0-9]+)+(__[a-z0-9]+(-[a-z0-9]+)*)*(--[a-z0-9]+(-[a-z0-9]+)*)*(\\@[a-z0-9]+(-[a-z0-9]+)*)?$",
9 { "resolveNestedSelectors": true } 10 {
11 "resolveNestedSelectors": true
12 }
10 ], 13 ],
11 "declaration-colon-space-after": null, 14 "scss/dollar-variable-colon-space-after": null
12 "function-parentheses-newline-inside": "always-multi-line", 15 }
13 "function-parentheses-space-inside": "never-single-line",
14 "scss/dollar-variable-colon-space-after": null,
15 "scss/dollar-variable-pattern": "[a-z0-9-]+"
16 },
17 "overrides": [
18 {
19 "files": ["src/**/*.scss"],
20 "customSyntax": "postcss-scss"
21 }
22 ]
23} 16}
diff --git a/package.json b/package.json
index a03255f..810a15f 100644
--- a/package.json
+++ b/package.json
@@ -4,9 +4,9 @@
4 "author": "Volpeon <me@volpeon.ink>", 4 "author": "Volpeon <me@volpeon.ink>",
5 "license": "MIT", 5 "license": "MIT",
6 "description": "A mixin-based Sass framework that makes it easier to work with BEM, organize variables and more.", 6 "description": "A mixin-based Sass framework that makes it easier to work with BEM, organize variables and more.",
7 "main": "src/index.scss", 7 "main": "src/_iro-sass.scss",
8 "style": "src/index.scss", 8 "style": "src/_iro-sass.scss",
9 "sass": "src/index.scss", 9 "sass": "src/_iro-sass.scss",
10 "keywords": [ 10 "keywords": [
11 "sass", 11 "sass",
12 "scss", 12 "scss",
@@ -24,19 +24,19 @@
24 }, 24 },
25 "homepage": "https://git.vulpes.one/iro-sass/", 25 "homepage": "https://git.vulpes.one/iro-sass/",
26 "devDependencies": { 26 "devDependencies": {
27 "mocha": "^9.2.0", 27 "mocha": "^10.7.3",
28 "nodemon": "^2.0.15", 28 "nodemon": "^3.1.7",
29 "postcss-scss": "^4.0.3", 29 "postcss-scss": "^4.0.3",
30 "sass": "^1.49.7", 30 "sass": "^1.79.4",
31 "sass-true": "^6.0.1", 31 "sass-true": "^8.1.0",
32 "sassdoc": "^2.7.3", 32 "sassdoc": "^2.7.3",
33 "stylelint": "^14.3.0", 33 "stylelint": "^16.9.0",
34 "stylelint-config-sass-guidelines": "^9.0.1" 34 "stylelint-config-sass-guidelines": "^12.1.0"
35 }, 35 },
36 "scripts": { 36 "scripts": {
37 "prepublishOnly": "npm run test", 37 "prepublishOnly": "npm run test",
38 "lint": "stylelint \"src/**/*.scss\"", 38 "lint": "stylelint \"{src,test}/**/*.scss\"",
39 "fix": "stylelint \"src/**/*.scss\" --fix", 39 "fix": "stylelint \"{src,test}/**/*.scss\" --fix",
40 "livelint": "nodemon --watch src --watch test -e scss -x 'echo \"BEGIN LINT\" && npm run lint && echo \"END LINT\"'", 40 "livelint": "nodemon --watch src --watch test -e scss -x 'echo \"BEGIN LINT\" && npm run lint && echo \"END LINT\"'",
41 "doc": "sassdoc src", 41 "doc": "sassdoc src",
42 "test": "mocha test/test.js" 42 "test": "mocha test/test.js"
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 0000000..b436de9
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,3399 @@
1lockfileVersion: '9.0'
2
3settings:
4 autoInstallPeers: true
5 excludeLinksFromLockfile: false
6
7importers:
8
9 .:
10 devDependencies:
11 mocha:
12 specifier: ^10.7.3
13 version: 10.7.3
14 nodemon:
15 specifier: ^3.1.7
16 version: 3.1.7
17 postcss-scss:
18 specifier: ^4.0.3
19 version: 4.0.9(postcss@8.4.47)
20 sass:
21 specifier: ^1.79.4
22 version: 1.79.4
23 sass-true:
24 specifier: ^8.1.0
25 version: 8.1.0(sass@1.79.4)
26 sassdoc:
27 specifier: ^2.7.3
28 version: 2.7.4(chokidar@3.6.0)
29 stylelint:
30 specifier: ^16.9.0
31 version: 16.9.0
32 stylelint-config-sass-guidelines:
33 specifier: ^12.1.0
34 version: 12.1.0(postcss@8.4.47)(stylelint@16.9.0)
35
36packages:
37
38 '@adobe/css-tools@4.4.0':
39 resolution: {integrity: sha512-Ff9+ksdQQB3rMncgqDK78uLznstjyfIf2Arnh22pW8kBpLs6rpKDwgnZT46hin5Hl1WzazzK64DOrhSwYpS7bQ==}
40
41 '@babel/code-frame@7.25.7':
42 resolution: {integrity: sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g==}
43 engines: {node: '>=6.9.0'}
44
45 '@babel/helper-validator-identifier@7.25.7':
46 resolution: {integrity: sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg==}
47 engines: {node: '>=6.9.0'}
48
49 '@babel/highlight@7.25.7':
50 resolution: {integrity: sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw==}
51 engines: {node: '>=6.9.0'}
52
53 '@csstools/css-parser-algorithms@3.0.1':
54 resolution: {integrity: sha512-lSquqZCHxDfuTg/Sk2hiS0mcSFCEBuj49JfzPHJogDBT0mGCyY5A1AQzBWngitrp7i1/HAZpIgzF/VjhOEIJIg==}
55 engines: {node: '>=18'}
56 peerDependencies:
57 '@csstools/css-tokenizer': ^3.0.1
58
59 '@csstools/css-tokenizer@3.0.1':
60 resolution: {integrity: sha512-UBqaiu7kU0lfvaP982/o3khfXccVlHPWp0/vwwiIgDF0GmqqqxoiXC/6FCjlS9u92f7CoEz6nXKQnrn1kIAkOw==}
61 engines: {node: '>=18'}
62
63 '@csstools/media-query-list-parser@3.0.1':
64 resolution: {integrity: sha512-HNo8gGD02kHmcbX6PvCoUuOQvn4szyB9ca63vZHKX5A81QytgDG4oxG4IaEfHTlEZSZ6MjPEMWIVU+zF2PZcgw==}
65 engines: {node: '>=18'}
66 peerDependencies:
67 '@csstools/css-parser-algorithms': ^3.0.1
68 '@csstools/css-tokenizer': ^3.0.1
69
70 '@csstools/selector-specificity@4.0.0':
71 resolution: {integrity: sha512-189nelqtPd8++phaHNwYovKZI0FOzH1vQEE3QhHHkNIGrg5fSs9CbYP3RvfEH5geztnIA9Jwq91wyOIwAW5JIQ==}
72 engines: {node: '>=18'}
73 peerDependencies:
74 postcss-selector-parser: ^6.1.0
75
76 '@dual-bundle/import-meta-resolve@4.1.0':
77 resolution: {integrity: sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==}
78
79 '@jest/schemas@29.6.3':
80 resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==}
81 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
82
83 '@nodelib/fs.scandir@2.1.5':
84 resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
85 engines: {node: '>= 8'}
86
87 '@nodelib/fs.stat@2.0.5':
88 resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
89 engines: {node: '>= 8'}
90
91 '@nodelib/fs.walk@1.2.8':
92 resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
93 engines: {node: '>= 8'}
94
95 '@sinclair/typebox@0.27.8':
96 resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==}
97
98 '@sindresorhus/is@0.14.0':
99 resolution: {integrity: sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==}
100 engines: {node: '>=6'}
101
102 '@stylistic/stylelint-plugin@3.1.1':
103 resolution: {integrity: sha512-XagAHHIa528EvyGybv8EEYGK5zrVW74cHpsjhtovVATbhDRuJYfE+X4HCaAieW9lCkwbX6L+X0I4CiUG3w/hFw==}
104 engines: {node: ^18.12 || >=20.9}
105 peerDependencies:
106 stylelint: ^16.8.0
107
108 '@szmarczak/http-timer@1.1.2':
109 resolution: {integrity: sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==}
110 engines: {node: '>=6'}
111
112 '@types/keyv@3.1.4':
113 resolution: {integrity: sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==}
114
115 '@types/node@20.14.7':
116 resolution: {integrity: sha512-uTr2m2IbJJucF3KUxgnGOZvYbN0QgkGyWxG6973HCpMYFy2KfcgYuIwkJQMQkt1VbBMlvWRbpshFTLxnxCZjKQ==}
117
118 '@types/responselike@1.0.3':
119 resolution: {integrity: sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==}
120
121 a-sync-waterfall@1.0.1:
122 resolution: {integrity: sha512-RYTOHHdWipFUliRFMCS4X2Yn2X8M87V/OpSqWzKKOGhzqyUxzyVmhHDH9sAvG+ZuQf/TAOFsLCpMw09I1ufUnA==}
123
124 ajv@8.17.1:
125 resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
126
127 ansi-align@3.0.1:
128 resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
129
130 ansi-colors@4.1.3:
131 resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==}
132 engines: {node: '>=6'}
133
134 ansi-regex@5.0.1:
135 resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
136 engines: {node: '>=8'}
137
138 ansi-regex@6.1.0:
139 resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
140 engines: {node: '>=12'}
141
142 ansi-styles@3.2.1:
143 resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
144 engines: {node: '>=4'}
145
146 ansi-styles@4.3.0:
147 resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
148 engines: {node: '>=8'}
149
150 ansi-styles@5.2.0:
151 resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==}
152 engines: {node: '>=10'}
153
154 anymatch@3.1.3:
155 resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
156 engines: {node: '>= 8'}
157
158 append-buffer@1.0.2:
159 resolution: {integrity: sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==}
160 engines: {node: '>=0.10.0'}
161
162 argparse@1.0.10:
163 resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
164
165 argparse@2.0.1:
166 resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
167
168 array-union@2.1.0:
169 resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==}
170 engines: {node: '>=8'}
171
172 asap@2.0.6:
173 resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==}
174
175 astral-regex@2.0.0:
176 resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==}
177 engines: {node: '>=8'}
178
179 babel-runtime@6.26.0:
180 resolution: {integrity: sha512-ITKNuq2wKlW1fJg9sSW52eepoYgZBggvOAHC0u/CYu/qxQ9EVzThCgR69BnSXLHjy2f7SY5zaQ4yt7H9ZVxY2g==}
181
182 balanced-match@1.0.2:
183 resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
184
185 balanced-match@2.0.0:
186 resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==}
187
188 binary-extensions@2.3.0:
189 resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
190 engines: {node: '>=8'}
191
192 boxen@4.2.0:
193 resolution: {integrity: sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ==}
194 engines: {node: '>=8'}
195
196 brace-expansion@1.1.11:
197 resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==}
198
199 brace-expansion@2.0.1:
200 resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
201
202 braces@3.0.3:
203 resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
204 engines: {node: '>=8'}
205
206 browser-stdout@1.3.1:
207 resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==}
208
209 buffer-equal@1.0.1:
210 resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==}
211 engines: {node: '>=0.4'}
212
213 buffer-from@1.1.2:
214 resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==}
215
216 cacheable-request@6.1.0:
217 resolution: {integrity: sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==}
218 engines: {node: '>=8'}
219
220 call-bind@1.0.7:
221 resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==}
222 engines: {node: '>= 0.4'}
223
224 callsites@3.1.0:
225 resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
226 engines: {node: '>=6'}
227
228 camel-case@3.0.0:
229 resolution: {integrity: sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==}
230
231 camelcase@5.3.1:
232 resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==}
233 engines: {node: '>=6'}
234
235 camelcase@6.3.0:
236 resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==}
237 engines: {node: '>=10'}
238
239 cdocparser@0.13.0:
240 resolution: {integrity: sha512-bMi4t0qjeT0xQ8ECBmWcilMYcUNYsERQoatXveMIbItgqliZDCNyv2xfkBoKrs5H08ApeRMoysJLwgPiHtv7HQ==}
241
242 chalk@2.4.2:
243 resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
244 engines: {node: '>=4'}
245
246 chalk@3.0.0:
247 resolution: {integrity: sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==}
248 engines: {node: '>=8'}
249
250 chalk@4.1.2:
251 resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
252 engines: {node: '>=10'}
253
254 chokidar@3.6.0:
255 resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
256 engines: {node: '>= 8.10.0'}
257
258 chokidar@4.0.1:
259 resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==}
260 engines: {node: '>= 14.16.0'}
261
262 chroma-js@1.4.1:
263 resolution: {integrity: sha512-jTwQiT859RTFN/vIf7s+Vl/Z2LcMrvMv3WUFmd/4u76AdlFC0NTNgqEEFPcRiHmAswPsMiQEDZLM8vX8qXpZNQ==}
264
265 ci-info@2.0.0:
266 resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==}
267
268 clean-css@4.2.4:
269 resolution: {integrity: sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A==}
270 engines: {node: '>= 4.0'}
271
272 cli-boxes@2.2.1:
273 resolution: {integrity: sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw==}
274 engines: {node: '>=6'}
275
276 cliui@7.0.4:
277 resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==}
278
279 clone-buffer@1.0.0:
280 resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==}
281 engines: {node: '>= 0.10'}
282
283 clone-response@1.0.3:
284 resolution: {integrity: sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==}
285
286 clone-stats@0.0.1:
287 resolution: {integrity: sha512-dhUqc57gSMCo6TX85FLfe51eC/s+Im2MLkAgJwfaRRexR2tA4dd3eLEW4L6efzHc2iNorrRRXITifnDLlRrhaA==}
288
289 clone-stats@1.0.0:
290 resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==}
291
292 clone@0.2.0:
293 resolution: {integrity: sha512-g62n3Kb9cszeZvmvBUqP/dsEJD/+80pDA8u8KqHnAPrVnQ2Je9rVV6opxkhuWCd1kCn2gOibzDKxCtBvD3q5kA==}
294
295 clone@1.0.4:
296 resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==}
297 engines: {node: '>=0.8'}
298
299 clone@2.1.2:
300 resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==}
301 engines: {node: '>=0.8'}
302
303 cloneable-readable@1.1.3:
304 resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==}
305
306 color-convert@1.9.3:
307 resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
308
309 color-convert@2.0.1:
310 resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
311 engines: {node: '>=7.0.0'}
312
313 color-name@1.1.3:
314 resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
315
316 color-name@1.1.4:
317 resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
318
319 colord@2.9.3:
320 resolution: {integrity: sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==}
321
322 commander@2.17.1:
323 resolution: {integrity: sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==}
324
325 commander@2.19.0:
326 resolution: {integrity: sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==}
327
328 commander@5.1.0:
329 resolution: {integrity: sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==}
330 engines: {node: '>= 6'}
331
332 concat-map@0.0.1:
333 resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
334
335 concat-stream@1.6.2:
336 resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==}
337 engines: {'0': node >= 0.8}
338
339 concat-stream@2.0.0:
340 resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==}
341 engines: {'0': node >= 6.0}
342
343 configstore@5.0.1:
344 resolution: {integrity: sha512-aMKprgk5YhBNyH25hj8wGt2+D52Sw1DRRIzqBwLp2Ya9mFmY8KPvvtvmna8SxVR9JMZ4kzMD68N22vlaRpkeFA==}
345 engines: {node: '>=8'}
346
347 convert-source-map@1.9.0:
348 resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==}
349
350 core-js@2.6.12:
351 resolution: {integrity: sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==}
352 deprecated: core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.
353
354 core-util-is@1.0.3:
355 resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==}
356
357 cosmiconfig@9.0.0:
358 resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==}
359 engines: {node: '>=14'}
360 peerDependencies:
361 typescript: '>=4.9.5'
362 peerDependenciesMeta:
363 typescript:
364 optional: true
365
366 crypto-random-string@2.0.0:
367 resolution: {integrity: sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==}
368 engines: {node: '>=8'}
369
370 css-functions-list@3.2.2:
371 resolution: {integrity: sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==}
372 engines: {node: '>=12 || >=16'}
373
374 css-tree@2.3.1:
375 resolution: {integrity: sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==}
376 engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0}
377
378 cssesc@3.0.0:
379 resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
380 engines: {node: '>=4'}
381 hasBin: true
382
383 dargs@4.1.0:
384 resolution: {integrity: sha512-jyweV/k0rbv2WK4r9KLayuBrSh2Py0tNmV7LBoSMH4hMQyrG8OPyIOWB2VEx4DJKXWmK4lopYMVvORlDt2S8Aw==}
385 engines: {node: '>=0.10.0'}
386
387 debug@4.3.7:
388 resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
389 engines: {node: '>=6.0'}
390 peerDependencies:
391 supports-color: '*'
392 peerDependenciesMeta:
393 supports-color:
394 optional: true
395
396 decamelize@4.0.0:
397 resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==}
398 engines: {node: '>=10'}
399
400 decompress-response@3.3.0:
401 resolution: {integrity: sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==}
402 engines: {node: '>=4'}
403
404 deep-extend@0.6.0:
405 resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
406 engines: {node: '>=4.0.0'}
407
408 defer-to-connect@1.1.3:
409 resolution: {integrity: sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==}
410
411 define-data-property@1.1.4:
412 resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==}
413 engines: {node: '>= 0.4'}
414
415 define-properties@1.2.1:
416 resolution: {integrity: sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==}
417 engines: {node: '>= 0.4'}
418
419 diff-sequences@29.6.3:
420 resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==}
421 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
422
423 diff@5.2.0:
424 resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
425 engines: {node: '>=0.3.1'}
426
427 dir-glob@3.0.1:
428 resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==}
429 engines: {node: '>=8'}
430
431 docopt@0.6.2:
432 resolution: {integrity: sha512-NqTbaYeE4gA/wU1hdKFdU+AFahpDOpgGLzHP42k6H6DKExJd0A55KEVWYhL9FEmHmgeLvEU2vuKXDuU+4yToOw==}
433 engines: {node: '>=0.10.0'}
434
435 dot-prop@5.3.0:
436 resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==}
437 engines: {node: '>=8'}
438
439 duplexer2@0.1.4:
440 resolution: {integrity: sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==}
441
442 duplexer3@0.1.5:
443 resolution: {integrity: sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==}
444
445 duplexify@3.7.1:
446 resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==}
447
448 emoji-regex@8.0.0:
449 resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
450
451 end-of-stream@1.4.4:
452 resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
453
454 ends-with@0.2.0:
455 resolution: {integrity: sha512-lRppY4dK3VkqBdR242sKcAJeYc8Gf/DhoX9AWvWI2RzccmLnqBQfwm2k4oSDv5MPDjUqawCauXhZkyWxkVhRsg==}
456 engines: {node: '>=0.10.0'}
457
458 env-paths@2.2.1:
459 resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==}
460 engines: {node: '>=6'}
461
462 error-ex@1.3.2:
463 resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==}
464
465 es-define-property@1.0.0:
466 resolution: {integrity: sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==}
467 engines: {node: '>= 0.4'}
468
469 es-errors@1.3.0:
470 resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==}
471 engines: {node: '>= 0.4'}
472
473 es6-denodeify@0.1.5:
474 resolution: {integrity: sha512-731Rf4NqlPvhkT1pIF7r8vZxESJlWocNpXLuyPlVnfEGXlwuJaMvU5WpyyDjpudDC2cgXVX849xljzvQqBg1QQ==}
475
476 es6-promise@3.3.1:
477 resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==}
478
479 es6-promise@4.2.8:
480 resolution: {integrity: sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==}
481
482 escalade@3.2.0:
483 resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
484 engines: {node: '>=6'}
485
486 escape-goat@2.1.1:
487 resolution: {integrity: sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q==}
488 engines: {node: '>=8'}
489
490 escape-string-regexp@1.0.5:
491 resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
492 engines: {node: '>=0.8.0'}
493
494 escape-string-regexp@4.0.0:
495 resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==}
496 engines: {node: '>=10'}
497
498 esprima@4.0.1:
499 resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
500 engines: {node: '>=4'}
501 hasBin: true
502
503 extend@3.0.2:
504 resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
505
506 fast-deep-equal@3.1.3:
507 resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
508
509 fast-glob@3.3.2:
510 resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
511 engines: {node: '>=8.6.0'}
512
513 fast-uri@3.0.2:
514 resolution: {integrity: sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row==}
515
516 fastest-levenshtein@1.0.16:
517 resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==}
518 engines: {node: '>= 4.9.1'}
519
520 fastq@1.17.1:
521 resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
522
523 file-entry-cache@9.1.0:
524 resolution: {integrity: sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==}
525 engines: {node: '>=18'}
526
527 fill-range@7.1.1:
528 resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
529 engines: {node: '>=8'}
530
531 find-index@0.1.1:
532 resolution: {integrity: sha512-uJ5vWrfBKMcE6y2Z8834dwEZj9mNGxYa3t3I53OwFeuZ8D9oc2E5zcsrkuhX6h4iYrjhiv0T3szQmxlAV9uxDg==}
533
534 find-up@5.0.0:
535 resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==}
536 engines: {node: '>=10'}
537
538 flat-cache@5.0.0:
539 resolution: {integrity: sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==}
540 engines: {node: '>=18'}
541
542 flat@5.0.2:
543 resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==}
544 hasBin: true
545
546 flatted@3.3.1:
547 resolution: {integrity: sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==}
548
549 flush-write-stream@1.1.1:
550 resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==}
551
552 fs-extra@2.1.2:
553 resolution: {integrity: sha512-9ztMtDZtSKC78V8mev+k31qaTabbmuH5jatdvPBMikrFHvw5BqlYnQIn/WGK3WHeRooSTkRvLa2IPlaHjPq5Sg==}
554
555 fs-mkdirp-stream@1.0.0:
556 resolution: {integrity: sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==}
557 engines: {node: '>= 0.10'}
558
559 fs.realpath@1.0.0:
560 resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
561
562 fsevents@2.3.3:
563 resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
564 engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
565 os: [darwin]
566
567 function-bind@1.1.2:
568 resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
569
570 get-caller-file@2.0.5:
571 resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
572 engines: {node: 6.* || 8.* || >= 10.*}
573
574 get-intrinsic@1.2.4:
575 resolution: {integrity: sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==}
576 engines: {node: '>= 0.4'}
577
578 get-stdin@4.0.1:
579 resolution: {integrity: sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw==}
580 engines: {node: '>=0.10.0'}
581
582 get-stream@4.1.0:
583 resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==}
584 engines: {node: '>=6'}
585
586 get-stream@5.2.0:
587 resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==}
588 engines: {node: '>=8'}
589
590 glob-parent@3.1.0:
591 resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==}
592
593 glob-parent@5.1.2:
594 resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
595 engines: {node: '>= 6'}
596
597 glob-stream@6.1.0:
598 resolution: {integrity: sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==}
599 engines: {node: '>= 0.10'}
600
601 glob2base@0.0.12:
602 resolution: {integrity: sha512-ZyqlgowMbfj2NPjxaZZ/EtsXlOch28FRXgMd64vqZWk1bT9+wvSRLYD1om9M7QfQru51zJPAT17qXm4/zd+9QA==}
603 engines: {node: '>= 0.10'}
604
605 glob@7.2.3:
606 resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==}
607 deprecated: Glob versions prior to v9 are no longer supported
608
609 glob@8.1.0:
610 resolution: {integrity: sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==}
611 engines: {node: '>=12'}
612 deprecated: Glob versions prior to v9 are no longer supported
613
614 global-dirs@2.1.0:
615 resolution: {integrity: sha512-MG6kdOUh/xBnyo9cJFeIKkLEc1AyFq42QTU4XiX51i2NEdxLxLWXIjEjmqKeSuKR7pAZjTqUVoT2b2huxVLgYQ==}
616 engines: {node: '>=8'}
617
618 global-modules@2.0.0:
619 resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==}
620 engines: {node: '>=6'}
621
622 global-prefix@3.0.0:
623 resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==}
624 engines: {node: '>=6'}
625
626 globby@11.1.0:
627 resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==}
628 engines: {node: '>=10'}
629
630 globjoin@0.1.4:
631 resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==}
632
633 gopd@1.0.1:
634 resolution: {integrity: sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==}
635
636 got@9.6.0:
637 resolution: {integrity: sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==}
638 engines: {node: '>=8.6'}
639
640 graceful-fs@4.2.11:
641 resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
642
643 has-flag@3.0.0:
644 resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
645 engines: {node: '>=4'}
646
647 has-flag@4.0.0:
648 resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
649 engines: {node: '>=8'}
650
651 has-property-descriptors@1.0.2:
652 resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==}
653
654 has-proto@1.0.3:
655 resolution: {integrity: sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==}
656 engines: {node: '>= 0.4'}
657
658 has-symbols@1.0.3:
659 resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==}
660 engines: {node: '>= 0.4'}
661
662 has-yarn@2.1.0:
663 resolution: {integrity: sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==}
664 engines: {node: '>=8'}
665
666 hasown@2.0.2:
667 resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
668 engines: {node: '>= 0.4'}
669
670 he@1.2.0:
671 resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
672 hasBin: true
673
674 html-minifier@3.5.21:
675 resolution: {integrity: sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==}
676 engines: {node: '>=4'}
677 hasBin: true
678
679 html-tags@3.3.1:
680 resolution: {integrity: sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==}
681 engines: {node: '>=8'}
682
683 http-cache-semantics@4.1.1:
684 resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
685
686 ignore-by-default@1.0.1:
687 resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==}
688
689 ignore@5.3.2:
690 resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
691 engines: {node: '>= 4'}
692
693 immutable@4.3.7:
694 resolution: {integrity: sha512-1hqclzwYwjRDFLjcFxOM5AYkkG0rpFPpr1RLPMEuGczoS7YA8gLhy8SWXYRAA/XwfEHpfo3cw5JGioS32fnMRw==}
695
696 import-fresh@3.3.0:
697 resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
698 engines: {node: '>=6'}
699
700 import-lazy@2.1.0:
701 resolution: {integrity: sha512-m7ZEHgtw69qOGw+jwxXkHlrlIPdTGkyh66zXZ1ajZbxkDBNjSY/LGbmjc7h0s2ELsUDTAhFr55TrPSSqJGPG0A==}
702 engines: {node: '>=4'}
703
704 imurmurhash@0.1.4:
705 resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
706 engines: {node: '>=0.8.19'}
707
708 inflight@1.0.6:
709 resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==}
710 deprecated: This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.
711
712 inherits@2.0.4:
713 resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
714
715 ini@1.3.7:
716 resolution: {integrity: sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==}
717
718 ini@1.3.8:
719 resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
720
721 is-absolute@1.0.0:
722 resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==}
723 engines: {node: '>=0.10.0'}
724
725 is-arrayish@0.2.1:
726 resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==}
727
728 is-binary-path@2.1.0:
729 resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
730 engines: {node: '>=8'}
731
732 is-buffer@1.1.6:
733 resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==}
734
735 is-ci@2.0.0:
736 resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==}
737 hasBin: true
738
739 is-extglob@2.1.1:
740 resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
741 engines: {node: '>=0.10.0'}
742
743 is-fullwidth-code-point@3.0.0:
744 resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
745 engines: {node: '>=8'}
746
747 is-glob@3.1.0:
748 resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==}
749 engines: {node: '>=0.10.0'}
750
751 is-glob@4.0.3:
752 resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
753 engines: {node: '>=0.10.0'}
754
755 is-installed-globally@0.3.2:
756 resolution: {integrity: sha512-wZ8x1js7Ia0kecP/CHM/3ABkAmujX7WPvQk6uu3Fly/Mk44pySulQpnHG46OMjHGXApINnV4QhY3SWnECO2z5g==}
757 engines: {node: '>=8'}
758
759 is-negated-glob@1.0.0:
760 resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==}
761 engines: {node: '>=0.10.0'}
762
763 is-npm@4.0.0:
764 resolution: {integrity: sha512-96ECIfh9xtDDlPylNPXhzjsykHsMJZ18ASpaWzQyBr4YRTcVjUvzaHayDAES2oU/3KpljhHUjtSRNiDwi0F0ig==}
765 engines: {node: '>=8'}
766
767 is-number@7.0.0:
768 resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
769 engines: {node: '>=0.12.0'}
770
771 is-obj@2.0.0:
772 resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==}
773 engines: {node: '>=8'}
774
775 is-path-inside@3.0.3:
776 resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==}
777 engines: {node: '>=8'}
778
779 is-plain-obj@2.1.0:
780 resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==}
781 engines: {node: '>=8'}
782
783 is-plain-object@5.0.0:
784 resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==}
785 engines: {node: '>=0.10.0'}
786
787 is-relative@1.0.0:
788 resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==}
789 engines: {node: '>=0.10.0'}
790
791 is-typedarray@1.0.0:
792 resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==}
793
794 is-unc-path@1.0.0:
795 resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==}
796 engines: {node: '>=0.10.0'}
797
798 is-unicode-supported@0.1.0:
799 resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==}
800 engines: {node: '>=10'}
801
802 is-utf8@0.2.1:
803 resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==}
804
805 is-valid-glob@1.0.0:
806 resolution: {integrity: sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==}
807 engines: {node: '>=0.10.0'}
808
809 is-windows@1.0.2:
810 resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==}
811 engines: {node: '>=0.10.0'}
812
813 is-yarn-global@0.3.0:
814 resolution: {integrity: sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==}
815
816 isarray@0.0.1:
817 resolution: {integrity: sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==}
818
819 isarray@1.0.0:
820 resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==}
821
822 isexe@2.0.0:
823 resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
824
825 jest-diff@29.7.0:
826 resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==}
827 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
828
829 jest-get-type@29.6.3:
830 resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==}
831 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
832
833 js-tokens@4.0.0:
834 resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
835
836 js-yaml@3.14.1:
837 resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
838 hasBin: true
839
840 js-yaml@4.1.0:
841 resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
842 hasBin: true
843
844 json-buffer@3.0.0:
845 resolution: {integrity: sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==}
846
847 json-buffer@3.0.1:
848 resolution: {integrity: sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==}
849
850 json-parse-even-better-errors@2.3.1:
851 resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==}
852
853 json-schema-traverse@1.0.0:
854 resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
855
856 json-stable-stringify-without-jsonify@1.0.1:
857 resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
858
859 jsonfile@2.4.0:
860 resolution: {integrity: sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==}
861
862 keyv@3.1.0:
863 resolution: {integrity: sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==}
864
865 keyv@4.5.4:
866 resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==}
867
868 kind-of@6.0.3:
869 resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
870 engines: {node: '>=0.10.0'}
871
872 known-css-properties@0.34.0:
873 resolution: {integrity: sha512-tBECoUqNFbyAY4RrbqsBQqDFpGXAEbdD5QKr8kACx3+rnArmuuR22nKQWKazvp07N9yjTyDZaw/20UIH8tL9DQ==}
874
875 latest-version@5.1.0:
876 resolution: {integrity: sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==}
877 engines: {node: '>=8'}
878
879 lazystream@1.0.1:
880 resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
881 engines: {node: '>= 0.6.3'}
882
883 lead@1.0.0:
884 resolution: {integrity: sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==}
885 engines: {node: '>= 0.10'}
886
887 lines-and-columns@1.2.4:
888 resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
889
890 locate-path@6.0.0:
891 resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==}
892 engines: {node: '>=10'}
893
894 lodash._basebind@2.4.1:
895 resolution: {integrity: sha512-VGHm6DH+1UiuafQdE/DNMqxOcSyhRu0xO9+jPDq7xITRn5YOorGrHVQmavMVXCYmTm80YRTZZCn/jTW7MokwLg==}
896
897 lodash._basecreate@2.4.1:
898 resolution: {integrity: sha512-8JJ3FnMPm54t3BwPLk8q8mPyQKQXm/rt9df+awr4NGtyJrtcCXM3Of1I86S6jVy1b4yAyFBb8wbKPEauuqzRmQ==}
899
900 lodash._basecreatecallback@2.4.1:
901 resolution: {integrity: sha512-SLczhg860fGW7AKlYcuOFstDtJuQhaANlJ4Y/jrOoRxhmVtK41vbJDH3OefVRSRkSCQo4HI82QVkAVsoGa5gSw==}
902
903 lodash._basecreatewrapper@2.4.1:
904 resolution: {integrity: sha512-x2ja1fa/qmzbizuXgVM4QAP9svtMbdxjG8Anl9bCeDAwLOVQ1vLrA0hLb/NkpbGi9evjtkl0aWLTEoOlUdBPQA==}
905
906 lodash._createwrapper@2.4.1:
907 resolution: {integrity: sha512-5TCfLt1haQpsa7bgLYRKNNE4yqhO4ZxIayN1btQmazMchO6Q8JYFRMqbJ3W+uNmMm4R0Jw7KGkZX5YfDDnywuw==}
908
909 lodash._isnative@2.4.1:
910 resolution: {integrity: sha512-BOlKGKNHhCHswGOWtmVb5zBygyxN7EmTuzVOSQI6QSoGhG+kvv71gICFS1TBpnqvT1n53txK8CDK3u5D2/GZxQ==}
911
912 lodash._objecttypes@2.4.1:
913 resolution: {integrity: sha512-XpqGh1e7hhkOzftBfWE7zt+Yn9mVHFkDhicVttvKLsoCMLVVL+xTQjfjB4X4vtznauxv0QZ5ZAeqjvat0dh62Q==}
914
915 lodash._setbinddata@2.4.1:
916 resolution: {integrity: sha512-Vx0XKzpg2DFbQw4wrp1xSWd2sfl3W/BG6bucSRZmftS1AzbWRemCmBQDxyQTNhlLNec428PXkuuja+VNBZgu2A==}
917
918 lodash._shimkeys@2.4.1:
919 resolution: {integrity: sha512-lBrglYxLD/6KAJ8IEa5Lg+YHgNAL7FyKqXg4XOUI+Du/vtniLs1ZqS+yHNKPkK54waAgkdUnDOYaWf+rv4B+AA==}
920
921 lodash._slice@2.4.1:
922 resolution: {integrity: sha512-+odPJa4PE2UgYnQgJgkLs0UD03QU78R2ivhrFnG9GdtYOZdE6ObxOj7KiUEUlqOOgatFT+ZqSypFjDSduTigKg==}
923
924 lodash.assign@2.4.1:
925 resolution: {integrity: sha512-AqQ4AJz5buSx9ELXWt5dONwJyVPd4NTADMKhoVYWCugjoVf172/LpvVhwmSJn4g8/Dc0S8hxTe8rt5Dob3X9KQ==}
926
927 lodash.bind@2.4.1:
928 resolution: {integrity: sha512-hn2VWYZ+N9aYncRad4jORvlGgpFrn+axnPIWRvFxjk6CWcZH5b5alI8EymYsHITI23Z9wrW/+ORq+azrVFpOfw==}
929
930 lodash.difference@4.5.0:
931 resolution: {integrity: sha512-dS2j+W26TQ7taQBGN8Lbbq04ssV3emRw4NY58WErlTO29pIqS0HmoT5aJ9+TUQ1N3G+JOZSji4eugsWwGp9yPA==}
932
933 lodash.identity@2.4.1:
934 resolution: {integrity: sha512-VRYX+8XipeLjorag5bz3YBBRJ+5kj8hVBzfnaHgXPZAVTYowBdY5l0M5ZnOmlAMCOXBFabQtm7f5VqjMKEji0w==}
935
936 lodash.isfunction@2.4.1:
937 resolution: {integrity: sha512-6XcAB3izeQxPOQQNAJbbdjXbvWEt2Pn9ezPrjr4CwoLwmqsLVbsiEXD19cmmt4mbzOCOCdHzOQiUivUOJLra7w==}
938
939 lodash.isobject@2.4.1:
940 resolution: {integrity: sha512-sTebg2a1PoicYEZXD5PBdQcTlIJ6hUslrlWr7iV0O7n+i4596s2NQ9I5CaZ5FbXSfya/9WQsrYLANUJv9paYVA==}
941
942 lodash.keys@2.4.1:
943 resolution: {integrity: sha512-ZpJhwvUXHSNL5wYd1RM6CUa2ZuqorG9ngoJ9Ix5Cce+uX7I5O/E06FCJdhSZ33b5dVyeQDnIlWH7B2s5uByZ7g==}
944
945 lodash.noop@2.4.1:
946 resolution: {integrity: sha512-uNcV98/blRhInPUGQEnj9ekXXfG+q+rfoNSFZgl/eBfog9yBDW9gfUv2AHX/rAF7zZRlzWhbslGhbGQFZlCkZA==}
947
948 lodash.support@2.4.1:
949 resolution: {integrity: sha512-6SwqWwGFHhTXEiqB/yQgu8FYd//tm786d49y7kizHVCJH7zdzs191UQn3ES3tkkDbUddNRfkCRYqJFHtbLnbCw==}
950
951 lodash.truncate@4.4.2:
952 resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==}
953
954 lodash.uniq@4.5.0:
955 resolution: {integrity: sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==}
956
957 lodash@4.17.21:
958 resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
959
960 log-symbols@4.1.0:
961 resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==}
962 engines: {node: '>=10'}
963
964 lower-case@1.1.4:
965 resolution: {integrity: sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==}
966
967 lowercase-keys@1.0.1:
968 resolution: {integrity: sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==}
969 engines: {node: '>=0.10.0'}
970
971 lowercase-keys@2.0.0:
972 resolution: {integrity: sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==}
973 engines: {node: '>=8'}
974
975 make-dir@3.1.0:
976 resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
977 engines: {node: '>=8'}
978
979 marked@0.6.3:
980 resolution: {integrity: sha512-Fqa7eq+UaxfMriqzYLayfqAE40WN03jf+zHjT18/uXNuzjq3TY0XTbrAoPeqSJrAmPz11VuUA+kBPYOhHt9oOQ==}
981 engines: {node: '>=0.10.0'}
982 hasBin: true
983
984 mathml-tag-names@2.1.3:
985 resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==}
986
987 mdn-data@2.0.30:
988 resolution: {integrity: sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==}
989
990 memoize-decorator@1.0.2:
991 resolution: {integrity: sha512-G2vHcq4c+EwnBAOeWCH1mNz99QPCgm4ECjhHOd3SFZm66jVlwhBLdqhCvnHxptaRyZfm8ap3igoeDfrO92+uHQ==}
992
993 meow@13.2.0:
994 resolution: {integrity: sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==}
995 engines: {node: '>=18'}
996
997 merge2@1.4.1:
998 resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
999 engines: {node: '>= 8'}
1000
1001 micromatch@4.0.8:
1002 resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
1003 engines: {node: '>=8.6'}
1004
1005 mimic-response@1.0.1:
1006 resolution: {integrity: sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==}
1007 engines: {node: '>=4'}
1008
1009 min-indent@1.0.1:
1010 resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==}
1011 engines: {node: '>=4'}
1012
1013 minimatch@3.1.2:
1014 resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==}
1015
1016 minimatch@5.1.6:
1017 resolution: {integrity: sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==}
1018 engines: {node: '>=10'}
1019
1020 minimist@1.2.8:
1021 resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
1022
1023 mkdirp@1.0.4:
1024 resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
1025 engines: {node: '>=10'}
1026 hasBin: true
1027
1028 mocha@10.7.3:
1029 resolution: {integrity: sha512-uQWxAu44wwiACGqjbPYmjo7Lg8sFrS3dQe7PP2FQI+woptP4vZXSMcfMyFL/e1yFEeEpV4RtyTpZROOKmxis+A==}
1030 engines: {node: '>= 14.0.0'}
1031 hasBin: true
1032
1033 ms@2.1.3:
1034 resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
1035
1036 multipipe@1.0.2:
1037 resolution: {integrity: sha512-6uiC9OvY71vzSGX8lZvSqscE7ft9nPupJ8fMjrCNRAUy2LREUW42UL+V/NTrogr6rFgRydUrCX4ZitfpSNkSCQ==}
1038
1039 nanoid@3.3.7:
1040 resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
1041 engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
1042 hasBin: true
1043
1044 no-case@2.3.2:
1045 resolution: {integrity: sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==}
1046
1047 nodemon@3.1.7:
1048 resolution: {integrity: sha512-hLj7fuMow6f0lbB0cD14Lz2xNjwsyruH251Pk4t/yIitCFJbmY1myuLlHm/q06aST4jg6EgAh74PIBBrRqpVAQ==}
1049 engines: {node: '>=10'}
1050 hasBin: true
1051
1052 normalize-path@2.1.1:
1053 resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==}
1054 engines: {node: '>=0.10.0'}
1055
1056 normalize-path@3.0.0:
1057 resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
1058 engines: {node: '>=0.10.0'}
1059
1060 normalize-url@4.5.1:
1061 resolution: {integrity: sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==}
1062 engines: {node: '>=8'}
1063
1064 now-and-later@2.0.1:
1065 resolution: {integrity: sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==}
1066 engines: {node: '>= 0.10'}
1067
1068 number-is-nan@1.0.1:
1069 resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==}
1070 engines: {node: '>=0.10.0'}
1071
1072 nunjucks@3.2.4:
1073 resolution: {integrity: sha512-26XRV6BhkgK0VOxfbU5cQI+ICFUtMLixv1noZn1tGU38kQH5A5nmmbk/O45xdyBhD1esk47nKrY0mvQpZIhRjQ==}
1074 engines: {node: '>= 6.9.0'}
1075 hasBin: true
1076 peerDependencies:
1077 chokidar: ^3.3.0
1078 peerDependenciesMeta:
1079 chokidar:
1080 optional: true
1081
1082 object-assign@3.0.0:
1083 resolution: {integrity: sha512-jHP15vXVGeVh1HuaA2wY6lxk+whK/x4KBG88VXeRma7CCun7iGD5qPc4eYykQ9sdQvg8jkwFKsSxHln2ybW3xQ==}
1084 engines: {node: '>=0.10.0'}
1085
1086 object-assign@4.1.1:
1087 resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
1088 engines: {node: '>=0.10.0'}
1089
1090 object-keys@1.1.1:
1091 resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==}
1092 engines: {node: '>= 0.4'}
1093
1094 object.assign@4.1.5:
1095 resolution: {integrity: sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==}
1096 engines: {node: '>= 0.4'}
1097
1098 once@1.4.0:
1099 resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
1100
1101 ordered-read-streams@1.0.1:
1102 resolution: {integrity: sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==}
1103
1104 p-cancelable@1.1.0:
1105 resolution: {integrity: sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==}
1106 engines: {node: '>=6'}
1107
1108 p-limit@3.1.0:
1109 resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==}
1110 engines: {node: '>=10'}
1111
1112 p-locate@5.0.0:
1113 resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==}
1114 engines: {node: '>=10'}
1115
1116 package-json@6.5.0:
1117 resolution: {integrity: sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==}
1118 engines: {node: '>=8'}
1119
1120 param-case@2.1.1:
1121 resolution: {integrity: sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==}
1122
1123 parent-module@1.0.1:
1124 resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==}
1125 engines: {node: '>=6'}
1126
1127 parse-json@5.2.0:
1128 resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==}
1129 engines: {node: '>=8'}
1130
1131 path-dirname@1.0.2:
1132 resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==}
1133
1134 path-exists@4.0.0:
1135 resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
1136 engines: {node: '>=8'}
1137
1138 path-is-absolute@1.0.1:
1139 resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==}
1140 engines: {node: '>=0.10.0'}
1141
1142 path-type@4.0.0:
1143 resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
1144 engines: {node: '>=8'}
1145
1146 picocolors@1.1.0:
1147 resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
1148
1149 picomatch@2.3.1:
1150 resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
1151 engines: {node: '>=8.6'}
1152
1153 postcss-media-query-parser@0.2.3:
1154 resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==}
1155
1156 postcss-resolve-nested-selector@0.1.6:
1157 resolution: {integrity: sha512-0sglIs9Wmkzbr8lQwEyIzlDOOC9bGmfVKcJTaxv3vMmd3uo4o4DerC3En0bnmgceeql9BfC8hRkp7cg0fjdVqw==}
1158
1159 postcss-safe-parser@7.0.1:
1160 resolution: {integrity: sha512-0AioNCJZ2DPYz5ABT6bddIqlhgwhpHZ/l65YAYo0BCIn0xiDpsnTHz0gnoTGk0OXZW0JRs+cDwL8u/teRdz+8A==}
1161 engines: {node: '>=18.0'}
1162 peerDependencies:
1163 postcss: ^8.4.31
1164
1165 postcss-scss@4.0.9:
1166 resolution: {integrity: sha512-AjKOeiwAitL/MXxQW2DliT28EKukvvbEWx3LBmJIRN8KfBGZbRTxNYW0kSqi1COiTZ57nZ9NW06S6ux//N1c9A==}
1167 engines: {node: '>=12.0'}
1168 peerDependencies:
1169 postcss: ^8.4.29
1170
1171 postcss-selector-parser@6.1.2:
1172 resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
1173 engines: {node: '>=4'}
1174
1175 postcss-value-parser@4.2.0:
1176 resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
1177
1178 postcss@8.4.47:
1179 resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==}
1180 engines: {node: ^10 || ^12 || >=14}
1181
1182 prepend-http@2.0.0:
1183 resolution: {integrity: sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==}
1184 engines: {node: '>=4'}
1185
1186 pretty-format@29.7.0:
1187 resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==}
1188 engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0}
1189
1190 process-nextick-args@2.0.1:
1191 resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==}
1192
1193 pstree.remy@1.1.8:
1194 resolution: {integrity: sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w==}
1195
1196 pump@2.0.1:
1197 resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==}
1198
1199 pump@3.0.0:
1200 resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==}
1201
1202 pumpify@1.5.1:
1203 resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==}
1204
1205 pupa@2.1.1:
1206 resolution: {integrity: sha512-l1jNAspIBSFqbT+y+5FosojNpVpF94nlI+wDUpqP9enwOTfHx9f0gh5nB96vl+6yTpsJsypeNrwfzPrKuHB41A==}
1207 engines: {node: '>=8'}
1208
1209 q@1.5.1:
1210 resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==}
1211 engines: {node: '>=0.6.0', teleport: '>=0.2.0'}
1212 deprecated: |-
1213 You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
1214
1215 (For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
1216
1217 queue-microtask@1.2.3:
1218 resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
1219
1220 randombytes@2.1.0:
1221 resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==}
1222
1223 rc@1.2.8:
1224 resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
1225 hasBin: true
1226
1227 react-is@18.3.1:
1228 resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
1229
1230 readable-stream@1.1.14:
1231 resolution: {integrity: sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ==}
1232
1233 readable-stream@2.3.8:
1234 resolution: {integrity: sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==}
1235
1236 readable-stream@3.6.2:
1237 resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
1238 engines: {node: '>= 6'}
1239
1240 readdirp@3.6.0:
1241 resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
1242 engines: {node: '>=8.10.0'}
1243
1244 readdirp@4.0.2:
1245 resolution: {integrity: sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA==}
1246 engines: {node: '>= 14.16.0'}
1247
1248 regenerator-runtime@0.11.1:
1249 resolution: {integrity: sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==}
1250
1251 registry-auth-token@4.2.2:
1252 resolution: {integrity: sha512-PC5ZysNb42zpFME6D/XlIgtNGdTl8bBOCw90xQLVMpzuuubJKYDWFAEuUNc+Cn8Z8724tg2SDhDRrkVEsqfDMg==}
1253 engines: {node: '>=6.0.0'}
1254
1255 registry-url@5.1.0:
1256 resolution: {integrity: sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==}
1257 engines: {node: '>=8'}
1258
1259 relateurl@0.2.7:
1260 resolution: {integrity: sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog==}
1261 engines: {node: '>= 0.10'}
1262
1263 remove-bom-buffer@3.0.0:
1264 resolution: {integrity: sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==}
1265 engines: {node: '>=0.10.0'}
1266
1267 remove-bom-stream@1.2.0:
1268 resolution: {integrity: sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==}
1269 engines: {node: '>= 0.10'}
1270
1271 remove-trailing-separator@1.1.0:
1272 resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==}
1273
1274 replace-ext@0.0.1:
1275 resolution: {integrity: sha512-AFBWBy9EVRTa/LhEcG8QDP3FvpwZqmvN2QFDuJswFeaVhWnZMp8q3E6Zd90SR04PlIwfGdyVjNyLPyen/ek5CQ==}
1276 engines: {node: '>= 0.4'}
1277
1278 replace-ext@1.0.1:
1279 resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==}
1280 engines: {node: '>= 0.10'}
1281
1282 require-directory@2.1.1:
1283 resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
1284 engines: {node: '>=0.10.0'}
1285
1286 require-from-string@2.0.2:
1287 resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
1288 engines: {node: '>=0.10.0'}
1289
1290 resolve-from@4.0.0:
1291 resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1292 engines: {node: '>=4'}
1293
1294 resolve-from@5.0.0:
1295 resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==}
1296 engines: {node: '>=8'}
1297
1298 resolve-options@1.1.0:
1299 resolution: {integrity: sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==}
1300 engines: {node: '>= 0.10'}
1301
1302 responselike@1.0.2:
1303 resolution: {integrity: sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==}
1304
1305 reusify@1.0.4:
1306 resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
1307 engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
1308
1309 rimraf@2.7.1:
1310 resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==}
1311 deprecated: Rimraf versions prior to v4 are no longer supported
1312 hasBin: true
1313
1314 rimraf@3.0.2:
1315 resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==}
1316 deprecated: Rimraf versions prior to v4 are no longer supported
1317 hasBin: true
1318
1319 run-parallel@1.2.0:
1320 resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
1321
1322 safe-buffer@5.1.2:
1323 resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==}
1324
1325 safe-buffer@5.2.1:
1326 resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
1327
1328 safe-wipe@0.2.5:
1329 resolution: {integrity: sha512-MwTNf4YrRqCHsB5jUzOVdXoRbW4jkhgTvhlyfiaxox8EP7cOCiD4ydMOQCxDPR9KpvwdBSM2dQHScV1m85k8wQ==}
1330
1331 sass-convert@0.5.2:
1332 resolution: {integrity: sha512-eV9wXZg7MrHmnKLD6WojC/WX7lhLm+PSSLrOukzRIECa04fGbkmFDO9Ot9/82KjzSe+VEClYe9WDKzCuBz30Dg==}
1333 engines: {node: '>=0.10.0', npm: '>=2.1.0'}
1334
1335 sass-true@8.1.0:
1336 resolution: {integrity: sha512-LUiNRslsNreGk8Oe85ZvMmV0mlIh3LFP2KTDMZsSHz5DxPElCy7wI9ocJzf8IpIf7Q5ZO0w+hDBF1nbdUcmZHA==}
1337 engines: {node: '>=18'}
1338 peerDependencies:
1339 sass: '>=1.45.0'
1340 sass-embedded: '>=1.45.0'
1341 peerDependenciesMeta:
1342 sass:
1343 optional: true
1344 sass-embedded:
1345 optional: true
1346
1347 sass@1.79.4:
1348 resolution: {integrity: sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg==}
1349 engines: {node: '>=14.0.0'}
1350 hasBin: true
1351
1352 sassdoc-extras@2.5.1:
1353 resolution: {integrity: sha512-/+ilEnk1H1hG9nympL1GIFWhAczzoclyDzgzfphIg46nsT/dWJuzWYHyzIpduc/nTVwKeQfmTz0ZVvy12QMkrQ==}
1354
1355 sassdoc-theme-default@2.8.6:
1356 resolution: {integrity: sha512-s12y6pThpPDm33UScHfnfa/RBs9+gkCxl/YNWDTyLl3a6IxzusEdut1uwv4fpmpaOsTpcjGxZw839Moi4d/3Eg==}
1357
1358 sassdoc@2.7.4:
1359 resolution: {integrity: sha512-/HEjX9pMILkePyC4ZKGhkLqZHJZpsTxFwQIQNsLhV4XHiPKoWHrSmam1pMntM79tcdtBII3JX7ShfyZjHnrkyw==}
1360 hasBin: true
1361
1362 scss-comment-parser@0.8.4:
1363 resolution: {integrity: sha512-ERw4BODvM22n8Ke8hJxuH3fKXLm0Q4chfUNHwDSOAExCths2ZXq8PT32vms4R9Om6dffRSXzzGZS1p38UU4EAg==}
1364
1365 semver-diff@3.1.1:
1366 resolution: {integrity: sha512-GX0Ix/CJcHyB8c4ykpHGIAvLyOwOobtM/8d+TQkAd81/bEjgPHrfba41Vpesr7jX/t8Uh+R3EX9eAS5be+jQYg==}
1367 engines: {node: '>=8'}
1368
1369 semver-regex@1.0.0:
1370 resolution: {integrity: sha512-1vZcoRC+LPtHFkLUPyrabsATDSHerxW+hJBN8h04HZOZBuewbXaNROtUVdEPrTdZsWNq6sfsXDhd48GB2xTG4g==}
1371 engines: {node: '>=0.10.0'}
1372
1373 semver@5.7.2:
1374 resolution: {integrity: sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==}
1375 hasBin: true
1376
1377 semver@6.3.1:
1378 resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
1379 hasBin: true
1380
1381 semver@7.6.3:
1382 resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
1383 engines: {node: '>=10'}
1384 hasBin: true
1385
1386 serialize-javascript@6.0.2:
1387 resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==}
1388
1389 set-function-length@1.2.2:
1390 resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==}
1391 engines: {node: '>= 0.4'}
1392
1393 signal-exit@3.0.7:
1394 resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
1395
1396 signal-exit@4.1.0:
1397 resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
1398 engines: {node: '>=14'}
1399
1400 simple-update-notifier@2.0.0:
1401 resolution: {integrity: sha512-a2B9Y0KlNXl9u/vsW6sTIu9vGEpfKu2wRV6l1H3XEas/0gUIzGzBoP/IouTcUQbm9JWZLH3COxyn03TYlFax6w==}
1402 engines: {node: '>=10'}
1403
1404 slash@3.0.0:
1405 resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==}
1406 engines: {node: '>=8'}
1407
1408 slice-ansi@4.0.0:
1409 resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==}
1410 engines: {node: '>=10'}
1411
1412 source-map-js@1.2.1:
1413 resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
1414 engines: {node: '>=0.10.0'}
1415
1416 source-map@0.6.1:
1417 resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
1418 engines: {node: '>=0.10.0'}
1419
1420 sprintf-js@1.0.3:
1421 resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
1422
1423 stream-shift@1.0.3:
1424 resolution: {integrity: sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==}
1425
1426 string-width@4.2.3:
1427 resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
1428 engines: {node: '>=8'}
1429
1430 string_decoder@0.10.31:
1431 resolution: {integrity: sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ==}
1432
1433 string_decoder@1.1.1:
1434 resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==}
1435
1436 string_decoder@1.3.0:
1437 resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
1438
1439 strip-ansi@6.0.1:
1440 resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
1441 engines: {node: '>=8'}
1442
1443 strip-ansi@7.1.0:
1444 resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
1445 engines: {node: '>=12'}
1446
1447 strip-indent@1.0.1:
1448 resolution: {integrity: sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA==}
1449 engines: {node: '>=0.10.0'}
1450 hasBin: true
1451
1452 strip-indent@3.0.0:
1453 resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==}
1454 engines: {node: '>=8'}
1455
1456 strip-json-comments@2.0.1:
1457 resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
1458 engines: {node: '>=0.10.0'}
1459
1460 strip-json-comments@3.1.1:
1461 resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==}
1462 engines: {node: '>=8'}
1463
1464 style-search@0.1.0:
1465 resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==}
1466
1467 stylelint-config-sass-guidelines@12.1.0:
1468 resolution: {integrity: sha512-NTxEtVT6uNSqRvq+A3ScyKhjUrY/Z845TnpWEwnMgIPZ/+/Waa4+51r6OPuQRMu4XZS3D8DK1UaT4TWFBvuuAw==}
1469 engines: {node: '>=18.12.0'}
1470 peerDependencies:
1471 postcss: ^8.4.21
1472 stylelint: ^16.1.0
1473
1474 stylelint-scss@6.7.0:
1475 resolution: {integrity: sha512-RFIa2A+pVWS5wjNT+whtK7wsbZEWazyqesCuSaPbPlZ8lh2TujwVJSnCYJijg6ChZzwI8pZPRZS1L6A9aCbXDg==}
1476 engines: {node: '>=18.12.0'}
1477 peerDependencies:
1478 stylelint: ^16.0.2
1479
1480 stylelint@16.9.0:
1481 resolution: {integrity: sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==}
1482 engines: {node: '>=18.12.0'}
1483 hasBin: true
1484
1485 supports-color@5.5.0:
1486 resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
1487 engines: {node: '>=4'}
1488
1489 supports-color@7.2.0:
1490 resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
1491 engines: {node: '>=8'}
1492
1493 supports-color@8.1.1:
1494 resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==}
1495 engines: {node: '>=10'}
1496
1497 supports-hyperlinks@3.1.0:
1498 resolution: {integrity: sha512-2rn0BZ+/f7puLOHZm1HOJfwBggfaHXUpPUSSG/SWM4TWp5KCfmNYwnC3hruy2rZlMnmWZ+QAGpZfchu3f3695A==}
1499 engines: {node: '>=14.18'}
1500
1501 svg-tags@1.0.0:
1502 resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==}
1503
1504 table@6.8.2:
1505 resolution: {integrity: sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==}
1506 engines: {node: '>=10.0.0'}
1507
1508 term-size@2.2.1:
1509 resolution: {integrity: sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==}
1510 engines: {node: '>=8'}
1511
1512 through2-filter@3.0.0:
1513 resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==}
1514
1515 through2@1.1.1:
1516 resolution: {integrity: sha512-zEbpaeSMHxczpTzO1KkMHjBC1enTA68ojeaZGG4toqdASpb9t4xUZaYFBq2/9OHo5nTGFVSYd4c910OR+6wxbQ==}
1517
1518 through2@2.0.5:
1519 resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==}
1520
1521 to-absolute-glob@2.0.2:
1522 resolution: {integrity: sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==}
1523 engines: {node: '>=0.10.0'}
1524
1525 to-readable-stream@1.0.0:
1526 resolution: {integrity: sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==}
1527 engines: {node: '>=6'}
1528
1529 to-regex-range@5.0.1:
1530 resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
1531 engines: {node: '>=8.0'}
1532
1533 to-through@2.0.0:
1534 resolution: {integrity: sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==}
1535 engines: {node: '>= 0.10'}
1536
1537 touch@3.1.1:
1538 resolution: {integrity: sha512-r0eojU4bI8MnHr8c5bNo7lJDdI2qXlWWJk6a9EAFG7vbhTjElYhBVS3/miuE0uOuoLdb8Mc/rVfsmm6eo5o9GA==}
1539 hasBin: true
1540
1541 type-fest@0.8.1:
1542 resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==}
1543 engines: {node: '>=8'}
1544
1545 typedarray-to-buffer@3.1.5:
1546 resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==}
1547
1548 typedarray@0.0.6:
1549 resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==}
1550
1551 uglify-js@3.4.10:
1552 resolution: {integrity: sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==}
1553 engines: {node: '>=0.8.0'}
1554 hasBin: true
1555
1556 unc-path-regex@0.1.2:
1557 resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==}
1558 engines: {node: '>=0.10.0'}
1559
1560 undefsafe@2.0.5:
1561 resolution: {integrity: sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA==}
1562
1563 undici-types@5.26.5:
1564 resolution: {integrity: sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==}
1565
1566 unique-stream@2.3.1:
1567 resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==}
1568
1569 unique-string@2.0.0:
1570 resolution: {integrity: sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==}
1571 engines: {node: '>=8'}
1572
1573 update-notifier@4.1.3:
1574 resolution: {integrity: sha512-Yld6Z0RyCYGB6ckIjffGOSOmHXj1gMeE7aROz4MG+XMkmixBX4jUngrGXNYz7wPKBmtoD4MnBa2Anu7RSKht/A==}
1575 engines: {node: '>=8'}
1576
1577 upper-case@1.1.3:
1578 resolution: {integrity: sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==}
1579
1580 url-parse-lax@3.0.0:
1581 resolution: {integrity: sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==}
1582 engines: {node: '>=4'}
1583
1584 util-deprecate@1.0.2:
1585 resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
1586
1587 value-or-function@3.0.0:
1588 resolution: {integrity: sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==}
1589 engines: {node: '>= 0.10'}
1590
1591 vinyl-fs@3.0.3:
1592 resolution: {integrity: sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==}
1593 engines: {node: '>= 0.10'}
1594
1595 vinyl-source-stream@1.1.2:
1596 resolution: {integrity: sha512-X+1Jq+M6ufv/ky480hndPBsNb0ieqTQkvpakxMTxb7oUlyuNaJKL2HddYUrbTec0Lb0J53JlDiCetcgJ3b3Wmg==}
1597
1598 vinyl-sourcemap@1.1.0:
1599 resolution: {integrity: sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==}
1600 engines: {node: '>= 0.10'}
1601
1602 vinyl-string@1.0.2:
1603 resolution: {integrity: sha512-mDkPUvCM7K9r0WYZKIWc/dfPH8wkJBbe/3wZUU9EJyw3g6VSACg6FLlcZ/QbP1lTSdtBsVjQoYG1a9K0cfoKeQ==}
1604
1605 vinyl@0.4.6:
1606 resolution: {integrity: sha512-pmza4M5VA15HOImIQYWhoXGlGNafCm0QK5BpBUXkzzEwrRxKqBsbAhTfkT2zMcJhUX1G1Gkid0xaV8WjOl7DsA==}
1607 engines: {node: '>= 0.9'}
1608
1609 vinyl@1.2.0:
1610 resolution: {integrity: sha512-Ci3wnR2uuSAWFMSglZuB8Z2apBdtOyz8CV7dC6/U1XbltXBC+IuutUkXQISz01P+US2ouBuesSbV6zILZ6BuzQ==}
1611 engines: {node: '>= 0.9'}
1612
1613 vinyl@2.2.1:
1614 resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==}
1615 engines: {node: '>= 0.10'}
1616
1617 which@1.3.1:
1618 resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==}
1619 hasBin: true
1620
1621 widest-line@3.1.0:
1622 resolution: {integrity: sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg==}
1623 engines: {node: '>=8'}
1624
1625 workerpool@6.5.1:
1626 resolution: {integrity: sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA==}
1627
1628 wrap-ansi@7.0.0:
1629 resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
1630 engines: {node: '>=10'}
1631
1632 wrappy@1.0.2:
1633 resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
1634
1635 write-file-atomic@3.0.3:
1636 resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==}
1637
1638 write-file-atomic@5.0.1:
1639 resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==}
1640 engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
1641
1642 xdg-basedir@4.0.0:
1643 resolution: {integrity: sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q==}
1644 engines: {node: '>=8'}
1645
1646 xtend@4.0.2:
1647 resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
1648 engines: {node: '>=0.4'}
1649
1650 y18n@5.0.8:
1651 resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
1652 engines: {node: '>=10'}
1653
1654 yargs-parser@20.2.9:
1655 resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==}
1656 engines: {node: '>=10'}
1657
1658 yargs-unparser@2.0.0:
1659 resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==}
1660 engines: {node: '>=10'}
1661
1662 yargs@16.2.0:
1663 resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==}
1664 engines: {node: '>=10'}
1665
1666 yocto-queue@0.1.0:
1667 resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
1668 engines: {node: '>=10'}
1669
1670snapshots:
1671
1672 '@adobe/css-tools@4.4.0': {}
1673
1674 '@babel/code-frame@7.25.7':
1675 dependencies:
1676 '@babel/highlight': 7.25.7
1677 picocolors: 1.1.0
1678
1679 '@babel/helper-validator-identifier@7.25.7': {}
1680
1681 '@babel/highlight@7.25.7':
1682 dependencies:
1683 '@babel/helper-validator-identifier': 7.25.7
1684 chalk: 2.4.2
1685 js-tokens: 4.0.0
1686 picocolors: 1.1.0
1687
1688 '@csstools/css-parser-algorithms@3.0.1(@csstools/css-tokenizer@3.0.1)':
1689 dependencies:
1690 '@csstools/css-tokenizer': 3.0.1
1691
1692 '@csstools/css-tokenizer@3.0.1': {}
1693
1694 '@csstools/media-query-list-parser@3.0.1(@csstools/css-parser-algorithms@3.0.1(@csstools/css-tokenizer@3.0.1))(@csstools/css-tokenizer@3.0.1)':
1695 dependencies:
1696 '@csstools/css-parser-algorithms': 3.0.1(@csstools/css-tokenizer@3.0.1)
1697 '@csstools/css-tokenizer': 3.0.1
1698
1699 '@csstools/selector-specificity@4.0.0(postcss-selector-parser@6.1.2)':
1700 dependencies:
1701 postcss-selector-parser: 6.1.2
1702
1703 '@dual-bundle/import-meta-resolve@4.1.0': {}
1704
1705 '@jest/schemas@29.6.3':
1706 dependencies:
1707 '@sinclair/typebox': 0.27.8
1708
1709 '@nodelib/fs.scandir@2.1.5':
1710 dependencies:
1711 '@nodelib/fs.stat': 2.0.5
1712 run-parallel: 1.2.0
1713
1714 '@nodelib/fs.stat@2.0.5': {}
1715
1716 '@nodelib/fs.walk@1.2.8':
1717 dependencies:
1718 '@nodelib/fs.scandir': 2.1.5
1719 fastq: 1.17.1
1720
1721 '@sinclair/typebox@0.27.8': {}
1722
1723 '@sindresorhus/is@0.14.0': {}
1724
1725 '@stylistic/stylelint-plugin@3.1.1(stylelint@16.9.0)':
1726 dependencies:
1727 '@csstools/css-parser-algorithms': 3.0.1(@csstools/css-tokenizer@3.0.1)
1728 '@csstools/css-tokenizer': 3.0.1
1729 '@csstools/media-query-list-parser': 3.0.1(@csstools/css-parser-algorithms@3.0.1(@csstools/css-tokenizer@3.0.1))(@csstools/css-tokenizer@3.0.1)
1730 is-plain-object: 5.0.0
1731 postcss-selector-parser: 6.1.2
1732 postcss-value-parser: 4.2.0
1733 style-search: 0.1.0
1734 stylelint: 16.9.0
1735
1736 '@szmarczak/http-timer@1.1.2':
1737 dependencies:
1738 defer-to-connect: 1.1.3
1739
1740 '@types/keyv@3.1.4':
1741 dependencies:
1742 '@types/node': 20.14.7
1743
1744 '@types/node@20.14.7':
1745 dependencies:
1746 undici-types: 5.26.5
1747
1748 '@types/responselike@1.0.3':
1749 dependencies:
1750 '@types/node': 20.14.7
1751
1752 a-sync-waterfall@1.0.1: {}
1753
1754 ajv@8.17.1:
1755 dependencies:
1756 fast-deep-equal: 3.1.3
1757 fast-uri: 3.0.2
1758 json-schema-traverse: 1.0.0
1759 require-from-string: 2.0.2
1760
1761 ansi-align@3.0.1:
1762 dependencies:
1763 string-width: 4.2.3
1764
1765 ansi-colors@4.1.3: {}
1766
1767 ansi-regex@5.0.1: {}
1768
1769 ansi-regex@6.1.0: {}
1770
1771 ansi-styles@3.2.1:
1772 dependencies:
1773 color-convert: 1.9.3
1774
1775 ansi-styles@4.3.0:
1776 dependencies:
1777 color-convert: 2.0.1
1778
1779 ansi-styles@5.2.0: {}
1780
1781 anymatch@3.1.3:
1782 dependencies:
1783 normalize-path: 3.0.0
1784 picomatch: 2.3.1
1785
1786 append-buffer@1.0.2:
1787 dependencies:
1788 buffer-equal: 1.0.1
1789
1790 argparse@1.0.10:
1791 dependencies:
1792 sprintf-js: 1.0.3
1793
1794 argparse@2.0.1: {}
1795
1796 array-union@2.1.0: {}
1797
1798 asap@2.0.6: {}
1799
1800 astral-regex@2.0.0: {}
1801
1802 babel-runtime@6.26.0:
1803 dependencies:
1804 core-js: 2.6.12
1805 regenerator-runtime: 0.11.1
1806
1807 balanced-match@1.0.2: {}
1808
1809 balanced-match@2.0.0: {}
1810
1811 binary-extensions@2.3.0: {}
1812
1813 boxen@4.2.0:
1814 dependencies:
1815 ansi-align: 3.0.1
1816 camelcase: 5.3.1
1817 chalk: 3.0.0
1818 cli-boxes: 2.2.1
1819 string-width: 4.2.3
1820 term-size: 2.2.1
1821 type-fest: 0.8.1
1822 widest-line: 3.1.0
1823
1824 brace-expansion@1.1.11:
1825 dependencies:
1826 balanced-match: 1.0.2
1827 concat-map: 0.0.1
1828
1829 brace-expansion@2.0.1:
1830 dependencies:
1831 balanced-match: 1.0.2
1832
1833 braces@3.0.3:
1834 dependencies:
1835 fill-range: 7.1.1
1836
1837 browser-stdout@1.3.1: {}
1838
1839 buffer-equal@1.0.1: {}
1840
1841 buffer-from@1.1.2: {}
1842
1843 cacheable-request@6.1.0:
1844 dependencies:
1845 clone-response: 1.0.3
1846 get-stream: 5.2.0
1847 http-cache-semantics: 4.1.1
1848 keyv: 3.1.0
1849 lowercase-keys: 2.0.0
1850 normalize-url: 4.5.1
1851 responselike: 1.0.2
1852
1853 call-bind@1.0.7:
1854 dependencies:
1855 es-define-property: 1.0.0
1856 es-errors: 1.3.0
1857 function-bind: 1.1.2
1858 get-intrinsic: 1.2.4
1859 set-function-length: 1.2.2
1860
1861 callsites@3.1.0: {}
1862
1863 camel-case@3.0.0:
1864 dependencies:
1865 no-case: 2.3.2
1866 upper-case: 1.1.3
1867
1868 camelcase@5.3.1: {}
1869
1870 camelcase@6.3.0: {}
1871
1872 cdocparser@0.13.0:
1873 dependencies:
1874 escape-string-regexp: 1.0.5
1875 lodash.assign: 2.4.1
1876 strip-indent: 1.0.1
1877
1878 chalk@2.4.2:
1879 dependencies:
1880 ansi-styles: 3.2.1
1881 escape-string-regexp: 1.0.5
1882 supports-color: 5.5.0
1883
1884 chalk@3.0.0:
1885 dependencies:
1886 ansi-styles: 4.3.0
1887 supports-color: 7.2.0
1888
1889 chalk@4.1.2:
1890 dependencies:
1891 ansi-styles: 4.3.0
1892 supports-color: 7.2.0
1893
1894 chokidar@3.6.0:
1895 dependencies:
1896 anymatch: 3.1.3
1897 braces: 3.0.3
1898 glob-parent: 5.1.2
1899 is-binary-path: 2.1.0
1900 is-glob: 4.0.3
1901 normalize-path: 3.0.0
1902 readdirp: 3.6.0
1903 optionalDependencies:
1904 fsevents: 2.3.3
1905
1906 chokidar@4.0.1:
1907 dependencies:
1908 readdirp: 4.0.2
1909
1910 chroma-js@1.4.1: {}
1911
1912 ci-info@2.0.0: {}
1913
1914 clean-css@4.2.4:
1915 dependencies:
1916 source-map: 0.6.1
1917
1918 cli-boxes@2.2.1: {}
1919
1920 cliui@7.0.4:
1921 dependencies:
1922 string-width: 4.2.3
1923 strip-ansi: 6.0.1
1924 wrap-ansi: 7.0.0
1925
1926 clone-buffer@1.0.0: {}
1927
1928 clone-response@1.0.3:
1929 dependencies:
1930 mimic-response: 1.0.1
1931
1932 clone-stats@0.0.1: {}
1933
1934 clone-stats@1.0.0: {}
1935
1936 clone@0.2.0: {}
1937
1938 clone@1.0.4: {}
1939
1940 clone@2.1.2: {}
1941
1942 cloneable-readable@1.1.3:
1943 dependencies:
1944 inherits: 2.0.4
1945 process-nextick-args: 2.0.1
1946 readable-stream: 2.3.8
1947
1948 color-convert@1.9.3:
1949 dependencies:
1950 color-name: 1.1.3
1951
1952 color-convert@2.0.1:
1953 dependencies:
1954 color-name: 1.1.4
1955
1956 color-name@1.1.3: {}
1957
1958 color-name@1.1.4: {}
1959
1960 colord@2.9.3: {}
1961
1962 commander@2.17.1: {}
1963
1964 commander@2.19.0: {}
1965
1966 commander@5.1.0: {}
1967
1968 concat-map@0.0.1: {}
1969
1970 concat-stream@1.6.2:
1971 dependencies:
1972 buffer-from: 1.1.2
1973 inherits: 2.0.4
1974 readable-stream: 2.3.8
1975 typedarray: 0.0.6
1976
1977 concat-stream@2.0.0:
1978 dependencies:
1979 buffer-from: 1.1.2
1980 inherits: 2.0.4
1981 readable-stream: 3.6.2
1982 typedarray: 0.0.6
1983
1984 configstore@5.0.1:
1985 dependencies:
1986 dot-prop: 5.3.0
1987 graceful-fs: 4.2.11
1988 make-dir: 3.1.0
1989 unique-string: 2.0.0
1990 write-file-atomic: 3.0.3
1991 xdg-basedir: 4.0.0
1992
1993 convert-source-map@1.9.0: {}
1994
1995 core-js@2.6.12: {}
1996
1997 core-util-is@1.0.3: {}
1998
1999 cosmiconfig@9.0.0:
2000 dependencies:
2001 env-paths: 2.2.1
2002 import-fresh: 3.3.0
2003 js-yaml: 4.1.0
2004 parse-json: 5.2.0
2005
2006 crypto-random-string@2.0.0: {}
2007
2008 css-functions-list@3.2.2: {}
2009
2010 css-tree@2.3.1:
2011 dependencies:
2012 mdn-data: 2.0.30
2013 source-map-js: 1.2.1
2014
2015 cssesc@3.0.0: {}
2016
2017 dargs@4.1.0:
2018 dependencies:
2019 number-is-nan: 1.0.1
2020
2021 debug@4.3.7:
2022 dependencies:
2023 ms: 2.1.3
2024
2025 debug@4.3.7(supports-color@5.5.0):
2026 dependencies:
2027 ms: 2.1.3
2028 optionalDependencies:
2029 supports-color: 5.5.0
2030
2031 debug@4.3.7(supports-color@8.1.1):
2032 dependencies:
2033 ms: 2.1.3
2034 optionalDependencies:
2035 supports-color: 8.1.1
2036
2037 decamelize@4.0.0: {}
2038
2039 decompress-response@3.3.0:
2040 dependencies:
2041 mimic-response: 1.0.1
2042
2043 deep-extend@0.6.0: {}
2044
2045 defer-to-connect@1.1.3: {}
2046
2047 define-data-property@1.1.4:
2048 dependencies:
2049 es-define-property: 1.0.0
2050 es-errors: 1.3.0
2051 gopd: 1.0.1
2052
2053 define-properties@1.2.1:
2054 dependencies:
2055 define-data-property: 1.1.4
2056 has-property-descriptors: 1.0.2
2057 object-keys: 1.1.1
2058
2059 diff-sequences@29.6.3: {}
2060
2061 diff@5.2.0: {}
2062
2063 dir-glob@3.0.1:
2064 dependencies:
2065 path-type: 4.0.0
2066
2067 docopt@0.6.2: {}
2068
2069 dot-prop@5.3.0:
2070 dependencies:
2071 is-obj: 2.0.0
2072
2073 duplexer2@0.1.4:
2074 dependencies:
2075 readable-stream: 2.3.8
2076
2077 duplexer3@0.1.5: {}
2078
2079 duplexify@3.7.1:
2080 dependencies:
2081 end-of-stream: 1.4.4
2082 inherits: 2.0.4
2083 readable-stream: 2.3.8
2084 stream-shift: 1.0.3
2085
2086 emoji-regex@8.0.0: {}
2087
2088 end-of-stream@1.4.4:
2089 dependencies:
2090 once: 1.4.0
2091
2092 ends-with@0.2.0: {}
2093
2094 env-paths@2.2.1: {}
2095
2096 error-ex@1.3.2:
2097 dependencies:
2098 is-arrayish: 0.2.1
2099
2100 es-define-property@1.0.0:
2101 dependencies:
2102 get-intrinsic: 1.2.4
2103
2104 es-errors@1.3.0: {}
2105
2106 es6-denodeify@0.1.5: {}
2107
2108 es6-promise@3.3.1: {}
2109
2110 es6-promise@4.2.8: {}
2111
2112 escalade@3.2.0: {}
2113
2114 escape-goat@2.1.1: {}
2115
2116 escape-string-regexp@1.0.5: {}
2117
2118 escape-string-regexp@4.0.0: {}
2119
2120 esprima@4.0.1: {}
2121
2122 extend@3.0.2: {}
2123
2124 fast-deep-equal@3.1.3: {}
2125
2126 fast-glob@3.3.2:
2127 dependencies:
2128 '@nodelib/fs.stat': 2.0.5
2129 '@nodelib/fs.walk': 1.2.8
2130 glob-parent: 5.1.2
2131 merge2: 1.4.1
2132 micromatch: 4.0.8
2133
2134 fast-uri@3.0.2: {}
2135
2136 fastest-levenshtein@1.0.16: {}
2137
2138 fastq@1.17.1:
2139 dependencies:
2140 reusify: 1.0.4
2141
2142 file-entry-cache@9.1.0:
2143 dependencies:
2144 flat-cache: 5.0.0
2145
2146 fill-range@7.1.1:
2147 dependencies:
2148 to-regex-range: 5.0.1
2149
2150 find-index@0.1.1: {}
2151
2152 find-up@5.0.0:
2153 dependencies:
2154 locate-path: 6.0.0
2155 path-exists: 4.0.0
2156
2157 flat-cache@5.0.0:
2158 dependencies:
2159 flatted: 3.3.1
2160 keyv: 4.5.4
2161
2162 flat@5.0.2: {}
2163
2164 flatted@3.3.1: {}
2165
2166 flush-write-stream@1.1.1:
2167 dependencies:
2168 inherits: 2.0.4
2169 readable-stream: 2.3.8
2170
2171 fs-extra@2.1.2:
2172 dependencies:
2173 graceful-fs: 4.2.11
2174 jsonfile: 2.4.0
2175
2176 fs-mkdirp-stream@1.0.0:
2177 dependencies:
2178 graceful-fs: 4.2.11
2179 through2: 2.0.5
2180
2181 fs.realpath@1.0.0: {}
2182
2183 fsevents@2.3.3:
2184 optional: true
2185
2186 function-bind@1.1.2: {}
2187
2188 get-caller-file@2.0.5: {}
2189
2190 get-intrinsic@1.2.4:
2191 dependencies:
2192 es-errors: 1.3.0
2193 function-bind: 1.1.2
2194 has-proto: 1.0.3
2195 has-symbols: 1.0.3
2196 hasown: 2.0.2
2197
2198 get-stdin@4.0.1: {}
2199
2200 get-stream@4.1.0:
2201 dependencies:
2202 pump: 3.0.0
2203
2204 get-stream@5.2.0:
2205 dependencies:
2206 pump: 3.0.0
2207
2208 glob-parent@3.1.0:
2209 dependencies:
2210 is-glob: 3.1.0
2211 path-dirname: 1.0.2
2212
2213 glob-parent@5.1.2:
2214 dependencies:
2215 is-glob: 4.0.3
2216
2217 glob-stream@6.1.0:
2218 dependencies:
2219 extend: 3.0.2
2220 glob: 7.2.3
2221 glob-parent: 3.1.0
2222 is-negated-glob: 1.0.0
2223 ordered-read-streams: 1.0.1
2224 pumpify: 1.5.1
2225 readable-stream: 2.3.8
2226 remove-trailing-separator: 1.1.0
2227 to-absolute-glob: 2.0.2
2228 unique-stream: 2.3.1
2229
2230 glob2base@0.0.12:
2231 dependencies:
2232 find-index: 0.1.1
2233
2234 glob@7.2.3:
2235 dependencies:
2236 fs.realpath: 1.0.0
2237 inflight: 1.0.6
2238 inherits: 2.0.4
2239 minimatch: 3.1.2
2240 once: 1.4.0
2241 path-is-absolute: 1.0.1
2242
2243 glob@8.1.0:
2244 dependencies:
2245 fs.realpath: 1.0.0
2246 inflight: 1.0.6
2247 inherits: 2.0.4
2248 minimatch: 5.1.6
2249 once: 1.4.0
2250
2251 global-dirs@2.1.0:
2252 dependencies:
2253 ini: 1.3.7
2254
2255 global-modules@2.0.0:
2256 dependencies:
2257 global-prefix: 3.0.0
2258
2259 global-prefix@3.0.0:
2260 dependencies:
2261 ini: 1.3.8
2262 kind-of: 6.0.3
2263 which: 1.3.1
2264
2265 globby@11.1.0:
2266 dependencies:
2267 array-union: 2.1.0
2268 dir-glob: 3.0.1
2269 fast-glob: 3.3.2
2270 ignore: 5.3.2
2271 merge2: 1.4.1
2272 slash: 3.0.0
2273
2274 globjoin@0.1.4: {}
2275
2276 gopd@1.0.1:
2277 dependencies:
2278 get-intrinsic: 1.2.4
2279
2280 got@9.6.0:
2281 dependencies:
2282 '@sindresorhus/is': 0.14.0
2283 '@szmarczak/http-timer': 1.1.2
2284 '@types/keyv': 3.1.4
2285 '@types/responselike': 1.0.3
2286 cacheable-request: 6.1.0
2287 decompress-response: 3.3.0
2288 duplexer3: 0.1.5
2289 get-stream: 4.1.0
2290 lowercase-keys: 1.0.1
2291 mimic-response: 1.0.1
2292 p-cancelable: 1.1.0
2293 to-readable-stream: 1.0.0
2294 url-parse-lax: 3.0.0
2295
2296 graceful-fs@4.2.11: {}
2297
2298 has-flag@3.0.0: {}
2299
2300 has-flag@4.0.0: {}
2301
2302 has-property-descriptors@1.0.2:
2303 dependencies:
2304 es-define-property: 1.0.0
2305
2306 has-proto@1.0.3: {}
2307
2308 has-symbols@1.0.3: {}
2309
2310 has-yarn@2.1.0: {}
2311
2312 hasown@2.0.2:
2313 dependencies:
2314 function-bind: 1.1.2
2315
2316 he@1.2.0: {}
2317
2318 html-minifier@3.5.21:
2319 dependencies:
2320 camel-case: 3.0.0
2321 clean-css: 4.2.4
2322 commander: 2.17.1
2323 he: 1.2.0
2324 param-case: 2.1.1
2325 relateurl: 0.2.7
2326 uglify-js: 3.4.10
2327
2328 html-tags@3.3.1: {}
2329
2330 http-cache-semantics@4.1.1: {}
2331
2332 ignore-by-default@1.0.1: {}
2333
2334 ignore@5.3.2: {}
2335
2336 immutable@4.3.7: {}
2337
2338 import-fresh@3.3.0:
2339 dependencies:
2340 parent-module: 1.0.1
2341 resolve-from: 4.0.0
2342
2343 import-lazy@2.1.0: {}
2344
2345 imurmurhash@0.1.4: {}
2346
2347 inflight@1.0.6:
2348 dependencies:
2349 once: 1.4.0
2350 wrappy: 1.0.2
2351
2352 inherits@2.0.4: {}
2353
2354 ini@1.3.7: {}
2355
2356 ini@1.3.8: {}
2357
2358 is-absolute@1.0.0:
2359 dependencies:
2360 is-relative: 1.0.0
2361 is-windows: 1.0.2
2362
2363 is-arrayish@0.2.1: {}
2364
2365 is-binary-path@2.1.0:
2366 dependencies:
2367 binary-extensions: 2.3.0
2368
2369 is-buffer@1.1.6: {}
2370
2371 is-ci@2.0.0:
2372 dependencies:
2373 ci-info: 2.0.0
2374
2375 is-extglob@2.1.1: {}
2376
2377 is-fullwidth-code-point@3.0.0: {}
2378
2379 is-glob@3.1.0:
2380 dependencies:
2381 is-extglob: 2.1.1
2382
2383 is-glob@4.0.3:
2384 dependencies:
2385 is-extglob: 2.1.1
2386
2387 is-installed-globally@0.3.2:
2388 dependencies:
2389 global-dirs: 2.1.0
2390 is-path-inside: 3.0.3
2391
2392 is-negated-glob@1.0.0: {}
2393
2394 is-npm@4.0.0: {}
2395
2396 is-number@7.0.0: {}
2397
2398 is-obj@2.0.0: {}
2399
2400 is-path-inside@3.0.3: {}
2401
2402 is-plain-obj@2.1.0: {}
2403
2404 is-plain-object@5.0.0: {}
2405
2406 is-relative@1.0.0:
2407 dependencies:
2408 is-unc-path: 1.0.0
2409
2410 is-typedarray@1.0.0: {}
2411
2412 is-unc-path@1.0.0:
2413 dependencies:
2414 unc-path-regex: 0.1.2
2415
2416 is-unicode-supported@0.1.0: {}
2417
2418 is-utf8@0.2.1: {}
2419
2420 is-valid-glob@1.0.0: {}
2421
2422 is-windows@1.0.2: {}
2423
2424 is-yarn-global@0.3.0: {}
2425
2426 isarray@0.0.1: {}
2427
2428 isarray@1.0.0: {}
2429
2430 isexe@2.0.0: {}
2431
2432 jest-diff@29.7.0:
2433 dependencies:
2434 chalk: 4.1.2
2435 diff-sequences: 29.6.3
2436 jest-get-type: 29.6.3
2437 pretty-format: 29.7.0
2438
2439 jest-get-type@29.6.3: {}
2440
2441 js-tokens@4.0.0: {}
2442
2443 js-yaml@3.14.1:
2444 dependencies:
2445 argparse: 1.0.10
2446 esprima: 4.0.1
2447
2448 js-yaml@4.1.0:
2449 dependencies:
2450 argparse: 2.0.1
2451
2452 json-buffer@3.0.0: {}
2453
2454 json-buffer@3.0.1: {}
2455
2456 json-parse-even-better-errors@2.3.1: {}
2457
2458 json-schema-traverse@1.0.0: {}
2459
2460 json-stable-stringify-without-jsonify@1.0.1: {}
2461
2462 jsonfile@2.4.0:
2463 optionalDependencies:
2464 graceful-fs: 4.2.11
2465
2466 keyv@3.1.0:
2467 dependencies:
2468 json-buffer: 3.0.0
2469
2470 keyv@4.5.4:
2471 dependencies:
2472 json-buffer: 3.0.1
2473
2474 kind-of@6.0.3: {}
2475
2476 known-css-properties@0.34.0: {}
2477
2478 latest-version@5.1.0:
2479 dependencies:
2480 package-json: 6.5.0
2481
2482 lazystream@1.0.1:
2483 dependencies:
2484 readable-stream: 2.3.8
2485
2486 lead@1.0.0:
2487 dependencies:
2488 flush-write-stream: 1.1.1
2489
2490 lines-and-columns@1.2.4: {}
2491
2492 locate-path@6.0.0:
2493 dependencies:
2494 p-locate: 5.0.0
2495
2496 lodash._basebind@2.4.1:
2497 dependencies:
2498 lodash._basecreate: 2.4.1
2499 lodash._setbinddata: 2.4.1
2500 lodash._slice: 2.4.1
2501 lodash.isobject: 2.4.1
2502
2503 lodash._basecreate@2.4.1:
2504 dependencies:
2505 lodash._isnative: 2.4.1
2506 lodash.isobject: 2.4.1
2507 lodash.noop: 2.4.1
2508
2509 lodash._basecreatecallback@2.4.1:
2510 dependencies:
2511 lodash._setbinddata: 2.4.1
2512 lodash.bind: 2.4.1
2513 lodash.identity: 2.4.1
2514 lodash.support: 2.4.1
2515
2516 lodash._basecreatewrapper@2.4.1:
2517 dependencies:
2518 lodash._basecreate: 2.4.1
2519 lodash._setbinddata: 2.4.1
2520 lodash._slice: 2.4.1
2521 lodash.isobject: 2.4.1
2522
2523 lodash._createwrapper@2.4.1:
2524 dependencies:
2525 lodash._basebind: 2.4.1
2526 lodash._basecreatewrapper: 2.4.1
2527 lodash._slice: 2.4.1
2528 lodash.isfunction: 2.4.1
2529
2530 lodash._isnative@2.4.1: {}
2531
2532 lodash._objecttypes@2.4.1: {}
2533
2534 lodash._setbinddata@2.4.1:
2535 dependencies:
2536 lodash._isnative: 2.4.1
2537 lodash.noop: 2.4.1
2538
2539 lodash._shimkeys@2.4.1:
2540 dependencies:
2541 lodash._objecttypes: 2.4.1
2542
2543 lodash._slice@2.4.1: {}
2544
2545 lodash.assign@2.4.1:
2546 dependencies:
2547 lodash._basecreatecallback: 2.4.1
2548 lodash._objecttypes: 2.4.1
2549 lodash.keys: 2.4.1
2550
2551 lodash.bind@2.4.1:
2552 dependencies:
2553 lodash._createwrapper: 2.4.1
2554 lodash._slice: 2.4.1
2555
2556 lodash.difference@4.5.0: {}
2557
2558 lodash.identity@2.4.1: {}
2559
2560 lodash.isfunction@2.4.1: {}
2561
2562 lodash.isobject@2.4.1:
2563 dependencies:
2564 lodash._objecttypes: 2.4.1
2565
2566 lodash.keys@2.4.1:
2567 dependencies:
2568 lodash._isnative: 2.4.1
2569 lodash._shimkeys: 2.4.1
2570 lodash.isobject: 2.4.1
2571
2572 lodash.noop@2.4.1: {}
2573
2574 lodash.support@2.4.1:
2575 dependencies:
2576 lodash._isnative: 2.4.1
2577
2578 lodash.truncate@4.4.2: {}
2579
2580 lodash.uniq@4.5.0: {}
2581
2582 lodash@4.17.21: {}
2583
2584 log-symbols@4.1.0:
2585 dependencies:
2586 chalk: 4.1.2
2587 is-unicode-supported: 0.1.0
2588
2589 lower-case@1.1.4: {}
2590
2591 lowercase-keys@1.0.1: {}
2592
2593 lowercase-keys@2.0.0: {}
2594
2595 make-dir@3.1.0:
2596 dependencies:
2597 semver: 6.3.1
2598
2599 marked@0.6.3: {}
2600
2601 mathml-tag-names@2.1.3: {}
2602
2603 mdn-data@2.0.30: {}
2604
2605 memoize-decorator@1.0.2: {}
2606
2607 meow@13.2.0: {}
2608
2609 merge2@1.4.1: {}
2610
2611 micromatch@4.0.8:
2612 dependencies:
2613 braces: 3.0.3
2614 picomatch: 2.3.1
2615
2616 mimic-response@1.0.1: {}
2617
2618 min-indent@1.0.1: {}
2619
2620 minimatch@3.1.2:
2621 dependencies:
2622 brace-expansion: 1.1.11
2623
2624 minimatch@5.1.6:
2625 dependencies:
2626 brace-expansion: 2.0.1
2627
2628 minimist@1.2.8: {}
2629
2630 mkdirp@1.0.4: {}
2631
2632 mocha@10.7.3:
2633 dependencies:
2634 ansi-colors: 4.1.3
2635 browser-stdout: 1.3.1
2636 chokidar: 3.6.0
2637 debug: 4.3.7(supports-color@8.1.1)
2638 diff: 5.2.0
2639 escape-string-regexp: 4.0.0
2640 find-up: 5.0.0
2641 glob: 8.1.0
2642 he: 1.2.0
2643 js-yaml: 4.1.0
2644 log-symbols: 4.1.0
2645 minimatch: 5.1.6
2646 ms: 2.1.3
2647 serialize-javascript: 6.0.2
2648 strip-json-comments: 3.1.1
2649 supports-color: 8.1.1
2650 workerpool: 6.5.1
2651 yargs: 16.2.0
2652 yargs-parser: 20.2.9
2653 yargs-unparser: 2.0.0
2654
2655 ms@2.1.3: {}
2656
2657 multipipe@1.0.2:
2658 dependencies:
2659 duplexer2: 0.1.4
2660 object-assign: 4.1.1
2661
2662 nanoid@3.3.7: {}
2663
2664 no-case@2.3.2:
2665 dependencies:
2666 lower-case: 1.1.4
2667
2668 nodemon@3.1.7:
2669 dependencies:
2670 chokidar: 3.6.0
2671 debug: 4.3.7(supports-color@5.5.0)
2672 ignore-by-default: 1.0.1
2673 minimatch: 3.1.2
2674 pstree.remy: 1.1.8
2675 semver: 7.6.3
2676 simple-update-notifier: 2.0.0
2677 supports-color: 5.5.0
2678 touch: 3.1.1
2679 undefsafe: 2.0.5
2680
2681 normalize-path@2.1.1:
2682 dependencies:
2683 remove-trailing-separator: 1.1.0
2684
2685 normalize-path@3.0.0: {}
2686
2687 normalize-url@4.5.1: {}
2688
2689 now-and-later@2.0.1:
2690 dependencies:
2691 once: 1.4.0
2692
2693 number-is-nan@1.0.1: {}
2694
2695 nunjucks@3.2.4(chokidar@3.6.0):
2696 dependencies:
2697 a-sync-waterfall: 1.0.1
2698 asap: 2.0.6
2699 commander: 5.1.0
2700 optionalDependencies:
2701 chokidar: 3.6.0
2702
2703 object-assign@3.0.0: {}
2704
2705 object-assign@4.1.1: {}
2706
2707 object-keys@1.1.1: {}
2708
2709 object.assign@4.1.5:
2710 dependencies:
2711 call-bind: 1.0.7
2712 define-properties: 1.2.1
2713 has-symbols: 1.0.3
2714 object-keys: 1.1.1
2715
2716 once@1.4.0:
2717 dependencies:
2718 wrappy: 1.0.2
2719
2720 ordered-read-streams@1.0.1:
2721 dependencies:
2722 readable-stream: 2.3.8
2723
2724 p-cancelable@1.1.0: {}
2725
2726 p-limit@3.1.0:
2727 dependencies:
2728 yocto-queue: 0.1.0
2729
2730 p-locate@5.0.0:
2731 dependencies:
2732 p-limit: 3.1.0
2733
2734 package-json@6.5.0:
2735 dependencies:
2736 got: 9.6.0
2737 registry-auth-token: 4.2.2
2738 registry-url: 5.1.0
2739 semver: 6.3.1
2740
2741 param-case@2.1.1:
2742 dependencies:
2743 no-case: 2.3.2
2744
2745 parent-module@1.0.1:
2746 dependencies:
2747 callsites: 3.1.0
2748
2749 parse-json@5.2.0:
2750 dependencies:
2751 '@babel/code-frame': 7.25.7
2752 error-ex: 1.3.2
2753 json-parse-even-better-errors: 2.3.1
2754 lines-and-columns: 1.2.4
2755
2756 path-dirname@1.0.2: {}
2757
2758 path-exists@4.0.0: {}
2759
2760 path-is-absolute@1.0.1: {}
2761
2762 path-type@4.0.0: {}
2763
2764 picocolors@1.1.0: {}
2765
2766 picomatch@2.3.1: {}
2767
2768 postcss-media-query-parser@0.2.3: {}
2769
2770 postcss-resolve-nested-selector@0.1.6: {}
2771
2772 postcss-safe-parser@7.0.1(postcss@8.4.47):
2773 dependencies:
2774 postcss: 8.4.47
2775
2776 postcss-scss@4.0.9(postcss@8.4.47):
2777 dependencies:
2778 postcss: 8.4.47
2779
2780 postcss-selector-parser@6.1.2:
2781 dependencies:
2782 cssesc: 3.0.0
2783 util-deprecate: 1.0.2
2784
2785 postcss-value-parser@4.2.0: {}
2786
2787 postcss@8.4.47:
2788 dependencies:
2789 nanoid: 3.3.7
2790 picocolors: 1.1.0
2791 source-map-js: 1.2.1
2792
2793 prepend-http@2.0.0: {}
2794
2795 pretty-format@29.7.0:
2796 dependencies:
2797 '@jest/schemas': 29.6.3
2798 ansi-styles: 5.2.0
2799 react-is: 18.3.1
2800
2801 process-nextick-args@2.0.1: {}
2802
2803 pstree.remy@1.1.8: {}
2804
2805 pump@2.0.1:
2806 dependencies:
2807 end-of-stream: 1.4.4
2808 once: 1.4.0
2809
2810 pump@3.0.0:
2811 dependencies:
2812 end-of-stream: 1.4.4
2813 once: 1.4.0
2814
2815 pumpify@1.5.1:
2816 dependencies:
2817 duplexify: 3.7.1
2818 inherits: 2.0.4
2819 pump: 2.0.1
2820
2821 pupa@2.1.1:
2822 dependencies:
2823 escape-goat: 2.1.1
2824
2825 q@1.5.1: {}
2826
2827 queue-microtask@1.2.3: {}
2828
2829 randombytes@2.1.0:
2830 dependencies:
2831 safe-buffer: 5.2.1
2832
2833 rc@1.2.8:
2834 dependencies:
2835 deep-extend: 0.6.0
2836 ini: 1.3.8
2837 minimist: 1.2.8
2838 strip-json-comments: 2.0.1
2839
2840 react-is@18.3.1: {}
2841
2842 readable-stream@1.1.14:
2843 dependencies:
2844 core-util-is: 1.0.3
2845 inherits: 2.0.4
2846 isarray: 0.0.1
2847 string_decoder: 0.10.31
2848
2849 readable-stream@2.3.8:
2850 dependencies:
2851 core-util-is: 1.0.3
2852 inherits: 2.0.4
2853 isarray: 1.0.0
2854 process-nextick-args: 2.0.1
2855 safe-buffer: 5.1.2
2856 string_decoder: 1.1.1
2857 util-deprecate: 1.0.2
2858
2859 readable-stream@3.6.2:
2860 dependencies:
2861 inherits: 2.0.4
2862 string_decoder: 1.3.0
2863 util-deprecate: 1.0.2
2864
2865 readdirp@3.6.0:
2866 dependencies:
2867 picomatch: 2.3.1
2868
2869 readdirp@4.0.2: {}
2870
2871 regenerator-runtime@0.11.1: {}
2872
2873 registry-auth-token@4.2.2:
2874 dependencies:
2875 rc: 1.2.8
2876
2877 registry-url@5.1.0:
2878 dependencies:
2879 rc: 1.2.8
2880
2881 relateurl@0.2.7: {}
2882
2883 remove-bom-buffer@3.0.0:
2884 dependencies:
2885 is-buffer: 1.1.6
2886 is-utf8: 0.2.1
2887
2888 remove-bom-stream@1.2.0:
2889 dependencies:
2890 remove-bom-buffer: 3.0.0
2891 safe-buffer: 5.2.1
2892 through2: 2.0.5
2893
2894 remove-trailing-separator@1.1.0: {}
2895
2896 replace-ext@0.0.1: {}
2897
2898 replace-ext@1.0.1: {}
2899
2900 require-directory@2.1.1: {}
2901
2902 require-from-string@2.0.2: {}
2903
2904 resolve-from@4.0.0: {}
2905
2906 resolve-from@5.0.0: {}
2907
2908 resolve-options@1.1.0:
2909 dependencies:
2910 value-or-function: 3.0.0
2911
2912 responselike@1.0.2:
2913 dependencies:
2914 lowercase-keys: 1.0.1
2915
2916 reusify@1.0.4: {}
2917
2918 rimraf@2.7.1:
2919 dependencies:
2920 glob: 7.2.3
2921
2922 rimraf@3.0.2:
2923 dependencies:
2924 glob: 7.2.3
2925
2926 run-parallel@1.2.0:
2927 dependencies:
2928 queue-microtask: 1.2.3
2929
2930 safe-buffer@5.1.2: {}
2931
2932 safe-buffer@5.2.1: {}
2933
2934 safe-wipe@0.2.5:
2935 dependencies:
2936 extend: 3.0.2
2937 q: 1.5.1
2938 rimraf: 2.7.1
2939
2940 sass-convert@0.5.2:
2941 dependencies:
2942 concat-stream: 1.6.2
2943 dargs: 4.1.0
2944 ends-with: 0.2.0
2945 es6-denodeify: 0.1.5
2946 es6-promise: 3.3.1
2947 memoize-decorator: 1.0.2
2948 object-assign: 3.0.0
2949 semver: 5.7.2
2950 semver-regex: 1.0.0
2951 through2: 2.0.5
2952 which: 1.3.1
2953
2954 sass-true@8.1.0(sass@1.79.4):
2955 dependencies:
2956 '@adobe/css-tools': 4.4.0
2957 jest-diff: 29.7.0
2958 lodash: 4.17.21
2959 optionalDependencies:
2960 sass: 1.79.4
2961
2962 sass@1.79.4:
2963 dependencies:
2964 chokidar: 4.0.1
2965 immutable: 4.3.7
2966 source-map-js: 1.2.1
2967
2968 sassdoc-extras@2.5.1:
2969 dependencies:
2970 marked: 0.6.3
2971
2972 sassdoc-theme-default@2.8.6(chokidar@3.6.0):
2973 dependencies:
2974 babel-runtime: 6.26.0
2975 chroma-js: 1.4.1
2976 es6-denodeify: 0.1.5
2977 es6-promise: 4.2.8
2978 extend: 3.0.2
2979 fs-extra: 2.1.2
2980 html-minifier: 3.5.21
2981 nunjucks: 3.2.4(chokidar@3.6.0)
2982 sassdoc-extras: 2.5.1
2983 transitivePeerDependencies:
2984 - chokidar
2985
2986 sassdoc@2.7.4(chokidar@3.6.0):
2987 dependencies:
2988 ansi-styles: 4.3.0
2989 babel-runtime: 6.26.0
2990 chalk: 2.4.2
2991 concat-stream: 2.0.0
2992 docopt: 0.6.2
2993 glob: 7.2.3
2994 glob2base: 0.0.12
2995 js-yaml: 3.14.1
2996 lodash.difference: 4.5.0
2997 lodash.uniq: 4.5.0
2998 minimatch: 3.1.2
2999 mkdirp: 1.0.4
3000 multipipe: 1.0.2
3001 rimraf: 3.0.2
3002 safe-wipe: 0.2.5
3003 sass-convert: 0.5.2
3004 sassdoc-theme-default: 2.8.6(chokidar@3.6.0)
3005 scss-comment-parser: 0.8.4
3006 strip-indent: 3.0.0
3007 through2: 1.1.1
3008 update-notifier: 4.1.3
3009 vinyl-fs: 3.0.3
3010 vinyl-source-stream: 1.1.2
3011 vinyl-string: 1.0.2
3012 transitivePeerDependencies:
3013 - chokidar
3014
3015 scss-comment-parser@0.8.4:
3016 dependencies:
3017 cdocparser: 0.13.0
3018
3019 semver-diff@3.1.1:
3020 dependencies:
3021 semver: 6.3.1
3022
3023 semver-regex@1.0.0: {}
3024
3025 semver@5.7.2: {}
3026
3027 semver@6.3.1: {}
3028
3029 semver@7.6.3: {}
3030
3031 serialize-javascript@6.0.2:
3032 dependencies:
3033 randombytes: 2.1.0
3034
3035 set-function-length@1.2.2:
3036 dependencies:
3037 define-data-property: 1.1.4
3038 es-errors: 1.3.0
3039 function-bind: 1.1.2
3040 get-intrinsic: 1.2.4
3041 gopd: 1.0.1
3042 has-property-descriptors: 1.0.2
3043
3044 signal-exit@3.0.7: {}
3045
3046 signal-exit@4.1.0: {}
3047
3048 simple-update-notifier@2.0.0:
3049 dependencies:
3050 semver: 7.6.3
3051
3052 slash@3.0.0: {}
3053
3054 slice-ansi@4.0.0:
3055 dependencies:
3056 ansi-styles: 4.3.0
3057 astral-regex: 2.0.0
3058 is-fullwidth-code-point: 3.0.0
3059
3060 source-map-js@1.2.1: {}
3061
3062 source-map@0.6.1: {}
3063
3064 sprintf-js@1.0.3: {}
3065
3066 stream-shift@1.0.3: {}
3067
3068 string-width@4.2.3:
3069 dependencies:
3070 emoji-regex: 8.0.0
3071 is-fullwidth-code-point: 3.0.0
3072 strip-ansi: 6.0.1
3073
3074 string_decoder@0.10.31: {}
3075
3076 string_decoder@1.1.1:
3077 dependencies:
3078 safe-buffer: 5.1.2
3079
3080 string_decoder@1.3.0:
3081 dependencies:
3082 safe-buffer: 5.2.1
3083
3084 strip-ansi@6.0.1:
3085 dependencies:
3086 ansi-regex: 5.0.1
3087
3088 strip-ansi@7.1.0:
3089 dependencies:
3090 ansi-regex: 6.1.0
3091
3092 strip-indent@1.0.1:
3093 dependencies:
3094 get-stdin: 4.0.1
3095
3096 strip-indent@3.0.0:
3097 dependencies:
3098 min-indent: 1.0.1
3099
3100 strip-json-comments@2.0.1: {}
3101
3102 strip-json-comments@3.1.1: {}
3103
3104 style-search@0.1.0: {}
3105
3106 stylelint-config-sass-guidelines@12.1.0(postcss@8.4.47)(stylelint@16.9.0):
3107 dependencies:
3108 '@stylistic/stylelint-plugin': 3.1.1(stylelint@16.9.0)
3109 postcss: 8.4.47
3110 postcss-scss: 4.0.9(postcss@8.4.47)
3111 stylelint: 16.9.0
3112 stylelint-scss: 6.7.0(stylelint@16.9.0)
3113
3114 stylelint-scss@6.7.0(stylelint@16.9.0):
3115 dependencies:
3116 css-tree: 2.3.1
3117 is-plain-object: 5.0.0
3118 known-css-properties: 0.34.0
3119 postcss-media-query-parser: 0.2.3
3120 postcss-resolve-nested-selector: 0.1.6
3121 postcss-selector-parser: 6.1.2
3122 postcss-value-parser: 4.2.0
3123 stylelint: 16.9.0
3124
3125 stylelint@16.9.0:
3126 dependencies:
3127 '@csstools/css-parser-algorithms': 3.0.1(@csstools/css-tokenizer@3.0.1)
3128 '@csstools/css-tokenizer': 3.0.1
3129 '@csstools/media-query-list-parser': 3.0.1(@csstools/css-parser-algorithms@3.0.1(@csstools/css-tokenizer@3.0.1))(@csstools/css-tokenizer@3.0.1)
3130 '@csstools/selector-specificity': 4.0.0(postcss-selector-parser@6.1.2)
3131 '@dual-bundle/import-meta-resolve': 4.1.0
3132 balanced-match: 2.0.0
3133 colord: 2.9.3
3134 cosmiconfig: 9.0.0
3135 css-functions-list: 3.2.2
3136 css-tree: 2.3.1
3137 debug: 4.3.7
3138 fast-glob: 3.3.2
3139 fastest-levenshtein: 1.0.16
3140 file-entry-cache: 9.1.0
3141 global-modules: 2.0.0
3142 globby: 11.1.0
3143 globjoin: 0.1.4
3144 html-tags: 3.3.1
3145 ignore: 5.3.2
3146 imurmurhash: 0.1.4
3147 is-plain-object: 5.0.0
3148 known-css-properties: 0.34.0
3149 mathml-tag-names: 2.1.3
3150 meow: 13.2.0
3151 micromatch: 4.0.8
3152 normalize-path: 3.0.0
3153 picocolors: 1.1.0
3154 postcss: 8.4.47
3155 postcss-resolve-nested-selector: 0.1.6
3156 postcss-safe-parser: 7.0.1(postcss@8.4.47)
3157 postcss-selector-parser: 6.1.2
3158 postcss-value-parser: 4.2.0
3159 resolve-from: 5.0.0
3160 string-width: 4.2.3
3161 strip-ansi: 7.1.0
3162 supports-hyperlinks: 3.1.0
3163 svg-tags: 1.0.0
3164 table: 6.8.2
3165 write-file-atomic: 5.0.1
3166 transitivePeerDependencies:
3167 - supports-color
3168 - typescript
3169
3170 supports-color@5.5.0:
3171 dependencies:
3172 has-flag: 3.0.0
3173
3174 supports-color@7.2.0:
3175 dependencies:
3176 has-flag: 4.0.0
3177
3178 supports-color@8.1.1:
3179 dependencies:
3180 has-flag: 4.0.0
3181
3182 supports-hyperlinks@3.1.0:
3183 dependencies:
3184 has-flag: 4.0.0
3185 supports-color: 7.2.0
3186
3187 svg-tags@1.0.0: {}
3188
3189 table@6.8.2:
3190 dependencies:
3191 ajv: 8.17.1
3192 lodash.truncate: 4.4.2
3193 slice-ansi: 4.0.0
3194 string-width: 4.2.3
3195 strip-ansi: 6.0.1
3196
3197 term-size@2.2.1: {}
3198
3199 through2-filter@3.0.0:
3200 dependencies:
3201 through2: 2.0.5
3202 xtend: 4.0.2
3203
3204 through2@1.1.1:
3205 dependencies:
3206 readable-stream: 1.1.14
3207 xtend: 4.0.2
3208
3209 through2@2.0.5:
3210 dependencies:
3211 readable-stream: 2.3.8
3212 xtend: 4.0.2
3213
3214 to-absolute-glob@2.0.2:
3215 dependencies:
3216 is-absolute: 1.0.0
3217 is-negated-glob: 1.0.0
3218
3219 to-readable-stream@1.0.0: {}
3220
3221 to-regex-range@5.0.1:
3222 dependencies:
3223 is-number: 7.0.0
3224
3225 to-through@2.0.0:
3226 dependencies:
3227 through2: 2.0.5
3228
3229 touch@3.1.1: {}
3230
3231 type-fest@0.8.1: {}
3232
3233 typedarray-to-buffer@3.1.5:
3234 dependencies:
3235 is-typedarray: 1.0.0
3236
3237 typedarray@0.0.6: {}
3238
3239 uglify-js@3.4.10:
3240 dependencies:
3241 commander: 2.19.0
3242 source-map: 0.6.1
3243
3244 unc-path-regex@0.1.2: {}
3245
3246 undefsafe@2.0.5: {}
3247
3248 undici-types@5.26.5: {}
3249
3250 unique-stream@2.3.1:
3251 dependencies:
3252 json-stable-stringify-without-jsonify: 1.0.1
3253 through2-filter: 3.0.0
3254
3255 unique-string@2.0.0:
3256 dependencies:
3257 crypto-random-string: 2.0.0
3258
3259 update-notifier@4.1.3:
3260 dependencies:
3261 boxen: 4.2.0
3262 chalk: 3.0.0
3263 configstore: 5.0.1
3264 has-yarn: 2.1.0
3265 import-lazy: 2.1.0
3266 is-ci: 2.0.0
3267 is-installed-globally: 0.3.2
3268 is-npm: 4.0.0
3269 is-yarn-global: 0.3.0
3270 latest-version: 5.1.0
3271 pupa: 2.1.1
3272 semver-diff: 3.1.1
3273 xdg-basedir: 4.0.0
3274
3275 upper-case@1.1.3: {}
3276
3277 url-parse-lax@3.0.0:
3278 dependencies:
3279 prepend-http: 2.0.0
3280
3281 util-deprecate@1.0.2: {}
3282
3283 value-or-function@3.0.0: {}
3284
3285 vinyl-fs@3.0.3:
3286 dependencies:
3287 fs-mkdirp-stream: 1.0.0
3288 glob-stream: 6.1.0
3289 graceful-fs: 4.2.11
3290 is-valid-glob: 1.0.0
3291 lazystream: 1.0.1
3292 lead: 1.0.0
3293 object.assign: 4.1.5
3294 pumpify: 1.5.1
3295 readable-stream: 2.3.8
3296 remove-bom-buffer: 3.0.0
3297 remove-bom-stream: 1.2.0
3298 resolve-options: 1.1.0
3299 through2: 2.0.5
3300 to-through: 2.0.0
3301 value-or-function: 3.0.0
3302 vinyl: 2.2.1
3303 vinyl-sourcemap: 1.1.0
3304
3305 vinyl-source-stream@1.1.2:
3306 dependencies:
3307 through2: 2.0.5
3308 vinyl: 0.4.6
3309
3310 vinyl-sourcemap@1.1.0:
3311 dependencies:
3312 append-buffer: 1.0.2
3313 convert-source-map: 1.9.0
3314 graceful-fs: 4.2.11
3315 normalize-path: 2.1.1
3316 now-and-later: 2.0.1
3317 remove-bom-buffer: 3.0.0
3318 vinyl: 2.2.1
3319
3320 vinyl-string@1.0.2:
3321 dependencies:
3322 vinyl: 1.2.0
3323
3324 vinyl@0.4.6:
3325 dependencies:
3326 clone: 0.2.0
3327 clone-stats: 0.0.1
3328
3329 vinyl@1.2.0:
3330 dependencies:
3331 clone: 1.0.4
3332 clone-stats: 0.0.1
3333 replace-ext: 0.0.1
3334
3335 vinyl@2.2.1:
3336 dependencies:
3337 clone: 2.1.2
3338 clone-buffer: 1.0.0
3339 clone-stats: 1.0.0
3340 cloneable-readable: 1.1.3
3341 remove-trailing-separator: 1.1.0
3342 replace-ext: 1.0.1
3343
3344 which@1.3.1:
3345 dependencies:
3346 isexe: 2.0.0
3347
3348 widest-line@3.1.0:
3349 dependencies:
3350 string-width: 4.2.3
3351
3352 workerpool@6.5.1: {}
3353
3354 wrap-ansi@7.0.0:
3355 dependencies:
3356 ansi-styles: 4.3.0
3357 string-width: 4.2.3
3358 strip-ansi: 6.0.1
3359
3360 wrappy@1.0.2: {}
3361
3362 write-file-atomic@3.0.3:
3363 dependencies:
3364 imurmurhash: 0.1.4
3365 is-typedarray: 1.0.0
3366 signal-exit: 3.0.7
3367 typedarray-to-buffer: 3.1.5
3368
3369 write-file-atomic@5.0.1:
3370 dependencies:
3371 imurmurhash: 0.1.4
3372 signal-exit: 4.1.0
3373
3374 xdg-basedir@4.0.0: {}
3375
3376 xtend@4.0.2: {}
3377
3378 y18n@5.0.8: {}
3379
3380 yargs-parser@20.2.9: {}
3381
3382 yargs-unparser@2.0.0:
3383 dependencies:
3384 camelcase: 6.3.0
3385 decamelize: 4.0.0
3386 flat: 5.0.2
3387 is-plain-obj: 2.1.0
3388
3389 yargs@16.2.0:
3390 dependencies:
3391 cliui: 7.0.4
3392 escalade: 3.2.0
3393 get-caller-file: 2.0.5
3394 require-directory: 2.1.1
3395 string-width: 4.2.3
3396 y18n: 5.0.8
3397 yargs-parser: 20.2.9
3398
3399 yocto-queue@0.1.0: {}
diff --git a/src/_contexts.scss b/src/_contexts.scss
index 7ffbb4e..ed376a2 100644
--- a/src/_contexts.scss
+++ b/src/_contexts.scss
@@ -15,6 +15,9 @@
15/// @access public 15/// @access public
16//// 16////
17 17
18@use 'sass:list';
19@use 'sass:map';
20@use 'sass:meta';
18@use './functions'; 21@use './functions';
19 22
20/// 23///
@@ -34,7 +37,7 @@ $stacks: ();
34/// @throw If context stack already exists 37/// @throw If context stack already exists
35/// 38///
36@mixin create($stack-id) { 39@mixin create($stack-id) {
37 $noop: create($stack-id); 40 $noop: create($stack-id);
38} 41}
39 42
40/// 43///
@@ -43,13 +46,13 @@ $stacks: ();
43/// @param {string} $stack-id - ID of context stack 46/// @param {string} $stack-id - ID of context stack
44/// 47///
45@function create($stack-id) { 48@function create($stack-id) {
46 @if map-has-key($stacks, $stack-id) { 49 @if map.has-key($stacks, $stack-id) {
47 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 50 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
48 } 51 }
49 52
50 $stacks: map-merge($stacks, ($stack-id: ())) !global; 53 $stacks: map.merge($stacks, ($stack-id: ())) !global;
51 54
52 @return null; 55 @return null;
53} 56}
54 57
55/// 58///
@@ -58,7 +61,7 @@ $stacks: ();
58/// @param {string} $stack-id - ID of context stack 61/// @param {string} $stack-id - ID of context stack
59/// 62///
60@mixin clear($stack-id) { 63@mixin clear($stack-id) {
61 $noop: clear($stack-id); 64 $noop: clear($stack-id);
62} 65}
63 66
64/// 67///
@@ -67,14 +70,14 @@ $stacks: ();
67/// @param {string} $stack-id - ID of context stack 70/// @param {string} $stack-id - ID of context stack
68/// 71///
69@function clear($stack-id) { 72@function clear($stack-id) {
70 @if not map-has-key($stacks, $stack-id) { 73 @if not map.has-key($stacks, $stack-id) {
71 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 74 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
72 } 75 }
73 76
74 $context-stack: (); 77 $context-stack: ();
75 $stacks: map-merge($stacks, ($stack-id: $context-stack)) !global; 78 $stacks: map.merge($stacks, ($stack-id: $context-stack)) !global;
76 79
77 @return null; 80 @return null;
78} 81}
79 82
80/// 83///
@@ -83,7 +86,7 @@ $stacks: ();
83/// @param {string} $stack-id - ID of context stack 86/// @param {string} $stack-id - ID of context stack
84/// 87///
85@mixin delete($stack-id) { 88@mixin delete($stack-id) {
86 $noop: delete($stack-id); 89 $noop: delete($stack-id);
87} 90}
88 91
89/// 92///
@@ -92,13 +95,13 @@ $stacks: ();
92/// @param {string} $stack-id - ID of context stack 95/// @param {string} $stack-id - ID of context stack
93/// 96///
94@function delete($stack-id) { 97@function delete($stack-id) {
95 @if not map-has-key($stacks, $stack-id) { 98 @if not map.has-key($stacks, $stack-id) {
96 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 99 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
97 } 100 }
98 101
99 $stacks: map-remove($stacks, $stack-id) !global; 102 $stacks: map.remove($stacks, $stack-id) !global;
100 103
101 @return null; 104 @return null;
102} 105}
103 106
104/// 107///
@@ -109,7 +112,7 @@ $stacks: ();
109/// @param {any} $data [()] - Data that belongs to the context 112/// @param {any} $data [()] - Data that belongs to the context
110/// 113///
111@mixin push($stack-id, $id, $data: ()) { 114@mixin push($stack-id, $id, $data: ()) {
112 $noop: push($stack-id, $id, $data); 115 $noop: push($stack-id, $id, $data);
113} 116}
114 117
115/// 118///
@@ -122,16 +125,16 @@ $stacks: ();
122/// @return {list} A list with two items: 1 = context id, 2 = context data 125/// @return {list} A list with two items: 1 = context id, 2 = context data
123/// 126///
124@function push($stack-id, $id, $data: ()) { 127@function push($stack-id, $id, $data: ()) {
125 @if not map-has-key($stacks, $stack-id) { 128 @if not map.has-key($stacks, $stack-id) {
126 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 129 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
127 } 130 }
128 131
129 $context: $id $data; 132 $context: $id $data;
130 $context-stack: map-get($stacks, $stack-id); 133 $context-stack: map.get($stacks, $stack-id);
131 $context-stack: append($context-stack, $context); 134 $context-stack: list.append($context-stack, $context);
132 $stacks: map-merge($stacks, ($stack-id: $context-stack)) !global; 135 $stacks: map.merge($stacks, ($stack-id: $context-stack)) !global;
133 136
134 @return $context; 137 @return $context;
135} 138}
136 139
137/// 140///
@@ -142,7 +145,7 @@ $stacks: ();
142/// @throw If context stack doesn't exist 145/// @throw If context stack doesn't exist
143/// 146///
144@mixin pop($stack-id) { 147@mixin pop($stack-id) {
145 $noop: pop($stack-id); 148 $noop: pop($stack-id);
146} 149}
147 150
148/// 151///
@@ -153,27 +156,27 @@ $stacks: ();
153/// @return {list} A list with two items: 1 = context id, 2 = context data 156/// @return {list} A list with two items: 1 = context id, 2 = context data
154/// 157///
155@function pop($stack-id) { 158@function pop($stack-id) {
156 @if not map-has-key($stacks, $stack-id) { 159 @if not map.has-key($stacks, $stack-id) {
157 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 160 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
158 } 161 }
159 162
160 $context-stack: map-get($stacks, $stack-id); 163 $context-stack: map.get($stacks, $stack-id);
161 164
162 @if length($context-stack) == 0 { 165 @if list.length($context-stack) == 0 {
163 @error 'Context stack "#{inspect($stack-id)}" is already empty.'; 166 @error 'Context stack "#{inspect($stack-id)}" is already empty.';
164 } 167 }
165 168
166 $popped-context: nth($context-stack, -1); 169 $popped-context: list.nth($context-stack, -1);
167 170
168 @if length($context-stack) == 1 { 171 @if list.length($context-stack) == 1 {
169 $context-stack: (); 172 $context-stack: ();
170 } @else { 173 } @else {
171 $context-stack: functions.list-slice($context-stack, 1, length($context-stack) - 1); 174 $context-stack: functions.list-slice($context-stack, 1, list.length($context-stack) - 1);
172 } 175 }
173 176
174 $stacks: map-merge($stacks, ($stack-id: $context-stack)) !global; 177 $stacks: map.merge($stacks, ($stack-id: $context-stack)) !global;
175 178
176 @return $popped-context; 179 @return $popped-context;
177} 180}
178 181
179/// 182///
@@ -186,15 +189,15 @@ $stacks: ();
186/// @throw If assertion fails 189/// @throw If assertion fails
187/// 190///
188@function assert-stack-must-contain($stack-id, $context-ids, $check-head-only: false) { 191@function assert-stack-must-contain($stack-id, $context-ids, $check-head-only: false) {
189 @if not contains($stack-id, $context-ids, $check-head-only) { 192 @if not contains($stack-id, $context-ids, $check-head-only) {
190 @error 'Must be called inside of contexts "#{inspect($context-ids)}".'; 193 @error 'Must be called inside of contexts "#{inspect($context-ids)}".';
191 } 194 }
192 195
193 @return null; 196 @return null;
194} 197}
195 198
196@mixin assert-stack-must-contain($stack-id, $context-ids, $check-head-only: false) { 199@mixin assert-stack-must-contain($stack-id, $context-ids, $check-head-only: false) {
197 $noop: assert-stack-must-contain($stack-id, $context-ids, $check-head-only); 200 $noop: assert-stack-must-contain($stack-id, $context-ids, $check-head-only);
198} 201}
199 202
200/// 203///
@@ -207,15 +210,15 @@ $stacks: ();
207/// @throw If assertion fails 210/// @throw If assertion fails
208/// 211///
209@function assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only: false) { 212@function assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only: false) {
210 @if contains($stack-id, $context-ids, $check-head-only) { 213 @if contains($stack-id, $context-ids, $check-head-only) {
211 @error 'Must not be called inside of contexts "#{inspect($context-ids)}".'; 214 @error 'Must not be called inside of contexts "#{inspect($context-ids)}".';
212 } 215 }
213 216
214 @return null; 217 @return null;
215} 218}
216 219
217@mixin assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only: false) { 220@mixin assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only: false) {
218 $noop: assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only); 221 $noop: assert-stack-must-not-contain($stack-id, $context-ids, $check-head-only);
219} 222}
220 223
221/// 224///
@@ -228,29 +231,29 @@ $stacks: ();
228/// @return {bool} `true` if the context stack contains one of the context IDs, otherwise `false` 231/// @return {bool} `true` if the context stack contains one of the context IDs, otherwise `false`
229/// 232///
230@function contains($stack-id, $context-ids, $check-head-only: false) { 233@function contains($stack-id, $context-ids, $check-head-only: false) {
231 @if not map-has-key($stacks, $stack-id) { 234 @if not map.has-key($stacks, $stack-id) {
232 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 235 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
233 } 236 }
234 237
235 $context-stack: map-get($stacks, $stack-id); 238 $context-stack: map.get($stacks, $stack-id);
236 239
237 @if length($context-stack) == 0 { 240 @if list.length($context-stack) == 0 {
238 @return false; 241 @return false;
239 } 242 }
240 243
241 $end-idx: if($check-head-only, length($context-stack), 1); 244 $end-idx: if($check-head-only, list.length($context-stack), 1);
242 245
243 @for $i from length($context-stack) through $end-idx { 246 @for $i from list.length($context-stack) through $end-idx {
244 $context: nth($context-stack, $i); 247 $context: list.nth($context-stack, $i);
245 248
246 @each $chk-context in $context-ids { 249 @each $chk-context in $context-ids {
247 @if nth($context, 1) == $chk-context { 250 @if list.nth($context, 1) == $chk-context {
248 @return true; 251 @return true;
249 } 252 }
250 } 253 }
251 } 254 }
252 255
253 @return false; 256 @return false;
254} 257}
255 258
256/// 259///
@@ -262,15 +265,15 @@ $stacks: ();
262/// @throw If assertion fails 265/// @throw If assertion fails
263/// 266///
264@function assert-stack-count($stack-id, $max-count) { 267@function assert-stack-count($stack-id, $max-count) {
265 @if count($stack-id) > $max-count { 268 @if count($stack-id) > $max-count {
266 @error 'Maximum context count "#{inspect($max-count)}" exceeded.'; 269 @error 'Maximum context count "#{inspect($max-count)}" exceeded.';
267 } 270 }
268 271
269 @return null; 272 @return null;
270} 273}
271 274
272@mixin assert-stack-count($stack-id, $max-count) { 275@mixin assert-stack-count($stack-id, $max-count) {
273 $noop: assert-stack-count($stack-id, $max-count); 276 $noop: assert-stack-count($stack-id, $max-count);
274} 277}
275 278
276/// 279///
@@ -281,13 +284,13 @@ $stacks: ();
281/// @return {number} The number of contexts 284/// @return {number} The number of contexts
282/// 285///
283@function count($stack-id) { 286@function count($stack-id) {
284 @if not map-has-key($stacks, $stack-id) { 287 @if not map.has-key($stacks, $stack-id) {
285 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 288 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
286 } 289 }
287 290
288 $context-stack: map-get($stacks, $stack-id); 291 $context-stack: map.get($stacks, $stack-id);
289 292
290 @return length($context-stack); 293 @return list.length($context-stack);
291} 294}
292 295
293/// 296///
@@ -299,37 +302,37 @@ $stacks: ();
299/// @return {list} Null if no match was found, otherwise a list with two items: 1. context ID, 2. context data. 302/// @return {list} Null if no match was found, otherwise a list with two items: 1. context ID, 2. context data.
300/// 303///
301@function get($stack-id, $type-or-level: null) { 304@function get($stack-id, $type-or-level: null) {
302 @if not map-has-key($stacks, $stack-id) { 305 @if not map.has-key($stacks, $stack-id) {
303 @error 'Context stack "#{inspect($stack-id)}" does not exist.'; 306 @error 'Context stack "#{inspect($stack-id)}" does not exist.';
304 } 307 }
305 308
306 $context-stack: map-get($stacks, $stack-id); 309 $context-stack: map.get($stacks, $stack-id);
307 310
308 @if length($context-stack) == 0 { 311 @if list.length($context-stack) == 0 {
309 @return null; 312 @return null;
310 } 313 }
311 314
312 @if type-of($type-or-level) == number { 315 @if meta.type-of($type-or-level) == number {
313 $context: nth($context-stack, -$type-or-level); 316 $context: list.nth($context-stack, -$type-or-level);
314 317
315 @return $context; 318 @return $context;
316 } @else { 319 } @else {
317 @for $i from -1 through -(length($context-stack)) { 320 @for $i from -1 through -(list.length($context-stack)) {
318 $context: nth($context-stack, $i); 321 $context: list.nth($context-stack, $i);
319 322
320 @if type-of($type-or-level) == list { 323 @if meta.type-of($type-or-level) == list {
321 @for $j from 1 through length($type-or-level) { 324 @for $j from 1 through list.length($type-or-level) {
322 $ctx: nth($type-or-level, $j); 325 $ctx: list.nth($type-or-level, $j);
323 326
324 @if nth($context, 1) == $ctx { 327 @if list.nth($context, 1) == $ctx {
325 @return $context; 328 @return $context;
326 } 329 }
327 } 330 }
328 } @else if nth($context, 1) == $type-or-level { 331 } @else if list.nth($context, 1) == $type-or-level {
329 @return $context; 332 @return $context;
330 } 333 }
331 } 334 }
332 } 335 }
333 336
334 @return null; 337 @return null;
335} 338}
diff --git a/src/_easing.scss b/src/_easing.scss
index 8bcfd39..939eda2 100644
--- a/src/_easing.scss
+++ b/src/_easing.scss
@@ -10,6 +10,8 @@
10//// 10////
11 11
12@use 'sass:math'; 12@use 'sass:math';
13@use 'sass:map';
14@use 'sass:list';
13 15
14/// 16///
15/// @access private 17/// @access private
@@ -53,62 +55,62 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
53/// @return {number} 55/// @return {number}
54/// 56///
55@function cubic-bezier($x1, $y1, $x2, $y2, $x) { 57@function cubic-bezier($x1, $y1, $x2, $y2, $x) {
56 // 58 //
57 // Cover simple cases 59 // Cover simple cases
58 // 60 //
59 61
60 @if ($x1 == $y1) and ($x2 == $y2) { 62 @if ($x1 == $y1) and ($x2 == $y2) {
61 @return $x; 63 @return $x;
62 } 64 }
63 @if $x == 0 { 65 @if $x == 0 {
64 @return 0; 66 @return 0;
65 } 67 }
66 @if $x == 1 { 68 @if $x == 1 {
67 @return 1; 69 @return 1;
68 } 70 }
69 71
70 // 72 //
71 // Generate samples 73 // Generate samples
72 // 74 //
73 75
74 $sample-pool-key: $x1 + '_' + $x2; 76 $sample-pool-key: $x1 + '_' + $x2;
75 77
76 @if not map-has-key($cubic-bezier-sample-pool, $sample-pool-key) { 78 @if not map.has-key($cubic-bezier-sample-pool, $sample-pool-key) {
77 $samples: (); 79 $samples: ();
78 80
79 @for $i from 0 through $cubic-bezier-sample-pool-size { 81 @for $i from 0 through $cubic-bezier-sample-pool-size {
80 $samples: append($samples, cubic-bezier-func($x1, $x2, math.div($i, $cubic-bezier-sample-pool-size))); 82 $samples: list.append($samples, cubic-bezier-func($x1, $x2, math.div($i, $cubic-bezier-sample-pool-size)));
81 } 83 }
82 84
83 $cubic-bezier-sample-pool: map-merge($cubic-bezier-sample-pool, ($sample-pool-key: $samples)) !global; 85 $cubic-bezier-sample-pool: map.merge($cubic-bezier-sample-pool, ($sample-pool-key: $samples)) !global;
84 } 86 }
85 87
86 // 88 //
87 // Calculate cubic bezier 89 // Calculate cubic bezier
88 // 90 //
89 91
90 @return cubic-bezier-func($y1, $y2, cubic-bezier-t-for-x($x1, $x2, $x)); 92 @return cubic-bezier-func($y1, $y2, cubic-bezier-t-for-x($x1, $x2, $x));
91} 93}
92 94
93/// 95///
94/// @access private 96/// @access private
95/// 97///
96@function cubic-bezier-func-a($p1, $p2) { 98@function cubic-bezier-func-a($p1, $p2) {
97 @return 1 - 3 * $p2 + 3 * $p1; 99 @return 1 - 3 * $p2 + 3 * $p1;
98} 100}
99 101
100/// 102///
101/// @access private 103/// @access private
102/// 104///
103@function cubic-bezier-func-b($p1, $p2) { 105@function cubic-bezier-func-b($p1, $p2) {
104 @return 3 * $p2 - 6 * $p1; 106 @return 3 * $p2 - 6 * $p1;
105} 107}
106 108
107/// 109///
108/// @access private 110/// @access private
109/// 111///
110@function cubic-bezier-func-c($p1) { 112@function cubic-bezier-func-c($p1) {
111 @return 3 * $p1; 113 @return 3 * $p1;
112} 114}
113 115
114/// 116///
@@ -117,7 +119,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
117/// @access private 119/// @access private
118/// 120///
119@function cubic-bezier-func($p1, $p2, $t) { 121@function cubic-bezier-func($p1, $p2, $t) {
120 @return ((cubic-bezier-func-a($p1, $p2) * $t + cubic-bezier-func-b($p1, $p2)) * $t + cubic-bezier-func-c($p1)) * $t; 122 @return ((cubic-bezier-func-a($p1, $p2) * $t + cubic-bezier-func-b($p1, $p2)) * $t + cubic-bezier-func-c($p1)) * $t;
121} 123}
122 124
123/// 125///
@@ -126,7 +128,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
126/// @access private 128/// @access private
127/// 129///
128@function cubic-bezier-func-slope($p1, $p2, $t) { 130@function cubic-bezier-func-slope($p1, $p2, $t) {
129 @return 3 * cubic-bezier-func-a($p1, $p2) * $t * $t + 2 * cubic-bezier-func-b($p1, $p2) * $t + cubic-bezier-func-c($p1); 131 @return 3 * cubic-bezier-func-a($p1, $p2) * $t * $t + 2 * cubic-bezier-func-b($p1, $p2) * $t + cubic-bezier-func-c($p1);
130} 132}
131 133
132/// 134///
@@ -135,18 +137,18 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
135/// @access private 137/// @access private
136/// 138///
137@function cubic-bezier-newton-raphson($x1, $x2, $x, $t) { 139@function cubic-bezier-newton-raphson($x1, $x2, $x, $t) {
138 @for $i from 1 through $cubic-bezier-newton-iters { 140 @for $i from 1 through $cubic-bezier-newton-iters {
139 $cur-slope: cubic-bezier-func-slope($x1, $x2, $t); 141 $cur-slope: cubic-bezier-func-slope($x1, $x2, $t);
140 142
141 @if $cur-slope == 0 { 143 @if $cur-slope == 0 {
142 @return $t; 144 @return $t;
143 } 145 }
144 146
145 $cur-x: cubic-bezier-func($x1, $x2, $t) - $x; 147 $cur-x: cubic-bezier-func($x1, $x2, $t) - $x;
146 $t: $t - math.div($cur-x, $cur-slope); 148 $t: $t - math.div($cur-x, $cur-slope);
147 } 149 }
148 150
149 @return $t; 151 @return $t;
150} 152}
151 153
152/// 154///
@@ -155,26 +157,26 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
155/// @access private 157/// @access private
156/// 158///
157@function cubic-bezier-binary-subdivide($x1, $x2, $x, $a, $b) { 159@function cubic-bezier-binary-subdivide($x1, $x2, $x, $a, $b) {
158 $cur-x: 0; 160 $cur-x: 0;
159 $cur-t: 0; 161 $cur-t: 0;
160 $i: 0; 162 $i: 0;
161 163
162 @while $i < $cubic-bezier-subdiv-max-iters { 164 @while $i < $cubic-bezier-subdiv-max-iters {
163 $cur-t: $a + ($b - $a) / 2; 165 $cur-t: $a + ($b - $a) / 2;
164 $cur-x: cubic-bezier-func($x1, $x2, $cur-t) - $x; 166 $cur-x: cubic-bezier-func($x1, $x2, $cur-t) - $x;
165 167
166 @if $cur-x > 0 { 168 @if $cur-x > 0 {
167 $b: $cur-t; 169 $b: $cur-t;
168 } @else { 170 } @else {
169 $a: $cur-t; 171 $a: $cur-t;
170 } 172 }
171 173
172 @if abs($cur-x) < $cubic-bezier-subdiv-precision { 174 @if math.abs($cur-x) < $cubic-bezier-subdiv-precision {
173 @return $cur-t; 175 @return $cur-t;
174 } 176 }
175 } 177 }
176 178
177 @return $cur-t; 179 @return $cur-t;
178} 180}
179 181
180/// 182///
@@ -183,30 +185,41 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
183/// @access private 185/// @access private
184/// 186///
185@function cubic-bezier-t-for-x($x1, $x2, $x) { 187@function cubic-bezier-t-for-x($x1, $x2, $x) {
186 $sample-pool-key: $x1 + '_' + $x2; 188 $sample-pool-key: $x1 + '_' + $x2;
187 $samples: map-get($cubic-bezier-sample-pool, $sample-pool-key); 189 $samples: map.get($cubic-bezier-sample-pool, $sample-pool-key);
188 190
189 $intv-start: 0; 191 $intv-start: 0;
190 $cur-sample: 1; 192 $cur-sample: 1;
191 $last-sample: $cubic-bezier-sample-pool-size; 193 $last-sample: $cubic-bezier-sample-pool-size;
192 194
193 @while ($cur-sample != $last-sample) and (nth($samples, $cur-sample) <= $x) { 195 @while ($cur-sample != $last-sample) and (list.nth($samples, $cur-sample) <= $x) {
194 $intv-start: $intv-start + math.div(1, $cubic-bezier-sample-pool-size); 196 $intv-start: $intv-start + math.div(1, $cubic-bezier-sample-pool-size);
195 $cur-sample: $cur-sample + 1; 197 $cur-sample: $cur-sample + 1;
196 } 198 }
197 $cur-sample: $cur-sample - 1; 199 $cur-sample: $cur-sample - 1;
198 200
199 $dist: math.div($x - nth($samples, $cur-sample), nth($samples, $cur-sample + 1) - nth($samples, $cur-sample)); 201 $dist: math.div($x - list.nth($samples, $cur-sample), list.nth($samples, $cur-sample + 1) - list.nth($samples, $cur-sample));
200 $guess-t: $intv-start + math.div($dist, $cubic-bezier-sample-pool-size); 202 $guess-t: $intv-start + math.div($dist, $cubic-bezier-sample-pool-size);
201 203
202 $init-slope: cubic-bezier-func-slope($x1, $x2, $guess-t); 204 $init-slope: cubic-bezier-func-slope($x1, $x2, $guess-t);
203 @if $init-slope >= $cubic-bezier-newton-min-slope { 205 @if $init-slope >= $cubic-bezier-newton-min-slope {
204 @return cubic-bezier-newton-raphson($x1, $x2, $x, $guess-t); 206 @return cubic-bezier-newton-raphson($x1, $x2, $x, $guess-t);
205 } @else if $init-slope == 0 { 207 } @else if $init-slope == 0 {
206 @return $guess-t; 208 @return $guess-t;
207 } @else { 209 } @else {
208 @return cubic-bezier-binary-subdivide($x1, $x2, $x, $intv-start, $intv-start + 1 / $cubic-bezier-sample-pool-size); 210 @return cubic-bezier-binary-subdivide($x1, $x2, $x, $intv-start, $intv-start + 1 / $cubic-bezier-sample-pool-size);
209 } 211 }
212}
213
214///
215/// Linear easing function.
216///
217/// @param {number} $x - Progress between 0 and 1 inclusive
218///
219/// @return {number}
220///
221@function linear($x) {
222 @return $x;
210} 223}
211 224
212/// 225///
@@ -217,7 +230,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
217/// @return {number} 230/// @return {number}
218/// 231///
219@function ease($x) { 232@function ease($x) {
220 @return cubic-bezier(.25, .1, .25, 1, $x); 233 @return cubic-bezier(.25, .1, .25, 1, $x);
221} 234}
222 235
223/// 236///
@@ -228,7 +241,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
228/// @return {number} 241/// @return {number}
229/// 242///
230@function ease-in($x) { 243@function ease-in($x) {
231 @return cubic-bezier(.42, 0, 1, 1, $x); 244 @return cubic-bezier(.42, 0, 1, 1, $x);
232} 245}
233 246
234/// 247///
@@ -239,7 +252,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
239/// @return {number} 252/// @return {number}
240/// 253///
241@function ease-out($x) { 254@function ease-out($x) {
242 @return cubic-bezier(0, 0, .58, 1, $x); 255 @return cubic-bezier(0, 0, .58, 1, $x);
243} 256}
244 257
245/// 258///
@@ -250,7 +263,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
250/// @return {number} 263/// @return {number}
251/// 264///
252@function ease-in-out($x) { 265@function ease-in-out($x) {
253 @return cubic-bezier(.42, 0, .58, 1, $x); 266 @return cubic-bezier(.42, 0, .58, 1, $x);
254} 267}
255 268
256/// 269///
@@ -261,7 +274,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
261/// @return {number} 274/// @return {number}
262/// 275///
263@function ease-in-sine($x) { 276@function ease-in-sine($x) {
264 @return cubic-bezier(.47, 0, .745, .715, $x); 277 @return cubic-bezier(.47, 0, .745, .715, $x);
265} 278}
266 279
267/// 280///
@@ -272,7 +285,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
272/// @return {number} 285/// @return {number}
273/// 286///
274@function ease-out-sine($x) { 287@function ease-out-sine($x) {
275 @return cubic-bezier(.39, .575, .565, 1, $x); 288 @return cubic-bezier(.39, .575, .565, 1, $x);
276} 289}
277 290
278/// 291///
@@ -283,7 +296,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
283/// @return {number} 296/// @return {number}
284/// 297///
285@function ease-in-out-sine($x) { 298@function ease-in-out-sine($x) {
286 @return cubic-bezier(.445, .05, .55, .95, $x); 299 @return cubic-bezier(.445, .05, .55, .95, $x);
287} 300}
288 301
289/// 302///
@@ -294,7 +307,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
294/// @return {number} 307/// @return {number}
295/// 308///
296@function ease-in-quad($x) { 309@function ease-in-quad($x) {
297 @return cubic-bezier(.55, .085, .68, .53, $x); 310 @return cubic-bezier(.55, .085, .68, .53, $x);
298} 311}
299 312
300/// 313///
@@ -305,7 +318,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
305/// @return {number} 318/// @return {number}
306/// 319///
307@function ease-out-quad($x) { 320@function ease-out-quad($x) {
308 @return cubic-bezier(.25, .46, .45, .94, $x); 321 @return cubic-bezier(.25, .46, .45, .94, $x);
309} 322}
310 323
311/// 324///
@@ -316,7 +329,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
316/// @return {number} 329/// @return {number}
317/// 330///
318@function ease-in-out-quad($x) { 331@function ease-in-out-quad($x) {
319 @return cubic-bezier(.455, .03, .515, .955, $x); 332 @return cubic-bezier(.455, .03, .515, .955, $x);
320} 333}
321 334
322/// 335///
@@ -327,7 +340,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
327/// @return {number} 340/// @return {number}
328/// 341///
329@function ease-in-cubic($x) { 342@function ease-in-cubic($x) {
330 @return cubic-bezier(.55, .055, .675, .19, $x); 343 @return cubic-bezier(.55, .055, .675, .19, $x);
331} 344}
332 345
333/// 346///
@@ -338,7 +351,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
338/// @return {number} 351/// @return {number}
339/// 352///
340@function ease-out-cubic($x) { 353@function ease-out-cubic($x) {
341 @return cubic-bezier(.215, .61, .355, 1, $x); 354 @return cubic-bezier(.215, .61, .355, 1, $x);
342} 355}
343 356
344/// 357///
@@ -349,7 +362,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
349/// @return {number} 362/// @return {number}
350/// 363///
351@function ease-in-out-cubic($x) { 364@function ease-in-out-cubic($x) {
352 @return cubic-bezier(.645, .045, .355, 1, $x); 365 @return cubic-bezier(.645, .045, .355, 1, $x);
353} 366}
354 367
355/// 368///
@@ -360,7 +373,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
360/// @return {number} 373/// @return {number}
361/// 374///
362@function ease-in-quart($x) { 375@function ease-in-quart($x) {
363 @return cubic-bezier(.895, .03, .685, .22, $x); 376 @return cubic-bezier(.895, .03, .685, .22, $x);
364} 377}
365 378
366/// 379///
@@ -371,7 +384,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
371/// @return {number} 384/// @return {number}
372/// 385///
373@function ease-out-quart($x) { 386@function ease-out-quart($x) {
374 @return cubic-bezier(.165, .84, .44, 1, $x); 387 @return cubic-bezier(.165, .84, .44, 1, $x);
375} 388}
376 389
377/// 390///
@@ -382,7 +395,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
382/// @return {number} 395/// @return {number}
383/// 396///
384@function ease-in-out-quart($x) { 397@function ease-in-out-quart($x) {
385 @return cubic-bezier(.77, 0, .175, 1, $x); 398 @return cubic-bezier(.77, 0, .175, 1, $x);
386} 399}
387 400
388/// 401///
@@ -393,7 +406,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
393/// @return {number} 406/// @return {number}
394/// 407///
395@function ease-in-quint($x) { 408@function ease-in-quint($x) {
396 @return cubic-bezier(.755, .05, .855, .06, $x); 409 @return cubic-bezier(.755, .05, .855, .06, $x);
397} 410}
398 411
399/// 412///
@@ -404,7 +417,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
404/// @return {number} 417/// @return {number}
405/// 418///
406@function ease-out-quint($x) { 419@function ease-out-quint($x) {
407 @return cubic-bezier(.23, 1, .32, 1, $x); 420 @return cubic-bezier(.23, 1, .32, 1, $x);
408} 421}
409 422
410/// 423///
@@ -415,7 +428,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
415/// @return {number} 428/// @return {number}
416/// 429///
417@function ease-in-out-quint($x) { 430@function ease-in-out-quint($x) {
418 @return cubic-bezier(.86, 0, .07, 1, $x); 431 @return cubic-bezier(.86, 0, .07, 1, $x);
419} 432}
420 433
421/// 434///
@@ -426,7 +439,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
426/// @return {number} 439/// @return {number}
427/// 440///
428@function ease-in-expo($x) { 441@function ease-in-expo($x) {
429 @return cubic-bezier(.95, .05, .795, .035, $x); 442 @return cubic-bezier(.95, .05, .795, .035, $x);
430} 443}
431 444
432/// 445///
@@ -437,7 +450,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
437/// @return {number} 450/// @return {number}
438/// 451///
439@function ease-out-expo($x) { 452@function ease-out-expo($x) {
440 @return cubic-bezier(.19, 1, .22, 1, $x); 453 @return cubic-bezier(.19, 1, .22, 1, $x);
441} 454}
442 455
443/// 456///
@@ -448,7 +461,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
448/// @return {number} 461/// @return {number}
449/// 462///
450@function ease-in-out-expo($x) { 463@function ease-in-out-expo($x) {
451 @return cubic-bezier(1, 0, 0, 1, $x); 464 @return cubic-bezier(1, 0, 0, 1, $x);
452} 465}
453 466
454/// 467///
@@ -459,7 +472,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
459/// @return {number} 472/// @return {number}
460/// 473///
461@function ease-in-circ($x) { 474@function ease-in-circ($x) {
462 @return cubic-bezier(.6, .04, .98, .335, $x); 475 @return cubic-bezier(.6, .04, .98, .335, $x);
463} 476}
464 477
465/// 478///
@@ -470,7 +483,7 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
470/// @return {number} 483/// @return {number}
471/// 484///
472@function ease-out-circ($x) { 485@function ease-out-circ($x) {
473 @return cubic-bezier(.075, .82, .165, 1, $x); 486 @return cubic-bezier(.075, .82, .165, 1, $x);
474} 487}
475 488
476/// 489///
@@ -481,5 +494,5 @@ $cubic-bezier-subdiv-max-iters: 10 !default;
481/// @return {number} 494/// @return {number}
482/// 495///
483@function ease-in-out-circ($x) { 496@function ease-in-out-circ($x) {
484 @return cubic-bezier(.785, .135, .15, .86, $x); 497 @return cubic-bezier(.785, .135, .15, .86, $x);
485} 498}
diff --git a/src/_functions.scss b/src/_functions.scss
index 9dd14b1..74cc1b5 100644
--- a/src/_functions.scss
+++ b/src/_functions.scss
@@ -10,9 +10,32 @@
10//// 10////
11 11
12@use 'sass:map'; 12@use 'sass:map';
13@use 'sass:list';
13@use 'sass:math'; 14@use 'sass:math';
15@use 'sass:string';
16@use 'sass:meta';
14@use './vars'; 17@use './vars';
15 18
19$numbers: ('0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9);
20
21$units: (
22 'px': 1px,
23 'cm': 1cm,
24 'mm': 1mm,
25 '%': 1%,
26 'ch': 1ch,
27 'pc': 1pc,
28 'in': 1in,
29 'em': 1em,
30 'rem': 1rem,
31 'pt': 1pt,
32 'ex': 1ex,
33 'vw': 1vw,
34 'vh': 1vh,
35 'vmin': 1vmin,
36 'vmax': 1vmax
37);
38
16/// 39///
17/// Replace a substring with a new string. 40/// Replace a substring with a new string.
18/// 41///
@@ -23,13 +46,13 @@
23/// @return {string} A string with all instances of $search replaced with $replace 46/// @return {string} A string with all instances of $search replaced with $replace
24/// 47///
25@function str-replace($string, $search, $replace) { 48@function str-replace($string, $search, $replace) {
26 $index: str-index($string, $search); 49 $index: string.index($string, $search);
27 50
28 @if $index { 51 @if $index {
29 @return str-slice($string, 1, $index - 1) + $replace + str-replace(str-slice($string, $index + str-length($search)), $search, $replace); 52 @return string.slice($string, 1, $index - 1) + $replace + str-replace(string.slice($string, $index + string.length($search)), $search, $replace);
30 } 53 }
31 54
32 @return $string; 55 @return $string;
33} 56}
34 57
35/// 58///
@@ -41,17 +64,17 @@
41/// @return {string} 64/// @return {string}
42/// 65///
43@function str-implode($list, $glue: '') { 66@function str-implode($list, $glue: '') {
44 $result: ''; 67 $result: '';
45 68
46 @each $item in $list { 69 @each $item in $list {
47 $result: $result + if(length($item) > 1, str-implode($item, $glue), $item); 70 $result: $result + if(list.length($item) > 1, str-implode($item, $glue), $item);
48 71
49 @if $item != nth($list, length($list)) { 72 @if $item != list.nth($list, list.length($list)) {
50 $result: $result + $glue; 73 $result: $result + $glue;
51 } 74 }
52 } 75 }
53 76
54 @return $result; 77 @return $result;
55} 78}
56 79
57/// 80///
@@ -63,18 +86,18 @@
63/// 86///
64/// @return {list} A slice of the list 87/// @return {list} A slice of the list
65/// 88///
66@function list-slice($list, $start: 1, $end: length($list)) { 89@function list-slice($list, $start: 1, $end: list.length($list)) {
67 $result: (); 90 $result: ();
68 91
69 @if $end >= $start { 92 @if $end >= $start {
70 @for $i from $start through $end { 93 @for $i from $start through $end {
71 @if $i != 0 { 94 @if $i != 0 {
72 $result: append($result, nth($list, $i), list-separator($list)); 95 $result: list.append($result, list.nth($list, $i), list.separator($list));
73 } 96 }
74 } 97 }
75 } 98 }
76 99
77 @return $result; 100 @return $result;
78} 101}
79 102
80/// 103///
@@ -86,15 +109,15 @@
86/// @return {list} A list with $value at the beginning, followed by the other items 109/// @return {list} A list with $value at the beginning, followed by the other items
87/// 110///
88@function list-prepend($list, $value) { 111@function list-prepend($list, $value) {
89 $result: append((), $value, list-separator($list)); 112 $result: list.append((), $value, list.separator($list));
90 113
91 @if length($list) > 0 { 114 @if list.length($list) > 0 {
92 @for $i from 1 through length($list) { 115 @for $i from 1 through list.length($list) {
93 $result: append($result, nth($list, $i), list-separator($list)); 116 $result: list.append($result, list.nth($list, $i), list.separator($list));
94 } 117 }
95 } 118 }
96 119
97 @return $result; 120 @return $result;
98} 121}
99 122
100/// 123///
@@ -105,15 +128,15 @@
105/// @return {list} Teh reversed list 128/// @return {list} Teh reversed list
106/// 129///
107@function list-reverse($list) { 130@function list-reverse($list) {
108 @if length($list) == 0 { 131 @if list.length($list) == 0 {
109 @return $list; 132 @return $list;
110 } 133 }
111 134
112 $result: (); 135 $result: ();
113 @for $i from length($list) * -1 through -1 { 136 @for $i from list.length($list) * -1 through -1 {
114 $result: append($result, nth($list, abs($i))); 137 $result: list.append($result, list.nth($list, math.abs($i)));
115 } 138 }
116 @return $result; 139 @return $result;
117} 140}
118 141
119/// 142///
@@ -126,52 +149,52 @@
126/// 149///
127/// @return {list} Sorted list 150/// @return {list} Sorted list
128/// 151///
129@function quicksort($l, $left: 1, $right: length($l)) { 152@function quicksort($l, $left: 1, $right: list.length($l)) {
130 @if $left < $right { 153 @if $left < $right {
131 $pvr: quicksort-partition($l, $left, $right); 154 $pvr: quicksort-partition($l, $left, $right);
132 $pivot: nth($pvr, 1); 155 $pivot: list.nth($pvr, 1);
133 $l: nth($pvr, 2); 156 $l: list.nth($pvr, 2);
134 $l: quicksort($l, $left, $pivot); 157 $l: quicksort($l, $left, $pivot);
135 $l: quicksort($l, $pivot + 1, $right); 158 $l: quicksort($l, $pivot + 1, $right);
136 } 159 }
137 160
138 @return $l; 161 @return $l;
139} 162}
140 163
141/// 164///
142/// @access private 165/// @access private
143/// 166///
144@function quicksort-partition($l, $left, $right) { 167@function quicksort-partition($l, $left, $right) {
145 $start: true; 168 $start: true;
146 $i: $left; 169 $i: $left;
147 $j: $right - 1; 170 $j: $right - 1;
148 $pivot: nth($l, $right); 171 $pivot: list.nth($l, $right);
149 172
150 @while ($i < $j) or $start { 173 @while ($i < $j) or $start {
151 @while (nth($l, $i) < $pivot) and ($i < $right - 1) { 174 @while (list.nth($l, $i) < $pivot) and ($i < $right - 1) {
152 $i: $i + 1; 175 $i: $i + 1;
153 } 176 }
154 177
155 @while (nth($l, $j)>= $pivot) and ($j > $left) { 178 @while (list.nth($l, $j)>= $pivot) and ($j > $left) {
156 $j: $j - 1; 179 $j: $j - 1;
157 } 180 }
158 181
159 @if $i < $j { 182 @if $i < $j {
160 $i-val: nth($l, $i); 183 $i-val: list.nth($l, $i);
161 $l: set-nth($l, $i, nth($l, $j)); 184 $l: list.set-nth($l, $i, list.nth($l, $j));
162 $l: set-nth($l, $j, $i-val); 185 $l: list.set-nth($l, $j, $i-val);
163 } 186 }
164 187
165 $start: false; 188 $start: false;
166 } 189 }
167 190
168 @if nth($l, $i) > $pivot { 191 @if list.nth($l, $i) > $pivot {
169 $i-val: nth($l, $i); 192 $i-val: list.nth($l, $i);
170 $l: set-nth($l, $i, nth($l, $right)); 193 $l: list.set-nth($l, $i, list.nth($l, $right));
171 $l: set-nth($l, $right, $i-val); 194 $l: list.set-nth($l, $right, $i-val);
172 } 195 }
173 196
174 @return $i $l; 197 @return $i $l;
175} 198}
176 199
177/// 200///
@@ -185,10 +208,10 @@
185/// @return {any} Either the value assigned to $key or $default 208/// @return {any} Either the value assigned to $key or $default
186/// 209///
187@function map-get-default($map, $key, $keys...) { 210@function map-get-default($map, $key, $keys...) {
188 $default: nth($keys, length($keys)); 211 $default: list.nth($keys, list.length($keys));
189 $keys: list-slice($keys, 1, length($keys) - 1); 212 $keys: list-slice($keys, 1, list.length($keys) - 1);
190 213
191 @return if(map-has-key($map, $key, $keys...), map-get($map, $key, $keys...), $default); 214 @return if(map.has-key($map, $key, $keys...), map.get($map, $key, $keys...), $default);
192} 215}
193 216
194/// 217///
@@ -199,29 +222,29 @@
199/// @return {string} 222/// @return {string}
200/// 223///
201@function map-print($map) { 224@function map-print($map) {
202 $output: ''; 225 $output: '';
203 226
204 @each $key, $value in $map { 227 @each $key, $value in $map {
205 $value-str: ''; 228 $value-str: '';
206 229
207 @if type-of($value) == map { 230 @if meta.type-of($value) == map {
208 $value-str: '[ ' + map-print($value) + ' ]'; 231 $value-str: '[ ' + map-print($value) + ' ]';
209 } @else if type-of($value) == list { 232 } @else if meta.type-of($value) == list {
210 $value-str: '[ ' + str-implode($value, ', ') + ' ]'; 233 $value-str: '[ ' + str-implode($value, ', ') + ' ]';
211 } @else if type-of($value) == string { 234 } @else if meta.type-of($value) == string {
212 $value-str: '\'' + $value + '\''; 235 $value-str: '\'' + $value + '\'';
213 } @else { 236 } @else {
214 $value-str: $value; 237 $value-str: $value;
215 } 238 }
216 239
217 @if $output == '' { 240 @if $output == '' {
218 $output: $key + ': ' + $value-str; 241 $output: $key + ': ' + $value-str;
219 } @else { 242 } @else {
220 $output: $output + ', ' + $key + ': ' + $value-str; 243 $output: $output + ', ' + $key + ': ' + $value-str;
221 } 244 }
222 } 245 }
223 246
224 @return $output; 247 @return $output;
225} 248}
226 249
227/// 250///
@@ -233,35 +256,35 @@
233/// @return {bool} `true` if the selector matches at least one suffix, otherwise `false`. 256/// @return {bool} `true` if the selector matches at least one suffix, otherwise `false`.
234/// 257///
235@function selector-suffix-match($selector, $suffixes) { 258@function selector-suffix-match($selector, $suffixes) {
236 $match: true; 259 $match: true;
237 260
238 @each $sel in $selector { 261 @each $sel in $selector {
239 @if $match { 262 @if $match {
240 $sel-match: false; 263 $sel-match: false;
241 264
242 @each $suffix in $suffixes { 265 @each $suffix in $suffixes {
243 @if not $sel-match { 266 @if not $sel-match {
244 $suf-match: true; 267 $suf-match: true;
245 268
246 @for $i from 1 through length($suffix) { 269 @for $i from 1 through list.length($suffix) {
247 @if $suf-match and (nth($sel, -$i) != nth($suffix, -$i)) { 270 @if $suf-match and (list.nth($sel, -$i) != list.nth($suffix, -$i)) {
248 $suf-match: false; 271 $suf-match: false;
249 } 272 }
250 } 273 }
251 274
252 @if $suf-match { 275 @if $suf-match {
253 $sel-match: true; 276 $sel-match: true;
254 } 277 }
255 } 278 }
256 } 279 }
257 280
258 @if not $sel-match { 281 @if not $sel-match {
259 $match: false; 282 $match: false;
260 } 283 }
261 } 284 }
262 } 285 }
263 286
264 @return $match; 287 @return $match;
265} 288}
266 289
267/// 290///
@@ -272,7 +295,7 @@
272/// @return {number} Unit-less variable 295/// @return {number} Unit-less variable
273/// 296///
274@function strip-unit($n) { 297@function strip-unit($n) {
275 @return math.div($n, $n * 0 + 1); 298 @return math.div($n, $n * 0 + 1);
276} 299}
277 300
278/// 301///
@@ -284,7 +307,62 @@
284/// @return {number} Pixel value converted to rem 307/// @return {number} Pixel value converted to rem
285/// 308///
286@function px-to-rem($size, $base: vars.$root-size) { 309@function px-to-rem($size, $base: vars.$root-size) {
287 @return math.div($size, $base) * 1rem; 310 @return math.div($size, $base) * 1rem;
311}
312
313///
314/// Casts a string into a number
315///
316/// @param {string|number} $value
317///
318/// @return {number}
319///
320@function to-number($value) {
321 @if meta.type-of($value) == 'number' {
322 @return $value;
323 }
324 @if meta.type-of($value) != 'string' {
325 @error 'Value for `to-number` should be a number or a string.';
326 }
327
328 $result: 0;
329 $digits: 0;
330 $minus: string.slice($value, 1, 1) == '-';
331
332 @for $i from if($minus, 2, 1) through string.length($value) {
333 $character: string.slice($value, $i, $i);
334
335 @if not list.index(map.keys($numbers), $character) and $character != '.' {
336 @return to-length(if($minus, -$result, $result), string.slice($value, $i));
337 }
338
339 @if $character == '.' {
340 $digits: 1;
341 } @else if $digits == 0 {
342 $result: $result * 10 + map.get($numbers, $character);
343 } @else {
344 $digits: $digits * 10;
345 $result: $result + math.div(map.get($numbers, $character), $digits);
346 }
347 }
348
349 @return if($minus, -$result, $result);
350}
351
352///
353/// Add $unit to $value
354///
355/// @param {number} $value - Value to add unit to
356/// @param {string} $unit - String representation of the unit
357///
358/// @return {number} $value expressed in $unit
359///
360@function to-length($value, $unit) {
361 @if not list.index(map.keys($units), $unit) {
362 @error 'Invalid unit `#{$unit}`.';
363 }
364
365 @return $value * map.get($units, $unit);
288} 366}
289 367
290/// 368///
@@ -293,5 +371,5 @@
293/// @content 371/// @content
294/// 372///
295@mixin execute { 373@mixin execute {
296 @content; 374 @content;
297} 375}
diff --git a/src/_gradients.scss b/src/_gradients.scss
index 6575482..345a9f1 100644
--- a/src/_gradients.scss
+++ b/src/_gradients.scss
@@ -15,8 +15,11 @@
15/// @access public 15/// @access public
16//// 16////
17 17
18@use 'sass:color';
19@use 'sass:list';
18@use 'sass:math'; 20@use 'sass:math';
19@use 'sass:meta'; 21@use 'sass:meta';
22@use 'sass:string';
20@use './functions'; 23@use './functions';
21@use './easing'; 24@use './easing';
22 25
@@ -135,144 +138,136 @@ $easing-gradient-steps: 10 !default;
135/// } 138/// }
136/// 139///
137@function easing-gradient($type, $dir, $stop, $stops...) { 140@function easing-gradient($type, $dir, $stop, $stops...) {
138 $pos-template: null; 141 $pos-template: null;
139 $stops: functions.list-prepend($stops, $stop); 142 $stops: functions.list-prepend($stops, $stop);
140 143
141 $last-positioned-stop: 1; 144 $last-positioned-stop: 1;
142 $generated-stops: (); 145 $generated-stops: ();
143 146
144 // 147 //
145 // Generate gradient 148 // Generate gradient
146 // 149 //
147 150
148 @for $i from 1 through length($stops) { 151 @for $i from 1 through list.length($stops) {
149 $stop: nth($stops, $i); 152 $stop: list.nth($stops, $i);
150 153
151 @if $i == 1 { 154 @if $i == 1 {
152 @if not easing-gradient-is-color-stop($stop) { 155 @if not easing-gradient-is-color-stop($stop) {
153 @error 'The first color stop argument must be a color stop.'; 156 @error 'The first color stop argument must be a color stop.';
154 } 157 }
155 158
156 @if type-of($stop) == color { 159 @if meta.type-of($stop) == color {
157 // 160 //
158 // The first color stop is unpositioned. The default position for the first 161 // The first color stop is unpositioned. The default position for the first
159 // color stop is 0, which is explicitly added for easier calculations. 162 // color stop is 0, which is explicitly added for easier calculations.
160 // 163 //
161 164
162 $stop: $stop 0; 165 $stop: $stop 0;
163 $stops: set-nth($stops, $i, $stop); 166 $stops: list.set-nth($stops, $i, $stop);
164 } 167 }
165 168
166 $generated-stops: append($generated-stops, functions.str-implode($stop, ' ')); 169 $generated-stops: list.append($generated-stops, functions.str-implode($stop, ' '));
167 } @else if easing-gradient-is-positioned-color-stop($stop) or ($i == length($stops)) { 170 } @else if easing-gradient-is-positioned-color-stop($stop) or ($i == list.length($stops)) {
168 @if not easing-gradient-is-color-stop($stop) { 171 @if not easing-gradient-is-color-stop($stop) {
169 @error 'The last color stop argument must be a color stop.'; 172 @error 'The last color stop argument must be a color stop.';
170 } 173 }
171 174
172 // 175 //
173 // Either the current stops list item is a positioned color stop, or the end of 176 // Either the current stops list item is a positioned color stop, or the end of
174 // the stops list has been reached. 177 // the stops list has been reached.
175 // 178 //
176 179
177 @if (type-of($stop) == color) and ($i == length($stops)) { 180 @if (meta.type-of($stop) == color) and ($i == list.length($stops)) {
178 // 181 //
179 // The current stop is an unpositioned color stop, which means this is the end 182 // The current stop is an unpositioned color stop, which means this is the end
180 // of the stops list. The default position for the last color stop is 100%, which 183 // of the stops list. The default position for the last color stop is 100%, which
181 // is explicitly added for easier calculations. 184 // is explicitly added for easier calculations.
182 // 185 //
183 186
184 $stop: $stop 100%; 187 $stop: $stop 100%;
185 $stops: set-nth($stops, $i, $stop); 188 $stops: list.set-nth($stops, $i, $stop);
186 } 189 }
187 190
188 // 191 //
189 // Now the current color stop is guaranteed to be a positioned color stop. 192 // Now the current color stop is guaranteed to be a positioned color stop.
190 // 193 //
191 194
192 @if $i > $last-positioned-stop + 1 { 195 @if $i > $last-positioned-stop + 1 {
193 // 196 //
194 // There is at least one stops list item (unpositioned color stop or easing function) 197 // There is at least one stops list item (unpositioned color stop or easing function)
195 // between the last positioned color stop and the current stops list item. Interpolate 198 // between the last positioned color stop and the current stops list item. Interpolate
196 // the positions of all stops list items that are color stops. 199 // the positions of all stops list items that are color stops.
197 // 200 //
198 201
199 $interpolated-stops: easing-gradient-interpolate-stop-positions( 202 $interpolated-stops: easing-gradient-interpolate-stop-positions(list.nth($stops, $last-positioned-stop),
200 nth($stops, $last-positioned-stop), 203 functions.list-slice($stops, $last-positioned-stop + 1, $i - 1),
201 functions.list-slice($stops, $last-positioned-stop + 1, $i - 1), 204 $stop);
202 $stop
203 );
204 205
205 $new-stops: join( 206 $new-stops: list.join(functions.list-slice($stops, 1, $last-positioned-stop),
206 functions.list-slice($stops, 1, $last-positioned-stop), 207 $interpolated-stops);
207 $interpolated-stops 208 $new-stops: list.join($new-stops,
208 ); 209 functions.list-slice($stops, $i));
209 $new-stops: join( 210 $stops: $new-stops;
210 $new-stops, 211 }
211 functions.list-slice($stops, $i)
212 );
213 $stops: $new-stops;
214 }
215 212
216 // 213 //
217 // Now all color stops between this one and the last positioned one have 214 // Now all color stops between this one and the last positioned one have
218 // interpolated positions. 215 // interpolated positions.
219 // Next task is to perform an easing transition between all color stops that 216 // Next task is to perform an easing transition between all color stops that
220 // have an easing function specified. The rest can be left alone since the 217 // have an easing function specified. The rest can be left alone since the
221 // browser will automatically apply a linear transition between them. 218 // browser will automatically apply a linear transition between them.
222 // 219 //
223 220
224 $j: $last-positioned-stop + 1; 221 $j: $last-positioned-stop + 1;
225 @while $j <= $i { 222 @while $j <= $i {
226 $easing: null; 223 $easing: null;
227 $prev-stop: nth($stops, $j - 1); 224 $prev-stop: list.nth($stops, $j - 1);
228 $next-stop: nth($stops, $j); 225 $next-stop: list.nth($stops, $j);
229 226
230 @if not easing-gradient-is-color-stop($next-stop) { 227 @if not easing-gradient-is-color-stop($next-stop) {
231 $j: $j + 1; 228 $j: $j + 1;
232 229
233 $easing: $next-stop; 230 $easing: $next-stop;
234 $next-stop: nth($stops, $j); 231 $next-stop: list.nth($stops, $j);
235 232
236 @if not easing-gradient-is-color-stop($next-stop) { 233 @if not easing-gradient-is-color-stop($next-stop) {
237 @error 'There can be at most one interpolation hint between to color stops.'; 234 @error 'There can be at most one interpolation hint between to color stops.';
238 } 235 }
239 } 236 }
240 237
241 @if $easing != null { 238 @if $easing != null {
242 @if type-of($easing) == number { 239 @if meta.type-of($easing) == number {
243 @error 'Midpoint shifts are not supported.'; 240 @error 'Midpoint shifts are not supported.';
244 } 241 }
245 242
246 $easing-func: null; 243 $easing-func: null;
247 $easing-args: (); 244 $easing-args: ();
248 245
249 @if type-of($easing) == list { 246 @if meta.type-of($easing) == list {
250 $easing-args: functions.list-slice($easing, 2); 247 $easing-args: functions.list-slice($easing, 2);
251 $easing: nth($easing, 1); 248 $easing: list.nth($easing, 1);
252 } 249 }
253 250
254 $generated-stops: join( 251 $generated-stops: list.join($generated-stops,
255 $generated-stops, 252 easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args));
256 easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args) 253 } @else {
257 ); 254 $generated-stops: list.append($generated-stops, functions.str-implode($next-stop, ' '));
258 } @else { 255 }
259 $generated-stops: append($generated-stops, functions.str-implode($next-stop, ' '));
260 }
261 256
262 $j: $j + 1; 257 $j: $j + 1;
263 } 258 }
264 259
265 $last-positioned-stop: $i; 260 $last-positioned-stop: $i;
266 } 261 }
267 } 262 }
268 263
269 @if $type == 'linear' { 264 @if $type == 'linear' {
270 @return linear-gradient($dir, unquote(functions.str-implode($generated-stops, ', '))); 265 @return linear-gradient($dir, string.unquote(functions.str-implode($generated-stops, ', ')));
271 } @else if $type == 'radial' { 266 } @else if $type == 'radial' {
272 @return radial-gradient($dir, unquote(functions.str-implode($generated-stops, ', '))); 267 @return radial-gradient($dir, string.unquote(functions.str-implode($generated-stops, ', ')));
273 } @else { 268 } @else {
274 @error 'Invalid gradient type: #{inspect($type)}.'; 269 @error 'Invalid gradient type: #{inspect($type)}.';
275 } 270 }
276} 271}
277 272
278/// 273///
@@ -281,7 +276,7 @@ $easing-gradient-steps: 10 !default;
281/// @see {function} easing-gradient 276/// @see {function} easing-gradient
282/// 277///
283@function easing-linear-gradient($dir, $stop, $stops...) { 278@function easing-linear-gradient($dir, $stop, $stops...) {
284 @return easing-gradient('linear', $dir, $stop, $stops...); 279 @return easing-gradient('linear', $dir, $stop, $stops...);
285} 280}
286 281
287/// 282///
@@ -290,7 +285,7 @@ $easing-gradient-steps: 10 !default;
290/// @see {function} easing-gradient 285/// @see {function} easing-gradient
291/// 286///
292@function easing-radial-gradient($dir, $stop, $stops...) { 287@function easing-radial-gradient($dir, $stop, $stops...) {
293 @return easing-gradient('radial', $dir, $stop, $stops...); 288 @return easing-gradient('radial', $dir, $stop, $stops...);
294} 289}
295 290
296/// 291///
@@ -299,24 +294,24 @@ $easing-gradient-steps: 10 !default;
299/// @access private 294/// @access private
300/// 295///
301@function easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args: ()) { 296@function easing-gradient-ease-stops($prev-stop, $next-stop, $easing, $easing-args: ()) {
302 @if $easing == 'steps' { 297 @if $easing == 'steps' {
303 $steps: null; 298 $steps: null;
304 $jump: null; 299 $jump: null;
305 300
306 @if length($easing-args) > 1 { 301 @if list.length($easing-args) > 1 {
307 $steps: nth($easing-args, 1); 302 $steps: list.nth($easing-args, 1);
308 $jump: nth($easing-args, 2); 303 $jump: list.nth($easing-args, 2);
309 } @else { 304 } @else {
310 $steps: nth($easing-args, 1); 305 $steps: list.nth($easing-args, 1);
311 $jump: jump-end; 306 $jump: jump-end;
312 } 307 }
313 308
314 @return easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump); 309 @return easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump);
315 } @else { 310 } @else {
316 $easing-func: get-function($easing, $module: easing); 311 $easing-func: meta.get-function($easing, $module: easing);
317 312
318 @return easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args); 313 @return easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args);
319 } 314 }
320} 315}
321 316
322/// 317///
@@ -325,74 +320,74 @@ $easing-gradient-steps: 10 !default;
325/// @access private 320/// @access private
326/// 321///
327@function easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args: ()) { 322@function easing-gradient-bezier-stops($prev-stop, $next-stop, $easing-func, $easing-args: ()) {
328 $prev-stop-color: nth($prev-stop, 1); 323 $prev-stop-color: list.nth($prev-stop, 1);
329 $prev-stop-pos: nth($prev-stop, 2); 324 $prev-stop-pos: list.nth($prev-stop, 2);
330 $next-stop-color: nth($next-stop, 1); 325 $next-stop-color: list.nth($next-stop, 1);
331 $next-stop-pos: nth($next-stop, 2); 326 $next-stop-pos: list.nth($next-stop, 2);
332 327
333 $stops: (); 328 $stops: ();
334 329
335 @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { 330 @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) {
336 // 331 //
337 // The transition color stop positions can be statically calculated. 332 // The transition color stop positions can be statically calculated.
338 // 333 //
339 334
340 $distance: $next-stop-pos - $prev-stop-pos; 335 $distance: $next-stop-pos - $prev-stop-pos;
341 336
342 @for $i from 1 through $easing-gradient-steps { 337 @for $i from 1 through $easing-gradient-steps {
343 $perc: math.div($i, $easing-gradient-steps); 338 $perc: math.div($i, $easing-gradient-steps);
344 339
345 $color: null; 340 $color: null;
346 $pos: $prev-stop-pos + $perc * $distance; 341 $pos: $prev-stop-pos + $perc * $distance;
347 @if $perc == 1 { 342 @if $perc == 1 {
348 $color: $next-stop-color; 343 $color: $next-stop-color;
349 } @else { 344 } @else {
350 $color: mix($next-stop-color, $prev-stop-color, call($easing-func, append($easing-args, $perc)...) * 100%); 345 $color: color.mix($next-stop-color, $prev-stop-color, meta.call($easing-func, list.append($easing-args, $perc)...) * 100%);
351 } 346 }
352 347
353 $stops: append($stops, $color + ' ' + $pos); 348 $stops: list.append($stops, $color + ' ' + $pos);
354 } 349 }
355 } @else { 350 } @else {
356 // 351 //
357 // The transition color stop positions have to be dynamically calculated with the calc() function. 352 // The transition color stop positions have to be dynamically calculated with the calc() function.
358 // 353 //
359 354
360 @if type-of($prev-stop-pos) != number { 355 @if meta.type-of($prev-stop-pos) != number {
361 // must be calc() 356 // must be calc()
362 @if type-of($prev-stop-pos) != calculation { 357 @if meta.type-of($prev-stop-pos) != calculation {
363 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; 358 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}';
364 } 359 }
365 360
366 $prev-stop-pos: meta.calc-args($prev-stop-pos); 361 $prev-stop-pos: meta.calc-args($prev-stop-pos);
367 } 362 }
368 363
369 @if type-of($next-stop-pos) != number { 364 @if meta.type-of($next-stop-pos) != number {
370 // must be calc() 365 // must be calc()
371 @if type-of($next-stop-pos) != calculation { 366 @if meta.type-of($next-stop-pos) != calculation {
372 @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; 367 @error 'Invalid color stop position: #{inspect($next-stop-pos)}';
373 } 368 }
374 369
375 $next-stop-pos: meta.calc-args($next-stop-pos); 370 $next-stop-pos: meta.calc-args($next-stop-pos);
376 } 371 }
377 372
378 @for $i from 1 through $easing-gradient-steps { 373 @for $i from 1 through $easing-gradient-steps {
379 $perc: math.div($i, $easing-gradient-steps); 374 $perc: math.div($i, $easing-gradient-steps);
380 375
381 $color: null; 376 $color: null;
382 $pos: null; 377 $pos: null;
383 @if $perc == 1 { 378 @if $perc == 1 {
384 $color: $next-stop-color; 379 $color: $next-stop-color;
385 $pos: calc(#{$next-stop-pos}); 380 $pos: calc(#{$next-stop-pos});
386 } @else { 381 } @else {
387 $color: mix($next-stop-color, $prev-stop-color, call($easing-func, append($easing-args, $perc)...) * 100%); 382 $color: color.mix($next-stop-color, $prev-stop-color, meta.call($easing-func, list.append($easing-args, $perc)...) * 100%);
388 $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); 383 $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc});
389 } 384 }
390 385
391 $stops: append($stops, $color + ' ' + $pos); 386 $stops: list.append($stops, $color + ' ' + $pos);
392 } 387 }
393 } 388 }
394 389
395 @return $stops; 390 @return $stops;
396} 391}
397 392
398/// 393///
@@ -401,110 +396,110 @@ $easing-gradient-steps: 10 !default;
401/// @access private 396/// @access private
402/// 397///
403@function easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump: jump-end) { 398@function easing-gradient-steps-stops($prev-stop, $next-stop, $steps, $jump: jump-end) {
404 $prev-stop-color: nth($prev-stop, 1); 399 $prev-stop-color: list.nth($prev-stop, 1);
405 $prev-stop-pos: nth($prev-stop, 2); 400 $prev-stop-pos: list.nth($prev-stop, 2);
406 $next-stop-color: nth($next-stop, 1); 401 $next-stop-color: list.nth($next-stop, 1);
407 $next-stop-pos: nth($next-stop, 2); 402 $next-stop-pos: list.nth($next-stop, 2);
408 403
409 $stops: (); 404 $stops: ();
410 405
411 @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { 406 @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) {
412 // 407 //
413 // The transition color stop positions can be statically calculated. 408 // The transition color stop positions can be statically calculated.
414 // 409 //
415 410
416 $distance: $next-stop-pos - $prev-stop-pos; 411 $distance: $next-stop-pos - $prev-stop-pos;
417 412
418 @for $i from 1 through $steps { 413 @for $i from 1 through $steps {
419 $x1: math.div($i - 1, $steps); 414 $xx1: math.div($i - 1, $steps);
420 $x2: math.div($i, $steps); 415 $xx2: math.div($i, $steps);
421 $y: null; 416 $y: null;
422 417
423 @if $jump == jump-start { 418 @if $jump == jump-start {
424 $y: math.div($i, $steps); 419 $y: math.div($i, $steps);
425 } @else if $jump == jump-end { 420 } @else if $jump == jump-end {
426 $y: math.div($i - 1, $steps); 421 $y: math.div($i - 1, $steps);
427 } @else if $jump == jump-both { 422 } @else if $jump == jump-both {
428 $y: math.div($i, $steps + 1); 423 $y: math.div($i, $steps + 1);
429 } @else if $jump == jump-none { 424 } @else if $jump == jump-none {
430 $y: math.div($i - 1, $steps - 1); 425 $y: math.div($i - 1, $steps - 1);
431 } @else { 426 } @else {
432 @error 'Invalid $jump: #{inspect($jump)}'; 427 @error 'Invalid $jump: #{inspect($jump)}';
433 } 428 }
434 429
435 $color: null; 430 $color: null;
436 $pos1: if($x1 == 0, $prev-stop-pos, $prev-stop-pos + $x1 * $distance); 431 $pos1: if($xx1 == 0, $prev-stop-pos, $prev-stop-pos + $xx1 * $distance);
437 $pos2: if($x2 == 1, $next-stop-pos, $prev-stop-pos + $x2 * $distance); 432 $pos2: if($xx2 == 1, $next-stop-pos, $prev-stop-pos + $xx2 * $distance);
438 433
439 @if $y == 0 { 434 @if $y == 0 {
440 $color: $prev-stop-color; 435 $color: $prev-stop-color;
441 } @else if $y == 1 { 436 } @else if $y == 1 {
442 $color: $next-stop-color; 437 $color: $next-stop-color;
443 } @else { 438 } @else {
444 $color: mix($next-stop-color, $prev-stop-color, $y * 100%); 439 $color: color.mix($next-stop-color, $prev-stop-color, $y * 100%);
445 } 440 }
446 441
447 $stops: append($stops, $color + ' ' + $pos1); 442 $stops: list.append($stops, $color + ' ' + $pos1);
448 $stops: append($stops, $color + ' ' + $pos2); 443 $stops: list.append($stops, $color + ' ' + $pos2);
449 } 444 }
450 } @else { 445 } @else {
451 // 446 //
452 // The transition color stop positions have to be dynamically calculated with the calc() function. 447 // The transition color stop positions have to be dynamically calculated with the calc() function.
453 // 448 //
454 449
455 @if type-of($prev-stop-pos) != number { 450 @if meta.type-of($prev-stop-pos) != number {
456 // must be calc() 451 // must be calc()
457 @if type-of($prev-stop-pos) != calculation { 452 @if meta.type-of($prev-stop-pos) != calculation {
458 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; 453 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}';
459 } 454 }
460 455
461 $prev-stop-pos: meta.calc-args($prev-stop-pos); 456 $prev-stop-pos: meta.calc-args($prev-stop-pos);
462 } 457 }
463 458
464 @if type-of($next-stop-pos) != number { 459 @if meta.type-of($next-stop-pos) != number {
465 // must be calc() 460 // must be calc()
466 @if type-of($next-stop-pos) != calculation { 461 @if meta.type-of($next-stop-pos) != calculation {
467 @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; 462 @error 'Invalid color stop position: #{inspect($next-stop-pos)}';
468 } 463 }
469 464
470 $next-stop-pos: meta.calc-args($next-stop-pos); 465 $next-stop-pos: meta.calc-args($next-stop-pos);
471 } 466 }
472 467
473 @for $i from 1 through $steps { 468 @for $i from 1 through $steps {
474 $x1: math.div($i - 1, $steps); 469 $xx1: math.div($i - 1, $steps);
475 $x2: math.div($i, $steps); 470 $xx2: math.div($i, $steps);
476 $y: null; 471 $y: null;
477 472
478 @if $jump == jump-start { 473 @if $jump == jump-start {
479 $y: math.div($i, $steps); 474 $y: math.div($i, $steps);
480 } @else if $jump == jump-end { 475 } @else if $jump == jump-end {
481 $y: math.div($i - 1, $steps); 476 $y: math.div($i - 1, $steps);
482 } @else if $jump == jump-both { 477 } @else if $jump == jump-both {
483 $y: math.div($i, $steps + 1); 478 $y: math.div($i, $steps + 1);
484 } @else if $jump == jump-none { 479 } @else if $jump == jump-none {
485 $y: math.div($i - 1, $steps - 1); 480 $y: math.div($i - 1, $steps - 1);
486 } @else { 481 } @else {
487 @error 'Invalid $jump: #{inspect($jump)}'; 482 @error 'Invalid $jump: #{inspect($jump)}';
488 } 483 }
489 484
490 $color: null; 485 $color: null;
491 $pos1: if($x1 == 0, $prev-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$x1})); 486 $pos1: if($xx1 == 0, $prev-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$xx1}));
492 $pos2: if($x2 == 1, $next-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$x2})); 487 $pos2: if($xx2 == 1, $next-stop-pos, calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$xx2}));
493 488
494 @if $y == 0 { 489 @if $y == 0 {
495 $color: $prev-stop-color; 490 $color: $prev-stop-color;
496 } @else if $y == 1 { 491 } @else if $y == 1 {
497 $color: $next-stop-color; 492 $color: $next-stop-color;
498 } @else { 493 } @else {
499 $color: mix($next-stop-color, $prev-stop-color, $y * 100%); 494 $color: color.mix($next-stop-color, $prev-stop-color, $y * 100%);
500 } 495 }
501 496
502 $stops: append($stops, $color + ' ' + $pos1); 497 $stops: list.append($stops, $color + ' ' + $pos1);
503 $stops: append($stops, $color + ' ' + $pos2); 498 $stops: list.append($stops, $color + ' ' + $pos2);
504 } 499 }
505 } 500 }
506 501
507 @return $stops; 502 @return $stops;
508} 503}
509 504
510/// 505///
@@ -513,72 +508,72 @@ $easing-gradient-steps: 10 !default;
513/// @access private 508/// @access private
514/// 509///
515@function easing-gradient-interpolate-stop-positions($prev-stop, $stops, $next-stop) { 510@function easing-gradient-interpolate-stop-positions($prev-stop, $stops, $next-stop) {
516 $prev-stop-pos: nth($prev-stop, 2); 511 $prev-stop-pos: list.nth($prev-stop, 2);
517 $next-stop-pos: nth($next-stop, 2); 512 $next-stop-pos: list.nth($next-stop, 2);
518 513
519 $stops-num: 0; 514 $stops-num: 0;
520 @for $i from 1 through length($stops) { 515 @for $i from 1 through list.length($stops) {
521 $stop: nth($stops, $i); 516 $stop: list.nth($stops, $i);
522 @if easing-gradient-is-color-stop($stop) { 517 @if easing-gradient-is-color-stop($stop) {
523 $stops-num: $stops-num + 1; 518 $stops-num: $stops-num + 1;
524 } 519 }
525 } 520 }
526 521
527 $i: 1; 522 $i: 1;
528 $cur-stop-num: 1; 523 $cur-stop-num: 1;
529 524
530 @if ((type-of($prev-stop-pos) == number) and (type-of($next-stop-pos) == number) and (unit($prev-stop-pos) == unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) { 525 @if ((meta.type-of($prev-stop-pos) == number) and (meta.type-of($next-stop-pos) == number) and (math.unit($prev-stop-pos) == math.unit($next-stop-pos))) or ($prev-stop-pos == 0) or ($next-stop-pos == 0) {
531 // 526 //
532 // The color stop positions can be statically calculated. 527 // The color stop positions can be statically calculated.
533 // 528 //
534 529
535 $distance: $next-stop-pos - $prev-stop-pos; 530 $distance: $next-stop-pos - $prev-stop-pos;
536 531
537 @for $i from 1 through length($stops) { 532 @for $i from 1 through list.length($stops) {
538 $stop: nth($stops, $i); 533 $stop: list.nth($stops, $i);
539 @if easing-gradient-is-color-stop($stop) { 534 @if easing-gradient-is-color-stop($stop) {
540 $pos: $prev-stop-pos + math.div($distance, $stops-num + 1) * $cur-stop-num; 535 $pos: $prev-stop-pos + math.div($distance, $stops-num + 1) * $cur-stop-num;
541 $stops: set-nth($stops, $i, $stop $pos); 536 $stops: list.set-nth($stops, $i, $stop $pos);
542 537
543 $cur-stop-num: $cur-stop-num + 1; 538 $cur-stop-num: $cur-stop-num + 1;
544 } 539 }
545 } 540 }
546 } @else { 541 } @else {
547 // 542 //
548 // The color stop positions have to be dynamically calculated with the calc() function. 543 // The color stop positions have to be dynamically calculated with the calc() function.
549 // 544 //
550 545
551 @if type-of($prev-stop-pos) != number { 546 @if meta.type-of($prev-stop-pos) != number {
552 // must be calc() 547 // must be calc()
553 @if type-of($prev-stop-pos) != calculation { 548 @if meta.type-of($prev-stop-pos) != calculation {
554 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}'; 549 @error 'Invalid color stop position: #{inspect($prev-stop-pos)}';
555 } 550 }
556 551
557 $prev-stop-pos: meta.calc-args($prev-stop-pos); 552 $prev-stop-pos: meta.calc-args($prev-stop-pos);
558 } 553 }
559 554
560 @if type-of($next-stop-pos) != number { 555 @if meta.type-of($next-stop-pos) != number {
561 // must be calc() 556 // must be calc()
562 @if type-of($next-stop-pos) != calculation { 557 @if meta.type-of($next-stop-pos) != calculation {
563 @error 'Invalid color stop position: #{inspect($next-stop-pos)}'; 558 @error 'Invalid color stop position: #{inspect($next-stop-pos)}';
564 } 559 }
565 560
566 $next-stop-pos: meta.calc-args($next-stop-pos); 561 $next-stop-pos: meta.calc-args($next-stop-pos);
567 } 562 }
568 563
569 @for $i from 1 through length($stops) { 564 @for $i from 1 through list.length($stops) {
570 $stop: nth($stops, $i); 565 $stop: list.nth($stops, $i);
571 @if easing-gradient-is-color-stop($stop) { 566 @if easing-gradient-is-color-stop($stop) {
572 $perc: math.div($cur-stop-num, $stops-num + 1); 567 $perc: math.div($cur-stop-num, $stops-num + 1);
573 $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc}); 568 $pos: calc(#{$prev-stop-pos} + (#{$next-stop-pos} - #{$prev-stop-pos}) * #{$perc});
574 $stops: set-nth($stops, $i, $stop $pos); 569 $stops: list.set-nth($stops, $i, $stop $pos);
575 570
576 $cur-stop-num: $cur-stop-num + 1; 571 $cur-stop-num: $cur-stop-num + 1;
577 } 572 }
578 } 573 }
579 } 574 }
580 575
581 @return $stops; 576 @return $stops;
582} 577}
583 578
584/// 579///
@@ -587,7 +582,7 @@ $easing-gradient-steps: 10 !default;
587/// @access private 582/// @access private
588/// 583///
589@function easing-gradient-is-color-stop($input) { 584@function easing-gradient-is-color-stop($input) {
590 @return (type-of($input) == color) or easing-gradient-is-positioned-color-stop($input); 585 @return (meta.type-of($input) == color) or easing-gradient-is-positioned-color-stop($input);
591} 586}
592 587
593/// 588///
@@ -596,5 +591,5 @@ $easing-gradient-steps: 10 !default;
596/// @access private 591/// @access private
597/// 592///
598@function easing-gradient-is-positioned-color-stop($input) { 593@function easing-gradient-is-positioned-color-stop($input) {
599 @return (type-of($input) == list) and (type-of(nth($input, 1)) == color); 594 @return (meta.type-of($input) == list) and (meta.type-of(list.nth($input, 1)) == color);
600} 595}
diff --git a/src/_harmony.scss b/src/_harmony.scss
index aaab726..c0cb772 100644
--- a/src/_harmony.scss
+++ b/src/_harmony.scss
@@ -8,7 +8,10 @@
8/// @access public 8/// @access public
9//// 9////
10 10
11@use 'sass:list';
12@use 'sass:map';
11@use 'sass:math'; 13@use 'sass:math';
14@use 'sass:meta';
12@use './functions'; 15@use './functions';
13@use './responsive'; 16@use './responsive';
14 17
@@ -26,35 +29,35 @@
26/// @return {number} 29/// @return {number}
27/// 30///
28@function modular-scale($times, $base, $ratio) { 31@function modular-scale($times, $base, $ratio) {
29 @if type-of($base) == number { 32 @if meta.type-of($base) == number {
30 @return $base * math.pow($ratio, $times); 33 @return $base * math.pow($ratio, $times);
31 } 34 }
32 35
33 $main-base: nth($base, 1); 36 $main-base: list.nth($base, 1);
34 $norm-bases: (); 37 $norm-bases: ();
35 38
36 @each $b in functions.list-slice($base, 2) { 39 @each $b in functions.list-slice($base, 2) {
37 @if $b > $main-base { 40 @if $b > $main-base {
38 @while $b > $main-base { 41 @while $b > $main-base {
39 $b: math.div($b, $ratio); 42 $b: math.div($b, $ratio);
40 } 43 }
41 $b: $b * $ratio; 44 $b: $b * $ratio;
42 } @else if $b < $main-base { 45 } @else if $b < $main-base {
43 @while $b < $main-base { 46 @while $b < $main-base {
44 $b: $b * $ratio; 47 $b: $b * $ratio;
45 } 48 }
46 } 49 }
47 50
48 $norm-bases: append($norm-bases, $b); 51 $norm-bases: list.append($norm-bases, $b);
49 } 52 }
50 53
51 $all-bases: append($norm-bases, $main-base); 54 $all-bases: list.append($norm-bases, $main-base);
52 $all-bases: functions.quicksort($all-bases); 55 $all-bases: functions.quicksort($all-bases);
53 56
54 $base-index: $times % length($all-bases) + 1; 57 $base-index: $times % list.length($all-bases) + 1;
55 $exp: math.floor(math.div($times, length($all-bases))); 58 $exp: math.floor(math.div($times, list.length($all-bases)));
56 59
57 @return nth($all-bases, $base-index) * math.pow($ratio, $exp); 60 @return list.nth($all-bases, $base-index) * math.pow($ratio, $exp);
58} 61}
59 62
60/// 63///
@@ -86,15 +89,13 @@
86/// } 89/// }
87/// 90///
88@mixin responsive-modular-scale($props, $times, $responsive-map, $fluid: true) { 91@mixin responsive-modular-scale($props, $times, $responsive-map, $fluid: true) {
89 $new-map: (); 92 $new-map: ();
90 93
91 @each $key, $value in $responsive-map { 94 @each $key, $value in $responsive-map {
92 $new-map: map-merge( 95 $new-map: map.merge($new-map, (
93 $new-map, ( 96 $key: modular-scale($times, $value...)
94 $key: modular-scale($times, $value...) 97 ));
95 ) 98 }
96 );
97 }
98 99
99 @include responsive.property($props, $new-map, $fluid); 100 @include responsive.property($props, $new-map, $fluid);
100} 101}
diff --git a/src/index.scss b/src/_iro-sass.scss
index cc9cda7..d1b8ee3 100644
--- a/src/index.scss
+++ b/src/_iro-sass.scss
@@ -1,9 +1,9 @@
1@forward 'bem' as bem-*; 1@forward 'vars' as vars-*;
2@forward 'functions' as fn-*;
2@forward 'contexts' as ctx-*; 3@forward 'contexts' as ctx-*;
4@forward 'props' as props-*;
5@forward 'bem' as bem-*;
3@forward 'easing' as easing-*; 6@forward 'easing' as easing-*;
4@forward 'functions' as fn-*;
5@forward 'gradients' as gradients-*; 7@forward 'gradients' as gradients-*;
6@forward 'harmony' as harmony-*;
7@forward 'props' as props-*;
8@forward 'responsive' as responsive-*; 8@forward 'responsive' as responsive-*;
9@forward 'vars' as vars-*; 9@forward 'harmony' as harmony-*;
diff --git a/src/_props.scss b/src/_props.scss
index 8d84aa1..17e9de7 100644
--- a/src/_props.scss
+++ b/src/_props.scss
@@ -1,423 +1,139 @@
1//// 1@use 'sass:list';
2/// Property trees.
3///
4/// Property trees allow you to organize properties in a tree structure (internally nested maps).
5/// The intended use is to store all your properties at the beginning and for the rest of the
6/// stylesheet you just get them.
7///
8/// @group Property trees
9///
10/// @access public
11////
12
13@use 'sass:map'; 2@use 'sass:map';
14@use './functions'; 3@use 'sass:meta';
15@use './contexts';
16
17///
18/// The maximum depth of resolved iro-prop-ref() references.
19///
20/// @type number
21///
22$native-assign-max-depth: 2 !default;
23
24///
25/// Indicate if property names must start with two dashes (--).
26/// This is required if property trees are also used for native CSS custom properties.
27///
28/// @type bool
29///
30$enforce-double-dashes: true !default;
31
32///
33/// Default tree name to use if no name is specified.
34///
35/// @type string
36///
37$default-tree: 'default' !default;
38
39///
40/// List of all created property trees.
41///
42/// @type list
43///
44/// @access private
45///
46$trees: ();
47
48///
49/// Default context name used for the namespace context.
50///
51/// @type string
52///
53$namespace-context-id: 'namespace' !default;
54
55///
56/// Declare a namespace, meaning that all variables declared and accessed.
57///
58/// @param {string} $name - Name of the namespace
59///
60@mixin namespace($name) {
61 $key: '--#{$name}';
62
63 $ns-key: get-ns-key();
64
65 @if $ns-key != null {
66 $key: append($ns-key, $key);
67 } @else {
68 $key: ($key);
69 }
70
71 @include contexts.push($namespace-context-id, 'namespace', (
72 'name': $name,
73 'key': $key
74 ));
75
76 @content;
77
78 @include contexts.pop($namespace-context-id);
79}
80 4
81/// 5@function is-prop-ref($value) {
82/// Get the current namespace name. 6 @if meta.type-of($value) != 'list' {
83/// 7 @return false;
84@function namespace() { 8 }
85 $noop: contexts.assert-stack-must-contain($namespace-context-id, 'namespace'); 9 @if list.length($value) != 4 {
86 10 @return false;
87 $data: nth(contexts.get($namespace-context-id, 'namespace'), 2); 11 }
88 $name: map-get($data, 'name'); 12 @if list.nth($value, 1) != 'prop-ref' {
89 13 @return false;
90 @return $name; 14 }
15 @return true;
91} 16}
92 17
93/// 18@function def($name, $value: (), $metadata: ()) {
94/// Save a property tree. If a tree with the sane name already exists, the trees 19 @return ('prop-ref' $name $value $metadata);
95/// will be merged.
96///
97/// @param {map} $map - Map containing properties
98/// @param {string} $tree [$default-tree] - ID the map is saved as
99/// @param {bool} $merge [true] - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted.
100///
101@mixin store($map, $tree: $default-tree, $merge: true, $global: false) {
102 $noop: store($map, $tree, $merge, $global);
103} 20}
104 21
105/// 22@function merge($ref, $value) {
106/// Save a property tree. 23 @if not is-prop-ref($ref) {
107/// 24 @return $ref;
108/// @param {map} $map - Map containing properties 25 }
109/// @param {string} $tree [$default-tree] - ID the map is saved as
110/// @param {bool} $merge [true] - If a tree named $tree already exists and this value is set to true, they will be merged. Otherwise an error will be emitted.
111///
112@function store($map, $tree: $default-tree, $merge: true, $global: false) {
113 $prop-map: null;
114
115 @if $enforce-double-dashes {
116 @if not validate($map) {
117 @error 'Property tree keys must start with two dashes (--). If you don\'t use property trees for native CSS custom properties, set $enforce-double-dashes to false.';
118 }
119 }
120
121 @if not $global {
122 $ns-key: get-ns-key();
123
124 @if $ns-key != null {
125 $map: ($ns-key: $map);
126 }
127 }
128
129 @if map-has-key($trees, $tree) {
130 @if $merge {
131 $map: map.deep-merge(map-get($trees, $tree), $map);
132 } @else {
133 @error 'Property tree #{inspect($tree)} does already exist.';
134 }
135 }
136
137 $trees: map-merge($trees, ($tree: $map)) !global;
138 26
139 @return null; 27 $v: list.nth($ref, 3);
28 $ref: list.set-nth($ref, 3, map.deep-merge($v, $value));
29 @return $ref;
140} 30}
141 31
142/// 32@function get-deep($name, $value, $key: null, $keys...) {
143/// Delete a property tree. 33 @if is-prop-ref($value) {
144/// 34 @return get($value, $key, $keys);
145/// @param {string} $tree [$default-tree] - ID of the tree to be deleted 35 }
146/// 36 @if meta.type-of($value) == 'map' and $key != null {
147@mixin clear($tree: $default-tree) { 37 @if meta.type-of($key) != 'string' {
148 $noop: clear($tree); 38 @error 'Expected string, got #{$key}';
39 }
40 @return get-deep(#{$name}#{$key}, map.get($value, $key), $keys...);
41 }
42 @return $name $value;
149} 43}
150 44
151/// 45@function map-to-vars($name, $map) {
152/// Delete a property tree. 46 @if meta.type-of($map) != 'map' {
153/// 47 @if meta.type-of($name) != 'string' {
154/// @param {string} $tree [$default-tree] - ID of the tree to be deleted 48 @error 'Expected variable name, got #{$name} instead';
155/// 49 }
156/// @throw If the property tree does not exist 50 @return var($name);
157/// 51 }
158@function clear($tree: $default-tree) {
159 @if not map-has-key($trees, $tree) {
160 @error 'Property tree "#{inspect($tree)}" does not exist.';
161 }
162
163 $trees: map-remove($trees, $tree) !global;
164
165 @return null;
166}
167
168///
169/// Access a whole property or a subsection (i.e. value) of it.
170///
171/// @param {string | list} $key [null] - Key of the property to read. If this is a list of keys, the map will be traversed in that order.
172/// @param {string} $tree [$default-tree] - ID of the property tree to use
173/// @param {any} $default [null] - Default value to return of no match was found. If null, this function will throw an error instead.
174///
175/// @return {any} Value assigned to property or $default
176///
177/// @throw If there was no match for $key and $default is null
178///
179@function get-static($key: (), $tree: $default-tree, $default: null, $global: false) {
180 @if not map-has-key($trees, $tree) {
181 @error 'Unknown tree "#{$tree}".';
182 }
183
184 $result: map-get($trees, $tree);
185
186 @if not $global {
187 $ns-key: get-ns-key();
188 52
189 @if $ns-key != null { 53 $out: ();
190 $orig-key: $key;
191 $key: $ns-key;
192 54
193 @if type-of($orig-key) == list { 55 @each $key, $value in $map {
194 @each $subkey in $orig-key { 56 $out: map.set($out, $key, map-to-vars(#{$name}#{$key}, $value));
195 $key: append($key, $subkey); 57 }
196 }
197 } @else {
198 $key: append($key, $orig-key);
199 }
200 }
201 }
202 58
203 @if type-of($key) == list { 59 @return $out;
204 $stop: false;
205
206 @each $k in $key {
207 @if not $stop and map-has-key($result, $k) {
208 $result: map-get($result, $k);
209
210 @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' {
211 @if length($result) == 2 {
212 $result: get-static($tree: nth($result, 2), $global: true);
213 } @else {
214 $result: get-static(nth($result, 3), nth($result, 2), $global: true);
215 }
216 }
217 } @else {
218 $stop: true;
219 }
220 }
221
222 @if $stop {
223 $result: null;
224 }
225 } @else {
226 $result: map-get($result, $key);
227
228 @if type-of($result) == list and nth($result, 1) == 'iro-prop-ref' {
229 @if length($result) == 2 {
230 $result: get-static($tree: nth($result, 2), $global: true);
231 } @else {
232 $result: get-static(nth($result, 3), nth($result, 2), $global: true);
233 }
234 }
235 }
236
237 @if $result == null {
238 @if $default == null {
239 @error '"#{$key}" is null.';
240 } @else {
241 @return $default;
242 }
243 }
244
245 @return $result;
246} 60}
247 61
248/// 62@function get($ref, $key: null, $keys...) {
249/// Generate a var() function call to get native CSS custom property. 63 @if not is-prop-ref($ref) {
250/// 64 @return $ref;
251/// @param {string | list} $key - Key of the property to read. If this is a list of keys, the map will be traversed in that order. 65 }
252/// @param {string | null} $tree [null] - Optional tree to check if the property actually exists.
253/// @param {any} $default [null] - Default value to return of no match was found.
254///
255/// @return {string} var()
256///
257@function get($key, $tree: $default-tree, $default: null, $global: false) {
258 @if $tree != null {
259 $noop: get-static($key, $tree, $default, $global);
260 }
261
262 @if not $global {
263 $ns-key: get-ns-key();
264 66
265 @if $ns-key != null { 67 $name: list.nth($ref, 2);
266 $orig-key: $key; 68 $value: get(list.nth($ref, 3));
267 $key: $ns-key;
268 69
269 @if type-of($orig-key) == list { 70 @if meta.type-of($value) == 'map' {
270 @each $subkey in $orig-key { 71 $res: get-deep($name, $value, $key, $keys...);
271 $key: append($key, $subkey); 72 $name: list.nth($res, 1);
272 } 73 $value: list.nth($res, 2);
273 } @else { 74 } @else if meta.type-of($value) == 'list' {
274 $key: append($key, $orig-key); 75 $i: 1;
275 } 76 @each $item in $value {
276 } 77 $value: list.set-nth($value, $i, get($item));
277 } 78 $i: $i + 1;
79 }
80 }
278 81
279 $native-var: ''; 82 @return map-to-vars($name, $value);
280
281 @if type-of($key) == list {
282 @each $subkey in $key {
283 $native-var: $native-var + $subkey;
284 }
285 } @else {
286 $native-var: $key;
287 }
288
289 @if $default == null {
290 @return var(#{$native-var});
291 } @else {
292 @return var(#{$native-var}, #{$default});
293 }
294} 83}
295 84
296/// 85@mixin materialize-helper($name, $value) {
297/// Generate assignments for native CSS custom properties with the values from the specified tree. 86 @if meta.type-of($value) == 'map' {
298/// 87 @each $key, $value in $value {
299/// @param {string} $tree [$default-tree] - ID of the property tree to use 88 @include materialize-helper(#{$name}#{$key}, $value);
300/// @param {string} $root [()] - Sub-tree to use for assignment 89 }
301/// 90 } @else {
302@mixin assign($tree: $default-tree, $root: (), $skip: (), $prefix: '', $global: false) { 91 #{$name}: #{$value};
303 $map: get-static($root, $tree, $global: $global); 92 }
304 $map: map-remove($map, $skip...);
305
306 @if type-of($prefix) == list {
307 $prefix: functions.str-implode($prefix);
308 }
309
310 @if not $global {
311 $ns-key: get-ns-key();
312
313 @if $ns-key != null {
314 $prefix: $prefix + functions.str-implode($ns-key);
315 }
316 }
317
318 @include assign-internal($map, $prefix);
319} 93}
320 94
321/// 95@mixin materialize($ref, $match-meta: ()) {
322/// @access private 96 @if is-prop-ref($ref) {
323/// 97 $name: list.nth($ref, 2);
324@mixin assign-internal($map, $prefix: '', $ref-depth: $native-assign-max-depth) { 98 $value: get(list.nth($ref, 3));
325 @each $key, $value in $map { 99 $meta: get(list.nth($ref, 4));
326 $rd: $ref-depth;
327 @if type-of($value) == list and length($value) > 0 and nth($value, 1) == 'iro-prop-ref' {
328 @if $ref-depth != 0 {
329 $rd: $rd - 1;
330 @if length($value) == 2 {
331 $value: get-static($tree: nth($value, 2));
332 } @else {
333 $value: get-static(nth($value, 3), nth($value, 2));
334 }
335 } @else {
336 $value: null;
337 }
338 }
339 @if type-of($value) != map and $value != () {
340 #{$prefix + $key}: #{$value};
341 } @else {
342 @include assign-internal($value, $prefix + $key, $rd);
343 }
344 }
345}
346
347///
348/// Validate property names.
349///
350/// @access private
351///
352@function validate($map) {
353 @each $key, $value in $map {
354 @if str-index($key, '--') != 1 {
355 @return false;
356 }
357
358 @if type-of($value) == map {
359 @if not validate($value) {
360 @return false;
361 }
362 }
363 }
364
365 @return true;
366}
367
368///
369/// Generate a reference to another tree. Dereferencing is lazy, so you may specify a tree that hasn't been created yet.
370///
371/// @param {string} $tree [$default-tree] - ID of the property tree to use
372/// @param {string | list} $key - Key of the property to read. If this is a list of keys, the map will be traversed in that order.
373///
374/// @return {list} A special list that let's Ignis know that this is a lazy value.
375///
376/// @throw If there was no match for $key and $default is null
377///
378@function ref($tree: $default-tree, $key: null, $global: false) {
379 @if not $global {
380 $ns-key: get-ns-key();
381 100
382 @if $ns-key != null { 101 $match: true;
383 $orig-key: $key; 102 @if meta.type-of($match-meta) == 'list' {
384 $key: $ns-key; 103 @each $item in $match-meta {
104 $match: $match and list.index($meta, $item) != null;
105 }
106 } @else if $match-meta == null and list.length($meta) == 0 {
107 $match: true;
108 } @else {
109 $match: list.index($meta, $match-meta) != null;
110 }
385 111
386 @if $orig-key != null { 112 @if $match {
387 @if type-of($orig-key) == list { 113 @include materialize-helper($name, $value);
388 @each $subkey in $orig-key { 114 }
389 $key: append($key, $subkey); 115 } @else if meta.type-of($ref) == 'list' {
390 } 116 @each $r in $ref {
391 } @else { 117 @if is-prop-ref($r) {
392 $key: append($key, $orig-key); 118 $name: list.nth($r, 2);
393 } 119 $value: get(list.nth($r, 3));
394 } 120 $meta: get(list.nth($r, 4));
395 }
396 }
397 121
398 @if $key == null { 122 $match: true;
399 @return ('iro-prop-ref' $tree); 123 @if meta.type-of($match-meta) == 'list' {
400 } @else { 124 @each $item in $match-meta {
401 @return ('iro-prop-ref' $tree $key); 125 $match: $match and list.index($meta, $item) != null;
402 } 126 }
127 } @else if $match-meta == null and list.length($meta) == 0 {
128 $match: true;
129 } @else {
130 $match: list.index($meta, $match-meta) != null;
131 }
132
133 @if $match {
134 @include materialize-helper($name, $value);
135 }
136 }
137 }
138 }
403} 139}
404
405///
406/// Get the current namespace key.
407///
408/// @access private
409///
410@function get-ns-key() {
411 $ctx: contexts.get($namespace-context-id, 'namespace');
412
413 @if $ctx == null {
414 @return null;
415 }
416
417 $data: nth($ctx, 2);
418 $key: map-get($data, 'key');
419
420 @return $key;
421}
422
423@include contexts.create($namespace-context-id);
diff --git a/src/_responsive.scss b/src/_responsive.scss
index 4d98638..f613a6d 100644
--- a/src/_responsive.scss
+++ b/src/_responsive.scss
@@ -17,6 +17,11 @@
17/// @access public 17/// @access public
18//// 18////
19 19
20@use 'sass:list';
21@use 'sass:map';
22@use 'sass:math';
23@use 'sass:meta';
24@use 'sass:string';
20@use './functions'; 25@use './functions';
21@use './contexts'; 26@use './contexts';
22 27
@@ -99,15 +104,15 @@ $named-viewports: () !default;
99/// } 104/// }
100/// 105///
101@mixin property($props, $responsive-map, $fluid: true, $vertical: false) { 106@mixin property($props, $responsive-map, $fluid: true, $vertical: false) {
102 @include env(map-keys($responsive-map), $fluid, $vertical) { 107 @include env(map.keys($responsive-map), $fluid, $vertical) {
103 @if type-of($props) == list { 108 @if meta.type-of($props) == list {
104 @each $prop in $props { 109 @each $prop in $props {
105 #{$prop}: set(map-values($responsive-map)); 110 #{$prop}: set(map.values($responsive-map));
106 } 111 }
107 } @else { 112 } @else {
108 #{$props}: set(map-values($responsive-map)); 113 #{$props}: set(map.values($responsive-map));
109 } 114 }
110 } 115 }
111} 116}
112 117
113/// 118///
@@ -150,153 +155,153 @@ $named-viewports: () !default;
150/// } 155/// }
151/// 156///
152@mixin env($viewports, $fluid: true, $vertical: false) { 157@mixin env($viewports, $fluid: true, $vertical: false) {
153 @if length($viewports) <= 1 { 158 @if list.length($viewports) <= 1 {
154 @error '$viewports must contain at least two viewports.'; 159 @error '$viewports must contain at least two viewports.';
155 } 160 }
156 161
157 $new-viewports: (); 162 $new-viewports: ();
158 163
159 @each $viewport in $viewports { 164 @each $viewport in $viewports {
160 @if map-has-key($named-viewports, $viewport) { 165 @if map.has-key($named-viewports, $viewport) {
161 $viewport: map-get($named-viewports, $viewport); 166 $viewport: map.get($named-viewports, $viewport);
162 } 167 }
163 168
164 @if (type-of($viewport) != number) or unitless($viewport) { 169 @if (meta.type-of($viewport) != number) or math.is-unitless($viewport) {
165 @error '$viewports contains invalid viewports.'; 170 @error '$viewports contains invalid viewports.';
166 } 171 }
167 172
168 $new-viewports: append($new-viewports, $viewport); 173 $new-viewports: list.append($new-viewports, $viewport);
169 } 174 }
170 175
171 $viewports: functions.quicksort($new-viewports); 176 $viewports: functions.quicksort($new-viewports);
172 177
173 @if $new-viewports != $viewports { 178 @if $new-viewports != $viewports {
174 @error '$viewports was not sorted in ascending order.'; 179 @error '$viewports was not sorted in ascending order.';
175 } 180 }
176 181
177 @if $fluid { 182 @if $fluid {
178 $first-vp: nth($viewports, 1); 183 $first-vp: list.nth($viewports, 1);
179 $last-vp: nth($viewports, length($viewports)); 184 $last-vp: list.nth($viewports, list.length($viewports));
180 185
181 @include contexts.push($context-id, 'env', ( 186 @include contexts.push($context-id, 'env', (
182 'viewports': $viewports, 187 'viewports': $viewports,
183 'mode': set, 188 'mode': set,
184 'index': 1, 189 'index': 1,
185 'fluid': $fluid, 190 'fluid': $fluid,
186 'vertical': $vertical, 191 'vertical': $vertical,
187 )); 192 ));
188 193
189 @content; 194 @content;
190 195
191 @include contexts.pop($context-id); 196 @include contexts.pop($context-id);
192 197
193 @for $i from 1 to length($viewports) { 198 @for $i from 1 to list.length($viewports) {
194 $prev-vp: nth($viewports, $i); 199 $prev-vp: list.nth($viewports, $i);
195 $next-vp: nth($viewports, $i + 1); 200 $next-vp: list.nth($viewports, $i + 1);
196 201
197 @if not $vertical { 202 @if not $vertical {
198 @media (min-width: $prev-vp) and (max-width: $next-vp) { 203 @media (min-width: $prev-vp) and (max-width: $next-vp) {
199 @include contexts.push($context-id, 'env', ( 204 @include contexts.push($context-id, 'env', (
200 'viewports': $viewports, 205 'viewports': $viewports,
201 'mode': transition, 206 'mode': transition,
202 'index': $i, 207 'index': $i,
203 'fluid': $fluid, 208 'fluid': $fluid,
204 'vertical': $vertical, 209 'vertical': $vertical,
205 )); 210 ));
206 211
207 @content; 212 @content;
208 213
209 @include contexts.pop($context-id); 214 @include contexts.pop($context-id);
210 } 215 }
211 } @else { 216 } @else {
212 @media (min-height: $prev-vp) and (max-height: $next-vp) { 217 @media (min-height: $prev-vp) and (max-height: $next-vp) {
213 @include contexts.push($context-id, 'env', ( 218 @include contexts.push($context-id, 'env', (
214 'viewports': $viewports, 219 'viewports': $viewports,
215 'mode': transition, 220 'mode': transition,
216 'index': $i, 221 'index': $i,
217 'fluid': $fluid, 222 'fluid': $fluid,
218 'vertical': $vertical, 223 'vertical': $vertical,
219 )); 224 ));
220 225
221 @content; 226 @content;
222 227
223 @include contexts.pop($context-id); 228 @include contexts.pop($context-id);
224 } 229 }
225 } 230 }
226 } 231 }
227 232
228 @if not $vertical { 233 @if not $vertical {
229 @media (min-width: $last-vp) { 234 @media (min-width: $last-vp) {
230 @include contexts.push($context-id, 'env', ( 235 @include contexts.push($context-id, 'env', (
231 'viewports': $viewports, 236 'viewports': $viewports,
232 'mode': set, 237 'mode': set,
233 'index': length($viewports), 238 'index': list.length($viewports),
234 'fluid': $fluid, 239 'fluid': $fluid,
235 'vertical': $vertical, 240 'vertical': $vertical,
236 )); 241 ));
237 242
238 @content; 243 @content;
239 244
240 @include contexts.pop($context-id); 245 @include contexts.pop($context-id);
241 } 246 }
242 } @else { 247 } @else {
243 @media (min-height: $last-vp) { 248 @media (min-height: $last-vp) {
244 @include contexts.push($context-id, 'env', ( 249 @include contexts.push($context-id, 'env', (
245 'viewports': $viewports, 250 'viewports': $viewports,
246 'mode': set, 251 'mode': set,
247 'index': length($viewports), 252 'index': list.length($viewports),
248 'fluid': $fluid, 253 'fluid': $fluid,
249 'vertical': $vertical, 254 'vertical': $vertical,
250 )); 255 ));
251 256
252 @content; 257 @content;
253 258
254 @include contexts.pop($context-id); 259 @include contexts.pop($context-id);
255 } 260 }
256 } 261 }
257 } @else { 262 } @else {
258 @include contexts.push($context-id, 'env', ( 263 @include contexts.push($context-id, 'env', (
259 'viewports': $viewports, 264 'viewports': $viewports,
260 'mode': set, 265 'mode': set,
261 'index': 1, 266 'index': 1,
262 'fluid': $fluid, 267 'fluid': $fluid,
263 'vertical': $vertical, 268 'vertical': $vertical,
264 )); 269 ));
265 270
266 @content; 271 @content;
267 272
268 @include contexts.pop($context-id); 273 @include contexts.pop($context-id);
269 274
270 @for $i from 2 through length($viewports) { 275 @for $i from 2 through list.length($viewports) {
271 $vp: nth($viewports, $i); 276 $vp: list.nth($viewports, $i);
272 277
273 @if not $vertical { 278 @if not $vertical {
274 @media (min-width: $vp) { 279 @media (min-width: $vp) {
275 @include contexts.push($context-id, 'env', ( 280 @include contexts.push($context-id, 'env', (
276 'viewports': $viewports, 281 'viewports': $viewports,
277 'mode': set, 282 'mode': set,
278 'index': $i 283 'index': $i
279 )); 284 ));
280 285
281 @content; 286 @content;
282 287
283 @include contexts.pop($context-id); 288 @include contexts.pop($context-id);
284 } 289 }
285 } @else { 290 } @else {
286 @media (min-height: $vp) { 291 @media (min-height: $vp) {
287 @include contexts.push($context-id, 'env', ( 292 @include contexts.push($context-id, 'env', (
288 'viewports': $viewports, 293 'viewports': $viewports,
289 'mode': set, 294 'mode': set,
290 'index': $i 295 'index': $i
291 )); 296 ));
292 297
293 @content; 298 @content;
294 299
295 @include contexts.pop($context-id); 300 @include contexts.pop($context-id);
296 } 301 }
297 } 302 }
298 } 303 }
299 } 304 }
300} 305}
301 306
302/// 307///
@@ -307,29 +312,29 @@ $named-viewports: () !default;
307/// @return {number|string} 312/// @return {number|string}
308/// 313///
309@function set($values, $without-calc: false) { 314@function set($values, $without-calc: false) {
310 $noop: contexts.assert-stack-must-contain($context-id, 'env'); 315 $noop: contexts.assert-stack-must-contain($context-id, 'env');
311 316
312 $data: nth(contexts.get($context-id, 'env'), 2); 317 $data: list.nth(contexts.get($context-id, 'env'), 2);
313 $viewports: map-get($data, 'viewports'); 318 $viewports: map.get($data, 'viewports');
314 $mode: map-get($data, 'mode'); 319 $mode: map.get($data, 'mode');
315 $fluid: map-get($data, 'fluid'); 320 $fluid: map.get($data, 'fluid');
316 $vertical: map-get($data, 'vertical'); 321 $vertical: map.get($data, 'vertical');
317 322
318 @if length($values) != length($viewports) { 323 @if list.length($values) != list.length($viewports) {
319 @error '$values must contain the same number of items as the responsive environment\'s $viewports.'; 324 @error '$values must contain the same number of items as the responsive environment\'s $viewports.';
320 } 325 }
321 326
322 @if $mode == set { 327 @if $mode == set {
323 @return nth($values, map-get($data, 'index')); 328 @return list.nth($values, map.get($data, 'index'));
324 } @else { 329 } @else {
325 $index: map-get($data, 'index'); 330 $index: map.get($data, 'index');
326 $prev-vp: nth($viewports, $index); 331 $prev-vp: list.nth($viewports, $index);
327 $next-vp: nth($viewports, $index + 1); 332 $next-vp: list.nth($viewports, $index + 1);
328 $prev-value: nth($values, $index); 333 $prev-value: list.nth($values, $index);
329 $next-value: nth($values, $index + 1); 334 $next-value: list.nth($values, $index + 1);
330 335
331 @return fluid-calc($prev-value, $next-value, $prev-vp, $next-vp, $vertical, $without-calc); 336 @return fluid-calc($prev-value, $next-value, $prev-vp, $next-vp, $vertical, $without-calc);
332 } 337 }
333} 338}
334 339
335/// 340///
@@ -345,62 +350,62 @@ $named-viewports: () !default;
345/// @access private 350/// @access private
346/// 351///
347@function fluid-calc($min-value, $max-value, $min-viewport, $max-viewport, $vertical: false, $without-calc: false) { 352@function fluid-calc($min-value, $max-value, $min-viewport, $max-viewport, $vertical: false, $without-calc: false) {
348 $value-unit: unit($min-value); 353 $value-unit: math.unit($min-value);
349 $max-value-unit: unit($max-value); 354 $max-value-unit: math.unit($max-value);
350 $viewport-unit: unit($min-viewport); 355 $viewport-unit: math.unit($min-viewport);
351 $max-viewport-unit: unit($max-viewport); 356 $max-viewport-unit: math.unit($max-viewport);
352 357
353 @if $min-value == 0 { 358 @if $min-value == 0 {
354 $value-unit: $max-value-unit; 359 $value-unit: $max-value-unit;
355 } 360 }
356 @if $max-value == 0 { 361 @if $max-value == 0 {
357 $max-value-unit: $value-unit; 362 $max-value-unit: $value-unit;
358 } 363 }
359 @if $min-viewport == 0 { 364 @if $min-viewport == 0 {
360 $viewport-unit: $max-viewport-unit; 365 $viewport-unit: $max-viewport-unit;
361 } 366 }
362 @if $max-viewport == 0 { 367 @if $max-viewport == 0 {
363 $max-viewport-unit: $viewport-unit; 368 $max-viewport-unit: $viewport-unit;
364 } 369 }
365 370
366 @if ($value-unit != $max-value-unit) or ($viewport-unit != $max-viewport-unit) { 371 @if ($value-unit != $max-value-unit) or ($viewport-unit != $max-viewport-unit) {
367 @error 'Units of $min-value and $max-value, $min-viewport and $max-viewport must match.'; 372 @error 'Units of $min-value and $max-value, $min-viewport and $max-viewport must match.';
368 } 373 }
369 374
370 @if ($value-unit == rem) and ($viewport-unit == px) { 375 @if ($value-unit == rem) and ($viewport-unit == px) {
371 $min-viewport: functions.px-to-rem($min-viewport); 376 $min-viewport: functions.px-to-rem($min-viewport);
372 $max-viewport: functions.px-to-rem($max-viewport); 377 $max-viewport: functions.px-to-rem($max-viewport);
373 $viewport-unit: rem; 378 $viewport-unit: rem;
374 } @else if ($value-unit == px) and ($viewport-unit == rem) { 379 } @else if ($value-unit == px) and ($viewport-unit == rem) {
375 $min-value: functions.px-to-rem($min-value); 380 $min-value: functions.px-to-rem($min-value);
376 $max-value: functions.px-to-rem($max-value); 381 $max-value: functions.px-to-rem($max-value);
377 $value-unit: rem; 382 $value-unit: rem;
378 } 383 }
379 384
380 @if $value-unit != $viewport-unit { 385 @if $value-unit != $viewport-unit {
381 @error 'This combination of units is not supported.'; 386 @error 'This combination of units is not supported.';
382 } 387 }
383 388
384 $value-diff: functions.strip-unit($max-value - $min-value); 389 $value-diff: functions.strip-unit($max-value - $min-value);
385 $viewport-diff: functions.strip-unit($max-viewport - $min-viewport); 390 $viewport-diff: functions.strip-unit($max-viewport - $min-viewport);
386 391
387 $calc: ''; 392 $calc: '';
388 393
389 @if $min-value != 0 { 394 @if $min-value != 0 {
390 $calc: '#{$min-value} + '; 395 $calc: '#{$min-value} + ';
391 } 396 }
392 397
393 @if not $vertical { 398 @if not $vertical {
394 $calc: unquote('#{$calc}#{$value-diff} * (100vw - #{$min-viewport}) / #{$viewport-diff}'); 399 $calc: string.unquote('#{$calc}#{$value-diff} * (100vw - #{$min-viewport}) / #{$viewport-diff}');
395 } @else { 400 } @else {
396 $calc: unquote('#{$calc}#{$value-diff} * (100vh - #{$min-viewport}) / #{$viewport-diff}'); 401 $calc: string.unquote('#{$calc}#{$value-diff} * (100vh - #{$min-viewport}) / #{$viewport-diff}');
397 } 402 }
398 403
399 @if $without-calc { 404 @if $without-calc {
400 @return $calc; 405 @return $calc;
401 } @else { 406 } @else {
402 @return calc(#{$calc}); 407 @return calc(#{$calc});
403 } 408 }
404} 409}
405 410
406@include contexts.create($context-id); 411@include contexts.create($context-id);
diff --git a/src/bem/_block.scss b/src/bem/_block.scss
index 49af04b..a4b2a47 100644
--- a/src/bem/_block.scss
+++ b/src/bem/_block.scss
@@ -4,6 +4,10 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:meta';
10@use 'sass:selector';
7@use './validators'; 11@use './validators';
8@use './vars'; 12@use './vars';
9@use './functions' as bemfunctions; 13@use './functions' as bemfunctions;
@@ -37,28 +41,34 @@
37/// } 41/// }
38/// 42///
39@mixin block($name, $type: null) { 43@mixin block($name, $type: null) {
40 $result: block($name, $type); 44 $result: block($name, $type);
41 $selector: nth($result, 1); 45 $selector: list.nth($result, 1);
42 $context: nth($result, 2); 46 $context: list.nth($result, 2);
43 47
44 @include validators.validate( 48 @include validators.validate(
45 'block', 49 'block',
46 (name: $name, type: $type), 50 (name: $name, type: $type),
47 $selector, 51 $selector,
48 $context 52 $context
49 ); 53 );
50 54
51 @if $type != null { 55 @if $type != null {
52 vars.$blocks: append(vars.$blocks, $name + '_' + $type); 56 vars.$blocks: list.append(vars.$blocks, $name + '_' + $type);
53 } @else { 57 } @else {
54 vars.$blocks: append(vars.$blocks, $name); 58 vars.$blocks: list.append(vars.$blocks, $name);
55 } 59 }
56 60
57 @include contexts.push(vars.$context-id, $context...); 61 @include contexts.push(vars.$context-id, $context...);
58 @at-root #{$selector} { 62 @at-root #{$selector} {
59 @content; 63 @if $type != null {
60 } 64 @layer #{$type} {
61 @include contexts.pop(vars.$context-id); 65 @content;
66 }
67 } @else {
68 @content;
69 }
70 }
71 @include contexts.pop(vars.$context-id);
62} 72}
63 73
64/// 74///
@@ -69,47 +79,47 @@
69/// @see {mixin} block 79/// @see {mixin} block
70/// 80///
71@function block($name, $type: null) { 81@function block($name, $type: null) {
72 // 82 //
73 // Possible outcomes: 83 // Possible outcomes:
74 // - ({b,e,m,s}) block 84 // - ({b,e,m,s}) block
75 // 85 //
76 86
77 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 87 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
78 88
79 $selector: null; 89 $selector: null;
80 $base-selector: null; 90 $base-selector: null;
81 91
82 @if $type != null { 92 @if $type != null {
83 $namespace: map-get(vars.$namespaces, $type); 93 $namespace: map.get(vars.$namespaces, $type);
84 94
85 @if not $namespace { 95 @if not $namespace {
86 @error '"#{$type}" is not a valid type.'; 96 @error '"#{$type}" is not a valid type.';
87 } 97 }
88 98
89 $base-selector: selector-parse('.' + $namespace + '-' + $name); 99 $base-selector: selector.parse('.' + $namespace + '-' + $name);
90 100
91 @if $type != 'theme' or & { 101 @if $type != 'theme' or & {
92 $selector: $base-selector; 102 $selector: $base-selector;
93 } @else if not & { 103 } @else if not & {
94 $selector: bemfunctions.theme-selector($name); 104 $selector: bemfunctions.theme-selector($name);
95 } 105 }
96 } @else { 106 } @else {
97 $base-selector: selector-parse('.' + $name); 107 $base-selector: selector.parse('.' + $name);
98 $selector: $base-selector; 108 $selector: $base-selector;
99 } 109 }
100 110
101 @if & { 111 @if & {
102 $selector: selector-nest(&, $selector); 112 $selector: selector.nest(&, $selector);
103 } 113 }
104 114
105 $context: 'block', ( 115 $context: 'block', (
106 'name': $name, 116 'name': $name,
107 'type': $type, 117 'type': $type,
108 'selector': $selector, 118 'selector': $selector,
109 'base-selector': $base-selector 119 'base-selector': $base-selector
110 ); 120 );
111 121
112 @return $selector $context; 122 @return $selector $context;
113} 123}
114 124
115/// 125///
@@ -120,9 +130,9 @@
120/// @content 130/// @content
121/// 131///
122@mixin object($name) { 132@mixin object($name) {
123 @include block($name, 'object') { 133 @include block($name, 'object') {
124 @content; 134 @content;
125 } 135 }
126} 136}
127 137
128/// 138///
@@ -133,7 +143,7 @@
133/// @see {mixin} object 143/// @see {mixin} object
134/// 144///
135@function object($name) { 145@function object($name) {
136 @return block($name, 'object'); 146 @return block($name, 'object');
137} 147}
138 148
139/// 149///
@@ -144,9 +154,9 @@
144/// @content 154/// @content
145/// 155///
146@mixin component($name) { 156@mixin component($name) {
147 @include block($name, 'component') { 157 @include block($name, 'component') {
148 @content; 158 @content;
149 } 159 }
150} 160}
151 161
152/// 162///
@@ -157,7 +167,7 @@
157/// @see {mixin} component 167/// @see {mixin} component
158/// 168///
159@function component($name) { 169@function component($name) {
160 @return block($name, 'component'); 170 @return block($name, 'component');
161} 171}
162 172
163/// 173///
@@ -168,9 +178,9 @@
168/// @content 178/// @content
169/// 179///
170@mixin layout($name) { 180@mixin layout($name) {
171 @include block($name, 'layout') { 181 @include block($name, 'layout') {
172 @content; 182 @content;
173 } 183 }
174} 184}
175 185
176/// 186///
@@ -181,7 +191,7 @@
181/// @see {mixin} layout 191/// @see {mixin} layout
182/// 192///
183@function layout($name) { 193@function layout($name) {
184 @return block($name, 'layout'); 194 @return block($name, 'layout');
185} 195}
186 196
187/// 197///
@@ -192,9 +202,9 @@
192/// @content 202/// @content
193/// 203///
194@mixin utility($name) { 204@mixin utility($name) {
195 @include block($name, 'utility') { 205 @include block($name, 'utility') {
196 @content; 206 @content;
197 } 207 }
198} 208}
199 209
200/// 210///
@@ -205,7 +215,7 @@
205/// @see {mixin} utility 215/// @see {mixin} utility
206/// 216///
207@function utility($name) { 217@function utility($name) {
208 @return block($name, 'utility'); 218 @return block($name, 'utility');
209} 219}
210 220
211/// 221///
@@ -216,9 +226,9 @@
216/// @content 226/// @content
217/// 227///
218@mixin scope($name) { 228@mixin scope($name) {
219 @include block($name, 'scope') { 229 @include block($name, 'scope') {
220 @content; 230 @content;
221 } 231 }
222} 232}
223 233
224/// 234///
@@ -229,7 +239,7 @@
229/// @see {mixin} scope 239/// @see {mixin} scope
230/// 240///
231@function scope($name) { 241@function scope($name) {
232 @return block($name, 'scope'); 242 @return block($name, 'scope');
233} 243}
234 244
235/// 245///
@@ -240,9 +250,9 @@
240/// @content 250/// @content
241/// 251///
242@mixin theme($name) { 252@mixin theme($name) {
243 @include block($name, 'theme') { 253 @include block($name, 'theme') {
244 @content; 254 @content;
245 } 255 }
246} 256}
247 257
248/// 258///
@@ -253,7 +263,7 @@
253/// @see {mixin} theme 263/// @see {mixin} theme
254/// 264///
255@function theme($name) { 265@function theme($name) {
256 @return block($name, 'theme'); 266 @return block($name, 'theme');
257} 267}
258 268
259/// 269///
@@ -264,9 +274,9 @@
264/// @content 274/// @content
265/// 275///
266@mixin js($name) { 276@mixin js($name) {
267 @include block($name, 'js') { 277 @include block($name, 'js') {
268 @content; 278 @content;
269 } 279 }
270} 280}
271 281
272/// 282///
@@ -277,7 +287,7 @@
277/// @see {mixin} js 287/// @see {mixin} js
278/// 288///
279@function js($name) { 289@function js($name) {
280 @return block($name, 'js'); 290 @return block($name, 'js');
281} 291}
282 292
283/// 293///
@@ -288,9 +298,9 @@
288/// @content 298/// @content
289/// 299///
290@mixin qa($name) { 300@mixin qa($name) {
291 @include block($name, 'qa') { 301 @include block($name, 'qa') {
292 @content; 302 @content;
293 } 303 }
294} 304}
295 305
296/// 306///
@@ -301,7 +311,7 @@
301/// @see {mixin} qa 311/// @see {mixin} qa
302/// 312///
303@function qa($name) { 313@function qa($name) {
304 @return block($name, 'qa'); 314 @return block($name, 'qa');
305} 315}
306 316
307/// 317///
@@ -312,9 +322,9 @@
312/// @content 322/// @content
313/// 323///
314@mixin hack($name) { 324@mixin hack($name) {
315 @include block($name, 'hack') { 325 @include block($name, 'hack') {
316 @content; 326 @content;
317 } 327 }
318} 328}
319 329
320/// 330///
@@ -325,7 +335,7 @@
325/// @see {mixin} hack 335/// @see {mixin} hack
326/// 336///
327@function hack($name) { 337@function hack($name) {
328 @return block($name, 'hack'); 338 @return block($name, 'hack');
329} 339}
330 340
331/// 341///
@@ -377,22 +387,22 @@
377/// // Compilation will fail because c-someBlock is defined after c-anotherBlock__elem 387/// // Compilation will fail because c-someBlock is defined after c-anotherBlock__elem
378/// 388///
379@mixin composed-of($block, $blocks...) { 389@mixin composed-of($block, $blocks...) {
380 @each $block in functions.list-prepend($blocks, $block) { 390 @each $block in functions.list-prepend($blocks, $block) {
381 @if type-of($block) == string { 391 @if meta.type-of($block) == string {
382 @if not index(vars.$blocks, $block) { 392 @if not list.index(vars.$blocks, $block) {
383 @error 'Block "#{$block}" does not exist.'; 393 @error 'Block "#{$block}" does not exist.';
384 } 394 }
385 } @else { 395 } @else {
386 $name: nth($block, 1); 396 $name: list.nth($block, 1);
387 $type: nth($block, 2); 397 $type: list.nth($block, 2);
388 398
389 @if not map-get(vars.$namespaces, $type) { 399 @if not map.get(vars.$namespaces, $type) {
390 @error '"#{$type}" is not a valid type.'; 400 @error '"#{$type}" is not a valid type.';
391 } 401 }
392 402
393 @if not index(vars.$blocks, $name + '_' + $type) { 403 @if not list.index(vars.$blocks, $name + '_' + $type) {
394 @error 'Block "#{$name}" does not exist.'; 404 @error 'Block "#{$name}" does not exist.';
395 } 405 }
396 } 406 }
397 } 407 }
398} 408}
diff --git a/src/bem/_debug.scss b/src/bem/_debug.scss
index 8ea0f05..b1f20a7 100644
--- a/src/bem/_debug.scss
+++ b/src/bem/_debug.scss
@@ -4,15 +4,16 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:map';
7@use './vars'; 8@use './vars';
8 9
9@if vars.$debug { 10@if vars.$debug {
10 @each $type, $color in vars.$debug-colors { 11 @each $type, $color in vars.$debug-colors {
11 $namespace: map-get(vars.$namespaces, $type); 12 $namespace: map.get(vars.$namespaces, $type);
12 13
13 [class^='#{$namespace}-'], 14 [class^='#{$namespace}-'],
14 [class*=' #{$namespace}-'] { 15 [class*=' #{$namespace}-'] {
15 outline: 5px solid $color; 16 outline: 5px solid $color;
16 } 17 }
17 } 18 }
18} 19}
diff --git a/src/bem/_element.scss b/src/bem/_element.scss
index 64862b0..9f108fe 100644
--- a/src/bem/_element.scss
+++ b/src/bem/_element.scss
@@ -4,6 +4,11 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:meta';
10@use 'sass:selector';
11@use 'sass:string';
7@use './validators'; 12@use './validators';
8@use './vars'; 13@use './vars';
9@use '../functions'; 14@use '../functions';
@@ -92,22 +97,22 @@
92/// } 97/// }
93/// 98///
94@mixin elem($name, $names...) { 99@mixin elem($name, $names...) {
95 $result: elem($name, $names...); 100 $result: elem($name, $names...);
96 $selector: nth($result, 1); 101 $selector: list.nth($result, 1);
97 $context: nth($result, 2); 102 $context: list.nth($result, 2);
98 103
99 @include validators.validate( 104 @include validators.validate(
100 'element', 105 'element',
101 (name: $name, names: $names), 106 (name: $name, names: $names),
102 $selector, 107 $selector,
103 $context 108 $context
104 ); 109 );
105 110
106 @include contexts.push(vars.$context-id, $context...); 111 @include contexts.push(vars.$context-id, $context...);
107 @at-root #{$selector} { 112 @at-root #{$selector} {
108 @content; 113 @content;
109 } 114 }
110 @include contexts.pop(vars.$context-id); 115 @include contexts.pop(vars.$context-id);
111} 116}
112 117
113/// 118///
@@ -118,99 +123,93 @@
118/// @see {mixin} element 123/// @see {mixin} element
119/// 124///
120@function elem($name, $names...) { 125@function elem($name, $names...) {
121 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 126 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
122 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block'); 127 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block');
123 128
124 $parent-context: contexts.get(vars.$context-id, 'block' 'element'); 129 $parent-context: contexts.get(vars.$context-id, 'block' 'element');
125 130
126 $selector: (); 131 $selector: ();
127 $parts-data: (); 132 $parts-data: ();
128 133
129 @if nth($parent-context, 1) == 'element' { 134 @if list.nth($parent-context, 1) == 'element' {
130 @if vars.$element-nesting-policy == 'disallow' { 135 @if vars.$element-nesting-policy == 'disallow' {
131 @error 'Element nesting is forbidden.'; 136 @error 'Element nesting is forbidden.';
132 } 137 }
133 138
134 @if vars.$element-nesting-policy == 'append' { 139 @if vars.$element-nesting-policy == 'append' {
135 $element-selector: map-get(nth($parent-context, 2), 'selector'); 140 $element-selector: map.get(list.nth($parent-context, 2), 'selector');
136 141
137 @if not functions.selector-suffix-match(&, $element-selector) { 142 @if not functions.selector-suffix-match(&, $element-selector) {
138 @error 'A nested element must be an immediate children of the parent element.'; 143 @error 'A nested element must be an immediate children of the parent element.';
139 } 144 }
140 145
141 // 146 //
142 // Possible outcomes: 147 // Possible outcomes:
143 // - {e}__element 148 // - {e}__element
144 // - [manual selector] {e}__element 149 // - [manual selector] {e}__element
145 // 150 //
146 151
147 @each $name in join($name, $names) { 152 @each $name in list.join($name, $names) {
148 $sel: selector-append(&, vars.$element-separator + $name); 153 $sel: selector.append(&, vars.$element-separator + $name);
149 $selector: join($selector, $sel, comma); 154 $selector: list.join($selector, $sel, comma);
150 $parts-data: append( 155 $parts-data: list.append($parts-data, (
151 $parts-data, ( 156 'name': $name,
152 'name': $name, 157 'selector': $sel
153 'selector': $sel 158 ));
154 ) 159 }
155 ); 160 }
156 }
157 }
158 161
159 $parent-context: contexts.get(vars.$context-id, 'block'); 162 $parent-context: contexts.get(vars.$context-id, 'block');
160 } 163 }
161 164
162 @if length($selector) == 0 { 165 @if list.length($selector) == 0 {
163 $parent-selector: map-get(nth($parent-context, 2), 'selector'); 166 $parent-selector: map.get(list.nth($parent-context, 2), 'selector');
164 167
165 @if functions.selector-suffix-match(&, $parent-selector) { 168 @if functions.selector-suffix-match(&, $parent-selector) {
166 // 169 //
167 // Possible outcomes: 170 // Possible outcomes:
168 // - {b}__element 171 // - {b}__element
169 // - [manual selector] {b}__element 172 // - [manual selector] {b}__element
170 // 173 //
171 174
172 @each $name in join($name, $names) { 175 @each $name in list.join($name, $names) {
173 $sel: selector-append(&, vars.$element-separator + $name); 176 $sel: selector.append(&, vars.$element-separator + $name);
174 $selector: join($selector, $sel, comma); 177 $selector: list.join($selector, $sel, comma);
175 $parts-data: append( 178 $parts-data: list.append($parts-data, (
176 $parts-data, ( 179 'name': $name,
177 'name': $name, 180 'selector': $sel
178 'selector': $sel 181 ));
179 ) 182 }
180 ); 183 } @else {
181 } 184 //
182 } @else { 185 // Possible outcomes:
183 // 186 // - {b} [manual selector] {b}__element
184 // Possible outcomes: 187 // - {e,m,s} ([manual selector]) {b}__element
185 // - {b} [manual selector] {b}__element 188 //
186 // - {e,m,s} ([manual selector]) {b}__element
187 //
188 189
189 @if nth($parent-context, 1) != 'block' { 190 @if list.nth($parent-context, 1) != 'block' {
190 $parent-context: contexts.get(vars.$context-id, 'block'); 191 $parent-context: contexts.get(vars.$context-id, 'block');
191 } 192 }
192 193
193 $block-base-selector: map-get(nth($parent-context, 2), 'base-selector'); 194 $block-base-selector: map.get(list.nth($parent-context, 2), 'base-selector');
194 195
195 @each $name in join($name, $names) { 196 @each $name in list.join($name, $names) {
196 $sel: selector-nest(&, selector-append($block-base-selector, vars.$element-separator + $name)); 197 $sel: selector.nest(&, selector.append($block-base-selector, vars.$element-separator + $name));
197 $selector: join($selector, $sel, comma); 198 $selector: list.join($selector, $sel, comma);
198 $parts-data: append( 199 $parts-data: list.append($parts-data, (
199 $parts-data, ( 200 'name': $name,
200 'name': $name, 201 'selector': $sel
201 'selector': $sel 202 ));
202 ) 203 }
203 ); 204 }
204 } 205 }
205 }
206 }
207 206
208 $context: 'element', ( 207 $context: 'element', (
209 'parts': $parts-data, 208 'parts': $parts-data,
210 'selector': $selector 209 'selector': $selector
211 ); 210 );
212 211
213 @return $selector $context; 212 @return $selector $context;
214} 213}
215 214
216/// 215///
@@ -291,22 +290,22 @@
291/// } 290/// }
292/// 291///
293@mixin related-elem($sign, $name, $names...) { 292@mixin related-elem($sign, $name, $names...) {
294 $result: related-elem($sign, $name, $names...); 293 $result: related-elem($sign, $name, $names...);
295 $selector: nth($result, 1); 294 $selector: list.nth($result, 1);
296 $context: nth($result, 2); 295 $context: list.nth($result, 2);
297 296
298 @include validators.validate( 297 @include validators.validate(
299 'related-element', 298 'related-element',
300 (sign: $sign, name: $name, names: $names), 299 (sign: $sign, name: $name, names: $names),
301 $selector, 300 $selector,
302 $context 301 $context
303 ); 302 );
304 303
305 @include contexts.push(vars.$context-id, $context...); 304 @include contexts.push(vars.$context-id, $context...);
306 @at-root #{$selector} { 305 @at-root #{$selector} {
307 @content; 306 @content;
308 } 307 }
309 @include contexts.pop(vars.$context-id); 308 @include contexts.pop(vars.$context-id);
310} 309}
311 310
312/// 311///
@@ -318,44 +317,42 @@
318/// @see {mixin} related-element 317/// @see {mixin} related-element
319/// 318///
320@function related-elem($sign, $name, $names...) { 319@function related-elem($sign, $name, $names...) {
321 // 320 //
322 // Generating this selector is simple: Take the latest block context, use it 321 // Generating this selector is simple: Take the latest block context, use it
323 // to generate the element part, and insert it at the end of the current selector. 322 // to generate the element part, and insert it at the end of the current selector.
324 // Possible outcomes: 323 // Possible outcomes:
325 // - {e} ({m,s}) ([manual selector]) + {e} 324 // - {e} ({m,s}) ([manual selector]) + {e}
326 // - {e} ({m,s}) ([manual selector]) ~ {e} 325 // - {e} ({m,s}) ([manual selector]) ~ {e}
327 // 326 //
328 327
329 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 328 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
330 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'element'); 329 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'element');
331 330
332 @if $sign != '+' and $sign != '~' { 331 @if $sign != '+' and $sign != '~' {
333 @error 'Invalid relationship sign #{inspect($sign)}.'; 332 @error 'Invalid relationship sign #{inspect($sign)}.';
334 } 333 }
335 334
336 $block-context: contexts.get(vars.$context-id, 'block'); 335 $block-context: contexts.get(vars.$context-id, 'block');
337 $block-base-selector: map-get(nth($block-context, 2), 'base-selector'); 336 $block-base-selector: map.get(list.nth($block-context, 2), 'base-selector');
338 337
339 $selector: (); 338 $selector: ();
340 $parts-data: (); 339 $parts-data: ();
341 340
342 @each $name in join($name, $names) { 341 @each $name in list.join($name, $names) {
343 $sel: selector-nest(&, $sign, selector-append($block-base-selector, vars.$element-separator + $name)); 342 $sel: selector.nest(&, $sign, selector.append($block-base-selector, vars.$element-separator + $name));
344 $selector: join($selector, $sel, comma); 343 $selector: list.join($selector, $sel, comma);
345 $parts-data: append( 344 $parts-data: list.append($parts-data, (
346 $parts-data, ( 345 'name': $name,
347 'name': $name, 346 'selector': $sel
348 'selector': $sel 347 ));
349 ) 348 }
350 );
351 }
352 349
353 $context: 'element', ( 350 $context: 'element', (
354 'parts': $parts-data, 351 'parts': $parts-data,
355 'selector': $selector 352 'selector': $selector
356 ); 353 );
357 354
358 @return $selector $context; 355 @return $selector $context;
359} 356}
360 357
361/// 358///
@@ -369,9 +366,9 @@
369/// @content 366/// @content
370/// 367///
371@mixin sibling-elem($name, $names...) { 368@mixin sibling-elem($name, $names...) {
372 @include related-elem('~', $name, $names...) { 369 @include related-elem('~', $name, $names...) {
373 @content; 370 @content;
374 } 371 }
375} 372}
376 373
377/// 374///
@@ -383,7 +380,7 @@
383/// @see {mixin} sibling-element 380/// @see {mixin} sibling-element
384/// 381///
385@function sibling-elem($name, $names...) { 382@function sibling-elem($name, $names...) {
386 @return related-elem('~', $name, $names...); 383 @return related-elem('~', $name, $names...);
387} 384}
388 385
389/// 386///
@@ -397,9 +394,9 @@
397/// @content 394/// @content
398/// 395///
399@mixin next-elem($name, $names...) { 396@mixin next-elem($name, $names...) {
400 @include related-elem('+', $name, $names...) { 397 @include related-elem('+', $name, $names...) {
401 @content; 398 @content;
402 } 399 }
403} 400}
404 401
405/// 402///
@@ -411,7 +408,7 @@
411/// @see {mixin} next-element 408/// @see {mixin} next-element
412/// 409///
413@function next-elem($name, $names...) { 410@function next-elem($name, $names...) {
414 @return related-elem('+', $name, $names...); 411 @return related-elem('+', $name, $names...);
415} 412}
416 413
417/// 414///
@@ -467,22 +464,22 @@
467/// } 464/// }
468/// 465///
469@mixin related-twin-elem($sign) { 466@mixin related-twin-elem($sign) {
470 $result: related-twin-elem($sign); 467 $result: related-twin-elem($sign);
471 $selector: nth($result, 1); 468 $selector: list.nth($result, 1);
472 $context: nth($result, 2); 469 $context: list.nth($result, 2);
473 470
474 @include validators.validate( 471 @include validators.validate(
475 'next-twin-elem', 472 'next-twin-elem',
476 (), 473 (),
477 $selector, 474 $selector,
478 $context 475 $context
479 ); 476 );
480 477
481 @include contexts.push(vars.$context-id, $context...); 478 @include contexts.push(vars.$context-id, $context...);
482 @at-root #{$selector} { 479 @at-root #{$selector} {
483 @content; 480 @content;
484 } 481 }
485 @include contexts.pop(vars.$context-id); 482 @include contexts.pop(vars.$context-id);
486} 483}
487 484
488/// 485///
@@ -494,96 +491,94 @@
494/// @see {mixin} next-twin-elem 491/// @see {mixin} next-twin-elem
495/// 492///
496@function related-twin-elem($sign) { 493@function related-twin-elem($sign) {
497 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 494 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
498 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'element'); 495 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'element');
499 496
500 $element-context: contexts.get(vars.$context-id, 'element'); 497 $element-context: contexts.get(vars.$context-id, 'element');
501 $element-selector: map-get(nth($element-context, 2), 'selector'); 498 $element-selector: map.get(list.nth($element-context, 2), 'selector');
502 499
503 $block-context: contexts.get(vars.$context-id, 'block'); 500 $block-context: contexts.get(vars.$context-id, 'block');
504 $block-base-selector: map-get(nth($block-context, 2), 'base-selector'); 501 $block-base-selector: map.get(list.nth($block-context, 2), 'base-selector');
505 502
506 $selector: (); 503 $selector: ();
507 $parts-data: (); 504 $parts-data: ();
508 505
509 // 506 //
510 // To determine the twin for each element, iterate the sub-selectors from the current selector 507 // To determine the twin for each element, iterate the sub-selectors from the current selector
511 // and check if it contains the currently inspected element. This has to be done with string 508 // and check if it contains the currently inspected element. This has to be done with string
512 // comparison since none of Sass selector functions is of use here. 509 // comparison since none of Sass selector functions is of use here.
513 // Finally, the current twin will be appended to the extracted sub-selector as a successor 510 // Finally, the current twin will be appended to the extracted sub-selector as a successor
514 // element. 511 // element.
515 // 512 //
516 @each $part-data in map-get(nth($element-context, 2), 'parts') { 513 @each $part-data in map.get(list.nth($element-context, 2), 'parts') {
517 $part-selector: map-get($part-data, 'selector'); 514 $part-selector: map.get($part-data, 'selector');
518 $part-name: map-get($part-data, 'name'); 515 $part-name: map.get($part-data, 'name');
519 516
520 $sel: (); 517 $sel: ();
521 @if functions.selector-suffix-match(&, $element-selector) { 518 @if functions.selector-suffix-match(&, $element-selector) {
522 // 519 //
523 // This mixin is included in the selector the last element mixin created. 520 // This mixin is included in the selector the last element mixin created.
524 // Possible outcomes: 521 // Possible outcomes:
525 // - {e} + {e} 522 // - {e} + {e}
526 // - [manual selector] {e} + {e} 523 // - [manual selector] {e} + {e}
527 // 524 //
528 525
529 @each $s in & { 526 @each $s in & {
530 @each $ps in $part-selector { 527 @each $ps in $part-selector {
531 @if nth($s, -1) == nth($ps, -1) { 528 @if list.nth($s, -1) == list.nth($ps, -1) {
532 $sel-ent: selector-nest($s, $sign, selector-append($block-base-selector, vars.$element-separator + $part-name)); 529 $sel-ent: selector.nest($s, $sign, selector.append($block-base-selector, vars.$element-separator + $part-name));
533 $sel: join($sel, $sel-ent, comma); 530 $sel: list.join($sel, $sel-ent, comma);
534 } 531 }
535 } 532 }
536 } 533 }
537 } @else { 534 } @else {
538 // 535 //
539 // This mixin is NOT included in the selector the last element mixin created. 536 // This mixin is NOT included in the selector the last element mixin created.
540 // Possible outcomes: 537 // Possible outcomes:
541 // - {e} {m,s} + {e} 538 // - {e} {m,s} + {e}
542 // - {e} [manual selector] + {e} 539 // - {e} [manual selector] + {e}
543 // - {e} {m,s} [manual selector] + {e} 540 // - {e} {m,s} [manual selector] + {e}
544 // 541 //
545 542
546 @each $s in & { 543 @each $s in & {
547 @each $ps in $part-selector { 544 @each $ps in $part-selector {
548 @if str-index(inspect($s), inspect($ps)) { 545 @if string.index(meta.inspect($s), meta.inspect($ps)) {
549 $char-index: str-length(inspect($ps)) + 1; 546 $char-index: string.length(meta.inspect($ps)) + 1;
550 $match: index(' ' ':' ',', str-slice(inspect($s), $char-index, $char-index)) != null; 547 $match: list.index(' ' ':' ',', string.slice(meta.inspect($s), $char-index, $char-index)) != null;
551 548
552 @if not $match { 549 @if not $match {
553 @each $separator in vars.$element-separator vars.$modifier-separator vars.$suffix-separator { 550 @each $separator in vars.$element-separator vars.$modifier-separator vars.$suffix-separator {
554 @if str-slice(inspect($s), $char-index, $char-index + str-length($separator) - 1) == $separator { 551 @if string.slice(meta.inspect($s), $char-index, $char-index + string.length($separator) - 1) == $separator {
555 $match: true; 552 $match: true;
556 } 553 }
557 } 554 }
558 } 555 }
559 556
560 @if $match { 557 @if $match {
561 $sel-ent: selector-nest($s, '+', selector-append($block-base-selector, vars.$element-separator + $part-name)); 558 $sel-ent: selector.nest($s, '+', selector.append($block-base-selector, vars.$element-separator + $part-name));
562 $sel: join($sel, $sel-ent, comma); 559 $sel: list.join($sel, $sel-ent, comma);
563 } 560 }
564 } 561 }
565 } 562 }
566 } 563 }
567 } 564 }
568 @if length($sel) != length($part-selector) { 565 @if list.length($sel) != list.length($part-selector) {
569 @error 'Could not generate twin element selector.'; 566 @error 'Could not generate twin element selector.';
570 } 567 }
571 568
572 $selector: join($selector, $sel, comma); 569 $selector: list.join($selector, $sel, comma);
573 $parts-data: append( 570 $parts-data: list.append($parts-data, (
574 $parts-data, ( 571 'name': $part-name,
575 'name': $part-name, 572 'selector': $sel
576 'selector': $sel 573 ));
577 ) 574 }
578 );
579 }
580 575
581 $context: 'element', ( 576 $context: 'element', (
582 'parts': $parts-data, 577 'parts': $parts-data,
583 'selector': $selector 578 'selector': $selector
584 ); 579 );
585 580
586 @return $selector $context; 581 @return $selector $context;
587} 582}
588 583
589/// 584///
@@ -594,9 +589,9 @@
594/// @content 589/// @content
595/// 590///
596@mixin sibling-twin-element { 591@mixin sibling-twin-element {
597 @include related-twin-elem('~') { 592 @include related-twin-elem('~') {
598 @content; 593 @content;
599 } 594 }
600} 595}
601 596
602/// 597///
@@ -608,7 +603,7 @@
608/// @see {mixin} sibling-twin-element 603/// @see {mixin} sibling-twin-element
609/// 604///
610@function sibling-twin-elem() { 605@function sibling-twin-elem() {
611 @return related-twin-elem('~'); 606 @return related-twin-elem('~');
612} 607}
613 608
614/// 609///
@@ -619,9 +614,9 @@
619/// @content 614/// @content
620/// 615///
621@mixin next-twin-elem { 616@mixin next-twin-elem {
622 @include related-twin-elem('+') { 617 @include related-twin-elem('+') {
623 @content; 618 @content;
624 } 619 }
625} 620}
626 621
627/// 622///
@@ -633,5 +628,5 @@
633/// @see {mixin} next-twin-elem 628/// @see {mixin} next-twin-elem
634/// 629///
635@function next-twin-elem() { 630@function next-twin-elem() {
636 @return related-twin-elem('+'); 631 @return related-twin-elem('+');
637} 632}
diff --git a/src/bem/_functions.scss b/src/bem/_functions.scss
index b7bd5ec..7f52b93 100644
--- a/src/bem/_functions.scss
+++ b/src/bem/_functions.scss
@@ -4,25 +4,28 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:selector';
7@use './vars'; 10@use './vars';
8 11
9/// 12///
10/// @access private 13/// @access private
11/// 14///
12@function theme-selector($name, $names...) { 15@function theme-selector($name, $names...) {
13 $namespace: map-get(vars.$namespaces, 'theme'); 16 $namespace: map.get(vars.$namespaces, 'theme');
14 $selector: null; 17 $selector: null;
15 18
16 @each $name in join($name, $names) { 19 @each $name in list.join($name, $names) {
17 $sel: '.' + $namespace + '-' + $name; 20 $sel: '.' + $namespace + '-' + $name;
18 21
19 @if $selector == null { 22 @if $selector == null {
20 $selector: join(selector-parse($sel), selector-parse('[class*=\' t-\'] ' + $sel), comma); 23 $selector: list.join(selector.parse($sel), selector.parse('[class*=\' t-\'] ' + $sel), comma);
21 $selector: join($selector, selector-parse('[class^=\'t-\'] ' + $sel), comma); 24 $selector: list.join($selector, selector.parse('[class^=\'t-\'] ' + $sel), comma);
22 } @else { 25 } @else {
23 $selector: selector-nest($selector, $sel); 26 $selector: selector.nest($selector, $sel);
24 } 27 }
25 } 28 }
26 29
27 @return $selector; 30 @return $selector;
28} 31}
diff --git a/src/bem/_modifier.scss b/src/bem/_modifier.scss
index 07267fe..10e2826 100644
--- a/src/bem/_modifier.scss
+++ b/src/bem/_modifier.scss
@@ -4,6 +4,11 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:meta';
10@use 'sass:selector';
11@use 'sass:string';
7@use './validators'; 12@use './validators';
8@use './vars'; 13@use './vars';
9@use '../functions'; 14@use '../functions';
@@ -111,22 +116,22 @@
111/// } 116/// }
112/// 117///
113@mixin modifier($name, $names...) { 118@mixin modifier($name, $names...) {
114 $result: modifier($name, $names...); 119 $result: modifier($name, $names...);
115 $selector: nth($result, 1); 120 $selector: list.nth($result, 1);
116 $context: nth($result, 2); 121 $context: list.nth($result, 2);
117 122
118 @include validators.validate( 123 @include validators.validate(
119 'modifier', 124 'modifier',
120 (name: $name, names: $names), 125 (name: $name, names: $names),
121 $selector, 126 $selector,
122 $context 127 $context
123 ); 128 );
124 129
125 @include contexts.push(vars.$context-id, $context...); 130 @include contexts.push(vars.$context-id, $context...);
126 @at-root #{$selector} { 131 @at-root #{$selector} {
127 @content; 132 @content;
128 } 133 }
129 @include contexts.pop(vars.$context-id); 134 @include contexts.pop(vars.$context-id);
130} 135}
131 136
132/// 137///
@@ -137,121 +142,115 @@
137/// @see {mixin} modifier 142/// @see {mixin} modifier
138/// 143///
139@function modifier($name, $names...) { 144@function modifier($name, $names...) {
140 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 145 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
141 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block'); 146 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block');
142 147
143 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier' 'suffix' 'state'); 148 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier' 'suffix' 'state');
144 $parent-selector: map-get(nth($parent-context, 2), 'selector'); 149 $parent-selector: map.get(list.nth($parent-context, 2), 'selector');
145 $selector: (); 150 $selector: ();
146 $parts-data: (); 151 $parts-data: ();
147 152
148 @if not functions.selector-suffix-match(&, $parent-selector) { 153 @if not functions.selector-suffix-match(&, $parent-selector) {
149 // 154 //
150 // The current selector doesn't match the parent selector. 155 // The current selector doesn't match the parent selector.
151 // The user manually added a selector between parent context and this modifier call. 156 // The user manually added a selector between parent context and this modifier call.
152 // This case is forbidden because any outcome semantically wouldn't make sense: 157 // This case is forbidden because any outcome semantically wouldn't make sense:
153 // - {b,e,m,s} [manual selector] {b,e,m,s}--modifier 158 // - {b,e,m,s} [manual selector] {b,e,m,s}--modifier
154 // - {b,e,m,s}--modifier [manual selector] 159 // - {b,e,m,s}--modifier [manual selector]
155 // The first case would make the modifier behave like an element. 160 // The first case would make the modifier behave like an element.
156 // The second case is unintuitive, the code would be more clear by nesting the manual 161 // The second case is unintuitive, the code would be more clear by nesting the manual
157 // selector in the modifier instead. 162 // selector in the modifier instead.
158 // 163 //
159 164
160 @error 'A modifier must be an immediate child of the parent context'; 165 @error 'A modifier must be an immediate child of the parent context';
161 } 166 }
162 167
163 @each $name in functions.list-prepend($names, $name) { 168 @each $name in functions.list-prepend($names, $name) {
164 $extend: false; 169 $extend: false;
165 @if type-of($name) == list { 170 @if meta.type-of($name) == list {
166 $extend: nth($name, 2); 171 $extend: list.nth($name, 2);
167 $name: nth($name, 1); 172 $name: list.nth($name, 1);
168 } 173 }
169 174
170 @if index('block' 'element', nth($parent-context, 1)) or $extend == true { 175 @if list.index('block' 'element', list.nth($parent-context, 1)) or $extend == true {
171 // 176 //
172 // Either the parent context is block or element, or a modifier or suffix 177 // Either the parent context is block or element, or a modifier or suffix
173 // is to be extended. The modifier part can simply be appended. 178 // is to be extended. The modifier part can simply be appended.
174 // Possible outcomes: 179 // Possible outcomes:
175 // - {b,e,m,s}--modifier 180 // - {b,e,m,s}--modifier
176 // 181 //
177 182
178 $sel: selector-append(&, vars.$modifier-separator + $name); 183 $sel: selector.append(&, vars.$modifier-separator + $name);
179 $selector: join($selector, $sel, comma); 184 $selector: list.join($selector, $sel, comma);
180 $parts-data: append( 185 $parts-data: list.append($parts-data, (
181 $parts-data, ( 186 'name': $name,
182 'name': $name, 187 'selector': $sel
183 'selector': $sel 188 ));
184 ) 189 } @else {
185 ); 190 //
186 } @else { 191 // Parent context is modifier, suffix or state and $extend is false.
187 // 192 //
188 // Parent context is modifier, suffix or state and $extend is false.
189 //
190 193
191 $be-context: contexts.get(vars.$context-id, 'block' 'element'); 194 $be-context: contexts.get(vars.$context-id, 'block' 'element');
192 195
193 @if nth($be-context, 1) == 'element' { 196 @if list.nth($be-context, 1) == 'element' {
194 // 197 //
195 // Latest context is element. Since element contexts can consist of multiple single 198 // Latest context is element. Since element contexts can consist of multiple single
196 // elements, inspect all elements and append its selector with the suffix "--$name". 199 // elements, inspect all elements and append its selector with the suffix "--$name".
197 // This has to be done with string comparison since none of Sass selector functions 200 // This has to be done with string comparison since none of Sass selector functions
198 // is of use here. 201 // is of use here.
199 // Possible outcomes: 202 // Possible outcomes:
200 // - {m,s}.{e}--modifier 203 // - {m,s}.{e}--modifier
201 // 204 //
202 205
203 $nsel: (); 206 $nsel: ();
204 207
205 @each $elem-part-data in map-get(nth($be-context, 2), 'parts') { 208 @each $elem-part-data in map.get(list.nth($be-context, 2), 'parts') {
206 $elem-part-selector: map-get($elem-part-data, 'selector'); 209 $elem-part-selector: map.get($elem-part-data, 'selector');
207 210
208 $sel: (); 211 $sel: ();
209 @each $s in & { 212 @each $s in & {
210 @each $ps in $elem-part-selector { 213 @each $ps in $elem-part-selector {
211 @if str-index(inspect($s), inspect($ps) + vars.$modifier-separator) or str-index(inspect($s), inspect($ps) + vars.$suffix-separator) { 214 @if string.index(meta.inspect($s), meta.inspect($ps) + vars.$modifier-separator) or string.index(meta.inspect($s), meta.inspect($ps) + vars.$suffix-separator) {
212 $sel: join($sel, selector-unify($s, selector-append($ps, vars.$modifier-separator + $name)), comma); 215 $sel: list.join($sel, selector.unify($s, selector.append($ps, vars.$modifier-separator + $name)), comma);
213 } 216 }
214 } 217 }
215 } 218 }
216 @if length($sel) == 0 { 219 @if list.length($sel) == 0 {
217 @error 'Could not generate modifier selector.'; 220 @error 'Could not generate modifier selector.';
218 } 221 }
219 222
220 $nsel: join($nsel, $sel, comma); 223 $nsel: list.join($nsel, $sel, comma);
221 } 224 }
222 225
223 $selector: join($selector, $nsel, comma); 226 $selector: list.join($selector, $nsel, comma);
224 $parts-data: append( 227 $parts-data: list.append($parts-data, (
225 $parts-data, ( 228 'name': $name,
226 'name': $name, 229 'selector': $nsel
227 'selector': $nsel 230 ));
228 ) 231 } @else {
229 ); 232 //
230 } @else { 233 // Latest context is block. Just append the modifier part.
231 // 234 // Possible outcomes:
232 // Latest context is block. Just append the modifier part. 235 // - {m,s}.{b}--modifier
233 // Possible outcomes: 236 //
234 // - {m,s}.{b}--modifier
235 //
236 237
237 $block-base-selector: map-get(nth($be-context, 2), 'base-selector'); 238 $block-base-selector: map.get(list.nth($be-context, 2), 'base-selector');
238 239
239 $sel: selector-append(&, $block-base-selector, vars.$modifier-separator + $name); 240 $sel: selector.append(&, $block-base-selector, vars.$modifier-separator + $name);
240 $selector: join($selector, $sel, comma); 241 $selector: list.join($selector, $sel, comma);
241 $parts-data: append( 242 $parts-data: list.append($parts-data, (
242 $parts-data, ( 243 'name': $name,
243 'name': $name, 244 'selector': $sel
244 'selector': $sel 245 ));
245 ) 246 }
246 ); 247 }
247 } 248 }
248 }
249 }
250 249
251 $context: 'modifier', ( 250 $context: 'modifier', (
252 'parts': $parts-data, 251 'parts': $parts-data,
253 'selector': $selector 252 'selector': $selector
254 ); 253 );
255 254
256 @return $selector $context; 255 @return $selector $context;
257} 256}
diff --git a/src/bem/_multi.scss b/src/bem/_multi.scss
index 1de5cdc..c0beeeb 100644
--- a/src/bem/_multi.scss
+++ b/src/bem/_multi.scss
@@ -4,6 +4,10 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:meta';
9@use 'sass:selector';
10@use 'sass:string';
7@use '../functions'; 11@use '../functions';
8@use '../contexts'; 12@use '../contexts';
9@use './block'; 13@use './block';
@@ -81,67 +85,67 @@
81/// } 85/// }
82/// 86///
83@mixin multi($first, $others...) { 87@mixin multi($first, $others...) {
84 @include contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 88 @include contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
85 89
86 @each $entity in functions.list-prepend($others, $first) { 90 @each $entity in functions.list-prepend($others, $first) {
87 $is-manual-selector: false; 91 $is-manual-selector: false;
88 92
89 @if type-of($entity) == string { 93 @if meta.type-of($entity) == string {
90 @if find-bem-function($entity) == null { 94 @if find-bem-function($entity) == null {
91 $is-manual-selector: true; 95 $is-manual-selector: true;
92 } 96 }
93 } 97 }
94 98
95 @if $is-manual-selector { 99 @if $is-manual-selector {
96 $sel: if(&, selector-nest(&, $entity), selector-parse($entity)); 100 $sel: if(&, selector.nest(&, $entity), selector.parse($entity));
97 101
98 @at-root #{$sel} { 102 @at-root #{$sel} {
99 @content; 103 @content;
100 } 104 }
101 } @else { 105 } @else {
102 $entity-func-id: null; 106 $entity-func-id: null;
103 107
104 @if type-of($entity) == list { 108 @if meta.type-of($entity) == list {
105 $entity-func-id: nth($entity, 1); 109 $entity-func-id: list.nth($entity, 1);
106 $entity: functions.list-slice($entity, 2); 110 $entity: functions.list-slice($entity, 2);
107 } @else { 111 } @else {
108 $entity-func-id: $entity; 112 $entity-func-id: $entity;
109 $entity: (); 113 $entity: ();
110 } 114 }
111 115
112 @if str-slice($entity-func-id, str-length($entity-func-id)) == ':' { 116 @if string.slice($entity-func-id, string.length($entity-func-id)) == ':' {
113 $entity-func-id: unquote(str-slice($entity-func-id, 1, str-length($entity-func-id) - 1)); 117 $entity-func-id: string.unquote(string.slice($entity-func-id, 1, string.length($entity-func-id) - 1));
114 } 118 }
115 119
116 $sel-func: find-bem-function($entity-func-id); 120 $sel-func: find-bem-function($entity-func-id);
117 121
118 @if $sel-func == null { 122 @if $sel-func == null {
119 @error 'Function "#{inspect($entity-func-id)}" was not found.'; 123 @error 'Function "#{inspect($entity-func-id)}" was not found.';
120 } 124 }
121 125
122 $entity-result: call($sel-func, $entity...); 126 $entity-result: meta.call($sel-func, $entity...);
123 $entity-result-selector: nth($entity-result, 1); 127 $entity-result-selector: list.nth($entity-result, 1);
124 $entity-result-context: nth($entity-result, 2); 128 $entity-result-context: list.nth($entity-result, 2);
125 129
126 @if $entity-result-context != null { 130 @if $entity-result-context != null {
127 @include contexts.push(vars.$context-id, $entity-result-context...); 131 @include contexts.push(vars.$context-id, $entity-result-context...);
128 } 132 }
129 @at-root #{$entity-result-selector} { 133 @at-root #{$entity-result-selector} {
130 @content; 134 @content;
131 } 135 }
132 @if $entity-result-context != null { 136 @if $entity-result-context != null {
133 @include contexts.pop(vars.$context-id); 137 @include contexts.pop(vars.$context-id);
134 } 138 }
135 } 139 }
136 } 140 }
137} 141}
138 142
139@function find-bem-function($name) { 143@function find-bem-function($name) {
140 @each $module in (block element modifier state suffix theme) { 144 @each $module in (block element modifier state suffix theme) {
141 @if function-exists($name, $module) { 145 @if meta.function-exists($name, $module) {
142 @return get-function($name, $module: $module); 146 @return meta.get-function($name, $module: $module);
143 } 147 }
144 } 148 }
145 149
146 @return null; 150 @return null;
147} 151}
diff --git a/src/bem/_state.scss b/src/bem/_state.scss
index 41bacee..bd0efb1 100644
--- a/src/bem/_state.scss
+++ b/src/bem/_state.scss
@@ -4,6 +4,8 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:selector';
7@use './validators'; 9@use './validators';
8@use './vars'; 10@use './vars';
9@use '../contexts'; 11@use '../contexts';
@@ -56,22 +58,22 @@
56/// } 58/// }
57/// 59///
58@mixin state($prefix, $state, $states...) { 60@mixin state($prefix, $state, $states...) {
59 $result: state($prefix, $state, $states...); 61 $result: state($prefix, $state, $states...);
60 $selector: nth($result, 1); 62 $selector: list.nth($result, 1);
61 $context: nth($result, 2); 63 $context: list.nth($result, 2);
62 64
63 @include validators.validate( 65 @include validators.validate(
64 'state', 66 'state',
65 (prefix: $prefix, state: $state, states: $states), 67 (prefix: $prefix, state: $state, states: $states),
66 $selector, 68 $selector,
67 $context 69 $context
68 ); 70 );
69 71
70 @include contexts.push(vars.$context-id, $context...); 72 @include contexts.push(vars.$context-id, $context...);
71 @at-root #{$selector} { 73 @at-root #{$selector} {
72 @content; 74 @content;
73 } 75 }
74 @include contexts.pop(vars.$context-id); 76 @include contexts.pop(vars.$context-id);
75} 77}
76 78
77/// 79///
@@ -82,29 +84,27 @@
82/// @see {mixin} has 84/// @see {mixin} has
83/// 85///
84@function state($prefix, $state, $states...) { 86@function state($prefix, $state, $states...) {
85 $selector: (); 87 $selector: ();
86 $parts-data: (); 88 $parts-data: ();
87 89
88 @each $state in join($state, $states) { 90 @each $state in list.join($state, $states) {
89 $sel: selector-parse('.#{$prefix}-#{$state}'); 91 $sel: selector.parse('.#{$prefix}-#{$state}');
90 @if & { 92 @if & {
91 $sel: selector-append(&, $sel); 93 $sel: selector.append(&, $sel);
92 } 94 }
93 $selector: join($selector, $sel, comma); 95 $selector: list.join($selector, $sel, comma);
94 $parts-data: append( 96 $parts-data: list.append($parts-data, (
95 $parts-data, ( 97 'name': $state,
96 'name': $state, 98 'selector': $sel
97 'selector': $sel 99 ));
98 ) 100 }
99 );
100 }
101 101
102 $context: 'state', ( 102 $context: 'state', (
103 'parts': $parts-data, 103 'parts': $parts-data,
104 'selector': $selector 104 'selector': $selector
105 ); 105 );
106 106
107 @return $selector $context; 107 @return $selector $context;
108} 108}
109 109
110/// 110///
@@ -113,9 +113,9 @@
113/// It's a shorthand for state('is', $state, $states...). 113/// It's a shorthand for state('is', $state, $states...).
114/// 114///
115@mixin is($state, $states...) { 115@mixin is($state, $states...) {
116 @include state('is', $state, $states...) { 116 @include state('is', $state, $states...) {
117 @content; 117 @content;
118 } 118 }
119} 119}
120 120
121/// 121///
@@ -126,7 +126,7 @@
126/// @see {mixin} is 126/// @see {mixin} is
127/// 127///
128@function is($state, $states...) { 128@function is($state, $states...) {
129 @return state('is', $state, $states...); 129 @return state('is', $state, $states...);
130} 130}
131 131
132/// 132///
@@ -135,9 +135,9 @@
135/// It's a shorthand for state('has', $state, $states...). 135/// It's a shorthand for state('has', $state, $states...).
136/// 136///
137@mixin has($state, $states...) { 137@mixin has($state, $states...) {
138 @include state('has', $state, $states...) { 138 @include state('has', $state, $states...) {
139 @content; 139 @content;
140 } 140 }
141} 141}
142 142
143/// 143///
@@ -148,5 +148,5 @@
148/// @see {mixin} has 148/// @see {mixin} has
149/// 149///
150@function has($state, $states...) { 150@function has($state, $states...) {
151 @return state('has', $state, $states...); 151 @return state('has', $state, $states...);
152} 152}
diff --git a/src/bem/_suffix.scss b/src/bem/_suffix.scss
index 2ddb54d..93e4066 100644
--- a/src/bem/_suffix.scss
+++ b/src/bem/_suffix.scss
@@ -4,6 +4,9 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:selector';
7@use './validators'; 10@use './validators';
8@use './vars'; 11@use './vars';
9@use '../functions'; 12@use '../functions';
@@ -54,22 +57,22 @@
54/// } 57/// }
55/// 58///
56@mixin suffix($name) { 59@mixin suffix($name) {
57 $result: suffix($name); 60 $result: suffix($name);
58 $selector: nth($result, 1); 61 $selector: list.nth($result, 1);
59 $context: nth($result, 2); 62 $context: list.nth($result, 2);
60 63
61 @include validators.validate( 64 @include validators.validate(
62 'suffix', 65 'suffix',
63 (name: $name), 66 (name: $name),
64 $selector, 67 $selector,
65 $context 68 $context
66 ); 69 );
67 70
68 @include contexts.push(vars.$context-id, $context...); 71 @include contexts.push(vars.$context-id, $context...);
69 @at-root #{$selector} { 72 @at-root #{$selector} {
70 @content; 73 @content;
71 } 74 }
72 @include contexts.pop(vars.$context-id); 75 @include contexts.pop(vars.$context-id);
73} 76}
74 77
75/// 78///
@@ -80,44 +83,44 @@
80/// @see {mixin} suffix 83/// @see {mixin} suffix
81/// 84///
82@function suffix($name) { 85@function suffix($name) {
83 // 86 //
84 // Suffixes can be used on block, element and modifier. 87 // Suffixes can be used on block, element and modifier.
85 // 88 //
86 89
87 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth); 90 $noop: contexts.assert-stack-count(vars.$context-id, vars.$max-depth);
88 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block'); 91 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block');
89 $noop: contexts.assert-stack-must-not-contain(vars.$context-id, 'suffix'); 92 $noop: contexts.assert-stack-must-not-contain(vars.$context-id, 'suffix');
90 93
91 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier'); 94 $parent-context: contexts.get(vars.$context-id, 'block' 'element' 'modifier');
92 $parent-selector: map-get(nth($parent-context, 2), 'selector'); 95 $parent-selector: map.get(list.nth($parent-context, 2), 'selector');
93 96
94 @if not functions.selector-suffix-match(&, $parent-selector) { 97 @if not functions.selector-suffix-match(&, $parent-selector) {
95 // 98 //
96 // The current selector doesn't match the parent selector. 99 // The current selector doesn't match the parent selector.
97 // The user manually added a selector between parent context and this suffix call. 100 // The user manually added a selector between parent context and this suffix call.
98 // This case is forbidden because any outcome semantically wouldn't make sense: 101 // This case is forbidden because any outcome semantically wouldn't make sense:
99 // - {b,e,m} [manual selector] {b,e,m}@suffix 102 // - {b,e,m} [manual selector] {b,e,m}@suffix
100 // - {b,e,m}@suffix [manual selector] 103 // - {b,e,m}@suffix [manual selector]
101 // The first case would make the modifier behave like an element. 104 // The first case would make the modifier behave like an element.
102 // The second case is unintuitive, the code would be more clear by nesting the manual 105 // The second case is unintuitive, the code would be more clear by nesting the manual
103 // selector in the suffix instead. 106 // selector in the suffix instead.
104 // 107 //
105 108
106 @error 'A suffix must be an immediate child of the parent context'; 109 @error 'A suffix must be an immediate child of the parent context';
107 } 110 }
108 111
109 // 112 //
110 // The suffix part can simply be appended. 113 // The suffix part can simply be appended.
111 // Possible outcomes: 114 // Possible outcomes:
112 // - {b,e,m}@suffix 115 // - {b,e,m}@suffix
113 // 116 //
114 117
115 $selector: selector-append(&, vars.$suffix-separator + $name); 118 $selector: selector.append(&, vars.$suffix-separator + $name);
116 119
117 $context: 'suffix', ( 120 $context: 'suffix', (
118 'name': $name, 121 'name': $name,
119 'selector': $selector 122 'selector': $selector
120 ); 123 );
121 124
122 @return $selector $context; 125 @return $selector $context;
123} 126}
diff --git a/src/bem/_theme.scss b/src/bem/_theme.scss
index ff1ba49..535cc81 100644
--- a/src/bem/_theme.scss
+++ b/src/bem/_theme.scss
@@ -4,6 +4,9 @@
4/// @access public 4/// @access public
5//// 5////
6 6
7@use 'sass:list';
8@use 'sass:map';
9@use 'sass:selector';
7@use './functions'; 10@use './functions';
8@use './validators'; 11@use './validators';
9@use './vars'; 12@use './vars';
@@ -18,22 +21,22 @@
18/// @content 21/// @content
19/// 22///
20@mixin at-theme($name, $names...) { 23@mixin at-theme($name, $names...) {
21 $result: at-theme($name, $names...); 24 $result: at-theme($name, $names...);
22 $selector: nth($result, 1); 25 $selector: list.nth($result, 1);
23 $context: nth($result, 2); 26 $context: list.nth($result, 2);
24 27
25 @include validators.validate( 28 @include validators.validate(
26 'at-theme', 29 'at-theme',
27 (name: $name, names: $names), 30 (name: $name, names: $names),
28 $selector, 31 $selector,
29 $context 32 $context
30 ); 33 );
31 34
32 @include contexts.push(vars.$context-id, $context...); 35 @include contexts.push(vars.$context-id, $context...);
33 @at-root #{$selector} { 36 @at-root #{$selector} {
34 @content; 37 @content;
35 } 38 }
36 @include contexts.pop(vars.$context-id); 39 @include contexts.pop(vars.$context-id);
37} 40}
38 41
39/// 42///
@@ -45,22 +48,22 @@
45/// @see {mixin} at-theme 48/// @see {mixin} at-theme
46/// 49///
47@function at-theme($name, $names...) { 50@function at-theme($name, $names...) {
48 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block'); 51 $noop: contexts.assert-stack-must-contain(vars.$context-id, 'block');
49 52
50 $parent-context: contexts.get(vars.$context-id, 'block'); 53 $parent-context: contexts.get(vars.$context-id, 'block');
51 $parent-selector: map-get(nth($parent-context, 2), 'selector'); 54 $parent-selector: map.get(list.nth($parent-context, 2), 'selector');
52 55
53 //@if not functions.selector-suffix-match(&, $parent-selector) { 56 //@if not functions.selector-suffix-match(&, $parent-selector) {
54 // @error 'An at-theme rule must be an immediate child of a block'; 57 // @error 'An at-theme rule must be an immediate child of a block';
55 //} 58 //}
56 59
57 $selector: functions.theme-selector($name, $names...); 60 $selector: functions.theme-selector($name, $names...);
58 $selector: selector-nest($selector, &); 61 $selector: selector.nest($selector, &);
59 62
60 $context: 'at-theme', ( 63 $context: 'at-theme', (
61 'name': join($name, $names), 64 'name': list.join($name, $names),
62 'selector': $selector 65 'selector': $selector
63 ); 66 );
64 67
65 @return $selector $context; 68 @return $selector $context;
66} 69}
diff --git a/src/bem/_validators.scss b/src/bem/_validators.scss
index 042e15e..bc3c9b7 100644
--- a/src/bem/_validators.scss
+++ b/src/bem/_validators.scss
@@ -16,6 +16,9 @@
16/// @access public 16/// @access public
17//// 17////
18 18
19@use 'sass:list';
20@use 'sass:map';
21@use 'sass:meta';
19@use './vars'; 22@use './vars';
20@use '../functions'; 23@use '../functions';
21@use '../contexts'; 24@use '../contexts';
@@ -46,7 +49,7 @@ $validators: ();
46/// @param {string} $func-names - Other function names. 49/// @param {string} $func-names - Other function names.
47/// 50///
48@mixin add($func-name, $func-names...) { 51@mixin add($func-name, $func-names...) {
49 $noop: add($func-name, $func-names...); 52 $noop: add($func-name, $func-names...);
50} 53}
51 54
52/// 55///
@@ -55,11 +58,11 @@ $validators: ();
55/// @see {mixin} add 58/// @see {mixin} add
56/// 59///
57@function add($func-name, $func-names...) { 60@function add($func-name, $func-names...) {
58 @each $fn-name in join($func-name, $func-names) { 61 @each $fn-name in list.join($func-name, $func-names) {
59 $fn: get-function($fn-name); 62 $fn: meta.get-function($fn-name);
60 $validators: map-merge($validators, ($fn-name: $fn)); 63 $validators: map.merge($validators, ($fn-name: $fn));
61 } 64 }
62 @return null; 65 @return null;
63} 66}
64 67
65/// 68///
@@ -69,7 +72,7 @@ $validators: ();
69/// @param {string} $func-names - Other function names. 72/// @param {string} $func-names - Other function names.
70/// 73///
71@mixin remove($func-name, $func-names...) { 74@mixin remove($func-name, $func-names...) {
72 $noop: remove($func-name, $func-names...); 75 $noop: remove($func-name, $func-names...);
73} 76}
74 77
75/// 78///
@@ -78,20 +81,20 @@ $validators: ();
78/// @see {mixin} remove 81/// @see {mixin} remove
79/// 82///
80@function remove($func-name, $func-names...) { 83@function remove($func-name, $func-names...) {
81 $validators: map-remove($validators, $func-name, $func-names...); 84 $validators: map.remove($validators, $func-name, $func-names...);
82 @return null; 85 @return null;
83} 86}
84 87
85/// 88///
86/// @access private 89/// @access private
87/// 90///
88@mixin validate($type, $args, $selector, $context) { 91@mixin validate($type, $args, $selector, $context) {
89 @each $id, $fn in $validators { 92 @each $id, $fn in $validators {
90 $result: call($fn, $type, $args, $selector, $context); 93 $result: meta.call($fn, $type, $args, $selector, $context);
91 @if not nth($result, 1) { 94 @if not list.nth($result, 1) {
92 @error 'A BEM validator rejected this mixin usage due to the following reason: #{nth($result, 2)}'; 95 @error 'A BEM validator rejected this mixin usage due to the following reason: #{nth($result, 2)}';
93 } 96 }
94 } 97 }
95} 98}
96 99
97// 100//
@@ -105,76 +108,76 @@ $validators: ();
105/// namespace used. 108/// namespace used.
106/// 109///
107@function enforce-namespace-order($type, $args, $selector, $context) { 110@function enforce-namespace-order($type, $args, $selector, $context) {
108 @if not global-variable-exists(namespace-order, vars) { 111 @if not meta.global-variable-exists(namespace-order, vars) {
109 vars.$namespace-order: map-keys(vars.$namespaces); 112 vars.$namespace-order: map.keys(vars.$namespaces);
110 } 113 }
111 @if not global-variable-exists(cur-namespace-index, vars) { 114 @if not meta.global-variable-exists(cur-namespace-index, vars) {
112 vars.$cur-namespace-index: 1; 115 vars.$cur-namespace-index: 1;
113 } 116 }
114 117
115 @if $type == 'block' { 118 @if $type == 'block' {
116 $block-type: map-get($args, 'type'); 119 $block-type: map.get($args, 'type');
117 120
118 @if $block-type != null { 121 @if $block-type != null {
119 $ns-index: index(vars.$namespace-order, $block-type); 122 $ns-index: list.index(vars.$namespace-order, $block-type);
120 123
121 @if $ns-index != null { 124 @if $ns-index != null {
122 @if $ns-index < vars.$cur-namespace-index { 125 @if $ns-index < vars.$cur-namespace-index {
123 @return false 'Namespace "#{$block-type}" comes before current namespace #{nth(vars.$namespace-order, vars.$cur-namespace-index)}'; 126 @return false 'Namespace "#{$block-type}" comes before current namespace #{nth(vars.$namespace-order, vars.$cur-namespace-index)}';
124 } 127 }
125 128
126 vars.$cur-namespace-index: $ns-index; 129 vars.$cur-namespace-index: $ns-index;
127 } 130 }
128 } 131 }
129 } 132 }
130 133
131 @return true ''; 134 @return true '';
132} 135}
133 136
134/// 137///
135/// A validator that makes all BEM entities immutable. 138/// A validator that makes all BEM entities immutable.
136/// 139///
137@function immutable-entities($type, $args, $selector, $context) { 140@function immutable-entities($type, $args, $selector, $context) {
138 @if not global-variable-exists(generated-selectors, vars) { 141 @if not meta.global-variable-exists(generated-selectors, vars) {
139 vars.$generated-selectors: (); 142 vars.$generated-selectors: ();
140 } 143 }
141 144
142 $block-name: null; 145 $block-name: null;
143 $block-type: null; 146 $block-type: null;
144 $block-id: null; 147 $block-id: null;
145 148
146 @if $type == 'block' { 149 @if $type == 'block' {
147 $block-name: map-get($args, 'name'); 150 $block-name: map.get($args, 'name');
148 $block-type: map-get($args, 'type'); 151 $block-type: map.get($args, 'type');
149 } @else { 152 } @else {
150 $block-context: contexts.get(vars.$context-id, 'block'); 153 $block-context: contexts.get(vars.$context-id, 'block');
151 $block-name: map-get(nth($block-context, 2), 'name'); 154 $block-name: map.get(list.nth($block-context, 2), 'name');
152 $block-type: map-get(nth($block-context, 2), 'type'); 155 $block-type: map.get(list.nth($block-context, 2), 'type');
153 } 156 }
154 157
155 @if $block-type != null { 158 @if $block-type != null {
156 $block-id: $block-name + '_' + $block-type; 159 $block-id: $block-name + '_' + $block-type;
157 } @else { 160 } @else {
158 $block-id: $block-name; 161 $block-id: $block-name;
159 } 162 }
160 163
161 @if $type == 'block' { 164 @if $type == 'block' {
162 @if map-has-key(vars.$generated-selectors, $block-id) { 165 @if map.has-key(vars.$generated-selectors, $block-id) {
163 @return false 'Entity "#{$type}" with arguments [ #{functions.map-print($args)} ] was already defined.'; 166 @return false 'Entity "#{$type}" with arguments [ #{functions.map-print($args)} ] was already defined.';
164 } 167 }
165 168
166 vars.$generated-selectors: map-merge(vars.$generated-selectors, ($block-id: ())); 169 vars.$generated-selectors: map.merge(vars.$generated-selectors, ($block-id: ()));
167 } @else { 170 } @else {
168 $selectors: map-get(vars.$generated-selectors, $block-id); 171 $selectors: map.get(vars.$generated-selectors, $block-id);
169 172
170 @if index($selectors, $selector) { 173 @if list.index($selectors, $selector) {
171 @return false 'Entity "#{$type}" with arguments [ #{functions.map-print($args)} ] was already defined.'; 174 @return false 'Entity "#{$type}" with arguments [ #{functions.map-print($args)} ] was already defined.';
172 } 175 }
173 176
174 $selectors: append($selectors, $selector); 177 $selectors: list.append($selectors, $selector);
175 178
176 vars.$generated-selectors: map-merge(vars.$generated-selectors, ($block-id: $selectors)); 179 vars.$generated-selectors: map.merge(vars.$generated-selectors, ($block-id: $selectors));
177 } 180 }
178 181
179 @return true ''; 182 @return true '';
180} 183}
diff --git a/src/bem/_vars.scss b/src/bem/_vars.scss
index 3d0f92a..823bf0a 100644
--- a/src/bem/_vars.scss
+++ b/src/bem/_vars.scss
@@ -41,15 +41,15 @@ $suffix-separator: '\\@' !default;
41/// @type map 41/// @type map
42/// 42///
43$namespaces: ( 43$namespaces: (
44 object: 'o', 44 object: 'o',
45 component: 'c', 45 component: 'c',
46 layout: 'l', 46 layout: 'l',
47 scope: 's', 47 scope: 's',
48 theme: 't', 48 theme: 't',
49 utility: 'u', 49 utility: 'u',
50 js: 'js', 50 js: 'js',
51 qa: 'qa', 51 qa: 'qa',
52 hack: '_' 52 hack: '_'
53) !default; 53) !default;
54 54
55/// 55///
@@ -100,9 +100,9 @@ $debug: false !default;
100/// @type map 100/// @type map
101/// 101///
102$debug-colors: ( 102$debug-colors: (
103 object: #ffa500, 103 object: #ffa500,
104 component: #00f, 104 component: #00f,
105 layout: #ff0, 105 layout: #ff0,
106 utility: #008000, 106 utility: #008000,
107 hack: #f00 107 hack: #f00
108) !default; 108) !default;
diff --git a/test/_bem.scss b/test/_bem.scss
index b7bd6b4..48a5ee9 100644
--- a/test/_bem.scss
+++ b/test/_bem.scss
@@ -1,21 +1,21 @@
1@use 'true' as *; 1@use 'true' as *;
2 2
3@include describe('bem') { 3@include describe('bem') {
4 // 4 //
5 // The following unit tests only test the BEM mixins. 5 // The following unit tests only test the BEM mixins.
6 // Since they are wrappers for the BEM functions, the latter are 6 // Since they are wrappers for the BEM functions, the latter are
7 // automatically covered. 7 // automatically covered.
8 // 8 //
9 9
10 @import 'bem/block'; 10 @import 'bem/block';
11 @import 'bem/composed-of'; 11 @import 'bem/composed-of';
12 @import 'bem/at-theme'; 12 @import 'bem/at-theme';
13 @import 'bem/element'; 13 @import 'bem/element';
14 @import 'bem/related-element'; 14 @import 'bem/related-element';
15 @import 'bem/next-twin-element'; 15 @import 'bem/next-twin-element';
16 @import 'bem/modifier'; 16 @import 'bem/modifier';
17 @import 'bem/suffix'; 17 @import 'bem/suffix';
18 @import 'bem/state'; 18 @import 'bem/state';
19 @import 'bem/multi'; 19 @import 'bem/multi';
20 @import 'bem/examples'; 20 @import 'bem/examples';
21} 21}
diff --git a/test/_contexts.scss b/test/_contexts.scss
index 510f79b..fc49186 100644
--- a/test/_contexts.scss
+++ b/test/_contexts.scss
@@ -2,67 +2,67 @@
2@use '../src/contexts'; 2@use '../src/contexts';
3 3
4@include describe('contexts') { 4@include describe('contexts') {
5 @include it('Creating / deleting context stacks') { 5 @include it('Creating / deleting context stacks') {
6 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created'); 6 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created');
7 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted'); 7 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted');
8 } 8 }
9 9
10 @include it('Adding / removing contexts') { 10 @include it('Adding / removing contexts') {
11 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created'); 11 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created');
12 12
13 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed'); 13 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed');
14 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed'); 14 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed');
15 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed'); 15 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed');
16 16
17 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped'); 17 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped');
18 @include assert-equal(contexts.pop('test'), 'another' 'text', 'Check if context 2 was popped'); 18 @include assert-equal(contexts.pop('test'), 'another' 'text', 'Check if context 2 was popped');
19 @include assert-equal(contexts.pop('test'), 'ctx' 1234, 'Check if context 1 was popped'); 19 @include assert-equal(contexts.pop('test'), 'ctx' 1234, 'Check if context 1 was popped');
20 20
21 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted'); 21 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted');
22 } 22 }
23 23
24 @include it('Clearing / counting context stacks') { 24 @include it('Clearing / counting context stacks') {
25 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created'); 25 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created');
26 26
27 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed'); 27 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed');
28 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed'); 28 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed');
29 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed'); 29 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed');
30 30
31 @include assert-equal(contexts.count('test'), 3, 'Check if context stack contains 3 contexts'); 31 @include assert-equal(contexts.count('test'), 3, 'Check if context stack contains 3 contexts');
32 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped'); 32 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped');
33 @include assert-equal(contexts.count('test'), 2, 'Check if context stack contains 2 contexts'); 33 @include assert-equal(contexts.count('test'), 2, 'Check if context stack contains 2 contexts');
34 @include assert-equal(contexts.clear('test'), null, 'Check if context stack was cleared'); 34 @include assert-equal(contexts.clear('test'), null, 'Check if context stack was cleared');
35 @include assert-equal(contexts.count('test'), 0, 'Check if context stack contains no contexts'); 35 @include assert-equal(contexts.count('test'), 0, 'Check if context stack contains no contexts');
36 36
37 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted'); 37 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted');
38 } 38 }
39 39
40 @include it('Retrieving contexts') { 40 @include it('Retrieving contexts') {
41 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created'); 41 @include assert-equal(contexts.create('test'), null, 'Check if context stack was created');
42 42
43 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed'); 43 @include assert-equal(contexts.push('test', 'ctx', 1234), 'ctx' 1234, 'Check if context 1 was pushed');
44 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed'); 44 @include assert-equal(contexts.push('test', 'another', 'text'), 'another' 'text', 'Check if context 2 was pushed');
45 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed'); 45 @include assert-equal(contexts.push('test', 'ctx', 56), 'ctx' 56, 'Check if context 3 was pushed');
46 46
47 @include assert-equal(contexts.get('test', 1), 'ctx' 56, 'Check if context at position 1 is context 3'); 47 @include assert-equal(contexts.get('test', 1), 'ctx' 56, 'Check if context at position 1 is context 3');
48 @include assert-equal(contexts.get('test', 'ctx'), 'ctx' 56, 'Check if latest context with id "ctx" is context 3'); 48 @include assert-equal(contexts.get('test', 'ctx'), 'ctx' 56, 'Check if latest context with id "ctx" is context 3');
49 @include assert-equal(contexts.get('test', 2), 'another' 'text', 'Check if latest context with id "another" is context 2'); 49 @include assert-equal(contexts.get('test', 2), 'another' 'text', 'Check if latest context with id "another" is context 2');
50 50
51 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped'); 51 @include assert-equal(contexts.pop('test'), 'ctx' 56, 'Check if context 3 was popped');
52 52
53 @include assert-equal(contexts.get('test', 1), 'another' 'text', 'Check if context at position 1 is context 2'); 53 @include assert-equal(contexts.get('test', 1), 'another' 'text', 'Check if context at position 1 is context 2');
54 @include assert-equal(contexts.get('test', -1), 'ctx' 1234, 'Check if latest context with id "ctx" is context 1'); 54 @include assert-equal(contexts.get('test', -1), 'ctx' 1234, 'Check if latest context with id "ctx" is context 1');
55 55
56 @include assert-equal(contexts.push('test', 'more', 'string'), 'more' 'string', 'Check if context 4 was pushed'); 56 @include assert-equal(contexts.push('test', 'more', 'string'), 'more' 'string', 'Check if context 4 was pushed');
57 57
58 @include assert-equal(contexts.get('test', 1), 'more' 'string', 'Check if context at position 1 is context 4'); 58 @include assert-equal(contexts.get('test', 1), 'more' 'string', 'Check if context at position 1 is context 4');
59 @include assert-equal(contexts.get('test', 'more'), 'more' 'string', 'Check if latest context with id "more" is context 4'); 59 @include assert-equal(contexts.get('test', 'more'), 'more' 'string', 'Check if latest context with id "more" is context 4');
60 60
61 @include assert-equal(contexts.pop('test'), 'more' 'string', 'Check if context 4 was popped'); 61 @include assert-equal(contexts.pop('test'), 'more' 'string', 'Check if context 4 was popped');
62 @include assert-equal(contexts.pop('test'), 'another' 'text', 'Check if context 2 was popped'); 62 @include assert-equal(contexts.pop('test'), 'another' 'text', 'Check if context 2 was popped');
63 63
64 @include assert-equal(contexts.get('test', 1), contexts.get('test', -1), 'Check if first and last context are context 1'); 64 @include assert-equal(contexts.get('test', 1), contexts.get('test', -1), 'Check if first and last context are context 1');
65 65
66 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted'); 66 @include assert-equal(contexts.delete('test'), null, 'Check if context stack was deleted');
67 } 67 }
68} 68}
diff --git a/test/_functions.scss b/test/_functions.scss
index 07561ef..4d545db 100644
--- a/test/_functions.scss
+++ b/test/_functions.scss
@@ -2,56 +2,56 @@
2@use '../src/functions'; 2@use '../src/functions';
3 3
4@include describe('functions') { 4@include describe('functions') {
5 @include it('str-replace') { 5 @include it('str-replace') {
6 $str: 'Hello world!'; 6 $str: 'Hello world!';
7 7
8 @include assert-equal(functions.str-replace($str, 'world', 'neighbor'), 'Hello neighbor!', 'Replace "world" with "neighbor"'); 8 @include assert-equal(functions.str-replace($str, 'world', 'neighbor'), 'Hello neighbor!', 'Replace "world" with "neighbor"');
9 @include assert-equal(functions.str-replace($str, 'neighbor', 'moon'), 'Hello world!', 'Replace "neighbor" with "moon"'); 9 @include assert-equal(functions.str-replace($str, 'neighbor', 'moon'), 'Hello world!', 'Replace "neighbor" with "moon"');
10 @include assert-equal(functions.str-replace($str, 'Hello', 'Bye'), 'Bye world!', 'Replace "Hello" with "Bye"'); 10 @include assert-equal(functions.str-replace($str, 'Hello', 'Bye'), 'Bye world!', 'Replace "Hello" with "Bye"');
11 } 11 }
12 12
13 @include it('list-slice') { 13 @include it('list-slice') {
14 $list: 'this' 'is' 'a' 'list'; 14 $list: 'this' 'is' 'a' 'list';
15 15
16 @include assert-equal(functions.list-slice($list, 2), 'is' 'a' 'list', 'Discard first item'); 16 @include assert-equal(functions.list-slice($list, 2), 'is' 'a' 'list', 'Discard first item');
17 @include assert-equal(functions.list-slice($list, 1, 3), 'this' 'is' 'a', 'Keep first 3 items'); 17 @include assert-equal(functions.list-slice($list, 1, 3), 'this' 'is' 'a', 'Keep first 3 items');
18 @include assert-equal(functions.list-slice($list, 2, 3), 'is' 'a', 'Extract list from index 2 to 3'); 18 @include assert-equal(functions.list-slice($list, 2, 3), 'is' 'a', 'Extract list from index 2 to 3');
19 @include assert-equal(functions.list-slice($list, -1, -1), join((), 'list'), 'Keep last item'); 19 @include assert-equal(functions.list-slice($list, -1, -1), join((), 'list'), 'Keep last item');
20 @include assert-equal(functions.list-slice($list, -1, 1), 'list' 'this', 'Extract first and last item'); 20 @include assert-equal(functions.list-slice($list, -1, 1), 'list' 'this', 'Extract first and last item');
21 } 21 }
22 22
23 @include it('list-prepend') { 23 @include it('list-prepend') {
24 $list: 'this' 'is' 'a' 'list'; 24 $list: 'this' 'is' 'a' 'list';
25 25
26 @include assert-equal(functions.list-prepend($list, 'and'), 'and' 'this' 'is' 'a' 'list', 'Prepend "and"'); 26 @include assert-equal(functions.list-prepend($list, 'and'), 'and' 'this' 'is' 'a' 'list', 'Prepend "and"');
27 @include assert-equal(functions.list-prepend($list, 2), 2 'this' 'is' 'a' 'list', 'Prepend 2'); 27 @include assert-equal(functions.list-prepend($list, 2), 2 'this' 'is' 'a' 'list', 'Prepend 2');
28 } 28 }
29 29
30 @include it('quicksort') { 30 @include it('quicksort') {
31 @include assert-equal(functions.quicksort(1 2 3 4 5), 1 2 3 4 5, 'Already sorted list of 5 items'); 31 @include assert-equal(functions.quicksort(1 2 3 4 5), 1 2 3 4 5, 'Already sorted list of 5 items');
32 @include assert-equal(functions.quicksort(1 3 2), 1 2 3, 'Random list of 3 items'); 32 @include assert-equal(functions.quicksort(1 3 2), 1 2 3, 'Random list of 3 items');
33 @include assert-equal(functions.quicksort(6 3 7 3 8 1 4), 1 3 3 4 6 7 8, 'Random list of 7 items, one duplicate'); 33 @include assert-equal(functions.quicksort(6 3 7 3 8 1 4), 1 3 3 4 6 7 8, 'Random list of 7 items, one duplicate');
34 @include assert-equal(functions.quicksort(1 1 1 1), 1 1 1 1, 'List of 4 identical items'); 34 @include assert-equal(functions.quicksort(1 1 1 1), 1 1 1 1, 'List of 4 identical items');
35 } 35 }
36 36
37 @include it('map-get-default') { 37 @include it('map-get-default') {
38 $map: ('key': 'value', 'another': 'item'); 38 $map: ('key': 'value', 'another': 'item');
39 39
40 @include assert-equal(functions.map-get-default($map, 'another', 0), map-get($map, 'another'), 'Get existing value'); 40 @include assert-equal(functions.map-get-default($map, 'another', 0), map-get($map, 'another'), 'Get existing value');
41 @include assert-equal(functions.map-get-default($map, 'index', 'nothing'), 'nothing', 'Get missing value'); 41 @include assert-equal(functions.map-get-default($map, 'index', 'nothing'), 'nothing', 'Get missing value');
42 } 42 }
43 43
44 @include it('strip-unit') { 44 @include it('strip-unit') {
45 @include assert-true(unitless(functions.strip-unit(1em)), 'Remove unit from 1em'); 45 @include assert-true(unitless(functions.strip-unit(1em)), 'Remove unit from 1em');
46 @include assert-true(unitless(functions.strip-unit(2rem)), 'Remove unit from 2rem'); 46 @include assert-true(unitless(functions.strip-unit(2rem)), 'Remove unit from 2rem');
47 @include assert-true(unitless(functions.strip-unit(3px)), 'Remove unit from 3px'); 47 @include assert-true(unitless(functions.strip-unit(3px)), 'Remove unit from 3px');
48 @include assert-true(unitless(functions.strip-unit(4)), 'Remove unit from 4'); 48 @include assert-true(unitless(functions.strip-unit(4)), 'Remove unit from 4');
49 @include assert-true(unitless(functions.strip-unit(5pt)), 'Remove unit from 5pt'); 49 @include assert-true(unitless(functions.strip-unit(5pt)), 'Remove unit from 5pt');
50 } 50 }
51 51
52 @include it('px-to-rem') { 52 @include it('px-to-rem') {
53 @include assert-equal(functions.px-to-rem(16px, 16px), 1rem, 'Convert 16px'); 53 @include assert-equal(functions.px-to-rem(16px, 16px), 1rem, 'Convert 16px');
54 @include assert-equal(functions.px-to-rem(32px, 16px), 2rem, 'Convert 16px'); 54 @include assert-equal(functions.px-to-rem(32px, 16px), 2rem, 'Convert 16px');
55 @include assert-equal(functions.px-to-rem(8px, 16px), 0.5rem, 'Convert 16px'); 55 @include assert-equal(functions.px-to-rem(8px, 16px), .5rem, 'Convert 16px');
56 } 56 }
57} 57}
diff --git a/test/_gradients.scss b/test/_gradients.scss
index c11439c..db5fda7 100644
--- a/test/_gradients.scss
+++ b/test/_gradients.scss
@@ -5,264 +5,220 @@
5@use '../src/gradients'; 5@use '../src/gradients';
6 6
7@include describe('gradients') { 7@include describe('gradients') {
8 @include it('easing-gradient') { 8 @include it('easing-gradient') {
9 $gradient1: gradients.easing-gradient( 9 $gradient1: gradients.easing-gradient(linear,
10 linear, 10 to right,
11 to right, 11 #000,
12 #000, 12 ease-in-quad,
13 ease-in-quad, 13 transparent);
14 transparent
15 );
16 14
17 $expected1: linear-gradient( 15 $expected1: linear-gradient(to right,
18 to right, 16 #000 0,
19 #000 0, 17 mix(transparent, #000, easing.ease-in-quad(.25) * 100%) 25%,
20 mix(transparent, #000, easing.ease-in-quad(0.25) * 100%) 25%, 18 mix(transparent, #000, easing.ease-in-quad(.5) * 100%) 50%,
21 mix(transparent, #000, easing.ease-in-quad(0.5) * 100%) 50%, 19 mix(transparent, #000, easing.ease-in-quad(.75) * 100%) 75%,
22 mix(transparent, #000, easing.ease-in-quad(0.75) * 100%) 75%, 20 transparent 100%);
23 transparent 100%
24 );
25 21
26 @include assert-equal($gradient1, $expected1, 'Simple linear gradient'); 22 @include assert-equal($gradient1, $expected1, 'Simple linear gradient');
27 23
28 // --------------------------------------------------------------------------- 24 // ---------------------------------------------------------------------------
29 25
30 $gradient2: gradients.easing-gradient( 26 $gradient2: gradients.easing-gradient(radial,
31 radial, 27 1em 2em at 50% 60%,
32 1em 2em at 50% 60%, 28 #000,
33 #000, 29 ease-out-cubic,
34 ease-out-cubic, 30 transparent);
35 transparent
36 );
37 31
38 $expected2: radial-gradient( 32 $expected2: radial-gradient(1em 2em at 50% 60%,
39 1em 2em at 50% 60%, 33 #000 0,
40 #000 0, 34 mix(transparent, #000, easing.ease-out-cubic(.25) * 100%) 25%,
41 mix(transparent, #000, easing.ease-out-cubic(0.25) * 100%) 25%, 35 mix(transparent, #000, easing.ease-out-cubic(.5) * 100%) 50%,
42 mix(transparent, #000, easing.ease-out-cubic(0.5) * 100%) 50%, 36 mix(transparent, #000, easing.ease-out-cubic(.75) * 100%) 75%,
43 mix(transparent, #000, easing.ease-out-cubic(0.75) * 100%) 75%, 37 transparent 100%);
44 transparent 100%
45 );
46 38
47 @include assert-equal($gradient2, $expected2, 'Simple radial gradient'); 39 @include assert-equal($gradient2, $expected2, 'Simple radial gradient');
48 40
49 // --------------------------------------------------------------------------- 41 // ---------------------------------------------------------------------------
50 42
51 $gradient3: gradients.easing-gradient( 43 $gradient3: gradients.easing-gradient(linear,
52 linear, 44 to right,
53 to right, 45 #000 2em,
54 #000 2em, 46 ease-in-quad,
55 ease-in-quad, 47 transparent 10em);
56 transparent 10em
57 );
58 48
59 $expected3: linear-gradient( 49 $expected3: linear-gradient(to right,
60 to right, 50 #000 2em,
61 #000 2em, 51 mix(transparent, #000, easing.ease-in-quad(.25) * 100%) 4em,
62 mix(transparent, #000, easing.ease-in-quad(0.25) * 100%) 4em, 52 mix(transparent, #000, easing.ease-in-quad(.5) * 100%) 6em,
63 mix(transparent, #000, easing.ease-in-quad(0.5) * 100%) 6em, 53 mix(transparent, #000, easing.ease-in-quad(.75) * 100%) 8em,
64 mix(transparent, #000, easing.ease-in-quad(0.75) * 100%) 8em, 54 transparent 10em);
65 transparent 10em
66 );
67 55
68 @include assert-equal($gradient3, $expected3, 'Linear gradient with positioned color stops'); 56 @include assert-equal($gradient3, $expected3, 'Linear gradient with positioned color stops');
69 57
70 // --------------------------------------------------------------------------- 58 // ---------------------------------------------------------------------------
71 59
72 $gradient4: gradients.easing-gradient( 60 $gradient4: gradients.easing-gradient(linear,
73 linear, 61 to right,
74 to right, 62 #000 20%,
75 #000 20%, 63 ease-in-quad,
76 ease-in-quad, 64 transparent calc(20% + 10em));
77 transparent calc(20% + 10em)
78 );
79 65
80 $expected4: linear-gradient( 66 $expected4: linear-gradient(to right,
81 to right, 67 #000 20%,
82 #000 20%, 68 mix(transparent, #000, easing.ease-in-quad(.25) * 100%) calc(20% + (20% + 10em - 20%) * .25),
83 mix(transparent, #000, easing.ease-in-quad(0.25) * 100%) calc(20% + (20% + 10em - 20%) * 0.25), 69 mix(transparent, #000, easing.ease-in-quad(.5) * 100%) calc(20% + (20% + 10em - 20%) * .5),
84 mix(transparent, #000, easing.ease-in-quad(0.5) * 100%) calc(20% + (20% + 10em - 20%) * 0.5), 70 mix(transparent, #000, easing.ease-in-quad(.75) * 100%) calc(20% + (20% + 10em - 20%) * .75),
85 mix(transparent, #000, easing.ease-in-quad(0.75) * 100%) calc(20% + (20% + 10em - 20%) * 0.75), 71 transparent calc(20% + 10em));
86 transparent calc(20% + 10em)
87 );
88 72
89 @include assert-equal($gradient4, $expected4, 'More advanced linear gradient with positioned color stops'); 73 @include assert-equal($gradient4, $expected4, 'More advanced linear gradient with positioned color stops');
90 74
91 // --------------------------------------------------------------------------- 75 // ---------------------------------------------------------------------------
92 76
93 $gradient5: gradients.easing-gradient( 77 $gradient5: gradients.easing-gradient(linear,
94 linear, 78 to right,
95 to right, 79 #000 2em,
96 #000 2em, 80 #f00 7em,
97 #f00 7em, 81 ease-in-quad,
98 ease-in-quad, 82 transparent 10em);
99 transparent 10em
100 );
101 83
102 $expected5: linear-gradient( 84 $expected5: linear-gradient(to right,
103 to right, 85 #000 2em,
104 #000 2em, 86 #f00 7em,
105 #f00 7em, 87 mix(transparent, #f00, easing.ease-in-quad(.25) * 100%) 7em + 3em * .25,
106 mix(transparent, #f00, easing.ease-in-quad(0.25) * 100%) 7em + 3em * 0.25, 88 mix(transparent, #f00, easing.ease-in-quad(.5) * 100%) 7em + 3em * .5,
107 mix(transparent, #f00, easing.ease-in-quad(0.5) * 100%) 7em + 3em * 0.5, 89 mix(transparent, #f00, easing.ease-in-quad(.75) * 100%) 7em + 3em * .75,
108 mix(transparent, #f00, easing.ease-in-quad(0.75) * 100%) 7em + 3em * 0.75, 90 transparent 10em);
109 transparent 10em
110 );
111 91
112 @include assert-equal($gradient5, $expected5, 'Linear gradient with 3 positioned color stops, 1 easing transitions'); 92 @include assert-equal($gradient5, $expected5, 'Linear gradient with 3 positioned color stops, 1 easing transitions');
113 93
114 // --------------------------------------------------------------------------- 94 // ---------------------------------------------------------------------------
115 95
116 $gradient6: gradients.easing-gradient( 96 $gradient6: gradients.easing-gradient(linear,
117 linear, 97 to right,
118 to right, 98 #000 2em,
119 #000 2em, 99 ease-in-quad,
120 ease-in-quad, 100 #f00 7em,
121 #f00 7em, 101 ease-in-quad,
122 ease-in-quad, 102 transparent 10em);
123 transparent 10em
124 );
125 103
126 $expected6: linear-gradient( 104 $expected6: linear-gradient(to right,
127 to right, 105 #000 2em,
128 #000 2em, 106 mix(#f00, #000, easing.ease-in-quad(.25) * 100%) 2em + 5em * .25,
129 mix(#f00, #000, easing.ease-in-quad(0.25) * 100%) 2em + 5em * 0.25, 107 mix(#f00, #000, easing.ease-in-quad(.5) * 100%) 2em + 5em * .5,
130 mix(#f00, #000, easing.ease-in-quad(0.5) * 100%) 2em + 5em * 0.5, 108 mix(#f00, #000, easing.ease-in-quad(.75) * 100%) 2em + 5em * .75,
131 mix(#f00, #000, easing.ease-in-quad(0.75) * 100%) 2em + 5em * 0.75, 109 #f00 7em,
132 #f00 7em, 110 mix(transparent, #f00, easing.ease-in-quad(.25) * 100%) 7em + 3em * .25,
133 mix(transparent, #f00, easing.ease-in-quad(0.25) * 100%) 7em + 3em * 0.25, 111 mix(transparent, #f00, easing.ease-in-quad(.5) * 100%) 7em + 3em * .5,
134 mix(transparent, #f00, easing.ease-in-quad(0.5) * 100%) 7em + 3em * 0.5, 112 mix(transparent, #f00, easing.ease-in-quad(.75) * 100%) 7em + 3em * .75,
135 mix(transparent, #f00, easing.ease-in-quad(0.75) * 100%) 7em + 3em * 0.75, 113 transparent 10em);
136 transparent 10em
137 );
138 114
139 @include assert-equal($gradient6, $expected6, 'Linear gradient with 3 positioned color stops, 2 easing transitions'); 115 @include assert-equal($gradient6, $expected6, 'Linear gradient with 3 positioned color stops, 2 easing transitions');
140 116
141 // --------------------------------------------------------------------------- 117 // ---------------------------------------------------------------------------
142 118
143 $gradient7: gradients.easing-gradient( 119 $gradient7: gradients.easing-gradient(linear,
144 linear, 120 to right,
145 to right, 121 #000 2em,
146 #000 2em, 122 ease-in-quad,
147 ease-in-quad, 123 #f00,
148 #f00, 124 ease-in-quad,
149 ease-in-quad, 125 transparent 10em);
150 transparent 10em
151 );
152 126
153 $expected7: linear-gradient( 127 $expected7: linear-gradient(to right,
154 to right, 128 #000 2em,
155 #000 2em, 129 mix(#f00, #000, easing.ease-in-quad(.25) * 100%) 2em + 4em * .25,
156 mix(#f00, #000, easing.ease-in-quad(0.25) * 100%) 2em + 4em * 0.25, 130 mix(#f00, #000, easing.ease-in-quad(.5) * 100%) 2em + 4em * .5,
157 mix(#f00, #000, easing.ease-in-quad(0.5) * 100%) 2em + 4em * 0.5, 131 mix(#f00, #000, easing.ease-in-quad(.75) * 100%) 2em + 4em * .75,
158 mix(#f00, #000, easing.ease-in-quad(0.75) * 100%) 2em + 4em * 0.75, 132 #f00 6em,
159 #f00 6em, 133 mix(transparent, #f00, easing.ease-in-quad(.25) * 100%) 6em + 4em * .25,
160 mix(transparent, #f00, easing.ease-in-quad(0.25) * 100%) 6em + 4em * 0.25, 134 mix(transparent, #f00, easing.ease-in-quad(.5) * 100%) 6em + 4em * .5,
161 mix(transparent, #f00, easing.ease-in-quad(0.5) * 100%) 6em + 4em * 0.5, 135 mix(transparent, #f00, easing.ease-in-quad(.75) * 100%) 6em + 4em * .75,
162 mix(transparent, #f00, easing.ease-in-quad(0.75) * 100%) 6em + 4em * 0.75, 136 transparent 10em);
163 transparent 10em
164 );
165 137
166 @include assert-equal($gradient7, $expected7, 'Linear gradient with 2 / 3 positioned color stops, 2 easing transitions'); 138 @include assert-equal($gradient7, $expected7, 'Linear gradient with 2 / 3 positioned color stops, 2 easing transitions');
167 139
168 // --------------------------------------------------------------------------- 140 // ---------------------------------------------------------------------------
169 141
170 $gradient8: gradients.easing-gradient( 142 $gradient8: gradients.easing-gradient(linear,
171 linear, 143 to right,
172 to right, 144 #000,
173 #000, 145 ease-in-quad,
174 ease-in-quad, 146 #f00,
175 #f00, 147 ease-in-quad,
176 ease-in-quad, 148 transparent);
177 transparent
178 );
179 149
180 $expected8: linear-gradient( 150 $expected8: linear-gradient(to right,
181 to right, 151 #000 0,
182 #000 0, 152 mix(#f00, #000, easing.ease-in-quad(.25) * 100%) 50% * .25,
183 mix(#f00, #000, easing.ease-in-quad(0.25) * 100%) 50% * 0.25, 153 mix(#f00, #000, easing.ease-in-quad(.5) * 100%) 50% * .5,
184 mix(#f00, #000, easing.ease-in-quad(0.5) * 100%) 50% * 0.5, 154 mix(#f00, #000, easing.ease-in-quad(.75) * 100%) 50% * .75,
185 mix(#f00, #000, easing.ease-in-quad(0.75) * 100%) 50% * 0.75, 155 #f00 50%,
186 #f00 50%, 156 mix(transparent, #f00, easing.ease-in-quad(.25) * 100%) 50% + 50% * .25,
187 mix(transparent, #f00, easing.ease-in-quad(0.25) * 100%) 50% + 50% * 0.25, 157 mix(transparent, #f00, easing.ease-in-quad(.5) * 100%) 50% + 50% * .5,
188 mix(transparent, #f00, easing.ease-in-quad(0.5) * 100%) 50% + 50% * 0.5, 158 mix(transparent, #f00, easing.ease-in-quad(.75) * 100%) 50% + 50% * .75,
189 mix(transparent, #f00, easing.ease-in-quad(0.75) * 100%) 50% + 50% * 0.75, 159 transparent 100%);
190 transparent 100%
191 );
192 160
193 @include assert-equal($gradient8, $expected8, 'Linear gradient with 0 / 3 positioned color stops, 2 easing transitions'); 161 @include assert-equal($gradient8, $expected8, 'Linear gradient with 0 / 3 positioned color stops, 2 easing transitions');
194 162
195 // --------------------------------------------------------------------------- 163 // ---------------------------------------------------------------------------
196 164
197 $gradient9: gradients.easing-gradient( 165 $gradient9: gradients.easing-gradient(linear,
198 linear, 166 to right,
199 to right, 167 #000,
200 #000, 168 ease-in-quad,
201 ease-in-quad, 169 #f00,
202 #f00, 170 ease-in-quad,
203 ease-in-quad, 171 transparent 20em);
204 transparent 20em
205 );
206 172
207 $expected9: linear-gradient( 173 $expected9: linear-gradient(to right,
208 to right, 174 #000 0,
209 #000 0, 175 mix(#f00, #000, easing.ease-in-quad(.25) * 100%) 10em * .25,
210 mix(#f00, #000, easing.ease-in-quad(0.25) * 100%) 10em * 0.25, 176 mix(#f00, #000, easing.ease-in-quad(.5) * 100%) 10em * .5,
211 mix(#f00, #000, easing.ease-in-quad(0.5) * 100%) 10em * 0.5, 177 mix(#f00, #000, easing.ease-in-quad(.75) * 100%) 10em * .75,
212 mix(#f00, #000, easing.ease-in-quad(0.75) * 100%) 10em * 0.75, 178 #f00 10em,
213 #f00 10em, 179 mix(transparent, #f00, easing.ease-in-quad(.25) * 100%) 10em + 10em * .25,
214 mix(transparent, #f00, easing.ease-in-quad(0.25) * 100%) 10em + 10em * 0.25, 180 mix(transparent, #f00, easing.ease-in-quad(.5) * 100%) 10em + 10em * .5,
215 mix(transparent, #f00, easing.ease-in-quad(0.5) * 100%) 10em + 10em * 0.5, 181 mix(transparent, #f00, easing.ease-in-quad(.75) * 100%) 10em + 10em * .75,
216 mix(transparent, #f00, easing.ease-in-quad(0.75) * 100%) 10em + 10em * 0.75, 182 transparent 20em);
217 transparent 20em
218 );
219 183
220 @include assert-equal($gradient9, $expected9, 'Linear gradient with 1 / 3 positioned color stops, 2 easing transitions'); 184 @include assert-equal($gradient9, $expected9, 'Linear gradient with 1 / 3 positioned color stops, 2 easing transitions');
221 185
222 // --------------------------------------------------------------------------- 186 // ---------------------------------------------------------------------------
223 187
224 $gradient10: gradients.easing-gradient( 188 $gradient10: gradients.easing-gradient(linear,
225 linear, 189 to right,
226 to right, 190 #000,
227 #000, 191 cubic-bezier .47 0 .745 .715,
228 cubic-bezier 0.47 0 0.745 0.715, 192 transparent);
229 transparent
230 );
231 193
232 $expected10: linear-gradient( 194 $expected10: linear-gradient(to right,
233 to right, 195 #000 0,
234 #000 0, 196 mix(transparent, #000, easing.cubic-bezier(.47, 0, .745, .715, .25) * 100%) 25%,
235 mix(transparent, #000, easing.cubic-bezier(0.47, 0, 0.745, 0.715, 0.25) * 100%) 25%, 197 mix(transparent, #000, easing.cubic-bezier(.47, 0, .745, .715, .5) * 100%) 50%,
236 mix(transparent, #000, easing.cubic-bezier(0.47, 0, 0.745, 0.715, 0.5) * 100%) 50%, 198 mix(transparent, #000, easing.cubic-bezier(.47, 0, .745, .715, .75) * 100%) 75%,
237 mix(transparent, #000, easing.cubic-bezier(0.47, 0, 0.745, 0.715, 0.75) * 100%) 75%, 199 transparent 100%);
238 transparent 100%
239 );
240 200
241 @include assert-equal($gradient10, $expected10, 'Simple linear gradient with custom cubic-bezier easing'); 201 @include assert-equal($gradient10, $expected10, 'Simple linear gradient with custom cubic-bezier easing');
242 202
243 // --------------------------------------------------------------------------- 203 // ---------------------------------------------------------------------------
244 204
245 $gradient11: gradients.easing-gradient( 205 $gradient11: gradients.easing-gradient(linear,
246 linear, 206 to right,
247 to right, 207 #000,
248 #000, 208 steps 4 jump-start,
249 steps 4 jump-start, 209 transparent);
250 transparent
251 );
252 210
253 $expected11: linear-gradient( 211 $expected11: linear-gradient(to right,
254 to right, 212 #000 0,
255 #000 0, 213 mix(transparent, #000, .25 * 100%) 0,
256 mix(transparent, #000, 0.25 * 100%) 0, 214 mix(transparent, #000, .25 * 100%) 25%,
257 mix(transparent, #000, 0.25 * 100%) 25%, 215 mix(transparent, #000, .5 * 100%) 25%,
258 mix(transparent, #000, 0.5 * 100%) 25%, 216 mix(transparent, #000, .5 * 100%) 50%,
259 mix(transparent, #000, 0.5 * 100%) 50%, 217 mix(transparent, #000, .75 * 100%) 50%,
260 mix(transparent, #000, 0.75 * 100%) 50%, 218 mix(transparent, #000, .75 * 100%) 75%,
261 mix(transparent, #000, 0.75 * 100%) 75%, 219 transparent 75%,
262 transparent 75%, 220 transparent 100%);
263 transparent 100%
264 );
265 221
266 @include assert-equal($gradient11, $expected11, 'Simple linear gradient with custom steps easing'); 222 @include assert-equal($gradient11, $expected11, 'Simple linear gradient with custom steps easing');
267 } 223 }
268} 224}
diff --git a/test/_harmony.scss b/test/_harmony.scss
index c7d309c..3229e8e 100644
--- a/test/_harmony.scss
+++ b/test/_harmony.scss
@@ -4,251 +4,251 @@
4@use '../src/harmony'; 4@use '../src/harmony';
5 5
6@function _limit-decimals($n) { 6@function _limit-decimals($n) {
7 @return math.div(math.floor($n * 1000), 1000); 7 @return math.div(math.floor($n * 1000), 1000);
8} 8}
9 9
10@include describe('harmony') { 10@include describe('harmony') {
11 @include it('modular-scale') { 11 @include it('modular-scale') {
12 @include assert-equal(_limit-decimals(harmony.modular-scale(0, 1em, 1.1)), 1em, 'Zero iterations, 1em base, 1.1 scale'); 12 @include assert-equal(_limit-decimals(harmony.modular-scale(0, 1em, 1.1)), 1em, 'Zero iterations, 1em base, 1.1 scale');
13 @include assert-equal(_limit-decimals(harmony.modular-scale(1, 1em, 1.1)), 1.1em, '1 iteration, 1em base, 1.1 scale'); 13 @include assert-equal(_limit-decimals(harmony.modular-scale(1, 1em, 1.1)), 1.1em, '1 iteration, 1em base, 1.1 scale');
14 @include assert-equal(_limit-decimals(harmony.modular-scale(2, 2px, 1.2)), 2.88px, '2 iterations, 2px base, 1.2 scale'); 14 @include assert-equal(_limit-decimals(harmony.modular-scale(2, 2px, 1.2)), 2.88px, '2 iterations, 2px base, 1.2 scale');
15 @include assert-equal(_limit-decimals(harmony.modular-scale(-1, 2rem, 2)), 1rem, '-1 iteration, 2rem base, 2 scale'); 15 @include assert-equal(_limit-decimals(harmony.modular-scale(-1, 2rem, 2)), 1rem, '-1 iteration, 2rem base, 2 scale');
16 @include assert-equal(_limit-decimals(harmony.modular-scale(-2, 2rem, 2)), 0.5rem, '-2 iterations, 2rem base, 2 scale'); 16 @include assert-equal(_limit-decimals(harmony.modular-scale(-2, 2rem, 2)), .5rem, '-2 iterations, 2rem base, 2 scale');
17 17
18 @include assert-equal(_limit-decimals(harmony.modular-scale(0, 1em 2em, 1.1)), 1em, 'Zero iterations, 1em 2em base, 1.1 scale'); 18 @include assert-equal(_limit-decimals(harmony.modular-scale(0, 1em 2em, 1.1)), 1em, 'Zero iterations, 1em 2em base, 1.1 scale');
19 @include assert-equal(_limit-decimals(harmony.modular-scale(1, 1em 2em, 1.1)), 1.026em, '1 iteration, 1em 2em base, 1.1 scale'); 19 @include assert-equal(_limit-decimals(harmony.modular-scale(1, 1em 2em, 1.1)), 1.026em, '1 iteration, 1em 2em base, 1.1 scale');
20 @include assert-equal(_limit-decimals(harmony.modular-scale(2, 1em 2em, 1.1)), 1.1em, '2 iterations, 1em 2em base, 1.1 scale'); 20 @include assert-equal(_limit-decimals(harmony.modular-scale(2, 1em 2em, 1.1)), 1.1em, '2 iterations, 1em 2em base, 1.1 scale');
21 @include assert-equal(_limit-decimals(harmony.modular-scale(-1, 1em 1.5em, 1.2)), 0.868em, '-1 iteration, 1em 2em base, 1.1 scale'); 21 @include assert-equal(_limit-decimals(harmony.modular-scale(-1, 1em 1.5em, 1.2)), .868em, '-1 iteration, 1em 2em base, 1.1 scale');
22 @include assert-equal(_limit-decimals(harmony.modular-scale(-2, 1em 1.5em, 1.2)), 0.833em, '-2 iterations, 1em 2em base, 1.1 scale'); 22 @include assert-equal(_limit-decimals(harmony.modular-scale(-2, 1em 1.5em, 1.2)), .833em, '-2 iterations, 1em 2em base, 1.1 scale');
23 } 23 }
24 24
25 @include it('responsive-modular-scale') { 25 @include it('responsive-modular-scale') {
26 @include assert('Single-stranded, fluid') { 26 @include assert('Single-stranded, fluid') {
27 $ms: ( 27 $ms: (
28 320px: (1rem, 1.1), 28 320px: (1rem, 1.1),
29 640px: (1rem, 1.2) 29 640px: (1rem, 1.2)
30 ); 30 );
31 31
32 $rem320px: functions.px-to-rem(320px); 32 $rem320px: functions.px-to-rem(320px);
33 $rem640px: functions.px-to-rem(640px); 33 $rem640px: functions.px-to-rem(640px);
34 $diff320px: functions.strip-unit($rem640px - $rem320px); 34 $diff320px: functions.strip-unit($rem640px - $rem320px);
35 35
36 @include output { 36 @include output {
37 h3 { 37 h3 {
38 @include harmony.responsive-modular-scale(font-size, 0, $ms); 38 @include harmony.responsive-modular-scale(font-size, 0, $ms);
39 } 39 }
40 40
41 h2 { 41 h2 {
42 @include harmony.responsive-modular-scale(font-size, 1, $ms); 42 @include harmony.responsive-modular-scale(font-size, 1, $ms);
43 } 43 }
44 44
45 h1 { 45 h1 {
46 @include harmony.responsive-modular-scale(font-size, 2, $ms); 46 @include harmony.responsive-modular-scale(font-size, 2, $ms);
47 } 47 }
48 } 48 }
49 49
50 @include expect { 50 @include expect {
51 h3 { 51 h3 {
52 font-size: 1rem; 52 font-size: 1rem;
53 53
54 @media (min-width: 320px) and (max-width: 640px) { 54 @media (min-width: 320px) and (max-width: 640px) {
55 font-size: calc(1rem + 0 * (100vw - #{$rem320px}) / #{$diff320px}); 55 font-size: calc(1rem + 0 * (100vw - #{$rem320px}) / #{$diff320px});
56 } 56 }
57 57
58 @media (min-width: 640px) { 58 @media (min-width: 640px) {
59 font-size: 1rem; 59 font-size: 1rem;
60 } 60 }
61 } 61 }
62 62
63 h2 { 63 h2 {
64 font-size: 1.1rem; 64 font-size: 1.1rem;
65 65
66 @media (min-width: 320px) and (max-width: 640px) { 66 @media (min-width: 320px) and (max-width: 640px) {
67 font-size: calc(1.1rem + 0.1 * (100vw - #{$rem320px}) / #{$diff320px}); 67 font-size: calc(1.1rem + .1 * (100vw - #{$rem320px}) / #{$diff320px});
68 } 68 }
69 69
70 @media (min-width: 640px) { 70 @media (min-width: 640px) {
71 font-size: 1.2rem; 71 font-size: 1.2rem;
72 } 72 }
73 } 73 }
74 74
75 h1 { 75 h1 {
76 font-size: 1.21rem; 76 font-size: 1.21rem;
77 77
78 @media (min-width: 320px) and (max-width: 640px) { 78 @media (min-width: 320px) and (max-width: 640px) {
79 font-size: calc(1.21rem + 0.23 * (100vw - #{$rem320px}) / #{$diff320px}); 79 font-size: calc(1.21rem + .23 * (100vw - #{$rem320px}) / #{$diff320px});
80 } 80 }
81 81
82 @media (min-width: 640px) { 82 @media (min-width: 640px) {
83 font-size: 1.44rem; 83 font-size: 1.44rem;
84 } 84 }
85 } 85 }
86 } 86 }
87 } 87 }
88 88
89 @include assert('Single-stranded, non-fluid') { 89 @include assert('Single-stranded, non-fluid') {
90 $ms: ( 90 $ms: (
91 320px: (1rem, 1.1), 91 320px: (1rem, 1.1),
92 640px: (1rem, 1.2) 92 640px: (1rem, 1.2)
93 ); 93 );
94 94
95 $rem320px: functions.px-to-rem(320px); 95 $rem320px: functions.px-to-rem(320px);
96 $rem640px: functions.px-to-rem(640px); 96 $rem640px: functions.px-to-rem(640px);
97 $diff320px: functions.strip-unit($rem640px - $rem320px); 97 $diff320px: functions.strip-unit($rem640px - $rem320px);
98 98
99 @include output { 99 @include output {
100 h3 { 100 h3 {
101 @include harmony.responsive-modular-scale(font-size, 0, $ms, false); 101 @include harmony.responsive-modular-scale(font-size, 0, $ms, false);
102 } 102 }
103 103
104 h2 { 104 h2 {
105 @include harmony.responsive-modular-scale(font-size, 1, $ms, false); 105 @include harmony.responsive-modular-scale(font-size, 1, $ms, false);
106 } 106 }
107 107
108 h1 { 108 h1 {
109 @include harmony.responsive-modular-scale(font-size, 2, $ms, false); 109 @include harmony.responsive-modular-scale(font-size, 2, $ms, false);
110 } 110 }
111 } 111 }
112 112
113 @include expect { 113 @include expect {
114 h3 { 114 h3 {
115 font-size: 1rem; 115 font-size: 1rem;
116 116
117 @media (min-width: 640px) { 117 @media (min-width: 640px) {
118 font-size: 1rem; 118 font-size: 1rem;
119 } 119 }
120 } 120 }
121 121
122 h2 { 122 h2 {
123 font-size: 1.1rem; 123 font-size: 1.1rem;
124 124
125 @media (min-width: 640px) { 125 @media (min-width: 640px) {
126 font-size: 1.2rem; 126 font-size: 1.2rem;
127 } 127 }
128 } 128 }
129 129
130 h1 { 130 h1 {
131 font-size: 1.21rem; 131 font-size: 1.21rem;
132 132
133 @media (min-width: 640px) { 133 @media (min-width: 640px) {
134 font-size: 1.44rem; 134 font-size: 1.44rem;
135 } 135 }
136 } 136 }
137 } 137 }
138 } 138 }
139 139
140 @include assert('Double-stranded, fluid') { 140 @include assert('Double-stranded, fluid') {
141 $ms: ( 141 $ms: (
142 320px: (1rem 2rem, 1.1), 142 320px: (1rem 2rem, 1.1),
143 640px: (1rem 2rem, 1.2) 143 640px: (1rem 2rem, 1.2)
144 ); 144 );
145 145
146 $rem320px: functions.px-to-rem(320px); 146 $rem320px: functions.px-to-rem(320px);
147 $rem640px: functions.px-to-rem(640px); 147 $rem640px: functions.px-to-rem(640px);
148 $diff320px: functions.strip-unit($rem640px - $rem320px); 148 $diff320px: functions.strip-unit($rem640px - $rem320px);
149 149
150 @include output { 150 @include output {
151 h3 { 151 h3 {
152 @include harmony.responsive-modular-scale(font-size, 0, $ms); 152 @include harmony.responsive-modular-scale(font-size, 0, $ms);
153 } 153 }
154 154
155 h2 { 155 h2 {
156 @include harmony.responsive-modular-scale(font-size, 1, $ms); 156 @include harmony.responsive-modular-scale(font-size, 1, $ms);
157 } 157 }
158 158
159 h1 { 159 h1 {
160 @include harmony.responsive-modular-scale(font-size, 2, $ms); 160 @include harmony.responsive-modular-scale(font-size, 2, $ms);
161 } 161 }
162 } 162 }
163 163
164 @include expect { 164 @include expect {
165 h3 { 165 h3 {
166 font-size: 1rem; 166 font-size: 1rem;
167 167
168 @media (min-width: 320px) and (max-width: 640px) { 168 @media (min-width: 320px) and (max-width: 640px) {
169 font-size: calc(1rem + 0 * (100vw - #{$rem320px}) / #{$diff320px}); 169 font-size: calc(1rem + 0 * (100vw - #{$rem320px}) / #{$diff320px});
170 } 170 }
171 171
172 @media (min-width: 640px) { 172 @media (min-width: 640px) {
173 font-size: 1rem; 173 font-size: 1rem;
174 } 174 }
175 } 175 }
176 176
177 h2 { 177 h2 {
178 font-size: 1.0263162365rem; 178 font-size: 1.0263162365rem;
179 179
180 @media (min-width: 320px) and (max-width: 640px) { 180 @media (min-width: 320px) and (max-width: 640px) {
181 font-size: calc(1.0263162365rem + 0.1310911709 * (100vw - #{$rem320px}) / #{$diff320px}); 181 font-size: calc(1.0263162365rem + .1310911709 * (100vw - #{$rem320px}) / #{$diff320px});
182 } 182 }
183 183
184 @media (min-width: 640px) { 184 @media (min-width: 640px) {
185 font-size: 1.1574074074rem; 185 font-size: 1.1574074074rem;
186 } 186 }
187 } 187 }
188 188
189 h1 { 189 h1 {
190 font-size: 1.1rem; 190 font-size: 1.1rem;
191 191
192 @media (min-width: 320px) and (max-width: 640px) { 192 @media (min-width: 320px) and (max-width: 640px) {
193 font-size: calc(1.1rem + 0.1 * (100vw - #{$rem320px}) / #{$diff320px}); 193 font-size: calc(1.1rem + .1 * (100vw - #{$rem320px}) / #{$diff320px});
194 } 194 }
195 195
196 @media (min-width: 640px) { 196 @media (min-width: 640px) {
197 font-size: 1.2rem; 197 font-size: 1.2rem;
198 } 198 }
199 } 199 }
200 } 200 }
201 } 201 }
202 202
203 @include assert('Double-stranded, non-fluid') { 203 @include assert('Double-stranded, non-fluid') {
204 $ms: ( 204 $ms: (
205 320px: (1rem 2rem, 1.1), 205 320px: (1rem 2rem, 1.1),
206 640px: (1rem 2rem, 1.2) 206 640px: (1rem 2rem, 1.2)
207 ); 207 );
208 208
209 $rem320px: functions.px-to-rem(320px); 209 $rem320px: functions.px-to-rem(320px);
210 $rem640px: functions.px-to-rem(640px); 210 $rem640px: functions.px-to-rem(640px);
211 $diff320px: functions.strip-unit($rem640px - $rem320px); 211 $diff320px: functions.strip-unit($rem640px - $rem320px);
212 212
213 @include output { 213 @include output {
214 h3 { 214 h3 {
215 @include harmony.responsive-modular-scale(font-size, 0, $ms, false); 215 @include harmony.responsive-modular-scale(font-size, 0, $ms, false);
216 } 216 }
217 217
218 h2 { 218 h2 {
219 @include harmony.responsive-modular-scale(font-size, 1, $ms, false); 219 @include harmony.responsive-modular-scale(font-size, 1, $ms, false);
220 } 220 }
221 221
222 h1 { 222 h1 {
223 @include harmony.responsive-modular-scale(font-size, 2, $ms, false); 223 @include harmony.responsive-modular-scale(font-size, 2, $ms, false);
224 } 224 }
225 } 225 }
226 226
227 @include expect { 227 @include expect {
228 h3 { 228 h3 {
229 font-size: 1rem; 229 font-size: 1rem;
230 230
231 @media (min-width: 640px) { 231 @media (min-width: 640px) {
232 font-size: 1rem; 232 font-size: 1rem;
233 } 233 }
234 } 234 }
235 235
236 h2 { 236 h2 {
237 font-size: 1.0263162365rem;; 237 font-size: 1.0263162365rem;
238 238
239 @media (min-width: 640px) { 239 @media (min-width: 640px) {
240 font-size: 1.1574074074rem;; 240 font-size: 1.1574074074rem;;
241 } 241 }
242 } 242 }
243 243
244 h1 { 244 h1 {
245 font-size: 1.1rem; 245 font-size: 1.1rem;
246 246
247 @media (min-width: 640px) { 247 @media (min-width: 640px) {
248 font-size: 1.2rem; 248 font-size: 1.2rem;
249 } 249 }
250 } 250 }
251 } 251 }
252 } 252 }
253 } 253 }
254} 254}
diff --git a/test/_props.scss b/test/_props.scss
index d8b550b..f8c85ee 100644
--- a/test/_props.scss
+++ b/test/_props.scss
@@ -6,290 +6,273 @@
6@use '../src/props'; 6@use '../src/props';
7 7
8@include describe('Property trees') { 8@include describe('Property trees') {
9 @include it('Validate names') { 9 @include it('Save / Delete') {
10 $map-valid: ( 10 $map: (
11 --background: #fff, 11 --background: #fff,
12 --text: #000, 12 --text: #000,
13 --buttons: ( 13 --buttons: (
14 --primary: ( 14 --primary: (
15 --background: #f00, 15 --background: #f00,
16 --text: #fff 16 --text: #fff
17 ) 17 )
18 ) 18 )
19 ); 19 );
20 20
21 $map-invalid: ( 21 @include assert-equal(props.store($map), null, 'Save default tree');
22 --background: #fff, 22 @include assert-equal(props.clear(), null, 'Delete default tree');
23 --text: #000, 23 }
24 --buttons: (
25 --primary: (
26 background: #f00,
27 text: #fff
28 )
29 )
30 );
31 24
32 @include assert-equal(props.validate($map-valid), true, 'Check valid map'); 25 @include it('Read') {
33 @include assert-equal(props.validate($map-invalid), false, 'Check invalid map'); 26 $map1: (
34 } 27 --background: #fff,
28 --text: #000,
29 --buttons: (
30 --primary: (
31 --background: #f00,
32 --text: #fff
33 )
34 )
35 );
35 36
36 @include it('Save / Delete') { 37 $map2: (
37 $map: ( 38 --background: #222,
38 --background: #fff, 39 --text: #fff,
39 --text: #000, 40 --buttons: (
40 --buttons: ( 41 --primary: (
41 --primary: ( 42 --background: #f00,
42 --background: #f00, 43 --text: #fff
43 --text: #fff 44 )
44 ) 45 )
45 ) 46 );
46 );
47 47
48 @include assert-equal(props.store($map), null, 'Save default tree'); 48 $map3: (
49 @include assert-equal(props.clear(), null, 'Delete default tree'); 49 --background: #666,
50 } 50 --text: #222,
51 --buttons: (
52 --primary: (
53 --background: #0f0,
54 --text: #000
55 )
56 )
57 );
51 58
52 @include it('Read') { 59 @include assert-equal(props.store($map1), null, 'Save default tree');
53 $map1: ( 60 @include assert-equal(props.store($map2, 'test'), null, 'Save "test" tree');
54 --background: #fff,
55 --text: #000,
56 --buttons: (
57 --primary: (
58 --background: #f00,
59 --text: #fff
60 )
61 )
62 );
63 61
64 $map2: ( 62 @include props.namespace('ns') {
65 --background: #222, 63 @include assert-equal(props.store($map3, 'namespaced'), null, 'Save "namespaced" tree');
66 --text: #fff, 64 }
67 --buttons: (
68 --primary: (
69 --background: #f00,
70 --text: #fff
71 )
72 )
73 );
74 65
75 $map3: ( 66 @include assert-equal(props.get-static(--background), map.get($map1, --background), 'Get --background in default');
76 --background: #666, 67 @include assert-equal(props.get-static(--buttons --primary --background), map.get($map1, --buttons, --primary, --background), 'Get --buttons --primary --background in default');
77 --text: #222, 68 @include assert-equal(props.get-static(--box, $default: false), false, 'Get nonexistent in default');
78 --buttons: (
79 --primary: (
80 --background: #0f0,
81 --text: #000
82 )
83 )
84 );
85 69
86 @include assert-equal(props.store($map1), null, 'Save default tree'); 70 @include assert-equal(props.get-static(--background, 'test'), map.get($map2, --background), 'Get --background in "test"');
87 @include assert-equal(props.store($map2, 'test'), null, 'Save "test" tree'); 71 @include assert-equal(props.get-static(--buttons --primary --background, 'test'), map.get($map2, --buttons, --primary, --background), 'Get --buttons --primary --background in "test"');
72 @include assert-equal(props.get-static(--box, 'test', $default: false), false, 'Get nonexistent in "test"');
73
74 @include assert-equal(props.get-static(--background, 'namespaced', $default: false), false, 'Get --background in "namespaced"');
75 @include assert-equal(props.get-static(--ns --background, 'namespaced'), map.get($map3, --background), 'Get --ns --background in "namespaced"');
76 @include props.namespace('ns') {
77 @include assert-equal(props.get-static(--background, 'namespaced'), map.get($map3, --background), 'Get namespaced --background in "namespaced"');
78 @include assert-equal(props.get-static(--buttons --primary --background, 'namespaced'), map.get($map3, --buttons, --primary, --background), 'Get namespaced --buttons --primary --background in "namespaced"');
79 @include assert-equal(props.get-static(--box, 'namespaced', $default: false), false, 'Get namespaced nonexistent in "namespaced"');
80 }
88 81
89 @include props.namespace('ns') { 82 @include assert-equal(props.clear(), null, 'Delete default tree');
90 @include assert-equal(props.store($map3, 'namespaced'), null, 'Save "namespaced" tree'); 83 @include assert-equal(props.clear('test'), null, 'Delete "test" tree');
91 } 84 @include assert-equal(props.clear('namespaced'), null, 'Delete "namespaced" tree');
85 }
92 86
93 @include assert-equal(props.get-static(--background), map-get($map1, --background), 'Get --background in default'); 87 @include it('Overwrite') {
94 @include assert-equal(props.get-static(--buttons --primary --background), map-get($map1, --buttons, --primary, --background), 'Get --buttons --primary --background in default'); 88 $map1: (
95 @include assert-equal(props.get-static(--box, $default: false), false, 'Get nonexistent in default'); 89 --background: #fff,
90 --buttons: (
91 --primary: (
92 --background: #f00,
93 --text: #fff
94 )
95 )
96 );
96 97
97 @include assert-equal(props.get-static(--background, 'test'), map-get($map2, --background), 'Get --background in "test"'); 98 $map2: (
98 @include assert-equal(props.get-static(--buttons --primary --background, 'test'), map-get($map2, --buttons, --primary, --background), 'Get --buttons --primary --background in "test"'); 99 --background: #eee,
99 @include assert-equal(props.get-static(--box, 'test', $default: false), false, 'Get nonexistent in "test"'); 100 --text: #000,
100 101 --buttons: (
101 @include assert-equal(props.get-static(--background, 'namespaced', $default: false), false, 'Get --background in "namespaced"'); 102 --primary: (
102 @include assert-equal(props.get-static(--ns --background, 'namespaced'), map-get($map3, --background), 'Get --ns --background in "namespaced"'); 103 --background: #00f
103 @include props.namespace('ns') { 104 )
104 @include assert-equal(props.get-static(--background, 'namespaced'), map-get($map3, --background), 'Get namespaced --background in "namespaced"'); 105 )
105 @include assert-equal(props.get-static(--buttons --primary --background, 'namespaced'), map-get($map3, --buttons, --primary, --background), 'Get namespaced --buttons --primary --background in "namespaced"'); 106 );
106 @include assert-equal(props.get-static(--box, 'namespaced', $default: false), false, 'Get namespaced nonexistent in "namespaced"');
107 }
108 107
109 @include assert-equal(props.clear(), null, 'Delete default tree'); 108 @include assert-equal(props.store($map1), null, 'Save default tree');
110 @include assert-equal(props.clear('test'), null, 'Delete "test" tree'); 109 @include assert-equal(props.store($map2, $merge: true), null, 'Overwrite default tree');
111 @include assert-equal(props.clear('namespaced'), null, 'Delete "namespaced" tree');
112 }
113 110
114 @include it('Overwrite') { 111 @include assert-equal(props.get-static(), map.deep-merge($map1, $map2), 'After update, get whole map');
115 $map1: ( 112 @include assert-equal(props.get-static(--background), map.get($map2, --background), 'After update, get --background');
116 --background: #fff, 113 @include assert-equal(props.get-static(--text), map.get($map2, --text), 'After update, get --text');
117 --buttons: ( 114 @include assert-equal(props.get-static(--buttons --primary --text), map.get($map1, --buttons, --primary, --text), 'After update, get --buttons --primary --text');
118 --primary: (
119 --background: #f00,
120 --text: #fff
121 )
122 )
123 );
124 115
125 $map2: ( 116 @include assert-equal(props.clear(), null, 'Delete default tree');
126 --background: #eee, 117 }
127 --text: #000,
128 --buttons: (
129 --primary: (
130 --background: #00f
131 )
132 )
133 );
134 118
135 @include assert-equal(props.store($map1), null, 'Save default tree'); 119 @include it('Native assignment') {
136 @include assert-equal(props.store($map2, $merge: true), null, 'Overwrite default tree'); 120 $map: (
121 --background: #fff,
122 --text: #000,
123 --buttons: (
124 --primary: (
125 --background: #f00,
126 --text: #fff
127 ),
128 --default: (
129 --background: #ddd,
130 --text: #000
131 )
132 )
133 );
137 134
138 @include assert-equal(props.get-static(), map.deep-merge($map1, $map2), 'After update, get whole map'); 135 @include assert('Simple') {
139 @include assert-equal(props.get-static(--background), map-get($map2, --background), 'After update, get --background'); 136 @include props.store($map);
140 @include assert-equal(props.get-static(--text), map-get($map2, --text), 'After update, get --text');
141 @include assert-equal(props.get-static(--buttons --primary --text), map-get($map1, --buttons, --primary, --text), 'After update, get --buttons --primary --text');
142 137
143 @include assert-equal(props.clear(), null, 'Delete default tree'); 138 @include output {
144 } 139 @include props.assign;
140 }
145 141
146 @include it('Native assignment') { 142 @include expect {
147 $map: ( 143 --background: #{map.get($map, --background)};
148 --background: #fff, 144 --text: #{map.get($map, --text)};
149 --text: #000, 145 --buttons--primary--background: #{map.get($map, --buttons, --primary, --background)};
150 --buttons: ( 146 --buttons--primary--text: #{map.get($map, --buttons, --primary, --text)};
151 --primary: ( 147 --buttons--default--background: #{map.get($map, --buttons, --default, --background)};
152 --background: #f00, 148 --buttons--default--text: #{map.get($map, --buttons, --default, --text)};
153 --text: #fff 149 }
154 ),
155 --default: (
156 --background: #ddd,
157 --text: #000
158 )
159 )
160 );
161 150
162 @include assert('Simple') { 151 @include props.clear;
163 @include props.store($map); 152 }
164 153
165 @include output { 154 @include assert('Filtered') {
166 @include props.assign; 155 @include props.store($map);
167 }
168 156
169 @include expect { 157 @include output {
170 --background: #{map-get($map, --background)}; 158 @include props.assign($skip: --buttons);
171 --text: #{map-get($map, --text)}; 159 }
172 --buttons--primary--background: #{map-get($map, --buttons, --primary, --background)};
173 --buttons--primary--text: #{map-get($map, --buttons, --primary, --text)};
174 --buttons--default--background: #{map-get($map, --buttons, --default, --background)};
175 --buttons--default--text: #{map-get($map, --buttons, --default, --text)};
176 }
177 160
178 @include props.clear; 161 @include expect {
179 } 162 --background: #{map.get($map, --background)};
163 --text: #{map.get($map, --text)};
164 }
180 165
181 @include assert('Filtered') { 166 @include props.clear;
182 @include props.store($map); 167 }
183 168
184 @include output { 169 @include assert('Namespaced') {
185 @include props.assign($skip: --buttons); 170 @include props.namespace('ns') {
186 } 171 @include props.store($map);
172 }
187 173
188 @include expect { 174 @include output {
189 --background: #{map-get($map, --background)}; 175 @include props.assign;
190 --text: #{map-get($map, --text)}; 176 }
191 }
192 177
193 @include props.clear; 178 @include expect {
194 } 179 --ns--background: #{map.get($map, --background)};
180 --ns--text: #{map.get($map, --text)};
181 --ns--buttons--primary--background: #{map.get($map, --buttons, --primary, --background)};
182 --ns--buttons--primary--text: #{map.get($map, --buttons, --primary, --text)};
183 --ns--buttons--default--background: #{map.get($map, --buttons, --default, --background)};
184 --ns--buttons--default--text: #{map.get($map, --buttons, --default, --text)};
185 }
195 186
196 @include assert('Namespaced') { 187 @include props.clear;
197 @include props.namespace('ns') { 188 }
198 @include props.store($map); 189 }
199 }
200 190
201 @include output { 191 @include it('Native get') {
202 @include props.assign; 192 $map: (
203 } 193 --background: #fff,
194 --text: #000,
195 --buttons: (
196 --primary: (
197 --background: #f00,
198 --text: #fff
199 ),
200 --default: (
201 --background: #ddd,
202 --text: #000
203 )
204 )
205 );
204 206
205 @include expect { 207 @include assert-equal(props.store($map), null, 'Save default tree');
206 --ns--background: #{map-get($map, --background)};
207 --ns--text: #{map-get($map, --text)};
208 --ns--buttons--primary--background: #{map-get($map, --buttons, --primary, --background)};
209 --ns--buttons--primary--text: #{map-get($map, --buttons, --primary, --text)};
210 --ns--buttons--default--background: #{map-get($map, --buttons, --default, --background)};
211 --ns--buttons--default--text: #{map-get($map, --buttons, --default, --text)};
212 }
213 208
214 @include props.clear; 209 @include assert-equal(props.get(--background), var(--background), 'Get --background');
215 } 210 @include assert-equal(props.get(--buttons --primary --text), var(--buttons--primary--text), 'Get --buttons --primary --text');
216 } 211 @include assert-equal(props.get(--buttons --secondary --text, $default: false), var(--buttons--secondary--text, false), 'Get --buttons --secondary --text with default');
212 @include props.namespace('buttons') {
213 @include assert-equal(props.get(--primary --text), var(--buttons--primary--text), 'Get via namespace "buttons" --primary --text');
214 @include assert-equal(props.get(--secondary --text, $default: false), var(--buttons--secondary--text, false), 'Get via namespace "buttons" --secondary --text with default');
215 }
216 @include assert-equal(props.get(--buttons), (
217 --primary: (
218 --background: var(--buttons--primary--background),
219 --text: var(--buttons--primary--text)
220 ),
221 --default: (
222 --background: var(--buttons--default--background),
223 --text: var(--buttons--default--text)
224 )
225 ), 'Get --buttons recursively');
217 226
218 @include it('Native get') { 227 @include assert-equal(props.clear(), null, 'Delete default tree');
219 $map: ( 228 }
220 --background: #fff,
221 --text: #000,
222 --buttons: (
223 --primary: (
224 --background: #f00,
225 --text: #fff
226 ),
227 --default: (
228 --background: #ddd,
229 --text: #000
230 )
231 )
232 );
233 229
234 @include assert-equal(props.store($map), null, 'Save default tree'); 230 @include it('References') {
231 $map1: (
232 --background: #fff,
233 --text: #000,
234 --buttons: (
235 --primary: (
236 --background: #f00,
237 --text: #fff
238 )
239 )
240 );
235 241
236 @include assert-equal(props.get(--background), var(--background), 'Get --background'); 242 $map2: (
237 @include assert-equal(props.get(--buttons --primary --text), var(--buttons--primary--text), 'Get --buttons --primary --text'); 243 --background: #eee,
238 @include assert-equal(props.get(--buttons --secondary --text, $default: false), var(--buttons--secondary--text, false), 'Get --buttons --secondary --text with default'); 244 --buttons: (
239 @include props.namespace('buttons') { 245 --primary: (
240 @include assert-equal(props.get(--primary --text), var(--buttons--primary--text), 'Get via namespace "buttons" --primary --text'); 246 --background: props.ref($key: --background)
241 @include assert-equal(props.get(--secondary --text, $default: false), var(--buttons--secondary--text, false), 'Get via namespace "buttons" --secondary --text with default'); 247 ),
242 } 248 --default: props.ref($key: --buttons --primary)
249 )
250 );
243 251
244 @include assert-equal(props.clear(), null, 'Delete default tree'); 252 @include assert-equal(props.store($map1), null, 'Save default tree');
245 } 253 @include assert-equal(props.store($map2, 'second'), null, 'Save "second" tree');
246 254
247 @include it('References') { 255 @include assert-equal(props.get-static(--buttons --primary --background, 'second'), map.get($map1, --background), 'Get referenced value');
248 $map1: ( 256 @include assert-equal(props.get(--buttons --primary --background, 'second'), var(--buttons--primary--background), 'Get referenced value, native');
249 --background: #fff,
250 --text: #000,
251 --buttons: (
252 --primary: (
253 --background: #f00,
254 --text: #fff
255 )
256 )
257 );
258 257
259 $map2: ( 258 @include assert-equal(props.get-static(--buttons --default, 'second'), map.get($map1, --buttons, --primary), 'Get referenced subtree, whole');
260 --background: #eee, 259 @include assert-equal(props.get-static(--buttons --default --background, 'second'), map.get($map1, --buttons, --primary, --background), 'Get referenced subtree, inner value');
261 --buttons: ( 260 @include assert-equal(props.get(--buttons --default --background, 'second'), var(--buttons--default--background), 'Get referenced subtree, native');
262 --primary: ( 261
263 --background: props.ref($key: --background) 262 @include assert('Native assignment') {
264 ), 263 @include output {
265 --default: props.ref($key: --buttons --primary) 264 @include props.assign('second');
266 ) 265 }
267 );
268 266
269 @include assert-equal(props.store($map1), null, 'Save default tree'); 267 @include expect {
270 @include assert-equal(props.store($map2, 'second'), null, 'Save "second" tree'); 268 --background: #{map.get($map2, --background)};
269 --buttons--primary--background: #{map.get($map1, --background)};
270 --buttons--default--background: #{map.get($map1, --buttons, --primary, --background)};
271 --buttons--default--text: #{map.get($map1, --buttons, --primary, --text)};
272 }
273 }
271 274
272 @include assert-equal(props.get-static(--buttons --primary --background, 'second'), map-get($map1, --background), 'Get referenced value'); 275 @include assert-equal(props.clear(), null, 'Delete default tree');
273 @include assert-equal(props.get(--buttons --primary --background, 'second'), var(--buttons--primary--background), 'Get referenced value, native'); 276 @include assert-equal(props.clear('second'), null, 'Delete "second" tree');
274 277 }
275 @include assert-equal(props.get-static(--buttons --default, 'second'), map-get($map1, --buttons, --primary), 'Get referenced subtree, whole');
276 @include assert-equal(props.get-static(--buttons --default --background, 'second'), map-get($map1, --buttons, --primary, --background), 'Get referenced subtree, inner value');
277 @include assert-equal(props.get(--buttons --default --background, 'second'), var(--buttons--default--background), 'Get referenced subtree, native');
278
279 @include assert('Native assignment') {
280 @include output {
281 @include props.assign('second');
282 }
283
284 @include expect {
285 --background: #{map-get($map2, --background)};
286 --buttons--primary--background: #{map-get($map1, --background)};
287 --buttons--default--background: #{map-get($map1, --buttons, --primary, --background)};
288 --buttons--default--text: #{map-get($map1, --buttons, --primary, --text)};
289 }
290 }
291
292 @include assert-equal(props.clear(), null, 'Delete default tree');
293 @include assert-equal(props.clear('second'), null, 'Delete "second" tree');
294 }
295} 278}
diff --git a/test/_responsive.scss b/test/_responsive.scss
index 6780ae6..aa76cfd 100644
--- a/test/_responsive.scss
+++ b/test/_responsive.scss
@@ -3,11 +3,11 @@
3@use '../src/responsive'; 3@use '../src/responsive';
4 4
5@include describe('responsive') { 5@include describe('responsive') {
6 @include it('fluid-calc') { 6 @include it('fluid-calc') {
7 $rem600px: functions.px-to-rem(600px); 7 $rem600px: functions.px-to-rem(600px);
8 $rem800px: functions.px-to-rem(800px); 8 $rem800px: functions.px-to-rem(800px);
9 9
10 @include assert-equal('#{responsive.fluid-calc(2rem, 4rem, 600px, 800px)}', 'calc(2rem + 2 * (100vw - #{$rem600px}) / #{functions.strip-unit($rem800px - $rem600px)})', 'Responsive value from 2rem to 4rem over 600px to 800px'); 10 @include assert-equal('#{responsive.fluid-calc(2rem, 4rem, 600px, 800px)}', 'calc(2rem + 2 * (100vw - #{$rem600px}) / #{functions.strip-unit($rem800px - $rem600px)})', 'Responsive value from 2rem to 4rem over 600px to 800px');
11 @include assert-equal('#{responsive.fluid-calc(4px, 12px, 600px, 800px)}', 'calc(4px + 8 * (100vw - 600px) / 200)', 'Responsive value from 4px to 12px over 600px to 800px'); 11 @include assert-equal('#{responsive.fluid-calc(4px, 12px, 600px, 800px)}', 'calc(4px + 8 * (100vw - 600px) / 200)', 'Responsive value from 4px to 12px over 600px to 800px');
12 } 12 }
13} 13}
diff --git a/test/bem/_at-theme.scss b/test/bem/_at-theme.scss
index 29a4eba..83ea4d1 100644
--- a/test/bem/_at-theme.scss
+++ b/test/bem/_at-theme.scss
@@ -10,49 +10,49 @@
10// 10//
11 11
12@include it('at-theme') { 12@include it('at-theme') {
13 @include assert('single theme') { /// 1 /// 13 @include assert('single theme') { /// 1 ///
14 @include output(false) { 14 @include output(false) {
15 @include bem.block('something') { 15 @include bem.block('something') {
16 @include bem.at-theme('theme') { 16 @include bem.at-theme('theme') {
17 font-size: 2em; 17 font-size: 2em;
18 } 18 }
19 } 19 }
20 } 20 }
21 21
22 @include expect(false) { 22 @include expect(false) {
23 .t-theme .something, 23 .t-theme .something,
24 [class*=' t-'] .t-theme .something, 24 [class*=' t-'] .t-theme .something,
25 [class^='t-'] .t-theme .something { 25 [class^='t-'] .t-theme .something {
26 font-size: 2em; 26 font-size: 2em;
27 } 27 }
28 } 28 }
29 } 29 }
30 30
31 @include assert('with sub-theme') { /// 2 /// 31 @include assert('with sub-theme') { /// 2 ///
32 @include output(false) { 32 @include output(false) {
33 @include bem.block('something') { 33 @include bem.block('something') {
34 @include bem.at-theme('theme') { 34 @include bem.at-theme('theme') {
35 font-size: 2em; 35 font-size: 2em;
36 } 36 }
37 37
38 @include bem.at-theme('theme', 'subtheme') { 38 @include bem.at-theme('theme', 'subtheme') {
39 font-size: 3em; 39 font-size: 3em;
40 } 40 }
41 } 41 }
42 } 42 }
43 43
44 @include expect(false) { 44 @include expect(false) {
45 .t-theme .something, 45 .t-theme .something,
46 [class*=' t-'] .t-theme .something, 46 [class*=' t-'] .t-theme .something,
47 [class^='t-'] .t-theme .something { 47 [class^='t-'] .t-theme .something {
48 font-size: 2em; 48 font-size: 2em;
49 } 49 }
50 50
51 .t-theme .t-subtheme .something, 51 .t-theme .t-subtheme .something,
52 [class*=' t-'] .t-theme .t-subtheme .something, 52 [class*=' t-'] .t-theme .t-subtheme .something,
53 [class^='t-'] .t-theme .t-subtheme .something { 53 [class^='t-'] .t-theme .t-subtheme .something {
54 font-size: 3em; 54 font-size: 3em;
55 } 55 }
56 } 56 }
57 } 57 }
58} 58}
diff --git a/test/bem/_block.scss b/test/bem/_block.scss
index fb3a545..e883567 100644
--- a/test/bem/_block.scss
+++ b/test/bem/_block.scss
@@ -1,5 +1,6 @@
1// sass-lint:disable class-name-format force-element-nesting force-pseudo-nesting mixins-before-declarations 1// sass-lint:disable class-name-format force-element-nesting force-pseudo-nesting mixins-before-declarations
2 2
3@use 'sass:map';
3@use 'true' as *; 4@use 'true' as *;
4@use '../../src/bem'; 5@use '../../src/bem';
5 6
@@ -12,77 +13,83 @@
12// 13//
13 14
14@include it('block') { 15@include it('block') {
15 @include assert('without namespace') { /// 1 /// 16 @include assert('without namespace') { /// 1 ///
16 @include output(false) { 17 @include output(false) {
17 @include bem.block('something') { 18 @include bem.block('something') {
18 font-size: 1em; 19 font-size: 1em;
19 } 20 }
20 } 21 }
21 22
22 @include expect(false) { 23 @include expect(false) {
23 .something { 24 .something {
24 font-size: 1em; 25 font-size: 1em;
25 } 26 }
26 } 27 }
27 } 28 }
28 29
29 @each $ns in map-keys(bem.$namespaces) { 30 @each $ns in map.keys(bem.$namespaces) {
30 @include assert('with namespace "#{$ns}"') { /// 2 /// 31 @include assert('with namespace "#{$ns}"') { /// 2 ///
31 @include output(false) { 32 @include output(false) {
32 @include bem.block('something', $ns) { 33 @include bem.block('something', $ns) {
33 font-size: 1em; 34 font-size: 1em;
34 } 35 }
35 } 36 }
36 37
37 @include expect(false) { 38 @include expect(false) {
38 @if $ns != 'theme' { 39 @layer #{$ns} {
39 .#{map-get(bem.$namespaces, $ns)}-something { 40 @if $ns != 'theme' {
40 font-size: 1em; 41 .#{map-get(bem.$namespaces, $ns)}-something {
41 } 42 font-size: 1em;
42 } @else { 43 }
43 .t-something, 44 } @else {
44 [class*=' t-'] .t-something, 45 .t-something,
45 [class^='t-'] .t-something { 46 [class*=' t-'] .t-something,
46 font-size: 1em; 47 [class^='t-'] .t-something {
47 } 48 font-size: 1em;
48 } 49 }
49 } 50 }
50 } 51 }
51 } 52 }
53 }
54 }
52 55
53 @include assert('nested') { /// 3 /// 56 @include assert('nested') { /// 3 ///
54 @include output(false) { 57 @include output(false) {
55 @include bem.theme('theme') { 58 @include bem.theme('theme') {
56 @include bem.theme('subtheme') { 59 @include bem.theme('subtheme') {
57 @include bem.block('something') { 60 @include bem.block('something') {
58 font-size: 2em; 61 font-size: 2em;
59 } 62 }
60 } 63 }
61 } 64 }
62 } 65 }
63 66
64 @include expect(false) { 67 @include expect(false) {
65 .t-theme .t-subtheme .something, 68 @layer theme {
66 [class*=' t-'] .t-theme .t-subtheme .something, 69 @layer theme {
67 [class^='t-'] .t-theme .t-subtheme .something { 70 .t-theme .t-subtheme .something,
68 font-size: 2em; 71 [class*=' t-'] .t-theme .t-subtheme .something,
69 } 72 [class^='t-'] .t-theme .t-subtheme .something {
70 } 73 font-size: 2em;
71 } 74 }
75 }
76 }
77 }
78 }
72 79
73 @include assert('within selector') { /// 4 /// 80 @include assert('within selector') { /// 4 ///
74 @include output(false) { 81 @include output(false) {
75 .sel { 82 .sel {
76 @include bem.block('something') { 83 @include bem.block('something') {
77 font-size: 2em; 84 font-size: 2em;
78 } 85 }
79 } 86 }
80 } 87 }
81 88
82 @include expect(false) { 89 @include expect(false) {
83 .sel .something { 90 .sel .something {
84 font-size: 2em; 91 font-size: 2em;
85 } 92 }
86 } 93 }
87 } 94 }
88} 95}
diff --git a/test/bem/_composed-of.scss b/test/bem/_composed-of.scss
index fcbf2c4..6a5f4ba 100644
--- a/test/bem/_composed-of.scss
+++ b/test/bem/_composed-of.scss
@@ -1,5 +1,6 @@
1// sass-lint:disable class-name-format force-element-nesting force-pseudo-nesting mixins-before-declarations 1// sass-lint:disable class-name-format force-element-nesting force-pseudo-nesting mixins-before-declarations
2 2
3@use 'sass:map';
3@use 'true' as *; 4@use 'true' as *;
4@use '../../src/bem'; 5@use '../../src/bem';
5 6
@@ -12,141 +13,151 @@
12// 13//
13 14
14@include it('composed-of') { 15@include it('composed-of') {
15 @include assert('without namespace, single') { /// 1 /// 16 @include assert('without namespace, single') { /// 1 ///
16 @include output(false) { 17 @include output(false) {
17 @include bem.block('something') { 18 @include bem.block('something') {
18 font-size: 1em; 19 font-size: 1em;
19 } 20 }
20 21
21 @include bem.block('another') { 22 @include bem.block('another') {
22 @include bem.composed-of('something'); 23 @include bem.composed-of('something');
23 24
24 font-size: 2em; 25 font-size: 2em;
25 } 26 }
26 } 27 }
27 28
28 @include expect(false) { 29 @include expect(false) {
29 .something { 30 .something {
30 font-size: 1em; 31 font-size: 1em;
31 } 32 }
32 33
33 .another { 34 .another {
34 font-size: 2em; 35 font-size: 2em;
35 } 36 }
36 } 37 }
37 } 38 }
38 39
39 @each $ns in map-keys(bem.$namespaces) { 40 @each $ns in map.keys(bem.$namespaces) {
40 @include assert('with namespace "#{$ns}", single') { /// 2 /// 41 @include assert('with namespace "#{$ns}", single') { /// 2 ///
41 @include output(false) { 42 @include output(false) {
42 @include bem.block('something', $ns) { 43 @include bem.block('something', $ns) {
43 font-size: 1em; 44 font-size: 1em;
44 } 45 }
45 46
46 @include bem.block('another') { 47 @include bem.block('another') {
47 @include bem.composed-of('something' $ns); 48 @include bem.composed-of('something' $ns);
48 49
49 font-size: 2em; 50 font-size: 2em;
50 } 51 }
51 } 52 }
52 53
53 @include expect(false) { 54 @include expect(false) {
54 @if $ns != 'theme' { 55 @layer #{$ns} {
55 .#{map-get(bem.$namespaces, $ns)}-something { 56 @if $ns != 'theme' {
56 font-size: 1em; 57 .#{map.get(bem.$namespaces, $ns)}-something {
57 } 58 font-size: 1em;
58 } @else { 59 }
59 .t-something, 60 } @else {
60 [class*=' t-'] .t-something, 61 .t-something,
61 [class^='t-'] .t-something { 62 [class*=' t-'] .t-something,
62 font-size: 1em; 63 [class^='t-'] .t-something {
63 } 64 font-size: 1em;
64 } 65 }
66 }
67 }
65 68
66 .another { 69 .another {
67 font-size: 2em; 70 font-size: 2em;
68 } 71 }
69 } 72 }
70 } 73 }
71 } 74 }
72 75
73 @include assert('without namespace, multiple') { /// 3 /// 76 @include assert('without namespace, multiple') { /// 3 ///
74 @include output(false) { 77 @include output(false) {
75 @include bem.block('something') { 78 @include bem.block('something') {
76 font-size: 1em; 79 font-size: 1em;
77 } 80 }
78 81
79 @include bem.block('somethingElse') { 82 @include bem.block('somethingElse') {
80 font-size: 1em; 83 font-size: 1em;
81 } 84 }
82 85
83 @include bem.block('another') { 86 @include bem.block('another') {
84 @include bem.composed-of('something', 'somethingElse'); 87 @include bem.composed-of('something', 'somethingElse');
85 88
86 font-size: 2em; 89 font-size: 2em;
87 } 90 }
88 } 91 }
89 92
90 @include expect(false) { 93 @include expect(false) {
91 .something { 94 .something {
92 font-size: 1em; 95 font-size: 1em;
93 } 96 }
94 97
95 .somethingElse { 98 .somethingElse {
96 font-size: 1em; 99 font-size: 1em;
97 } 100 }
98 101
99 .another { 102 .another {
100 font-size: 2em; 103 font-size: 2em;
101 } 104 }
102 } 105 }
103 } 106 }
104 107
105 @each $ns in map-keys(bem.$namespaces) { 108 @each $ns in map.keys(bem.$namespaces) {
106 @include assert('with namespace "#{$ns}", multiple') { /// 4 /// 109 @include assert('with namespace "#{$ns}", multiple') { /// 4 ///
107 @include output(false) { 110 @include output(false) {
108 @include bem.block('something', $ns) { 111 @include bem.block('something', $ns) {
109 font-size: 1em; 112 font-size: 1em;
110 } 113 }
111 114
112 @include bem.block('somethingElse', $ns) { 115 @include bem.block('somethingElse', $ns) {
113 font-size: 1em; 116 font-size: 1em;
114 } 117 }
115 118
116 @include bem.block('another') { 119 @include bem.block('another') {
117 @include bem.composed-of('something' $ns, 'somethingElse' $ns); 120 @include bem.composed-of('something' $ns, 'somethingElse' $ns);
118 121
119 font-size: 2em; 122 font-size: 2em;
120 } 123 }
121 } 124 }
122 125
123 @include expect(false) { 126 @include expect(false) {
124 @if $ns != 'theme' { 127 @if $ns != 'theme' {
125 .#{map-get(bem.$namespaces, $ns)}-something { 128 @layer #{$ns} {
126 font-size: 1em; 129 .#{map.get(bem.$namespaces, $ns)}-something {
127 } 130 font-size: 1em;
131 }
132 }
128 133
129 .#{map-get(bem.$namespaces, $ns)}-somethingElse { 134 @layer #{$ns} {
130 font-size: 1em; 135 .#{map.get(bem.$namespaces, $ns)}-somethingElse {
131 } 136 font-size: 1em;
132 } @else { 137 }
133 .t-something, 138 }
134 [class*=' t-'] .t-something, 139 } @else {
135 [class^='t-'] .t-something { 140 @layer #{$ns} {
136 font-size: 1em; 141 .t-something,
137 } 142 [class*=' t-'] .t-something,
143 [class^='t-'] .t-something {
144 font-size: 1em;
145 }
146 }
138 147
139 .t-somethingElse, 148 @layer #{$ns} {
140 [class*=' t-'] .t-somethingElse, 149 .t-somethingElse,
141 [class^='t-'] .t-somethingElse { 150 [class*=' t-'] .t-somethingElse,
142 font-size: 1em; 151 [class^='t-'] .t-somethingElse {
143 } 152 font-size: 1em;
144 } 153 }
154 }
155 }
145 156
146 .another { 157 .another {
147 font-size: 2em; 158 font-size: 2em;
148 } 159 }
149 } 160 }
150 } 161 }
151 } 162 }
152} 163}
diff --git a/test/bem/_element.scss b/test/bem/_element.scss
index c8839de..dd4efd4 100644
--- a/test/bem/_element.scss
+++ b/test/bem/_element.scss
@@ -22,473 +22,473 @@
22// 22//
23 23
24@include it('element') { 24@include it('element') {
25 @include assert('single element') { /// 1 /// 25 @include assert('single element') { /// 1 ///
26 @include output { 26 @include output {
27 @include bem.block('something') { 27 @include bem.block('something') {
28 @include bem.elem('child') { 28 @include bem.elem('child') {
29 font-size: 2em; 29 font-size: 2em;
30 } 30 }
31 } 31 }
32 } 32 }
33 33
34 @include expect { 34 @include expect {
35 .something__child { 35 .something__child {
36 font-size: 2em; 36 font-size: 2em;
37 } 37 }
38 } 38 }
39 } 39 }
40 40
41 @include assert('single element, manual selector in-between') { /// 2 /// 41 @include assert('single element, manual selector in-between') { /// 2 ///
42 @include output(false) { 42 @include output(false) {
43 @include bem.block('something') { 43 @include bem.block('something') {
44 &:hover { 44 &:hover {
45 @include bem.elem('child1') { 45 @include bem.elem('child1') {
46 font-size: 2em; 46 font-size: 2em;
47 } 47 }
48 } 48 }
49 49
50 .test & { 50 .test & {
51 @include bem.elem('child2') { 51 @include bem.elem('child2') {
52 font-size: 2em; 52 font-size: 2em;
53 } 53 }
54 } 54 }
55 } 55 }
56 } 56 }
57 57
58 @include expect(false) { 58 @include expect(false) {
59 .something:hover .something__child1 { 59 .something:hover .something__child1 {
60 font-size: 2em; 60 font-size: 2em;
61 } 61 }
62 62
63 .test .something__child2 { 63 .test .something__child2 {
64 font-size: 2em; 64 font-size: 2em;
65 } 65 }
66 } 66 }
67 } 67 }
68 68
69 @include assert('single element, modifier in-between') { /// 3 /// 69 @include assert('single element, modifier in-between') { /// 3 ///
70 @include output { 70 @include output {
71 @include bem.block('something') { 71 @include bem.block('something') {
72 @include bem.modifier('mod') { 72 @include bem.modifier('mod') {
73 @include bem.elem('child') { 73 @include bem.elem('child') {
74 font-size: 2em; 74 font-size: 2em;
75 } 75 }
76 } 76 }
77 } 77 }
78 } 78 }
79 79
80 @include expect { 80 @include expect {
81 .something--mod .something__child { 81 .something--mod .something__child {
82 font-size: 2em; 82 font-size: 2em;
83 } 83 }
84 } 84 }
85 } 85 }
86 86
87 @include assert('single element, nested') { /// 4 /// 87 @include assert('single element, nested') { /// 4 ///
88 @include output { 88 @include output {
89 @include bem.block('something') { 89 @include bem.block('something') {
90 @include bem.elem('child') { 90 @include bem.elem('child') {
91 font-size: 2em; 91 font-size: 2em;
92 92
93 @include bem.elem('subchild') { 93 @include bem.elem('subchild') {
94 font-size: 3em; 94 font-size: 3em;
95 } 95 }
96 } 96 }
97 } 97 }
98 } 98 }
99 99
100 @include expect { 100 @include expect {
101 .something__child { 101 .something__child {
102 font-size: 2em; 102 font-size: 2em;
103 } 103 }
104 104
105 .something__child .something__subchild { 105 .something__child .something__subchild {
106 font-size: 3em; 106 font-size: 3em;
107 } 107 }
108 } 108 }
109 } 109 }
110 110
111 @include assert('single element, nested, manual selector in-between') { /// 5 /// 111 @include assert('single element, nested, manual selector in-between') { /// 5 ///
112 @include output(false) { 112 @include output(false) {
113 @include bem.block('something') { 113 @include bem.block('something') {
114 &:hover { 114 &:hover {
115 @include bem.elem('child1') { 115 @include bem.elem('child1') {
116 font-size: 2em; 116 font-size: 2em;
117 117
118 @include bem.elem('subchild1') { 118 @include bem.elem('subchild1') {
119 font-size: 3em; 119 font-size: 3em;
120 } 120 }
121 } 121 }
122 } 122 }
123 123
124 .test & { 124 .test & {
125 @include bem.elem('child2') { 125 @include bem.elem('child2') {
126 font-size: 2em; 126 font-size: 2em;
127 127
128 @include bem.elem('subchild2') { 128 @include bem.elem('subchild2') {
129 font-size: 3em; 129 font-size: 3em;
130 } 130 }
131 } 131 }
132 } 132 }
133 133
134 @include bem.elem('child3') { 134 @include bem.elem('child3') {
135 font-size: 2em; 135 font-size: 2em;
136 136
137 &:hover { 137 &:hover {
138 @include bem.elem('subchild3') { 138 @include bem.elem('subchild3') {
139 font-size: 3em; 139 font-size: 3em;
140 } 140 }
141 } 141 }
142 142
143 .test & { 143 .test & {
144 @include bem.elem('subchild4') { 144 @include bem.elem('subchild4') {
145 font-size: 3em; 145 font-size: 3em;
146 } 146 }
147 } 147 }
148 } 148 }
149 } 149 }
150 } 150 }
151 151
152 @include expect(false) { 152 @include expect(false) {
153 .something:hover .something__child1 { 153 .something:hover .something__child1 {
154 font-size: 2em; 154 font-size: 2em;
155 } 155 }
156 156
157 .something:hover .something__child1 .something__subchild1 { 157 .something:hover .something__child1 .something__subchild1 {
158 font-size: 3em; 158 font-size: 3em;
159 } 159 }
160 160
161 .test .something__child2 { 161 .test .something__child2 {
162 font-size: 2em; 162 font-size: 2em;
163 } 163 }
164 164
165 .test .something__child2 .something__subchild2 { 165 .test .something__child2 .something__subchild2 {
166 font-size: 3em; 166 font-size: 3em;
167 } 167 }
168 168
169 .something__child3 { 169 .something__child3 {
170 font-size: 2em; 170 font-size: 2em;
171 } 171 }
172 172
173 .something__child3:hover .something__subchild3 { 173 .something__child3:hover .something__subchild3 {
174 font-size: 3em; 174 font-size: 3em;
175 } 175 }
176 176
177 .test .something__child3 .something__subchild4 { 177 .test .something__child3 .something__subchild4 {
178 font-size: 3em; 178 font-size: 3em;
179 } 179 }
180 } 180 }
181 } 181 }
182 182
183 @include assert('single element, nested, modifier in-between') { /// 6 /// 183 @include assert('single element, nested, modifier in-between') { /// 6 ///
184 @include output { 184 @include output {
185 @include bem.block('something') { 185 @include bem.block('something') {
186 @include bem.modifier('mod') { 186 @include bem.modifier('mod') {
187 @include bem.elem('child') { 187 @include bem.elem('child') {
188 font-size: 2em; 188 font-size: 2em;
189 189
190 @include bem.elem('subchild') { 190 @include bem.elem('subchild') {
191 font-size: 3em; 191 font-size: 3em;
192 } 192 }
193 } 193 }
194 } 194 }
195 195
196 @include bem.elem('child') { 196 @include bem.elem('child') {
197 font-size: 2em; 197 font-size: 2em;
198 198
199 @include bem.modifier('mod') { 199 @include bem.modifier('mod') {
200 @include bem.elem('subchild') { 200 @include bem.elem('subchild') {
201 font-size: 3em; 201 font-size: 3em;
202 } 202 }
203 } 203 }
204 } 204 }
205 } 205 }
206 } 206 }
207 207
208 @include expect { 208 @include expect {
209 .something--mod .something__child { 209 .something--mod .something__child {
210 font-size: 2em; 210 font-size: 2em;
211 } 211 }
212 212
213 .something--mod .something__child .something__subchild { 213 .something--mod .something__child .something__subchild {
214 font-size: 3em; 214 font-size: 3em;
215 } 215 }
216 216
217 .something__child { 217 .something__child {
218 font-size: 2em; 218 font-size: 2em;
219 } 219 }
220 220
221 .something__child--mod .something__subchild { 221 .something__child--mod .something__subchild {
222 font-size: 3em; 222 font-size: 3em;
223 } 223 }
224 } 224 }
225 } 225 }
226 226
227 @include assert('single element, in at-theme') { /// 7 /// 227 @include assert('single element, in at-theme') { /// 7 ///
228 @include output(false) { 228 @include output(false) {
229 @include bem.block('something') { 229 @include bem.block('something') {
230 @include bem.at-theme('dark') { 230 @include bem.at-theme('dark') {
231 @include bem.elem('child') { 231 @include bem.elem('child') {
232 font-size: 2em; 232 font-size: 2em;
233 } 233 }
234 } 234 }
235 } 235 }
236 } 236 }
237 237
238 @include expect(false) { 238 @include expect(false) {
239 .t-dark .something__child, 239 .t-dark .something__child,
240 [class*=' t-'] .t-dark .something__child, 240 [class*=' t-'] .t-dark .something__child,
241 [class^='t-'] .t-dark .something__child { 241 [class^='t-'] .t-dark .something__child {
242 font-size: 2em; 242 font-size: 2em;
243 } 243 }
244 } 244 }
245 } 245 }
246 246
247 @include assert('multiple elements') { /// 8 /// 247 @include assert('multiple elements') { /// 8 ///
248 @include output { 248 @include output {
249 @include bem.block('something') { 249 @include bem.block('something') {
250 @include bem.elem('child1', 'child2') { 250 @include bem.elem('child1', 'child2') {
251 font-size: 2em; 251 font-size: 2em;
252 } 252 }
253 } 253 }
254 } 254 }
255 255
256 @include expect { 256 @include expect {
257 .something__child1, 257 .something__child1,
258 .something__child2 { 258 .something__child2 {
259 font-size: 2em; 259 font-size: 2em;
260 } 260 }
261 } 261 }
262 } 262 }
263 263
264 @include assert('multiple elements, manual selector in-between') { /// 9 /// 264 @include assert('multiple elements, manual selector in-between') { /// 9 ///
265 @include output(false) { 265 @include output(false) {
266 @include bem.block('something') { 266 @include bem.block('something') {
267 &:hover { 267 &:hover {
268 @include bem.elem('child1', 'child2') { 268 @include bem.elem('child1', 'child2') {
269 font-size: 2em; 269 font-size: 2em;
270 } 270 }
271 } 271 }
272 272
273 .test & { 273 .test & {
274 @include bem.elem('child3', 'child4') { 274 @include bem.elem('child3', 'child4') {
275 font-size: 2em; 275 font-size: 2em;
276 } 276 }
277 } 277 }
278 } 278 }
279 } 279 }
280 280
281 @include expect(false) { 281 @include expect(false) {
282 .something:hover .something__child1, 282 .something:hover .something__child1,
283 .something:hover .something__child2 { 283 .something:hover .something__child2 {
284 font-size: 2em; 284 font-size: 2em;
285 } 285 }
286 286
287 .test .something__child3, 287 .test .something__child3,
288 .test .something__child4 { 288 .test .something__child4 {
289 font-size: 2em; 289 font-size: 2em;
290 } 290 }
291 } 291 }
292 } 292 }
293 293
294 @include assert('multiple elements, modifier in-between') { /// 10 /// 294 @include assert('multiple elements, modifier in-between') { /// 10 ///
295 @include output { 295 @include output {
296 @include bem.block('something') { 296 @include bem.block('something') {
297 @include bem.modifier('mod') { 297 @include bem.modifier('mod') {
298 @include bem.elem('child1', 'child2') { 298 @include bem.elem('child1', 'child2') {
299 font-size: 2em; 299 font-size: 2em;
300 } 300 }
301 } 301 }
302 } 302 }
303 } 303 }
304 304
305 @include expect { 305 @include expect {
306 .something--mod .something__child1, 306 .something--mod .something__child1,
307 .something--mod .something__child2 { 307 .something--mod .something__child2 {
308 font-size: 2em; 308 font-size: 2em;
309 } 309 }
310 } 310 }
311 } 311 }
312 312
313 @include assert('multiple elements, nested') { /// 11 /// 313 @include assert('multiple elements, nested') { /// 11 ///
314 @include output { 314 @include output {
315 @include bem.block('something') { 315 @include bem.block('something') {
316 @include bem.elem('child1', 'child2') { 316 @include bem.elem('child1', 'child2') {
317 font-size: 2em; 317 font-size: 2em;
318 318
319 @include bem.elem('subchild1') { 319 @include bem.elem('subchild1') {
320 font-size: 3em; 320 font-size: 3em;
321 } 321 }
322 } 322 }
323 323
324 @include bem.elem('child3') { 324 @include bem.elem('child3') {
325 font-size: 2em; 325 font-size: 2em;
326 326
327 @include bem.elem('subchild2', 'subchild3') { 327 @include bem.elem('subchild2', 'subchild3') {
328 font-size: 3em; 328 font-size: 3em;
329 } 329 }
330 } 330 }
331 } 331 }
332 } 332 }
333 333
334 @include expect { 334 @include expect {
335 .something__child1, 335 .something__child1,
336 .something__child2 { 336 .something__child2 {
337 font-size: 2em; 337 font-size: 2em;
338 } 338 }
339 339
340 .something__child1 .something__subchild1, 340 .something__child1 .something__subchild1,
341 .something__child2 .something__subchild1 { 341 .something__child2 .something__subchild1 {
342 font-size: 3em; 342 font-size: 3em;
343 } 343 }
344 344
345 .something__child3 { 345 .something__child3 {
346 font-size: 2em; 346 font-size: 2em;
347 } 347 }
348 348
349 .something__child3 .something__subchild2, 349 .something__child3 .something__subchild2,
350 .something__child3 .something__subchild3 { 350 .something__child3 .something__subchild3 {
351 font-size: 3em; 351 font-size: 3em;
352 } 352 }
353 } 353 }
354 } 354 }
355 355
356 @include assert('multiple elements, nested, manual selector in-between') { /// 12 /// 356 @include assert('multiple elements, nested, manual selector in-between') { /// 12 ///
357 @include output(false) { 357 @include output(false) {
358 @include bem.block('something') { 358 @include bem.block('something') {
359 @include bem.elem('child1', 'child2') { 359 @include bem.elem('child1', 'child2') {
360 font-size: 2em; 360 font-size: 2em;
361 361
362 &:hover { 362 &:hover {
363 @include bem.elem('subchild1') { 363 @include bem.elem('subchild1') {
364 font-size: 3em; 364 font-size: 3em;
365 } 365 }
366 } 366 }
367 367
368 .test & { 368 .test & {
369 @include bem.elem('subchild2') { 369 @include bem.elem('subchild2') {
370 font-size: 3em; 370 font-size: 3em;
371 } 371 }
372 } 372 }
373 } 373 }
374 374
375 @include bem.elem('child3') { 375 @include bem.elem('child3') {
376 font-size: 2em; 376 font-size: 2em;
377 377
378 &:hover { 378 &:hover {
379 @include bem.elem('subchild3', 'subchild4') { 379 @include bem.elem('subchild3', 'subchild4') {
380 font-size: 3em; 380 font-size: 3em;
381 } 381 }
382 } 382 }
383 383
384 .test & { 384 .test & {
385 @include bem.elem('subchild5', 'subchild6') { 385 @include bem.elem('subchild5', 'subchild6') {
386 font-size: 3em; 386 font-size: 3em;
387 } 387 }
388 } 388 }
389 } 389 }
390 } 390 }
391 } 391 }
392 392
393 @include expect(false) { 393 @include expect(false) {
394 .something__child1, 394 .something__child1,
395 .something__child2 { 395 .something__child2 {
396 font-size: 2em; 396 font-size: 2em;
397 } 397 }
398 398
399 .something__child1:hover .something__subchild1, 399 .something__child1:hover .something__subchild1,
400 .something__child2:hover .something__subchild1 { 400 .something__child2:hover .something__subchild1 {
401 font-size: 3em; 401 font-size: 3em;
402 } 402 }
403 403
404 .test .something__child1 .something__subchild2, 404 .test .something__child1 .something__subchild2,
405 .test .something__child2 .something__subchild2 { 405 .test .something__child2 .something__subchild2 {
406 font-size: 3em; 406 font-size: 3em;
407 } 407 }
408 408
409 .something__child3 { 409 .something__child3 {
410 font-size: 2em; 410 font-size: 2em;
411 } 411 }
412 412
413 .something__child3:hover .something__subchild3, 413 .something__child3:hover .something__subchild3,
414 .something__child3:hover .something__subchild4 { 414 .something__child3:hover .something__subchild4 {
415 font-size: 3em; 415 font-size: 3em;
416 } 416 }
417 417
418 .test .something__child3 .something__subchild5, 418 .test .something__child3 .something__subchild5,
419 .test .something__child3 .something__subchild6 { 419 .test .something__child3 .something__subchild6 {
420 font-size: 3em; 420 font-size: 3em;
421 } 421 }
422 } 422 }
423 } 423 }
424 424
425 @include assert('multiple elements, nested, modifier in-between') { /// 13 /// 425 @include assert('multiple elements, nested, modifier in-between') { /// 13 ///
426 @include output { 426 @include output {
427 @include bem.block('something') { 427 @include bem.block('something') {
428 @include bem.elem('child1', 'child2') { 428 @include bem.elem('child1', 'child2') {
429 font-size: 2em; 429 font-size: 2em;
430 430
431 @include bem.modifier('mod') { 431 @include bem.modifier('mod') {
432 @include bem.elem('subchild1') { 432 @include bem.elem('subchild1') {
433 font-size: 3em; 433 font-size: 3em;
434 } 434 }
435 } 435 }
436 } 436 }
437 437
438 @include bem.elem('child3') { 438 @include bem.elem('child3') {
439 font-size: 2em; 439 font-size: 2em;
440 440
441 @include bem.modifier('mod') { 441 @include bem.modifier('mod') {
442 @include bem.elem('subchild2', 'subchild3') { 442 @include bem.elem('subchild2', 'subchild3') {
443 font-size: 3em; 443 font-size: 3em;
444 } 444 }
445 } 445 }
446 } 446 }
447 } 447 }
448 } 448 }
449 449
450 @include expect { 450 @include expect {
451 .something__child1, 451 .something__child1,
452 .something__child2 { 452 .something__child2 {
453 font-size: 2em; 453 font-size: 2em;
454 } 454 }
455 455
456 .something__child1--mod .something__subchild1, 456 .something__child1--mod .something__subchild1,
457 .something__child2--mod .something__subchild1 { 457 .something__child2--mod .something__subchild1 {
458 font-size: 3em; 458 font-size: 3em;
459 } 459 }
460 460
461 .something__child3 { 461 .something__child3 {
462 font-size: 2em; 462 font-size: 2em;
463 } 463 }
464 464
465 .something__child3--mod .something__subchild2, 465 .something__child3--mod .something__subchild2,
466 .something__child3--mod .something__subchild3 { 466 .something__child3--mod .something__subchild3 {
467 font-size: 3em; 467 font-size: 3em;
468 } 468 }
469 } 469 }
470 } 470 }
471 471
472 @include assert('multiple elements, in at-theme') { /// 14 /// 472 @include assert('multiple elements, in at-theme') { /// 14 ///
473 @include output(false) { 473 @include output(false) {
474 @include bem.block('something') { 474 @include bem.block('something') {
475 @include bem.at-theme('dark') { 475 @include bem.at-theme('dark') {
476 @include bem.elem('child1', 'child2') { 476 @include bem.elem('child1', 'child2') {
477 font-size: 2em; 477 font-size: 2em;
478 } 478 }
479 } 479 }
480 } 480 }
481 } 481 }
482 482
483 @include expect(false) { 483 @include expect(false) {
484 .t-dark .something__child1, 484 .t-dark .something__child1,
485 [class*=' t-'] .t-dark .something__child1, 485 [class*=' t-'] .t-dark .something__child1,
486 [class^='t-'] .t-dark .something__child1, 486 [class^='t-'] .t-dark .something__child1,
487 .t-dark .something__child2, 487 .t-dark .something__child2,
488 [class*=' t-'] .t-dark .something__child2, 488 [class*=' t-'] .t-dark .something__child2,
489 [class^='t-'] .t-dark .something__child2 { 489 [class^='t-'] .t-dark .something__child2 {
490 font-size: 2em; 490 font-size: 2em;
491 } 491 }
492 } 492 }
493 } 493 }
494} 494}
diff --git a/test/bem/_examples.scss b/test/bem/_examples.scss
index 33deca0..9679566 100644
--- a/test/bem/_examples.scss
+++ b/test/bem/_examples.scss
@@ -11,217 +11,223 @@
11// 11//
12 12
13@include it('Examples') { 13@include it('Examples') {
14 @include assert('Media object') { /// 1 /// 14 @include assert('Media object') { /// 1 ///
15 @include output { 15 @include output {
16 @include bem.object('media') { 16 @include bem.object('media') {
17 display: flex; 17 display: flex;
18 align-items: flex-start; 18 align-items: flex-start;
19 justify-content: flex-start; 19 justify-content: flex-start;
20 20
21 @include bem.elem('image') { 21 @include bem.elem('image') {
22 display: block; 22 display: block;
23 flex: 0 0 auto; 23 flex: 0 0 auto;
24 order: 1; 24 order: 1;
25 overflow: hidden; 25 overflow: hidden;
26 } 26 }
27 27
28 @include bem.elem('body') { 28 @include bem.elem('body') {
29 order: 2; 29 order: 2;
30 } 30 }
31 31
32 @include bem.modifier('rtl') { 32 @include bem.modifier('rtl') {
33 justify-content: flex-end; 33 justify-content: flex-end;
34 34
35 @include bem.elem('image') { 35 @include bem.elem('image') {
36 order: 2; 36 order: 2;
37 } 37 }
38 38
39 @include bem.elem('body') { 39 @include bem.elem('body') {
40 order: 1; 40 order: 1;
41 } 41 }
42 } 42 }
43 } 43 }
44 } 44 }
45 45
46 @include expect { 46 @include expect {
47 .o-media { 47 @layer object {
48 display: flex; 48 .o-media {
49 align-items: flex-start; 49 display: flex;
50 justify-content: flex-start; 50 align-items: flex-start;
51 } 51 justify-content: flex-start;
52 }
52 53
53 .o-media__image { 54 .o-media__image {
54 display: block; 55 display: block;
55 flex: 0 0 auto; 56 flex: 0 0 auto;
56 order: 1; 57 order: 1;
57 overflow: hidden; 58 overflow: hidden;
58 } 59 }
59 60
60 .o-media__body { 61 .o-media__body {
61 order: 2; 62 order: 2;
62 } 63 }
63 64
64 .o-media--rtl { 65 .o-media--rtl {
65 justify-content: flex-end; 66 justify-content: flex-end;
66 67
67 .o-media__image { 68 .o-media__image {
68 order: 2; 69 order: 2;
69 } 70 }
70 71
71 .o-media__body { 72 .o-media__body {
72 order: 1; 73 order: 1;
73 } 74 }
74 } 75 }
75 } 76 }
76 } 77 }
78 }
77 79
78 @include assert('Tabs') { /// 2 /// 80 @include assert('Tabs') { /// 2 ///
79 @include output { 81 @include output {
80 @include bem.component('tabs') { 82 @include bem.component('tabs') {
81 position: relative; 83 position: relative;
82 84
83 @include bem.elem('tab') { 85 @include bem.elem('tab') {
84 float: left; 86 float: left;
85 } 87 }
86 88
87 @include bem.elem('tabRadio') { 89 @include bem.elem('tabRadio') {
88 position: absolute; 90 position: absolute;
89 top: -9999px; 91 top: -9999px;
90 left: -9999px; 92 left: -9999px;
91 93
92 &:checked { 94 &:checked {
93 @include bem.sibling-elem('tabLabel') { 95 @include bem.sibling-elem('tabLabel') {
94 font-weight: bold; 96 font-weight: bold;
95 } 97 }
96 98
97 @include bem.sibling-elem('tabContent') { 99 @include bem.sibling-elem('tabContent') {
98 display: block; 100 display: block;
99 } 101 }
100 } 102 }
101 } 103 }
102 104
103 @include bem.elem('tabLabel') { 105 @include bem.elem('tabLabel') {
104 cursor: pointer; 106 cursor: pointer;
105 107
106 &:hover, 108 &:hover,
107 &:active { 109 &:active {
108 text-decoration: underline; 110 text-decoration: underline;
109 } 111 }
110 } 112 }
111 113
112 @include bem.elem('tabContent') { 114 @include bem.elem('tabContent') {
113 position: absolute; 115 position: absolute;
114 left: 0; 116 left: 0;
115 display: none; 117 display: none;
116 } 118 }
117 } 119 }
118 } 120 }
119 121
120 @include expect { 122 @include expect {
121 .c-tabs { 123 @layer component {
122 position: relative; 124 .c-tabs {
123 } 125 position: relative;
126 }
124 127
125 .c-tabs__tab { 128 .c-tabs__tab {
126 float: left; 129 float: left;
127 } 130 }
128 131
129 .c-tabs__tabRadio { 132 .c-tabs__tabRadio {
130 position: absolute; 133 position: absolute;
131 top: -9999px; 134 top: -9999px;
132 left: -9999px; 135 left: -9999px;
133 } 136 }
134 137
135 .c-tabs__tabRadio:checked ~ .c-tabs__tabLabel { 138 .c-tabs__tabRadio:checked ~ .c-tabs__tabLabel {
136 font-weight: bold; 139 font-weight: bold;
137 } 140 }
138 141
139 .c-tabs__tabRadio:checked ~ .c-tabs__tabContent { 142 .c-tabs__tabRadio:checked ~ .c-tabs__tabContent {
140 display: block; 143 display: block;
141 } 144 }
142 145
143 .c-tabs__tabLabel { 146 .c-tabs__tabLabel {
144 cursor: pointer; 147 cursor: pointer;
145 } 148 }
146 149
147 .c-tabs__tabLabel:hover, 150 .c-tabs__tabLabel:hover,
148 .c-tabs__tabLabel:active { 151 .c-tabs__tabLabel:active {
149 text-decoration: underline; 152 text-decoration: underline;
150 } 153 }
151 154
152 .c-tabs__tabContent { 155 .c-tabs__tabContent {
153 position: absolute; 156 position: absolute;
154 left: 0; 157 left: 0;
155 display: none; 158 display: none;
156 } 159 }
157 } 160 }
158 } 161 }
162 }
159 163
160 @include assert('Accordion') { /// 3 /// 164 @include assert('Accordion') { /// 3 ///
161 @include output { 165 @include output {
162 @include bem.component('accordion') { 166 @include bem.component('accordion') {
163 @include bem.elem('section') { 167 @include bem.elem('section') {
164 // nothing to do 168 // nothing to do
165 } 169 }
166 170
167 @include bem.elem('sectionCheckbox') { 171 @include bem.elem('sectionCheckbox') {
168 position: absolute; 172 position: absolute;
169 top: -9999px; 173 top: -9999px;
170 left: -9999px; 174 left: -9999px;
171 175
172 &:checked { 176 &:checked {
173 @include bem.sibling-elem('sectionLabel') { 177 @include bem.sibling-elem('sectionLabel') {
174 font-weight: bold; 178 font-weight: bold;
175 } 179 }
176 180
177 @include bem.sibling-elem('sectionContent') { 181 @include bem.sibling-elem('sectionContent') {
178 display: block; 182 display: block;
179 } 183 }
180 } 184 }
181 } 185 }
182 186
183 @include bem.elem('sectionLabel') { 187 @include bem.elem('sectionLabel') {
184 cursor: pointer; 188 cursor: pointer;
185 189
186 &:hover, 190 &:hover,
187 &:active { 191 &:active {
188 text-decoration: underline; 192 text-decoration: underline;
189 } 193 }
190 } 194 }
191 195
192 @include bem.elem('sectionContent') { 196 @include bem.elem('sectionContent') {
193 display: none; 197 display: none;
194 } 198 }
195 } 199 }
196 } 200 }
197 201
198 @include expect { 202 @include expect {
199 .c-accordion__sectionCheckbox { 203 @layer component {
200 position: absolute; 204 .c-accordion__sectionCheckbox {
201 top: -9999px; 205 position: absolute;
202 left: -9999px; 206 top: -9999px;
203 } 207 left: -9999px;
208 }
204 209
205 .c-accordion__sectionCheckbox:checked ~ .c-accordion__sectionLabel { 210 .c-accordion__sectionCheckbox:checked ~ .c-accordion__sectionLabel {
206 font-weight: bold; 211 font-weight: bold;
207 } 212 }
208 213
209 .c-accordion__sectionCheckbox:checked ~ .c-accordion__sectionContent { 214 .c-accordion__sectionCheckbox:checked ~ .c-accordion__sectionContent {
210 display: block; 215 display: block;
211 } 216 }
212 217
213 .c-accordion__sectionLabel { 218 .c-accordion__sectionLabel {
214 cursor: pointer; 219 cursor: pointer;
215 } 220 }
216 221
217 .c-accordion__sectionLabel:hover, 222 .c-accordion__sectionLabel:hover,
218 .c-accordion__sectionLabel:active { 223 .c-accordion__sectionLabel:active {
219 text-decoration: underline; 224 text-decoration: underline;
220 } 225 }
221 226
222 .c-accordion__sectionContent { 227 .c-accordion__sectionContent {
223 display: none; 228 display: none;
224 } 229 }
225 } 230 }
226 } 231 }
232 }
227} 233}
diff --git a/test/bem/_modifier.scss b/test/bem/_modifier.scss
index 934efa3..419aa91 100644
--- a/test/bem/_modifier.scss
+++ b/test/bem/_modifier.scss
@@ -23,633 +23,633 @@
23// 23//
24 24
25@include it('modifier') { 25@include it('modifier') {
26 @include assert('block modifier') { /// 1 /// 26 @include assert('block modifier') { /// 1 ///
27 @include output { 27 @include output {
28 @include bem.block('something') { 28 @include bem.block('something') {
29 @include bem.modifier('mod') { 29 @include bem.modifier('mod') {
30 font-size: 1.5em; 30 font-size: 1.5em;
31 31
32 @include bem.modifier('submod') { 32 @include bem.modifier('submod') {
33 font-size: 1.75em; 33 font-size: 1.75em;
34 } 34 }
35 } 35 }
36 } 36 }
37 } 37 }
38 38
39 @include expect { 39 @include expect {
40 .something--mod { 40 .something--mod {
41 font-size: 1.5em; 41 font-size: 1.5em;
42 } 42 }
43 43
44 .something--mod.something--submod { 44 .something--mod.something--submod {
45 font-size: 1.75em; 45 font-size: 1.75em;
46 } 46 }
47 } 47 }
48 } 48 }
49 49
50 @include assert('block modifier, in at-theme') { /// 2 /// 50 @include assert('block modifier, in at-theme') { /// 2 ///
51 @include output(false) { 51 @include output(false) {
52 @include bem.block('something') { 52 @include bem.block('something') {
53 @include bem.at-theme('dark') { 53 @include bem.at-theme('dark') {
54 @include bem.modifier('mod') { 54 @include bem.modifier('mod') {
55 font-size: 1.5em; 55 font-size: 1.5em;
56 56
57 @include bem.modifier('submod') { 57 @include bem.modifier('submod') {
58 font-size: 1.75em; 58 font-size: 1.75em;
59 } 59 }
60 } 60 }
61 } 61 }
62 } 62 }
63 } 63 }
64 64
65 @include expect(false) { 65 @include expect(false) {
66 .t-dark .something--mod, 66 .t-dark .something--mod,
67 [class*=' t-'] .t-dark .something--mod, 67 [class*=' t-'] .t-dark .something--mod,
68 [class^='t-'] .t-dark .something--mod { 68 [class^='t-'] .t-dark .something--mod {
69 font-size: 1.5em; 69 font-size: 1.5em;
70 } 70 }
71 71
72 .t-dark .something--mod.something--submod, 72 .t-dark .something--mod.something--submod,
73 [class*=' t-'] .t-dark .something--mod.something--submod, 73 [class*=' t-'] .t-dark .something--mod.something--submod,
74 [class^='t-'] .t-dark .something--mod.something--submod { 74 [class^='t-'] .t-dark .something--mod.something--submod {
75 font-size: 1.75em; 75 font-size: 1.75em;
76 } 76 }
77 } 77 }
78 } 78 }
79 79
80 @include assert('element modifier, single element') { /// 3 /// 80 @include assert('element modifier, single element') { /// 3 ///
81 @include output { 81 @include output {
82 @include bem.block('something') { 82 @include bem.block('something') {
83 @include bem.elem('child') { 83 @include bem.elem('child') {
84 @include bem.modifier('mod') { 84 @include bem.modifier('mod') {
85 font-size: 2.5em; 85 font-size: 2.5em;
86 86
87 @include bem.modifier('submod') { 87 @include bem.modifier('submod') {
88 font-size: 2.75em; 88 font-size: 2.75em;
89 } 89 }
90 } 90 }
91 } 91 }
92 } 92 }
93 } 93 }
94 94
95 @include expect { 95 @include expect {
96 .something__child--mod { 96 .something__child--mod {
97 font-size: 2.5em; 97 font-size: 2.5em;
98 } 98 }
99 99
100 .something__child--mod.something__child--submod { 100 .something__child--mod.something__child--submod {
101 font-size: 2.75em; 101 font-size: 2.75em;
102 } 102 }
103 } 103 }
104 } 104 }
105 105
106 @include assert('element modifier, multiple elements') { /// 4 /// 106 @include assert('element modifier, multiple elements') { /// 4 ///
107 @include output { 107 @include output {
108 @include bem.block('something') { 108 @include bem.block('something') {
109 @include bem.elem('child1', 'child2') { 109 @include bem.elem('child1', 'child2') {
110 @include bem.modifier('mod') { 110 @include bem.modifier('mod') {
111 font-size: 2.5em; 111 font-size: 2.5em;
112 112
113 @include bem.modifier('submod') { 113 @include bem.modifier('submod') {
114 font-size: 2.75em; 114 font-size: 2.75em;
115 } 115 }
116 } 116 }
117 } 117 }
118 } 118 }
119 } 119 }
120 120
121 @include expect { 121 @include expect {
122 .something__child1--mod, 122 .something__child1--mod,
123 .something__child2--mod { 123 .something__child2--mod {
124 font-size: 2.5em; 124 font-size: 2.5em;
125 } 125 }
126 126
127 .something__child1--mod.something__child1--submod, 127 .something__child1--mod.something__child1--submod,
128 .something__child2--mod.something__child2--submod { 128 .something__child2--mod.something__child2--submod {
129 font-size: 2.75em; 129 font-size: 2.75em;
130 } 130 }
131 } 131 }
132 } 132 }
133 133
134 @include assert('element modifier, single related element') { /// 5 /// 134 @include assert('element modifier, single related element') { /// 5 ///
135 @include output { 135 @include output {
136 @include bem.block('something') { 136 @include bem.block('something') {
137 @include bem.elem('child1') { 137 @include bem.elem('child1') {
138 @include bem.next-elem('child2') { 138 @include bem.next-elem('child2') {
139 @include bem.modifier('mod') { 139 @include bem.modifier('mod') {
140 font-size: 2.5em; 140 font-size: 2.5em;
141 141
142 @include bem.modifier('submod') { 142 @include bem.modifier('submod') {
143 font-size: 2.75em; 143 font-size: 2.75em;
144 } 144 }
145 } 145 }
146 } 146 }
147 } 147 }
148 } 148 }
149 } 149 }
150 150
151 @include expect { 151 @include expect {
152 .something__child1 + .something__child2--mod { 152 .something__child1 + .something__child2--mod {
153 font-size: 2.5em; 153 font-size: 2.5em;
154 } 154 }
155 155
156 .something__child1 + .something__child2--mod.something__child2--submod { 156 .something__child1 + .something__child2--mod.something__child2--submod {
157 font-size: 2.75em; 157 font-size: 2.75em;
158 } 158 }
159 } 159 }
160 } 160 }
161 161
162 @include assert('element modifier, multiple related elements') { /// 6 /// 162 @include assert('element modifier, multiple related elements') { /// 6 ///
163 @include output { 163 @include output {
164 @include bem.block('something') { 164 @include bem.block('something') {
165 @include bem.elem('child1') { 165 @include bem.elem('child1') {
166 @include bem.next-elem('child2', 'child3') { 166 @include bem.next-elem('child2', 'child3') {
167 @include bem.modifier('mod') { 167 @include bem.modifier('mod') {
168 font-size: 2.5em; 168 font-size: 2.5em;
169 169
170 @include bem.modifier('submod') { 170 @include bem.modifier('submod') {
171 font-size: 2.75em; 171 font-size: 2.75em;
172 } 172 }
173 } 173 }
174 } 174 }
175 } 175 }
176 } 176 }
177 } 177 }
178 178
179 @include expect { 179 @include expect {
180 .something__child1 + .something__child2--mod, 180 .something__child1 + .something__child2--mod,
181 .something__child1 + .something__child3--mod { 181 .something__child1 + .something__child3--mod {
182 font-size: 2.5em; 182 font-size: 2.5em;
183 } 183 }
184 184
185 .something__child1 + .something__child2--mod.something__child2--submod, 185 .something__child1 + .something__child2--mod.something__child2--submod,
186 .something__child1 + .something__child3--mod.something__child3--submod { 186 .something__child1 + .something__child3--mod.something__child3--submod {
187 font-size: 2.75em; 187 font-size: 2.75em;
188 } 188 }
189 } 189 }
190 } 190 }
191 191
192 @include assert('element modifier, single element, manual selector before') { /// 7 /// 192 @include assert('element modifier, single element, manual selector before') { /// 7 ///
193 @include output(false) { 193 @include output(false) {
194 @include bem.block('something') { 194 @include bem.block('something') {
195 &:hover { 195 &:hover {
196 @include bem.elem('child1') { 196 @include bem.elem('child1') {
197 @include bem.modifier('mod') { 197 @include bem.modifier('mod') {
198 font-size: 2.5em; 198 font-size: 2.5em;
199 199
200 @include bem.modifier('submod') { 200 @include bem.modifier('submod') {
201 font-size: 2.75em; 201 font-size: 2.75em;
202 } 202 }
203 } 203 }
204 } 204 }
205 } 205 }
206 206
207 .test & { 207 .test & {
208 @include bem.elem('child2') { 208 @include bem.elem('child2') {
209 @include bem.modifier('mod') { 209 @include bem.modifier('mod') {
210 font-size: 2.5em; 210 font-size: 2.5em;
211 211
212 @include bem.modifier('submod') { 212 @include bem.modifier('submod') {
213 font-size: 2.75em; 213 font-size: 2.75em;
214 } 214 }
215 } 215 }
216 } 216 }
217 } 217 }
218 } 218 }
219 } 219 }
220 220
221 @include expect(false) { 221 @include expect(false) {
222 .something:hover .something__child1--mod { 222 .something:hover .something__child1--mod {
223 font-size: 2.5em; 223 font-size: 2.5em;
224 } 224 }
225 225
226 .something:hover .something__child1--mod.something__child1--submod { 226 .something:hover .something__child1--mod.something__child1--submod {
227 font-size: 2.75em; 227 font-size: 2.75em;
228 } 228 }
229 229
230 .test .something__child2--mod { 230 .test .something__child2--mod {
231 font-size: 2.5em; 231 font-size: 2.5em;
232 } 232 }
233 233
234 .test .something__child2--mod.something__child2--submod { 234 .test .something__child2--mod.something__child2--submod {
235 font-size: 2.75em; 235 font-size: 2.75em;
236 } 236 }
237 } 237 }
238 } 238 }
239 239
240 @include assert('element modifier, multiple elements, manual selector before') { /// 8 /// 240 @include assert('element modifier, multiple elements, manual selector before') { /// 8 ///
241 @include output(false) { 241 @include output(false) {
242 @include bem.block('something') { 242 @include bem.block('something') {
243 &:hover { 243 &:hover {
244 @include bem.elem('child1', 'child2') { 244 @include bem.elem('child1', 'child2') {
245 @include bem.modifier('mod') { 245 @include bem.modifier('mod') {
246 font-size: 2.5em; 246 font-size: 2.5em;
247 247
248 @include bem.modifier('submod') { 248 @include bem.modifier('submod') {
249 font-size: 2.75em; 249 font-size: 2.75em;
250 } 250 }
251 } 251 }
252 } 252 }
253 } 253 }
254 254
255 .test & { 255 .test & {
256 @include bem.elem('child3', 'child4') { 256 @include bem.elem('child3', 'child4') {
257 @include bem.modifier('mod') { 257 @include bem.modifier('mod') {
258 font-size: 2.5em; 258 font-size: 2.5em;
259 259
260 @include bem.modifier('submod') { 260 @include bem.modifier('submod') {
261 font-size: 2.75em; 261 font-size: 2.75em;
262 } 262 }
263 } 263 }
264 } 264 }
265 } 265 }
266 } 266 }
267 } 267 }
268 268
269 @include expect(false) { 269 @include expect(false) {
270 .something:hover .something__child1--mod, 270 .something:hover .something__child1--mod,
271 .something:hover .something__child2--mod { 271 .something:hover .something__child2--mod {
272 font-size: 2.5em; 272 font-size: 2.5em;
273 } 273 }
274 274
275 .something:hover .something__child1--mod.something__child1--submod, 275 .something:hover .something__child1--mod.something__child1--submod,
276 .something:hover .something__child2--mod.something__child2--submod { 276 .something:hover .something__child2--mod.something__child2--submod {
277 font-size: 2.75em; 277 font-size: 2.75em;
278 } 278 }
279 279
280 .test .something__child3--mod, 280 .test .something__child3--mod,
281 .test .something__child4--mod { 281 .test .something__child4--mod {
282 font-size: 2.5em; 282 font-size: 2.5em;
283 } 283 }
284 284
285 .test .something__child3--mod.something__child3--submod, 285 .test .something__child3--mod.something__child3--submod,
286 .test .something__child4--mod.something__child4--submod { 286 .test .something__child4--mod.something__child4--submod {
287 font-size: 2.75em; 287 font-size: 2.75em;
288 } 288 }
289 } 289 }
290 } 290 }
291 291
292 @include assert('element modifier, single related element, manual selector before') { /// 9 /// 292 @include assert('element modifier, single related element, manual selector before') { /// 9 ///
293 @include output(false) { 293 @include output(false) {
294 @include bem.block('something') { 294 @include bem.block('something') {
295 &:hover { 295 &:hover {
296 @include bem.elem('child1') { 296 @include bem.elem('child1') {
297 @include bem.next-elem('child2') { 297 @include bem.next-elem('child2') {
298 @include bem.modifier('mod1') { 298 @include bem.modifier('mod1') {
299 font-size: 2.5em; 299 font-size: 2.5em;
300 300
301 @include bem.modifier('submod1') { 301 @include bem.modifier('submod1') {
302 font-size: 2.75em; 302 font-size: 2.75em;
303 } 303 }
304 } 304 }
305 } 305 }
306 } 306 }
307 } 307 }
308 308
309 .test & { 309 .test & {
310 @include bem.elem('child3') { 310 @include bem.elem('child3') {
311 @include bem.next-elem('child4') { 311 @include bem.next-elem('child4') {
312 @include bem.modifier('mod1') { 312 @include bem.modifier('mod1') {
313 font-size: 2.5em; 313 font-size: 2.5em;
314 314
315 @include bem.modifier('submod1') { 315 @include bem.modifier('submod1') {
316 font-size: 2.75em; 316 font-size: 2.75em;
317 } 317 }
318 } 318 }
319 } 319 }
320 } 320 }
321 } 321 }
322 322
323 @include bem.elem('child5') { 323 @include bem.elem('child5') {
324 &:hover { 324 &:hover {
325 @include bem.next-elem('child6') { 325 @include bem.next-elem('child6') {
326 @include bem.modifier('mod2') { 326 @include bem.modifier('mod2') {
327 font-size: 2.5em; 327 font-size: 2.5em;
328 328
329 @include bem.modifier('submod2') { 329 @include bem.modifier('submod2') {
330 font-size: 2.75em; 330 font-size: 2.75em;
331 } 331 }
332 } 332 }
333 } 333 }
334 } 334 }
335 335
336 .test & { 336 .test & {
337 @include bem.next-elem('child7') { 337 @include bem.next-elem('child7') {
338 @include bem.modifier('mod2') { 338 @include bem.modifier('mod2') {
339 font-size: 2.5em; 339 font-size: 2.5em;
340 340
341 @include bem.modifier('submod2') { 341 @include bem.modifier('submod2') {
342 font-size: 2.75em; 342 font-size: 2.75em;
343 } 343 }
344 } 344 }
345 } 345 }
346 } 346 }
347 } 347 }
348 } 348 }
349 } 349 }
350 350
351 @include expect(false) { 351 @include expect(false) {
352 .something:hover .something__child1 + .something__child2--mod1 { 352 .something:hover .something__child1 + .something__child2--mod1 {
353 font-size: 2.5em; 353 font-size: 2.5em;
354 } 354 }
355 355
356 .something:hover .something__child1 + .something__child2--mod1.something__child2--submod1 { 356 .something:hover .something__child1 + .something__child2--mod1.something__child2--submod1 {
357 font-size: 2.75em; 357 font-size: 2.75em;
358 } 358 }
359 359
360 .test .something__child3 + .something__child4--mod1 { 360 .test .something__child3 + .something__child4--mod1 {
361 font-size: 2.5em; 361 font-size: 2.5em;
362 } 362 }
363 363
364 .test .something__child3 + .something__child4--mod1.something__child4--submod1 { 364 .test .something__child3 + .something__child4--mod1.something__child4--submod1 {
365 font-size: 2.75em; 365 font-size: 2.75em;
366 } 366 }
367 367
368 .something__child5:hover + .something__child6--mod2 { 368 .something__child5:hover + .something__child6--mod2 {
369 font-size: 2.5em; 369 font-size: 2.5em;
370 } 370 }
371 371
372 .something__child5:hover + .something__child6--mod2.something__child6--submod2 { 372 .something__child5:hover + .something__child6--mod2.something__child6--submod2 {
373 font-size: 2.75em; 373 font-size: 2.75em;
374 } 374 }
375 375
376 .test .something__child5 + .something__child7--mod2 { 376 .test .something__child5 + .something__child7--mod2 {
377 font-size: 2.5em; 377 font-size: 2.5em;
378 } 378 }
379 379
380 .test .something__child5 + .something__child7--mod2.something__child7--submod2 { 380 .test .something__child5 + .something__child7--mod2.something__child7--submod2 {
381 font-size: 2.75em; 381 font-size: 2.75em;
382 } 382 }
383 } 383 }
384 } 384 }
385 385
386 @include assert('element modifier, multiple related elements, manual selector before') { /// 10 /// 386 @include assert('element modifier, multiple related elements, manual selector before') { /// 10 ///
387 @include output(false) { 387 @include output(false) {
388 @include bem.block('something') { 388 @include bem.block('something') {
389 &:hover { 389 &:hover {
390 @include bem.elem('child1') { 390 @include bem.elem('child1') {
391 @include bem.next-elem('child2', 'child3') { 391 @include bem.next-elem('child2', 'child3') {
392 @include bem.modifier('mod1') { 392 @include bem.modifier('mod1') {
393 font-size: 2.5em; 393 font-size: 2.5em;
394 394
395 @include bem.modifier('submod1') { 395 @include bem.modifier('submod1') {
396 font-size: 2.75em; 396 font-size: 2.75em;
397 } 397 }
398 } 398 }
399 } 399 }
400 } 400 }
401 } 401 }
402 402
403 .test & { 403 .test & {
404 @include bem.elem('child4') { 404 @include bem.elem('child4') {
405 @include bem.next-elem('child5', 'child6') { 405 @include bem.next-elem('child5', 'child6') {
406 @include bem.modifier('mod1') { 406 @include bem.modifier('mod1') {
407 font-size: 2.5em; 407 font-size: 2.5em;
408 408
409 @include bem.modifier('submod1') { 409 @include bem.modifier('submod1') {
410 font-size: 2.75em; 410 font-size: 2.75em;
411 } 411 }
412 } 412 }
413 } 413 }
414 } 414 }
415 } 415 }
416 416
417 @include bem.elem('child7') { 417 @include bem.elem('child7') {
418 &:hover { 418 &:hover {
419 @include bem.next-elem('child8', 'child9') { 419 @include bem.next-elem('child8', 'child9') {
420 @include bem.modifier('mod2') { 420 @include bem.modifier('mod2') {
421 font-size: 2.5em; 421 font-size: 2.5em;
422 422
423 @include bem.modifier('submod2') { 423 @include bem.modifier('submod2') {
424 font-size: 2.75em; 424 font-size: 2.75em;
425 } 425 }
426 } 426 }
427 } 427 }
428 } 428 }
429 429
430 .test & { 430 .test & {
431 @include bem.next-elem('child10', 'child11') { 431 @include bem.next-elem('child10', 'child11') {
432 @include bem.modifier('mod2') { 432 @include bem.modifier('mod2') {
433 font-size: 2.5em; 433 font-size: 2.5em;
434 434
435 @include bem.modifier('submod2') { 435 @include bem.modifier('submod2') {
436 font-size: 2.75em; 436 font-size: 2.75em;
437 } 437 }
438 } 438 }
439 } 439 }
440 } 440 }
441 } 441 }
442 } 442 }
443 } 443 }
444 444
445 @include expect(false) { 445 @include expect(false) {
446 .something:hover .something__child1 + .something__child2--mod1, 446 .something:hover .something__child1 + .something__child2--mod1,
447 .something:hover .something__child1 + .something__child3--mod1 { 447 .something:hover .something__child1 + .something__child3--mod1 {
448 font-size: 2.5em; 448 font-size: 2.5em;
449 } 449 }
450 450
451 .something:hover .something__child1 + .something__child2--mod1.something__child2--submod1, 451 .something:hover .something__child1 + .something__child2--mod1.something__child2--submod1,
452 .something:hover .something__child1 + .something__child3--mod1.something__child3--submod1 { 452 .something:hover .something__child1 + .something__child3--mod1.something__child3--submod1 {
453 font-size: 2.75em; 453 font-size: 2.75em;
454 } 454 }
455 455
456 .test .something__child4 + .something__child5--mod1, 456 .test .something__child4 + .something__child5--mod1,
457 .test .something__child4 + .something__child6--mod1 { 457 .test .something__child4 + .something__child6--mod1 {
458 font-size: 2.5em; 458 font-size: 2.5em;
459 } 459 }
460 460
461 .test .something__child4 + .something__child5--mod1.something__child5--submod1, 461 .test .something__child4 + .something__child5--mod1.something__child5--submod1,
462 .test .something__child4 + .something__child6--mod1.something__child6--submod1 { 462 .test .something__child4 + .something__child6--mod1.something__child6--submod1 {
463 font-size: 2.75em; 463 font-size: 2.75em;
464 } 464 }
465 465
466 .something__child7:hover + .something__child8--mod2, 466 .something__child7:hover + .something__child8--mod2,
467 .something__child7:hover + .something__child9--mod2 { 467 .something__child7:hover + .something__child9--mod2 {
468 font-size: 2.5em; 468 font-size: 2.5em;
469 } 469 }
470 470
471 .something__child7:hover + .something__child8--mod2.something__child8--submod2, 471 .something__child7:hover + .something__child8--mod2.something__child8--submod2,
472 .something__child7:hover + .something__child9--mod2.something__child9--submod2 { 472 .something__child7:hover + .something__child9--mod2.something__child9--submod2 {
473 font-size: 2.75em; 473 font-size: 2.75em;
474 } 474 }
475 475
476 .test .something__child7 + .something__child10--mod2, 476 .test .something__child7 + .something__child10--mod2,
477 .test .something__child7 + .something__child11--mod2 { 477 .test .something__child7 + .something__child11--mod2 {
478 font-size: 2.5em; 478 font-size: 2.5em;
479 } 479 }
480 480
481 .test .something__child7 + .something__child10--mod2.something__child10--submod2, 481 .test .something__child7 + .something__child10--mod2.something__child10--submod2,
482 .test .something__child7 + .something__child11--mod2.something__child11--submod2 { 482 .test .something__child7 + .something__child11--mod2.something__child11--submod2 {
483 font-size: 2.75em; 483 font-size: 2.75em;
484 } 484 }
485 } 485 }
486 } 486 }
487 487
488 // @include assert('element modifier, in at-theme') { /// 11 /// 488 // @include assert('element modifier, in at-theme') { /// 11 ///
489 // @include output(false) { 489 // @include output(false) {
490 // @include bem.block('something') { 490 // @include bem.block('something') {
491 // @include bem.at-theme('dark') { 491 // @include bem.at-theme('dark') {
492 // @include bem.elem('child') { 492 // @include bem.elem('child') {
493 // @include bem.modifier('mod') { 493 // @include bem.modifier('mod') {
494 // font-size: 2.5em; 494 // font-size: 2.5em;
495 // 495 //
496 // @include bem.modifier('submod') { 496 // @include bem.modifier('submod') {
497 // font-size: 2.75em; 497 // font-size: 2.75em;
498 // } 498 // }
499 // } 499 // }
500 // } 500 // }
501 // } 501 // }
502 // } 502 // }
503 // } 503 // }
504 // 504 //
505 // @include expect(false) { 505 // @include expect(false) {
506 // .t-dark .something__child--mod, 506 // .t-dark .something__child--mod,
507 // [class*=' t-'] .t-dark .something__child--mod, 507 // [class*=' t-'] .t-dark .something__child--mod,
508 // [class^='t-'] .t-dark .something__child--mod { 508 // [class^='t-'] .t-dark .something__child--mod {
509 // font-size: 2.5em; 509 // font-size: 2.5em;
510 // } 510 // }
511 // 511 //
512 // .t-dark .something__child--mod.something__child--submod, 512 // .t-dark .something__child--mod.something__child--submod,
513 // [class*=' t-'] .t-dark .something__child--mod.something__child--submod, 513 // [class*=' t-'] .t-dark .something__child--mod.something__child--submod,
514 // [class^='t-'] .t-dark .something__child--mod.something__child--submod { 514 // [class^='t-'] .t-dark .something__child--mod.something__child--submod {
515 // font-size: 2.75em; 515 // font-size: 2.75em;
516 // } 516 // }
517 // } 517 // }
518 // } 518 // }
519 519
520 @include assert('nested block modifiers, extending') { /// 12 /// 520 @include assert('nested block modifiers, extending') { /// 12 ///
521 @include output { 521 @include output {
522 @include bem.block('something') { 522 @include bem.block('something') {
523 @include bem.modifier('mod') { 523 @include bem.modifier('mod') {
524 font-size: 1.5em; 524 font-size: 1.5em;
525 525
526 @include bem.modifier('submod' true) { 526 @include bem.modifier('submod' true) {
527 font-size: 1.75em; 527 font-size: 1.75em;
528 } 528 }
529 } 529 }
530 } 530 }
531 } 531 }
532 532
533 @include expect { 533 @include expect {
534 .something--mod { 534 .something--mod {
535 font-size: 1.5em; 535 font-size: 1.5em;
536 } 536 }
537 537
538 .something--mod--submod { 538 .something--mod--submod {
539 font-size: 1.75em; 539 font-size: 1.75em;
540 } 540 }
541 } 541 }
542 } 542 }
543 543
544 @include assert('nested element modifiers, extending') { /// 13 /// 544 @include assert('nested element modifiers, extending') { /// 13 ///
545 @include output { 545 @include output {
546 @include bem.block('something') { 546 @include bem.block('something') {
547 @include bem.elem('child') { 547 @include bem.elem('child') {
548 @include bem.modifier('mod') { 548 @include bem.modifier('mod') {
549 font-size: 2.5em; 549 font-size: 2.5em;
550 550
551 @include bem.modifier('submod' true) { 551 @include bem.modifier('submod' true) {
552 font-size: 2.75em; 552 font-size: 2.75em;
553 } 553 }
554 } 554 }
555 } 555 }
556 } 556 }
557 } 557 }
558 558
559 @include expect { 559 @include expect {
560 .something__child--mod { 560 .something__child--mod {
561 font-size: 2.5em; 561 font-size: 2.5em;
562 } 562 }
563 563
564 .something__child--mod--submod { 564 .something__child--mod--submod {
565 font-size: 2.75em; 565 font-size: 2.75em;
566 } 566 }
567 } 567 }
568 } 568 }
569 569
570 @include assert('block and element modifiers, single element') { /// 14 /// 570 @include assert('block and element modifiers, single element') { /// 14 ///
571 @include output { 571 @include output {
572 @include bem.block('something') { 572 @include bem.block('something') {
573 @include bem.modifier('mod1') { 573 @include bem.modifier('mod1') {
574 font-size: 1.5em; 574 font-size: 1.5em;
575 575
576 @include bem.modifier('submod1') { 576 @include bem.modifier('submod1') {
577 font-size: 1.75em; 577 font-size: 1.75em;
578 } 578 }
579 579
580 @include bem.elem('child') { 580 @include bem.elem('child') {
581 @include bem.modifier('mod2') { 581 @include bem.modifier('mod2') {
582 font-size: 2.5em; 582 font-size: 2.5em;
583 583
584 @include bem.modifier('submod2') { 584 @include bem.modifier('submod2') {
585 font-size: 2.75em; 585 font-size: 2.75em;
586 } 586 }
587 } 587 }
588 } 588 }
589 } 589 }
590 } 590 }
591 } 591 }
592 592
593 @include expect { 593 @include expect {
594 .something--mod1 { 594 .something--mod1 {
595 font-size: 1.5em; 595 font-size: 1.5em;
596 } 596 }
597 597
598 .something--mod1.something--submod1 { 598 .something--mod1.something--submod1 {
599 font-size: 1.75em; 599 font-size: 1.75em;
600 } 600 }
601 601
602 .something--mod1 .something__child--mod2 { 602 .something--mod1 .something__child--mod2 {
603 font-size: 2.5em; 603 font-size: 2.5em;
604 } 604 }
605 605
606 .something--mod1 .something__child--mod2.something__child--submod2 { 606 .something--mod1 .something__child--mod2.something__child--submod2 {
607 font-size: 2.75em; 607 font-size: 2.75em;
608 } 608 }
609 } 609 }
610 } 610 }
611 611
612 @include assert('block and element modifiers, multiple elements') { /// 15 /// 612 @include assert('block and element modifiers, multiple elements') { /// 15 ///
613 @include output { 613 @include output {
614 @include bem.block('something') { 614 @include bem.block('something') {
615 @include bem.modifier('mod1') { 615 @include bem.modifier('mod1') {
616 font-size: 1.5em; 616 font-size: 1.5em;
617 617
618 @include bem.modifier('submod1') { 618 @include bem.modifier('submod1') {
619 font-size: 1.75em; 619 font-size: 1.75em;
620 } 620 }
621 621
622 @include bem.elem('child1', 'child2') { 622 @include bem.elem('child1', 'child2') {
623 @include bem.modifier('mod2') { 623 @include bem.modifier('mod2') {
624 font-size: 2.5em; 624 font-size: 2.5em;
625 625
626 @include bem.modifier('submod2') { 626 @include bem.modifier('submod2') {
627 font-size: 2.75em; 627 font-size: 2.75em;
628 } 628 }
629 } 629 }
630 } 630 }
631 } 631 }
632 } 632 }
633 } 633 }
634 634
635 @include expect { 635 @include expect {
636 .something--mod1 { 636 .something--mod1 {
637 font-size: 1.5em; 637 font-size: 1.5em;
638 } 638 }
639 639
640 .something--mod1.something--submod1 { 640 .something--mod1.something--submod1 {
641 font-size: 1.75em; 641 font-size: 1.75em;
642 } 642 }
643 643
644 .something--mod1 .something__child1--mod2, 644 .something--mod1 .something__child1--mod2,
645 .something--mod1 .something__child2--mod2 { 645 .something--mod1 .something__child2--mod2 {
646 font-size: 2.5em; 646 font-size: 2.5em;
647 } 647 }
648 648
649 .something--mod1 .something__child1--mod2.something__child1--submod2, 649 .something--mod1 .something__child1--mod2.something__child1--submod2,
650 .something--mod1 .something__child2--mod2.something__child2--submod2 { 650 .something--mod1 .something__child2--mod2.something__child2--submod2 {
651 font-size: 2.75em; 651 font-size: 2.75em;
652 } 652 }
653 } 653 }
654 } 654 }
655} 655}
diff --git a/test/bem/_multi.scss b/test/bem/_multi.scss
index 255fb45..88a4cf4 100644
--- a/test/bem/_multi.scss
+++ b/test/bem/_multi.scss
@@ -26,569 +26,569 @@
26// 26//
27 27
28@include it('multi') { 28@include it('multi') {
29 @include assert('in root, 2 blocks') { /// 1 /// 29 @include assert('in root, 2 blocks') { /// 1 ///
30 @include output { 30 @include output {
31 @include bem.multi('component:' 'block1', 'object:' 'block2') { 31 @include bem.multi('component:' 'block1', 'object:' 'block2') {
32 font-size: 1em; 32 font-size: 1em;
33 33
34 @include bem.elem('child2') { 34 @include bem.elem('child2') {
35 font-size: 2em; 35 font-size: 2em;
36 } 36 }
37 } 37 }
38 } 38 }
39 39
40 @include expect { 40 @include expect {
41 .c-block1 { 41 .c-block1 {
42 font-size: 1em; 42 font-size: 1em;
43 } 43 }
44 44
45 .c-block1__child2 { 45 .c-block1__child2 {
46 font-size: 2em; 46 font-size: 2em;
47 } 47 }
48 48
49 .o-block2 { 49 .o-block2 {
50 font-size: 1em; 50 font-size: 1em;
51 } 51 }
52 52
53 .o-block2__child2 { 53 .o-block2__child2 {
54 font-size: 2em; 54 font-size: 2em;
55 } 55 }
56 } 56 }
57 } 57 }
58 58
59 @include assert('in root, 1 block, 1 manual selector') { /// 2 /// 59 @include assert('in root, 1 block, 1 manual selector') { /// 2 ///
60 @include output { 60 @include output {
61 @include bem.multi('component:' 'block1', 'a:hover') { 61 @include bem.multi('component:' 'block1', 'a:hover') {
62 font-size: 1em; 62 font-size: 1em;
63 } 63 }
64 } 64 }
65 65
66 @include expect { 66 @include expect {
67 .c-block1 { 67 .c-block1 {
68 font-size: 1em; 68 font-size: 1em;
69 } 69 }
70 70
71 a:hover { 71 a:hover {
72 font-size: 1em; 72 font-size: 1em;
73 } 73 }
74 } 74 }
75 } 75 }
76 76
77 @include assert('in block, 2 elements') { /// 3 /// 77 @include assert('in block, 2 elements') { /// 3 ///
78 @include output { 78 @include output {
79 @include bem.block('something') { 79 @include bem.block('something') {
80 @include bem.multi('elem:' 'child1' 'child2') { 80 @include bem.multi('elem:' 'child1' 'child2') {
81 font-size: 2em; 81 font-size: 2em;
82 82
83 @include bem.modifier('mod') { 83 @include bem.modifier('mod') {
84 font-size: 2.5em; 84 font-size: 2.5em;
85 } 85 }
86 } 86 }
87 } 87 }
88 } 88 }
89 89
90 @include expect { 90 @include expect {
91 .something__child1, 91 .something__child1,
92 .something__child2 { 92 .something__child2 {
93 font-size: 2em; 93 font-size: 2em;
94 } 94 }
95 95
96 .something__child1--mod, 96 .something__child1--mod,
97 .something__child2--mod { 97 .something__child2--mod {
98 font-size: 2.5em; 98 font-size: 2.5em;
99 } 99 }
100 } 100 }
101 } 101 }
102 102
103 @include assert('in block, 1 element, 1 modifier') { /// 4 /// 103 @include assert('in block, 1 element, 1 modifier') { /// 4 ///
104 @include output { 104 @include output {
105 @include bem.block('something') { 105 @include bem.block('something') {
106 @include bem.multi('elem:' 'child', 'modifier:' 'mod1') { 106 @include bem.multi('elem:' 'child', 'modifier:' 'mod1') {
107 font-size: 2em; 107 font-size: 2em;
108 108
109 @include bem.modifier('mod2') { 109 @include bem.modifier('mod2') {
110 font-size: 2.5em; 110 font-size: 2.5em;
111 } 111 }
112 } 112 }
113 } 113 }
114 } 114 }
115 115
116 @include expect { 116 @include expect {
117 .something__child { 117 .something__child {
118 font-size: 2em; 118 font-size: 2em;
119 } 119 }
120 120
121 .something__child--mod2 { 121 .something__child--mod2 {
122 font-size: 2.5em; 122 font-size: 2.5em;
123 } 123 }
124 124
125 .something--mod1 { 125 .something--mod1 {
126 font-size: 2em; 126 font-size: 2em;
127 } 127 }
128 128
129 .something--mod1.something--mod2 { 129 .something--mod1.something--mod2 {
130 font-size: 2.5em; 130 font-size: 2.5em;
131 } 131 }
132 } 132 }
133 } 133 }
134 134
135 @include assert('in block, 1 element, 1 extending modifier') { /// 5 /// 135 @include assert('in block, 1 element, 1 extending modifier') { /// 5 ///
136 @include output { 136 @include output {
137 @include bem.block('something') { 137 @include bem.block('something') {
138 @include bem.multi('elem:' 'child', 'modifier:' 'mod1') { 138 @include bem.multi('elem:' 'child', 'modifier:' 'mod1') {
139 font-size: 2em; 139 font-size: 2em;
140 140
141 @include bem.modifier('mod2' true) { 141 @include bem.modifier('mod2' true) {
142 font-size: 2.5em; 142 font-size: 2.5em;
143 } 143 }
144 } 144 }
145 } 145 }
146 } 146 }
147 147
148 @include expect { 148 @include expect {
149 .something__child { 149 .something__child {
150 font-size: 2em; 150 font-size: 2em;
151 } 151 }
152 152
153 .something__child--mod2 { 153 .something__child--mod2 {
154 font-size: 2.5em; 154 font-size: 2.5em;
155 } 155 }
156 156
157 .something--mod1 { 157 .something--mod1 {
158 font-size: 2em; 158 font-size: 2em;
159 } 159 }
160 160
161 .something--mod1--mod2 { 161 .something--mod1--mod2 {
162 font-size: 2.5em; 162 font-size: 2.5em;
163 } 163 }
164 } 164 }
165 } 165 }
166 166
167 @include assert('in block, 1 element, 1 & selector') { /// 6 /// 167 @include assert('in block, 1 element, 1 & selector') { /// 6 ///
168 @include output { 168 @include output {
169 @include bem.block('something') { 169 @include bem.block('something') {
170 @include bem.multi('&', 'elem:' 'child') { 170 @include bem.multi('&', 'elem:' 'child') {
171 font-size: 2em; 171 font-size: 2em;
172 172
173 @include bem.modifier('mod') { 173 @include bem.modifier('mod') {
174 font-size: 2.5em; 174 font-size: 2.5em;
175 } 175 }
176 } 176 }
177 } 177 }
178 } 178 }
179 179
180 @include expect { 180 @include expect {
181 .something { 181 .something {
182 font-size: 2em; 182 font-size: 2em;
183 } 183 }
184 184
185 .something--mod { 185 .something--mod {
186 font-size: 2.5em; 186 font-size: 2.5em;
187 } 187 }
188 188
189 .something__child { 189 .something__child {
190 font-size: 2em; 190 font-size: 2em;
191 } 191 }
192 192
193 .something__child--mod { 193 .something__child--mod {
194 font-size: 2.5em; 194 font-size: 2.5em;
195 } 195 }
196 } 196 }
197 } 197 }
198 198
199 @include assert('in block, 1 element, 1 manual selector') { /// 7 /// 199 @include assert('in block, 1 element, 1 manual selector') { /// 7 ///
200 @include output { 200 @include output {
201 @include bem.block('something') { 201 @include bem.block('something') {
202 @include bem.multi('> a:hover', 'elem:' 'child1') { 202 @include bem.multi('> a:hover', 'elem:' 'child1') {
203 font-size: 2em; 203 font-size: 2em;
204 204
205 @include bem.elem('child2') { 205 @include bem.elem('child2') {
206 font-size: 3em; 206 font-size: 3em;
207 } 207 }
208 } 208 }
209 } 209 }
210 } 210 }
211 211
212 @include expect { 212 @include expect {
213 .something > a:hover { 213 .something > a:hover {
214 font-size: 2em; 214 font-size: 2em;
215 } 215 }
216 216
217 .something > a:hover .something__child2 { 217 .something > a:hover .something__child2 {
218 font-size: 3em; 218 font-size: 3em;
219 } 219 }
220 220
221 .something__child1 { 221 .something__child1 {
222 font-size: 2em; 222 font-size: 2em;
223 } 223 }
224 224
225 .something__child1 .something__child2 { 225 .something__child1 .something__child2 {
226 font-size: 3em; 226 font-size: 3em;
227 } 227 }
228 } 228 }
229 } 229 }
230 230
231 @include assert('in element, 2 elements, 1 modifier') { /// 8 /// 231 @include assert('in element, 2 elements, 1 modifier') { /// 8 ///
232 @include output { 232 @include output {
233 @include bem.block('something') { 233 @include bem.block('something') {
234 @include bem.elem('child') { 234 @include bem.elem('child') {
235 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod1') { 235 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod1') {
236 font-size: 3em; 236 font-size: 3em;
237 237
238 @include bem.modifier('mod2') { 238 @include bem.modifier('mod2') {
239 font-size: 3.5em; 239 font-size: 3.5em;
240 } 240 }
241 } 241 }
242 } 242 }
243 } 243 }
244 } 244 }
245 245
246 @include expect { 246 @include expect {
247 .something__child .something__subchild1, 247 .something__child .something__subchild1,
248 .something__child .something__subchild2 { 248 .something__child .something__subchild2 {
249 font-size: 3em; 249 font-size: 3em;
250 } 250 }
251 251
252 .something__child .something__subchild1--mod2, 252 .something__child .something__subchild1--mod2,
253 .something__child .something__subchild2--mod2 { 253 .something__child .something__subchild2--mod2 {
254 font-size: 3.5em; 254 font-size: 3.5em;
255 } 255 }
256 256
257 .something__child--mod1 { 257 .something__child--mod1 {
258 font-size: 3em; 258 font-size: 3em;
259 } 259 }
260 260
261 .something__child--mod1.something__child--mod2 { 261 .something__child--mod1.something__child--mod2 {
262 font-size: 3.5em; 262 font-size: 3.5em;
263 } 263 }
264 } 264 }
265 } 265 }
266 266
267 @include assert('in element, 1 element, 1 & selector') { /// 9 /// 267 @include assert('in element, 1 element, 1 & selector') { /// 9 ///
268 @include output { 268 @include output {
269 @include bem.block('something') { 269 @include bem.block('something') {
270 @include bem.elem('child') { 270 @include bem.elem('child') {
271 @include bem.multi('elem:' 'subchild', '&') { 271 @include bem.multi('elem:' 'subchild', '&') {
272 font-size: 3em; 272 font-size: 3em;
273 273
274 @include bem.modifier('mod') { 274 @include bem.modifier('mod') {
275 font-size: 3.5em; 275 font-size: 3.5em;
276 } 276 }
277 } 277 }
278 } 278 }
279 } 279 }
280 } 280 }
281 281
282 @include expect { 282 @include expect {
283 .something__child .something__subchild { 283 .something__child .something__subchild {
284 font-size: 3em; 284 font-size: 3em;
285 } 285 }
286 286
287 .something__child .something__subchild--mod { 287 .something__child .something__subchild--mod {
288 font-size: 3.5em; 288 font-size: 3.5em;
289 } 289 }
290 290
291 .something__child { 291 .something__child {
292 font-size: 3em; 292 font-size: 3em;
293 } 293 }
294 294
295 .something__child--mod { 295 .something__child--mod {
296 font-size: 3.5em; 296 font-size: 3.5em;
297 } 297 }
298 } 298 }
299 } 299 }
300 300
301 @include assert('in element in manual selector, 2 elements') { /// 10 /// 301 @include assert('in element in manual selector, 2 elements') { /// 10 ///
302 @include output { 302 @include output {
303 @include bem.block('something') { 303 @include bem.block('something') {
304 @include bem.elem('child') { 304 @include bem.elem('child') {
305 &:hover { 305 &:hover {
306 @include bem.multi('elem:' 'subchild1' 'subchild2') { 306 @include bem.multi('elem:' 'subchild1' 'subchild2') {
307 font-size: 3em; 307 font-size: 3em;
308 308
309 @include bem.modifier('mod2') { 309 @include bem.modifier('mod2') {
310 font-size: 3.5em; 310 font-size: 3.5em;
311 } 311 }
312 } 312 }
313 } 313 }
314 } 314 }
315 } 315 }
316 } 316 }
317 317
318 @include expect { 318 @include expect {
319 .something__child:hover .something__subchild1, 319 .something__child:hover .something__subchild1,
320 .something__child:hover .something__subchild2 { 320 .something__child:hover .something__subchild2 {
321 font-size: 3em; 321 font-size: 3em;
322 } 322 }
323 323
324 .something__child:hover .something__subchild1--mod2, 324 .something__child:hover .something__subchild1--mod2,
325 .something__child:hover .something__subchild2--mod2 { 325 .something__child:hover .something__subchild2--mod2 {
326 font-size: 3.5em; 326 font-size: 3.5em;
327 } 327 }
328 } 328 }
329 } 329 }
330 330
331 @include assert('in element in manual selector, 1 element, 1 & selector') { /// 11 /// 331 @include assert('in element in manual selector, 1 element, 1 & selector') { /// 11 ///
332 @include output { 332 @include output {
333 @include bem.block('something') { 333 @include bem.block('something') {
334 @include bem.elem('child') { 334 @include bem.elem('child') {
335 &:hover { 335 &:hover {
336 @include bem.multi('elem:' 'subchild', '&') { 336 @include bem.multi('elem:' 'subchild', '&') {
337 font-size: 3em; 337 font-size: 3em;
338 } 338 }
339 } 339 }
340 } 340 }
341 } 341 }
342 } 342 }
343 343
344 @include expect { 344 @include expect {
345 .something__child:hover .something__subchild { 345 .something__child:hover .something__subchild {
346 font-size: 3em; 346 font-size: 3em;
347 } 347 }
348 348
349 .something__child:hover { 349 .something__child:hover {
350 font-size: 3em; 350 font-size: 3em;
351 } 351 }
352 } 352 }
353 } 353 }
354 354
355 @include assert('in multiple elements, 2 elements, 1 modifier') { /// 12 /// 355 @include assert('in multiple elements, 2 elements, 1 modifier') { /// 12 ///
356 @include output { 356 @include output {
357 @include bem.block('something') { 357 @include bem.block('something') {
358 @include bem.elem('child1', 'child2') { 358 @include bem.elem('child1', 'child2') {
359 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod') { 359 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod') {
360 font-size: 3em; 360 font-size: 3em;
361 } 361 }
362 } 362 }
363 } 363 }
364 } 364 }
365 365
366 @include expect { 366 @include expect {
367 .something__child1 .something__subchild1, 367 .something__child1 .something__subchild1,
368 .something__child2 .something__subchild1, 368 .something__child2 .something__subchild1,
369 .something__child1 .something__subchild2, 369 .something__child1 .something__subchild2,
370 .something__child2 .something__subchild2 { 370 .something__child2 .something__subchild2 {
371 font-size: 3em; 371 font-size: 3em;
372 } 372 }
373 373
374 .something__child1--mod, 374 .something__child1--mod,
375 .something__child2--mod { 375 .something__child2--mod {
376 font-size: 3em; 376 font-size: 3em;
377 } 377 }
378 } 378 }
379 } 379 }
380 380
381 @include assert('in multiple elements, 1 element, 1 & selector') { /// 13 /// 381 @include assert('in multiple elements, 1 element, 1 & selector') { /// 13 ///
382 @include output { 382 @include output {
383 @include bem.block('something') { 383 @include bem.block('something') {
384 @include bem.elem('child1', 'child2') { 384 @include bem.elem('child1', 'child2') {
385 @include bem.multi('elem:' 'subchild', '&') { 385 @include bem.multi('elem:' 'subchild', '&') {
386 font-size: 3em; 386 font-size: 3em;
387 387
388 @include bem.modifier('mod') { 388 @include bem.modifier('mod') {
389 font-size: 3.5em; 389 font-size: 3.5em;
390 } 390 }
391 } 391 }
392 } 392 }
393 } 393 }
394 } 394 }
395 395
396 @include expect { 396 @include expect {
397 .something__child1 .something__subchild, 397 .something__child1 .something__subchild,
398 .something__child2 .something__subchild { 398 .something__child2 .something__subchild {
399 font-size: 3em; 399 font-size: 3em;
400 } 400 }
401 401
402 .something__child1 .something__subchild--mod, 402 .something__child1 .something__subchild--mod,
403 .something__child2 .something__subchild--mod { 403 .something__child2 .something__subchild--mod {
404 font-size: 3.5em; 404 font-size: 3.5em;
405 } 405 }
406 406
407 .something__child1, 407 .something__child1,
408 .something__child2 { 408 .something__child2 {
409 font-size: 3em; 409 font-size: 3em;
410 } 410 }
411 411
412 .something__child1--mod, 412 .something__child1--mod,
413 .something__child2--mod { 413 .something__child2--mod {
414 font-size: 3.5em; 414 font-size: 3.5em;
415 } 415 }
416 } 416 }
417 } 417 }
418 418
419 @include assert('in related elements, 2 elements, 1 modifier') { /// 14 /// 419 @include assert('in related elements, 2 elements, 1 modifier') { /// 14 ///
420 @include output { 420 @include output {
421 @include bem.block('something') { 421 @include bem.block('something') {
422 @include bem.elem('child1') { 422 @include bem.elem('child1') {
423 @include bem.next-elem('child2', 'child3') { 423 @include bem.next-elem('child2', 'child3') {
424 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod') { 424 @include bem.multi('elem:' 'subchild1' 'subchild2', 'modifier:' 'mod') {
425 font-size: 3em; 425 font-size: 3em;
426 } 426 }
427 } 427 }
428 } 428 }
429 } 429 }
430 } 430 }
431 431
432 @include expect { 432 @include expect {
433 .something__child1 + .something__child2 .something__subchild1, 433 .something__child1 + .something__child2 .something__subchild1,
434 .something__child1 + .something__child3 .something__subchild1, 434 .something__child1 + .something__child3 .something__subchild1,
435 .something__child1 + .something__child2 .something__subchild2, 435 .something__child1 + .something__child2 .something__subchild2,
436 .something__child1 + .something__child3 .something__subchild2 { 436 .something__child1 + .something__child3 .something__subchild2 {
437 font-size: 3em; 437 font-size: 3em;
438 } 438 }
439 439
440 .something__child1 + .something__child2--mod, 440 .something__child1 + .something__child2--mod,
441 .something__child1 + .something__child3--mod { 441 .something__child1 + .something__child3--mod {
442 font-size: 3em; 442 font-size: 3em;
443 } 443 }
444 } 444 }
445 } 445 }
446 446
447 @include assert('in related elements, 1 element, 1 & selector') { /// 15 /// 447 @include assert('in related elements, 1 element, 1 & selector') { /// 15 ///
448 @include output { 448 @include output {
449 @include bem.block('something') { 449 @include bem.block('something') {
450 @include bem.elem('child1') { 450 @include bem.elem('child1') {
451 @include bem.next-elem('child2', 'child3') { 451 @include bem.next-elem('child2', 'child3') {
452 @include bem.multi('elem:' 'subchild', '&') { 452 @include bem.multi('elem:' 'subchild', '&') {
453 font-size: 4em; 453 font-size: 4em;
454 454
455 @include bem.modifier('mod') { 455 @include bem.modifier('mod') {
456 font-size: 4.5em; 456 font-size: 4.5em;
457 } 457 }
458 } 458 }
459 } 459 }
460 } 460 }
461 } 461 }
462 } 462 }
463 463
464 @include expect { 464 @include expect {
465 .something__child1 + .something__child2 .something__subchild, 465 .something__child1 + .something__child2 .something__subchild,
466 .something__child1 + .something__child3 .something__subchild { 466 .something__child1 + .something__child3 .something__subchild {
467 font-size: 4em; 467 font-size: 4em;
468 } 468 }
469 469
470 .something__child1 + .something__child2 .something__subchild--mod, 470 .something__child1 + .something__child2 .something__subchild--mod,
471 .something__child1 + .something__child3 .something__subchild--mod { 471 .something__child1 + .something__child3 .something__subchild--mod {
472 font-size: 4.5em; 472 font-size: 4.5em;
473 } 473 }
474 474
475 .something__child1 + .something__child2, 475 .something__child1 + .something__child2,
476 .something__child1 + .something__child3 { 476 .something__child1 + .something__child3 {
477 font-size: 4em; 477 font-size: 4em;
478 } 478 }
479 479
480 .something__child1 + .something__child2--mod, 480 .something__child1 + .something__child2--mod,
481 .something__child1 + .something__child3--mod { 481 .something__child1 + .something__child3--mod {
482 font-size: 4.5em; 482 font-size: 4.5em;
483 } 483 }
484 } 484 }
485 } 485 }
486 486
487 @include assert('in element, 2 related elements, 1 modifier') { /// 16 /// 487 @include assert('in element, 2 related elements, 1 modifier') { /// 16 ///
488 @include output { 488 @include output {
489 @include bem.block('something') { 489 @include bem.block('something') {
490 @include bem.elem('child1') { 490 @include bem.elem('child1') {
491 @include bem.multi('next-elem:' 'child2' 'child3', 'modifier:' 'mod1') { 491 @include bem.multi('next-elem:' 'child2' 'child3', 'modifier:' 'mod1') {
492 font-size: 3em; 492 font-size: 3em;
493 493
494 @include bem.modifier('mod2') { 494 @include bem.modifier('mod2') {
495 font-size: 3.5em; 495 font-size: 3.5em;
496 } 496 }
497 } 497 }
498 } 498 }
499 } 499 }
500 } 500 }
501 501
502 @include expect { 502 @include expect {
503 .something__child1 + .something__child2, 503 .something__child1 + .something__child2,
504 .something__child1 + .something__child3 { 504 .something__child1 + .something__child3 {
505 font-size: 3em; 505 font-size: 3em;
506 } 506 }
507 507
508 .something__child1 + .something__child2--mod2, 508 .something__child1 + .something__child2--mod2,
509 .something__child1 + .something__child3--mod2 { 509 .something__child1 + .something__child3--mod2 {
510 font-size: 3.5em; 510 font-size: 3.5em;
511 } 511 }
512 512
513 .something__child1--mod1 { 513 .something__child1--mod1 {
514 font-size: 3em; 514 font-size: 3em;
515 } 515 }
516 516
517 .something__child1--mod1.something__child1--mod2 { 517 .something__child1--mod1.something__child1--mod2 {
518 font-size: 3.5em; 518 font-size: 3.5em;
519 } 519 }
520 } 520 }
521 } 521 }
522 522
523 @include assert('in element, 1 twin element, 1 modifier') { /// 17 /// 523 @include assert('in element, 1 twin element, 1 modifier') { /// 17 ///
524 @include output { 524 @include output {
525 @include bem.block('something') { 525 @include bem.block('something') {
526 @include bem.elem('child') { 526 @include bem.elem('child') {
527 @include bem.multi('next-twin-elem', 'modifier:' 'mod1') { 527 @include bem.multi('next-twin-elem', 'modifier:' 'mod1') {
528 font-size: 3em; 528 font-size: 3em;
529 529
530 @include bem.modifier('mod2') { 530 @include bem.modifier('mod2') {
531 font-size: 3.5em; 531 font-size: 3.5em;
532 } 532 }
533 } 533 }
534 } 534 }
535 } 535 }
536 } 536 }
537 537
538 @include expect { 538 @include expect {
539 .something__child + .something__child { 539 .something__child + .something__child {
540 font-size: 3em; 540 font-size: 3em;
541 } 541 }
542 542
543 .something__child + .something__child--mod2 { 543 .something__child + .something__child--mod2 {
544 font-size: 3.5em; 544 font-size: 3.5em;
545 } 545 }
546 546
547 .something__child--mod1 { 547 .something__child--mod1 {
548 font-size: 3em; 548 font-size: 3em;
549 } 549 }
550 550
551 .something__child--mod1.something__child--mod2 { 551 .something__child--mod1.something__child--mod2 {
552 font-size: 3.5em; 552 font-size: 3.5em;
553 } 553 }
554 } 554 }
555 } 555 }
556 556
557 @include assert('in multiple elements, 1 twin element, 1 modifier') { /// 18 /// 557 @include assert('in multiple elements, 1 twin element, 1 modifier') { /// 18 ///
558 @include output { 558 @include output {
559 @include bem.block('something') { 559 @include bem.block('something') {
560 @include bem.elem('child1', 'child2') { 560 @include bem.elem('child1', 'child2') {
561 @include bem.multi('next-twin-elem', 'modifier:' 'mod1') { 561 @include bem.multi('next-twin-elem', 'modifier:' 'mod1') {
562 font-size: 3em; 562 font-size: 3em;
563 563
564 @include bem.modifier('mod2') { 564 @include bem.modifier('mod2') {
565 font-size: 3.5em; 565 font-size: 3.5em;
566 } 566 }
567 } 567 }
568 } 568 }
569 } 569 }
570 } 570 }
571 571
572 @include expect { 572 @include expect {
573 .something__child1 + .something__child1, 573 .something__child1 + .something__child1,
574 .something__child2 + .something__child2 { 574 .something__child2 + .something__child2 {
575 font-size: 3em; 575 font-size: 3em;
576 } 576 }
577 577
578 .something__child1 + .something__child1--mod2, 578 .something__child1 + .something__child1--mod2,
579 .something__child2 + .something__child2--mod2 { 579 .something__child2 + .something__child2--mod2 {
580 font-size: 3.5em; 580 font-size: 3.5em;
581 } 581 }
582 582
583 .something__child1--mod1, 583 .something__child1--mod1,
584 .something__child2--mod1 { 584 .something__child2--mod1 {
585 font-size: 3em; 585 font-size: 3em;
586 } 586 }
587 587
588 .something__child1--mod1.something__child1--mod2, 588 .something__child1--mod1.something__child1--mod2,
589 .something__child2--mod1.something__child2--mod2 { 589 .something__child2--mod1.something__child2--mod2 {
590 font-size: 3.5em; 590 font-size: 3.5em;
591 } 591 }
592 } 592 }
593 } 593 }
594} 594}
diff --git a/test/bem/_next-twin-element.scss b/test/bem/_next-twin-element.scss
index 355e635..3365a0b 100644
--- a/test/bem/_next-twin-element.scss
+++ b/test/bem/_next-twin-element.scss
@@ -14,143 +14,143 @@
14// 14//
15 15
16@include it('next-twin-elem') { 16@include it('next-twin-elem') {
17 @include assert('single element') { /// 1 /// 17 @include assert('single element') { /// 1 ///
18 @include output { 18 @include output {
19 @include bem.block('something') { 19 @include bem.block('something') {
20 @include bem.elem('child') { 20 @include bem.elem('child') {
21 @include bem.next-twin-elem { 21 @include bem.next-twin-elem {
22 font-size: 2em; 22 font-size: 2em;
23 } 23 }
24 } 24 }
25 } 25 }
26 } 26 }
27 27
28 @include expect { 28 @include expect {
29 .something__child + .something__child { 29 .something__child + .something__child {
30 font-size: 2em; 30 font-size: 2em;
31 } 31 }
32 } 32 }
33 } 33 }
34 34
35 @include assert('single element, manual selector in-between') { /// 2 /// 35 @include assert('single element, manual selector in-between') { /// 2 ///
36 @include output(false) { 36 @include output(false) {
37 @include bem.block('something') { 37 @include bem.block('something') {
38 @include bem.elem('child') { 38 @include bem.elem('child') {
39 &:hover { 39 &:hover {
40 @include bem.next-twin-elem { 40 @include bem.next-twin-elem {
41 font-size: 2em; 41 font-size: 2em;
42 } 42 }
43 } 43 }
44 44
45 .test & { 45 .test & {
46 @include bem.next-twin-elem { 46 @include bem.next-twin-elem {
47 font-size: 2em; 47 font-size: 2em;
48 } 48 }
49 } 49 }
50 } 50 }
51 } 51 }
52 } 52 }
53 53
54 @include expect(false) { 54 @include expect(false) {
55 .something__child:hover + .something__child { 55 .something__child:hover + .something__child {
56 font-size: 2em; 56 font-size: 2em;
57 } 57 }
58 58
59 .test .something__child + .something__child { 59 .test .something__child + .something__child {
60 font-size: 2em; 60 font-size: 2em;
61 } 61 }
62 } 62 }
63 } 63 }
64 64
65 @include assert('single element, modifier in-between') { /// 3 /// 65 @include assert('single element, modifier in-between') { /// 3 ///
66 @include output { 66 @include output {
67 @include bem.block('something') { 67 @include bem.block('something') {
68 @include bem.elem('child') { 68 @include bem.elem('child') {
69 @include bem.modifier('mod') { 69 @include bem.modifier('mod') {
70 @include bem.next-twin-elem { 70 @include bem.next-twin-elem {
71 font-size: 2.5em; 71 font-size: 2.5em;
72 } 72 }
73 } 73 }
74 } 74 }
75 } 75 }
76 } 76 }
77 77
78 @include expect { 78 @include expect {
79 .something__child--mod + .something__child { 79 .something__child--mod + .something__child {
80 font-size: 2.5em; 80 font-size: 2.5em;
81 } 81 }
82 } 82 }
83 } 83 }
84 84
85 @include assert('multiple elements') { /// 4 /// 85 @include assert('multiple elements') { /// 4 ///
86 @include output { 86 @include output {
87 @include bem.block('something') { 87 @include bem.block('something') {
88 @include bem.elem('child1', 'child2') { 88 @include bem.elem('child1', 'child2') {
89 @include bem.next-twin-elem { 89 @include bem.next-twin-elem {
90 font-size: 2em; 90 font-size: 2em;
91 } 91 }
92 } 92 }
93 } 93 }
94 } 94 }
95 95
96 @include expect { 96 @include expect {
97 .something__child1 + .something__child1, 97 .something__child1 + .something__child1,
98 .something__child2 + .something__child2 { 98 .something__child2 + .something__child2 {
99 font-size: 2em; 99 font-size: 2em;
100 } 100 }
101 } 101 }
102 } 102 }
103 103
104 @include assert('multiple elements, manual selector in-between') { /// 5 /// 104 @include assert('multiple elements, manual selector in-between') { /// 5 ///
105 @include output(false) { 105 @include output(false) {
106 @include bem.block('something') { 106 @include bem.block('something') {
107 @include bem.elem('child1', 'child2') { 107 @include bem.elem('child1', 'child2') {
108 &:hover { 108 &:hover {
109 @include bem.next-twin-elem { 109 @include bem.next-twin-elem {
110 font-size: 2em; 110 font-size: 2em;
111 } 111 }
112 } 112 }
113 113
114 .test & { 114 .test & {
115 @include bem.next-twin-elem { 115 @include bem.next-twin-elem {
116 font-size: 2em; 116 font-size: 2em;
117 } 117 }
118 } 118 }
119 } 119 }
120 } 120 }
121 } 121 }
122 122
123 @include expect(false) { 123 @include expect(false) {
124 .something__child1:hover + .something__child1, 124 .something__child1:hover + .something__child1,
125 .something__child2:hover + .something__child2 { 125 .something__child2:hover + .something__child2 {
126 font-size: 2em; 126 font-size: 2em;
127 } 127 }
128 128
129 .test .something__child1 + .something__child1, 129 .test .something__child1 + .something__child1,
130 .test .something__child2 + .something__child2 { 130 .test .something__child2 + .something__child2 {
131 font-size: 2em; 131 font-size: 2em;
132 } 132 }
133 } 133 }
134 } 134 }
135 135
136 @include assert('multiple elements, modifier in-between') { /// 6 /// 136 @include assert('multiple elements, modifier in-between') { /// 6 ///
137 @include output { 137 @include output {
138 @include bem.block('something') { 138 @include bem.block('something') {
139 @include bem.elem('child1', 'child2') { 139 @include bem.elem('child1', 'child2') {
140 @include bem.modifier('mod') { 140 @include bem.modifier('mod') {
141 @include bem.next-twin-elem { 141 @include bem.next-twin-elem {
142 font-size: 2.5em; 142 font-size: 2.5em;
143 } 143 }
144 } 144 }
145 } 145 }
146 } 146 }
147 } 147 }
148 148
149 @include expect { 149 @include expect {
150 .something__child1--mod + .something__child1, 150 .something__child1--mod + .something__child1,
151 .something__child2--mod + .something__child2 { 151 .something__child2--mod + .something__child2 {
152 font-size: 2.5em; 152 font-size: 2.5em;
153 } 153 }
154 } 154 }
155 } 155 }
156} 156}
diff --git a/test/bem/_related-element.scss b/test/bem/_related-element.scss
index 5a829e8..48b3457 100644
--- a/test/bem/_related-element.scss
+++ b/test/bem/_related-element.scss
@@ -20,443 +20,443 @@
20// 20//
21 21
22@include it('related-element') { 22@include it('related-element') {
23 @include assert('single element, single related element') { /// 1 /// 23 @include assert('single element, single related element') { /// 1 ///
24 @include output { 24 @include output {
25 @include bem.block('something') { 25 @include bem.block('something') {
26 @include bem.elem('child') { 26 @include bem.elem('child') {
27 @include bem.related-elem('+', 'subchild1') { 27 @include bem.related-elem('+', 'subchild1') {
28 font-size: 2em; 28 font-size: 2em;
29 } 29 }
30 30
31 @include bem.related-elem('~', 'subchild2') { 31 @include bem.related-elem('~', 'subchild2') {
32 font-size: 2em; 32 font-size: 2em;
33 } 33 }
34 } 34 }
35 } 35 }
36 } 36 }
37 37
38 @include expect { 38 @include expect {
39 .something__child + .something__subchild1 { 39 .something__child + .something__subchild1 {
40 font-size: 2em; 40 font-size: 2em;
41 } 41 }
42 42
43 .something__child ~ .something__subchild2 { 43 .something__child ~ .something__subchild2 {
44 font-size: 2em; 44 font-size: 2em;
45 } 45 }
46 } 46 }
47 } 47 }
48 48
49 @include assert('single element, single related element, manual selector in-between') { /// 2 /// 49 @include assert('single element, single related element, manual selector in-between') { /// 2 ///
50 @include output(false) { 50 @include output(false) {
51 @include bem.block('something') { 51 @include bem.block('something') {
52 @include bem.elem('child') { 52 @include bem.elem('child') {
53 &:hover { 53 &:hover {
54 @include bem.related-elem('+', 'subchild1') { 54 @include bem.related-elem('+', 'subchild1') {
55 font-size: 2em; 55 font-size: 2em;
56 } 56 }
57 57
58 @include bem.related-elem('~', 'subchild2') { 58 @include bem.related-elem('~', 'subchild2') {
59 font-size: 2em; 59 font-size: 2em;
60 } 60 }
61 } 61 }
62 62
63 .test & { 63 .test & {
64 @include bem.related-elem('+', 'subchild3') { 64 @include bem.related-elem('+', 'subchild3') {
65 font-size: 2em; 65 font-size: 2em;
66 } 66 }
67 67
68 @include bem.related-elem('~', 'subchild4') { 68 @include bem.related-elem('~', 'subchild4') {
69 font-size: 2em; 69 font-size: 2em;
70 } 70 }
71 } 71 }
72 } 72 }
73 } 73 }
74 } 74 }
75 75
76 @include expect(false) { 76 @include expect(false) {
77 .something__child:hover + .something__subchild1 { 77 .something__child:hover + .something__subchild1 {
78 font-size: 2em; 78 font-size: 2em;
79 } 79 }
80 80
81 .something__child:hover ~ .something__subchild2 { 81 .something__child:hover ~ .something__subchild2 {
82 font-size: 2em; 82 font-size: 2em;
83 } 83 }
84 84
85 .test .something__child + .something__subchild3 { 85 .test .something__child + .something__subchild3 {
86 font-size: 2em; 86 font-size: 2em;
87 } 87 }
88 88
89 .test .something__child ~ .something__subchild4 { 89 .test .something__child ~ .something__subchild4 {
90 font-size: 2em; 90 font-size: 2em;
91 } 91 }
92 } 92 }
93 } 93 }
94 94
95 @include assert('single element, single related element, modifier in-between') { /// 3 /// 95 @include assert('single element, single related element, modifier in-between') { /// 3 ///
96 @include output { 96 @include output {
97 @include bem.block('something') { 97 @include bem.block('something') {
98 @include bem.elem('child') { 98 @include bem.elem('child') {
99 @include bem.modifier('mod') { 99 @include bem.modifier('mod') {
100 @include bem.related-elem('+', 'subchild1') { 100 @include bem.related-elem('+', 'subchild1') {
101 font-size: 2.5em; 101 font-size: 2.5em;
102 } 102 }
103 103
104 @include bem.related-elem('~', 'subchild2') { 104 @include bem.related-elem('~', 'subchild2') {
105 font-size: 2.5em; 105 font-size: 2.5em;
106 } 106 }
107 } 107 }
108 } 108 }
109 } 109 }
110 } 110 }
111 111
112 @include expect { 112 @include expect {
113 .something__child--mod + .something__subchild1 { 113 .something__child--mod + .something__subchild1 {
114 font-size: 2.5em; 114 font-size: 2.5em;
115 } 115 }
116 116
117 .something__child--mod ~ .something__subchild2 { 117 .something__child--mod ~ .something__subchild2 {
118 font-size: 2.5em; 118 font-size: 2.5em;
119 } 119 }
120 } 120 }
121 } 121 }
122 122
123 @include assert('single element, multiple related elements') { /// 4 /// 123 @include assert('single element, multiple related elements') { /// 4 ///
124 @include output { 124 @include output {
125 @include bem.block('something') { 125 @include bem.block('something') {
126 @include bem.elem('child') { 126 @include bem.elem('child') {
127 @include bem.related-elem('+', 'subchild1', 'subchild2') { 127 @include bem.related-elem('+', 'subchild1', 'subchild2') {
128 font-size: 2.5em; 128 font-size: 2.5em;
129 } 129 }
130 130
131 @include bem.related-elem('~', 'subchild3', 'subchild4') { 131 @include bem.related-elem('~', 'subchild3', 'subchild4') {
132 font-size: 2.5em; 132 font-size: 2.5em;
133 } 133 }
134 } 134 }
135 } 135 }
136 } 136 }
137 137
138 @include expect { 138 @include expect {
139 .something__child + .something__subchild1, 139 .something__child + .something__subchild1,
140 .something__child + .something__subchild2 { 140 .something__child + .something__subchild2 {
141 font-size: 2.5em; 141 font-size: 2.5em;
142 } 142 }
143 143
144 .something__child ~ .something__subchild3, 144 .something__child ~ .something__subchild3,
145 .something__child ~ .something__subchild4 { 145 .something__child ~ .something__subchild4 {
146 font-size: 2.5em; 146 font-size: 2.5em;
147 } 147 }
148 } 148 }
149 } 149 }
150 150
151 @include assert('single element, multiple related elements, manual selector in-between') { /// 5 /// 151 @include assert('single element, multiple related elements, manual selector in-between') { /// 5 ///
152 @include output(false) { 152 @include output(false) {
153 @include bem.block('something') { 153 @include bem.block('something') {
154 @include bem.elem('child') { 154 @include bem.elem('child') {
155 &:hover { 155 &:hover {
156 @include bem.related-elem('+', 'subchild1', 'subchild2') { 156 @include bem.related-elem('+', 'subchild1', 'subchild2') {
157 font-size: 2.5em; 157 font-size: 2.5em;
158 } 158 }
159 159
160 @include bem.related-elem('~', 'subchild3', 'subchild4') { 160 @include bem.related-elem('~', 'subchild3', 'subchild4') {
161 font-size: 2.5em; 161 font-size: 2.5em;
162 } 162 }
163 } 163 }
164 164
165 .test & { 165 .test & {
166 @include bem.related-elem('+', 'subchild5', 'subchild6') { 166 @include bem.related-elem('+', 'subchild5', 'subchild6') {
167 font-size: 2.5em; 167 font-size: 2.5em;
168 } 168 }
169 169
170 @include bem.related-elem('~', 'subchild7', 'subchild8') { 170 @include bem.related-elem('~', 'subchild7', 'subchild8') {
171 font-size: 2.5em; 171 font-size: 2.5em;
172 } 172 }
173 } 173 }
174 } 174 }
175 } 175 }
176 } 176 }
177 177
178 @include expect(false) { 178 @include expect(false) {
179 .something__child:hover + .something__subchild1, 179 .something__child:hover + .something__subchild1,
180 .something__child:hover + .something__subchild2 { 180 .something__child:hover + .something__subchild2 {
181 font-size: 2.5em; 181 font-size: 2.5em;
182 } 182 }
183 183
184 .something__child:hover ~ .something__subchild3, 184 .something__child:hover ~ .something__subchild3,
185 .something__child:hover ~ .something__subchild4 { 185 .something__child:hover ~ .something__subchild4 {
186 font-size: 2.5em; 186 font-size: 2.5em;
187 } 187 }
188 188
189 .test .something__child + .something__subchild5, 189 .test .something__child + .something__subchild5,
190 .test .something__child + .something__subchild6 { 190 .test .something__child + .something__subchild6 {
191 font-size: 2.5em; 191 font-size: 2.5em;
192 } 192 }
193 193
194 .test .something__child ~ .something__subchild7, 194 .test .something__child ~ .something__subchild7,
195 .test .something__child ~ .something__subchild8 { 195 .test .something__child ~ .something__subchild8 {
196 font-size: 2.5em; 196 font-size: 2.5em;
197 } 197 }
198 } 198 }
199 } 199 }
200 200
201 @include assert('single element, multiple related elements, modifier in-between') { /// 6 /// 201 @include assert('single element, multiple related elements, modifier in-between') { /// 6 ///
202 @include output { 202 @include output {
203 @include bem.block('something') { 203 @include bem.block('something') {
204 @include bem.elem('child') { 204 @include bem.elem('child') {
205 @include bem.modifier('mod') { 205 @include bem.modifier('mod') {
206 @include bem.related-elem('+', 'subchild1', 'subchild2') { 206 @include bem.related-elem('+', 'subchild1', 'subchild2') {
207 font-size: 2.5em; 207 font-size: 2.5em;
208 } 208 }
209 209
210 @include bem.related-elem('~', 'subchild3', 'subchild4') { 210 @include bem.related-elem('~', 'subchild3', 'subchild4') {
211 font-size: 2.5em; 211 font-size: 2.5em;
212 } 212 }
213 } 213 }
214 } 214 }
215 } 215 }
216 } 216 }
217 217
218 @include expect { 218 @include expect {
219 .something__child--mod + .something__subchild1, 219 .something__child--mod + .something__subchild1,
220 .something__child--mod + .something__subchild2 { 220 .something__child--mod + .something__subchild2 {
221 font-size: 2.5em; 221 font-size: 2.5em;
222 } 222 }
223 223
224 .something__child--mod ~ .something__subchild3, 224 .something__child--mod ~ .something__subchild3,
225 .something__child--mod ~ .something__subchild4 { 225 .something__child--mod ~ .something__subchild4 {
226 font-size: 2.5em; 226 font-size: 2.5em;
227 } 227 }
228 } 228 }
229 } 229 }
230 230
231 @include assert('multiple elements, single related element') { /// 7 /// 231 @include assert('multiple elements, single related element') { /// 7 ///
232 @include output { 232 @include output {
233 @include bem.block('something') { 233 @include bem.block('something') {
234 @include bem.elem('child1', 'child2') { 234 @include bem.elem('child1', 'child2') {
235 @include bem.related-elem('+', 'subchild1') { 235 @include bem.related-elem('+', 'subchild1') {
236 font-size: 2em; 236 font-size: 2em;
237 } 237 }
238 238
239 @include bem.related-elem('~', 'subchild2') { 239 @include bem.related-elem('~', 'subchild2') {
240 font-size: 2em; 240 font-size: 2em;
241 } 241 }
242 } 242 }
243 } 243 }
244 } 244 }
245 245
246 @include expect { 246 @include expect {
247 .something__child1 + .something__subchild1, 247 .something__child1 + .something__subchild1,
248 .something__child2 + .something__subchild1 { 248 .something__child2 + .something__subchild1 {
249 font-size: 2em; 249 font-size: 2em;
250 } 250 }
251 251
252 .something__child1 ~ .something__subchild2, 252 .something__child1 ~ .something__subchild2,
253 .something__child2 ~ .something__subchild2 { 253 .something__child2 ~ .something__subchild2 {
254 font-size: 2em; 254 font-size: 2em;
255 } 255 }
256 } 256 }
257 } 257 }
258 258
259 @include assert('multiple elements, single related element, manual selector in-between') { /// 8 /// 259 @include assert('multiple elements, single related element, manual selector in-between') { /// 8 ///
260 @include output(false) { 260 @include output(false) {
261 @include bem.block('something') { 261 @include bem.block('something') {
262 @include bem.elem('child1', 'child2') { 262 @include bem.elem('child1', 'child2') {
263 &:hover { 263 &:hover {
264 @include bem.related-elem('+', 'subchild1') { 264 @include bem.related-elem('+', 'subchild1') {
265 font-size: 2em; 265 font-size: 2em;
266 } 266 }
267 267
268 @include bem.related-elem('~', 'subchild2') { 268 @include bem.related-elem('~', 'subchild2') {
269 font-size: 2em; 269 font-size: 2em;
270 } 270 }
271 } 271 }
272 272
273 .test & { 273 .test & {
274 @include bem.related-elem('+', 'subchild3') { 274 @include bem.related-elem('+', 'subchild3') {
275 font-size: 2em; 275 font-size: 2em;
276 } 276 }
277 277
278 @include bem.related-elem('~', 'subchild4') { 278 @include bem.related-elem('~', 'subchild4') {
279 font-size: 2em; 279 font-size: 2em;
280 } 280 }
281 } 281 }
282 } 282 }
283 } 283 }
284 } 284 }
285 285
286 @include expect(false) { 286 @include expect(false) {
287 .something__child1:hover + .something__subchild1, 287 .something__child1:hover + .something__subchild1,
288 .something__child2:hover + .something__subchild1 { 288 .something__child2:hover + .something__subchild1 {
289 font-size: 2em; 289 font-size: 2em;
290 } 290 }
291 291
292 .something__child1:hover ~ .something__subchild2, 292 .something__child1:hover ~ .something__subchild2,
293 .something__child2:hover ~ .something__subchild2 { 293 .something__child2:hover ~ .something__subchild2 {
294 font-size: 2em; 294 font-size: 2em;
295 } 295 }
296 296
297 .test .something__child1 + .something__subchild3, 297 .test .something__child1 + .something__subchild3,
298 .test .something__child2 + .something__subchild3 { 298 .test .something__child2 + .something__subchild3 {
299 font-size: 2em; 299 font-size: 2em;
300 } 300 }
301 301
302 .test .something__child1 ~ .something__subchild4, 302 .test .something__child1 ~ .something__subchild4,
303 .test .something__child2 ~ .something__subchild4 { 303 .test .something__child2 ~ .something__subchild4 {
304 font-size: 2em; 304 font-size: 2em;
305 } 305 }
306 } 306 }
307 } 307 }
308 308
309 @include assert('multiple elements, single related element, modifier in-between') { /// 9 /// 309 @include assert('multiple elements, single related element, modifier in-between') { /// 9 ///
310 @include output { 310 @include output {
311 @include bem.block('something') { 311 @include bem.block('something') {
312 @include bem.elem('child1', 'child2') { 312 @include bem.elem('child1', 'child2') {
313 @include bem.modifier('mod') { 313 @include bem.modifier('mod') {
314 @include bem.related-elem('+', 'subchild1') { 314 @include bem.related-elem('+', 'subchild1') {
315 font-size: 2.5em; 315 font-size: 2.5em;
316 } 316 }
317 317
318 @include bem.related-elem('~', 'subchild2') { 318 @include bem.related-elem('~', 'subchild2') {
319 font-size: 2.5em; 319 font-size: 2.5em;
320 } 320 }
321 } 321 }
322 } 322 }
323 } 323 }
324 } 324 }
325 325
326 @include expect { 326 @include expect {
327 .something__child1--mod + .something__subchild1, 327 .something__child1--mod + .something__subchild1,
328 .something__child2--mod + .something__subchild1 { 328 .something__child2--mod + .something__subchild1 {
329 font-size: 2.5em; 329 font-size: 2.5em;
330 } 330 }
331 331
332 .something__child1--mod ~ .something__subchild2, 332 .something__child1--mod ~ .something__subchild2,
333 .something__child2--mod ~ .something__subchild2 { 333 .something__child2--mod ~ .something__subchild2 {
334 font-size: 2.5em; 334 font-size: 2.5em;
335 } 335 }
336 } 336 }
337 } 337 }
338 338
339 @include assert('multiple elements, multiple related elements') { /// 10 /// 339 @include assert('multiple elements, multiple related elements') { /// 10 ///
340 @include output { 340 @include output {
341 @include bem.block('something') { 341 @include bem.block('something') {
342 @include bem.elem('child1', 'child2') { 342 @include bem.elem('child1', 'child2') {
343 @include bem.related-elem('+', 'subchild1', 'subchild2') { 343 @include bem.related-elem('+', 'subchild1', 'subchild2') {
344 font-size: 2em; 344 font-size: 2em;
345 } 345 }
346 346
347 @include bem.related-elem('~', 'subchild3', 'subchild4') { 347 @include bem.related-elem('~', 'subchild3', 'subchild4') {
348 font-size: 2em; 348 font-size: 2em;
349 } 349 }
350 } 350 }
351 } 351 }
352 } 352 }
353 353
354 @include expect { 354 @include expect {
355 .something__child1 + .something__subchild1, 355 .something__child1 + .something__subchild1,
356 .something__child2 + .something__subchild1, 356 .something__child2 + .something__subchild1,
357 .something__child1 + .something__subchild2, 357 .something__child1 + .something__subchild2,
358 .something__child2 + .something__subchild2 { 358 .something__child2 + .something__subchild2 {
359 font-size: 2em; 359 font-size: 2em;
360 } 360 }
361 361
362 .something__child1 ~ .something__subchild3, 362 .something__child1 ~ .something__subchild3,
363 .something__child2 ~ .something__subchild3, 363 .something__child2 ~ .something__subchild3,
364 .something__child1 ~ .something__subchild4, 364 .something__child1 ~ .something__subchild4,
365 .something__child2 ~ .something__subchild4 { 365 .something__child2 ~ .something__subchild4 {
366 font-size: 2em; 366 font-size: 2em;
367 } 367 }
368 } 368 }
369 } 369 }
370 370
371 @include assert('multiple elements, multiple related elements, manual selector in-between') { /// 11 /// 371 @include assert('multiple elements, multiple related elements, manual selector in-between') { /// 11 ///
372 @include output(false) { 372 @include output(false) {
373 @include bem.block('something') { 373 @include bem.block('something') {
374 @include bem.elem('child1', 'child2') { 374 @include bem.elem('child1', 'child2') {
375 &:hover { 375 &:hover {
376 @include bem.related-elem('+', 'subchild1', 'subchild2') { 376 @include bem.related-elem('+', 'subchild1', 'subchild2') {
377 font-size: 2em; 377 font-size: 2em;
378 } 378 }
379 379
380 @include bem.related-elem('~', 'subchild3', 'subchild4') { 380 @include bem.related-elem('~', 'subchild3', 'subchild4') {
381 font-size: 2em; 381 font-size: 2em;
382 } 382 }
383 } 383 }
384 384
385 .test & { 385 .test & {
386 @include bem.related-elem('+', 'subchild5', 'subchild6') { 386 @include bem.related-elem('+', 'subchild5', 'subchild6') {
387 font-size: 2em; 387 font-size: 2em;
388 } 388 }
389 389
390 @include bem.related-elem('~', 'subchild7', 'subchild8') { 390 @include bem.related-elem('~', 'subchild7', 'subchild8') {
391 font-size: 2em; 391 font-size: 2em;
392 } 392 }
393 } 393 }
394 } 394 }
395 } 395 }
396 } 396 }
397 397
398 @include expect(false) { 398 @include expect(false) {
399 .something__child1:hover + .something__subchild1, 399 .something__child1:hover + .something__subchild1,
400 .something__child2:hover + .something__subchild1, 400 .something__child2:hover + .something__subchild1,
401 .something__child1:hover + .something__subchild2, 401 .something__child1:hover + .something__subchild2,
402 .something__child2:hover + .something__subchild2 { 402 .something__child2:hover + .something__subchild2 {
403 font-size: 2em; 403 font-size: 2em;
404 } 404 }
405 405
406 .something__child1:hover ~ .something__subchild3, 406 .something__child1:hover ~ .something__subchild3,
407 .something__child2:hover ~ .something__subchild3, 407 .something__child2:hover ~ .something__subchild3,
408 .something__child1:hover ~ .something__subchild4, 408 .something__child1:hover ~ .something__subchild4,
409 .something__child2:hover ~ .something__subchild4 { 409 .something__child2:hover ~ .something__subchild4 {
410 font-size: 2em; 410 font-size: 2em;
411 } 411 }
412 412
413 .test .something__child1 + .something__subchild5, 413 .test .something__child1 + .something__subchild5,
414 .test .something__child2 + .something__subchild5, 414 .test .something__child2 + .something__subchild5,
415 .test .something__child1 + .something__subchild6, 415 .test .something__child1 + .something__subchild6,
416 .test .something__child2 + .something__subchild6 { 416 .test .something__child2 + .something__subchild6 {
417 font-size: 2em; 417 font-size: 2em;
418 } 418 }
419 419
420 .test .something__child1 ~ .something__subchild7, 420 .test .something__child1 ~ .something__subchild7,
421 .test .something__child2 ~ .something__subchild7, 421 .test .something__child2 ~ .something__subchild7,
422 .test .something__child1 ~ .something__subchild8, 422 .test .something__child1 ~ .something__subchild8,
423 .test .something__child2 ~ .something__subchild8 { 423 .test .something__child2 ~ .something__subchild8 {
424 font-size: 2em; 424 font-size: 2em;
425 } 425 }
426 } 426 }
427 } 427 }
428 428
429 @include assert('multiple elements, multiple related elements, modifier in-between') { /// 12 /// 429 @include assert('multiple elements, multiple related elements, modifier in-between') { /// 12 ///
430 @include output { 430 @include output {
431 @include bem.block('something') { 431 @include bem.block('something') {
432 @include bem.elem('child1', 'child2') { 432 @include bem.elem('child1', 'child2') {
433 @include bem.modifier('mod') { 433 @include bem.modifier('mod') {
434 @include bem.related-elem('+', 'subchild1', 'subchild2') { 434 @include bem.related-elem('+', 'subchild1', 'subchild2') {
435 font-size: 2em; 435 font-size: 2em;
436 } 436 }
437 437
438 @include bem.related-elem('~', 'subchild3', 'subchild4') { 438 @include bem.related-elem('~', 'subchild3', 'subchild4') {
439 font-size: 2em; 439 font-size: 2em;
440 } 440 }
441 } 441 }
442 } 442 }
443 } 443 }
444 } 444 }
445 445
446 @include expect { 446 @include expect {
447 .something__child1--mod + .something__subchild1, 447 .something__child1--mod + .something__subchild1,
448 .something__child2--mod + .something__subchild1, 448 .something__child2--mod + .something__subchild1,
449 .something__child1--mod + .something__subchild2, 449 .something__child1--mod + .something__subchild2,
450 .something__child2--mod + .something__subchild2 { 450 .something__child2--mod + .something__subchild2 {
451 font-size: 2em; 451 font-size: 2em;
452 } 452 }
453 453
454 .something__child1--mod ~ .something__subchild3, 454 .something__child1--mod ~ .something__subchild3,
455 .something__child2--mod ~ .something__subchild3, 455 .something__child2--mod ~ .something__subchild3,
456 .something__child1--mod ~ .something__subchild4, 456 .something__child1--mod ~ .something__subchild4,
457 .something__child2--mod ~ .something__subchild4 { 457 .something__child2--mod ~ .something__subchild4 {
458 font-size: 2em; 458 font-size: 2em;
459 } 459 }
460 } 460 }
461 } 461 }
462} 462}
diff --git a/test/bem/_state.scss b/test/bem/_state.scss
index 674da5f..5a1e1d6 100644
--- a/test/bem/_state.scss
+++ b/test/bem/_state.scss
@@ -14,167 +14,167 @@
14// 14//
15 15
16@include it('state') { 16@include it('state') {
17 @include assert('single block, single state') { /// 1 /// 17 @include assert('single block, single state') { /// 1 ///
18 @include output { 18 @include output {
19 @include bem.block('something') { 19 @include bem.block('something') {
20 @include bem.is('active') { 20 @include bem.is('active') {
21 font-size: 1.25em; 21 font-size: 1.25em;
22 } 22 }
23 23
24 @include bem.has('state') { 24 @include bem.has('state') {
25 font-size: 1.75em; 25 font-size: 1.75em;
26 } 26 }
27 } 27 }
28 } 28 }
29 29
30 @include expect { 30 @include expect {
31 .something.is-active { 31 .something.is-active {
32 font-size: 1.25em; 32 font-size: 1.25em;
33 } 33 }
34 34
35 .something.has-state { 35 .something.has-state {
36 font-size: 1.75em; 36 font-size: 1.75em;
37 } 37 }
38 } 38 }
39 } 39 }
40 40
41 @include assert('single element, single state') { /// 2 /// 41 @include assert('single element, single state') { /// 2 ///
42 @include output { 42 @include output {
43 @include bem.block('something') { 43 @include bem.block('something') {
44 @include bem.elem('child') { 44 @include bem.elem('child') {
45 @include bem.is('active') { 45 @include bem.is('active') {
46 font-size: 2.25em; 46 font-size: 2.25em;
47 } 47 }
48 48
49 @include bem.has('state') { 49 @include bem.has('state') {
50 font-size: 2.75em; 50 font-size: 2.75em;
51 } 51 }
52 } 52 }
53 } 53 }
54 } 54 }
55 55
56 @include expect { 56 @include expect {
57 .something__child.is-active { 57 .something__child.is-active {
58 font-size: 2.25em; 58 font-size: 2.25em;
59 } 59 }
60 60
61 .something__child.has-state { 61 .something__child.has-state {
62 font-size: 2.75em; 62 font-size: 2.75em;
63 } 63 }
64 } 64 }
65 } 65 }
66 66
67 @include assert('single block, multiple states') { /// 3 /// 67 @include assert('single block, multiple states') { /// 3 ///
68 @include output { 68 @include output {
69 @include bem.block('something') { 69 @include bem.block('something') {
70 @include bem.is('active', 'primary') { 70 @include bem.is('active', 'primary') {
71 font-size: 1.25em; 71 font-size: 1.25em;
72 } 72 }
73 73
74 @include bem.has('state', 'indicator') { 74 @include bem.has('state', 'indicator') {
75 font-size: 1.75em; 75 font-size: 1.75em;
76 } 76 }
77 } 77 }
78 } 78 }
79 79
80 @include expect { 80 @include expect {
81 .something.is-active, 81 .something.is-active,
82 .something.is-primary { 82 .something.is-primary {
83 font-size: 1.25em; 83 font-size: 1.25em;
84 } 84 }
85 85
86 .something.has-state, 86 .something.has-state,
87 .something.has-indicator { 87 .something.has-indicator {
88 font-size: 1.75em; 88 font-size: 1.75em;
89 } 89 }
90 } 90 }
91 } 91 }
92 92
93 @include assert('single element, multiple states') { /// 4 /// 93 @include assert('single element, multiple states') { /// 4 ///
94 @include output { 94 @include output {
95 @include bem.block('something') { 95 @include bem.block('something') {
96 @include bem.elem('child') { 96 @include bem.elem('child') {
97 @include bem.is('active', 'primary') { 97 @include bem.is('active', 'primary') {
98 font-size: 2.25em; 98 font-size: 2.25em;
99 } 99 }
100 100
101 @include bem.has('state', 'indicator') { 101 @include bem.has('state', 'indicator') {
102 font-size: 2.75em; 102 font-size: 2.75em;
103 } 103 }
104 } 104 }
105 } 105 }
106 } 106 }
107 107
108 @include expect { 108 @include expect {
109 .something__child.is-active, 109 .something__child.is-active,
110 .something__child.is-primary { 110 .something__child.is-primary {
111 font-size: 2.25em; 111 font-size: 2.25em;
112 } 112 }
113 113
114 .something__child.has-state, 114 .something__child.has-state,
115 .something__child.has-indicator { 115 .something__child.has-indicator {
116 font-size: 2.75em; 116 font-size: 2.75em;
117 } 117 }
118 } 118 }
119 } 119 }
120 120
121 @include assert('multiple elements, single state') { /// 5 /// 121 @include assert('multiple elements, single state') { /// 5 ///
122 @include output { 122 @include output {
123 @include bem.block('something') { 123 @include bem.block('something') {
124 @include bem.elem('child1', 'child2') { 124 @include bem.elem('child1', 'child2') {
125 @include bem.is('active') { 125 @include bem.is('active') {
126 font-size: 2.25em; 126 font-size: 2.25em;
127 } 127 }
128 128
129 @include bem.has('state') { 129 @include bem.has('state') {
130 font-size: 2.75em; 130 font-size: 2.75em;
131 } 131 }
132 } 132 }
133 } 133 }
134 } 134 }
135 135
136 @include expect { 136 @include expect {
137 .something__child1.is-active, 137 .something__child1.is-active,
138 .something__child2.is-active { 138 .something__child2.is-active {
139 font-size: 2.25em; 139 font-size: 2.25em;
140 } 140 }
141 141
142 .something__child1.has-state, 142 .something__child1.has-state,
143 .something__child2.has-state { 143 .something__child2.has-state {
144 font-size: 2.75em; 144 font-size: 2.75em;
145 } 145 }
146 } 146 }
147 } 147 }
148 148
149 @include assert('multiple elements, multiple states') { /// 6 /// 149 @include assert('multiple elements, multiple states') { /// 6 ///
150 @include output { 150 @include output {
151 @include bem.block('something') { 151 @include bem.block('something') {
152 @include bem.elem('child1', 'child2') { 152 @include bem.elem('child1', 'child2') {
153 @include bem.is('active', 'primary') { 153 @include bem.is('active', 'primary') {
154 font-size: 2.25em; 154 font-size: 2.25em;
155 } 155 }
156 156
157 @include bem.has('state', 'indicator') { 157 @include bem.has('state', 'indicator') {
158 font-size: 2.75em; 158 font-size: 2.75em;
159 } 159 }
160 } 160 }
161 } 161 }
162 } 162 }
163 163
164 @include expect { 164 @include expect {
165 .something__child1.is-active, 165 .something__child1.is-active,
166 .something__child2.is-active, 166 .something__child2.is-active,
167 .something__child1.is-primary, 167 .something__child1.is-primary,
168 .something__child2.is-primary { 168 .something__child2.is-primary {
169 font-size: 2.25em; 169 font-size: 2.25em;
170 } 170 }
171 171
172 .something__child1.has-state, 172 .something__child1.has-state,
173 .something__child2.has-state, 173 .something__child2.has-state,
174 .something__child1.has-indicator, 174 .something__child1.has-indicator,
175 .something__child2.has-indicator { 175 .something__child2.has-indicator {
176 font-size: 2.75em; 176 font-size: 2.75em;
177 } 177 }
178 } 178 }
179 } 179 }
180} 180}
diff --git a/test/bem/_suffix.scss b/test/bem/_suffix.scss
index 34f55b6..cfec25b 100644
--- a/test/bem/_suffix.scss
+++ b/test/bem/_suffix.scss
@@ -12,86 +12,86 @@
12// 12//
13 13
14@include it('suffix') { 14@include it('suffix') {
15 @include assert('block suffix') { /// 1 /// 15 @include assert('block suffix') { /// 1 ///
16 @include output { 16 @include output {
17 @include bem.block('something') { 17 @include bem.block('something') {
18 @include bem.suffix('sm') { 18 @include bem.suffix('sm') {
19 font-size: 1.5em; 19 font-size: 1.5em;
20 } 20 }
21 } 21 }
22 } 22 }
23 23
24 @include expect { 24 @include expect {
25 .something\@sm { 25 .something\@sm {
26 font-size: 1.5em; 26 font-size: 1.5em;
27 } 27 }
28 } 28 }
29 } 29 }
30 30
31 @include assert('element suffix') { /// 2 /// 31 @include assert('element suffix') { /// 2 ///
32 @include output { 32 @include output {
33 @include bem.block('something') { 33 @include bem.block('something') {
34 @include bem.elem('child') { 34 @include bem.elem('child') {
35 @include bem.suffix('sm') { 35 @include bem.suffix('sm') {
36 font-size: 2.5em; 36 font-size: 2.5em;
37 } 37 }
38 } 38 }
39 } 39 }
40 } 40 }
41 41
42 @include expect { 42 @include expect {
43 .something__child\@sm { 43 .something__child\@sm {
44 font-size: 2.5em; 44 font-size: 2.5em;
45 } 45 }
46 } 46 }
47 } 47 }
48 48
49 @include assert('modifier suffix') { /// 3 /// 49 @include assert('modifier suffix') { /// 3 ///
50 @include output { 50 @include output {
51 @include bem.block('something') { 51 @include bem.block('something') {
52 @include bem.modifier('mod1') { 52 @include bem.modifier('mod1') {
53 @include bem.suffix('sm') { 53 @include bem.suffix('sm') {
54 font-size: 1.75em; 54 font-size: 1.75em;
55 } 55 }
56 } 56 }
57 57
58 @include bem.elem('child') { 58 @include bem.elem('child') {
59 @include bem.modifier('mod2') { 59 @include bem.modifier('mod2') {
60 @include bem.suffix('sm') { 60 @include bem.suffix('sm') {
61 font-size: 2.75em; 61 font-size: 2.75em;
62 } 62 }
63 } 63 }
64 } 64 }
65 } 65 }
66 } 66 }
67 67
68 @include expect { 68 @include expect {
69 .something--mod1\@sm { 69 .something--mod1\@sm {
70 font-size: 1.75em; 70 font-size: 1.75em;
71 } 71 }
72 72
73 .something__child--mod2\@sm { 73 .something__child--mod2\@sm {
74 font-size: 2.75em; 74 font-size: 2.75em;
75 } 75 }
76 } 76 }
77 } 77 }
78 78
79 @include assert('multiple element suffix') { /// 4 /// 79 @include assert('multiple element suffix') { /// 4 ///
80 @include output { 80 @include output {
81 @include bem.block('something') { 81 @include bem.block('something') {
82 @include bem.elem('child1', 'child2') { 82 @include bem.elem('child1', 'child2') {
83 @include bem.suffix('sm') { 83 @include bem.suffix('sm') {
84 font-size: 2.5em; 84 font-size: 2.5em;
85 } 85 }
86 } 86 }
87 } 87 }
88 } 88 }
89 89
90 @include expect { 90 @include expect {
91 .something__child1\@sm, 91 .something__child1\@sm,
92 .something__child2\@sm { 92 .something__child2\@sm {
93 font-size: 2.5em; 93 font-size: 2.5em;
94 } 94 }
95 } 95 }
96 } 96 }
97} 97}
diff --git a/test/test.js b/test/test.js
index 94d16da..cce331c 100644
--- a/test/test.js
+++ b/test/test.js
@@ -1,4 +1,4 @@
1const path = require("path"); 1const path = require("path");
2const sassTrue = require("sass-true"); 2const sassTrue = require("sass-true");
3 3
4sassTrue.runSass({ file: path.join(__dirname, "test.scss") }, { describe, it }); 4sassTrue.runSass({ describe, it }, path.join(__dirname, "test.scss"));
diff --git a/test/test.scss b/test/test.scss
index bddd801..39e369a 100644
--- a/test/test.scss
+++ b/test/test.scss
@@ -9,6 +9,6 @@ gradients.$easing-gradient-steps: 4;
9@import 'responsive'; 9@import 'responsive';
10@import 'harmony'; 10@import 'harmony';
11@import 'gradients'; 11@import 'gradients';
12@import 'props'; 12//@import 'props';
13 13
14@include report; 14@include report;