next 15.2.0-canary.75 → 15.2.0-canary.76

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.

Potentially problematic release.


This version of next might be problematic. Click here for more details.

Files changed (120) hide show
  1. package/dist/bin/next +1 -1
  2. package/dist/build/index.js +2 -2
  3. package/dist/build/swc/index.js +1 -1
  4. package/dist/build/webpack-config.js +2 -2
  5. package/dist/client/app-bootstrap.js +1 -1
  6. package/dist/client/app-dir/form.d.ts +2 -43
  7. package/dist/client/app-dir/form.js +20 -144
  8. package/dist/client/app-dir/form.js.map +1 -1
  9. package/dist/client/components/react-dev-overlay/shared.d.ts +2 -0
  10. package/dist/client/components/react-dev-overlay/shared.js +10 -0
  11. package/dist/client/components/react-dev-overlay/shared.js.map +1 -1
  12. package/dist/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.d.ts +1 -1
  13. package/dist/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.js +11 -3
  14. package/dist/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.js.map +1 -1
  15. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-indicator.d.ts +3 -4
  16. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-indicator.js +45 -9
  17. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-indicator.js.map +1 -1
  18. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/dev-tools-info.d.ts +4 -4
  19. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/dev-tools-info.js +5 -4
  20. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/dev-tools-info.js.map +1 -1
  21. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/route-info.d.ts +1 -1
  22. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/route-info.js +1 -1
  23. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/route-info.js.map +1 -1
  24. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/turbopack-info.d.ts +1 -1
  25. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/turbopack-info.js +1 -1
  26. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/turbopack-info.js.map +1 -1
  27. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/user-preferences.d.ts +10 -0
  28. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/user-preferences.js +254 -0
  29. package/dist/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/user-preferences.js.map +1 -0
  30. package/dist/client/components/react-dev-overlay/ui/components/shadow-portal.js +12 -0
  31. package/dist/client/components/react-dev-overlay/ui/components/shadow-portal.js.map +1 -1
  32. package/dist/client/components/react-dev-overlay/ui/icons/dark-icon.d.ts +1 -0
  33. package/dist/client/components/react-dev-overlay/ui/icons/dark-icon.js +34 -0
  34. package/dist/client/components/react-dev-overlay/ui/icons/dark-icon.js.map +1 -0
  35. package/dist/client/components/react-dev-overlay/ui/icons/external.d.ts +1 -0
  36. package/dist/client/components/react-dev-overlay/ui/icons/external.js +31 -3
  37. package/dist/client/components/react-dev-overlay/ui/icons/external.js.map +1 -1
  38. package/dist/client/components/react-dev-overlay/ui/icons/eye-icon.d.ts +1 -0
  39. package/dist/client/components/react-dev-overlay/ui/icons/eye-icon.js +33 -0
  40. package/dist/client/components/react-dev-overlay/ui/icons/eye-icon.js.map +1 -0
  41. package/dist/client/components/react-dev-overlay/ui/icons/gear-icon.d.ts +1 -0
  42. package/dist/client/components/react-dev-overlay/ui/icons/gear-icon.js +34 -0
  43. package/dist/client/components/react-dev-overlay/ui/icons/gear-icon.js.map +1 -0
  44. package/dist/client/components/react-dev-overlay/ui/icons/light-icon.d.ts +1 -0
  45. package/dist/client/components/react-dev-overlay/ui/icons/light-icon.js +48 -0
  46. package/dist/client/components/react-dev-overlay/ui/icons/light-icon.js.map +1 -0
  47. package/dist/client/components/react-dev-overlay/ui/styles/base.js +14 -2
  48. package/dist/client/components/react-dev-overlay/ui/styles/base.js.map +1 -1
  49. package/dist/client/components/react-dev-overlay/ui/styles/colors.js +16 -4
  50. package/dist/client/components/react-dev-overlay/ui/styles/colors.js.map +1 -1
  51. package/dist/client/components/react-dev-overlay/ui/styles/component-styles.js +3 -1
  52. package/dist/client/components/react-dev-overlay/ui/styles/component-styles.js.map +1 -1
  53. package/dist/client/form-shared.d.ts +50 -0
  54. package/dist/client/form-shared.js +155 -0
  55. package/dist/client/form-shared.js.map +1 -0
  56. package/dist/client/form.d.ts +6 -41
  57. package/dist/client/form.js +38 -196
  58. package/dist/client/form.js.map +1 -1
  59. package/dist/client/index.js +1 -1
  60. package/dist/compiled/next-server/app-page-experimental.runtime.dev.js +3 -3
  61. package/dist/compiled/next-server/app-page-experimental.runtime.dev.js.map +1 -1
  62. package/dist/compiled/next-server/app-page.runtime.dev.js +3 -3
  63. package/dist/compiled/next-server/app-page.runtime.dev.js.map +1 -1
  64. package/dist/esm/build/index.js +2 -2
  65. package/dist/esm/build/swc/index.js +1 -1
  66. package/dist/esm/build/webpack-config.js +2 -2
  67. package/dist/esm/client/app-bootstrap.js +1 -1
  68. package/dist/esm/client/app-dir/form.js +17 -141
  69. package/dist/esm/client/app-dir/form.js.map +1 -1
  70. package/dist/esm/client/components/react-dev-overlay/shared.js +2 -0
  71. package/dist/esm/client/components/react-dev-overlay/shared.js.map +1 -1
  72. package/dist/esm/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.js +12 -4
  73. package/dist/esm/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.js.map +1 -1
  74. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-indicator.js +44 -9
  75. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-indicator.js.map +1 -1
  76. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/dev-tools-info.js +5 -4
  77. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/dev-tools-info.js.map +1 -1
  78. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/route-info.js +1 -1
  79. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/route-info.js.map +1 -1
  80. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/turbopack-info.js +1 -1
  81. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/turbopack-info.js.map +1 -1
  82. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/user-preferences.js +225 -0
  83. package/dist/esm/client/components/react-dev-overlay/ui/components/errors/dev-tools-indicator/dev-tools-info/user-preferences.js.map +1 -0
  84. package/dist/esm/client/components/react-dev-overlay/ui/components/shadow-portal.js +12 -0
  85. package/dist/esm/client/components/react-dev-overlay/ui/components/shadow-portal.js.map +1 -1
  86. package/dist/esm/client/components/react-dev-overlay/ui/icons/dark-icon.js +18 -0
  87. package/dist/esm/client/components/react-dev-overlay/ui/icons/dark-icon.js.map +1 -0
  88. package/dist/esm/client/components/react-dev-overlay/ui/icons/external.js +16 -0
  89. package/dist/esm/client/components/react-dev-overlay/ui/icons/external.js.map +1 -1
  90. package/dist/esm/client/components/react-dev-overlay/ui/icons/eye-icon.js +17 -0
  91. package/dist/esm/client/components/react-dev-overlay/ui/icons/eye-icon.js.map +1 -0
  92. package/dist/esm/client/components/react-dev-overlay/ui/icons/gear-icon.js +18 -0
  93. package/dist/esm/client/components/react-dev-overlay/ui/icons/gear-icon.js.map +1 -0
  94. package/dist/esm/client/components/react-dev-overlay/ui/icons/light-icon.js +32 -0
  95. package/dist/esm/client/components/react-dev-overlay/ui/icons/light-icon.js.map +1 -0
  96. package/dist/esm/client/components/react-dev-overlay/ui/styles/base.js +14 -2
  97. package/dist/esm/client/components/react-dev-overlay/ui/styles/base.js.map +1 -1
  98. package/dist/esm/client/components/react-dev-overlay/ui/styles/colors.js +16 -4
  99. package/dist/esm/client/components/react-dev-overlay/ui/styles/colors.js.map +1 -1
  100. package/dist/esm/client/components/react-dev-overlay/ui/styles/component-styles.js +3 -1
  101. package/dist/esm/client/components/react-dev-overlay/ui/styles/component-styles.js.map +1 -1
  102. package/dist/esm/client/form-shared.js +103 -0
  103. package/dist/esm/client/form-shared.js.map +1 -0
  104. package/dist/esm/client/form.js +35 -193
  105. package/dist/esm/client/form.js.map +1 -1
  106. package/dist/esm/client/index.js +1 -1
  107. package/dist/esm/server/config.js +1 -1
  108. package/dist/esm/server/dev/hot-reloader-turbopack.js +1 -1
  109. package/dist/esm/server/dev/hot-reloader-webpack.js +1 -1
  110. package/dist/esm/server/lib/app-info-log.js +1 -1
  111. package/dist/esm/server/lib/start-server.js +1 -1
  112. package/dist/server/config.js +1 -1
  113. package/dist/server/dev/hot-reloader-turbopack.js +1 -1
  114. package/dist/server/dev/hot-reloader-webpack.js +1 -1
  115. package/dist/server/lib/app-info-log.js +1 -1
  116. package/dist/server/lib/start-server.js +1 -1
  117. package/dist/telemetry/anonymous-meta.js +1 -1
  118. package/dist/telemetry/events/session-stopped.js +2 -2
  119. package/dist/telemetry/events/version.js +2 -2
  120. package/package.json +24 -24
@@ -296,7 +296,7 @@ export default async function build(dir, reactProductionProfiling = false, debug
296
296
  const nextBuildSpan = trace('next-build', undefined, {
297
297
  buildMode: experimentalBuildMode,
298
298
  isTurboBuild: String(turboNextBuild),
299
- version: "15.2.0-canary.75"
299
+ version: "15.2.0-canary.76"
300
300
  });
301
301
  NextBuildContext.nextBuildSpan = nextBuildSpan;
302
302
  NextBuildContext.dir = dir;
@@ -655,7 +655,7 @@ export default async function build(dir, reactProductionProfiling = false, debug
655
655
  // Files outside of the distDir can be "type": "module"
656
656
  await writeFileUtf8(path.join(distDir, 'package.json'), '{"type": "commonjs"}');
657
657
  // These are written to distDir, so they need to come after creating and cleaning distDr.
658
- await recordFrameworkVersion("15.2.0-canary.75");
658
+ await recordFrameworkVersion("15.2.0-canary.76");
659
659
  await updateBuildDiagnostics({
660
660
  buildStage: 'start'
661
661
  });
@@ -11,7 +11,7 @@ import { isDeepStrictEqual } from 'util';
11
11
  import { getDefineEnv } from '../webpack/plugins/define-env-plugin';
12
12
  import { getReactCompilerLoader } from '../get-babel-loader-config';
13
13
  import { TurbopackInternalError } from '../../shared/lib/turbopack/utils';
14
- const nextVersion = "15.2.0-canary.75";
14
+ const nextVersion = "15.2.0-canary.76";
15
15
  const ArchName = arch();
16
16
  const PlatformName = platform();
17
17
  function infoLog(...args) {
@@ -1525,7 +1525,7 @@ export default async function getBaseWebpackConfig(dir, { buildId, encryptionKey
1525
1525
  isClient && new CopyFilePlugin({
1526
1526
  // file path to build output of `@next/polyfill-nomodule`
1527
1527
  filePath: require.resolve('./polyfills/polyfill-nomodule'),
1528
- cacheKey: "15.2.0-canary.75",
1528
+ cacheKey: "15.2.0-canary.76",
1529
1529
  name: `static/chunks/polyfills${dev ? '' : '-[hash]'}.js`,
1530
1530
  minimize: false,
1531
1531
  info: {
@@ -1702,7 +1702,7 @@ export default async function getBaseWebpackConfig(dir, { buildId, encryptionKey
1702
1702
  // - Next.js location on disk (some loaders use absolute paths and some resolve options depend on absolute paths)
1703
1703
  // - Next.js version
1704
1704
  // - next.config.js keys that affect compilation
1705
- version: `${__dirname}|${"15.2.0-canary.75"}|${configVars}`,
1705
+ version: `${__dirname}|${"15.2.0-canary.76"}|${configVars}`,
1706
1706
  cacheDirectory: path.join(distDir, 'cache', 'webpack'),
1707
1707
  // For production builds, it's more efficient to compress all cache files together instead of compression each one individually.
1708
1708
  // So we disable compression here and allow the build runner to take care of compressing the cache as a whole.
@@ -3,7 +3,7 @@
3
3
  * sure the following scripts are executed in the correct order:
4
4
  * - Polyfills
5
5
  * - next/script with `beforeInteractive` strategy
6
- */ const version = "15.2.0-canary.75";
6
+ */ const version = "15.2.0-canary.76";
7
7
  window.next = {
8
8
  version,
9
9
  appDir: true
@@ -6,21 +6,16 @@ import { useIntersection } from '../use-intersection';
6
6
  import { useMergedRef } from '../use-merged-ref';
7
7
  import { AppRouterContext } from '../../shared/lib/app-router-context.shared-runtime';
8
8
  import { PrefetchKind } from '../components/router-reducer/router-reducer-types';
9
- import { RouterContext } from '../../shared/lib/router-context.shared-runtime';
10
- const DISALLOWED_FORM_PROPS = [
11
- 'method',
12
- 'encType',
13
- 'target'
14
- ];
9
+ import { checkFormActionUrl, createFormSubmitDestinationUrl, DISALLOWED_FORM_PROPS, hasReactClientActionAttributes, hasUnsupportedSubmitterAttributes } from '../form-shared';
15
10
  export default function Form(param) {
16
11
  let { replace, scroll, prefetch: prefetchProp, ref: externalRef, ...props } = param;
17
- const router = useAppOrPagesRouter();
12
+ const router = useContext(AppRouterContext);
18
13
  const actionProp = props.action;
19
14
  const isNavigatingForm = typeof actionProp === 'string';
20
15
  // Validate `action`
21
16
  if (process.env.NODE_ENV === 'development') {
22
17
  if (isNavigatingForm) {
23
- checkActionUrl(actionProp, 'action');
18
+ checkFormActionUrl(actionProp, 'action');
24
19
  }
25
20
  }
26
21
  // Validate `prefetch`
@@ -28,12 +23,8 @@ export default function Form(param) {
28
23
  if (!(prefetchProp === undefined || prefetchProp === false || prefetchProp === null)) {
29
24
  console.error('The `prefetch` prop of <Form> must be `false` or `null`');
30
25
  }
31
- if (prefetchProp !== undefined) {
32
- if (!isAppRouter(router)) {
33
- console.error('Passing `prefetch` to a <Form> has no effect in the pages directory.');
34
- } else if (!isNavigatingForm) {
35
- console.error('Passing `prefetch` to a <Form> whose `action` is a function has no effect.');
36
- }
26
+ if (prefetchProp !== undefined && !isNavigatingForm) {
27
+ console.error('Passing `prefetch` to a <Form> whose `action` is a function has no effect.');
37
28
  }
38
29
  }
39
30
  const prefetch = prefetchProp === false || prefetchProp === null ? prefetchProp : null;
@@ -52,9 +43,8 @@ export default function Form(param) {
52
43
  delete props[key];
53
44
  }
54
45
  }
55
- const isPrefetchEnabled = // there is no notion of instant loading states in pages dir, so prefetching is pointless
56
- isAppRouter(router) && // if we don't have an action path, we can't preload anything anyway.
57
- isNavigatingForm && prefetch === null;
46
+ const isPrefetchEnabled = // if we don't have an action path, we can't prefetch anything.
47
+ !!router && isNavigatingForm && prefetch === null;
58
48
  const [setIntersectionRef, isVisible] = useIntersection({
59
49
  rootMargin: '200px',
60
50
  disabled: !isPrefetchEnabled
@@ -109,6 +99,11 @@ function onFormSubmit(event, param) {
109
99
  return;
110
100
  }
111
101
  }
102
+ if (!router) {
103
+ // Form was somehow used outside of the router (but not in pages, the implementation is forked!).
104
+ // We can't perform a soft navigation, so let the native submit handling do its thing.
105
+ return;
106
+ }
112
107
  const formElement = event.currentTarget;
113
108
  const submitter = event.nativeEvent.submitter;
114
109
  let action = actionHref;
@@ -135,143 +130,24 @@ function onFormSubmit(event, param) {
135
130
  const submitterFormAction = submitter.getAttribute('formAction');
136
131
  if (submitterFormAction !== null) {
137
132
  if (process.env.NODE_ENV === 'development') {
138
- checkActionUrl(submitterFormAction, 'formAction');
133
+ checkFormActionUrl(submitterFormAction, 'formAction');
139
134
  }
140
135
  action = submitterFormAction;
141
136
  }
142
137
  }
143
- let targetUrl;
144
- try {
145
- // NOTE: It might be more correct to resolve URLs relative to `document.baseURI`,
146
- // but we already do it relative to `location.href` elsewhere:
147
- // (see e.g. https://github.com/vercel/next.js/blob/bb0e6722f87ceb2d43015f5b8a413d0072f2badf/packages/next/src/client/components/app-router.tsx#L146)
148
- // so it's better to stay consistent.
149
- const base = window.location.href;
150
- targetUrl = new URL(action, base);
151
- } catch (err) {
152
- throw Object.defineProperty(new Error('Cannot parse form action "' + action + '" as a URL', {
153
- cause: err
154
- }), "__NEXT_ERROR_CODE", {
155
- value: "E152",
156
- enumerable: false,
157
- configurable: true
158
- });
159
- }
160
- if (targetUrl.searchParams.size) {
161
- // url-encoded HTML forms *overwrite* any search params in the `action` url:
162
- //
163
- // "Let `query` be the result of running the application/x-www-form-urlencoded serializer [...]"
164
- // "Set parsed action's query component to `query`."
165
- // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mutate-action
166
- //
167
- // We need to match that.
168
- // (note that all other parts of the URL, like `hash`, are preserved)
169
- targetUrl.search = '';
170
- }
171
- const formData = new FormData(formElement);
172
- for (let [name, value] of formData){
173
- if (typeof value !== 'string') {
174
- // For file inputs, the native browser behavior is to use the filename as the value instead:
175
- //
176
- // "If entry's value is a File object, then let value be entry's value's name. Otherwise, let value be entry's value."
177
- // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs
178
- //
179
- if (process.env.NODE_ENV === 'development') {
180
- console.warn("<Form> only supports file inputs if `action` is a function. File inputs cannot be used if `action` is a string, " + "because files cannot be encoded as search params.");
181
- }
182
- value = value.name;
183
- }
184
- targetUrl.searchParams.append(name, value);
185
- }
138
+ const targetUrl = createFormSubmitDestinationUrl(action, formElement);
186
139
  // Finally, no more reasons for bailing out.
187
140
  event.preventDefault();
188
141
  const method = replace ? 'replace' : 'push';
189
142
  const targetHref = targetUrl.href;
190
- if (isAppRouter(router)) {
191
- router[method](targetHref, {
192
- scroll
193
- });
194
- } else {
195
- // TODO(form): Make this use a transition so that pending states work
196
- //
197
- // Unlike the app router, pages router doesn't use startTransition,
198
- // and can't easily be wrapped in one because of implementation details
199
- // (e.g. it doesn't use any react state)
200
- // But it's important to have this wrapped in a transition because
201
- // pending states from e.g. `useFormStatus` rely on that.
202
- // So this needs some follow up work.
203
- router[method](targetHref, undefined, {
204
- scroll
205
- });
206
- }
207
- }
208
- function isAppRouter(router) {
209
- return !('asPath' in router);
210
- }
211
- function useAppOrPagesRouter() {
212
- const pagesRouter = useContext(RouterContext);
213
- const appRouter = useContext(AppRouterContext);
214
- if (pagesRouter) {
215
- return pagesRouter;
216
- } else {
217
- // We're in the app directory if there is no pages router.
218
- return appRouter;
219
- }
220
- }
221
- function checkActionUrl(action, source) {
222
- const aPropName = source === 'action' ? "an `action`" : "a `formAction`";
223
- let testUrl;
224
- try {
225
- testUrl = new URL(action, 'http://n');
226
- } catch (err) {
227
- console.error("<Form> received " + aPropName + ' that cannot be parsed as a URL: "' + action + '".');
228
- return;
229
- }
230
- // url-encoded HTML forms ignore any queryparams in the `action` url. We need to match that.
231
- if (testUrl.searchParams.size) {
232
- console.warn("<Form> received " + aPropName + ' that contains search params: "' + action + '". This is not supported, and they will be ignored. ' + 'If you need to pass in additional search params, use an `<input type="hidden" />` instead.');
233
- }
234
- }
235
- const isSupportedEncType = (value)=>value === 'application/x-www-form-urlencoded';
236
- const isSupportedMethod = (value)=>value === 'get';
237
- const isSupportedTarget = (value)=>value === '_self';
238
- function hasUnsupportedSubmitterAttributes(submitter) {
239
- // A submitter can override `encType` for the form.
240
- const formEncType = submitter.getAttribute('formEncType');
241
- if (formEncType !== null && !isSupportedEncType(formEncType)) {
242
- if (process.env.NODE_ENV === 'development') {
243
- console.error("<Form>'s `encType` was set to an unsupported value via `formEncType=\"" + formEncType + '"`. ' + "This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.");
244
- }
245
- return true;
246
- }
247
- // A submitter can override `method` for the form.
248
- const formMethod = submitter.getAttribute('formMethod');
249
- if (formMethod !== null && !isSupportedMethod(formMethod)) {
250
- if (process.env.NODE_ENV === 'development') {
251
- console.error("<Form>'s `method` was set to an unsupported value via `formMethod=\"" + formMethod + '"`. ' + "This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.");
252
- }
253
- return true;
254
- }
255
- // A submitter can override `target` for the form.
256
- const formTarget = submitter.getAttribute('formTarget');
257
- if (formTarget !== null && !isSupportedTarget(formTarget)) {
258
- if (process.env.NODE_ENV === 'development') {
259
- console.error("<Form>'s `target` was set to an unsupported value via `formTarget=\"" + formTarget + '"`. ' + "This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.");
260
- }
261
- return true;
262
- }
263
- return false;
143
+ router[method](targetHref, {
144
+ scroll
145
+ });
264
146
  }
265
147
  function hasReactServerActionAttributes(submitter) {
266
148
  // https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-client/src/ReactFlightReplyClient.js#L931-L934
267
149
  const name = submitter.getAttribute('name');
268
150
  return name && (name.startsWith('$ACTION_ID_') || name.startsWith('$ACTION_REF_'));
269
151
  }
270
- function hasReactClientActionAttributes(submitter) {
271
- // CSR: https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-dom-bindings/src/client/ReactDOMComponent.js#L482-L487
272
- // SSR: https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-dom-bindings/src/client/ReactDOMComponent.js#L2401
273
- const action = submitter.getAttribute('formAction');
274
- return action && /\s*javascript:/i.test(action);
275
- }
276
152
 
277
153
  //# sourceMappingURL=form.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/client/app-dir/form.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, type HTMLProps, type FormEvent, useContext } from 'react'\nimport { addBasePath } from '../add-base-path'\nimport { useIntersection } from '../use-intersection'\nimport { useMergedRef } from '../use-merged-ref'\nimport {\n AppRouterContext,\n type AppRouterInstance,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport { PrefetchKind } from '../components/router-reducer/router-reducer-types'\nimport { RouterContext } from '../../shared/lib/router-context.shared-runtime'\nimport type { NextRouter } from '../router'\n\nconst DISALLOWED_FORM_PROPS = ['method', 'encType', 'target'] as const\n\ntype HTMLFormProps = HTMLProps<HTMLFormElement>\ntype DisallowedFormProps = (typeof DISALLOWED_FORM_PROPS)[number]\n\ntype InternalFormProps = {\n /**\n * `action` can be either a `string` or a function.\n * - If `action` is a string, it will be interpreted as a path or URL to navigate to when the form is submitted.\n * The path will be prefetched when the form becomes visible.\n * - If `action` is a function, it will be called when the form is submitted. See the [React docs](https://react.dev/reference/react-dom/components/form#props) for more.\n */\n action: NonNullable<HTMLFormProps['action']>\n /**\n * Controls how the route specified by `action` is prefetched.\n * Any `<Form />` that is in the viewport (initially or through scroll) will be prefetched.\n * Prefetch can be disabled by passing `prefetch={false}`. Prefetching is only enabled in production.\n *\n * Options:\n * - `null` (default): For statically generated pages, this will prefetch the full React Server Component data. For dynamic pages, this will prefetch up to the nearest route segment with a [`loading.js`](https://nextjs.org/docs/app/api-reference/file-conventions/loading) file. If there is no loading file, it will not fetch the full tree to avoid fetching too much data.\n * - `false`: This will not prefetch any data.\n *\n * In pages dir, prefetching is not supported, and passing this prop will emit a warning.\n *\n * @defaultValue `null`\n */\n prefetch?: false | null\n /**\n * Whether submitting the form should replace the current `history` state instead of adding a new url into the stack.\n * Only valid if `action` is a string.\n *\n * @defaultValue `false`\n */\n replace?: boolean\n /**\n * Override the default scroll behavior when navigating.\n * Only valid if `action` is a string.\n *\n * @defaultValue `true`\n */\n scroll?: boolean\n} & Omit<HTMLFormProps, 'action' | DisallowedFormProps>\n\n// `RouteInferType` is a stub here to avoid breaking `typedRoutes` when the type\n// isn't generated yet. It will be replaced when the webpack plugin runs.\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport type FormProps<RouteInferType = any> = InternalFormProps\n\nexport default function Form({\n replace,\n scroll,\n prefetch: prefetchProp,\n ref: externalRef,\n ...props\n}: FormProps) {\n const router = useAppOrPagesRouter()\n\n const actionProp = props.action\n const isNavigatingForm = typeof actionProp === 'string'\n\n // Validate `action`\n if (process.env.NODE_ENV === 'development') {\n if (isNavigatingForm) {\n checkActionUrl(actionProp, 'action')\n }\n }\n\n // Validate `prefetch`\n if (process.env.NODE_ENV === 'development') {\n if (\n !(\n prefetchProp === undefined ||\n prefetchProp === false ||\n prefetchProp === null\n )\n ) {\n console.error('The `prefetch` prop of <Form> must be `false` or `null`')\n }\n\n if (prefetchProp !== undefined) {\n if (!isAppRouter(router)) {\n console.error(\n 'Passing `prefetch` to a <Form> has no effect in the pages directory.'\n )\n } else if (!isNavigatingForm) {\n console.error(\n 'Passing `prefetch` to a <Form> whose `action` is a function has no effect.'\n )\n }\n }\n }\n\n const prefetch =\n prefetchProp === false || prefetchProp === null ? prefetchProp : null\n\n // Validate `scroll` and `replace`\n if (process.env.NODE_ENV === 'development') {\n if (!isNavigatingForm && (replace !== undefined || scroll !== undefined)) {\n console.error(\n 'Passing `replace` or `scroll` to a <Form> whose `action` is a function has no effect.\\n' +\n 'See the relevant docs to learn how to control this behavior for navigations triggered from actions:\\n' +\n ' `redirect()` - https://nextjs.org/docs/app/api-reference/functions/redirect#parameters\\n' +\n ' `router.replace()` - https://nextjs.org/docs/app/api-reference/functions/use-router#userouter\\n'\n )\n }\n }\n\n // Clean up any unsupported form props (and warn if present)\n for (const key of DISALLOWED_FORM_PROPS) {\n if (key in props) {\n if (process.env.NODE_ENV === 'development') {\n console.error(\n `<Form> does not support changing \\`${key}\\`. ` +\n (isNavigatingForm\n ? `If you'd like to use it to perform a mutation, consider making \\`action\\` a function instead.\\n` +\n `Learn more: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations`\n : '')\n )\n }\n delete (props as Record<string, unknown>)[key]\n }\n }\n\n const isPrefetchEnabled =\n // there is no notion of instant loading states in pages dir, so prefetching is pointless\n isAppRouter(router) &&\n // if we don't have an action path, we can't preload anything anyway.\n isNavigatingForm &&\n prefetch === null\n\n const [setIntersectionRef, isVisible] = useIntersection({\n rootMargin: '200px',\n disabled: !isPrefetchEnabled,\n })\n\n const ownRef = useMergedRef<HTMLFormElement>(\n setIntersectionRef,\n externalRef ?? null\n )\n\n useEffect(() => {\n if (!isVisible || !isPrefetchEnabled) {\n return\n }\n\n try {\n const prefetchKind = PrefetchKind.AUTO\n router.prefetch(actionProp, { kind: prefetchKind })\n } catch (err) {\n console.error(err)\n }\n }, [isPrefetchEnabled, isVisible, actionProp, prefetch, router])\n\n if (!isNavigatingForm) {\n return <form {...props} ref={ownRef} />\n }\n\n const actionHref = addBasePath(actionProp)\n\n return (\n <form\n {...props}\n ref={ownRef}\n action={actionHref}\n onSubmit={(event) =>\n onFormSubmit(event, {\n router,\n actionHref,\n replace,\n scroll,\n onSubmit: props.onSubmit,\n })\n }\n />\n )\n}\n\nfunction onFormSubmit(\n event: FormEvent<HTMLFormElement>,\n {\n actionHref,\n onSubmit,\n replace,\n scroll,\n router,\n }: {\n actionHref: string\n onSubmit: FormProps['onSubmit']\n replace: FormProps['replace']\n scroll: FormProps['scroll']\n router: SomeRouter\n }\n) {\n if (typeof onSubmit === 'function') {\n onSubmit(event)\n\n // if the user called event.preventDefault(), do nothing.\n // (this matches what Link does for `onClick`)\n if (event.defaultPrevented) {\n return\n }\n }\n\n const formElement = event.currentTarget\n const submitter = (event.nativeEvent as SubmitEvent).submitter\n\n let action = actionHref\n\n if (submitter) {\n if (process.env.NODE_ENV === 'development') {\n // the way server actions are encoded (e.g. `formMethod=\"post\")\n // causes some unnecessary dev-mode warnings from `hasUnsupportedSubmitterAttributes`.\n // we'd bail out anyway, but we just do it silently.\n if (hasReactServerActionAttributes(submitter)) {\n return\n }\n }\n\n if (hasUnsupportedSubmitterAttributes(submitter)) {\n return\n }\n\n // client actions have `formAction=\"javascript:...\"`. We obviously can't prefetch/navigate to that.\n if (hasReactClientActionAttributes(submitter)) {\n return\n }\n\n // If the submitter specified an alternate formAction,\n // use that URL instead -- this is what a native form would do.\n // NOTE: `submitter.formAction` is unreliable, because it will give us `location.href` if it *wasn't* set\n // NOTE: this should not have `basePath` added, because we can't add it before hydration\n const submitterFormAction = submitter.getAttribute('formAction')\n if (submitterFormAction !== null) {\n if (process.env.NODE_ENV === 'development') {\n checkActionUrl(submitterFormAction, 'formAction')\n }\n action = submitterFormAction\n }\n }\n\n let targetUrl: URL\n try {\n // NOTE: It might be more correct to resolve URLs relative to `document.baseURI`,\n // but we already do it relative to `location.href` elsewhere:\n // (see e.g. https://github.com/vercel/next.js/blob/bb0e6722f87ceb2d43015f5b8a413d0072f2badf/packages/next/src/client/components/app-router.tsx#L146)\n // so it's better to stay consistent.\n const base = window.location.href\n targetUrl = new URL(action, base)\n } catch (err) {\n throw new Error(`Cannot parse form action \"${action}\" as a URL`, {\n cause: err,\n })\n }\n if (targetUrl.searchParams.size) {\n // url-encoded HTML forms *overwrite* any search params in the `action` url:\n //\n // \"Let `query` be the result of running the application/x-www-form-urlencoded serializer [...]\"\n // \"Set parsed action's query component to `query`.\"\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#submit-mutate-action\n //\n // We need to match that.\n // (note that all other parts of the URL, like `hash`, are preserved)\n targetUrl.search = ''\n }\n\n const formData = new FormData(formElement)\n\n for (let [name, value] of formData) {\n if (typeof value !== 'string') {\n // For file inputs, the native browser behavior is to use the filename as the value instead:\n //\n // \"If entry's value is a File object, then let value be entry's value's name. Otherwise, let value be entry's value.\"\n // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#converting-an-entry-list-to-a-list-of-name-value-pairs\n //\n if (process.env.NODE_ENV === 'development') {\n console.warn(\n `<Form> only supports file inputs if \\`action\\` is a function. File inputs cannot be used if \\`action\\` is a string, ` +\n `because files cannot be encoded as search params.`\n )\n }\n value = value.name\n }\n\n targetUrl.searchParams.append(name, value)\n }\n\n // Finally, no more reasons for bailing out.\n event.preventDefault()\n\n const method = replace ? 'replace' : 'push'\n const targetHref = targetUrl.href\n if (isAppRouter(router)) {\n router[method](targetHref, { scroll })\n } else {\n // TODO(form): Make this use a transition so that pending states work\n //\n // Unlike the app router, pages router doesn't use startTransition,\n // and can't easily be wrapped in one because of implementation details\n // (e.g. it doesn't use any react state)\n // But it's important to have this wrapped in a transition because\n // pending states from e.g. `useFormStatus` rely on that.\n // So this needs some follow up work.\n router[method](targetHref, undefined, { scroll })\n }\n}\n\ntype SomeRouter = AppRouterInstance | NextRouter\n\nfunction isAppRouter(router: SomeRouter): router is AppRouterInstance {\n return !('asPath' in router)\n}\n\nfunction useAppOrPagesRouter(): SomeRouter {\n const pagesRouter = useContext(RouterContext)\n const appRouter = useContext(AppRouterContext)\n if (pagesRouter) {\n return pagesRouter\n } else {\n // We're in the app directory if there is no pages router.\n return appRouter!\n }\n}\n\nfunction checkActionUrl(action: string, source: 'action' | 'formAction') {\n const aPropName = source === 'action' ? `an \\`action\\`` : `a \\`formAction\\``\n\n let testUrl: URL\n try {\n testUrl = new URL(action, 'http://n')\n } catch (err) {\n console.error(\n `<Form> received ${aPropName} that cannot be parsed as a URL: \"${action}\".`\n )\n return\n }\n\n // url-encoded HTML forms ignore any queryparams in the `action` url. We need to match that.\n if (testUrl.searchParams.size) {\n console.warn(\n `<Form> received ${aPropName} that contains search params: \"${action}\". This is not supported, and they will be ignored. ` +\n `If you need to pass in additional search params, use an \\`<input type=\"hidden\" />\\` instead.`\n )\n }\n}\n\nconst isSupportedEncType = (value: string) =>\n value === 'application/x-www-form-urlencoded'\nconst isSupportedMethod = (value: string) => value === 'get'\nconst isSupportedTarget = (value: string) => value === '_self'\n\nfunction hasUnsupportedSubmitterAttributes(submitter: HTMLElement): boolean {\n // A submitter can override `encType` for the form.\n const formEncType = submitter.getAttribute('formEncType')\n if (formEncType !== null && !isSupportedEncType(formEncType)) {\n if (process.env.NODE_ENV === 'development') {\n console.error(\n `<Form>'s \\`encType\\` was set to an unsupported value via \\`formEncType=\"${formEncType}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`\n )\n }\n return true\n }\n\n // A submitter can override `method` for the form.\n const formMethod = submitter.getAttribute('formMethod')\n if (formMethod !== null && !isSupportedMethod(formMethod)) {\n if (process.env.NODE_ENV === 'development') {\n console.error(\n `<Form>'s \\`method\\` was set to an unsupported value via \\`formMethod=\"${formMethod}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`\n )\n }\n return true\n }\n\n // A submitter can override `target` for the form.\n const formTarget = submitter.getAttribute('formTarget')\n if (formTarget !== null && !isSupportedTarget(formTarget)) {\n if (process.env.NODE_ENV === 'development') {\n console.error(\n `<Form>'s \\`target\\` was set to an unsupported value via \\`formTarget=\"${formTarget}\"\\`. ` +\n `This will disable <Form>'s navigation functionality. If you need this, use a native <form> element instead.`\n )\n }\n return true\n }\n\n return false\n}\n\nfunction hasReactServerActionAttributes(submitter: HTMLElement) {\n // https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-client/src/ReactFlightReplyClient.js#L931-L934\n const name = submitter.getAttribute('name')\n return (\n name && (name.startsWith('$ACTION_ID_') || name.startsWith('$ACTION_REF_'))\n )\n}\n\nfunction hasReactClientActionAttributes(submitter: HTMLElement) {\n // CSR: https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-dom-bindings/src/client/ReactDOMComponent.js#L482-L487\n // SSR: https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-dom-bindings/src/client/ReactDOMComponent.js#L2401\n const action = submitter.getAttribute('formAction')\n return action && /\\s*javascript:/i.test(action)\n}\n"],"names":["useEffect","useContext","addBasePath","useIntersection","useMergedRef","AppRouterContext","PrefetchKind","RouterContext","DISALLOWED_FORM_PROPS","Form","replace","scroll","prefetch","prefetchProp","ref","externalRef","props","router","useAppOrPagesRouter","actionProp","action","isNavigatingForm","process","env","NODE_ENV","checkActionUrl","undefined","console","error","isAppRouter","key","isPrefetchEnabled","setIntersectionRef","isVisible","rootMargin","disabled","ownRef","prefetchKind","AUTO","kind","err","form","actionHref","onSubmit","event","onFormSubmit","defaultPrevented","formElement","currentTarget","submitter","nativeEvent","hasReactServerActionAttributes","hasUnsupportedSubmitterAttributes","hasReactClientActionAttributes","submitterFormAction","getAttribute","targetUrl","base","window","location","href","URL","Error","cause","searchParams","size","search","formData","FormData","name","value","warn","append","preventDefault","method","targetHref","pagesRouter","appRouter","source","aPropName","testUrl","isSupportedEncType","isSupportedMethod","isSupportedTarget","formEncType","formMethod","formTarget","startsWith","test"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/client/app-dir/form.tsx"],"sourcesContent":["'use client'\n\nimport { useEffect, type FormEvent, useContext } from 'react'\nimport { addBasePath } from '../add-base-path'\nimport { useIntersection } from '../use-intersection'\nimport { useMergedRef } from '../use-merged-ref'\nimport {\n AppRouterContext,\n type AppRouterInstance,\n} from '../../shared/lib/app-router-context.shared-runtime'\nimport { PrefetchKind } from '../components/router-reducer/router-reducer-types'\nimport {\n checkFormActionUrl,\n createFormSubmitDestinationUrl,\n DISALLOWED_FORM_PROPS,\n hasReactClientActionAttributes,\n hasUnsupportedSubmitterAttributes,\n type FormProps,\n} from '../form-shared'\n\nexport type { FormProps }\n\nexport default function Form({\n replace,\n scroll,\n prefetch: prefetchProp,\n ref: externalRef,\n ...props\n}: FormProps) {\n const router = useContext(AppRouterContext)\n\n const actionProp = props.action\n const isNavigatingForm = typeof actionProp === 'string'\n\n // Validate `action`\n if (process.env.NODE_ENV === 'development') {\n if (isNavigatingForm) {\n checkFormActionUrl(actionProp, 'action')\n }\n }\n\n // Validate `prefetch`\n if (process.env.NODE_ENV === 'development') {\n if (\n !(\n prefetchProp === undefined ||\n prefetchProp === false ||\n prefetchProp === null\n )\n ) {\n console.error('The `prefetch` prop of <Form> must be `false` or `null`')\n }\n\n if (prefetchProp !== undefined && !isNavigatingForm) {\n console.error(\n 'Passing `prefetch` to a <Form> whose `action` is a function has no effect.'\n )\n }\n }\n\n const prefetch =\n prefetchProp === false || prefetchProp === null ? prefetchProp : null\n\n // Validate `scroll` and `replace`\n if (process.env.NODE_ENV === 'development') {\n if (!isNavigatingForm && (replace !== undefined || scroll !== undefined)) {\n console.error(\n 'Passing `replace` or `scroll` to a <Form> whose `action` is a function has no effect.\\n' +\n 'See the relevant docs to learn how to control this behavior for navigations triggered from actions:\\n' +\n ' `redirect()` - https://nextjs.org/docs/app/api-reference/functions/redirect#parameters\\n' +\n ' `router.replace()` - https://nextjs.org/docs/app/api-reference/functions/use-router#userouter\\n'\n )\n }\n }\n\n // Clean up any unsupported form props (and warn if present)\n for (const key of DISALLOWED_FORM_PROPS) {\n if (key in props) {\n if (process.env.NODE_ENV === 'development') {\n console.error(\n `<Form> does not support changing \\`${key}\\`. ` +\n (isNavigatingForm\n ? `If you'd like to use it to perform a mutation, consider making \\`action\\` a function instead.\\n` +\n `Learn more: https://nextjs.org/docs/app/building-your-application/data-fetching/server-actions-and-mutations`\n : '')\n )\n }\n delete (props as Record<string, unknown>)[key]\n }\n }\n\n const isPrefetchEnabled =\n // if we don't have an action path, we can't prefetch anything.\n !!router && isNavigatingForm && prefetch === null\n\n const [setIntersectionRef, isVisible] = useIntersection({\n rootMargin: '200px',\n disabled: !isPrefetchEnabled,\n })\n\n const ownRef = useMergedRef<HTMLFormElement>(\n setIntersectionRef,\n externalRef ?? null\n )\n\n useEffect(() => {\n if (!isVisible || !isPrefetchEnabled) {\n return\n }\n\n try {\n const prefetchKind = PrefetchKind.AUTO\n router.prefetch(actionProp, { kind: prefetchKind })\n } catch (err) {\n console.error(err)\n }\n }, [isPrefetchEnabled, isVisible, actionProp, prefetch, router])\n\n if (!isNavigatingForm) {\n return <form {...props} ref={ownRef} />\n }\n\n const actionHref = addBasePath(actionProp)\n\n return (\n <form\n {...props}\n ref={ownRef}\n action={actionHref}\n onSubmit={(event) =>\n onFormSubmit(event, {\n router,\n actionHref,\n replace,\n scroll,\n onSubmit: props.onSubmit,\n })\n }\n />\n )\n}\n\nfunction onFormSubmit(\n event: FormEvent<HTMLFormElement>,\n {\n actionHref,\n onSubmit,\n replace,\n scroll,\n router,\n }: {\n actionHref: string\n onSubmit: FormProps['onSubmit']\n replace: FormProps['replace']\n scroll: FormProps['scroll']\n router: AppRouterInstance | null\n }\n) {\n if (typeof onSubmit === 'function') {\n onSubmit(event)\n\n // if the user called event.preventDefault(), do nothing.\n // (this matches what Link does for `onClick`)\n if (event.defaultPrevented) {\n return\n }\n }\n\n if (!router) {\n // Form was somehow used outside of the router (but not in pages, the implementation is forked!).\n // We can't perform a soft navigation, so let the native submit handling do its thing.\n return\n }\n\n const formElement = event.currentTarget\n const submitter = (event.nativeEvent as SubmitEvent).submitter\n\n let action = actionHref\n\n if (submitter) {\n if (process.env.NODE_ENV === 'development') {\n // the way server actions are encoded (e.g. `formMethod=\"post\")\n // causes some unnecessary dev-mode warnings from `hasUnsupportedSubmitterAttributes`.\n // we'd bail out anyway, but we just do it silently.\n if (hasReactServerActionAttributes(submitter)) {\n return\n }\n }\n\n if (hasUnsupportedSubmitterAttributes(submitter)) {\n return\n }\n\n // client actions have `formAction=\"javascript:...\"`. We obviously can't prefetch/navigate to that.\n if (hasReactClientActionAttributes(submitter)) {\n return\n }\n\n // If the submitter specified an alternate formAction,\n // use that URL instead -- this is what a native form would do.\n // NOTE: `submitter.formAction` is unreliable, because it will give us `location.href` if it *wasn't* set\n // NOTE: this should not have `basePath` added, because we can't add it before hydration\n const submitterFormAction = submitter.getAttribute('formAction')\n if (submitterFormAction !== null) {\n if (process.env.NODE_ENV === 'development') {\n checkFormActionUrl(submitterFormAction, 'formAction')\n }\n action = submitterFormAction\n }\n }\n\n const targetUrl = createFormSubmitDestinationUrl(action, formElement)\n\n // Finally, no more reasons for bailing out.\n event.preventDefault()\n\n const method = replace ? 'replace' : 'push'\n const targetHref = targetUrl.href\n router[method](targetHref, { scroll })\n}\n\nfunction hasReactServerActionAttributes(submitter: HTMLElement) {\n // https://github.com/facebook/react/blob/942eb80381b96f8410eab1bef1c539bed1ab0eb1/packages/react-client/src/ReactFlightReplyClient.js#L931-L934\n const name = submitter.getAttribute('name')\n return (\n name && (name.startsWith('$ACTION_ID_') || name.startsWith('$ACTION_REF_'))\n )\n}\n"],"names":["useEffect","useContext","addBasePath","useIntersection","useMergedRef","AppRouterContext","PrefetchKind","checkFormActionUrl","createFormSubmitDestinationUrl","DISALLOWED_FORM_PROPS","hasReactClientActionAttributes","hasUnsupportedSubmitterAttributes","Form","replace","scroll","prefetch","prefetchProp","ref","externalRef","props","router","actionProp","action","isNavigatingForm","process","env","NODE_ENV","undefined","console","error","key","isPrefetchEnabled","setIntersectionRef","isVisible","rootMargin","disabled","ownRef","prefetchKind","AUTO","kind","err","form","actionHref","onSubmit","event","onFormSubmit","defaultPrevented","formElement","currentTarget","submitter","nativeEvent","hasReactServerActionAttributes","submitterFormAction","getAttribute","targetUrl","preventDefault","method","targetHref","href","name","startsWith"],"mappings":"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"}
@@ -10,6 +10,8 @@ export const ACTION_UNHANDLED_ERROR = 'unhandled-error';
10
10
  export const ACTION_UNHANDLED_REJECTION = 'unhandled-rejection';
11
11
  export const ACTION_DEBUG_INFO = 'debug-info';
12
12
  export const ACTION_DEV_INDICATOR = 'dev-indicator';
13
+ export const STORAGE_KEY_THEME = '__nextjs-dev-tools-theme';
14
+ export const STORAGE_KEY_POSITION = '__nextjs-dev-tools-position';
13
15
  function pushErrorFilterDuplicates(errors, err) {
14
16
  return [
15
17
  ...errors.filter((e)=>{
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/client/components/react-dev-overlay/shared.ts"],"sourcesContent":["import { useReducer } from 'react'\n\nimport type { StackFrame } from 'next/dist/compiled/stacktrace-parser'\nimport type { VersionInfo } from '../../../server/dev/parse-version-info'\nimport type { SupportedErrorEvent } from './ui/container/runtime-error/render-error'\nimport type { ComponentStackFrame } from './utils/parse-component-stack'\nimport type { DebugInfo } from './types'\nimport type { DevIndicatorServerState } from '../../../server/dev/dev-indicator-server-state'\n\ntype FastRefreshState =\n /** No refresh in progress. */\n | { type: 'idle' }\n /** The refresh process has been triggered, but the new code has not been executed yet. */\n | { type: 'pending'; errors: SupportedErrorEvent[] }\n\nexport interface OverlayState {\n nextId: number\n buildError: string | null\n errors: SupportedErrorEvent[]\n refreshState: FastRefreshState\n rootLayoutMissingTags: typeof window.__next_root_layout_missing_tags\n versionInfo: VersionInfo\n notFound: boolean\n staticIndicator: boolean\n disableDevIndicator: boolean\n debugInfo: DebugInfo\n routerType: 'pages' | 'app'\n}\n\nexport const ACTION_STATIC_INDICATOR = 'static-indicator'\nexport const ACTION_BUILD_OK = 'build-ok'\nexport const ACTION_BUILD_ERROR = 'build-error'\nexport const ACTION_BEFORE_REFRESH = 'before-fast-refresh'\nexport const ACTION_REFRESH = 'fast-refresh'\nexport const ACTION_VERSION_INFO = 'version-info'\nexport const ACTION_UNHANDLED_ERROR = 'unhandled-error'\nexport const ACTION_UNHANDLED_REJECTION = 'unhandled-rejection'\nexport const ACTION_DEBUG_INFO = 'debug-info'\nexport const ACTION_DEV_INDICATOR = 'dev-indicator'\n\ninterface StaticIndicatorAction {\n type: typeof ACTION_STATIC_INDICATOR\n staticIndicator: boolean\n}\n\ninterface BuildOkAction {\n type: typeof ACTION_BUILD_OK\n}\ninterface BuildErrorAction {\n type: typeof ACTION_BUILD_ERROR\n message: string\n}\ninterface BeforeFastRefreshAction {\n type: typeof ACTION_BEFORE_REFRESH\n}\ninterface FastRefreshAction {\n type: typeof ACTION_REFRESH\n}\n\nexport interface UnhandledErrorAction {\n type: typeof ACTION_UNHANDLED_ERROR\n reason: Error\n frames: StackFrame[]\n componentStackFrames?: ComponentStackFrame[]\n warning?: [string, string, string]\n}\nexport interface UnhandledRejectionAction {\n type: typeof ACTION_UNHANDLED_REJECTION\n reason: Error\n frames: StackFrame[]\n}\n\nexport interface DebugInfoAction {\n type: typeof ACTION_DEBUG_INFO\n debugInfo: any\n}\n\ninterface VersionInfoAction {\n type: typeof ACTION_VERSION_INFO\n versionInfo: VersionInfo\n}\n\ninterface DevIndicatorAction {\n type: typeof ACTION_DEV_INDICATOR\n devIndicator: DevIndicatorServerState\n}\n\nexport type BusEvent =\n | BuildOkAction\n | BuildErrorAction\n | BeforeFastRefreshAction\n | FastRefreshAction\n | UnhandledErrorAction\n | UnhandledRejectionAction\n | VersionInfoAction\n | StaticIndicatorAction\n | DebugInfoAction\n | DevIndicatorAction\n\nfunction pushErrorFilterDuplicates(\n errors: SupportedErrorEvent[],\n err: SupportedErrorEvent\n): SupportedErrorEvent[] {\n return [\n ...errors.filter((e) => {\n // Filter out duplicate errors\n return e.event.reason.stack !== err.event.reason.stack\n }),\n err,\n ]\n}\n\nconst shouldDisableDevIndicator =\n process.env.__NEXT_DEV_INDICATOR?.toString() === 'false'\n\nexport const INITIAL_OVERLAY_STATE: Omit<OverlayState, 'routerType'> = {\n nextId: 1,\n buildError: null,\n errors: [],\n notFound: false,\n staticIndicator: false,\n // To prevent flickering, set the initial state to disabled.\n disableDevIndicator: true,\n refreshState: { type: 'idle' },\n rootLayoutMissingTags: [],\n versionInfo: { installed: '0.0.0', staleness: 'unknown' },\n debugInfo: { devtoolsFrontendUrl: undefined },\n}\n\nfunction getInitialState(\n routerType: 'pages' | 'app'\n): OverlayState & { routerType: 'pages' | 'app' } {\n return {\n ...INITIAL_OVERLAY_STATE,\n routerType,\n }\n}\n\nexport function useErrorOverlayReducer(routerType: 'pages' | 'app') {\n return useReducer((_state: OverlayState, action: BusEvent): OverlayState => {\n switch (action.type) {\n case ACTION_DEBUG_INFO: {\n return { ..._state, debugInfo: action.debugInfo }\n }\n case ACTION_STATIC_INDICATOR: {\n return { ..._state, staticIndicator: action.staticIndicator }\n }\n case ACTION_BUILD_OK: {\n return { ..._state, buildError: null }\n }\n case ACTION_BUILD_ERROR: {\n return { ..._state, buildError: action.message }\n }\n case ACTION_BEFORE_REFRESH: {\n return { ..._state, refreshState: { type: 'pending', errors: [] } }\n }\n case ACTION_REFRESH: {\n return {\n ..._state,\n buildError: null,\n errors:\n // Errors can come in during updates. In this case, UNHANDLED_ERROR\n // and UNHANDLED_REJECTION events might be dispatched between the\n // BEFORE_REFRESH and the REFRESH event. We want to keep those errors\n // around until the next refresh. Otherwise we run into a race\n // condition where those errors would be cleared on refresh completion\n // before they can be displayed.\n _state.refreshState.type === 'pending'\n ? _state.refreshState.errors\n : [],\n refreshState: { type: 'idle' },\n }\n }\n case ACTION_UNHANDLED_ERROR:\n case ACTION_UNHANDLED_REJECTION: {\n switch (_state.refreshState.type) {\n case 'idle': {\n return {\n ..._state,\n nextId: _state.nextId + 1,\n errors: pushErrorFilterDuplicates(_state.errors, {\n id: _state.nextId,\n event: action,\n }),\n }\n }\n case 'pending': {\n return {\n ..._state,\n nextId: _state.nextId + 1,\n refreshState: {\n ..._state.refreshState,\n errors: pushErrorFilterDuplicates(_state.refreshState.errors, {\n id: _state.nextId,\n event: action,\n }),\n },\n }\n }\n default:\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _: never = _state.refreshState\n return _state\n }\n }\n case ACTION_VERSION_INFO: {\n return { ..._state, versionInfo: action.versionInfo }\n }\n case ACTION_DEV_INDICATOR: {\n return {\n ..._state,\n disableDevIndicator:\n shouldDisableDevIndicator || !!action.devIndicator.disabledUntil,\n }\n }\n default: {\n return _state\n }\n }\n }, getInitialState(routerType))\n}\n\nexport const REACT_REFRESH_FULL_RELOAD_FROM_ERROR =\n '[Fast Refresh] performing full reload because your application had an unrecoverable error'\n"],"names":["process","useReducer","ACTION_STATIC_INDICATOR","ACTION_BUILD_OK","ACTION_BUILD_ERROR","ACTION_BEFORE_REFRESH","ACTION_REFRESH","ACTION_VERSION_INFO","ACTION_UNHANDLED_ERROR","ACTION_UNHANDLED_REJECTION","ACTION_DEBUG_INFO","ACTION_DEV_INDICATOR","pushErrorFilterDuplicates","errors","err","filter","e","event","reason","stack","shouldDisableDevIndicator","env","__NEXT_DEV_INDICATOR","toString","INITIAL_OVERLAY_STATE","nextId","buildError","notFound","staticIndicator","disableDevIndicator","refreshState","type","rootLayoutMissingTags","versionInfo","installed","staleness","debugInfo","devtoolsFrontendUrl","undefined","getInitialState","routerType","useErrorOverlayReducer","_state","action","message","id","_","devIndicator","disabledUntil","REACT_REFRESH_FULL_RELOAD_FROM_ERROR"],"mappings":"IAiHEA;AAjHF,SAASC,UAAU,QAAQ,QAAO;AA6BlC,OAAO,MAAMC,0BAA0B,mBAAkB;AACzD,OAAO,MAAMC,kBAAkB,WAAU;AACzC,OAAO,MAAMC,qBAAqB,cAAa;AAC/C,OAAO,MAAMC,wBAAwB,sBAAqB;AAC1D,OAAO,MAAMC,iBAAiB,eAAc;AAC5C,OAAO,MAAMC,sBAAsB,eAAc;AACjD,OAAO,MAAMC,yBAAyB,kBAAiB;AACvD,OAAO,MAAMC,6BAA6B,sBAAqB;AAC/D,OAAO,MAAMC,oBAAoB,aAAY;AAC7C,OAAO,MAAMC,uBAAuB,gBAAe;AA6DnD,SAASC,0BACPC,MAA6B,EAC7BC,GAAwB;IAExB,OAAO;WACFD,OAAOE,MAAM,CAAC,CAACC;YAChB,8BAA8B;YAC9B,OAAOA,EAAEC,KAAK,CAACC,MAAM,CAACC,KAAK,KAAKL,IAAIG,KAAK,CAACC,MAAM,CAACC,KAAK;QACxD;QACAL;KACD;AACH;AAEA,MAAMM,4BACJpB,EAAAA,oCAAAA,QAAQqB,GAAG,CAACC,oBAAoB,qBAAhCtB,kCAAkCuB,QAAQ,QAAO;AAEnD,OAAO,MAAMC,wBAA0D;IACrEC,QAAQ;IACRC,YAAY;IACZb,QAAQ,EAAE;IACVc,UAAU;IACVC,iBAAiB;IACjB,4DAA4D;IAC5DC,qBAAqB;IACrBC,cAAc;QAAEC,MAAM;IAAO;IAC7BC,uBAAuB,EAAE;IACzBC,aAAa;QAAEC,WAAW;QAASC,WAAW;IAAU;IACxDC,WAAW;QAAEC,qBAAqBC;IAAU;AAC9C,EAAC;AAED,SAASC,gBACPC,UAA2B;IAE3B,OAAO;QACL,GAAGhB,qBAAqB;QACxBgB;IACF;AACF;AAEA,OAAO,SAASC,uBAAuBD,UAA2B;IAChE,OAAOvC,WAAW,CAACyC,QAAsBC;QACvC,OAAQA,OAAOZ,IAAI;YACjB,KAAKrB;gBAAmB;oBACtB,OAAO;wBAAE,GAAGgC,MAAM;wBAAEN,WAAWO,OAAOP,SAAS;oBAAC;gBAClD;YACA,KAAKlC;gBAAyB;oBAC5B,OAAO;wBAAE,GAAGwC,MAAM;wBAAEd,iBAAiBe,OAAOf,eAAe;oBAAC;gBAC9D;YACA,KAAKzB;gBAAiB;oBACpB,OAAO;wBAAE,GAAGuC,MAAM;wBAAEhB,YAAY;oBAAK;gBACvC;YACA,KAAKtB;gBAAoB;oBACvB,OAAO;wBAAE,GAAGsC,MAAM;wBAAEhB,YAAYiB,OAAOC,OAAO;oBAAC;gBACjD;YACA,KAAKvC;gBAAuB;oBAC1B,OAAO;wBAAE,GAAGqC,MAAM;wBAAEZ,cAAc;4BAAEC,MAAM;4BAAWlB,QAAQ,EAAE;wBAAC;oBAAE;gBACpE;YACA,KAAKP;gBAAgB;oBACnB,OAAO;wBACL,GAAGoC,MAAM;wBACThB,YAAY;wBACZb,QACE,mEAAmE;wBACnE,iEAAiE;wBACjE,qEAAqE;wBACrE,8DAA8D;wBAC9D,sEAAsE;wBACtE,gCAAgC;wBAChC6B,OAAOZ,YAAY,CAACC,IAAI,KAAK,YACzBW,OAAOZ,YAAY,CAACjB,MAAM,GAC1B,EAAE;wBACRiB,cAAc;4BAAEC,MAAM;wBAAO;oBAC/B;gBACF;YACA,KAAKvB;YACL,KAAKC;gBAA4B;oBAC/B,OAAQiC,OAAOZ,YAAY,CAACC,IAAI;wBAC9B,KAAK;4BAAQ;gCACX,OAAO;oCACL,GAAGW,MAAM;oCACTjB,QAAQiB,OAAOjB,MAAM,GAAG;oCACxBZ,QAAQD,0BAA0B8B,OAAO7B,MAAM,EAAE;wCAC/CgC,IAAIH,OAAOjB,MAAM;wCACjBR,OAAO0B;oCACT;gCACF;4BACF;wBACA,KAAK;4BAAW;gCACd,OAAO;oCACL,GAAGD,MAAM;oCACTjB,QAAQiB,OAAOjB,MAAM,GAAG;oCACxBK,cAAc;wCACZ,GAAGY,OAAOZ,YAAY;wCACtBjB,QAAQD,0BAA0B8B,OAAOZ,YAAY,CAACjB,MAAM,EAAE;4CAC5DgC,IAAIH,OAAOjB,MAAM;4CACjBR,OAAO0B;wCACT;oCACF;gCACF;4BACF;wBACA;4BACE,6DAA6D;4BAC7D,MAAMG,IAAWJ,OAAOZ,YAAY;4BACpC,OAAOY;oBACX;gBACF;YACA,KAAKnC;gBAAqB;oBACxB,OAAO;wBAAE,GAAGmC,MAAM;wBAAET,aAAaU,OAAOV,WAAW;oBAAC;gBACtD;YACA,KAAKtB;gBAAsB;oBACzB,OAAO;wBACL,GAAG+B,MAAM;wBACTb,qBACET,6BAA6B,CAAC,CAACuB,OAAOI,YAAY,CAACC,aAAa;oBACpE;gBACF;YACA;gBAAS;oBACP,OAAON;gBACT;QACF;IACF,GAAGH,gBAAgBC;AACrB;AAEA,OAAO,MAAMS,uCACX,4FAA2F"}
1
+ {"version":3,"sources":["../../../../src/client/components/react-dev-overlay/shared.ts"],"sourcesContent":["import { useReducer } from 'react'\n\nimport type { StackFrame } from 'next/dist/compiled/stacktrace-parser'\nimport type { VersionInfo } from '../../../server/dev/parse-version-info'\nimport type { SupportedErrorEvent } from './ui/container/runtime-error/render-error'\nimport type { ComponentStackFrame } from './utils/parse-component-stack'\nimport type { DebugInfo } from './types'\nimport type { DevIndicatorServerState } from '../../../server/dev/dev-indicator-server-state'\n\ntype FastRefreshState =\n /** No refresh in progress. */\n | { type: 'idle' }\n /** The refresh process has been triggered, but the new code has not been executed yet. */\n | { type: 'pending'; errors: SupportedErrorEvent[] }\n\nexport interface OverlayState {\n nextId: number\n buildError: string | null\n errors: SupportedErrorEvent[]\n refreshState: FastRefreshState\n rootLayoutMissingTags: typeof window.__next_root_layout_missing_tags\n versionInfo: VersionInfo\n notFound: boolean\n staticIndicator: boolean\n disableDevIndicator: boolean\n debugInfo: DebugInfo\n routerType: 'pages' | 'app'\n}\n\nexport const ACTION_STATIC_INDICATOR = 'static-indicator'\nexport const ACTION_BUILD_OK = 'build-ok'\nexport const ACTION_BUILD_ERROR = 'build-error'\nexport const ACTION_BEFORE_REFRESH = 'before-fast-refresh'\nexport const ACTION_REFRESH = 'fast-refresh'\nexport const ACTION_VERSION_INFO = 'version-info'\nexport const ACTION_UNHANDLED_ERROR = 'unhandled-error'\nexport const ACTION_UNHANDLED_REJECTION = 'unhandled-rejection'\nexport const ACTION_DEBUG_INFO = 'debug-info'\nexport const ACTION_DEV_INDICATOR = 'dev-indicator'\n\nexport const STORAGE_KEY_THEME = '__nextjs-dev-tools-theme'\nexport const STORAGE_KEY_POSITION = '__nextjs-dev-tools-position'\n\ninterface StaticIndicatorAction {\n type: typeof ACTION_STATIC_INDICATOR\n staticIndicator: boolean\n}\n\ninterface BuildOkAction {\n type: typeof ACTION_BUILD_OK\n}\ninterface BuildErrorAction {\n type: typeof ACTION_BUILD_ERROR\n message: string\n}\ninterface BeforeFastRefreshAction {\n type: typeof ACTION_BEFORE_REFRESH\n}\ninterface FastRefreshAction {\n type: typeof ACTION_REFRESH\n}\n\nexport interface UnhandledErrorAction {\n type: typeof ACTION_UNHANDLED_ERROR\n reason: Error\n frames: StackFrame[]\n componentStackFrames?: ComponentStackFrame[]\n warning?: [string, string, string]\n}\nexport interface UnhandledRejectionAction {\n type: typeof ACTION_UNHANDLED_REJECTION\n reason: Error\n frames: StackFrame[]\n}\n\nexport interface DebugInfoAction {\n type: typeof ACTION_DEBUG_INFO\n debugInfo: any\n}\n\ninterface VersionInfoAction {\n type: typeof ACTION_VERSION_INFO\n versionInfo: VersionInfo\n}\n\ninterface DevIndicatorAction {\n type: typeof ACTION_DEV_INDICATOR\n devIndicator: DevIndicatorServerState\n}\n\nexport type BusEvent =\n | BuildOkAction\n | BuildErrorAction\n | BeforeFastRefreshAction\n | FastRefreshAction\n | UnhandledErrorAction\n | UnhandledRejectionAction\n | VersionInfoAction\n | StaticIndicatorAction\n | DebugInfoAction\n | DevIndicatorAction\n\nfunction pushErrorFilterDuplicates(\n errors: SupportedErrorEvent[],\n err: SupportedErrorEvent\n): SupportedErrorEvent[] {\n return [\n ...errors.filter((e) => {\n // Filter out duplicate errors\n return e.event.reason.stack !== err.event.reason.stack\n }),\n err,\n ]\n}\n\nconst shouldDisableDevIndicator =\n process.env.__NEXT_DEV_INDICATOR?.toString() === 'false'\n\nexport const INITIAL_OVERLAY_STATE: Omit<OverlayState, 'routerType'> = {\n nextId: 1,\n buildError: null,\n errors: [],\n notFound: false,\n staticIndicator: false,\n // To prevent flickering, set the initial state to disabled.\n disableDevIndicator: true,\n refreshState: { type: 'idle' },\n rootLayoutMissingTags: [],\n versionInfo: { installed: '0.0.0', staleness: 'unknown' },\n debugInfo: { devtoolsFrontendUrl: undefined },\n}\n\nfunction getInitialState(\n routerType: 'pages' | 'app'\n): OverlayState & { routerType: 'pages' | 'app' } {\n return {\n ...INITIAL_OVERLAY_STATE,\n routerType,\n }\n}\n\nexport function useErrorOverlayReducer(routerType: 'pages' | 'app') {\n return useReducer((_state: OverlayState, action: BusEvent): OverlayState => {\n switch (action.type) {\n case ACTION_DEBUG_INFO: {\n return { ..._state, debugInfo: action.debugInfo }\n }\n case ACTION_STATIC_INDICATOR: {\n return { ..._state, staticIndicator: action.staticIndicator }\n }\n case ACTION_BUILD_OK: {\n return { ..._state, buildError: null }\n }\n case ACTION_BUILD_ERROR: {\n return { ..._state, buildError: action.message }\n }\n case ACTION_BEFORE_REFRESH: {\n return { ..._state, refreshState: { type: 'pending', errors: [] } }\n }\n case ACTION_REFRESH: {\n return {\n ..._state,\n buildError: null,\n errors:\n // Errors can come in during updates. In this case, UNHANDLED_ERROR\n // and UNHANDLED_REJECTION events might be dispatched between the\n // BEFORE_REFRESH and the REFRESH event. We want to keep those errors\n // around until the next refresh. Otherwise we run into a race\n // condition where those errors would be cleared on refresh completion\n // before they can be displayed.\n _state.refreshState.type === 'pending'\n ? _state.refreshState.errors\n : [],\n refreshState: { type: 'idle' },\n }\n }\n case ACTION_UNHANDLED_ERROR:\n case ACTION_UNHANDLED_REJECTION: {\n switch (_state.refreshState.type) {\n case 'idle': {\n return {\n ..._state,\n nextId: _state.nextId + 1,\n errors: pushErrorFilterDuplicates(_state.errors, {\n id: _state.nextId,\n event: action,\n }),\n }\n }\n case 'pending': {\n return {\n ..._state,\n nextId: _state.nextId + 1,\n refreshState: {\n ..._state.refreshState,\n errors: pushErrorFilterDuplicates(_state.refreshState.errors, {\n id: _state.nextId,\n event: action,\n }),\n },\n }\n }\n default:\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n const _: never = _state.refreshState\n return _state\n }\n }\n case ACTION_VERSION_INFO: {\n return { ..._state, versionInfo: action.versionInfo }\n }\n case ACTION_DEV_INDICATOR: {\n return {\n ..._state,\n disableDevIndicator:\n shouldDisableDevIndicator || !!action.devIndicator.disabledUntil,\n }\n }\n default: {\n return _state\n }\n }\n }, getInitialState(routerType))\n}\n\nexport const REACT_REFRESH_FULL_RELOAD_FROM_ERROR =\n '[Fast Refresh] performing full reload because your application had an unrecoverable error'\n"],"names":["process","useReducer","ACTION_STATIC_INDICATOR","ACTION_BUILD_OK","ACTION_BUILD_ERROR","ACTION_BEFORE_REFRESH","ACTION_REFRESH","ACTION_VERSION_INFO","ACTION_UNHANDLED_ERROR","ACTION_UNHANDLED_REJECTION","ACTION_DEBUG_INFO","ACTION_DEV_INDICATOR","STORAGE_KEY_THEME","STORAGE_KEY_POSITION","pushErrorFilterDuplicates","errors","err","filter","e","event","reason","stack","shouldDisableDevIndicator","env","__NEXT_DEV_INDICATOR","toString","INITIAL_OVERLAY_STATE","nextId","buildError","notFound","staticIndicator","disableDevIndicator","refreshState","type","rootLayoutMissingTags","versionInfo","installed","staleness","debugInfo","devtoolsFrontendUrl","undefined","getInitialState","routerType","useErrorOverlayReducer","_state","action","message","id","_","devIndicator","disabledUntil","REACT_REFRESH_FULL_RELOAD_FROM_ERROR"],"mappings":"IAoHEA;AApHF,SAASC,UAAU,QAAQ,QAAO;AA6BlC,OAAO,MAAMC,0BAA0B,mBAAkB;AACzD,OAAO,MAAMC,kBAAkB,WAAU;AACzC,OAAO,MAAMC,qBAAqB,cAAa;AAC/C,OAAO,MAAMC,wBAAwB,sBAAqB;AAC1D,OAAO,MAAMC,iBAAiB,eAAc;AAC5C,OAAO,MAAMC,sBAAsB,eAAc;AACjD,OAAO,MAAMC,yBAAyB,kBAAiB;AACvD,OAAO,MAAMC,6BAA6B,sBAAqB;AAC/D,OAAO,MAAMC,oBAAoB,aAAY;AAC7C,OAAO,MAAMC,uBAAuB,gBAAe;AAEnD,OAAO,MAAMC,oBAAoB,2BAA0B;AAC3D,OAAO,MAAMC,uBAAuB,8BAA6B;AA6DjE,SAASC,0BACPC,MAA6B,EAC7BC,GAAwB;IAExB,OAAO;WACFD,OAAOE,MAAM,CAAC,CAACC;YAChB,8BAA8B;YAC9B,OAAOA,EAAEC,KAAK,CAACC,MAAM,CAACC,KAAK,KAAKL,IAAIG,KAAK,CAACC,MAAM,CAACC,KAAK;QACxD;QACAL;KACD;AACH;AAEA,MAAMM,4BACJtB,EAAAA,oCAAAA,QAAQuB,GAAG,CAACC,oBAAoB,qBAAhCxB,kCAAkCyB,QAAQ,QAAO;AAEnD,OAAO,MAAMC,wBAA0D;IACrEC,QAAQ;IACRC,YAAY;IACZb,QAAQ,EAAE;IACVc,UAAU;IACVC,iBAAiB;IACjB,4DAA4D;IAC5DC,qBAAqB;IACrBC,cAAc;QAAEC,MAAM;IAAO;IAC7BC,uBAAuB,EAAE;IACzBC,aAAa;QAAEC,WAAW;QAASC,WAAW;IAAU;IACxDC,WAAW;QAAEC,qBAAqBC;IAAU;AAC9C,EAAC;AAED,SAASC,gBACPC,UAA2B;IAE3B,OAAO;QACL,GAAGhB,qBAAqB;QACxBgB;IACF;AACF;AAEA,OAAO,SAASC,uBAAuBD,UAA2B;IAChE,OAAOzC,WAAW,CAAC2C,QAAsBC;QACvC,OAAQA,OAAOZ,IAAI;YACjB,KAAKvB;gBAAmB;oBACtB,OAAO;wBAAE,GAAGkC,MAAM;wBAAEN,WAAWO,OAAOP,SAAS;oBAAC;gBAClD;YACA,KAAKpC;gBAAyB;oBAC5B,OAAO;wBAAE,GAAG0C,MAAM;wBAAEd,iBAAiBe,OAAOf,eAAe;oBAAC;gBAC9D;YACA,KAAK3B;gBAAiB;oBACpB,OAAO;wBAAE,GAAGyC,MAAM;wBAAEhB,YAAY;oBAAK;gBACvC;YACA,KAAKxB;gBAAoB;oBACvB,OAAO;wBAAE,GAAGwC,MAAM;wBAAEhB,YAAYiB,OAAOC,OAAO;oBAAC;gBACjD;YACA,KAAKzC;gBAAuB;oBAC1B,OAAO;wBAAE,GAAGuC,MAAM;wBAAEZ,cAAc;4BAAEC,MAAM;4BAAWlB,QAAQ,EAAE;wBAAC;oBAAE;gBACpE;YACA,KAAKT;gBAAgB;oBACnB,OAAO;wBACL,GAAGsC,MAAM;wBACThB,YAAY;wBACZb,QACE,mEAAmE;wBACnE,iEAAiE;wBACjE,qEAAqE;wBACrE,8DAA8D;wBAC9D,sEAAsE;wBACtE,gCAAgC;wBAChC6B,OAAOZ,YAAY,CAACC,IAAI,KAAK,YACzBW,OAAOZ,YAAY,CAACjB,MAAM,GAC1B,EAAE;wBACRiB,cAAc;4BAAEC,MAAM;wBAAO;oBAC/B;gBACF;YACA,KAAKzB;YACL,KAAKC;gBAA4B;oBAC/B,OAAQmC,OAAOZ,YAAY,CAACC,IAAI;wBAC9B,KAAK;4BAAQ;gCACX,OAAO;oCACL,GAAGW,MAAM;oCACTjB,QAAQiB,OAAOjB,MAAM,GAAG;oCACxBZ,QAAQD,0BAA0B8B,OAAO7B,MAAM,EAAE;wCAC/CgC,IAAIH,OAAOjB,MAAM;wCACjBR,OAAO0B;oCACT;gCACF;4BACF;wBACA,KAAK;4BAAW;gCACd,OAAO;oCACL,GAAGD,MAAM;oCACTjB,QAAQiB,OAAOjB,MAAM,GAAG;oCACxBK,cAAc;wCACZ,GAAGY,OAAOZ,YAAY;wCACtBjB,QAAQD,0BAA0B8B,OAAOZ,YAAY,CAACjB,MAAM,EAAE;4CAC5DgC,IAAIH,OAAOjB,MAAM;4CACjBR,OAAO0B;wCACT;oCACF;gCACF;4BACF;wBACA;4BACE,6DAA6D;4BAC7D,MAAMG,IAAWJ,OAAOZ,YAAY;4BACpC,OAAOY;oBACX;gBACF;YACA,KAAKrC;gBAAqB;oBACxB,OAAO;wBAAE,GAAGqC,MAAM;wBAAET,aAAaU,OAAOV,WAAW;oBAAC;gBACtD;YACA,KAAKxB;gBAAsB;oBACzB,OAAO;wBACL,GAAGiC,MAAM;wBACTb,qBACET,6BAA6B,CAAC,CAACuB,OAAOI,YAAY,CAACC,aAAa;oBACpE;gBACF;YACA;gBAAS;oBACP,OAAON;gBACT;QACF;IACF,GAAGH,gBAAgBC;AACrB;AAEA,OAAO,MAAMS,uCACX,4FAA2F"}
@@ -1,13 +1,12 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { HotlinkedText } from '../hot-linked-text';
3
- import { ExternalIcon } from '../../icons/external';
3
+ import { ExternalIcon, SourceMappingErrorIcon } from '../../icons/external';
4
4
  import { getFrameSource } from '../../../utils/stack-frame';
5
5
  import { useOpenInEditor } from '../../utils/use-open-in-editor';
6
6
  export const CallStackFrame = function CallStackFrame(param) {
7
7
  let { frame, index } = param;
8
8
  var _frame_originalStackFrame;
9
9
  // TODO: ability to expand resolved frames
10
- // TODO: render error or external indicator
11
10
  const f = (_frame_originalStackFrame = frame.originalStackFrame) != null ? _frame_originalStackFrame : frame.sourceStackFrame;
12
11
  const hasSource = Boolean(frame.originalCodeFrame);
13
12
  const open = useOpenInEditor(hasSource ? {
@@ -45,7 +44,16 @@ export const CallStackFrame = function CallStackFrame(param) {
45
44
  width: 16,
46
45
  height: 16
47
46
  })
48
- })
47
+ }),
48
+ frame.error ? /*#__PURE__*/ _jsx("button", {
49
+ className: "source-mapping-error-button",
50
+ onClick: ()=>console.error(frame.reason),
51
+ title: "Sourcemapping failed. Click to log cause of error.",
52
+ children: /*#__PURE__*/ _jsx(SourceMappingErrorIcon, {
53
+ width: 16,
54
+ height: 16
55
+ })
56
+ }) : null
49
57
  ]
50
58
  }),
51
59
  /*#__PURE__*/ _jsx("span", {
@@ -56,6 +64,6 @@ export const CallStackFrame = function CallStackFrame(param) {
56
64
  ]
57
65
  });
58
66
  };
59
- export const CALL_STACK_FRAME_STYLES = "\n [data-nextjs-call-stack-frame-ignored] {\n padding: 6px 8px;\n margin-bottom: 4px;\n\n border-radius: var(--rounded-lg);\n }\n\n [data-nextjs-call-stack-frame-ignored]:last-child {\n margin-bottom: 0;\n }\n\n [data-nextjs-call-stack-frame] {\n user-select: text;\n display: block;\n box-sizing: border-box;\n\n user-select: text;\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n\n padding: 6px 8px;\n\n border-radius: var(--rounded-lg);\n }\n\n .call-stack-frame-method-name {\n display: flex;\n align-items: center;\n gap: 4px;\n\n margin-bottom: 4px;\n font-family: var(--font-stack-monospace);\n\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n\n svg {\n width: var(--size-16px);\n height: var(--size-16px);\n }\n }\n\n .open-in-editor-button {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rounded-full);\n padding: 4px;\n color: var(--color-font);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .call-stack-frame-file-source {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n }\n";
67
+ export const CALL_STACK_FRAME_STYLES = "\n [data-nextjs-call-stack-frame-ignored] {\n padding: 6px 8px;\n margin-bottom: 4px;\n\n border-radius: var(--rounded-lg);\n }\n\n [data-nextjs-call-stack-frame-ignored]:last-child {\n margin-bottom: 0;\n }\n\n [data-nextjs-call-stack-frame] {\n user-select: text;\n display: block;\n box-sizing: border-box;\n\n user-select: text;\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n\n padding: 6px 8px;\n\n border-radius: var(--rounded-lg);\n }\n\n .call-stack-frame-method-name {\n display: flex;\n align-items: center;\n gap: 4px;\n\n margin-bottom: 4px;\n font-family: var(--font-stack-monospace);\n\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n\n svg {\n width: var(--size-16px);\n height: var(--size-16px);\n }\n }\n\n .open-in-editor-button, .source-mapping-error-button {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rounded-full);\n padding: 4px;\n color: var(--color-font);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .call-stack-frame-file-source {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n }\n";
60
68
 
61
69
  //# sourceMappingURL=call-stack-frame.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.tsx"],"sourcesContent":["import type { StackFrame } from 'next/dist/compiled/stacktrace-parser'\nimport type { OriginalStackFrame } from '../../../utils/stack-frame'\n\nimport { HotlinkedText } from '../hot-linked-text'\nimport { ExternalIcon } from '../../icons/external'\nimport { getFrameSource } from '../../../utils/stack-frame'\nimport { useOpenInEditor } from '../../utils/use-open-in-editor'\n\nexport const CallStackFrame: React.FC<{\n frame: OriginalStackFrame\n index: number\n}> = function CallStackFrame({ frame, index }) {\n // TODO: ability to expand resolved frames\n // TODO: render error or external indicator\n\n const f: StackFrame = frame.originalStackFrame ?? frame.sourceStackFrame\n const hasSource = Boolean(frame.originalCodeFrame)\n const open = useOpenInEditor(\n hasSource\n ? {\n file: f.file,\n lineNumber: f.lineNumber,\n column: f.column,\n }\n : undefined\n )\n\n // Format method to strip out the webpack layer prefix.\n // e.g. (app-pages-browser)/./app/page.tsx -> ./app/page.tsx\n const formattedMethod = f.methodName.replace(/^\\([\\w-]+\\)\\//, '')\n\n // Formatted file source could be empty. e.g. <anonymous> will be formatted to empty string,\n // we'll skip rendering the frame in this case.\n const fileSource = getFrameSource(f)\n\n if (!fileSource) {\n return null\n }\n\n return (\n <div\n data-nextjs-call-stack-frame\n data-nextjs-call-stack-frame-ignored={!hasSource}\n style={\n {\n '--index': index,\n } as React.CSSProperties\n }\n >\n <div\n data-nextjs-frame-expanded={!frame.ignored}\n className=\"call-stack-frame-method-name\"\n >\n <HotlinkedText text={formattedMethod} />\n {hasSource && (\n <button onClick={open} className=\"open-in-editor-button\">\n <ExternalIcon width={16} height={16} />\n </button>\n )}\n </div>\n <span\n className=\"call-stack-frame-file-source\"\n data-has-source={hasSource}\n >\n {fileSource}\n </span>\n </div>\n )\n}\n\nexport const CALL_STACK_FRAME_STYLES = `\n [data-nextjs-call-stack-frame-ignored] {\n padding: 6px 8px;\n margin-bottom: 4px;\n\n border-radius: var(--rounded-lg);\n }\n\n [data-nextjs-call-stack-frame-ignored]:last-child {\n margin-bottom: 0;\n }\n\n [data-nextjs-call-stack-frame] {\n user-select: text;\n display: block;\n box-sizing: border-box;\n\n user-select: text;\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n\n padding: 6px 8px;\n\n border-radius: var(--rounded-lg);\n }\n\n .call-stack-frame-method-name {\n display: flex;\n align-items: center;\n gap: 4px;\n\n margin-bottom: 4px;\n font-family: var(--font-stack-monospace);\n\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n\n svg {\n width: var(--size-16px);\n height: var(--size-16px);\n }\n }\n\n .open-in-editor-button {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rounded-full);\n padding: 4px;\n color: var(--color-font);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .call-stack-frame-file-source {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n }\n`\n"],"names":["HotlinkedText","ExternalIcon","getFrameSource","useOpenInEditor","CallStackFrame","frame","index","f","originalStackFrame","sourceStackFrame","hasSource","Boolean","originalCodeFrame","open","file","lineNumber","column","undefined","formattedMethod","methodName","replace","fileSource","div","data-nextjs-call-stack-frame","data-nextjs-call-stack-frame-ignored","style","data-nextjs-frame-expanded","ignored","className","text","button","onClick","width","height","span","data-has-source","CALL_STACK_FRAME_STYLES"],"mappings":";AAGA,SAASA,aAAa,QAAQ,qBAAoB;AAClD,SAASC,YAAY,QAAQ,uBAAsB;AACnD,SAASC,cAAc,QAAQ,6BAA4B;AAC3D,SAASC,eAAe,QAAQ,iCAAgC;AAEhE,OAAO,MAAMC,iBAGR,SAASA,eAAe,KAAgB;IAAhB,IAAA,EAAEC,KAAK,EAAEC,KAAK,EAAE,GAAhB;QAILD;IAHtB,0CAA0C;IAC1C,2CAA2C;IAE3C,MAAME,IAAgBF,CAAAA,4BAAAA,MAAMG,kBAAkB,YAAxBH,4BAA4BA,MAAMI,gBAAgB;IACxE,MAAMC,YAAYC,QAAQN,MAAMO,iBAAiB;IACjD,MAAMC,OAAOV,gBACXO,YACI;QACEI,MAAMP,EAAEO,IAAI;QACZC,YAAYR,EAAEQ,UAAU;QACxBC,QAAQT,EAAES,MAAM;IAClB,IACAC;IAGN,uDAAuD;IACvD,4DAA4D;IAC5D,MAAMC,kBAAkBX,EAAEY,UAAU,CAACC,OAAO,CAAC,iBAAiB;IAE9D,4FAA4F;IAC5F,+CAA+C;IAC/C,MAAMC,aAAanB,eAAeK;IAElC,IAAI,CAACc,YAAY;QACf,OAAO;IACT;IAEA,qBACE,MAACC;QACCC,8BAA4B;QAC5BC,wCAAsC,CAACd;QACvCe,OACE;YACE,WAAWnB;QACb;;0BAGF,MAACgB;gBACCI,8BAA4B,CAACrB,MAAMsB,OAAO;gBAC1CC,WAAU;;kCAEV,KAAC5B;wBAAc6B,MAAMX;;oBACpBR,2BACC,KAACoB;wBAAOC,SAASlB;wBAAMe,WAAU;kCAC/B,cAAA,KAAC3B;4BAAa+B,OAAO;4BAAIC,QAAQ;;;;;0BAIvC,KAACC;gBACCN,WAAU;gBACVO,mBAAiBzB;0BAEhBW;;;;AAIT,EAAC;AAED,OAAO,MAAMe,0BAA2B,+9CA0EvC"}
1
+ {"version":3,"sources":["../../../../../../../src/client/components/react-dev-overlay/ui/components/call-stack-frame/call-stack-frame.tsx"],"sourcesContent":["import type { StackFrame } from 'next/dist/compiled/stacktrace-parser'\nimport type { OriginalStackFrame } from '../../../utils/stack-frame'\n\nimport { HotlinkedText } from '../hot-linked-text'\nimport { ExternalIcon, SourceMappingErrorIcon } from '../../icons/external'\nimport { getFrameSource } from '../../../utils/stack-frame'\nimport { useOpenInEditor } from '../../utils/use-open-in-editor'\n\nexport const CallStackFrame: React.FC<{\n frame: OriginalStackFrame\n index: number\n}> = function CallStackFrame({ frame, index }) {\n // TODO: ability to expand resolved frames\n\n const f: StackFrame = frame.originalStackFrame ?? frame.sourceStackFrame\n const hasSource = Boolean(frame.originalCodeFrame)\n const open = useOpenInEditor(\n hasSource\n ? {\n file: f.file,\n lineNumber: f.lineNumber,\n column: f.column,\n }\n : undefined\n )\n\n // Format method to strip out the webpack layer prefix.\n // e.g. (app-pages-browser)/./app/page.tsx -> ./app/page.tsx\n const formattedMethod = f.methodName.replace(/^\\([\\w-]+\\)\\//, '')\n\n // Formatted file source could be empty. e.g. <anonymous> will be formatted to empty string,\n // we'll skip rendering the frame in this case.\n const fileSource = getFrameSource(f)\n\n if (!fileSource) {\n return null\n }\n\n return (\n <div\n data-nextjs-call-stack-frame\n data-nextjs-call-stack-frame-ignored={!hasSource}\n style={\n {\n '--index': index,\n } as React.CSSProperties\n }\n >\n <div\n data-nextjs-frame-expanded={!frame.ignored}\n className=\"call-stack-frame-method-name\"\n >\n <HotlinkedText text={formattedMethod} />\n {hasSource && (\n <button onClick={open} className=\"open-in-editor-button\">\n <ExternalIcon width={16} height={16} />\n </button>\n )}\n {frame.error ? (\n <button\n className=\"source-mapping-error-button\"\n onClick={() => console.error(frame.reason)}\n title=\"Sourcemapping failed. Click to log cause of error.\"\n >\n <SourceMappingErrorIcon width={16} height={16} />\n </button>\n ) : null}\n </div>\n <span\n className=\"call-stack-frame-file-source\"\n data-has-source={hasSource}\n >\n {fileSource}\n </span>\n </div>\n )\n}\n\nexport const CALL_STACK_FRAME_STYLES = `\n [data-nextjs-call-stack-frame-ignored] {\n padding: 6px 8px;\n margin-bottom: 4px;\n\n border-radius: var(--rounded-lg);\n }\n\n [data-nextjs-call-stack-frame-ignored]:last-child {\n margin-bottom: 0;\n }\n\n [data-nextjs-call-stack-frame] {\n user-select: text;\n display: block;\n box-sizing: border-box;\n\n user-select: text;\n -webkit-user-select: text;\n -moz-user-select: text;\n -ms-user-select: text;\n\n padding: 6px 8px;\n\n border-radius: var(--rounded-lg);\n }\n\n .call-stack-frame-method-name {\n display: flex;\n align-items: center;\n gap: 4px;\n\n margin-bottom: 4px;\n font-family: var(--font-stack-monospace);\n\n color: var(--color-gray-1000);\n font-size: var(--size-14);\n font-weight: 500;\n line-height: var(--size-20);\n\n svg {\n width: var(--size-16px);\n height: var(--size-16px);\n }\n }\n\n .open-in-editor-button, .source-mapping-error-button {\n display: flex;\n align-items: center;\n justify-content: center;\n border-radius: var(--rounded-full);\n padding: 4px;\n color: var(--color-font);\n\n svg {\n width: var(--size-16);\n height: var(--size-16);\n }\n\n &:focus-visible {\n outline: var(--focus-ring);\n outline-offset: -2px;\n }\n\n &:hover {\n background: var(--color-gray-100);\n }\n }\n\n .call-stack-frame-file-source {\n color: var(--color-gray-900);\n font-size: var(--size-14);\n line-height: var(--size-20);\n }\n`\n"],"names":["HotlinkedText","ExternalIcon","SourceMappingErrorIcon","getFrameSource","useOpenInEditor","CallStackFrame","frame","index","f","originalStackFrame","sourceStackFrame","hasSource","Boolean","originalCodeFrame","open","file","lineNumber","column","undefined","formattedMethod","methodName","replace","fileSource","div","data-nextjs-call-stack-frame","data-nextjs-call-stack-frame-ignored","style","data-nextjs-frame-expanded","ignored","className","text","button","onClick","width","height","error","console","reason","title","span","data-has-source","CALL_STACK_FRAME_STYLES"],"mappings":";AAGA,SAASA,aAAa,QAAQ,qBAAoB;AAClD,SAASC,YAAY,EAAEC,sBAAsB,QAAQ,uBAAsB;AAC3E,SAASC,cAAc,QAAQ,6BAA4B;AAC3D,SAASC,eAAe,QAAQ,iCAAgC;AAEhE,OAAO,MAAMC,iBAGR,SAASA,eAAe,KAAgB;IAAhB,IAAA,EAAEC,KAAK,EAAEC,KAAK,EAAE,GAAhB;QAGLD;IAFtB,0CAA0C;IAE1C,MAAME,IAAgBF,CAAAA,4BAAAA,MAAMG,kBAAkB,YAAxBH,4BAA4BA,MAAMI,gBAAgB;IACxE,MAAMC,YAAYC,QAAQN,MAAMO,iBAAiB;IACjD,MAAMC,OAAOV,gBACXO,YACI;QACEI,MAAMP,EAAEO,IAAI;QACZC,YAAYR,EAAEQ,UAAU;QACxBC,QAAQT,EAAES,MAAM;IAClB,IACAC;IAGN,uDAAuD;IACvD,4DAA4D;IAC5D,MAAMC,kBAAkBX,EAAEY,UAAU,CAACC,OAAO,CAAC,iBAAiB;IAE9D,4FAA4F;IAC5F,+CAA+C;IAC/C,MAAMC,aAAanB,eAAeK;IAElC,IAAI,CAACc,YAAY;QACf,OAAO;IACT;IAEA,qBACE,MAACC;QACCC,8BAA4B;QAC5BC,wCAAsC,CAACd;QACvCe,OACE;YACE,WAAWnB;QACb;;0BAGF,MAACgB;gBACCI,8BAA4B,CAACrB,MAAMsB,OAAO;gBAC1CC,WAAU;;kCAEV,KAAC7B;wBAAc8B,MAAMX;;oBACpBR,2BACC,KAACoB;wBAAOC,SAASlB;wBAAMe,WAAU;kCAC/B,cAAA,KAAC5B;4BAAagC,OAAO;4BAAIC,QAAQ;;;oBAGpC5B,MAAM6B,KAAK,iBACV,KAACJ;wBACCF,WAAU;wBACVG,SAAS,IAAMI,QAAQD,KAAK,CAAC7B,MAAM+B,MAAM;wBACzCC,OAAM;kCAEN,cAAA,KAACpC;4BAAuB+B,OAAO;4BAAIC,QAAQ;;yBAE3C;;;0BAEN,KAACK;gBACCV,WAAU;gBACVW,mBAAiB7B;0BAEhBW;;;;AAIT,EAAC;AAED,OAAO,MAAMmB,0BAA2B,6/CA0EvC"}