@griffel/react 1.5.4 → 1.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,6 +15,8 @@ A package with wrappers and APIs to be used with React.js.
15
15
  - [`makeStaticStyles()`](#makestaticstyles)
16
16
  - [`makeResetStyles()`](#makeresetstyles)
17
17
  - [`createDOMRenderer()`, `RendererProvider`](#createdomrenderer-rendererprovider)
18
+ - [compareMediaQueries](#comparemediaqueries)
19
+ - [insertionPoint](#insertionpoint)
18
20
  - [styleElementAttributes](#styleelementattributes)
19
21
  - [`TextDirectionProvider`](#textdirectionprovider)
20
22
  - [Shorthands](#shorthands)
@@ -375,6 +377,85 @@ function App(props) {
375
377
  }
376
378
  ```
377
379
 
380
+ ### compareMediaQueries
381
+
382
+ A function with the same signature as sort functions in e.g. `Array.prototype.sort` for dynamically sorting media queries. Maps over an array of media query strings.
383
+
384
+ Griffel does not provide an opinionated default to sort media queries as the order may vary depending on the specific needs of the application.
385
+
386
+ ```js
387
+ import { createDOMRenderer } from '@griffel/react';
388
+
389
+ const mediaQueryOrder = [
390
+ 'only screen and (min-width: 1366px)',
391
+ 'only screen and (min-width: 1366px)',
392
+ 'only screen and (min-width: 1920px)',
393
+ ];
394
+
395
+ function sortMediaQueries(a, b) {
396
+ return mediaQueryOrder.indexOf(a) - mediaQueryOrder.indexOf(b);
397
+ }
398
+
399
+ const renderer = createDOMRenderer(document, {
400
+ compareMediaQueries,
401
+ });
402
+ ```
403
+
404
+ ```html
405
+ <html>
406
+ <head>
407
+ <style media="only screen and (min-width: 1024px)" data-make-styles-bucket="m"></style>
408
+ <style media="only screen and (min-width: 1366px)" data-make-styles-bucket="m"></style>
409
+ <style media="only screen and (min-width: 1920px)" data-make-styles-bucket="m"></style>
410
+ </head>
411
+ </html>
412
+ ```
413
+
414
+ For mobile-first methodology, you can consider using [`sort-css-media-queries`](https://github.com/dutchenkoOleg/sort-css-media-queries):
415
+
416
+ ```js
417
+ import { createDOMRenderer } from '@griffel/react';
418
+ import sortCSSmq from 'sort-css-media-queries';
419
+
420
+ const renderer = createDOMRenderer(document, {
421
+ compareMediaQueries: sortCSSmq,
422
+ });
423
+ ```
424
+
425
+ ```html
426
+ <html>
427
+ <head>
428
+ <style media="only screen and (min-width: 1px)" data-make-styles-bucket="m"></style>
429
+ <style media="only screen and (min-width: 480px)" data-make-styles-bucket="m"></style>
430
+ <style media="only screen and (min-width: 640px)" data-make-styles-bucket="m"></style>
431
+ </head>
432
+ </html>
433
+ ```
434
+
435
+ ### insertionPoint
436
+
437
+ If specified, a renderer will insert created style tags after this element:
438
+
439
+ ```js
440
+ import { createDOMRenderer } from '@griffel/react';
441
+
442
+ const insertionPoint = document.head.querySelector('#foo');
443
+ const renderer = createDOMRenderer(document, {
444
+ insertionPoint,
445
+ });
446
+ ```
447
+
448
+ ```html
449
+ <html>
450
+ <head>
451
+ <style id="foo" />
452
+ <!-- Style elements created by Griffel will be inserted after "#foo" element -->
453
+ <style data-make-styles-bucket="d" />
454
+ <style id="bar" />
455
+ </head>
456
+ </html>
457
+ ```
458
+
378
459
  ### styleElementAttributes
379
460
 
380
461
  A map of attributes that's passed to the generated style elements. For example, is useful to set ["nonce" attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/nonce).
@@ -382,7 +463,7 @@ A map of attributes that's passed to the generated style elements. For example,
382
463
  ```js
383
464
  import { createDOMRenderer } from '@griffel/react';
384
465
 
385
- const renderer = createDOMRenderer(targetDocument, {
466
+ const renderer = createDOMRenderer(document, {
386
467
  styleElementAttributes: {
387
468
  nonce: 'random',
388
469
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@griffel/react",
3
- "version": "1.5.4",
3
+ "version": "1.5.6",
4
4
  "description": "React implementation of Atomic CSS-in-JS",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -9,13 +9,13 @@
9
9
  },
10
10
  "sideEffects": false,
11
11
  "dependencies": {
12
- "@griffel/core": "^1.9.2",
12
+ "@griffel/core": "^1.10.1",
13
13
  "tslib": "^2.1.0"
14
14
  },
15
15
  "peerDependencies": {
16
16
  "react": ">=16.8.0 <19.0.0"
17
17
  },
18
- "main": "./index.cjs.js",
19
18
  "module": "./index.esm.js",
20
- "typings": "./index.d.ts"
19
+ "main": "./index.cjs.js",
20
+ "types": "./src/index.d.ts"
21
21
  }
@@ -54,14 +54,16 @@ function renderToStyleElements(renderer) {
54
54
  if (!cssRules.length) {
55
55
  return null;
56
56
  }
57
- return /*#__PURE__*/React__namespace.createElement('style', Object.assign({
58
- key: stylesheet.bucketName
59
- }, stylesheet.elementAttributes, {
57
+ return /*#__PURE__*/React__namespace.createElement('style', {
58
+ key: stylesheet.bucketName,
59
+ // TODO: support "nonce"
60
+ // ...renderer.styleNodeAttributes,
61
+ ...stylesheet.elementAttributes,
60
62
  'data-make-styles-rehydration': 'true',
61
63
  dangerouslySetInnerHTML: {
62
64
  __html: cssRules.join('')
63
65
  }
64
- }));
66
+ });
65
67
  }).filter(Boolean);
66
68
  }
67
69
 
@@ -1 +1 @@
1
- {"version":3,"file":"renderToStyleElements.cjs.js","sources":["../../../packages/react/src/renderToStyleElements.ts"],"sourcesContent":["import { styleBucketOrdering } from '@griffel/core';\nimport * as React from 'react';\nimport type { GriffelRenderer } from '@griffel/core';\n\n/**\n * This method returns a list of <style> React elements with the rendered CSS. This is useful for Server-Side rendering.\n *\n * @public\n */\nexport function renderToStyleElements(renderer: GriffelRenderer): React.ReactElement[] {\n const stylesheets = Object.values(renderer.stylesheets)\n // first sort: bucket names\n .sort((a, b) => {\n return styleBucketOrdering.indexOf(a.bucketName) - styleBucketOrdering.indexOf(b.bucketName);\n })\n // second sort: media queries\n .sort((a, b) => {\n const mediaA = a.elementAttributes['media'];\n const mediaB = b.elementAttributes['media'];\n\n if (mediaA && mediaB) {\n return renderer.compareMediaQueries(mediaA, mediaB);\n }\n\n if (mediaA || mediaB) {\n return mediaA ? 1 : -1;\n }\n\n return 0;\n });\n\n return stylesheets\n .map(stylesheet => {\n const cssRules = stylesheet.cssRules();\n // don't want to create any empty style elements\n if (!cssRules.length) {\n return null;\n }\n\n return React.createElement('style', {\n key: stylesheet.bucketName,\n\n // TODO: support \"nonce\"\n // ...renderer.styleNodeAttributes,\n ...stylesheet.elementAttributes,\n 'data-make-styles-rehydration': 'true',\n\n dangerouslySetInnerHTML: {\n __html: cssRules.join(''),\n },\n });\n })\n .filter(Boolean) as React.ReactElement[];\n}\n"],"names":["renderToStyleElements","renderer","stylesheets","Object","values","sort","a","b","styleBucketOrdering","indexOf","bucketName","mediaA","elementAttributes","mediaB","compareMediaQueries","map","stylesheet","cssRules","length","React","createElement","key","dangerouslySetInnerHTML","__html","join","filter","Boolean"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;;SAKgBA,qBAAqB,CAACC,QAAyB;EAC7D,MAAMC,WAAW,GAAGC,MAAM,CAACC,MAAM,CAACH,QAAQ,CAACC,WAAW;;GAEnDG,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,OAAOC,wBAAmB,CAACC,OAAO,CAACH,CAAC,CAACI,UAAU,CAAC,GAAGF,wBAAmB,CAACC,OAAO,CAACF,CAAC,CAACG,UAAU,CAAC;GAC7F;;GAEAL,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,MAAMI,MAAM,GAAGL,CAAC,CAACM,iBAAiB,CAAC,OAAO,CAAC;IAC3C,MAAMC,MAAM,GAAGN,CAAC,CAACK,iBAAiB,CAAC,OAAO,CAAC;IAE3C,IAAID,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOZ,QAAQ,CAACa,mBAAmB,CAACH,MAAM,EAAEE,MAAM,CAAC;;IAGrD,IAAIF,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOF,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;;IAGxB,OAAO,CAAC;GACT,CAAC;EAEJ,OAAOT,WAAW,CACfa,GAAG,CAACC,UAAU;IACb,MAAMC,QAAQ,GAAGD,UAAU,CAACC,QAAQ,EAAE;;IAEtC,IAAI,CAACA,QAAQ,CAACC,MAAM,EAAE;MACpB,OAAO,IAAI;;IAGb,oBAAOC,gBAAK,CAACC,aAAa,CAAC,OAAO;MAChCC,GAAG,EAAEL,UAAU,CAACN;OAIbM,UAAU,CAACJ,iBAAiB;MAC/B,8BAA8B,EAAE,MAAM;MAEtCU,uBAAuB,EAAE;QACvBC,MAAM,EAAEN,QAAQ,CAACO,IAAI,CAAC,EAAE;;OAE1B;GACH,CAAC,CACDC,MAAM,CAACC,OAAO,CAAyB;AAC5C;;;;"}
1
+ {"version":3,"file":"renderToStyleElements.cjs.js","sources":["../../../packages/react/src/renderToStyleElements.ts"],"sourcesContent":["import { styleBucketOrdering } from '@griffel/core';\nimport * as React from 'react';\nimport type { GriffelRenderer } from '@griffel/core';\n\n/**\n * This method returns a list of <style> React elements with the rendered CSS. This is useful for Server-Side rendering.\n *\n * @public\n */\nexport function renderToStyleElements(renderer: GriffelRenderer): React.ReactElement[] {\n const stylesheets = Object.values(renderer.stylesheets)\n // first sort: bucket names\n .sort((a, b) => {\n return styleBucketOrdering.indexOf(a.bucketName) - styleBucketOrdering.indexOf(b.bucketName);\n })\n // second sort: media queries\n .sort((a, b) => {\n const mediaA = a.elementAttributes['media'];\n const mediaB = b.elementAttributes['media'];\n\n if (mediaA && mediaB) {\n return renderer.compareMediaQueries(mediaA, mediaB);\n }\n\n if (mediaA || mediaB) {\n return mediaA ? 1 : -1;\n }\n\n return 0;\n });\n\n return stylesheets\n .map(stylesheet => {\n const cssRules = stylesheet.cssRules();\n // don't want to create any empty style elements\n if (!cssRules.length) {\n return null;\n }\n\n return React.createElement('style', {\n key: stylesheet.bucketName,\n\n // TODO: support \"nonce\"\n // ...renderer.styleNodeAttributes,\n ...stylesheet.elementAttributes,\n 'data-make-styles-rehydration': 'true',\n\n dangerouslySetInnerHTML: {\n __html: cssRules.join(''),\n },\n });\n })\n .filter(Boolean) as React.ReactElement[];\n}\n"],"names":["renderToStyleElements","renderer","stylesheets","Object","values","sort","a","b","styleBucketOrdering","indexOf","bucketName","mediaA","elementAttributes","mediaB","compareMediaQueries","map","stylesheet","cssRules","length","React","createElement","key","dangerouslySetInnerHTML","__html","join","filter","Boolean"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA;;;;;SAKgBA,qBAAqB,CAACC,QAAyB;EAC7D,MAAMC,WAAW,GAAGC,MAAM,CAACC,MAAM,CAACH,QAAQ,CAACC,WAAW;;GAEnDG,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,OAAOC,wBAAmB,CAACC,OAAO,CAACH,CAAC,CAACI,UAAU,CAAC,GAAGF,wBAAmB,CAACC,OAAO,CAACF,CAAC,CAACG,UAAU,CAAC;GAC7F;;GAEAL,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,MAAMI,MAAM,GAAGL,CAAC,CAACM,iBAAiB,CAAC,OAAO,CAAC;IAC3C,MAAMC,MAAM,GAAGN,CAAC,CAACK,iBAAiB,CAAC,OAAO,CAAC;IAE3C,IAAID,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOZ,QAAQ,CAACa,mBAAmB,CAACH,MAAM,EAAEE,MAAM,CAAC;;IAGrD,IAAIF,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOF,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;;IAGxB,OAAO,CAAC;GACT,CAAC;EAEJ,OAAOT,WAAW,CACfa,GAAG,CAACC,UAAU;IACb,MAAMC,QAAQ,GAAGD,UAAU,CAACC,QAAQ,EAAE;;IAEtC,IAAI,CAACA,QAAQ,CAACC,MAAM,EAAE;MACpB,OAAO,IAAI;;IAGb,oBAAOC,gBAAK,CAACC,aAAa,CAAC,OAAO,EAAE;MAClCC,GAAG,EAAEL,UAAU,CAACN,UAAU;;;MAI1B,GAAGM,UAAU,CAACJ,iBAAiB;MAC/B,8BAA8B,EAAE,MAAM;MAEtCU,uBAAuB,EAAE;QACvBC,MAAM,EAAEN,QAAQ,CAACO,IAAI,CAAC,EAAE;;KAE3B,CAAC;GACH,CAAC,CACDC,MAAM,CAACC,OAAO,CAAyB;AAC5C;;;;"}
@@ -30,14 +30,16 @@ function renderToStyleElements(renderer) {
30
30
  if (!cssRules.length) {
31
31
  return null;
32
32
  }
33
- return /*#__PURE__*/React.createElement('style', Object.assign({
34
- key: stylesheet.bucketName
35
- }, stylesheet.elementAttributes, {
33
+ return /*#__PURE__*/React.createElement('style', {
34
+ key: stylesheet.bucketName,
35
+ // TODO: support "nonce"
36
+ // ...renderer.styleNodeAttributes,
37
+ ...stylesheet.elementAttributes,
36
38
  'data-make-styles-rehydration': 'true',
37
39
  dangerouslySetInnerHTML: {
38
40
  __html: cssRules.join('')
39
41
  }
40
- }));
42
+ });
41
43
  }).filter(Boolean);
42
44
  }
43
45
 
@@ -1 +1 @@
1
- {"version":3,"file":"renderToStyleElements.esm.js","sources":["../../../packages/react/src/renderToStyleElements.ts"],"sourcesContent":["import { styleBucketOrdering } from '@griffel/core';\nimport * as React from 'react';\nimport type { GriffelRenderer } from '@griffel/core';\n\n/**\n * This method returns a list of <style> React elements with the rendered CSS. This is useful for Server-Side rendering.\n *\n * @public\n */\nexport function renderToStyleElements(renderer: GriffelRenderer): React.ReactElement[] {\n const stylesheets = Object.values(renderer.stylesheets)\n // first sort: bucket names\n .sort((a, b) => {\n return styleBucketOrdering.indexOf(a.bucketName) - styleBucketOrdering.indexOf(b.bucketName);\n })\n // second sort: media queries\n .sort((a, b) => {\n const mediaA = a.elementAttributes['media'];\n const mediaB = b.elementAttributes['media'];\n\n if (mediaA && mediaB) {\n return renderer.compareMediaQueries(mediaA, mediaB);\n }\n\n if (mediaA || mediaB) {\n return mediaA ? 1 : -1;\n }\n\n return 0;\n });\n\n return stylesheets\n .map(stylesheet => {\n const cssRules = stylesheet.cssRules();\n // don't want to create any empty style elements\n if (!cssRules.length) {\n return null;\n }\n\n return React.createElement('style', {\n key: stylesheet.bucketName,\n\n // TODO: support \"nonce\"\n // ...renderer.styleNodeAttributes,\n ...stylesheet.elementAttributes,\n 'data-make-styles-rehydration': 'true',\n\n dangerouslySetInnerHTML: {\n __html: cssRules.join(''),\n },\n });\n })\n .filter(Boolean) as React.ReactElement[];\n}\n"],"names":["renderToStyleElements","renderer","stylesheets","Object","values","sort","a","b","styleBucketOrdering","indexOf","bucketName","mediaA","elementAttributes","mediaB","compareMediaQueries","map","stylesheet","cssRules","length","React","createElement","key","dangerouslySetInnerHTML","__html","join","filter","Boolean"],"mappings":";;;AAIA;;;;;SAKgBA,qBAAqB,CAACC,QAAyB;EAC7D,MAAMC,WAAW,GAAGC,MAAM,CAACC,MAAM,CAACH,QAAQ,CAACC,WAAW;;GAEnDG,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,OAAOC,mBAAmB,CAACC,OAAO,CAACH,CAAC,CAACI,UAAU,CAAC,GAAGF,mBAAmB,CAACC,OAAO,CAACF,CAAC,CAACG,UAAU,CAAC;GAC7F;;GAEAL,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,MAAMI,MAAM,GAAGL,CAAC,CAACM,iBAAiB,CAAC,OAAO,CAAC;IAC3C,MAAMC,MAAM,GAAGN,CAAC,CAACK,iBAAiB,CAAC,OAAO,CAAC;IAE3C,IAAID,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOZ,QAAQ,CAACa,mBAAmB,CAACH,MAAM,EAAEE,MAAM,CAAC;;IAGrD,IAAIF,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOF,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;;IAGxB,OAAO,CAAC;GACT,CAAC;EAEJ,OAAOT,WAAW,CACfa,GAAG,CAACC,UAAU;IACb,MAAMC,QAAQ,GAAGD,UAAU,CAACC,QAAQ,EAAE;;IAEtC,IAAI,CAACA,QAAQ,CAACC,MAAM,EAAE;MACpB,OAAO,IAAI;;IAGb,oBAAOC,KAAK,CAACC,aAAa,CAAC,OAAO;MAChCC,GAAG,EAAEL,UAAU,CAACN;OAIbM,UAAU,CAACJ,iBAAiB;MAC/B,8BAA8B,EAAE,MAAM;MAEtCU,uBAAuB,EAAE;QACvBC,MAAM,EAAEN,QAAQ,CAACO,IAAI,CAAC,EAAE;;OAE1B;GACH,CAAC,CACDC,MAAM,CAACC,OAAO,CAAyB;AAC5C;;;;"}
1
+ {"version":3,"file":"renderToStyleElements.esm.js","sources":["../../../packages/react/src/renderToStyleElements.ts"],"sourcesContent":["import { styleBucketOrdering } from '@griffel/core';\nimport * as React from 'react';\nimport type { GriffelRenderer } from '@griffel/core';\n\n/**\n * This method returns a list of <style> React elements with the rendered CSS. This is useful for Server-Side rendering.\n *\n * @public\n */\nexport function renderToStyleElements(renderer: GriffelRenderer): React.ReactElement[] {\n const stylesheets = Object.values(renderer.stylesheets)\n // first sort: bucket names\n .sort((a, b) => {\n return styleBucketOrdering.indexOf(a.bucketName) - styleBucketOrdering.indexOf(b.bucketName);\n })\n // second sort: media queries\n .sort((a, b) => {\n const mediaA = a.elementAttributes['media'];\n const mediaB = b.elementAttributes['media'];\n\n if (mediaA && mediaB) {\n return renderer.compareMediaQueries(mediaA, mediaB);\n }\n\n if (mediaA || mediaB) {\n return mediaA ? 1 : -1;\n }\n\n return 0;\n });\n\n return stylesheets\n .map(stylesheet => {\n const cssRules = stylesheet.cssRules();\n // don't want to create any empty style elements\n if (!cssRules.length) {\n return null;\n }\n\n return React.createElement('style', {\n key: stylesheet.bucketName,\n\n // TODO: support \"nonce\"\n // ...renderer.styleNodeAttributes,\n ...stylesheet.elementAttributes,\n 'data-make-styles-rehydration': 'true',\n\n dangerouslySetInnerHTML: {\n __html: cssRules.join(''),\n },\n });\n })\n .filter(Boolean) as React.ReactElement[];\n}\n"],"names":["renderToStyleElements","renderer","stylesheets","Object","values","sort","a","b","styleBucketOrdering","indexOf","bucketName","mediaA","elementAttributes","mediaB","compareMediaQueries","map","stylesheet","cssRules","length","React","createElement","key","dangerouslySetInnerHTML","__html","join","filter","Boolean"],"mappings":";;;AAIA;;;;;SAKgBA,qBAAqB,CAACC,QAAyB;EAC7D,MAAMC,WAAW,GAAGC,MAAM,CAACC,MAAM,CAACH,QAAQ,CAACC,WAAW;;GAEnDG,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,OAAOC,mBAAmB,CAACC,OAAO,CAACH,CAAC,CAACI,UAAU,CAAC,GAAGF,mBAAmB,CAACC,OAAO,CAACF,CAAC,CAACG,UAAU,CAAC;GAC7F;;GAEAL,IAAI,CAAC,CAACC,CAAC,EAAEC,CAAC;IACT,MAAMI,MAAM,GAAGL,CAAC,CAACM,iBAAiB,CAAC,OAAO,CAAC;IAC3C,MAAMC,MAAM,GAAGN,CAAC,CAACK,iBAAiB,CAAC,OAAO,CAAC;IAE3C,IAAID,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOZ,QAAQ,CAACa,mBAAmB,CAACH,MAAM,EAAEE,MAAM,CAAC;;IAGrD,IAAIF,MAAM,IAAIE,MAAM,EAAE;MACpB,OAAOF,MAAM,GAAG,CAAC,GAAG,CAAC,CAAC;;IAGxB,OAAO,CAAC;GACT,CAAC;EAEJ,OAAOT,WAAW,CACfa,GAAG,CAACC,UAAU;IACb,MAAMC,QAAQ,GAAGD,UAAU,CAACC,QAAQ,EAAE;;IAEtC,IAAI,CAACA,QAAQ,CAACC,MAAM,EAAE;MACpB,OAAO,IAAI;;IAGb,oBAAOC,KAAK,CAACC,aAAa,CAAC,OAAO,EAAE;MAClCC,GAAG,EAAEL,UAAU,CAACN,UAAU;;;MAI1B,GAAGM,UAAU,CAACJ,iBAAiB;MAC/B,8BAA8B,EAAE,MAAM;MAEtCU,uBAAuB,EAAE;QACvBC,MAAM,EAAEN,QAAQ,CAACO,IAAI,CAAC,EAAE;;KAE3B,CAAC;GACH,CAAC,CACDC,MAAM,CAACC,OAAO,CAAyB;AAC5C;;;;"}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes