8923
);
8924
});
8925
8926
- it('can server render Suspense before, after, and around <html>', async () => {
8926
+ it('can render Suspense before, after, and around <html>', async () => {
8927
function BlockedOn({value, children}) {
8928
readText(value);
8929
return children;
8989
</body>
8990
</html>,
8991
);
8992
+
8993
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
8994
+ await waitForAll([]);
8995
+ expect(getVisibleChildren(document)).toEqual(
8996
+ <html lang="en">
8997
+ <head>
8998
+ <meta itemprop="" content="non-floaty meta" />
8999
+ </head>
9000
+ <body>
9001
+ <div>before</div>
9002
+ <div>hello world</div>
9003
+ <div>after</div>
9004
+ </body>
9005
+ </html>,
9006
+ );
9007
+ assertConsoleErrorDev(['In HTML, <div> cannot be a child of <#document>']);
9008
+
9009
+ root.unmount();
9010
+ expect(getVisibleChildren(document)).toEqual(
9011
+ <html>
9012
+ <head />
9013
+ <body />
9014
+ </html>,
9015
+ );
9016
});
9017
8994
- it('can server render Suspense before, after, and around <body>', async () => {
9018
+ it('can render Suspense before, after, and around <body>', async () => {
9019
function BlockedOn({value, children}) {
9020
readText(value);
9021
return children;
9076
</body>
9077
</html>,
9078
);
9079
+
9080
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
9081
+ await waitForAll([]);
9082
+ expect(getVisibleChildren(document)).toEqual(
9083
+ <html>
9084
+ <head>
9085
+ <meta content="before" />
9086
+ <meta content="after" />
9087
+ </head>
9088
+ <body lang="en">
9089
+ <meta itemprop="" content="before" />
9090
+ <div>hello world</div>
9091
+ <meta itemprop="" content="after" />
9092
+ </body>
9093
+ </html>,
9094
+ );
9095
+ if (gate(flags => flags.enableOwnerStacks)) {
9096
+ assertConsoleErrorDev([
9097
+ [
9098
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
9099
+ {withoutStack: true},
9100
+ ],
9101
+ 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
9102
+ '\n' +
9103
+ '\n <App>' +
9104
+ '\n> <html>' +
9105
+ '\n <Suspense fallback="this fallb...">' +
9106
+ '\n <meta>' +
9107
+ '\n> <meta itemProp="" content="before">' +
9108
+ '\n ...' +
9109
+ '\n' +
9110
+ '\n in meta (at **)' +
9111
+ '\n in App (at **)',
9112
+ '<html> cannot contain a nested <meta>.\nSee this log for the ancestor stack trace.' +
9113
+ '\n in html (at **)' +
9114
+ '\n in App (at **)',
9115
+ [
9116
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
9117
+ {withoutStack: true},
9118
+ ],
9119
+ ]);
9120
+ } else {
9121
+ assertConsoleErrorDev([
9122
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.' +
9123
+ '\n in Suspense (at **)' +
9124
+ '\n in html (at **)' +
9125
+ '\n in App (at **)',
9126
+ 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
9127
+ '\n' +
9128
+ '\n <App>' +
9129
+ '\n> <html>' +
9130
+ '\n <Suspense fallback="this fallb...">' +
9131
+ '\n <meta>' +
9132
+ '\n> <meta itemProp="" content="before">' +
9133
+ '\n ...' +
9134
+ '\n' +
9135
+ '\n in meta (at **)' +
9136
+ '\n in Suspense (at **)' +
9137
+ '\n in html (at **)' +
9138
+ '\n in App (at **)',
9139
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.' +
9140
+ '\n in Suspense (at **)' +
9141
+ '\n in html (at **)' +
9142
+ '\n in App (at **)',
9143
+ ]);
9144
+ }
9145
+
9146
+ await root.unmount();
9147
+ expect(getVisibleChildren(document)).toEqual(
9148
+ <html>
9149
+ <head />
9150
+ <body />
9151
+ </html>,
9152
+ );
9153
});
9154
9057
- it('can server render Suspense before, after, and around <head>', async () => {
9155
+ it('can render Suspense before, after, and around <head>', async () => {
9156
function BlockedOn({value, children}) {
9157
readText(value);
9158
return children;
9217
</body>
9218
</html>,
9219
);
9220
+
9221
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
9222
+ await waitForAll([]);
9223
+ expect(getVisibleChildren(document)).toEqual(
9224
+ <html>
9225
+ <head lang="en">
9226
+ <meta content="before" />
9227
+ <meta content="after" />
9228
+ <meta itemprop="" />
9229
+ </head>
9230
+ <body>
9231
+ <meta itemprop="" content="before" />
9232
+ <meta itemprop="" content="after" />
9233
+ <div>hello world</div>
9234
+ </body>
9235
+ </html>,
9236
+ );
9237
+ if (gate(flags => flags.enableOwnerStacks)) {
9238
+ assertConsoleErrorDev([
9239
+ [
9240
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
9241
+ {withoutStack: true},
9242
+ ],
9243
+ 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
9244
+ '\n' +
9245
+ '\n <App>' +
9246
+ '\n> <html>' +
9247
+ '\n <Suspense fallback="this fallb...">' +
9248
+ '\n <meta>' +
9249
+ '\n> <meta itemProp="" content="before">' +
9250
+ '\n ...' +
9251
+ '\n' +
9252
+ '\n in meta (at **)' +
9253
+ '\n in App (at **)',
9254
+ '<html> cannot contain a nested <meta>.\nSee this log for the ancestor stack trace.' +
9255
+ '\n in html (at **)' +
9256
+ '\n in App (at **)',
9257
+ [
9258
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.',
9259
+ {withoutStack: true},
9260
+ ],
9261
+ ]);
9262
+ } else {
9263
+ assertConsoleErrorDev([
9264
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.' +
9265
+ '\n in Suspense (at **)' +
9266
+ '\n in html (at **)' +
9267
+ '\n in App (at **)',
9268
+ 'In HTML, <meta> cannot be a child of <html>.\nThis will cause a hydration error.' +
9269
+ '\n' +
9270
+ '\n <App>' +
9271
+ '\n> <html>' +
9272
+ '\n <Suspense fallback="this fallb...">' +
9273
+ '\n <meta>' +
9274
+ '\n> <meta itemProp="" content="before">' +
9275
+ '\n ...' +
9276
+ '\n' +
9277
+ '\n in meta (at **)' +
9278
+ '\n in Suspense (at **)' +
9279
+ '\n in html (at **)' +
9280
+ '\n in App (at **)',
9281
+ 'Cannot render a <meta> outside the main document if it has an `itemProp` prop. `itemProp` suggests the tag belongs to an `itemScope` which can appear anywhere in the DOM. If you were intending for React to hoist this <meta> remove the `itemProp` prop. Otherwise, try moving this tag into the <head> or <body> of the Document.' +
9282
+ '\n in Suspense (at **)' +
9283
+ '\n in html (at **)' +
9284
+ '\n in App (at **)',
9285
+ ]);
9286
+ }
9287
+
9288
+ await root.unmount();
9289
+ expect(getVisibleChildren(document)).toEqual(
9290
+ <html>
9291
+ <head />
9292
+ <body />
9293
+ </html>,
9294
+ );
9295
});
9296
9124
- it('will render fallback Document when erroring a boundary above the body', async () => {
9297
+ it('will render fallback Document when erroring a boundary above the body and recover on the client', async () => {
9298
+ let serverRendering = true;
9299
function Boom() {
9126
- throw new Error('Boom!');
9300
+ if (serverRendering) {
9301
+ throw new Error('Boom!');
9302
+ }
9303
+ return null;
9304
}
9305
9306
function App() {
9351
</body>
9352
</html>,
9353
);
9354
+
9355
+ serverRendering = false;
9356
+
9357
+ const recoverableErrors = [];
9358
+ const root = ReactDOMClient.hydrateRoot(document, <App />, {
9359
+ onRecoverableError(err) {
9360
+ recoverableErrors.push(err);
9361
+ },
9362
+ });
9363
+ await waitForAll([]);
9364
+ expect(getVisibleChildren(document)).toEqual(
9365
+ <html data-content-html="">
9366
+ <head />
9367
+ <body data-content-body="">
9368
+ <span>hello world</span>
9369
+ </body>
9370
+ </html>,
9371
+ );
9372
+ expect(recoverableErrors).toEqual([
9373
+ __DEV__
9374
+ ? new Error(
9375
+ 'Switched to client rendering because the server rendering errored:\n\nBoom!',
9376
+ )
9377
+ : new Error(
9378
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
9379
+ ),
9380
+ ]);
9381
+
9382
+ root.unmount();
9383
+ expect(getVisibleChildren(document)).toEqual(
9384
+ <html>
9385
+ <head />
9386
+ <body />
9387
+ </html>,
9388
+ );
9389
});
9390
9391
it('will hoist resources and hositables from a primary tree into the <head> of a client rendered fallback', async () => {
9392
+ let serverRendering = true;
9393
function Boom() {
9181
- throw new Error('Boom!');
9394
+ if (serverRendering) {
9395
+ throw new Error('Boom!');
9396
+ }
9397
+ return null;
9398
}
9399
9400
function App() {
9471
</body>
9472
</html>,
9473
);
9474
+
9475
+ serverRendering = false;
9476
+
9477
+ const recoverableErrors = [];
9478
+ const root = ReactDOMClient.hydrateRoot(document, <App />, {
9479
+ onRecoverableError(err) {
9480
+ recoverableErrors.push(err);
9481
+ },
9482
+ });
9483
+ await waitForAll([]);
9484
+ expect(recoverableErrors).toEqual([
9485
+ __DEV__
9486
+ ? new Error(
9487
+ 'Switched to client rendering because the server rendering errored:\n\nBoom!',
9488
+ )
9489
+ : new Error(
9490
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
9491
+ ),
9492
+ ]);
9493
+ expect(getVisibleChildren(document)).toEqual(
9494
+ <html data-content-html="">
9495
+ <head>
9496
+ <link
9497
+ rel="stylesheet"
9498
+ href="hoistable before"
9499
+ data-precedence="default"
9500
+ />
9501
+ <link
9502
+ rel="stylesheet"
9503
+ href="hoistable after"
9504
+ data-precedence="default"
9505
+ />
9506
+ <meta content="hoistable before" />
9507
+ <meta content="hoistable after" />
9508
+ </head>
9509
+ <body data-content-body="">
9510
+ <span>hello world</span>
9511
+ </body>
9512
+ </html>,
9513
+ );
9514
+
9515
+ root.unmount();
9516
+ expect(getVisibleChildren(document)).toEqual(
9517
+ <html>
9518
+ <head>
9519
+ <link
9520
+ rel="stylesheet"
9521
+ href="hoistable before"
9522
+ data-precedence="default"
9523
+ />
9524
+ <link
9525
+ rel="stylesheet"
9526
+ href="hoistable after"
9527
+ data-precedence="default"
9528
+ />
9529
+ </head>
9530
+ <body />
9531
+ </html>,
9532
+ );
9533
});
9534
9535
it('Will wait to flush Document chunks until all boundaries which might contain a preamble are errored or resolved', async () => {
9628
});
9629
9630
it('Can render a fallback <head> alongside a non-fallback body', async () => {
9631
+ let serverRendering = true;
9632
function Boom() {
9357
- throw new Error('Boom!');
9633
+ if (serverRendering) {
9634
+ throw new Error('Boom!');
9635
+ }
9636
+ return null;
9637
}
9638
9639
function App() {
9695
</body>
9696
</html>,
9697
);
9698
+
9699
+ serverRendering = false;
9700
+
9701
+ const recoverableErrors = [];
9702
+ const root = ReactDOMClient.hydrateRoot(document, <App />, {
9703
+ onRecoverableError(err) {
9704
+ recoverableErrors.push(err);
9705
+ },
9706
+ });
9707
+ await waitForAll([]);
9708
+ expect(recoverableErrors).toEqual([
9709
+ __DEV__
9710
+ ? new Error(
9711
+ 'Switched to client rendering because the server rendering errored:\n\nBoom!',
9712
+ )
9713
+ : new Error(
9714
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
9715
+ ),
9716
+ ]);
9717
+ expect(getVisibleChildren(document)).toEqual(
9718
+ <html>
9719
+ <head data-primary="">
9720
+ <meta itemprop="" content="primary" />
9721
+ </head>
9722
+ <body data-primary="">
9723
+ <div>primary body</div>
9724
+ </body>
9725
+ </html>,
9726
+ );
9727
+
9728
+ root.unmount();
9729
+ expect(getVisibleChildren(document)).toEqual(
9730
+ <html>
9731
+ <head />
9732
+ <body />
9733
+ </html>,
9734
+ );
9735
});
9736
9737
it('Can render a fallback <body> alongside a non-fallback head', async () => {
9738
+ let serverRendering = true;
9739
function Boom() {
9423
- throw new Error('Boom!');
9740
+ if (serverRendering) {
9741
+ throw new Error('Boom!');
9742
+ }
9743
+ return null;
9744
}
9745
9746
function App() {
9802
</body>
9803
</html>,
9804
);
9805
+
9806
+ serverRendering = false;
9807
+
9808
+ const recoverableErrors = [];
9809
+ const root = ReactDOMClient.hydrateRoot(document, <App />, {
9810
+ onRecoverableError(err) {
9811
+ recoverableErrors.push(err);
9812
+ },
9813
+ });
9814
+ await waitForAll([]);
9815
+ expect(getVisibleChildren(document)).toEqual(
9816
+ <html>
9817
+ <head data-primary="">
9818
+ <meta itemprop="" content="primary" />
9819
+ </head>
9820
+ <body data-primary="">
9821
+ <div>primary body</div>
9822
+ </body>
9823
+ </html>,
9824
+ );
9825
+ expect(recoverableErrors).toEqual([
9826
+ __DEV__
9827
+ ? new Error(
9828
+ 'Switched to client rendering because the server rendering errored:\n\nBoom!',
9829
+ )
9830
+ : new Error(
9831
+ 'The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.',
9832
+ ),
9833
+ ]);
9834
+
9835
+ root.unmount();
9836
+ expect(getVisibleChildren(document)).toEqual(
9837
+ <html>
9838
+ <head />
9839
+ <body />
9840
+ </html>,
9841
+ );
9842
});
9843
9844
it('Can render a <head> outside of a containing <html>', async () => {
9885
</body>
9886
</html>,
9887
);
9888
+
9889
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
9890
+ await waitForAll([]);
9891
+ expect(getVisibleChildren(document)).toEqual(
9892
+ <html data-x="">
9893
+ <head data-y="">
9894
+ <meta itemprop="" />
9895
+ </head>
9896
+ <body data-x="">
9897
+ <span>hello world</span>
9898
+ </body>
9899
+ </html>,
9900
+ );
9901
+
9902
+ root.unmount();
9903
+ expect(getVisibleChildren(document)).toEqual(
9904
+ <html>
9905
+ <head />
9906
+ <body />
9907
+ </html>,
9908
+ );
9909
});
9910
9911
it('can render preamble tags in deeply nested indirect component trees', async () => {
10039
</body>
10040
</html>,
10041
);
10042
+
10043
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
10044
+ await waitForAll([]);
10045
+ expect(getVisibleChildren(document)).toEqual(
10046
+ <html lang="es">
10047
+ <head data-main="">
10048
+ <meta content="author" />
10049
+ <meta content="published date" />
10050
+ </head>
10051
+ <body data-main="">
10052
+ <div>This is soooo cool!</div>
10053
+ </body>
10054
+ </html>,
10055
+ );
10056
+
10057
+ root.unmount();
10058
+ expect(getVisibleChildren(document)).toEqual(
10059
+ <html>
10060
+ <head />
10061
+ <body />
10062
+ </html>,
10063
+ );
10064
});
10065
10066
it('will flush the preamble as soon as a complete preamble is available', async () => {
10140
</body>
10141
</html>,
10142
);
10143
+
10144
+ const root = ReactDOMClient.hydrateRoot(document, <App />);
10145
+ await waitForAll([]);
10146
+ expect(getVisibleChildren(document)).toEqual(
10147
+ <html>
10148
+ <head>
10149
+ <meta content="head" />
10150
+ </head>
10151
+ <body>
10152
+ loading before...
10153
+ <div>body</div>
10154
+ loading after...
10155
+ </body>
10156
+ </html>,
10157
+ );
10158
+
10159
+ await act(() => {
10160
+ resolveText('before');
10161
+ resolveText('after');
10162
+ });
10163
+ await waitForAll([]);
10164
+ expect(getVisibleChildren(document)).toEqual(
10165
+ <html>
10166
+ <head>
10167
+ <meta content="head" />
10168
+ </head>
10169
+ <body>
10170
+ <div>before</div>
10171
+ <div>body</div>
10172
+ <div>after</div>
10173
+ </body>
10174
+ </html>,
10175
+ );
10176
+ assertConsoleErrorDev(['In HTML, <div> cannot be a child of <#document>']);
10177
+
10178
+ root.unmount();
10179
+ expect(getVisibleChildren(document)).toEqual(
10180
+ <html>
10181
+ <head />
10182
+ <body />
10183
+ </html>,
10184
+ );
10185
+ });
10186
+
10187
+ it('will clean up the head when a hydration mismatch causes a boundary to recover on the client', async () => {
10188
+ let content = 'server';
10189
+
10190
+ function ServerApp() {
10191
+ return (
10192
+ <Suspense>
10193
+ <html data-x={content}>
10194
+ <head data-x={content}>
10195
+ <meta itemProp="" content={content} />
10196
+ </head>
10197
+ <body data-x={content}>{content}</body>
10198
+ </html>
10199
+ </Suspense>
10200
+ );
10201
+ }
10202
+
10203
+ function ClientApp() {
10204
+ return (
10205
+ <Suspense>
10206
+ <html data-y={content}>
10207
+ <head data-y={content}>
10208
+ <meta itemProp="" name={content} />
10209
+ </head>
10210
+ <body data-y={content}>{content}</body>
10211
+ </html>
10212
+ </Suspense>
10213
+ );
10214
+ }
10215
+
10216
+ await act(() => {
10217
+ const {pipe} = renderToPipeableStream(<ServerApp />);
10218
+ pipe(writable);
10219
+ });
10220
+ expect(getVisibleChildren(document)).toEqual(
10221
+ <html data-x="server">
10222
+ <head data-x="server">
10223
+ <meta itemprop="" content="server" />
10224
+ </head>
10225
+ <body data-x="server">server</body>
10226
+ </html>,
10227
+ );
10228
+
10229
+ content = 'client';
10230
+
10231
+ const recoverableErrors = [];
10232
+ const root = ReactDOMClient.hydrateRoot(document, <ClientApp />, {
10233
+ onRecoverableError(err) {
10234
+ recoverableErrors.push(err.message);
10235
+ },
10236
+ });
10237
+ await waitForAll([]);
10238
+ if (gate(flags => flags.favorSafetyOverHydrationPerf)) {
10239
+ expect(getVisibleChildren(document)).toEqual(
10240
+ <html data-y="client">
10241
+ <head data-y="client">
10242
+ <meta itemprop="" name="client" />
10243
+ </head>
10244
+ <body data-y="client">client</body>
10245
+ </html>,
10246
+ );
10247
+ expect(recoverableErrors).toEqual([
10248
+ expect.stringContaining(
10249
+ "Hydration failed because the server rendered HTML didn't match the client.",
10250
+ ),
10251
+ ]);
10252
+ } else {
10253
+ expect(getVisibleChildren(document)).toEqual(
10254
+ <html data-x="server">
10255
+ <head data-x="server">
10256
+ <meta itemprop="" content="server" />
10257
+ </head>
10258
+ <body data-x="server">server</body>
10259
+ </html>,
10260
+ );
10261
+ expect(recoverableErrors).toEqual([]);
10262
+ assertConsoleErrorDev([
10263
+ "A tree hydrated but some attributes of the server rendered HTML didn't match the client properties. This won't be patched up. This can happen if a SSR-ed Client Component used:" +
10264
+ '\n' +
10265
+ "\n- A server/client branch `if (typeof window !== 'undefined')`." +
10266
+ "\n- Variable input such as `Date.now()` or `Math.random()` which changes each time it's called." +
10267
+ "\n- Date formatting in a user's locale which doesn't match the server." +
10268
+ '\n- External changing data without sending a snapshot of it along with the HTML.' +
10269
+ '\n- Invalid HTML tag nesting.' +
10270
+ '\n' +
10271
+ '\nIt can also happen if the client has a browser extension installed which messes with the HTML before React loaded.' +
10272
+ '\n' +
10273
+ '\nhttps://react.dev/link/hydration-mismatch' +
10274
+ '\n' +
10275
+ '\n <ClientApp>' +
10276
+ '\n <Suspense>' +
10277
+ '\n <html' +
10278
+ '\n+ data-y="client"' +
10279
+ '\n- data-y={null}' +
10280
+ '\n- data-x="server"' +
10281
+ '\n >' +
10282
+ '\n <head' +
10283
+ '\n+ data-y="client"' +
10284
+ '\n- data-y={null}' +
10285
+ '\n- data-x="server"' +
10286
+ '\n >' +
10287
+ '\n <meta' +
10288
+ '\n itemProp=""' +
10289
+ '\n+ name="client"' +
10290
+ '\n- name={null}' +
10291
+ '\n- content="server"' +
10292
+ '\n >' +
10293
+ '\n <body' +
10294
+ '\n+ data-y="client"' +
10295
+ '\n- data-y={null}' +
10296
+ '\n- data-x="server"' +
10297
+ '\n >' +
10298
+ '\n+ client' +
10299
+ '\n- server' +
10300
+ '\n+ client' +
10301
+ '\n- server' +
10302
+ '\n' +
10303
+ '\n in Suspense (at **)' +
10304
+ '\n in ClientApp (at **)',
10305
+ ]);
10306
+ }
10307
+
10308
+ root.unmount();
10309
+ expect(getVisibleChildren(document)).toEqual(
10310
+ <html>
10311
+ <head />
10312
+ <body />
10313
+ </html>,
10314
+ );
10315
});
10316
});