@tanstack/router-core 0.0.1-beta.26 → 0.0.1-beta.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js +0 -2
  2. package/build/cjs/_virtual/_rollupPluginBabelHelpers.js.map +1 -1
  3. package/build/cjs/{packages/router-core/src/index.js → index.js} +22 -6
  4. package/build/cjs/{packages/router-core/src/index.js.map → index.js.map} +1 -1
  5. package/build/cjs/{packages/router-core/src/path.js → path.js} +4 -28
  6. package/build/cjs/path.js.map +1 -0
  7. package/build/cjs/{packages/router-core/src/qss.js → qss.js} +8 -13
  8. package/build/cjs/qss.js.map +1 -0
  9. package/build/cjs/{packages/router-core/src/route.js → route.js} +7 -16
  10. package/build/cjs/route.js.map +1 -0
  11. package/build/cjs/{packages/router-core/src/routeConfig.js → routeConfig.js} +10 -12
  12. package/build/cjs/routeConfig.js.map +1 -0
  13. package/build/cjs/{packages/router-core/src/routeMatch.js → routeMatch.js} +15 -35
  14. package/build/cjs/routeMatch.js.map +1 -0
  15. package/build/cjs/{packages/router-core/src/router.js → router.js} +103 -159
  16. package/build/cjs/router.js.map +1 -0
  17. package/build/cjs/{packages/router-core/src/searchParams.js → searchParams.js} +7 -10
  18. package/build/cjs/searchParams.js.map +1 -0
  19. package/build/cjs/{packages/router-core/src/utils.js → utils.js} +10 -24
  20. package/build/cjs/utils.js.map +1 -0
  21. package/build/esm/index.js +150 -1112
  22. package/build/esm/index.js.map +1 -1
  23. package/build/stats-html.html +59 -49
  24. package/build/stats-react.json +155 -155
  25. package/build/types/index.d.ts +34 -20
  26. package/build/umd/index.development.js +145 -290
  27. package/build/umd/index.development.js.map +1 -1
  28. package/build/umd/index.production.js +1 -1
  29. package/build/umd/index.production.js.map +1 -1
  30. package/package.json +2 -2
  31. package/src/route.ts +8 -5
  32. package/src/routeConfig.ts +6 -10
  33. package/src/routeMatch.ts +1 -1
  34. package/src/router.ts +114 -51
  35. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js +0 -33
  36. package/build/cjs/node_modules/@babel/runtime/helpers/esm/extends.js.map +0 -1
  37. package/build/cjs/node_modules/history/index.js +0 -815
  38. package/build/cjs/node_modules/history/index.js.map +0 -1
  39. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js +0 -30
  40. package/build/cjs/node_modules/tiny-invariant/dist/esm/tiny-invariant.js.map +0 -1
  41. package/build/cjs/packages/router-core/src/path.js.map +0 -1
  42. package/build/cjs/packages/router-core/src/qss.js.map +0 -1
  43. package/build/cjs/packages/router-core/src/route.js.map +0 -1
  44. package/build/cjs/packages/router-core/src/routeConfig.js.map +0 -1
  45. package/build/cjs/packages/router-core/src/routeMatch.js.map +0 -1
  46. package/build/cjs/packages/router-core/src/router.js.map +0 -1
  47. package/build/cjs/packages/router-core/src/searchParams.js.map +0 -1
  48. package/build/cjs/packages/router-core/src/utils.js.map +0 -1
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/router-core",
3
3
  "author": "Tanner Linsley",
4
- "version": "0.0.1-beta.26",
4
+ "version": "0.0.1-beta.29",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/router",
7
7
  "homepage": "https://tanstack.com/router",
@@ -23,7 +23,7 @@
23
23
  "url": "https://github.com/sponsors/tannerlinsley"
24
24
  },
25
25
  "module": "build/esm/index.js",
26
- "main": "build/cjs/packages/router-core/src/index.js",
26
+ "main": "build/cjs/index.js",
27
27
  "browser": "build/umd/index.production.js",
28
28
  "types": "build/types/index.d.ts",
29
29
  "engines": {
package/src/route.ts CHANGED
@@ -23,11 +23,12 @@ import {
23
23
  } from './router'
24
24
  import { NoInfer } from './utils'
25
25
 
26
- export interface AnyRoute extends Route<any, any> {}
26
+ export interface AnyRoute extends Route<any, any, any> {}
27
27
 
28
28
  export interface Route<
29
29
  TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
30
30
  TRouteInfo extends AnyRouteInfo = RouteInfo,
31
+ TRouterContext = unknown,
31
32
  > {
32
33
  routeInfo: TRouteInfo
33
34
  routeId: TRouteInfo['id']
@@ -37,7 +38,7 @@ export interface Route<
37
38
  parentRoute?: AnyRoute
38
39
  childRoutes?: AnyRoute[]
39
40
  options: RouteOptions
40
- router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo>
41
+ router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo, TRouterContext>
41
42
  buildLink: <TTo extends string = '.'>(
42
43
  options: Omit<
43
44
  LinkOptions<TAllRouteInfo, TRouteInfo['fullPath'], TTo>,
@@ -87,12 +88,13 @@ export interface Route<
87
88
  export function createRoute<
88
89
  TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
89
90
  TRouteInfo extends AnyRouteInfo = RouteInfo,
91
+ TRouterContext = unknown,
90
92
  >(
91
93
  routeConfig: RouteConfig,
92
94
  options: TRouteInfo['options'],
93
95
  parent: undefined | Route<TAllRouteInfo, any>,
94
- router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo>,
95
- ): Route<TAllRouteInfo, TRouteInfo> {
96
+ router: Router<TAllRouteInfo['routeConfig'], TAllRouteInfo, TRouterContext>,
97
+ ): Route<TAllRouteInfo, TRouteInfo, TRouterContext> {
96
98
  const { id, routeId, path: routePath, fullPath } = routeConfig
97
99
 
98
100
  const action =
@@ -138,6 +140,7 @@ export function createRoute<
138
140
  actionState.status = 'success'
139
141
  return res
140
142
  } catch (err) {
143
+ console.log('tanner')
141
144
  console.error(err)
142
145
  actionState.error = err
143
146
  actionState.status = 'error'
@@ -188,7 +191,7 @@ export function createRoute<
188
191
  return router.state.loaders[id]!
189
192
  })()
190
193
 
191
- let route: Route<TAllRouteInfo, TRouteInfo> = {
194
+ let route: Route<TAllRouteInfo, TRouteInfo, TRouterContext> = {
192
195
  routeInfo: undefined!,
193
196
  routeId: id,
194
197
  routeRouteId: routeId,
@@ -4,15 +4,8 @@ import { ParsePathParams } from './link'
4
4
  import { joinPaths, trimPath, trimPathRight } from './path'
5
5
  import { RouteInfo } from './routeInfo'
6
6
  import { RouteMatch } from './routeMatch'
7
- import { RouterContext } from './router'
8
- import {
9
- DeepAwaited,
10
- Expand,
11
- IsAny,
12
- NoInfer,
13
- PickUnsafe,
14
- Values,
15
- } from './utils'
7
+ import { RegisteredRouter, Router } from './router'
8
+ import { Expand, IsAny, NoInfer, PickUnsafe } from './utils'
16
9
 
17
10
  export const rootRouteId = '__root__' as const
18
11
  export type RootRouteId = typeof rootRouteId
@@ -132,7 +125,10 @@ export type RouteOptions<
132
125
  action?: ActionFn<TActionPayload, TActionResponse>
133
126
  // This async function is called before a route is loaded. If an error is thrown, the navigation is cancelled.
134
127
  // If you want to redirect instead, throw a call to the `router.navigate()` function
135
- beforeLoad?: (opts: { context: RouterContext }) => Promise<void> | void
128
+ beforeLoad?: (opts: {
129
+ router: Router<any, any, unknown>
130
+ match: RouteMatch
131
+ }) => Promise<void> | void
136
132
  // This function is called
137
133
  // when moving from an inactive state to an active one. Likewise, when moving from
138
134
  // an active to an inactive state, the return function (if provided) is called.
package/src/routeMatch.ts CHANGED
@@ -71,7 +71,7 @@ export function createRouteMatch<
71
71
  TAllRouteInfo extends AnyAllRouteInfo = DefaultAllRouteInfo,
72
72
  TRouteInfo extends AnyRouteInfo = RouteInfo,
73
73
  >(
74
- router: Router<any, any>,
74
+ router: Router<any, any, any>,
75
75
  route: Route<TAllRouteInfo, TRouteInfo>,
76
76
  opts: {
77
77
  parentMatch?: RouteMatch<any, any>
package/src/router.ts CHANGED
@@ -53,6 +53,22 @@ import {
53
53
  Updater,
54
54
  } from './utils'
55
55
 
56
+ export interface RegisterRouter {
57
+ // router: Router
58
+ }
59
+
60
+ export type RegisteredRouter = RegisterRouter extends {
61
+ router: Router<infer TRouteConfig, infer TAllRouteInfo, infer TRouterContext>
62
+ }
63
+ ? Router<TRouteConfig, TAllRouteInfo, TRouterContext>
64
+ : Router
65
+
66
+ export type RegisteredAllRouteInfo = RegisterRouter extends {
67
+ router: Router<infer TRouteConfig, infer TAllRouteInfo, infer TRouterContext>
68
+ }
69
+ ? TAllRouteInfo
70
+ : AnyAllRouteInfo
71
+
56
72
  export interface LocationState {}
57
73
 
58
74
  export interface Location<
@@ -81,7 +97,10 @@ export type FilterRoutesFn = <TRoute extends Route<any, RouteInfo>>(
81
97
  routeConfigs: TRoute[],
82
98
  ) => TRoute[]
83
99
 
84
- export interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
100
+ export interface RouterOptions<
101
+ TRouteConfig extends AnyRouteConfig,
102
+ TRouterContext,
103
+ > {
85
104
  history?: BrowserHistory | MemoryHistory | HashHistory
86
105
  stringifySearch?: SearchSerializer
87
106
  parseSearch?: SearchParser
@@ -99,8 +118,12 @@ export interface RouterOptions<TRouteConfig extends AnyRouteConfig> {
99
118
  routeConfig?: TRouteConfig
100
119
  basepath?: string
101
120
  useServerData?: boolean
102
- createRouter?: (router: Router<any, any>) => void
103
- createRoute?: (opts: { route: AnyRoute; router: Router<any, any> }) => void
121
+ createRouter?: (router: Router<any, any, any>) => void
122
+ createRoute?: (opts: {
123
+ route: AnyRoute
124
+ router: Router<any, any, any>
125
+ }) => void
126
+ context?: TRouterContext
104
127
  loadComponent?: (
105
128
  component: GetFrameworkGeneric<'Component'>,
106
129
  ) => Promise<GetFrameworkGeneric<'Component'>>
@@ -192,7 +215,7 @@ export interface PendingState {
192
215
  matches: RouteMatch[]
193
216
  }
194
217
 
195
- type Listener = (router: Router<any, any>) => void
218
+ type Listener = (router: Router<any, any, any>) => void
196
219
 
197
220
  export type ListenerFn = () => void
198
221
 
@@ -231,11 +254,20 @@ type LinkCurrentTargetElement = {
231
254
  preloadTimeout?: null | ReturnType<typeof setTimeout>
232
255
  }
233
256
 
234
- interface DehydratedRouterState
235
- extends Pick<RouterState, 'status' | 'location' | 'lastUpdated'> {
257
+ export interface DehydratedRouterState
258
+ extends Pick<
259
+ RouterState,
260
+ 'status' | 'location' | 'lastUpdated' | 'location'
261
+ > {
236
262
  matches: DehydratedRouteMatch[]
237
263
  }
238
264
 
265
+ export interface DehydratedRouter<TRouterContext = unknown> {
266
+ location: Router['location']
267
+ state: DehydratedRouterState
268
+ context: TRouterContext
269
+ }
270
+
239
271
  interface DehydratedRouteMatch
240
272
  extends Pick<
241
273
  RouteMatch<any, any>,
@@ -252,6 +284,7 @@ export interface RouterContext {}
252
284
  export interface Router<
253
285
  TRouteConfig extends AnyRouteConfig = RouteConfig,
254
286
  TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
287
+ TRouterContext = unknown,
255
288
  > {
256
289
  types: {
257
290
  // Super secret internal stuff
@@ -262,13 +295,12 @@ export interface Router<
262
295
  // Public API
263
296
  history: BrowserHistory | MemoryHistory | HashHistory
264
297
  options: PickAsRequired<
265
- RouterOptions<TRouteConfig>,
266
- 'stringifySearch' | 'parseSearch'
298
+ RouterOptions<TRouteConfig, TRouterContext>,
299
+ 'stringifySearch' | 'parseSearch' | 'context'
267
300
  >
268
301
  // Computed in this.update()
269
302
  basepath: string
270
303
  // Internal:
271
- context: RouterContext
272
304
  listeners: Listener[]
273
305
  location: Location<TAllRouteInfo['fullSearchSchema']>
274
306
  navigateTimeout?: Timeout
@@ -276,7 +308,7 @@ export interface Router<
276
308
  state: RouterState<TAllRouteInfo['fullSearchSchema']>
277
309
  routeTree: Route<TAllRouteInfo, RouteInfo>
278
310
  routesById: RoutesById<TAllRouteInfo>
279
- navigationPromise: Promise<void>
311
+ navigationPromise?: Promise<void>
280
312
  startedLoadingAt: number
281
313
  resolveNavigation: () => void
282
314
  subscribe: (listener: Listener) => () => void
@@ -284,9 +316,13 @@ export interface Router<
284
316
  notify: () => void
285
317
  mount: () => () => void
286
318
  onFocus: () => void
287
- update: <TRouteConfig extends RouteConfig = RouteConfig>(
288
- opts?: RouterOptions<TRouteConfig>,
289
- ) => Router<TRouteConfig>
319
+ update: <
320
+ TRouteConfig extends RouteConfig = RouteConfig,
321
+ TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
322
+ TRouterContext = unknown,
323
+ >(
324
+ opts?: RouterOptions<TRouteConfig, TRouterContext>,
325
+ ) => Router<TRouteConfig, TAllRouteInfo, TRouterContext>
290
326
 
291
327
  buildNext: (opts: BuildNextOptions) => Location
292
328
  cancelMatches: () => void
@@ -336,8 +372,8 @@ export interface Router<
336
372
  >(
337
373
  opts: LinkOptions<TAllRouteInfo, TFrom, TTo>,
338
374
  ) => LinkInfo
339
- dehydrateState: () => DehydratedRouterState
340
- hydrateState: (state: DehydratedRouterState) => void
375
+ dehydrate: () => DehydratedRouter<TRouterContext>
376
+ hydrate: (dehydratedRouter: DehydratedRouter<TRouterContext>) => void
341
377
  __: {
342
378
  buildRouteTree: (
343
379
  routeConfig: RouteConfig,
@@ -378,9 +414,10 @@ function getInitialRouterState(): RouterState {
378
414
  export function createRouter<
379
415
  TRouteConfig extends AnyRouteConfig = RouteConfig,
380
416
  TAllRouteInfo extends AnyAllRouteInfo = AllRouteInfo<TRouteConfig>,
417
+ TRouterContext = unknown,
381
418
  >(
382
- userOptions?: RouterOptions<TRouteConfig>,
383
- ): Router<TRouteConfig, TAllRouteInfo> {
419
+ userOptions?: RouterOptions<TRouteConfig, TRouterContext>,
420
+ ): Router<TRouteConfig, TAllRouteInfo, TRouterContext> {
384
421
  const history = userOptions?.history || createDefaultHistory()
385
422
 
386
423
  const originalOptions = {
@@ -388,12 +425,13 @@ export function createRouter<
388
425
  defaultLoaderMaxAge: 0,
389
426
  defaultPreloadMaxAge: 2000,
390
427
  defaultPreloadDelay: 50,
428
+ context: undefined!,
391
429
  ...userOptions,
392
430
  stringifySearch: userOptions?.stringifySearch ?? defaultStringifySearch,
393
431
  parseSearch: userOptions?.parseSearch ?? defaultParseSearch,
394
432
  }
395
433
 
396
- let router: Router<TRouteConfig, TAllRouteInfo> = {
434
+ let router: Router<TRouteConfig, TAllRouteInfo, TRouterContext> = {
397
435
  types: undefined!,
398
436
 
399
437
  // public api
@@ -401,13 +439,11 @@ export function createRouter<
401
439
  options: originalOptions,
402
440
  listeners: [],
403
441
  // Resolved after construction
404
- context: {},
405
442
  basepath: '',
406
443
  routeTree: undefined!,
407
444
  routesById: {} as any,
408
445
  location: undefined!,
409
446
  //
410
- navigationPromise: Promise.resolve(),
411
447
  resolveNavigation: () => {},
412
448
  matchCache: {},
413
449
  state: getInitialRouterState(),
@@ -451,30 +487,45 @@ export function createRouter<
451
487
  router.listeners.forEach((listener) => listener(router))
452
488
  },
453
489
 
454
- dehydrateState: () => {
490
+ dehydrate: () => {
455
491
  return {
456
- ...pick(router.state, ['status', 'location', 'lastUpdated']),
457
- matches: router.state.matches.map((match) =>
458
- pick(match, [
459
- 'matchId',
492
+ location: router.location,
493
+ state: {
494
+ ...pick(router.state, [
460
495
  'status',
461
- 'routeLoaderData',
462
- 'loaderData',
463
- 'isInvalid',
464
- 'invalidAt',
496
+ 'location',
497
+ 'lastUpdated',
498
+ 'location',
465
499
  ]),
466
- ),
500
+ matches: router.state.matches.map((match) =>
501
+ pick(match, [
502
+ 'matchId',
503
+ 'status',
504
+ 'routeLoaderData',
505
+ 'loaderData',
506
+ 'isInvalid',
507
+ 'invalidAt',
508
+ ]),
509
+ ),
510
+ },
511
+ context: router.options.context as TRouterContext,
467
512
  }
468
513
  },
469
514
 
470
- hydrateState: (dehydratedState) => {
515
+ hydrate: (dehydratedState) => {
516
+ // Update the location
517
+ router.location = dehydratedState.location
518
+
519
+ // Update the context
520
+ router.options.context = dehydratedState.context
521
+
471
522
  // Match the routes
472
523
  const matches = router.matchRoutes(router.location.pathname, {
473
524
  strictParseParams: true,
474
525
  })
475
526
 
476
527
  matches.forEach((match, index) => {
477
- const dehydratedMatch = dehydratedState.matches[index]
528
+ const dehydratedMatch = dehydratedState.state.matches[index]
478
529
  invariant(
479
530
  dehydratedMatch,
480
531
  'Oh no! Dehydrated route matches did not match the active state of the router 😬',
@@ -584,22 +635,6 @@ export function createRouter<
584
635
  strictParseParams: true,
585
636
  })
586
637
 
587
- // Check if each match middleware to see if the route can be accessed
588
- try {
589
- await Promise.all(
590
- matches.map((match) =>
591
- match.options.beforeLoad?.({
592
- context: router.context,
593
- }),
594
- ),
595
- )
596
- } catch (err: any) {
597
- if (err?.then) {
598
- await new Promise(() => {})
599
- }
600
- throw err
601
- }
602
-
603
638
  if (typeof document !== 'undefined') {
604
639
  router.state = {
605
640
  ...router.state,
@@ -618,6 +653,23 @@ export function createRouter<
618
653
  }
619
654
  }
620
655
 
656
+ // Check if each match middleware to see if the route can be accessed
657
+ try {
658
+ await Promise.all(
659
+ matches.map((match) =>
660
+ match.options.beforeLoad?.({
661
+ router: router as any,
662
+ match,
663
+ }),
664
+ ),
665
+ )
666
+ } catch (err: any) {
667
+ if (err?.then) {
668
+ await new Promise(() => {})
669
+ }
670
+ throw err
671
+ }
672
+
621
673
  router.notify()
622
674
 
623
675
  // Load the matches
@@ -848,7 +900,7 @@ export function createRouter<
848
900
  parentMatch,
849
901
  matchId,
850
902
  params,
851
- pathname: joinPaths([pathname, interpolatedPath]),
903
+ pathname: joinPaths([router.basepath, interpolatedPath]),
852
904
  })
853
905
 
854
906
  matches.push(match)
@@ -912,6 +964,16 @@ export function createRouter<
912
964
  }),
913
965
  })
914
966
 
967
+ // Refresh:
968
+ // '/dashboard'
969
+ // '/dashboard/invoices/'
970
+ // '/dashboard/invoices/123'
971
+
972
+ // New:
973
+ // '/dashboard/invoices/456'
974
+
975
+ // TODO: batch requests when possible
976
+
915
977
  const res = await fetch(next.href, {
916
978
  method: 'GET',
917
979
  // signal: routeMatch.__.abortController.signal,
@@ -1162,8 +1224,8 @@ export function createRouter<
1162
1224
  buildRouteTree: (rootRouteConfig: RouteConfig) => {
1163
1225
  const recurseRoutes = (
1164
1226
  routeConfigs: RouteConfig[],
1165
- parent?: Route<TAllRouteInfo, any>,
1166
- ): Route<TAllRouteInfo, any>[] => {
1227
+ parent?: Route<TAllRouteInfo, any, any>,
1228
+ ): Route<TAllRouteInfo, any, any>[] => {
1167
1229
  return routeConfigs.map((routeConfig) => {
1168
1230
  const routeOptions = routeConfig.options
1169
1231
  const route = createRoute(routeConfig, routeOptions, parent, router)
@@ -1354,6 +1416,7 @@ export function createRouter<
1354
1416
  router.resolveNavigation = () => {
1355
1417
  previousNavigationResolve()
1356
1418
  resolve()
1419
+ delete router.navigationPromise
1357
1420
  }
1358
1421
  })
1359
1422
 
@@ -1,33 +0,0 @@
1
- /**
2
- * router-core
3
- *
4
- * Copyright (c) TanStack
5
- *
6
- * This source code is licensed under the MIT license found in the
7
- * LICENSE.md file in the root directory of this source tree.
8
- *
9
- * @license MIT
10
- */
11
- 'use strict';
12
-
13
- Object.defineProperty(exports, '__esModule', { value: true });
14
-
15
- function _extends() {
16
- _extends = Object.assign ? Object.assign.bind() : function (target) {
17
- for (var i = 1; i < arguments.length; i++) {
18
- var source = arguments[i];
19
-
20
- for (var key in source) {
21
- if (Object.prototype.hasOwnProperty.call(source, key)) {
22
- target[key] = source[key];
23
- }
24
- }
25
- }
26
-
27
- return target;
28
- };
29
- return _extends.apply(this, arguments);
30
- }
31
-
32
- exports["default"] = _extends;
33
- //# sourceMappingURL=extends.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"extends.js","sources":["../../../../../../../../../node_modules/@babel/runtime/helpers/esm/extends.js"],"sourcesContent":["export default function _extends() {\n _extends = Object.assign ? Object.assign.bind() : function (target) {\n for (var i = 1; i < arguments.length; i++) {\n var source = arguments[i];\n\n for (var key in source) {\n if (Object.prototype.hasOwnProperty.call(source, key)) {\n target[key] = source[key];\n }\n }\n }\n\n return target;\n };\n return _extends.apply(this, arguments);\n}"],"names":[],"mappings":";;;;;;;;;;;;;;AAAe,SAAS,QAAQ,GAAG;AACnC,EAAE,QAAQ,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,UAAU,MAAM,EAAE;AACtE,IAAI,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;AAC/C,MAAM,IAAI,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;AAChC;AACA,MAAM,KAAK,IAAI,GAAG,IAAI,MAAM,EAAE;AAC9B,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;AAC/D,UAAU,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;AACpC,SAAS;AACT,OAAO;AACP,KAAK;AACL;AACA,IAAI,OAAO,MAAM,CAAC;AAClB,GAAG,CAAC;AACJ,EAAE,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACzC;;;;"}