pi-lean-dimension 0.2.4 → 0.3.1

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.
Files changed (159) hide show
  1. package/README.md +1 -1
  2. package/node_modules/pi-lean-portal/AGENTS.md +15 -23
  3. package/node_modules/pi-lean-portal/README.md +35 -7
  4. package/node_modules/pi-lean-portal/__tests__/browser-toggle-profile.test.ts +12 -1
  5. package/node_modules/pi-lean-portal/__tests__/browser-toggle.test.ts +263 -1126
  6. package/node_modules/pi-lean-portal/__tests__/fetch-backend.test.ts +6 -32
  7. package/node_modules/pi-lean-portal/__tests__/helpers/mock-python-bridge.py +1 -1
  8. package/node_modules/pi-lean-portal/__tests__/helpers/probe-user-backend.ts +1 -2
  9. package/node_modules/pi-lean-portal/__tests__/helpers/setup-temp-dir.ts +26 -0
  10. package/node_modules/pi-lean-portal/__tests__/plugin-config-browser.test.ts +1 -1
  11. package/node_modules/pi-lean-portal/__tests__/plugin-contract.test.ts +1 -1
  12. package/node_modules/pi-lean-portal/__tests__/plugin-loading.test.ts +1 -1
  13. package/node_modules/pi-lean-portal/__tests__/probe-user-backend.test.ts +1 -1
  14. package/node_modules/pi-lean-portal/__tests__/python-adapter.test.ts +65 -69
  15. package/node_modules/pi-lean-portal/__tests__/router-dispatch.test.ts +1 -14
  16. package/node_modules/pi-lean-portal/__tests__/run-contributed-suites.test.ts +31 -16
  17. package/node_modules/pi-lean-portal/__tests__/snapshot-cache.test.ts +1 -1
  18. package/node_modules/pi-lean-portal/__tests__/web-guides.test.ts +146 -19
  19. package/node_modules/pi-lean-portal/backends/playwright-base/playwright-plugin.ts +1 -1
  20. package/node_modules/pi-lean-portal/backends/python-adapter.ts +3 -3
  21. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__init__.py +2 -4
  22. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/__init__.cpython-312.pyc +0 -0
  23. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/__init__.cpython-313.pyc +0 -0
  24. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/playwright_base.cpython-312.pyc +0 -0
  25. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/__pycache__/playwright_base.cpython-313.pyc +0 -0
  26. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/playwright_base.py +572 -81
  27. package/node_modules/pi-lean-portal/backends/python-base/tests/__pycache__/test_playwright_base_quirks.cpython-313-pytest-9.1.1.pyc +0 -0
  28. package/node_modules/pi-lean-portal/backends/python-base/tests/test_playwright_base_quirks.py +13 -43
  29. package/node_modules/pi-lean-portal/browser-profile.ts +2 -3
  30. package/node_modules/pi-lean-portal/browser-toggle.ts +168 -385
  31. package/node_modules/pi-lean-portal/contributed/CHOOSING.md +2 -2
  32. package/node_modules/pi-lean-portal/contributed/README.md +65 -6
  33. package/node_modules/pi-lean-portal/contributed/camoufox-py/__pycache__/bridge.cpython-312.pyc +0 -0
  34. package/node_modules/pi-lean-portal/contributed/camoufox-py/bridge.py +108 -14
  35. package/node_modules/pi-lean-portal/contributed/camoufox-py/pin.json +4 -0
  36. package/node_modules/pi-lean-portal/core/fetch-backend.ts +10 -30
  37. package/node_modules/pi-lean-portal/core/guides.ts +14 -18
  38. package/node_modules/pi-lean-portal/core/router.ts +2 -20
  39. package/node_modules/pi-lean-portal/core/shared/bot-detection.ts +19 -30
  40. package/node_modules/pi-lean-portal/core/shared/browser-data.ts +4 -4
  41. package/node_modules/pi-lean-portal/core/shared/nav-settle.ts +2 -2
  42. package/node_modules/pi-lean-portal/core/shared/paths.ts +16 -2
  43. package/node_modules/pi-lean-portal/core/shared/settings-reader.ts +2 -7
  44. package/node_modules/pi-lean-portal/core/shared/snapshot-cache.ts +1 -1
  45. package/node_modules/pi-lean-portal/index.ts +8 -1
  46. package/node_modules/pi-lean-portal/package.json +2 -1
  47. package/node_modules/pi-lean-portal/tools/web-learn.ts +1 -4
  48. package/node_modules/pi-lean-search/__tests__/web-search.test.ts +87 -0
  49. package/node_modules/pi-lean-search/index.ts +134 -64
  50. package/node_modules/pi-lean-search/package.json +2 -1
  51. package/node_modules/playwright/README.md +3 -3
  52. package/node_modules/playwright/lib/agents/copilot-setup-steps.yml +2 -2
  53. package/node_modules/playwright/lib/cli/reportActions.js +2 -2
  54. package/node_modules/playwright/lib/common/index.js +77 -52
  55. package/node_modules/playwright/lib/common/index.js.txt +10 -11
  56. package/node_modules/playwright/lib/errorContext.js +2 -3
  57. package/node_modules/playwright/lib/index.js +30 -8
  58. package/node_modules/playwright/lib/matchers/expect.js +4811 -4379
  59. package/node_modules/playwright/lib/matchers/expect.js.LICENSE +87 -140
  60. package/node_modules/playwright/lib/matchers/expect.js.txt +30 -35
  61. package/node_modules/playwright/lib/program.js +19 -0
  62. package/node_modules/playwright/lib/runner/index.js +309 -153
  63. package/node_modules/playwright/lib/runner/index.js.txt +13 -12
  64. package/node_modules/playwright/lib/transform/babelBundle.js +12899 -11654
  65. package/node_modules/playwright/lib/transform/babelBundle.js.LICENSE +379 -354
  66. package/node_modules/playwright/lib/transform/babelBundle.js.txt +39 -39
  67. package/node_modules/playwright/lib/transform/esmLoader.js +3129 -1116
  68. package/node_modules/playwright/lib/transform/esmLoader.js.LICENSE +81 -61
  69. package/node_modules/playwright/lib/transform/esmLoader.js.txt +21 -18
  70. package/node_modules/playwright/lib/util.js +2 -29
  71. package/node_modules/playwright/lib/worker/workerProcessEntry.js +14 -32
  72. package/node_modules/playwright/lib/worker/workerProcessEntry.js.txt +7 -8
  73. package/node_modules/playwright/package.json +3 -6
  74. package/node_modules/playwright/types/test.d.ts +391 -4
  75. package/node_modules/playwright/types/testReporter.d.ts +79 -4
  76. package/node_modules/playwright-core/browsers.json +12 -18
  77. package/node_modules/playwright-core/lib/bootstrap.js +1 -1
  78. package/node_modules/playwright-core/lib/coreBundle.js +11344 -9900
  79. package/node_modules/playwright-core/lib/server/electron/loader.js +5 -2
  80. package/node_modules/playwright-core/lib/serverRegistry.js +5 -1
  81. package/node_modules/playwright-core/lib/tools/cli-client/help.json +21 -6
  82. package/node_modules/playwright-core/lib/tools/cli-client/program.js +1 -1
  83. package/node_modules/playwright-core/lib/tools/cli-client/session.js +4 -0
  84. package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/SKILL.md +21 -5
  85. package/node_modules/playwright-core/lib/tools/{cli-client/skill/references/spec-driven-testing.md → skills/playwright-cli/references/test-generation.md} +135 -7
  86. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/SKILL.md +143 -0
  87. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/gallery-spec.md +144 -0
  88. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/migration.md +85 -0
  89. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/react.md +67 -0
  90. package/node_modules/playwright-core/lib/tools/skills/playwright-component-testing/references/vue.md +75 -0
  91. package/node_modules/playwright-core/lib/tools/utils/extension.js +31 -8
  92. package/node_modules/playwright-core/lib/utilsBundle.js +37698 -33670
  93. package/node_modules/playwright-core/lib/utilsBundle.js.LICENSE +391 -268
  94. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-CyWAfh-p.js +11 -0
  95. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-DhC616m4.css +1 -0
  96. package/node_modules/playwright-core/lib/vite/dashboard/index.html +2 -2
  97. package/node_modules/playwright-core/lib/vite/htmlReport/report.css +2 -1
  98. package/node_modules/playwright-core/lib/vite/htmlReport/report.js +15 -55
  99. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule--QdMvsKi.css +1 -0
  100. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-CwYYHbcZ.js +32 -0
  101. package/node_modules/playwright-core/lib/vite/recorder/assets/index-DYjdXIbE.js +129 -0
  102. package/node_modules/playwright-core/lib/vite/recorder/assets/index-l_lX622x.css +1 -0
  103. package/node_modules/playwright-core/lib/vite/recorder/index.html +2 -2
  104. package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-By56iMx7.js +32 -0
  105. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-B34OrIms.js +181 -0
  106. package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-L3liM589.js +1 -0
  107. package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-COQkjINf.js +7 -0
  108. package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.-QdMvsKi.css +1 -0
  109. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.BLFoOugd.css +1 -0
  110. package/node_modules/playwright-core/lib/vite/traceViewer/index.B_TqY17P.css +1 -0
  111. package/node_modules/playwright-core/lib/vite/traceViewer/index.Dl36UVQT.js +1 -0
  112. package/node_modules/playwright-core/lib/vite/traceViewer/index.html +5 -5
  113. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.B_Jk1wbt.js +1 -0
  114. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.html +2 -2
  115. package/node_modules/playwright-core/lib/vite/traceViewer/sw.bundle.js +3 -4
  116. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.C7UW1sC9.css +1 -0
  117. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.D962mr9b.js +5 -0
  118. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.html +5 -5
  119. package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.kHJ-D0s7.css +1 -0
  120. package/node_modules/playwright-core/lib/webp_codec.LICENSE +173 -0
  121. package/node_modules/playwright-core/lib/webp_codec.wasm +0 -0
  122. package/node_modules/playwright-core/lib/xdg-open +338 -137
  123. package/node_modules/playwright-core/package.json +2 -2
  124. package/node_modules/playwright-core/types/protocol.d.ts +249 -36
  125. package/node_modules/playwright-core/types/structs.d.ts +3 -1
  126. package/node_modules/playwright-core/types/types.d.ts +2009 -266
  127. package/package.json +3 -3
  128. package/node_modules/pi-lean-portal/__tests__/url-safety.test.ts +0 -188
  129. package/node_modules/pi-lean-portal/backends/python-base/pi_browser_bridge/bridge.py +0 -525
  130. package/node_modules/pi-lean-portal/core/shared/url-safety.ts +0 -164
  131. package/node_modules/playwright-core/lib/server/deviceDescriptorsSource.json +0 -2739
  132. package/node_modules/playwright-core/lib/tools/cli-client/skill/references/test-generation.md +0 -134
  133. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-BY2S1tHT.css +0 -1
  134. package/node_modules/playwright-core/lib/vite/dashboard/assets/index-C_5TMfeg.js +0 -52
  135. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DYBRYzYX.css +0 -1
  136. package/node_modules/playwright-core/lib/vite/recorder/assets/codeMirrorModule-DeBYQozu.js +0 -32
  137. package/node_modules/playwright-core/lib/vite/recorder/assets/index-4ZiSSCmn.css +0 -1
  138. package/node_modules/playwright-core/lib/vite/recorder/assets/index-Bq-mQf8S.js +0 -193
  139. package/node_modules/playwright-core/lib/vite/traceViewer/assets/codeMirrorModule-LEHpjmcn.js +0 -32
  140. package/node_modules/playwright-core/lib/vite/traceViewer/assets/defaultSettingsView-BNmKHKpQ.js +0 -264
  141. package/node_modules/playwright-core/lib/vite/traceViewer/assets/urlMatch-BYQrIQwR.js +0 -1
  142. package/node_modules/playwright-core/lib/vite/traceViewer/assets/xtermModule-CsJ4vdCR.js +0 -9
  143. package/node_modules/playwright-core/lib/vite/traceViewer/codeMirrorModule.DYBRYzYX.css +0 -1
  144. package/node_modules/playwright-core/lib/vite/traceViewer/defaultSettingsView.CjdS-WJx.css +0 -1
  145. package/node_modules/playwright-core/lib/vite/traceViewer/index.CzXZzn5A.css +0 -1
  146. package/node_modules/playwright-core/lib/vite/traceViewer/index.DMMX1gXU.js +0 -2
  147. package/node_modules/playwright-core/lib/vite/traceViewer/snapshot.v8KI4P3m.js +0 -2
  148. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.BZQ54Kgt.css +0 -1
  149. package/node_modules/playwright-core/lib/vite/traceViewer/uiMode.Ut8wwJNp.js +0 -6
  150. package/node_modules/playwright-core/lib/vite/traceViewer/xtermModule.DYP7pi_n.css +0 -32
  151. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/element-attributes.md +0 -0
  152. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/playwright-tests.md +0 -0
  153. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/request-mocking.md +0 -0
  154. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/running-code.md +0 -0
  155. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/session-management.md +0 -0
  156. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/storage-state.md +0 -0
  157. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/tracing.md +0 -0
  158. /package/node_modules/playwright-core/lib/tools/{cli-client/skill → skills/playwright-cli}/references/video-recording.md +0 -0
  159. /package/node_modules/playwright-core/lib/tools/{trace → skills/playwright-trace}/SKILL.md +0 -0
@@ -15,7 +15,7 @@
15
15
  * limitations under the License.
16
16
  */
17
17
 
18
- import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo } from './test';
18
+ import type { TestStatus, Metadata, PlaywrightTestOptions, PlaywrightWorkerOptions, ReporterDescription, FullConfig, FullProject, Location, WorkerInfo, TestAnnotation } from './test';
19
19
  export type { FullConfig, FullProject, TestStatus, Location, WorkerInfo } from './test';
20
20
 
21
21
  /**
@@ -227,6 +227,36 @@ export interface Reporter {
227
227
  */
228
228
  onTestEnd?(test: TestCase, result: TestResult): void;
229
229
 
230
+ /**
231
+ * Called after the configuration has been resolved and before
232
+ * [reporter.onBegin(config, suite)](https://playwright.dev/docs/api/class-reporter#reporter-on-begin). Allows a
233
+ * reporter to mark individual tests as skipped, excluded, fixed or failing.
234
+ * @param params The suite reflects `--project`, `--grep`/`--grep-invert` and `.only` filtering, so it only contains tests that
235
+ * match the current invocation. Setup and dependency projects are readonly and cannot be changed through
236
+ * [TestRun](https://playwright.dev/docs/api/class-testrun).
237
+ *
238
+ * The suite ignores the `--shard` argument: it always contains the full, un-sharded corpus. Playwright applies its
239
+ * built-in sharding after
240
+ * [reporter.preprocess(params)](https://playwright.dev/docs/api/class-reporter#reporter-preprocess) returns, unless
241
+ * the reporter calls [testRun.skipSharding()](https://playwright.dev/docs/api/class-testrun#test-run-skip-sharding).
242
+ */
243
+ preprocess?(params: {
244
+ /**
245
+ * Resolved configuration.
246
+ */
247
+ config: FullConfig;
248
+
249
+ /**
250
+ * The root suite that contains the projects, files and test cases that will run.
251
+ */
252
+ suite: Suite;
253
+
254
+ /**
255
+ * Control which tests will run and their expected status.
256
+ */
257
+ testRun: TestRun;
258
+ }): Promise<void>;
259
+
230
260
  /**
231
261
  * Whether this reporter uses stdio for reporting. When it does not, Playwright Test could add some output to enhance
232
262
  * user experience. If your reporter does not print to the terminal, it is strongly recommended to return `false`.
@@ -283,7 +313,7 @@ export interface JSONReportSpec {
283
313
 
284
314
  export interface JSONReportTest {
285
315
  timeout: number;
286
- annotations: { type: string, description?: string }[],
316
+ annotations: TestAnnotation[],
287
317
  expectedStatus: TestStatus;
288
318
  projectName: string;
289
319
  projectId: string;
@@ -315,7 +345,7 @@ export interface JSONReportTestResult {
315
345
  body?: string;
316
346
  contentType: string;
317
347
  }[];
318
- annotations: { type: string, description?: string }[];
348
+ annotations: TestAnnotation[];
319
349
  errorLocation?: Location;
320
350
  }
321
351
 
@@ -719,7 +749,52 @@ export interface TestResult {
719
749
  }
720
750
 
721
751
  /**
722
- * Represents a step in the [TestRun].
752
+ * Controls which tests will run and their expected status. A [TestRun](https://playwright.dev/docs/api/class-testrun)
753
+ * is available during
754
+ * [reporter.preprocess(params)](https://playwright.dev/docs/api/class-reporter#reporter-preprocess). Setup and
755
+ * teardown projects cannot be changed.
756
+ */
757
+ export interface TestRun {
758
+ /**
759
+ * Excludes a test or suite from the run. Excluded tests do not appear in the report and their bodies are not
760
+ * executed.
761
+ * @param test Test or suite to exclude. The root suite cannot be excluded.
762
+ */
763
+ exclude(test: TestCase|Suite): void;
764
+
765
+ /**
766
+ * Marks a test or every test in a suite as "should fail". Playwright runs the tests and ensures they are actually
767
+ * failing, useful for documenting broken functionality until it is fixed.
768
+ * @param test Test or suite to mark as expected-to-fail.
769
+ * @param reason Optional explanation surfaced as the annotation description.
770
+ */
771
+ fail(test: TestCase|Suite, reason?: string): void;
772
+
773
+ /**
774
+ * Marks a test or every test in a suite as fixme. The test bodies are not executed and the tests are reported as
775
+ * skipped, with the intention to fix them.
776
+ * @param test Test or suite to mark as fixme.
777
+ * @param reason Optional explanation surfaced as the annotation description.
778
+ */
779
+ fixme(test: TestCase|Suite, reason?: string): void;
780
+
781
+ /**
782
+ * Skips a test or every test in a suite. The test bodies are not executed and the tests are reported as skipped.
783
+ * @param test Test or suite to skip.
784
+ * @param reason Optional explanation surfaced as the annotation description.
785
+ */
786
+ skip(test: TestCase|Suite, reason?: string): void;
787
+
788
+ /**
789
+ * Disables Playwright's built-in shard filter for this run, leaving sharding to the reporter. Reporters typically
790
+ * implement their own sharding by calling
791
+ * [testRun.exclude(test)](https://playwright.dev/docs/api/class-testrun#test-run-exclude) on out-of-shard tests.
792
+ */
793
+ skipSharding(): void;
794
+ }
795
+
796
+ /**
797
+ * Represents a step in a [TestResult](https://playwright.dev/docs/api/class-testresult).
723
798
  */
724
799
  export interface TestStep {
725
800
  /**
@@ -3,37 +3,37 @@
3
3
  "browsers": [
4
4
  {
5
5
  "name": "chromium",
6
- "revision": "1228",
6
+ "revision": "1234",
7
7
  "installByDefault": true,
8
- "browserVersion": "149.0.7827.55",
8
+ "browserVersion": "151.0.7922.34",
9
9
  "title": "Chrome for Testing"
10
10
  },
11
11
  {
12
12
  "name": "chromium-headless-shell",
13
- "revision": "1228",
13
+ "revision": "1234",
14
14
  "installByDefault": true,
15
- "browserVersion": "149.0.7827.55",
15
+ "browserVersion": "151.0.7922.34",
16
16
  "title": "Chrome Headless Shell"
17
17
  },
18
18
  {
19
19
  "name": "chromium-tip-of-tree",
20
- "revision": "1432",
20
+ "revision": "1433",
21
21
  "installByDefault": false,
22
- "browserVersion": "151.0.7886.0",
22
+ "browserVersion": "151.0.7893.0",
23
23
  "title": "Chrome Canary for Testing"
24
24
  },
25
25
  {
26
26
  "name": "chromium-tip-of-tree-headless-shell",
27
- "revision": "1432",
27
+ "revision": "1433",
28
28
  "installByDefault": false,
29
- "browserVersion": "151.0.7886.0",
29
+ "browserVersion": "151.0.7893.0",
30
30
  "title": "Chrome Canary Headless Shell"
31
31
  },
32
32
  {
33
33
  "name": "firefox",
34
- "revision": "1532",
34
+ "revision": "1538",
35
35
  "installByDefault": true,
36
- "browserVersion": "151.0",
36
+ "browserVersion": "153.0",
37
37
  "title": "Firefox"
38
38
  },
39
39
  {
@@ -45,13 +45,11 @@
45
45
  },
46
46
  {
47
47
  "name": "webkit",
48
- "revision": "2311",
48
+ "revision": "2336",
49
49
  "installByDefault": true,
50
50
  "revisionOverrides": {
51
51
  "mac14": "2251",
52
52
  "mac14-arm64": "2251",
53
- "debian11-x64": "2105",
54
- "debian11-arm64": "2105",
55
53
  "ubuntu20.04-x64": "2092",
56
54
  "ubuntu20.04-arm64": "2092"
57
55
  },
@@ -61,11 +59,7 @@
61
59
  {
62
60
  "name": "ffmpeg",
63
61
  "revision": "1011",
64
- "installByDefault": true,
65
- "revisionOverrides": {
66
- "mac12": "1010",
67
- "mac12-arm64": "1010"
68
- }
62
+ "installByDefault": true
69
63
  },
70
64
  {
71
65
  "name": "winldd",
@@ -1,5 +1,5 @@
1
1
  "use strict";
2
- const minimumMajorNodeVersion = 18;
2
+ const minimumMajorNodeVersion = 20;
3
3
  const currentNodeVersion = process.versions.node;
4
4
  const major = +currentNodeVersion.split(".")[0];
5
5
  if (major < minimumMajorNodeVersion) {