app-studio 0.7.7 → 0.7.9

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.
@@ -1066,12 +1066,15 @@ const deepMerge = (target, source) => {
1066
1066
  }
1067
1067
  return merged;
1068
1068
  };
1069
+ // Stable default references to prevent unnecessary re-renders and cache invalidation
1070
+ const DEFAULT_THEME_OVERRIDE = {};
1071
+ const DEFAULT_COLORS_OVERRIDE = {};
1069
1072
  const ThemeProvider = _ref => {
1070
1073
  let {
1071
- theme: themeOverride = {},
1074
+ theme: themeOverride = DEFAULT_THEME_OVERRIDE,
1072
1075
  mode: initialMode = 'light',
1073
- dark: darkOverride = {},
1074
- light: lightOverride = {},
1076
+ dark: darkOverride = DEFAULT_COLORS_OVERRIDE,
1077
+ light: lightOverride = DEFAULT_COLORS_OVERRIDE,
1075
1078
  children,
1076
1079
  strict = false,
1077
1080
  targetWindow
@@ -2950,10 +2953,11 @@ const AnalyticsProvider = _ref => {
2950
2953
  trackEvent,
2951
2954
  children
2952
2955
  } = _ref;
2956
+ const value = React.useMemo(() => ({
2957
+ trackEvent
2958
+ }), [trackEvent]);
2953
2959
  return /*#__PURE__*/React__default.createElement(AnalyticsContext.Provider, {
2954
- value: {
2955
- trackEvent
2956
- }
2960
+ value: value
2957
2961
  }, children);
2958
2962
  };
2959
2963
 
@@ -2985,12 +2989,10 @@ function hashStyleProps(props) {
2985
2989
  */
2986
2990
  function useStableStyleMemo(propsToProcess, getColor, mediaQueries, devices, manager, theme) {
2987
2991
  const cacheRef = React.useRef(null);
2988
- // Compute hash of current props
2989
- const currentHash = React.useMemo(() => {
2990
- // Include theme in hash to bust cache on theme changes
2991
- const themeHash = theme ? JSON.stringify(theme) : '';
2992
- return hashStyleProps(propsToProcess) + '|' + hash(themeHash);
2993
- }, [propsToProcess, theme]);
2992
+ // Compute hash directly no useMemo since propsToProcess is always a new
2993
+ // reference (from destructuring), so the memo deps would always change.
2994
+ const themeHash = theme ? JSON.stringify(theme) : '';
2995
+ const currentHash = hashStyleProps(propsToProcess) + '|' + hash(themeHash);
2994
2996
  // Only recompute classes if hash changed
2995
2997
  if (!cacheRef.current || cacheRef.current.hash !== currentHash) {
2996
2998
  const classes = extractUtilityClasses(propsToProcess, getColor, mediaQueries, devices, manager);
@@ -3082,44 +3084,44 @@ const Element = /*#__PURE__*/React__default.memo(/*#__PURE__*/React.forwardRef((
3082
3084
  };
3083
3085
  }, [animateOut, manager]);
3084
3086
  // Prepare props for processing (apply view/scroll timeline if needed)
3085
- const propsToProcess = React.useMemo(() => {
3086
- const processed = {
3087
- ...rest,
3088
- blend
3089
- };
3090
- // Apply view() timeline ONLY if animateOn='View' (not Both or Mount)
3091
- if (animateOn === 'View' && processed.animate) {
3092
- const animations = Array.isArray(processed.animate) ? processed.animate : [processed.animate];
3093
- processed.animate = animations.map(anim => {
3094
- // Only add timeline if not already specified
3095
- if (!anim.timeline) {
3096
- return {
3097
- ...anim,
3098
- timeline: 'view()',
3099
- range: anim.range || 'entry',
3100
- fillMode: anim.fillMode || 'both'
3101
- };
3102
- }
3103
- return anim;
3104
- });
3105
- }
3106
- // Apply scroll() timeline if animateOn='Scroll'
3107
- if (animateOn === 'Scroll' && processed.animate) {
3108
- const animations = Array.isArray(processed.animate) ? processed.animate : [processed.animate];
3109
- processed.animate = animations.map(anim => {
3110
- // Only add timeline if not already specified
3111
- if (!anim.timeline) {
3112
- return {
3113
- ...anim,
3114
- timeline: 'scroll()',
3115
- fillMode: anim.fillMode || 'both'
3116
- };
3117
- }
3118
- return anim;
3119
- });
3120
- }
3121
- return processed;
3122
- }, [rest, blend, animateOn]);
3087
+ // No useMemo `rest` is always a new reference from destructuring, so
3088
+ // memo deps would always change. useStableStyleMemo handles the real
3089
+ // memoization via hash-based comparison.
3090
+ const propsToProcess = {
3091
+ ...rest,
3092
+ blend
3093
+ };
3094
+ // Apply view() timeline ONLY if animateOn='View' (not Both or Mount)
3095
+ if (animateOn === 'View' && propsToProcess.animate) {
3096
+ const animations = Array.isArray(propsToProcess.animate) ? propsToProcess.animate : [propsToProcess.animate];
3097
+ propsToProcess.animate = animations.map(anim => {
3098
+ // Only add timeline if not already specified
3099
+ if (!anim.timeline) {
3100
+ return {
3101
+ ...anim,
3102
+ timeline: 'view()',
3103
+ range: anim.range || 'entry',
3104
+ fillMode: anim.fillMode || 'both'
3105
+ };
3106
+ }
3107
+ return anim;
3108
+ });
3109
+ }
3110
+ // Apply scroll() timeline if animateOn='Scroll'
3111
+ if (animateOn === 'Scroll' && propsToProcess.animate) {
3112
+ const animations = Array.isArray(propsToProcess.animate) ? propsToProcess.animate : [propsToProcess.animate];
3113
+ propsToProcess.animate = animations.map(anim => {
3114
+ // Only add timeline if not already specified
3115
+ if (!anim.timeline) {
3116
+ return {
3117
+ ...anim,
3118
+ timeline: 'scroll()',
3119
+ fillMode: anim.fillMode || 'both'
3120
+ };
3121
+ }
3122
+ return anim;
3123
+ });
3124
+ }
3123
3125
  // Use hash-based memoization for style extraction
3124
3126
  const utilityClasses = useStableStyleMemo(propsToProcess, getColor, mediaQueries, devices, manager, theme);
3125
3127
  const newProps = {
@@ -5041,14 +5043,28 @@ const WindowSizeProvider = _ref => {
5041
5043
  width: win?.innerWidth || 0,
5042
5044
  height: win?.innerHeight || 0
5043
5045
  });
5046
+ const timeoutRef = React.useRef();
5044
5047
  React.useEffect(() => {
5045
5048
  if (!win) return;
5046
- const handleResize = () => setSize({
5047
- width: win.innerWidth,
5048
- height: win.innerHeight
5049
- });
5049
+ const handleResize = () => {
5050
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
5051
+ timeoutRef.current = setTimeout(() => {
5052
+ const newWidth = win.innerWidth;
5053
+ const newHeight = win.innerHeight;
5054
+ setSize(prev => {
5055
+ if (prev.width === newWidth && prev.height === newHeight) return prev;
5056
+ return {
5057
+ width: newWidth,
5058
+ height: newHeight
5059
+ };
5060
+ });
5061
+ }, 100);
5062
+ };
5050
5063
  win.addEventListener('resize', handleResize);
5051
- return () => win.removeEventListener('resize', handleResize);
5064
+ return () => {
5065
+ win.removeEventListener('resize', handleResize);
5066
+ if (timeoutRef.current) clearTimeout(timeoutRef.current);
5067
+ };
5052
5068
  }, [win]);
5053
5069
  return /*#__PURE__*/React__default.createElement(WindowSizeContext.Provider, {
5054
5070
  value: size
@@ -5081,12 +5097,13 @@ function useActive() {
5081
5097
  return [ref, active];
5082
5098
  }
5083
5099
 
5100
+ const DEFAULT_CLICK_OUTSIDE_OPTIONS = {};
5084
5101
  function useClickOutside(options) {
5085
5102
  const [clickedOutside, setClickedOutside] = React.useState(false);
5086
5103
  const ref = React.useRef(null);
5087
5104
  const {
5088
5105
  targetWindow
5089
- } = options || {};
5106
+ } = options || DEFAULT_CLICK_OUTSIDE_OPTIONS;
5090
5107
  React.useEffect(() => {
5091
5108
  const win = targetWindow || (typeof window !== 'undefined' ? window : null);
5092
5109
  if (!win) return;
@@ -5106,13 +5123,14 @@ function useClickOutside(options) {
5106
5123
  return [ref, clickedOutside];
5107
5124
  }
5108
5125
 
5126
+ const DEFAULT_ELEMENT_POSITION_OPTIONS = {};
5109
5127
  /**
5110
5128
  * A React hook to determine an element's relative position within the viewport
5111
5129
  * and where the most available space is around it within the viewport.
5112
5130
  */
5113
5131
  function useElementPosition(options) {
5114
5132
  if (options === void 0) {
5115
- options = {};
5133
+ options = DEFAULT_ELEMENT_POSITION_OPTIONS;
5116
5134
  }
5117
5135
  const {
5118
5136
  trackChanges = true,
@@ -5284,18 +5302,21 @@ function useKeyPress(targetKey) {
5284
5302
  }
5285
5303
 
5286
5304
  const useMount = callback => {
5305
+ const callbackRef = React.useRef(callback);
5306
+ callbackRef.current = callback;
5287
5307
  React.useEffect(() => {
5288
- callback();
5308
+ callbackRef.current();
5289
5309
  }, []);
5290
5310
  };
5291
5311
 
5312
+ const DEFAULT_ON_SCREEN_OPTIONS = {};
5292
5313
  function useOnScreen(options) {
5293
5314
  const ref = React.useRef(null);
5294
5315
  const [isOnScreen, setOnScreen] = React.useState(false);
5295
5316
  const {
5296
5317
  targetWindow,
5297
5318
  ...observerOptions
5298
- } = options || {};
5319
+ } = options || DEFAULT_ON_SCREEN_OPTIONS;
5299
5320
  React.useEffect(() => {
5300
5321
  const node = ref.current;
5301
5322
  if (!node) return;
@@ -5314,7 +5335,7 @@ function useOnScreen(options) {
5314
5335
  return () => {
5315
5336
  observer.disconnect();
5316
5337
  };
5317
- }, [targetWindow, options]);
5338
+ }, [targetWindow, observerOptions.root, observerOptions.rootMargin, observerOptions.threshold]);
5318
5339
  return [ref, isOnScreen];
5319
5340
  }
5320
5341
 
@@ -5339,14 +5360,14 @@ const useBreakpoint = () => {
5339
5360
  devices
5340
5361
  } = context;
5341
5362
  // Helper to check if current screen matches a breakpoint or device
5342
- const on = s => devices[s] ? devices[s].includes(screen) : s === screen;
5343
- return {
5363
+ const on = React.useCallback(s => devices[s] ? devices[s].includes(screen) : s === screen, [devices, screen]);
5364
+ return React.useMemo(() => ({
5344
5365
  ...context,
5345
5366
  screen,
5346
5367
  orientation,
5347
5368
  on,
5348
5369
  is: on
5349
- };
5370
+ }), [context, screen, orientation, on]);
5350
5371
  };
5351
5372
  /**
5352
5373
  * Hook for components that need exact window dimensions.
@@ -5377,17 +5398,21 @@ const useResponsive = () => {
5377
5398
  orientation,
5378
5399
  devices
5379
5400
  } = context;
5380
- const on = s => devices[s] ? devices[s].includes(screen) : s === screen;
5381
- const result = {
5401
+ const on = React.useCallback(s => devices[s] ? devices[s].includes(screen) : s === screen, [devices, screen]);
5402
+ return React.useMemo(() => ({
5382
5403
  ...context,
5383
5404
  screen,
5384
5405
  orientation,
5385
5406
  on,
5386
5407
  is: on
5387
- };
5388
- return result;
5408
+ }), [context, screen, orientation, on]);
5389
5409
  };
5390
5410
 
5411
+ // Stable default references to prevent unnecessary re-renders
5412
+ const DEFAULT_SCROLL_OFFSET = [0, 0];
5413
+ const DEFAULT_SCROLL_OPTIONS = {};
5414
+ const DEFAULT_SCROLL_ANIMATION_OPTIONS = {};
5415
+ const DEFAULT_INFINITE_SCROLL_OPTIONS = {};
5391
5416
  // Helper to check if element is a Window object (works across iframes)
5392
5417
  const isWindow = obj => {
5393
5418
  return obj && obj.window === obj;
@@ -5421,18 +5446,21 @@ const getScrollDimensions = element => {
5421
5446
  const useScroll = function (_temp) {
5422
5447
  let {
5423
5448
  container,
5424
- offset = [0, 0],
5449
+ offset = DEFAULT_SCROLL_OFFSET,
5425
5450
  throttleMs = 100,
5426
5451
  disabled = false
5427
- } = _temp === void 0 ? {} : _temp;
5452
+ } = _temp === void 0 ? DEFAULT_SCROLL_OPTIONS : _temp;
5428
5453
  const [scrollPosition, setScrollPosition] = React.useState({
5429
5454
  x: 0,
5430
5455
  y: 0,
5431
5456
  xProgress: 0,
5432
- yProgress: 0
5457
+ yProgress: 0,
5458
+ elementY: 0,
5459
+ elementProgress: 0
5433
5460
  });
5434
5461
  const lastUpdateRef = React.useRef(0);
5435
5462
  const frameRef = React.useRef();
5463
+ const ticking = React.useRef(false);
5436
5464
  // Resolve the window/document context. If the container is an iframe element, use its contentWindow.
5437
5465
  const getContext = React.useCallback(() => {
5438
5466
  const targetEl = container?.current ?? null;
@@ -5453,18 +5481,21 @@ const useScroll = function (_temp) {
5453
5481
  targetDocument
5454
5482
  };
5455
5483
  }, [container]);
5456
- const handleScroll = React.useCallback(() => {
5457
- if (disabled) return;
5484
+ const updateScrollPosition = React.useCallback(() => {
5458
5485
  const {
5459
5486
  targetEl,
5460
5487
  targetWindow
5461
5488
  } = getContext();
5462
5489
  const hasScrollableElement = targetEl && isElementScrollable(targetEl);
5463
5490
  const scrollTarget = hasScrollableElement ? targetEl : targetWindow || targetEl;
5464
- if (!scrollTarget) return;
5491
+ if (!scrollTarget) {
5492
+ ticking.current = false;
5493
+ return;
5494
+ }
5465
5495
  const now = Date.now();
5496
+ // Verify throttle constraints inside the RAF to skip frame if needed
5466
5497
  if (throttleMs > 0 && now - lastUpdateRef.current < throttleMs) {
5467
- frameRef.current = requestAnimationFrame(handleScroll);
5498
+ ticking.current = false;
5468
5499
  return;
5469
5500
  }
5470
5501
  const dimensions = getScrollDimensions(scrollTarget);
@@ -5474,19 +5505,47 @@ const useScroll = function (_temp) {
5474
5505
  const maxScrollY = dimensions.scrollHeight - dimensions.clientHeight;
5475
5506
  const xProgress = maxScrollX <= 0 ? 1 : Math.min(Math.max(x / maxScrollX, 0), 1);
5476
5507
  const yProgress = maxScrollY <= 0 ? 1 : Math.min(Math.max(y / maxScrollY, 0), 1);
5508
+ // Calculate element-specific stats if we are tracking a specific element container
5509
+ // that is NOT the main scroller itself.
5510
+ let elementY = 0;
5511
+ let elementProgress = 0;
5512
+ if (targetEl && targetEl !== scrollTarget) {
5513
+ const rect = targetEl.getBoundingClientRect();
5514
+ elementY = rect.top;
5515
+ const viewportHeight = dimensions.clientHeight;
5516
+ const scrollDistance = rect.height - viewportHeight;
5517
+ if (scrollDistance > 0) {
5518
+ // Calculate progress consistent with sticky scrolling behavior
5519
+ // 0 when hitting top, 1 when finished scrolling
5520
+ const scrolled = -rect.top;
5521
+ elementProgress = Math.max(0, Math.min(1, scrolled / scrollDistance));
5522
+ } else {
5523
+ elementProgress = 0;
5524
+ }
5525
+ }
5477
5526
  setScrollPosition(prev => {
5478
- if (prev.x !== x || prev.y !== y || prev.xProgress !== xProgress || prev.yProgress !== yProgress) {
5527
+ if (prev.elementProgress !== elementProgress || prev.y !== y || prev.x !== x || prev.yProgress !== yProgress) {
5479
5528
  lastUpdateRef.current = now;
5480
5529
  return {
5481
5530
  x,
5482
5531
  y,
5483
5532
  xProgress,
5484
- yProgress
5533
+ yProgress,
5534
+ elementY,
5535
+ elementProgress
5485
5536
  };
5486
5537
  }
5487
5538
  return prev;
5488
5539
  });
5489
- }, [offset, throttleMs, disabled, getContext]);
5540
+ ticking.current = false;
5541
+ }, [offset, throttleMs, getContext]);
5542
+ const handleScroll = React.useCallback(() => {
5543
+ if (disabled) return;
5544
+ if (!ticking.current) {
5545
+ frameRef.current = requestAnimationFrame(updateScrollPosition);
5546
+ ticking.current = true;
5547
+ }
5548
+ }, [disabled, updateScrollPosition]);
5490
5549
  React.useEffect(() => {
5491
5550
  if (disabled) return;
5492
5551
  const {
@@ -5498,7 +5557,7 @@ const useScroll = function (_temp) {
5498
5557
  const scrollTarget = hasScrollableElement ? targetEl : targetWindow || targetEl;
5499
5558
  if (!scrollTarget) return;
5500
5559
  // Initial scroll position
5501
- handleScroll();
5560
+ updateScrollPosition();
5502
5561
  const options = {
5503
5562
  passive: true
5504
5563
  };
@@ -5521,14 +5580,15 @@ const useScroll = function (_temp) {
5521
5580
  if (frameRef.current) {
5522
5581
  cancelAnimationFrame(frameRef.current);
5523
5582
  }
5583
+ ticking.current = false;
5524
5584
  };
5525
- }, [handleScroll, disabled, getContext]);
5585
+ }, [handleScroll, disabled, getContext, updateScrollPosition]);
5526
5586
  return scrollPosition;
5527
5587
  };
5528
5588
  // Enhanced useScrollAnimation with callback support and iframe support
5529
5589
  const useScrollAnimation = function (ref, options) {
5530
5590
  if (options === void 0) {
5531
- options = {};
5591
+ options = DEFAULT_SCROLL_ANIMATION_OPTIONS;
5532
5592
  }
5533
5593
  const [isInView, setIsInView] = React.useState(false);
5534
5594
  const [progress, setProgress] = React.useState(0);
@@ -5596,7 +5656,7 @@ const useSmoothScroll = targetWindow => {
5596
5656
  // Enhanced useInfiniteScroll with debouncing
5597
5657
  const useInfiniteScroll = function (callback, options) {
5598
5658
  if (options === void 0) {
5599
- options = {};
5659
+ options = DEFAULT_INFINITE_SCROLL_OPTIONS;
5600
5660
  }
5601
5661
  const [sentinel, setSentinel] = React.useState(null);
5602
5662
  const callbackRef = React.useRef(callback);
@@ -5691,12 +5751,13 @@ const useScrollDirection = function (threshold, targetWindow) {
5691
5751
 
5692
5752
  const useWindowSize = () => React.useContext(WindowSizeContext);
5693
5753
 
5754
+ const DEFAULT_IN_VIEW_OPTIONS = {};
5694
5755
  function useInView(options) {
5695
5756
  const {
5696
5757
  triggerOnce = false,
5697
5758
  targetWindow,
5698
5759
  ...observerOptions
5699
- } = options || {};
5760
+ } = options || DEFAULT_IN_VIEW_OPTIONS;
5700
5761
  const ref = React.useRef(null);
5701
5762
  const [inView, setInView] = React.useState(false);
5702
5763
  React.useEffect(() => {
@@ -5726,7 +5787,7 @@ function useInView(options) {
5726
5787
  return () => {
5727
5788
  observer.disconnect();
5728
5789
  };
5729
- }, [triggerOnce, targetWindow, ...Object.values(observerOptions || {})]);
5790
+ }, [triggerOnce, targetWindow, observerOptions.root, observerOptions.rootMargin, observerOptions.threshold]);
5730
5791
  return {
5731
5792
  ref,
5732
5793
  inView
@@ -5811,7 +5872,7 @@ function useIframe(iframeRef) {
5811
5872
  if (!iframe) return;
5812
5873
  const updateState = () => {
5813
5874
  const win = iframe.contentWindow;
5814
- const doc = iframe.contentDocument || win?.document;
5875
+ const doc = win?.document || iframe.contentDocument;
5815
5876
  if (win && doc) {
5816
5877
  setIframeWindow(win);
5817
5878
  setIframeDocument(doc);
@@ -1 +1 @@
1
- {"version":3,"file":"app-studio.cjs.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"app-studio.cjs.development.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}