{"version":3,"file":"6019.6f3bb996.js","mappings":"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","sources":["webpack://@finviz/website/../config/colors.js","webpack://@finviz/website/./js/app/maps/constants/constants.ts","webpack://@finviz/website/./js/app/maps/constants/generator.ts","webpack://@finviz/website/./js/app/maps/constants/settings.ts","webpack://@finviz/website/./js/app/maps/layout-generator.tsx","webpack://@finviz/website/./js/app/maps/types.ts","webpack://@finviz/website/./js/app/maps/utils.ts","webpack://@finviz/website/./js/app/queryString.ts","webpack://@finviz/website/./js/app/screener/utils.ts","webpack://@finviz/website/./js/app/shared/documentVisibility.ts","webpack://@finviz/website/./js/app/shared/isStockFastRefreshAvailable.ts","webpack://@finviz/website/./js/app/shared/utils.ts","webpack://@finviz/website/./js/main/components/DateInputWithPicker/useDateInputWithPickerValue.ts","webpack://@finviz/website/./js/main/components/DateInputWithPicker/DateInputWithPicker.tsx","webpack://@finviz/website/./js/main/components/MenuGroup.tsx","webpack://@finviz/website/./js/main/components/OptionButton.tsx","webpack://@finviz/website/./js/main/components/RedGreenText.tsx","webpack://@finviz/website/./js/main/components/Table/TableStickyColumnWrapper.tsx","webpack://@finviz/website/./js/main/components/Table/Table.tsx","webpack://@finviz/website/./js/main/components/Table/constants.ts","webpack://@finviz/website/./js/main/components/Table/types.ts","webpack://@finviz/website/./js/main/components/Table/TableCell.tsx","webpack://@finviz/website/./js/main/components/Table/TableHeader.tsx","webpack://@finviz/website/./js/main/components/Table/TableRow.tsx","webpack://@finviz/website/./js/main/components/Table/hooks.ts","webpack://@finviz/website/./js/main/components/Table/utils.ts","webpack://@finviz/website/./js/main/components/button-group/button-group.tsx","webpack://@finviz/website/./js/main/components/date-picker/index.tsx","webpack://@finviz/website/./js/main/components/delayed.tsx","webpack://@finviz/website/./js/main/components/dialog/dialog-box.tsx","webpack://@finviz/website/./js/main/components/dialog/dialog.tsx","webpack://@finviz/website/./js/main/hooks/use-screen-size.ts","webpack://@finviz/website/./js/main/components/dialog/dialog-body.tsx","webpack://@finviz/website/./js/main/components/dialog/confirmation-dialog.tsx","webpack://@finviz/website/./js/main/components/dialog/dialog-footer.tsx","webpack://@finviz/website/./js/main/components/dialog/dialog-header.tsx","webpack://@finviz/website/./js/main/components/label-with-delayed-spinner.tsx","webpack://@finviz/website/./js/main/components/popover/popover.tsx","webpack://@finviz/website/./js/main/components/popover/PopoverProvider.tsx","webpack://@finviz/website/./js/main/components/popover/hooks.ts","webpack://@finviz/website/./js/main/components/popover/popover-trigger.tsx","webpack://@finviz/website/./js/main/components/select/NativeSelect.tsx","webpack://@finviz/website/./js/main/components/select/SelectOption.tsx","webpack://@finviz/website/./js/main/components/select/SelectItems.tsx","webpack://@finviz/website/./js/main/components/select/SelectList.tsx","webpack://@finviz/website/./js/main/components/select/SelectTooltipWrapper.tsx","webpack://@finviz/website/./js/main/components/select/DesktopSelect.tsx","webpack://@finviz/website/./js/main/components/select/SelectButton.tsx","webpack://@finviz/website/./js/main/components/select/Select.tsx","webpack://@finviz/website/./js/main/components/select/utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/daterange-select.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/timeframe-select.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/timeframe-bar.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/custom-date-range-utils.ts","webpack://@finviz/website/./js/main/components/timeframe-bar/custom-date-range.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/use-custom-date-range-dialog.tsx","webpack://@finviz/website/./js/main/components/timeframe-bar/use-favorite-timeframes.tsx","webpack://@finviz/website/./js/main/hooks/use-sync-local-storage.ts","webpack://@finviz/website/./js/main/hooks/use-element-measure.ts","webpack://@finviz/website/./js/main/hooks/use-is-mounted.ts","webpack://@finviz/website/./js/main/hooks/use-previous.ts","webpack://@finviz/website/./js/main/hooks/use-sort-data.ts","webpack://@finviz/website/./js/main/hooks/useVisualViewport.ts","webpack://@finviz/website/./js/main/modules/portfolio/constants/columns.tsx","webpack://@finviz/website/./js/main/modules/portfolio/constants/general.ts","webpack://@finviz/website/./js/main/modules/portfolio/services/api.ts","webpack://@finviz/website/./js/main/modules/portfolio/types.tsx","webpack://@finviz/website/./js/main/modules/portfolio/utils.ts","webpack://@finviz/website/./js/main/services/local-storage.ts","webpack://@finviz/website/./js/main/services/wait-for-previous-promise.ts"],"sourcesContent":["// Keep in sync with charts repository colors.js file in: app/constants/colors.js\r\n\r\nmodule.exports = {\r\n white: '#fff',\r\n black: '#000',\r\n inherit: 'inherit',\r\n transparent: 'transparent',\r\n current: 'currentColor',\r\n finviz: {\r\n 'blue-gray': '#262931',\r\n blue: '#4fa4f4',\r\n },\r\n gray: {\r\n 50: '#f3f3f5',\r\n 100: '#dedfe5',\r\n 200: '#c3c6d0',\r\n 300: '#a3a8b9',\r\n 400: '#868ea5',\r\n 500: '#676f85',\r\n 600: '#4c5263',\r\n 700: '#353945',\r\n 750: '#2c303b',\r\n 800: '#22262f',\r\n 900: '#14161d',\r\n },\r\n red: {\r\n 50: '#fef0f0',\r\n 100: '#fcd6d6',\r\n 200: '#fbb4b4',\r\n 300: '#fd8487',\r\n 400: '#fb5057',\r\n 500: '#d91e2b',\r\n 600: '#9f1f2a',\r\n 700: '#691f24',\r\n 800: '#45171a',\r\n 900: '#280e0f',\r\n },\r\n orange: {\r\n 50: '#fef2eb',\r\n 100: '#fdd9c5',\r\n 200: '#fab889',\r\n 300: '#ef9323',\r\n 400: '#ca7b14',\r\n 500: '#a0600e',\r\n 600: '#79460a',\r\n 700: '#583006',\r\n 800: '#3d1e03',\r\n 900: '#261101',\r\n },\r\n amber: {\r\n 50: '#fef2e7',\r\n 100: '#fedab5',\r\n 200: '#fbba56',\r\n 300: '#de9c1a',\r\n 400: '#bb830f',\r\n 500: '#956600',\r\n 600: '#704b00',\r\n 700: '#4f3400',\r\n 800: '#372200',\r\n 900: '#211300',\r\n },\r\n tangerine: {\r\n 50: '#fef1ee',\r\n 100: '#fed8ce',\r\n 200: '#fdb5a0',\r\n 300: '#fc8955',\r\n 400: '#db6e35',\r\n 500: '#b35314',\r\n 600: '#814021',\r\n 700: '#5a2d18',\r\n 800: '#3c1e12',\r\n 900: '#291711',\r\n },\r\n yellow: {\r\n 50: '#fdf2df',\r\n 100: '#fcdc86',\r\n 200: '#f3c736',\r\n 300: '#cda30b',\r\n 400: '#b08900',\r\n 500: '#8b6a00',\r\n 600: '#664e21',\r\n 700: '#46371e',\r\n 800: '#2f2516',\r\n 900: '#1b150d',\r\n },\r\n brightYellow: {\r\n 50: '#fff699',\r\n 100: '#fff200',\r\n },\r\n lime: {\r\n 50: '#ebfad6',\r\n 100: '#caec90',\r\n 200: '#aad547',\r\n 300: '#8db61e',\r\n 400: '#769913',\r\n 500: '#5b7800',\r\n 600: '#435900',\r\n 700: '#2e3e00',\r\n 800: '#1e2a00',\r\n 900: '#111900',\r\n },\r\n green: {\r\n 50: '#e7f7e8',\r\n 100: '#beeac1',\r\n 200: '#86d895',\r\n 300: '#34c062',\r\n 400: '#00a449',\r\n 500: '#19803d',\r\n 600: '#265d35',\r\n 700: '#1e4027',\r\n 800: '#162b1b',\r\n 900: '#0d1810',\r\n },\r\n emerald: {\r\n 50: '#ddfaee',\r\n 100: '#a2f0d2',\r\n 200: '#4dddaf',\r\n 300: '#25be93',\r\n 400: '#1d9f7b',\r\n 500: '#157e60',\r\n 600: '#035d47',\r\n 700: '#004139',\r\n 800: '#002c22',\r\n 900: '#001a13',\r\n },\r\n teal: {\r\n 50: '#e0f8fc',\r\n 100: '#9beef7',\r\n 200: '#4fd8e5',\r\n 300: '#27b9c4',\r\n 400: '#109ba5',\r\n 500: '#007c83',\r\n 600: '#005b62',\r\n 700: '#004045',\r\n 800: '#002b2e',\r\n 900: '#00191b',\r\n },\r\n blue: {\r\n 50: '#ebf4fe',\r\n 100: '#cae2fc',\r\n 200: '#9bcbfa',\r\n 300: '#57aefb',\r\n 400: '#2f91ef',\r\n 500: '#306dca',\r\n 600: '#2f5091',\r\n 700: '#263766',\r\n 800: '#1b2542',\r\n 900: '#101527',\r\n },\r\n violet: {\r\n 50: '#f4f2fe',\r\n 100: '#e1dbfd',\r\n 200: '#c9befc',\r\n 300: '#ad9bfb',\r\n 400: '#9978f9',\r\n 500: '#7c51e7',\r\n 600: '#5e36b8',\r\n 700: '#402979',\r\n 800: '#2a1e4e',\r\n 900: '#18122c',\r\n },\r\n purple: {\r\n 50: '#f9f1fe',\r\n 100: '#eed8fd',\r\n 200: '#e1b6fc',\r\n 300: '#d38bfb',\r\n 400: '#c85bf9',\r\n 500: '#ae27e0',\r\n 600: '#8514ac',\r\n 700: '#60077e',\r\n 800: '#44005a',\r\n 900: '#2a003a',\r\n },\r\n pink: {\r\n 50: '#fef1f4',\r\n 100: '#fdd6e1',\r\n 200: '#fcb2c7',\r\n 300: '#f984aa',\r\n 400: '#f25090',\r\n 500: '#cd2a74',\r\n 600: '#9d1658',\r\n 700: '#700c42',\r\n 800: '#4e052b',\r\n 900: '#32011a',\r\n },\r\n}\r\n","import { MapSubtype, MapSubtypeId, MapType, MapTypeId, PerfData, ScaleId } from '../types'\r\n\r\nexport const EXPANDED_MAP_BODY_CLASSS = 'is-map-expanded'\r\nexport const FALLBACK_PERF_RESPONSE: PerfData = { nodes: {}, additional: {}, subtype: MapSubtypeId.DayPerf, hash: '' }\r\n\r\ntype SubtypesRecord = Record\r\ntype SubtypesGroup = { items: MapSubtype[] }\r\n\r\nconst MAP_SUBTYPES_INTRADAY_BY_ID: SubtypesRecord = {\r\n [MapSubtypeId.IntradayPerf1m]: {\r\n value: MapSubtypeId.IntradayPerf1m,\r\n label: '1-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 1 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf2m]: {\r\n value: MapSubtypeId.IntradayPerf2m,\r\n label: '2-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 2 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf3m]: {\r\n value: MapSubtypeId.IntradayPerf3m,\r\n label: '3-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 3 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf5m]: {\r\n value: MapSubtypeId.IntradayPerf5m,\r\n label: '5-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 5 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf10m]: {\r\n value: MapSubtypeId.IntradayPerf10m,\r\n label: '10-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 10 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf15m]: {\r\n value: MapSubtypeId.IntradayPerf15m,\r\n label: '15-Minute Performance',\r\n scaleId: ScaleId.IntradayReduced,\r\n tooltip:\r\n 'Color indicates 15 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf30m]: {\r\n value: MapSubtypeId.IntradayPerf30m,\r\n label: '30-Minute Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n 'Color indicates 30 minute stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf1h]: {\r\n value: MapSubtypeId.IntradayPerf1h,\r\n label: '1-Hour Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n 'Color indicates 1 hour stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf2h]: {\r\n value: MapSubtypeId.IntradayPerf2h,\r\n label: '2-Hour Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n 'Color indicates 2 hour stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerf4h]: {\r\n value: MapSubtypeId.IntradayPerf4h,\r\n label: '4-Hour Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n 'Color indicates 4 hour stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.IntradayPerfAH]: {\r\n value: MapSubtypeId.IntradayPerfAH,\r\n label: 'After-Hours Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n 'Color indicates after-hours stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n}\r\n\r\nconst MAP_SUBTYPES_INTERDAY_BY_ID: SubtypesRecord = {\r\n [MapSubtypeId.DayPerf]: {\r\n value: MapSubtypeId.DayPerf,\r\n label: '1-Day Performance',\r\n scaleId: ScaleId.DayPerf,\r\n tooltip:\r\n \"Color indicates today's stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.WeekPerf]: {\r\n value: MapSubtypeId.WeekPerf,\r\n label: '1-Week Performance',\r\n scaleId: ScaleId.WeekPerf,\r\n tooltip:\r\n 'Color indicates weekly stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.MonthPerf]: {\r\n value: MapSubtypeId.MonthPerf,\r\n label: '1-Month Performance',\r\n scaleId: ScaleId.MonthPerf,\r\n tooltip:\r\n 'Color indicates monthly stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.ThreeMonthPerf]: {\r\n value: MapSubtypeId.ThreeMonthPerf,\r\n label: '3-Month Performance',\r\n scaleId: ScaleId.ThreeMonthPerf,\r\n tooltip:\r\n 'Color indicates quarterly stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.SixMonthPerf]: {\r\n value: MapSubtypeId.SixMonthPerf,\r\n label: '6-Month Performance',\r\n scaleId: ScaleId.SixMonthPerf,\r\n tooltip:\r\n 'Color indicates half-yearly stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.YearPerf]: {\r\n value: MapSubtypeId.YearPerf,\r\n label: '1-Year Performance',\r\n scaleId: ScaleId.YearPerf,\r\n tooltip:\r\n 'Color indicates yearly stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.YearToDatePerf]: {\r\n value: MapSubtypeId.YearToDatePerf,\r\n label: 'Year To Date Performance',\r\n scaleId: ScaleId.YearPerf,\r\n tooltip:\r\n 'Color indicates year to date stock performance in percent. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n}\r\n\r\nexport const MAP_SUBTYPES_GENERAL: SubtypesRecord = {\r\n [MapSubtypeId.RelativeVolume]: {\r\n value: MapSubtypeId.RelativeVolume,\r\n label: 'Relative Volume',\r\n scaleId: ScaleId.RelativeVolume,\r\n tooltip:\r\n \"Color indicates the stock's relative volume, ratio between today's and average volume. Values above 1.5 show strong volume, values below 0.5 indicate weak volume.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.PriceToEarnings]: {\r\n value: MapSubtypeId.PriceToEarnings,\r\n label: 'P/E',\r\n scaleId: ScaleId.PriceToEarnings,\r\n tooltip: \"Color indicates the stock's price-to-earnings ratio.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.ForwardPriceToEearnings]: {\r\n value: MapSubtypeId.ForwardPriceToEearnings,\r\n label: 'Forward P/E',\r\n scaleId: ScaleId.ForwardPriceToEearnings,\r\n tooltip: \"Color indicates the stock's forward price-to-earnings ratio.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.PriceEarningsToGrowth]: {\r\n value: MapSubtypeId.PriceEarningsToGrowth,\r\n label: 'PEG',\r\n scaleId: ScaleId.PriceEarningsToGrowth,\r\n tooltip: \"Color indicates the stock's price-to-earnings-to-growth ratio.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.PriceToSellsRatio]: {\r\n value: MapSubtypeId.PriceToSellsRatio,\r\n label: 'P/S',\r\n scaleId: ScaleId.PriceToSellsRatio,\r\n tooltip: \"Color indicates the stock's price-to-sales ratio.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.PriceToBookRatio]: {\r\n value: MapSubtypeId.PriceToBookRatio,\r\n label: 'P/B',\r\n scaleId: ScaleId.PriceToBookRatio,\r\n tooltip: \"Color indicates the stock's price-to-book ratio.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.DividendYield]: {\r\n value: MapSubtypeId.DividendYield,\r\n label: 'Dividend Yield',\r\n scaleId: ScaleId.DividendYield,\r\n tooltip: \"Color indicates the stock's dividend yield.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.EPSGrowth5y]: {\r\n value: MapSubtypeId.EPSGrowth5y,\r\n label: 'EPS Growth Past 5 Years',\r\n scaleId: ScaleId.EPSGrowth5y,\r\n tooltip: \"Color indicates the stock's annual earnings (EPS) growth over past 5 years.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.FloatShort]: {\r\n value: MapSubtypeId.FloatShort,\r\n label: 'Float Short',\r\n scaleId: ScaleId.FloatShort,\r\n tooltip: \"Color indicates percent of the stock's float sold short.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.AnalystRecommendation]: {\r\n value: MapSubtypeId.AnalystRecommendation,\r\n label: 'Analysts Recom.',\r\n scaleId: ScaleId.AnalystRecommendation,\r\n tooltip:\r\n \"Color indicates the analyst's recommendations for given stocks. The rating is based on a 1-5 scale, ranging from a strong-buy, to a strong-sell.\",\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n },\r\n [MapSubtypeId.EarningsPerf]: {\r\n value: MapSubtypeId.EarningsPerf,\r\n label: 'Earnings Day Performance',\r\n scaleId: ScaleId.MonthPerf,\r\n tooltip:\r\n \"Color indicates stock's performance on earnings day. Next day performance for earnings reported after market close.\",\r\n countIndustryPerf: false,\r\n countSectorPerf: false,\r\n },\r\n [MapSubtypeId.EarningsDate]: {\r\n value: MapSubtypeId.EarningsDate,\r\n label: 'Earnings Date',\r\n scaleId: ScaleId.EarningsDate,\r\n tooltip: \"Color indicates stock's earnings date.\",\r\n countIndustryPerf: false,\r\n countSectorPerf: false,\r\n },\r\n}\r\n\r\nexport const MAP_SUBTYPE_DAY_PERF = MAP_SUBTYPES_INTERDAY_BY_ID[MapSubtypeId.DayPerf]\r\nexport const MAP_SUBTYPE_MANAGERS_FUNDS = {\r\n value: MapSubtypeId.ManagersAndFunds,\r\n label: 'Holdings',\r\n scaleId: ScaleId.PercentHundred,\r\n tooltip:\r\n 'Color indicates holdings change in percent for currently selected quarter. Based on the color you can identify losers (red), neutral (black), and gainers (green).',\r\n countIndustryPerf: true,\r\n countSectorPerf: true,\r\n}\r\n\r\nconst MAP_SUBTYPES_INTRADAY: SubtypesGroup = { items: Object.values(MAP_SUBTYPES_INTRADAY_BY_ID) }\r\nconst MAP_SUBTYPES_INTERDAY: SubtypesGroup = { items: Object.values(MAP_SUBTYPES_INTERDAY_BY_ID) }\r\nconst MAP_SUBTYPES_TIMEFRAMES: SubtypesGroup[] = FinvizSettings.hasUserPremium\r\n ? [MAP_SUBTYPES_INTRADAY, MAP_SUBTYPES_INTERDAY]\r\n : [\r\n {\r\n items: [\r\n {\r\n label: 'Intraday',\r\n // @ts-expect-error - This isn’t a real selectable option, it’ll redirect users on click\r\n href: '/elite.ashx?utm_source=finviz&utm_medium=banner&utm_campaign=maps_intraday',\r\n reloadDocument: true,\r\n },\r\n ],\r\n },\r\n MAP_SUBTYPES_INTERDAY,\r\n ]\r\n\r\nexport const MAP_SUBTYPES_COMPANIES: SubtypesGroup[] = [\r\n ...MAP_SUBTYPES_TIMEFRAMES,\r\n { items: Object.values(MAP_SUBTYPES_GENERAL) },\r\n]\r\n\r\nexport const MAP_SUBTYPES_ETF: SubtypesGroup[] = [\r\n ...MAP_SUBTYPES_TIMEFRAMES,\r\n { items: [MAP_SUBTYPES_GENERAL[MapSubtypeId.RelativeVolume]] },\r\n]\r\n\r\nexport const MAP_TYPES: MapType[] = [\r\n {\r\n name: 'S&P 500',\r\n pageTitle: 'S&P 500 Map',\r\n description:\r\n \"Standard and Poor's 500 index stocks categorized by sectors and industries. Size represents market cap.\",\r\n type: MapTypeId.Sector,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\r\n },\r\n {\r\n name: 'World',\r\n pageTitle: 'World Map',\r\n description:\r\n 'Foreign ADR stocks listed on NYSE, NASDAQ, AMEX categorized by geo location. Size represents market cap.',\r\n type: MapTypeId.World,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\r\n },\r\n {\r\n name: 'Full',\r\n pageTitle: 'Stock Market Map',\r\n description:\r\n 'All stocks listed on US stock exchanges, categorized by sectors and industries. Size represents market cap.',\r\n type: MapTypeId.SectorFull,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\r\n },\r\n {\r\n name: 'Exchange Traded Funds',\r\n pageTitle: 'ETF Map - Exchange Traded Funds Map',\r\n nameShort: 'ETF',\r\n description: 'ETFs categorized by sectors and styles. Size represents 3-month average dollar volume, $1M minimum.',\r\n type: MapTypeId.ETF,\r\n subtypes: MAP_SUBTYPES_ETF,\r\n },\r\n]\r\n\r\nexport const MAP_TYPE_SCREENER = {\r\n name: 'Screener',\r\n pageTitle: 'Screener Map',\r\n description:\r\n 'All stocks listed on US stock exchanges, categorized by sectors and industries. Stock size represents market cap.',\r\n type: MapTypeId.Screener,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\r\n}\r\n\r\nexport const MAP_TYPE_ETF_HOLDINGS_WIDGET = {\r\n name: 'ETF Holdings',\r\n pageTitle: '',\r\n description: '',\r\n type: MapTypeId.ETFHoldings,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\r\n}\r\n\r\nexport const MAP_TYPE_MANAGERS_FUNDS_WIDGET = {\r\n name: 'Holdings',\r\n pageTitle: '',\r\n description: '',\r\n type: MapTypeId.ManagersAndFunds,\r\n subtypes: [{ items: [MAP_SUBTYPE_MANAGERS_FUNDS] }],\r\n}\r\n","export type MapOrder = Record\r\n\r\nexport const MAP_MIN_WIDTH = 700\r\nexport const MAP_MIN_HEIGHT = 388\r\nexport const SECTOR_MIN_HEIGHT = 5\r\nexport const LEGEND_HEIGHT = 79\r\n\r\nexport const LARGE_MAP_HEIGHT_RATIO = 1.8\r\nexport const SMALL_MAP_GEO_HEIGHT_RATIO = 1.7\r\nexport const SMALL_MAP_HEIGHT_RATIO = 1.085 // old design ratio - 1.33\r\n\r\n// Minimal size of node to display header\r\nexport const LARGE_NODE_SIZE = {\r\n dx: 40,\r\n dy: 12,\r\n}\r\n\r\n// Don't display header if node height - header is smaller than this\r\nexport const LARGE_NODE_MIN_HEIGHT = 5\r\n\r\nexport const ORDER_SP500: MapOrder = {\r\n Technology: 10,\r\n Financial: 11,\r\n 'Communication Services': 7,\r\n 'Consumer Defensive': 8,\r\n 'Consumer Cyclical': 9,\r\n Healthcare: 6,\r\n Industrials: 5,\r\n 'Real Estate': 4,\r\n Energy: 3,\r\n Utilities: 2,\r\n 'Basic Materials': 1,\r\n\r\n // Industries\r\n 'Software - Infrastructure': 2,\r\n Semiconductors: 1,\r\n}\r\n\r\nexport const ORDER_SP500_SMALL: MapOrder = {\r\n ...ORDER_SP500,\r\n 'Communication Services': 9,\r\n 'Consumer Defensive': 8,\r\n 'Consumer Cyclical': 7,\r\n}\r\n\r\nexport const ORDER_SEC_ALL: MapOrder = {\r\n Financial: 10,\r\n Technology: 9,\r\n 'Communication Services': 8,\r\n 'Consumer Cyclical': 6,\r\n 'Consumer Defensive': 7,\r\n Healthcare: 5,\r\n Industrials: 4,\r\n 'Real Estate': 3,\r\n Energy: 2,\r\n Utilities: 1,\r\n 'Basic Materials': 0,\r\n\r\n // Industries\r\n 'Software - Infrastructure': 2,\r\n Semiconductors: 1,\r\n}\r\nexport const ORDER_ETF: MapOrder = {\r\n US: 11,\r\n 'US Sector': 10,\r\n 'US Large Cap': 9,\r\n 'US Mid Cap': 8,\r\n 'US Small Cap': 7,\r\n 'US Volatility': 6,\r\n Global: 5,\r\n International: 3,\r\n 'Fixed Income': 2,\r\n Commodity: 4,\r\n Strategy: 1,\r\n Forex: 0,\r\n}\r\n\r\nexport const ORDER_SCREENER: MapOrder = {\r\n Technology: 10,\r\n Financial: 9,\r\n 'Communication Services': 8,\r\n Healthcare: 7,\r\n 'Consumer Cyclical': 6,\r\n 'Consumer Defensive': 5,\r\n Industrials: 4,\r\n 'Real Estate': 3,\r\n Energy: 2,\r\n Utilities: 1,\r\n 'Basic Materials': 0,\r\n}\r\n\r\nexport const ORDER_WORLD: MapOrder = {\r\n Ireland: 20,\r\n 'United Kingdom': 19,\r\n Spain: 18,\r\n France: 17,\r\n Belgium: 16,\r\n Netherlands: 15,\r\n Switzerland: 14,\r\n\r\n China: 21,\r\n Japan: 20,\r\n India: 19,\r\n 'Hong Kong': 18,\r\n 'South Korea': 15,\r\n Taiwan: 14,\r\n\r\n Panama: 5,\r\n Peru: 4,\r\n Chile: 3,\r\n Colombia: 2,\r\n Argentina: 1,\r\n Brazil: 0,\r\n}\r\n\r\nexport const WORLD_INDUSTRIES = [\r\n {\r\n x: 4,\r\n y: 0,\r\n dx: 240,\r\n dy: 226,\r\n name: 'Canada',\r\n countries: ['Canada'],\r\n },\r\n {\r\n x: 4,\r\n y: 230,\r\n dx: 240,\r\n dy: 135,\r\n name: 'Mexico',\r\n countries: ['Cayman Islands', 'Bermuda', 'Mexico'],\r\n },\r\n {\r\n x: 4,\r\n y: 375,\r\n dx: 240,\r\n dy: 170,\r\n name: 'South America',\r\n countries: ['Netherlands Antilles', 'Panama', 'Peru', 'Argentina', 'Colombia', 'Chile', 'Brazil'],\r\n },\r\n {\r\n x: 730,\r\n y: 380,\r\n dx: 108,\r\n dy: 80,\r\n name: 'South Africa',\r\n countries: ['South Africa'],\r\n },\r\n {\r\n x: 725,\r\n y: 180,\r\n dx: 108,\r\n dy: 81,\r\n name: 'Israel',\r\n countries: ['Israel'],\r\n },\r\n {\r\n x: 1055,\r\n y: 420,\r\n dx: 144,\r\n dy: 80,\r\n name: 'Australia',\r\n countries: ['Australia'],\r\n },\r\n {\r\n x: 871,\r\n y: 0,\r\n dx: 336,\r\n dy: 396,\r\n name: 'Asia',\r\n countries: [\r\n 'Malaysia',\r\n 'Russia',\r\n 'Philippines',\r\n 'Indonesia',\r\n 'Singapore',\r\n 'South Korea',\r\n 'Taiwan',\r\n 'India',\r\n 'Hong Kong',\r\n 'Japan',\r\n 'China',\r\n ],\r\n },\r\n {\r\n x: 324,\r\n y: 0,\r\n dx: 374,\r\n dy: 428,\r\n name: 'Europe',\r\n countries: [\r\n 'Cyprus',\r\n 'Channel Islands',\r\n 'Greece',\r\n 'Luxembourg',\r\n 'Germany',\r\n 'Belgium',\r\n 'Spain',\r\n 'France',\r\n 'Ireland',\r\n 'Switzerland',\r\n 'Netherlands',\r\n 'United Kingdom',\r\n ],\r\n },\r\n {\r\n x: 697,\r\n y: 75,\r\n dx: 144,\r\n dy: 51,\r\n name: 'Frozen',\r\n countries: ['Finland', 'Sweden', 'Norway', 'Denmark'],\r\n },\r\n {\r\n x: 542,\r\n y: 414,\r\n dx: 102,\r\n dy: 68,\r\n name: 'Italy',\r\n countries: ['Italy'],\r\n },\r\n]\r\n","import tailwindColors from '../../../../../config/colors'\r\nimport { ScaleId } from '../types'\r\n\r\nexport interface ISettings {\r\n padding: { top: number; right: number; bottom: number; left: number }\r\n background: string\r\n industry: ISettingsSection\r\n sector: ISettingsSection\r\n scaleFontSizes: Record\r\n fontSizePadding: Record\r\n fontSizePairs: Record\r\n}\r\n\r\nexport interface ISettingsSection {\r\n padding: { top: number; right: number; bottom: number; left: number }\r\n background: string | null\r\n border: string | null\r\n header: ISettingsSectionHeader\r\n hover?: ISettingsSectionHeader\r\n}\r\n\r\nexport interface ISettingsSectionHeader extends ISettingsSectionFont {\r\n background: string | null\r\n border: string | null\r\n height: number\r\n margin: { top: number; right: number; bottom: number; left: number }\r\n}\r\n\r\nexport interface ISettingsSectionFont {\r\n color: string\r\n fontSize: number\r\n fontWeight: 'bold' | 'normal'\r\n padding: { top: number; right: number; left: number }\r\n}\r\n\r\nexport const scaleMinMax: Record = {\r\n [ScaleId.IntradayReduced]: [-1, 1],\r\n [ScaleId.DayPerf]: [-3, 3],\r\n _5: [-6, 6],\r\n _10: [-10, 10],\r\n _15: [-18, 18],\r\n _20: [-24, 24],\r\n _25: [-30, 30],\r\n _relvol: [0, 3],\r\n _pe: [0, 30],\r\n _fpe: [0, 30],\r\n _peg: [0, 3],\r\n _ps: [0, 5],\r\n _pb: [0, 5],\r\n _div: [0, 5],\r\n _eps5y: [-50, 50],\r\n _short: [0, 15],\r\n _rec: [5, 1],\r\n _earndate: [30, -30],\r\n // Portfolio — values are just placeholders, the real value is computed from data\r\n _portfolioPct: [-1, 1],\r\n _portfolioUsd: [-1, 1],\r\n _percentHundred: [-100, 100],\r\n}\r\n\r\nexport const scaleStepFormat: Record = {\r\n [ScaleId.IntradayReduced]: '%N%',\r\n [ScaleId.DayPerf]: '%N%',\r\n _5: '%N%',\r\n _10: '%N%',\r\n _15: '%N%',\r\n _20: '%N%',\r\n _25: '%N%',\r\n _relvol: '%N',\r\n _pe: '%N',\r\n _fpe: '%N',\r\n _peg: '%N',\r\n _ps: '%N',\r\n _pb: '%N',\r\n _div: '%N%',\r\n _eps5y: '%N%',\r\n _short: '%N%',\r\n _rec: { 1: '%N Strong Buy', 2: '%N Buy', 3: '%N Hold', 4: '%N Sell', 5: '%N Strong Sell' },\r\n _earndate: {\r\n '-30': '%N Days',\r\n '-15': '%N Days',\r\n '-1': 'After Earnings',\r\n 1: 'Before Earnings',\r\n 15: '%N Days',\r\n 30: '%N Days',\r\n },\r\n _portfolioPct: '%N%',\r\n _portfolioUsd: '$%N',\r\n _percentHundred: '%N%',\r\n}\r\n\r\nexport const Settings: ISettings = {\r\n padding: { top: 0, right: 0, bottom: 1, left: 1 },\r\n background: tailwindColors.finviz['blue-gray'],\r\n sector: {\r\n padding: { top: 0, right: 1, bottom: 1, left: 1 },\r\n background: null,\r\n border: null,\r\n header: {\r\n color: '#fff',\r\n background: null,\r\n border: null,\r\n height: 14.5,\r\n fontSize: 13,\r\n fontWeight: 'bold',\r\n margin: { top: 0, right: 0, bottom: 0, left: 0 },\r\n padding: { top: -1, right: 4, left: 4 },\r\n },\r\n },\r\n industry: {\r\n padding: { top: 0, right: 1, bottom: 1, left: 1 },\r\n background: null,\r\n border: null,\r\n header: {\r\n color: '#fff',\r\n background: null,\r\n border: tailwindColors.finviz['blue-gray'],\r\n height: 12,\r\n fontSize: 10,\r\n fontWeight: 'normal',\r\n margin: { top: 0, right: 0.5, bottom: 0, left: -0.5 },\r\n padding: { top: -0.5, right: 4, left: 4 },\r\n },\r\n hover: {\r\n color: '#6b5811',\r\n background: '#ffd614',\r\n border: '#ffd614',\r\n height: 12,\r\n fontSize: 10,\r\n fontWeight: 'normal',\r\n margin: { top: 0, right: 0, bottom: 0, left: 0 },\r\n padding: { top: -0.5, right: 3, left: 4 },\r\n },\r\n },\r\n scaleFontSizes: {\r\n 1: [36, 30, 24, 20, 18, 14, 13, 12, 11, 10, 9, 8],\r\n 1.5: [36, 30, 24, 20, 18, 14, 13, 12, 11, 10, 9, 8, 6, 4],\r\n 2.25: [36, 30, 24, 20, 18, 14, 13, 12, 11, 10, 9, 8, 6, 4],\r\n 3: [36, 30, 24, 20, 18, 14, 13, 12, 11, 10, 9, 8, 6, 4],\r\n },\r\n fontSizePadding: {\r\n 36: 30,\r\n 30: 25,\r\n 24: 20,\r\n 20: 14,\r\n 18: 12,\r\n 14: 9,\r\n 13: 7,\r\n 12: 7,\r\n 11: 4,\r\n 10: 3,\r\n 9: 3,\r\n 8: 2.5,\r\n 6: 0,\r\n 4: 1,\r\n },\r\n fontSizePairs: {\r\n 36: [18, 14, 13, 12],\r\n 30: [14, 13, 12, 11, 10],\r\n 24: [14, 13, 12, 11, 10],\r\n 20: [12, 11, 10, 9, 8, 6],\r\n 18: [11, 10, 9, 8, 6],\r\n 14: [9, 8, 6, 4],\r\n 13: [9, 8, 6, 4],\r\n 12: [9, 8, 6, 4],\r\n 11: [8, 6, 4],\r\n 10: [10, 9, 8, 6, 4],\r\n 9: [9, 8, 6, 4],\r\n 8: [8, 6, 4],\r\n 6: [6, 4],\r\n 4: [4],\r\n },\r\n}\r\n\r\nexport const SettingsSmall: ISettings = {\r\n ...Settings,\r\n padding: { top: 0, right: 0, bottom: 0, left: 0 },\r\n background: '#343842',\r\n sector: {\r\n ...Settings.industry,\r\n padding: { top: 0.5, right: 0, bottom: 0, left: 2 },\r\n border: '#e0e0e0',\r\n header: {\r\n ...Settings.industry.header,\r\n margin: { top: 0, right: 0.5, bottom: 0, left: -1.5 },\r\n padding: { top: 0.5, right: 1, left: 1 },\r\n border: '#343842',\r\n fontSize: 9,\r\n },\r\n },\r\n industry: {\r\n ...Settings.industry,\r\n padding: { top: 0, right: 1, bottom: 1, left: 0 },\r\n header: {\r\n ...Settings.industry.header,\r\n height: 0,\r\n },\r\n },\r\n scaleFontSizes: { ...Settings.scaleFontSizes, 1: [14, 12, 11, 8, 6] },\r\n fontSizePadding: { 14: 5, 12: 2, 11: 2, 8: 2, 6: 0, 4: 0 },\r\n fontSizePairs: {\r\n 14: [9, 8, 6],\r\n 13: [9, 8, 6],\r\n 12: [6],\r\n 11: [6],\r\n 10: [6],\r\n 9: [6],\r\n 8: [6],\r\n 6: [6],\r\n },\r\n}\r\n\r\nexport const SettingsSmallDark: ISettings = {\r\n ...SettingsSmall,\r\n sector: {\r\n ...SettingsSmall.sector,\r\n background: tailwindColors.gray[800],\r\n border: tailwindColors.gray[800],\r\n header: {\r\n ...SettingsSmall.sector.header,\r\n padding: { top: 0.5, right: 2, left: 2 },\r\n margin: { top: 0, right: 1.5, bottom: 0, left: -0.5 },\r\n border: tailwindColors.gray[800],\r\n },\r\n },\r\n industry: {\r\n ...SettingsSmall.industry,\r\n header: {\r\n ...SettingsSmall.industry.header,\r\n border: tailwindColors.gray[800],\r\n },\r\n },\r\n}\r\n\r\nexport const SettingsSmallGeo: ISettings = {\r\n ...Settings,\r\n padding: { top: 0, right: 0, bottom: 0, left: 1 },\r\n background: '#a7c4d3',\r\n industry: {\r\n ...Settings.industry,\r\n background: '#e0e0e0',\r\n header: {\r\n ...Settings.industry.header,\r\n height: 9,\r\n fontSize: 8,\r\n border: '#e0e0e0',\r\n margin: { top: -0.5, right: 0.5, bottom: 0, left: -0.5 },\r\n padding: { top: -1, right: 0, left: 1 },\r\n },\r\n },\r\n scaleFontSizes: { ...Settings.scaleFontSizes, 1: [14, 12, 11, 8, 6] },\r\n fontSizePadding: { 14: 5, 12: 2, 11: 2, 8: 1, 6: 0, 4: 0 },\r\n fontSizePairs: {\r\n 14: [9, 8, 6],\r\n 13: [9, 8, 6],\r\n 12: [6],\r\n 11: [6],\r\n 10: [6],\r\n 9: [6],\r\n 8: [6],\r\n 6: [6],\r\n },\r\n}\r\n\r\nexport const SettingsSmallGeoDark: ISettings = {\r\n ...SettingsSmallGeo,\r\n background: tailwindColors.gray[800],\r\n sector: {\r\n ...SettingsSmallGeo.sector,\r\n background: tailwindColors.gray[800],\r\n border: tailwindColors.gray[800],\r\n },\r\n industry: {\r\n ...SettingsSmallGeo.industry,\r\n border: tailwindColors.gray[800],\r\n background: tailwindColors.gray[800],\r\n header: {\r\n ...SettingsSmallGeo.industry.header,\r\n border: tailwindColors.gray[800],\r\n },\r\n },\r\n}\r\n\r\nexport const SettingsScreener: ISettings = {\r\n ...Settings,\r\n padding: { top: 0, right: 0, bottom: 0, left: 0 },\r\n sector: {\r\n ...Settings.sector,\r\n padding: { top: 0, right: 0, bottom: 0, left: 1 },\r\n background: '#363a46',\r\n border: '#d3d3d3',\r\n header: {\r\n ...Settings.sector.header,\r\n height: 20,\r\n padding: { top: 2.5, right: 4, left: 4 },\r\n },\r\n },\r\n industry: {\r\n ...Settings.industry,\r\n header: {\r\n ...Settings.industry.header,\r\n border: '#363a46',\r\n },\r\n },\r\n}\r\n\r\nexport const SettingsScreenerDark: ISettings = {\r\n ...SettingsScreener,\r\n sector: {\r\n ...SettingsScreener.sector,\r\n background: tailwindColors.gray[800],\r\n border: tailwindColors.gray[800],\r\n },\r\n industry: {\r\n ...SettingsScreener.industry,\r\n header: {\r\n ...SettingsScreener.industry.header,\r\n border: tailwindColors.gray[800],\r\n },\r\n },\r\n}\r\n","import * as d3 from 'd3'\r\n\r\nimport * as constants from './constants/generator'\r\nimport { ISettings } from './constants/settings'\r\nimport { MapDataIndustry, MapDataNode, MapDataRoot, MapDataRow, MapDataSector, MapTypeId, NodeDepth } from './types'\r\n\r\nexport default class LayoutGenerator {\r\n width: number\r\n height: number\r\n settings: ISettings\r\n layout?: Array>\r\n sectors: MapDataSector[] = []\r\n industries: MapDataIndustry[] = []\r\n nodes: MapDataNode[] = []\r\n isSmall: boolean\r\n type: MapTypeId\r\n minSectorHeight: number\r\n\r\n static smallIndustryPadding = {\r\n top: 4,\r\n right: 1,\r\n bottom: 1,\r\n left: 1,\r\n }\r\n\r\n static smallIndustryGeoPadding = {\r\n top: 4,\r\n right: 1,\r\n bottom: 1,\r\n left: 1,\r\n }\r\n\r\n static getSizeRatio = (type: MapTypeId, isSmall: boolean) => {\r\n if (isSmall) {\r\n if (type === MapTypeId.World) {\r\n return constants.SMALL_MAP_GEO_HEIGHT_RATIO\r\n }\r\n return constants.SMALL_MAP_HEIGHT_RATIO\r\n }\r\n\r\n return constants.LARGE_MAP_HEIGHT_RATIO\r\n }\r\n\r\n static calculateHeight = (\r\n width: number,\r\n type: MapTypeId,\r\n isSmall: boolean,\r\n ratio = LayoutGenerator.getSizeRatio(type, isSmall)\r\n ) => ~~(width / ratio)\r\n\r\n static calculateWidth = (height: number, type: MapTypeId, isSmall: boolean) => {\r\n const ratio = LayoutGenerator.getSizeRatio(type, isSmall)\r\n\r\n return Math.round(height * ratio)\r\n }\r\n\r\n static isNodeHeaderVisible(node: any, settings: ISettings) {\r\n const deltaX = node.dx ?? Math.round(node.x1) - Math.round(node.x0)\r\n const deltaY = node.dy ?? Math.round(node.y1) - Math.round(node.y0)\r\n\r\n const isLargeNode = deltaX >= constants.LARGE_NODE_SIZE.dx && deltaY >= constants.LARGE_NODE_SIZE.dy\r\n const showHeader =\r\n deltaY - settings.industry.padding.top - settings.industry.header.height > constants.LARGE_NODE_MIN_HEIGHT\r\n\r\n return isLargeNode && showHeader\r\n }\r\n\r\n constructor(width: number, height: number, type: MapTypeId, settings: ISettings, isSmall: boolean = false) {\r\n this.width = width\r\n this.height = height\r\n this.settings = settings\r\n this.isSmall = isSmall\r\n this.type = type\r\n this.minSectorHeight = settings.sector.padding.top + settings.sector.header.height + constants.SECTOR_MIN_HEIGHT\r\n }\r\n\r\n getExportData() {\r\n let mapRoot: MapDataRoot\r\n if (this.type === MapTypeId.World) {\r\n mapRoot = this._rootsToRoot(this.industries)\r\n } else {\r\n mapRoot = this.layout?.find((node) => node.data.name === 'Root') as unknown as MapDataRoot\r\n }\r\n\r\n // Save some file size by filtering out small nodes on maps where hover is not a concern\r\n if (this.isSmall) {\r\n mapRoot.children = this.filterVisibleNodes(mapRoot.children)\r\n }\r\n\r\n const stringified = JSON.stringify(mapRoot, (key, value) => (key === 'parent' ? '[Circular]' : value))\r\n\r\n return JSON.parse(stringified)\r\n }\r\n\r\n getLayoutData() {\r\n return {\r\n nodes: this.nodes,\r\n sectors: this.sectors,\r\n industries: this.industries,\r\n }\r\n }\r\n\r\n filterVisibleNodes = (arr: T[]) =>\r\n arr.filter((node) => {\r\n const isVisible = this.isNodeVisible(node)\r\n if (isVisible && node.children?.length) {\r\n node.children = this.filterVisibleNodes(node.children)\r\n }\r\n return isVisible\r\n })\r\n\r\n isNodeVisible(d: MapDataRow) {\r\n if (!d.depth || d.depth < NodeDepth.Industry) return true\r\n\r\n return d.dx > 0 && d.dy > 0\r\n }\r\n\r\n getLayout(data: MapDataRoot) {\r\n this.nodes = []\r\n this.sectors = []\r\n this.industries = []\r\n\r\n switch (this.type) {\r\n case MapTypeId.Sector:\r\n this.layout = this._generateSP500(data).descendants()\r\n break\r\n case MapTypeId.SectorFull:\r\n this.layout = this._generateFull(data).descendants()\r\n break\r\n case MapTypeId.Portfolio:\r\n case MapTypeId.Screener:\r\n case MapTypeId.ETFHoldings:\r\n this.layout = this._generateScreener(data).descendants()\r\n break\r\n case MapTypeId.ManagersAndFunds:\r\n this.layout = this._generateSectorSizeOrdered(data).descendants()\r\n break\r\n case MapTypeId.World:\r\n this.layout = this._generateWorld(data)\r\n break\r\n case MapTypeId.ETF:\r\n this.layout = this._generateETF(data).descendants()\r\n break\r\n }\r\n\r\n this.layout?.forEach((d: any) => {\r\n this._transformNode(d)\r\n\r\n if (!this.isNodeVisible(d)) return\r\n\r\n if (!d.children) {\r\n this.nodes.push(d)\r\n } else if (d.parent && !d.parent.parent) {\r\n this.sectors.push(d)\r\n } else if (d.parent && !!d.parent.parent && d.children) {\r\n this.industries.push(d)\r\n }\r\n })\r\n\r\n return this.getLayoutData()\r\n }\r\n\r\n _transformNode(d: d3.HierarchyRectangularNode) {\r\n Object.assign(d, {\r\n name: d.data.name,\r\n description: d.data.description,\r\n perf: d.data.perf,\r\n additional: d.data.additional,\r\n x: d.x0,\r\n y: d.y0,\r\n dx: d.x1 - d.x0,\r\n dy: d.y1 - d.y0,\r\n })\r\n }\r\n\r\n _rootsToRoot(roots: any) {\r\n return {\r\n name: 'Root',\r\n children: [\r\n {\r\n name: 'World',\r\n children: roots,\r\n },\r\n ],\r\n duplicateTickers: 0,\r\n } as MapDataRoot\r\n }\r\n\r\n _getPadding = (d: d3.HierarchyRectangularNode) => {\r\n // Root\r\n if (d.depth === NodeDepth.Root) {\r\n return [\r\n this.settings.padding.top,\r\n this.settings.padding.right,\r\n this.settings.padding.bottom,\r\n this.settings.padding.left,\r\n ]\r\n }\r\n\r\n // Industries\r\n if (d.depth === NodeDepth.Industry) {\r\n if (this.isSmall || LayoutGenerator.isNodeHeaderVisible(d, this.settings)) {\r\n return [\r\n this.settings.industry.padding.top + this.settings.industry.header.height,\r\n this.settings.industry.padding.right,\r\n this.settings.industry.padding.bottom,\r\n this.settings.industry.padding.left,\r\n ]\r\n }\r\n\r\n return [\r\n LayoutGenerator.smallIndustryPadding.top,\r\n LayoutGenerator.smallIndustryPadding.right,\r\n LayoutGenerator.smallIndustryPadding.bottom,\r\n LayoutGenerator.smallIndustryPadding.left,\r\n ]\r\n }\r\n\r\n // Sectors\r\n return [\r\n this.settings.sector.padding.top + this.settings.sector.header.height,\r\n this.settings.sector.padding.right,\r\n this.settings.sector.padding.bottom,\r\n this.settings.sector.padding.left,\r\n ]\r\n }\r\n\r\n _getPaddingGeo = (d: d3.HierarchyRectangularNode) => {\r\n // Root\r\n if (d.depth === NodeDepth.Root) {\r\n return [\r\n this.settings.padding.top,\r\n this.settings.padding.right,\r\n this.settings.padding.bottom,\r\n this.settings.padding.left,\r\n ]\r\n }\r\n\r\n // Industries\r\n if (d.depth === NodeDepth.Industry) {\r\n if (LayoutGenerator.isNodeHeaderVisible(d, this.settings)) {\r\n return [\r\n this.settings.industry.padding.top + this.settings.industry.header.height,\r\n this.settings.industry.padding.right,\r\n this.settings.industry.padding.bottom,\r\n this.settings.industry.padding.left,\r\n ]\r\n }\r\n\r\n return [\r\n LayoutGenerator.smallIndustryGeoPadding.top,\r\n LayoutGenerator.smallIndustryGeoPadding.right,\r\n LayoutGenerator.smallIndustryGeoPadding.bottom,\r\n LayoutGenerator.smallIndustryGeoPadding.left,\r\n ]\r\n }\r\n\r\n // Sectors\r\n return [\r\n this.settings.sector.padding.top + this.settings.sector.header.height,\r\n this.settings.sector.padding.right,\r\n this.settings.sector.padding.bottom,\r\n this.settings.sector.padding.left,\r\n ]\r\n }\r\n\r\n _getHierarchySort = <\r\n Datum extends { y0?: number; y1?: number; value?: number; data: { name: string }; depth?: number },\r\n >(\r\n a: Datum,\r\n b: Datum,\r\n order?: constants.MapOrder\r\n ): number => {\r\n // Sort small sectors (works only when layout is recalculated)\r\n const heightB = b.y1! - b.y0!\r\n if (b.depth === NodeDepth.Sector && Number.isFinite(heightB) && heightB < this.minSectorHeight) {\r\n return b.value! - a.value!\r\n }\r\n\r\n if (order?.hasOwnProperty(a.data.name) && order?.hasOwnProperty(b.data.name)) {\r\n return order[b.data.name] - order[a.data.name]\r\n }\r\n return b.value! - a.value!\r\n }\r\n\r\n _getHierarchy = (data: MapDataRoot, order?: constants.MapOrder) =>\r\n d3\r\n .hierarchy(data as unknown as MapDataNode)\r\n .sum((d) => d.value)\r\n .sort((a, b) => this._getHierarchySort(a, b, order))\r\n\r\n _getTreemap = (width: number, height: number) => {\r\n const paddingFn = this.type === MapTypeId.World ? this._getPaddingGeo : this._getPadding\r\n\r\n return d3\r\n .treemap()\r\n .size([width, height])\r\n .round(true)\r\n .tile(d3.treemapSquarify.ratio(1))\r\n .paddingTop((d) => paddingFn(d)[0])\r\n .paddingRight((d) => paddingFn(d)[1])\r\n .paddingBottom((d) => paddingFn(d)[2])\r\n .paddingLeft((d) => paddingFn(d)[3])\r\n }\r\n\r\n _getIndustriesRoots(data: MapDataRoot, industries: string[]) {\r\n return data.children[0].children.filter(function (d) {\r\n return industries.some((i) => i === d.name)\r\n })\r\n }\r\n\r\n _getSectorsRoots(data: MapDataRoot, sectors: string[]) {\r\n return data.children.filter(function (d) {\r\n return sectors.some((s) => s === d.name)\r\n })\r\n }\r\n\r\n _generateLayout(data: MapDataRoot, order?: constants.MapOrder, recountSectors = false) {\r\n const treemapHeight = LayoutGenerator.calculateHeight(this.width, this.type, false)\r\n const treemap = this._getTreemap(this.width, treemapHeight)\r\n const hierarchy = this._getHierarchy(data, order)\r\n const recalculateHeight = this.height !== treemapHeight\r\n\r\n // Calculate the base layout\r\n let nodes = treemap(hierarchy)\r\n\r\n // Recalculate for custom height\r\n if (this.height !== treemapHeight) {\r\n treemap.tile(d3.treemapResquarify).size([this.width, this.height])\r\n }\r\n\r\n // Run layout again so that possible small sectors are reordered\r\n // This also applies the recalculateHeight option\r\n if (recountSectors || recalculateHeight) {\r\n nodes = treemap(nodes.sort((a, b) => this._getHierarchySort(a, b, order)))\r\n }\r\n\r\n return nodes\r\n }\r\n\r\n _generateSP500(data: MapDataRoot) {\r\n const nodes = this._generateLayout(data, this.isSmall ? constants.ORDER_SP500_SMALL : constants.ORDER_SP500)\r\n\r\n // Switch financial and technology sector\r\n const financialSector = nodes.find((node) => node.data.name === 'Financial')!\r\n const technologySector = nodes.find((node) => node.data.name === 'Technology')!\r\n const financialHeight = financialSector.y1 - financialSector.y0\r\n const technologyHeight = technologySector.y1 - technologySector.y0\r\n\r\n financialSector.eachAfter((node) => {\r\n if (node.y1 - node.y0 < 1) return\r\n node.y0 += technologyHeight\r\n node.y1 += technologyHeight\r\n })\r\n\r\n technologySector.eachAfter((node) => {\r\n if (node.y1 - node.y0 < 1) return\r\n node.y0 -= financialHeight\r\n node.y1 -= financialHeight\r\n })\r\n\r\n if (this.isSmall) {\r\n // Switch consumer sectors\r\n const consumerDefensiveSector = nodes.find((node) => node.data.name === 'Consumer Defensive')!\r\n const consumerCyclicalSector = nodes.find((node) => node.data.name === 'Consumer Cyclical')!\r\n const consumerDefensiveWidth = consumerDefensiveSector.x1 - consumerDefensiveSector.x0\r\n const consumerCyclicalWidth = consumerCyclicalSector.x1 - consumerCyclicalSector.x0\r\n\r\n consumerDefensiveSector.eachAfter((node) => {\r\n if (node.x1 - node.x0 < 1) return\r\n node.x0 += consumerCyclicalWidth\r\n node.x1 += consumerCyclicalWidth\r\n })\r\n\r\n consumerCyclicalSector.eachAfter((node) => {\r\n if (node.x1 - node.x0 < 1) return\r\n node.x0 -= consumerDefensiveWidth\r\n node.x1 -= consumerDefensiveWidth\r\n })\r\n }\r\n\r\n return nodes\r\n }\r\n\r\n _generateFull(data: MapDataRoot) {\r\n const layout = this._generateLayout(data, constants.ORDER_SEC_ALL)\r\n\r\n // Swap Technology and financial sectors\r\n const technologySector = layout.find((node) => node.depth === NodeDepth.Sector && node.data.name === 'Technology')!\r\n const financialSector = layout.find((node) => node.depth === NodeDepth.Sector && node.data.name === 'Financial')!\r\n\r\n const financialHeight = financialSector.y1 - financialSector.y0\r\n technologySector.each((node) => {\r\n node.y0 -= financialHeight\r\n node.y1 -= financialHeight\r\n })\r\n\r\n const technologyHeight = technologySector.y1 - technologySector.y0\r\n financialSector.each((node) => {\r\n node.y0 += technologyHeight\r\n node.y1 += technologyHeight\r\n })\r\n\r\n // Swap Consumer Cyclical and Consumer Defensive\r\n const consumerCyclical = layout.find(\r\n (node) => node.depth === NodeDepth.Sector && node.data.name === 'Consumer Cyclical'\r\n )!\r\n const consumerDefensive = layout.find(\r\n (node) => node.depth === NodeDepth.Sector && node.data.name === 'Consumer Defensive'\r\n )!\r\n\r\n const consumerDefensiveWidth = consumerDefensive.x1 - consumerDefensive.x0\r\n consumerCyclical.each((node) => {\r\n node.x0 -= consumerDefensiveWidth\r\n node.x1 -= consumerDefensiveWidth\r\n })\r\n\r\n const consumerCyclicalWidth = consumerCyclical.x1 - consumerCyclical.x0\r\n consumerDefensive.each((node) => {\r\n node.x0 += consumerCyclicalWidth\r\n node.x1 += consumerCyclicalWidth\r\n })\r\n\r\n return layout\r\n }\r\n\r\n _generateScreener(data: MapDataRoot) {\r\n return this._generateLayout(data, constants.ORDER_SCREENER, true)\r\n }\r\n\r\n _generateETF(data: MapDataRoot) {\r\n return this._generateLayout(data, constants.ORDER_ETF)\r\n }\r\n\r\n _generateWorld = (data: MapDataRoot) => {\r\n const originalWidth = 1211\r\n const ratio = this.width / originalWidth\r\n let nodes: Array> = []\r\n\r\n for (let industryIndex = 0; industryIndex < constants.WORLD_INDUSTRIES.length; industryIndex++) {\r\n const industry = constants.WORLD_INDUSTRIES[industryIndex]\r\n const industryX = Math.round(industry.x * ratio)\r\n const industryY = Math.round(industry.y * ratio)\r\n const industryWidth = Math.round(industry.dx * ratio)\r\n const industryHeight = Math.round(industry.dy * ratio)\r\n\r\n const countriesRoots = this._getIndustriesRoots(data, industry.countries)\r\n const root = this._rootsToRoot(countriesRoots)\r\n const hierarchy = this._getHierarchy(root, constants.ORDER_WORLD)\r\n const treemap = this._getTreemap(industryWidth, industryHeight)\r\n const treemapNodes = treemap(hierarchy)\r\n\r\n treemapNodes.each((d) => {\r\n d.x0 += industryX\r\n d.x1 += industryX\r\n d.y0 += industryY\r\n d.y1 += industryY\r\n })\r\n\r\n nodes = nodes.concat(treemapNodes.descendants())\r\n }\r\n\r\n return nodes\r\n }\r\n\r\n _generateSectorSizeOrdered(data: MapDataRoot) {\r\n return this._generateLayout(data)\r\n }\r\n}\r\n","import { ReactNode } from 'react'\r\n\r\nexport enum MapTypeId {\r\n Sector = 'sec',\r\n World = 'geo',\r\n SectorFull = 'sec_all',\r\n ETF = 'etf',\r\n Screener = 'screener',\r\n Portfolio = 'portfolio',\r\n ETFHoldings = 'etf_holdings',\r\n ManagersAndFunds = 'managers_and_funds',\r\n}\r\n\r\nexport enum MapSubtypeId {\r\n IntradayPerf1m = 'i1',\r\n IntradayPerf2m = 'i2',\r\n IntradayPerf3m = 'i3',\r\n IntradayPerf5m = 'i5',\r\n IntradayPerf10m = 'i10',\r\n IntradayPerf15m = 'i15',\r\n IntradayPerf30m = 'i30',\r\n IntradayPerf1h = 'h',\r\n IntradayPerf2h = '2h',\r\n IntradayPerf4h = '4h',\r\n IntradayPerfAH = 'ah',\r\n DayPerf = 'd1',\r\n WeekPerf = 'w1',\r\n MonthPerf = 'w4',\r\n ThreeMonthPerf = 'w13',\r\n SixMonthPerf = 'w26',\r\n YearPerf = 'w52',\r\n YearToDatePerf = 'ytd',\r\n RelativeVolume = 'relvol',\r\n PriceToEarnings = 'pe',\r\n ForwardPriceToEearnings = 'fpe',\r\n PriceEarningsToGrowth = 'peg',\r\n PriceToSellsRatio = 'ps',\r\n PriceToBookRatio = 'pb',\r\n DividendYield = 'div',\r\n EPSGrowth5y = 'eps5y',\r\n FloatShort = 'short',\r\n AnalystRecommendation = 'rec',\r\n EarningsPerf = 'earnperf',\r\n EarningsDate = 'earndate',\r\n // Portfolio\r\n PortfolioGainPct = 'portfolioGainPct',\r\n PortfolioGainUsd = 'portfolioGainUsd',\r\n PortfolioChangePct = 'portfolioChangePct',\r\n PortfolioChangeUsd = 'portfolioChangeUsd',\r\n ManagersAndFunds = 'managersAndFunds',\r\n}\r\n\r\nexport enum ScaleId {\r\n IntradayReduced = 'intradayReduced',\r\n DayPerf = 'default',\r\n WeekPerf = '_5',\r\n MonthPerf = '_10',\r\n ThreeMonthPerf = '_15',\r\n SixMonthPerf = '_20',\r\n YearPerf = '_25',\r\n RelativeVolume = '_relvol',\r\n PriceToEarnings = '_pe',\r\n ForwardPriceToEearnings = '_fpe',\r\n PriceEarningsToGrowth = '_peg',\r\n PriceToSellsRatio = '_ps',\r\n PriceToBookRatio = '_pb',\r\n DividendYield = '_div',\r\n EPSGrowth5y = '_eps5y',\r\n FloatShort = '_short',\r\n AnalystRecommendation = '_rec',\r\n EarningsDate = '_earndate',\r\n // Portfolio\r\n PortfolioPct = '_portfolioPct',\r\n PortfolioUsd = '_portfolioUsd',\r\n PercentHundred = '_percentHundred',\r\n}\r\n\r\nexport const enum NodeDepth {\r\n Root,\r\n Sector,\r\n Industry,\r\n Node,\r\n}\r\n\r\nexport interface MapDataRow {\r\n name: string\r\n perf?: number\r\n x: number\r\n y: number\r\n dx: number\r\n dy: number\r\n data: any\r\n depth: NodeDepth\r\n}\r\n\r\nexport interface MapDataRoot {\r\n name: string\r\n children: MapDataSector[]\r\n duplicateTickers: number\r\n hash: string\r\n}\r\n\r\nexport interface MapDataSector extends MapDataRow {\r\n children: MapDataIndustry[]\r\n parent: MapDataRoot\r\n}\r\n\r\nexport interface MapDataIndustry extends MapDataRow {\r\n children: MapDataNode[]\r\n parent: MapDataSector\r\n}\r\n\r\nexport interface MapDataNode extends MapDataRow {\r\n parent: MapDataIndustry\r\n additional?: string\r\n description: string\r\n perfText: string\r\n value: number\r\n}\r\n\r\nexport interface MapData {\r\n sectors: MapDataSector[]\r\n industries: MapDataIndustry[]\r\n nodes: MapDataNode[]\r\n}\r\n\r\nexport type PerfData = {\r\n nodes: Record | Array\r\n additional: Record\r\n subtype: MapSubtypeId\r\n version?: number\r\n hash: string\r\n}\r\n\r\nexport interface MapSubtype {\r\n value: MapSubtypeId\r\n label: string\r\n scaleId: ScaleId\r\n tooltip: string\r\n countIndustryPerf: boolean\r\n countSectorPerf: boolean\r\n}\r\n\r\nexport interface MapType {\r\n name: string\r\n pageTitle: string\r\n nameShort?: string\r\n description: string\r\n type: MapTypeId\r\n subtypes: Array<{ items: MapSubtype[] }>\r\n}\r\n\r\nexport interface Scale {\r\n name: string\r\n tooltip: ReactNode\r\n id: ScaleId\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { ScreenerQuery, ScreenerView } from '../screener/utils'\r\nimport { isMobile } from '../shared/isMobile'\r\nimport { isStockFastRefreshAvailable } from '../shared/isStockFastRefreshAvailable'\r\nimport { EXPANDED_MAP_BODY_CLASSS } from './constants/constants'\r\nimport { LEGEND_HEIGHT, MAP_MIN_HEIGHT, MAP_MIN_WIDTH } from './constants/generator'\r\nimport { Settings, SettingsSmall, SettingsSmallGeo } from './constants/settings'\r\nimport LayoutGenerator from './layout-generator'\r\nimport type Treemap from './treemap'\r\nimport {\r\n MapDataIndustry,\r\n MapDataNode,\r\n MapDataRoot,\r\n MapDataRow,\r\n MapDataSector,\r\n MapSubtypeId,\r\n MapTypeId,\r\n PerfData,\r\n} from './types'\r\n\r\nexport function getOffset(e: MouseEvent | React.MouseEvent) {\r\n const rect = (e.currentTarget as HTMLElement).getBoundingClientRect()\r\n\r\n return {\r\n offsetX: e.clientX - rect.left,\r\n offsetY: e.clientY - rect.top,\r\n }\r\n}\r\n\r\nexport function getIsSmall() {\r\n const query = new URLSearchParams(window.location.search)\r\n return query.get('settings') === 'small'\r\n}\r\n\r\nexport function getSettingsForMapType(type: MapTypeId, isSmall?: boolean) {\r\n if (isSmall) {\r\n if (type === MapTypeId.World) {\r\n return SettingsSmallGeo\r\n }\r\n return SettingsSmall\r\n }\r\n\r\n return Settings\r\n}\r\n\r\ntype DataRow = MapDataRow | MapDataRoot\r\n/**\r\n * We strip parents when serializing data for precomputed JSONs\r\n * but we need to restore them so that we can get them in treemap\r\n */\r\nexport function restoreDataKeys(\r\n data: T[],\r\n perfData: PerfData,\r\n parent?: any\r\n): T[] {\r\n return data.map((row) => {\r\n const newRow = {\r\n ...row,\r\n parent,\r\n perf: (perfData.nodes as Record)[row.name],\r\n additional: perfData.additional[row.name],\r\n }\r\n\r\n newRow.children = row.children ? restoreDataKeys(row.children, perfData, newRow) : undefined\r\n\r\n return newRow\r\n })\r\n}\r\n\r\nexport function splitData(mapData: MapDataRoot) {\r\n let sectors: MapDataSector[] = []\r\n let industries: MapDataIndustry[] = []\r\n let nodes: MapDataNode[] = []\r\n\r\n mapData.children?.forEach((sector) => {\r\n sectors.push(sector)\r\n sector.children?.forEach((industry) => {\r\n industries.push(industry)\r\n industry.children?.forEach((company) => {\r\n if (!(company.dx < 1 || company.dy < 1)) {\r\n nodes.push(company)\r\n }\r\n })\r\n })\r\n })\r\n\r\n return { sectors, industries, nodes }\r\n}\r\n\r\nexport function getMapData(mapData: MapDataRoot, perfData: PerfData) {\r\n const [data] = restoreDataKeys([mapData], perfData)\r\n\r\n return splitData(data)\r\n}\r\n\r\nexport function getIndexMapData() {\r\n if (FinvizSettings.hasRedesignEnabled) {\r\n return import('./assets/base_data/hp_redesign.js' /* webpackChunkName: \"map_base_index_redesign\" */)\r\n } else {\r\n return import('./assets/base_data/hp.js' /* webpackChunkName: \"map_base_index\" */)\r\n }\r\n}\r\n\r\nexport function getMapBaseData(mapType: MapTypeId) {\r\n switch (mapType) {\r\n case MapTypeId.World:\r\n return import('./assets/base_data/geo.js' /* webpackChunkName: \"map_base_geo\" */)\r\n case MapTypeId.SectorFull:\r\n return import('./assets/base_data/sec_all.js' /* webpackChunkName: \"map_base_sec_all\" */)\r\n case MapTypeId.ETF:\r\n return import('./assets/base_data/etf.js' /* webpackChunkName: \"map_base_etf\" */)\r\n default:\r\n return import('./assets/base_data/sec.js' /* webpackChunkName: \"map_base_sec\" */)\r\n }\r\n}\r\n\r\nfunction getSizeForExpandedMap(element: HTMLElement, wrapper: HTMLElement | null, type: MapTypeId, isSmall: boolean) {\r\n wrapper?.style.removeProperty('max-width')\r\n let size = getRatioSizeForWidth(element.clientWidth, type, isSmall)\r\n const elementHeight = Math.max(window.innerHeight - LEGEND_HEIGHT - 50, MAP_MIN_HEIGHT)\r\n\r\n // We don’t want the map to overflow the height\r\n if (size.height > elementHeight) {\r\n const newWidth = LayoutGenerator.calculateWidth(elementHeight, type, isSmall)\r\n size = {\r\n width: newWidth,\r\n height: LayoutGenerator.calculateHeight(newWidth, type, isSmall),\r\n }\r\n }\r\n\r\n if (wrapper) {\r\n wrapper.style.maxWidth = `${size.width}px`\r\n }\r\n\r\n return size\r\n}\r\n\r\nfunction getRatioSizeForWidth(width: number, type: MapTypeId, isSmall: boolean) {\r\n const mapWidth = Math.max(width, MAP_MIN_WIDTH)\r\n return {\r\n width: mapWidth,\r\n height: LayoutGenerator.calculateHeight(mapWidth, type, isSmall),\r\n }\r\n}\r\n\r\nfunction getSizeRatioBasedMap(element: HTMLElement, wrapper: HTMLElement | null, type: MapTypeId, isSmall: boolean) {\r\n // Remove maxWidth if exiting expanded mode\r\n if (wrapper?.style.maxWidth) {\r\n wrapper.style.removeProperty('max-width')\r\n }\r\n\r\n let size = getRatioSizeForWidth(element.clientWidth, type, isSmall)\r\n\r\n // Set height so that we know if scrollbars are visible\r\n element.style.height = `${size.height + LEGEND_HEIGHT}px`\r\n\r\n // Add a bit of padding if scrollbar is visible and map touches it\r\n const scrollbarWidth = window.innerWidth - document.documentElement.clientWidth\r\n const isMediumScreen =\r\n window.innerWidth > 1430 &&\r\n window.innerWidth < 1450 &&\r\n !document.body.classList.contains('is-screener') &&\r\n !document.body.classList.contains('is-portfolio')\r\n if (isMediumScreen && scrollbarWidth > 0) {\r\n size = getRatioSizeForWidth(element.clientWidth - 10, type, isSmall)\r\n\r\n // This means we would display a horizontal scrollbar, which we don’t want\r\n } else if (size.width !== element.clientWidth) {\r\n size = getRatioSizeForWidth(element.clientWidth, type, isSmall)\r\n }\r\n\r\n element.style.removeProperty('height')\r\n\r\n return size\r\n}\r\n\r\n/**\r\n * Calculate size of the treemap based on w/h ratio and scrollbars visibility\r\n */\r\nexport function getSize(element: HTMLElement | null, type: MapTypeId, isSmall: boolean) {\r\n const canvasWrapper = document.getElementById('canvas-wrapper')\r\n\r\n if (!element) {\r\n return { width: 1, height: 1 }\r\n }\r\n\r\n // Custom width using query param\r\n const query = new URLSearchParams(window.location.search)\r\n if (query.has('width')) {\r\n const width = Number(query.get('width'))\r\n const parsedRatio = query.has('ratio') ? parseFloat(query.get('ratio')!) : undefined\r\n const ratio = Number.isFinite(parsedRatio) ? parsedRatio : undefined\r\n return {\r\n width,\r\n height: LayoutGenerator.calculateHeight(width, type, isSmall, ratio),\r\n }\r\n }\r\n\r\n // Expanded map\r\n if (document.body.classList.contains(EXPANDED_MAP_BODY_CLASSS)) {\r\n return getSizeForExpandedMap(element, canvasWrapper, type, isSmall)\r\n }\r\n\r\n if (type === MapTypeId.ETFHoldings || type === MapTypeId.ManagersAndFunds) {\r\n return { height: element.clientHeight, width: element.clientWidth }\r\n }\r\n\r\n return getSizeRatioBasedMap(element, canvasWrapper, type, isSmall)\r\n}\r\n\r\n/**\r\n * Get treemap zoom levels based on env\r\n */\r\nexport function getDefaultZoomLevels() {\r\n if (isMobile()) {\r\n return [1, 1.5]\r\n }\r\n\r\n if (/^((?!chrome|android).)*safari/i.test(navigator.userAgent)) {\r\n return [1, 1.5, 2.25]\r\n }\r\n\r\n return [1, 1.5, 2.25, 3]\r\n}\r\n\r\nexport function parseInitDataAsPerf(data?: MapDataRoot): PerfData | undefined {\r\n if (!data) return\r\n\r\n const nodes: Record = {}\r\n const additional: Record = {}\r\n\r\n for (const sector of data.children) {\r\n for (const industry of sector.children) {\r\n for (const node of industry.children) {\r\n if (node.perf !== undefined) {\r\n nodes[node.name] = node.perf\r\n }\r\n if (node.additional !== undefined) {\r\n additional[node.name] = node.additional\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n nodes,\r\n additional,\r\n subtype: MapSubtypeId.DayPerf,\r\n version: 1,\r\n hash: data.hash,\r\n }\r\n}\r\n\r\nconst MAX_SPARKLINES = 120\r\nconst HOVER_TOP_ROW_HEIGHT = 100\r\nconst HOVER_BORDER_WIDTH = 4\r\nconst ROW_HEIGHT = 30\r\nconst ROW_HEIGHT_SMALL = 24\r\nconst ROW_HEIGHT_BREAKPOINT = 15\r\n\r\nexport function getVisibleTooltipNodes(node?: MapDataNode | null) {\r\n if (!node) return []\r\n\r\n const industryTickers = node.parent.children\r\n const isSmall = industryTickers.length > ROW_HEIGHT_BREAKPOINT\r\n const rowHeight = isSmall ? ROW_HEIGHT_SMALL : ROW_HEIGHT\r\n const visibleRows = Math.floor((window.innerHeight - HOVER_TOP_ROW_HEIGHT - 2 * HOVER_BORDER_WIDTH) / rowHeight)\r\n const visibleChildren = industryTickers\r\n .slice()\r\n .sort((a, b) => b.dx * b.dy - a.dx * a.dy)\r\n .slice(0, Math.min(visibleRows, MAX_SPARKLINES))\r\n\r\n return visibleChildren\r\n}\r\n\r\nexport function onNodeClick({\r\n treemap,\r\n node,\r\n industry,\r\n sector,\r\n}: {\r\n treemap: Treemap\r\n node?: MapDataNode\r\n industry?: MapDataIndustry\r\n sector?: MapDataSector\r\n}) {\r\n if (node) {\r\n window.open(`/quote.ashx?t=${node.name}`)\r\n return\r\n }\r\n\r\n const query = new URLSearchParams()\r\n query.set(ScreenerQuery.View, ScreenerView.Overview.toString())\r\n\r\n // Use ticker filter for ETFs\r\n if (treemap.type === MapTypeId.ETF) {\r\n let tickers: string[] = []\r\n if (industry) {\r\n tickers = industry.children.map((node) => node.name)\r\n } else if (sector) {\r\n tickers = sector.children.flatMap((industry) => industry.children.map((node) => node.name))\r\n }\r\n\r\n if (tickers.length) {\r\n query.set(ScreenerQuery.Tickers, tickers.join(','))\r\n window.open(`/screener.ashx?${query}`)\r\n }\r\n\r\n return\r\n }\r\n\r\n if (industry) {\r\n const id = industry.name.replace(/[^a-zA-Z]/g, '').toLowerCase()\r\n const filter = treemap.type === MapTypeId.World ? 'geo' : 'ind'\r\n\r\n query.set(ScreenerQuery.Filters, `${filter}_${id}`)\r\n window.open(`/screener.ashx?${query}`)\r\n } else if (sector) {\r\n const id = sector.name.replace(/[^a-zA-Z]/g, '').toLowerCase()\r\n\r\n query.set(ScreenerQuery.Filters, `sec_${id}`)\r\n window.open(`/screener.ashx?${query}`)\r\n }\r\n}\r\n\r\nenum MapsPollingIntervalInMs {\r\n Free = 30000,\r\n Elite = 3000,\r\n Reduced = 60000,\r\n}\r\n\r\nexport function getMapsRefreshInterval({\r\n base = MapsPollingIntervalInMs.Elite,\r\n reduced = MapsPollingIntervalInMs.Reduced,\r\n free = MapsPollingIntervalInMs.Free,\r\n}: { base?: number; reduced?: number; free?: number } = {}) {\r\n const isPremium = FinvizSettings.hasUserPremium\r\n let customRefreshInterval = base\r\n if (!isPremium) {\r\n customRefreshInterval = free\r\n }\r\n if (!isStockFastRefreshAvailable()) {\r\n customRefreshInterval = reduced\r\n }\r\n\r\n return customRefreshInterval\r\n}\r\n","export type ObjectHash = Record\r\n\r\nexport const decodeQueryString = function = ObjectHash>(\r\n search = window.location.search\r\n): T {\r\n const vars = search ? search.substring(1).split('&') : []\r\n const obj: ObjectHash = {}\r\n vars.forEach((pair) => {\r\n const delimiterPos = pair.indexOf('='),\r\n key = decodeURIComponent(pair.substring(0, delimiterPos)),\r\n value = decodeURIComponent(pair.substring(delimiterPos + 1))\r\n obj[key] = value\r\n })\r\n return obj as T\r\n}\r\n\r\nexport const encodeQueryString = function (values: ObjectHash, whitelistedValues: string[] = []) {\r\n return Object.keys(values).reduce((prev, key) => {\r\n const value = values[key]\r\n if (!['', null, undefined].includes(value) || whitelistedValues.includes(value)) {\r\n return prev + (prev.length > 0 ? '&' : '') + encodeURIComponent(key) + '=' + encodeURIComponent(value)\r\n }\r\n return prev\r\n }, '')\r\n}\r\n","export enum ScreenerQuery {\r\n View = 'v',\r\n Signal = 's',\r\n Order = 'o',\r\n Tickers = 't',\r\n Filters = 'f',\r\n FilterTab = 'ft',\r\n MapSubtype = 'st',\r\n}\r\n\r\nexport enum ScreenerFilter {\r\n MarketCap = 'cap',\r\n Index = 'idx',\r\n Sector = 'sec',\r\n Industry = 'ind',\r\n AverageVolume = 'sh_avgvol',\r\n}\r\n\r\nexport enum ScreenerAddtionalQuery {\r\n ShowEtf = 'show_etf',\r\n}\r\n\r\nexport enum ScreenerView {\r\n Overview = 11,\r\n Maps = 71,\r\n Bubbles = 72,\r\n}\r\n\r\nexport function eventListenerRegister(el: HTMLElement, eventName: string, handler: (...args: any[]) => any) {\r\n el.addEventListener(eventName, handler)\r\n\r\n return () => {\r\n el.removeEventListener(eventName, handler)\r\n }\r\n}\r\n\r\nexport function textContent(el: HTMLElement) {\r\n return el.textContent || el.innerText\r\n}\r\n\r\nexport function ScreenerGetOptionsList(select: HTMLSelectElement) {\r\n const options = select.getAttribute('data-selected')?.split('|') ?? [],\r\n result = []\r\n for (var i = 0, len = options.length; i < len; i++) {\r\n var option = options[i]\r\n for (var j = 0; j < select.children.length; j++) {\r\n var optionEl = select.children[j] as HTMLOptionElement\r\n if (optionEl.value === option) {\r\n result.push({\r\n key: option,\r\n value: textContent(optionEl),\r\n })\r\n }\r\n }\r\n }\r\n return result\r\n}\r\n\r\nexport function ScreenerRenderCustomModal(select: any) {\r\n const filter = select.getAttribute('data-filter')\r\n const customWrapper = document.getElementById('fsm_' + filter) as HTMLElement\r\n if (customWrapper) {\r\n select.style.display = 'none'\r\n customWrapper.style.display = 'block'\r\n const input = document.getElementById('fsmi_' + filter) as HTMLInputElement\r\n const options = ScreenerGetOptionsList(select)\r\n const arr = []\r\n for (let i = 0, len = options.length; i < len; i++) {\r\n arr.push(options[i].value)\r\n }\r\n input.value = arr.join(', ')\r\n }\r\n}\r\n\r\nconst DATE_REGEX = /^[0-9]{2}[-][0-9]{2}[-][0-9]{4}/\r\n\r\nexport function getIsOptionDateRange(option: string) {\r\n if (!option.includes('x')) return false\r\n\r\n const [from, to] = option.split('x')\r\n const [isValidFromDate, isValidToDate] = [from, to].map((value) => {\r\n if (DATE_REGEX.test(value)) {\r\n return !Number.isNaN(new Date(value.replace(/-/g, '/')).getTime())\r\n }\r\n return false\r\n })\r\n\r\n return isValidFromDate || isValidToDate\r\n}\r\n\r\nexport function getInitialDateFromSelectedValues(selectedValues: string[]) {\r\n const initialDate = selectedValues.find(getIsOptionDateRange)\r\n\r\n if (initialDate) {\r\n return initialDate.split('x').map((date) => (DATE_REGEX.test(date) ? date.replace(/-/g, '/') : undefined))\r\n }\r\n}\r\n\r\nexport function dateRangeToFilterString({ from, to }: { from?: string; to?: string }) {\r\n return from || to ? `${from ?? ''}x${to ?? ''}`.replace(/\\//g, '-') : null\r\n}\r\n\r\n/**\r\n * Creates link for given view & subview and ignores any additional query params\r\n */\r\nexport function getQueryForView(view?: ScreenerView, allowedParams: string[] = [], baseQuery = window.location.search) {\r\n const query = new URLSearchParams(baseQuery)\r\n const allowList = [...allowedParams, ...Object.values(ScreenerQuery)]\r\n\r\n /**\r\n * Seems like `query` is a live property, so we can’t use `query.forEach` to delete,\r\n * so we need to copy keys before looping.\r\n * https://stackoverflow.com/questions/60522437\r\n */\r\n const keys = Array.from(query.keys())\r\n\r\n keys.forEach((key) => {\r\n if (!allowList.includes(key)) {\r\n query.delete(key)\r\n }\r\n })\r\n\r\n const [, originalView, settings = 0] = query.get(ScreenerQuery.View)?.match(/(\\d{2})(\\d)/) ?? []\r\n\r\n if (view ?? originalView) {\r\n query.set(ScreenerQuery.View, `${view ?? originalView}${settings}`)\r\n }\r\n\r\n return query\r\n}\r\n\r\n/**\r\n * Parse screener `f` query param to object\r\n */\r\nexport function parseScreenerFilters(baseQuery = window.location.search) {\r\n const query = new URLSearchParams(baseQuery)\r\n const filtersString = query.get(ScreenerQuery.Filters)\r\n\r\n if (!filtersString) return {}\r\n\r\n return Object.fromEntries(\r\n filtersString.split(',').map((f) => {\r\n const lastUnderscore = f.lastIndexOf('_')\r\n const key = f.substring(0, lastUnderscore)\r\n const value = f.substring(lastUnderscore + 1)\r\n return [key, value.split('|')]\r\n })\r\n )\r\n}\r\n\r\n/**\r\n * Stringify screener `f` query param\r\n */\r\nexport function stringifyScreenerFilters(filters: Record) {\r\n return Object.entries(filters)\r\n .filter(([, value]) => String(value).length > 0)\r\n .map(([key, value]) => `${key}_${value.join('|')}`)\r\n .join(',')\r\n}\r\n\r\nexport function rangesToFilter(\r\n ranges: {\r\n from: string\r\n to: string\r\n }[],\r\n rangeSuffixes?: string[],\r\n delimiter = 'x',\r\n rangeDelimiter = 'to'\r\n) {\r\n return ranges.reduce((filter, range, index) => {\r\n const { from, to } = range\r\n const rangeStr = from || to ? `${from}${rangeDelimiter}${to}${rangeSuffixes?.[index] ?? ''}` : ''\r\n\r\n let currentFilter = filter\r\n if (index > 0) currentFilter += delimiter\r\n return currentFilter + rangeStr\r\n }, '')\r\n}\r\n","import { waitForPreviousPromise } from '../../main/services/wait-for-previous-promise'\r\n\r\nconst DECAY_FACTOR = 1.25\r\n\r\ntype IntervalOrGetter = number | (() => number)\r\ntype IntervalOptions = {\r\n interval: IntervalOrGetter\r\n /**\r\n * Gradually lower the refetch interval by `decayFactor` when the window is not visible\r\n */\r\n decay?: boolean\r\n /**\r\n * Set factor of decay\r\n * @default 1.25\r\n */\r\n decayFactor?: number\r\n /**\r\n * The maximum interval when decaying the refresh interval\r\n * @default QuotePollingIntervalInMs based on free/elite\r\n */\r\n maxDecayInterval?: IntervalOrGetter\r\n}\r\ntype IntervalCallback = () => void | Promise\r\n\r\nfunction getCurrentDateInMs() {\r\n return new Date().valueOf()\r\n}\r\n\r\nfunction getIsDocumentVisible() {\r\n return document.visibilityState === 'visible' || document.hidden === false\r\n}\r\n\r\n/**\r\n * Invoke a callback when page visibility changes. Turns the callback into a promise\r\n * and waits for the previous promise to finish before invoking it again\r\n */\r\nexport function notifyOnVisibilityChange(callback: (visible: boolean) => void | Promise) {\r\n const promisifiedCallback = waitForPreviousPromise(() => callback(getIsDocumentVisible()))\r\n\r\n document.addEventListener('visibilitychange', promisifiedCallback)\r\n\r\n return {\r\n callback: promisifiedCallback,\r\n unsubscribe: () => {\r\n document.removeEventListener('visibilitychange', promisifiedCallback)\r\n },\r\n }\r\n}\r\n\r\nfunction getInterval(interval: IntervalOrGetter) {\r\n if (typeof interval === 'number') return () => interval\r\n return interval\r\n}\r\n\r\n/**\r\n * Calls callback based on interval and document visibility. Returns unsubscribe function.\r\n * How it works:\r\n * - document is hidden: interval cleared (or if options.decay is enabled it decays slowly)\r\n * - document visible: interval set-up with remaining time from last interval. Call immediately if interval elapsed\r\n */\r\nexport function intervalCallbackOnWindowVisible(initOptions: IntervalOptions, callback: IntervalCallback) {\r\n const options = {\r\n interval: getInterval(initOptions.interval),\r\n decay: initOptions.decay,\r\n decayFactor: initOptions.decayFactor ?? DECAY_FACTOR,\r\n maxDecayInterval: getInterval(initOptions.maxDecayInterval ?? 0),\r\n }\r\n let refreshPromise: Promise | void | null = null\r\n let nextRefresh = getCurrentDateInMs() + options.interval()\r\n let refreshTimeout: number | null = null\r\n\r\n async function refresh() {\r\n const currentDateMs = getCurrentDateInMs()\r\n\r\n // Call callback asynchronously\r\n if (refreshPromise === null || currentDateMs < nextRefresh) refreshPromise = callback()\r\n nextRefresh = currentDateMs + options.interval()\r\n await refreshPromise\r\n refreshPromise = null\r\n\r\n // Queue next refresh\r\n if (getIsDocumentVisible()) {\r\n refreshTimeout = window.setTimeout(refresh, Math.max(0, nextRefresh - getCurrentDateInMs()))\r\n }\r\n }\r\n\r\n // When the window is not visible, slowly lower the refresh interval, but keep it under a minute\r\n function decayRefreshInterval() {\r\n let decayedInterval = options.interval()\r\n\r\n async function decay() {\r\n // Call the getter again, interval might have changed (eg. ah)\r\n const maxTimeout = options.maxDecayInterval()\r\n\r\n await refresh()\r\n decayedInterval = Math.round(decayedInterval * options.decayFactor)\r\n\r\n if (decayedInterval > maxTimeout) decayedInterval = maxTimeout\r\n\r\n refreshTimeout = window.setTimeout(decay, decayedInterval)\r\n }\r\n\r\n refreshTimeout = window.setTimeout(decay, decayedInterval)\r\n }\r\n\r\n /**\r\n * Handle the visibility change event, compute callback remaining time or call immediately\r\n */\r\n function handleVisibilityChange() {\r\n if (refreshTimeout) clearTimeout(refreshTimeout)\r\n\r\n if (getIsDocumentVisible()) {\r\n const currentDateMs = getCurrentDateInMs()\r\n // Refresh if the document is stale, otherwise set a timeout to refresh later\r\n if (nextRefresh <= currentDateMs) {\r\n refresh()\r\n } else {\r\n refreshTimeout = window.setTimeout(refresh, nextRefresh - currentDateMs)\r\n }\r\n } else if (options.decay && options.maxDecayInterval() > 0) {\r\n decayRefreshInterval()\r\n }\r\n }\r\n\r\n if (getIsDocumentVisible()) {\r\n refreshTimeout = window.setTimeout(refresh, options.interval())\r\n }\r\n\r\n document.addEventListener('visibilitychange', handleVisibilityChange)\r\n\r\n return () => {\r\n if (refreshTimeout) clearTimeout(refreshTimeout)\r\n document.removeEventListener('visibilitychange', handleVisibilityChange)\r\n }\r\n}\r\n","import { getDate } from '../header/utils'\r\n\r\n// Keep in sync with the original in charts repo in app/constants/common.ts\r\nexport const PREMARKET_AFTERMARKET_HOURS = 2.5\r\nexport const MARKET_START = { hours: 9, minutes: 30 }\r\nexport const MARKET_END = { hours: 16, minutes: 0 }\r\n\r\n/*\r\n * Keep in sync with the original (Utils static method) in charts repo in app/utils.ts\r\n * See line 15, we use getDate instead of convertLocalToNyTime\r\n */\r\nexport function isStockFastRefreshAvailable(hasPremarket = true, hasAftermarket = true, bufferMinutes = 30) {\r\n const getMinutes = ({ hours, minutes }: { hours: number; minutes: number }) => hours * 60 + minutes\r\n\r\n const date = getDate()\r\n const dayOfWeek = date.getDay()\r\n const currentDayMinutes = date.getHours() * 60 + date.getMinutes()\r\n\r\n const premarketMinutes = hasPremarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n const aftermarketMinutes = hasAftermarket ? PREMARKET_AFTERMARKET_HOURS * 60 : 0\r\n\r\n const isWeekend = dayOfWeek === 0 || dayOfWeek === 6\r\n const isOpen = getMinutes(MARKET_START) - premarketMinutes - bufferMinutes <= currentDayMinutes\r\n const isClosed = getMinutes(MARKET_END) + aftermarketMinutes + bufferMinutes <= currentDayMinutes\r\n return !isWeekend && isOpen && !isClosed\r\n}\r\n","import { setCookieRequest } from '../../main/services/api'\r\nimport { decodeQueryString, encodeQueryString } from '../queryString'\r\nimport { getCookie, setCookie } from './cookie'\r\n\r\nexport const formatDateToStringUS = (date: Date) =>\r\n date.toLocaleDateString('en-US', {\r\n day: '2-digit',\r\n month: '2-digit',\r\n year: 'numeric',\r\n })\r\n\r\nconst DRAWING_QUOTE_PAGE_COOKIE_NAME = 'charts-draw'\r\nexport function getIsDrawingEnabledOnQuotePage() {\r\n return getCookie(DRAWING_QUOTE_PAGE_COOKIE_NAME) === 'on'\r\n}\r\n\r\nexport async function setIsDrawingEnabledOnQuotePage(isEnabled: boolean) {\r\n return setCookieRequest(DRAWING_QUOTE_PAGE_COOKIE_NAME, isEnabled ? 'on' : 'off')\r\n .catch(() => {\r\n // fallback to JS otherwise draw toggle won't work if API doesn't work\r\n setIsDrawingEnabledOnQuotePageCookieViaJS(isEnabled)\r\n })\r\n .finally(() => {\r\n const { i: idea, ...rest } = decodeQueryString()\r\n if (idea) {\r\n document.location = `quote.ashx?${encodeQueryString(rest)}`\r\n } else {\r\n document.location.reload()\r\n }\r\n })\r\n}\r\n\r\nfunction setIsDrawingEnabledOnQuotePageCookieViaJS(isEnabled: boolean) {\r\n const expires = new Date()\r\n expires.setMonth(expires.getMonth() + 1)\r\n setCookie(DRAWING_QUOTE_PAGE_COOKIE_NAME, isEnabled ? 'on' : 'off', expires)\r\n}\r\n\r\nexport function parseInitData(elementId: string): T | undefined {\r\n try {\r\n const initDataElement = document.getElementById(elementId)!\r\n return JSON.parse(initDataElement.textContent!)\r\n } catch (e) {\r\n Sentry.captureException(e)\r\n return\r\n }\r\n}\r\n\r\nexport function getSidebarFromCookie() {\r\n const chartsUrl = getCookie('chartsUrl')\r\n const decodedCookie = chartsUrl ? decodeQueryString<{ sidebar?: string }>(chartsUrl) : null\r\n return decodedCookie?.sidebar || undefined\r\n}\r\n","import * as dateFns from 'date-fns'\r\nimport * as React from 'react'\r\n\r\nimport { parseInputAsDate } from '../../modules/portfolio/utils'\r\n\r\ninterface Props {\r\n inputValue: string\r\n dataDateFormat: string\r\n viewDateFormat: string\r\n}\r\n\r\nexport function getDateInputWithPickerValue({ inputValue, dataDateFormat, viewDateFormat }: Props) {\r\n try {\r\n const parsedDate = parseInputAsDate({\r\n input: inputValue,\r\n format: dataDateFormat,\r\n checkFormat: false,\r\n })\r\n\r\n return {\r\n input: dateFns.format(parsedDate, viewDateFormat),\r\n picker: parsedDate,\r\n }\r\n } catch {\r\n return {\r\n input: inputValue,\r\n picker: new Date(),\r\n }\r\n }\r\n}\r\n\r\nexport function useDateInputWithPickerValue({ inputValue, dataDateFormat, viewDateFormat }: Props) {\r\n return React.useMemo(\r\n () =>\r\n getDateInputWithPickerValue({\r\n inputValue,\r\n dataDateFormat,\r\n viewDateFormat,\r\n }),\r\n [inputValue, dataDateFormat, viewDateFormat]\r\n )\r\n}\r\n","import * as dateFns from 'date-fns'\r\nimport * as React from 'react'\r\n\r\nimport { parseInputAsDate } from '../../modules/portfolio/utils'\r\nimport { StatelessDatePicker } from '../date-picker'\r\nimport { InputComponentProps } from '../input'\r\nimport { usePopoverState } from '../popover'\r\nimport { Tooltip, TooltipTrigger, useTooltipState } from '../tooltip'\r\nimport { useDateInputWithPickerValue } from './useDateInputWithPickerValue'\r\n\r\nconst DEFAULT_DATE_FORMAT = 'MM-dd-yyyy'\r\n\r\ninterface Props {\r\n /**\r\n * Date input element / calendar popover trigger\r\n */\r\n trigger: React.ReactElement\r\n\r\n /**\r\n * Date string format which is used for input element (trigger) value\r\n */\r\n viewDateFormat?: string\r\n\r\n /**\r\n * Date string format which is used for inputValue value and onChange callback value\r\n */\r\n dataDateFormat?: string\r\n\r\n /**\r\n * Min date for datepicker\r\n */\r\n minDate?: Date\r\n\r\n /**\r\n * Date input value in dataDateFormat\r\n */\r\n inputValue: string | undefined\r\n\r\n /**\r\n * Change callback with value in dataDateFormat if in correct dataDateFormat\r\n * or with string value which is provided in the input if it's invalid date\r\n */\r\n onChange: (value: string) => void\r\n\r\n /**\r\n * When true, error style is applied on ticker and error popover shows on focus\r\n */\r\n hasError: boolean\r\n\r\n /**\r\n * Callback if error state changes\r\n */\r\n onErrorChange: (hasError: boolean) => void\r\n\r\n /**\r\n * Callback which triggers if error tooltip or calendar popover opens/closes\r\n */\r\n onIsInteractingChange?: (isInteracting: boolean) => void\r\n}\r\n\r\nexport function DateInputWithPicker({\r\n trigger,\r\n viewDateFormat = DEFAULT_DATE_FORMAT,\r\n dataDateFormat = DEFAULT_DATE_FORMAT,\r\n minDate,\r\n inputValue = '',\r\n onChange,\r\n hasError,\r\n onErrorChange,\r\n onIsInteractingChange,\r\n}: Props) {\r\n const pickerState = usePopoverState()\r\n const isPickerMounted = pickerState.useState('mounted')\r\n const tooltipState = useTooltipState({ placement: 'top' })\r\n const isTooltipMounted = tooltipState.useState('mounted')\r\n const WrapperComponent = hasError ? TooltipTrigger : React.Fragment\r\n const wrapperProps = hasError\r\n ? ({\r\n state: tooltipState,\r\n tabIndex: -1,\r\n hideOnBlur: true,\r\n showOnHover: false,\r\n } as React.ComponentProps)\r\n : {}\r\n\r\n const isInteractingWithDateInput = isPickerMounted || isTooltipMounted\r\n const value = useDateInputWithPickerValue({\r\n inputValue,\r\n dataDateFormat,\r\n viewDateFormat,\r\n })\r\n\r\n React.useEffect(() => {\r\n onIsInteractingChange?.(isInteractingWithDateInput)\r\n // We don't need to pass entire props as we check only if onIsInteractingChange changed\r\n }, [onIsInteractingChange, isInteractingWithDateInput])\r\n\r\n /**\r\n * Handle date changes\r\n */\r\n const onDateChange = React.useCallback(\r\n (dateValue: Date | string) => {\r\n // Convert input to correct format if valid\r\n const parsedDate = parseInputAsDate({ input: dateValue, format: viewDateFormat })\r\n\r\n if (typeof dateValue === 'string' && !dateFns.isValid(parsedDate)) {\r\n onChange(dateValue)\r\n return\r\n }\r\n\r\n const date = dateFns.format(parsedDate, dataDateFormat)\r\n onErrorChange(false)\r\n onChange(date)\r\n tooltipState.hide()\r\n },\r\n [tooltipState, onErrorChange, onChange, dataDateFormat, viewDateFormat]\r\n )\r\n\r\n /**\r\n * Reset error state on blur when editing manually\r\n */\r\n const handleBlur = React.useCallback(() => {\r\n tooltipState.hide()\r\n const date = parseInputAsDate({ input: value.input ?? '', format: viewDateFormat })\r\n\r\n if (dateFns.isValid(date)) {\r\n onErrorChange(false)\r\n }\r\n }, [onErrorChange, value.input, viewDateFormat, tooltipState])\r\n\r\n return (\r\n \r\n \r\n {React.cloneElement(trigger, {\r\n onChange: (ev) => onDateChange(ev.currentTarget.value),\r\n onKeyDown: () => {\r\n setTimeout(() => {\r\n pickerState.hide()\r\n })\r\n },\r\n onBlur: handleBlur,\r\n onFocus: hasError ? () => tooltipState.show() : undefined,\r\n })}\r\n \r\n \r\n Invalid date, please enter date in {viewDateFormat.toUpperCase()} format.\r\n \r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\ninterface ItemsGroupProps extends Omit, 'ref' | 'label'> {\r\n /**\r\n * Group label\r\n */\r\n label?: React.ReactNode\r\n\r\n /**\r\n * Virtualized disables margins and paddings so the group could be positioned absolutely within a virtualized list\r\n */\r\n virtualized?: boolean\r\n\r\n /**\r\n * Toggles the border between groups\r\n *\r\n * @default true\r\n */\r\n hasBorder?: boolean\r\n}\r\n\r\nexport const MenuGroup = React.forwardRef(function ItemsGroup(\r\n { label, virtualized, hasBorder = true, children, ...props }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n) {\r\n return (\r\n \r\n {label && {label}}\r\n {children}\r\n \r\n )\r\n})\r\n","import classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport {\r\n BUTTON_DEFAULT_ELEMENT,\r\n Button,\r\n ButtonComponentProps,\r\n ButtonPadding,\r\n ButtonProps,\r\n ButtonThemeType,\r\n} from './button'\r\nimport { Icon, isValidIconName } from './icon'\r\n\r\nexport interface OptionButtonProps extends Omit {\r\n /**\r\n * Description for the option\r\n */\r\n subtitle?: React.ReactNode\r\n\r\n /**\r\n * Set the button theme when it is selected\r\n */\r\n activeTheme?: ButtonThemeType\r\n\r\n /**\r\n * Set the base button theme when not selected\r\n */\r\n theme?: ButtonThemeType | ((isHovered: boolean) => ButtonThemeType)\r\n\r\n /**\r\n * Internal prop denoting whether or not the button is part of a multiselect.\r\n * When true, it’ll have selected icon\r\n */\r\n isMultiSelect?: boolean\r\n}\r\n\r\nfunction getDefaultTheme(isHovered: boolean) {\r\n return isHovered ? 'menuItem' : 'menuItemTransparent'\r\n}\r\n\r\nexport const OptionButton = React.forwardRef(function OptionButton<\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n {\r\n subtitle,\r\n children,\r\n 'aria-selected': ariaSelected,\r\n 'data-active-item': dataActiveItem,\r\n rounding = 'small',\r\n activeTheme = 'blue',\r\n theme = getDefaultTheme,\r\n isMultiSelect,\r\n ...props\r\n }: Omit, 'theme'> & OptionButtonProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const isSelected = ariaSelected === true\r\n const isHovered = dataActiveItem === true\r\n const defaultTheme = typeof theme === 'function' ? theme(isHovered) : theme\r\n\r\n const iconTheme = classNames({\r\n 'text-gray-500 dark:text-gray-400': !isSelected && !isHovered,\r\n 'text-white dark:text-default': isSelected,\r\n 'text-default': !isSelected && isHovered,\r\n })\r\n\r\n return (\r\n )}\r\n ref={ref}\r\n align=\"left\"\r\n className={classNames(props.className, ButtonPadding.regular, 'select-none', {\r\n 'text-2xs': !!subtitle,\r\n })}\r\n contentClass={classNames(props.contentClass, 'font-normal')}\r\n rounding={rounding}\r\n active={props.active ?? (isHovered && !isSelected)}\r\n theme={isSelected ? activeTheme : defaultTheme}\r\n size={props.size ?? (subtitle ? 'none' : props.size)}\r\n aria-selected={ariaSelected}\r\n data-active-item={dataActiveItem}\r\n leftContent={\r\n isValidIconName(props.leftContent) ? (\r\n \r\n ) : (\r\n (props.leftContent ?? (isMultiSelect ? : undefined))\r\n )\r\n }\r\n rightContent={\r\n isValidIconName(props.rightContent) ? (\r\n \r\n ) : (\r\n props.rightContent\r\n )\r\n }\r\n >\r\n {children}\r\n {subtitle && (\r\n \r\n {subtitle}\r\n \r\n )}\r\n \r\n )\r\n})\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Icon } from './icon'\r\n\r\ninterface RedGreenTextProps {\r\n value?: number | null\r\n children: any\r\n rightContent?: React.ReactNode\r\n className?: string\r\n rightClass?: string\r\n}\r\n\r\n/**\r\n * Component which renders red/green text based on whether the value is positive or negative if value\r\n * is 0, it will not be colored and it will not display the guide triangle\r\n */\r\nexport function RedGreenText({ value, children, className, rightContent, rightClass }: RedGreenTextProps) {\r\n const hasValue = value && Number.isFinite(value)\r\n const showArrow = rightContent === undefined && hasValue && value !== 0\r\n\r\n return (\r\n 0,\r\n 'text-negative': hasValue && value < 0,\r\n 'text-muted-2': typeof hasValue !== 'number',\r\n })}\r\n >\r\n {children}\r\n \r\n {showArrow ? (\r\n 0 ? 'arrowUpShort' : 'arrowDownShort'} className=\"block\" />\r\n ) : null}\r\n {rightContent}\r\n \r\n \r\n )\r\n}\r\n\r\n/**\r\n * Used to position multiple lines of RedGreen text, this component will make sure all numbers are\r\n * in line with their `rightContent`\r\n */\r\nexport function RedGreenMultiline({ className, children, ...props }: React.PropsWithChildren) {\r\n return (\r\n
\r\n {React.Children.map(children, (child: React.ReactElement) => {\r\n if (React.isValidElement(child) && child.type === RedGreenText) {\r\n return React.cloneElement(child, {\r\n className: classnames(child.props.className, 'table-row'),\r\n rightClass: 'table-cell align-middle',\r\n })\r\n }\r\n\r\n return child\r\n })}\r\n
\r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport throttle from 'lodash.throttle'\r\nimport * as React from 'react'\r\n\r\nimport { useElementMeasure } from '../../hooks/use-element-measure'\r\n\r\ninterface Props {\r\n children: React.ReactElement\r\n className?: string\r\n shouldScrollToEnd?: boolean\r\n hasBorder?: boolean\r\n hasHeaderShadow?: boolean\r\n cropFillerClassName?: string\r\n}\r\n\r\nenum ShadowPosition {\r\n none,\r\n left,\r\n right,\r\n leftAndRight,\r\n}\r\n\r\ninterface TableScrollShadowProps {\r\n side: ShadowPosition.left | ShadowPosition.right\r\n position: { top?: number; left?: number; right?: number }\r\n height: number\r\n className?: string\r\n isVisible: boolean\r\n hasBorder?: boolean\r\n}\r\n\r\nfunction TableScrollShadow({\r\n className,\r\n side,\r\n position,\r\n height,\r\n isVisible,\r\n hasBorder = false,\r\n}: TableScrollShadowProps) {\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport function TableStickyColumnWrapper({\r\n children,\r\n className,\r\n shouldScrollToEnd,\r\n cropFillerClassName = 'w-3 bg-primary',\r\n hasBorder = false,\r\n hasHeaderShadow = false,\r\n}: Props) {\r\n const { setElementRef, elementHeight } = useElementMeasure()\r\n const tableWrapperRef = React.useRef(null)\r\n const [shadowPosition, setShadowPosition] = React.useState(ShadowPosition.none)\r\n const [shadowDimensions, setShadowDimensions] = React.useState({ left: 0, top: 0, height: 0 })\r\n\r\n const tableShadowMargin = hasBorder ? 1 : 0 // margins to prevent covering borders with the shadow\r\n\r\n React.useEffect(() => {\r\n const tableWrapperElement = tableWrapperRef.current\r\n if (!tableWrapperElement) return\r\n\r\n const onScroll = throttle(function () {\r\n const tableWrapperElement = tableWrapperRef.current\r\n if (!tableWrapperElement) return\r\n\r\n const tableWrapperElementScrollLeft = Math.ceil(tableWrapperElement.scrollLeft)\r\n\r\n let newShadowPosition = ShadowPosition.none\r\n const hasScrollSpaceToLeft = tableWrapperElementScrollLeft > 0\r\n const hasScrollSpaceToRight =\r\n Math.ceil(tableWrapperElement.offsetWidth) + tableWrapperElementScrollLeft < tableWrapperElement.scrollWidth\r\n if (hasScrollSpaceToLeft && hasScrollSpaceToRight) {\r\n newShadowPosition = ShadowPosition.leftAndRight\r\n } else if (hasScrollSpaceToLeft) {\r\n newShadowPosition = ShadowPosition.left\r\n } else if (hasScrollSpaceToRight) {\r\n newShadowPosition = ShadowPosition.right\r\n }\r\n\r\n setShadowPosition(newShadowPosition)\r\n }, 100)\r\n\r\n if (shouldScrollToEnd) {\r\n tableWrapperElement.scrollTo({\r\n left: tableWrapperElement.scrollWidth,\r\n })\r\n }\r\n\r\n onScroll()\r\n\r\n tableWrapperElement.addEventListener('scroll', onScroll)\r\n window.addEventListener('resize', onScroll)\r\n\r\n return () => {\r\n tableWrapperElement.removeEventListener('scroll', onScroll)\r\n window.removeEventListener('resize', onScroll)\r\n }\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n const tableWrapperElement = tableWrapperRef.current\r\n if (!tableWrapperElement) return\r\n\r\n setElementRef(tableWrapperElement)\r\n const financialsTable = tableWrapperElement.querySelector('table')\r\n const headHeight = financialsTable?.querySelector('thead')?.clientHeight ?? 0\r\n const firstColum = financialsTable?.querySelector('tbody tr > td')\r\n const firstColumnWidth = firstColum?.getBoundingClientRect().width ?? 0\r\n\r\n const topOffset = hasHeaderShadow ? 0 : headHeight + tableShadowMargin\r\n setShadowDimensions({\r\n left: firstColumnWidth,\r\n top: topOffset,\r\n height: (financialsTable?.clientHeight ?? 0) - (hasHeaderShadow ? 0 : topOffset + tableShadowMargin),\r\n })\r\n }, [setElementRef, elementHeight, tableShadowMargin, hasHeaderShadow])\r\n\r\n const { radiusCropFillerStyle, shadowLeftStyle, shadowRightStyle } = React.useMemo(\r\n () => ({\r\n radiusCropFillerStyle: {\r\n top: shadowDimensions.top - tableShadowMargin,\r\n height: shadowDimensions.height + 2 * tableShadowMargin,\r\n },\r\n shadowLeftStyle: {\r\n top: shadowDimensions.top,\r\n left: shadowDimensions.left,\r\n },\r\n shadowRightStyle: {\r\n top: shadowDimensions.top,\r\n right: 0,\r\n },\r\n }),\r\n [shadowDimensions, tableShadowMargin]\r\n )\r\n\r\n return (\r\n
\r\n {/* Width of radius crop filler needs to be the same as radius */}\r\n \r\n \r\n
\r\n {children}\r\n
\r\n \r\n
\r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\ninterface TableProps extends React.PropsWithChildren> {\r\n isFullWidth?: boolean\r\n}\r\n\r\nexport const Table = React.forwardRef(\r\n ({ isFullWidth = true, ...props }: TableProps, ref: React.ForwardedRef) => (\r\n \r\n )\r\n)\r\n\r\nexport function TableHead(props: React.PropsWithChildren>) {\r\n return (\r\n \r\n {/* sticky column uses bg-inherit which we want to propagate from thead */}\r\n {props.children}\r\n \r\n )\r\n}\r\n\r\ninterface TableBodyProps extends React.HTMLProps {\r\n spacing?: 'regular' | 'large' | 'none'\r\n}\r\n\r\nexport const TableBody = React.forwardRef(\r\n (\r\n { spacing = 'none', ...props }: React.PropsWithChildren,\r\n ref: React.ForwardedRef\r\n ) => (\r\n \r\n )\r\n)\r\n\r\nexport function TableFooter(props: React.PropsWithChildren>) {\r\n return (\r\n \r\n {props.children}\r\n \r\n )\r\n}\r\n","export const TABLE_STICKY_CELL_CLASS_NAME = 'sticky left-0 whitespace-nowrap z-20 bg-inherit'\r\n","export enum TableAlign {\r\n Left,\r\n Center,\r\n Right,\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { TABLE_STICKY_CELL_CLASS_NAME } from './constants'\r\nimport { TableAlign } from './types'\r\n\r\nexport interface TableCellProps extends React.HTMLProps {\r\n isFirst?: boolean\r\n isLast?: boolean\r\n align?: TableAlign\r\n hasPadding?: boolean\r\n hasLeading?: boolean\r\n isSticky?: boolean\r\n}\r\n\r\nexport function TableCell({\r\n isFirst,\r\n isLast,\r\n align = TableAlign.Left,\r\n hasPadding = true,\r\n hasLeading = true,\r\n isSticky,\r\n className,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n return (\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Icon } from '../icon'\r\nimport { PropsWithAs } from '../types'\r\nimport { TABLE_STICKY_CELL_CLASS_NAME } from './constants'\r\nimport { TableAlign } from './types'\r\n\r\nconst TABLE_HEADER_DEFAULT_ELEMENT = 'th'\r\n\r\ninterface SortProps {\r\n isActive: boolean\r\n direction: 1 | -1\r\n}\r\n\r\nfunction TableSortIndicator({ isActive, direction, className }: Partial & { className?: string }) {\r\n return (\r\n \r\n )\r\n}\r\n\r\ninterface TableHeaderProps extends Omit, 'as'> {\r\n isActive?: boolean\r\n align?: TableAlign\r\n hasPadding?: boolean\r\n hasHover?: boolean\r\n isSticky?: boolean\r\n}\r\n\r\nexport function TableHeader({\r\n as: asComponent,\r\n align,\r\n children,\r\n isActive,\r\n hasPadding = true,\r\n hasHover,\r\n isSticky,\r\n ...props\r\n}: Omit, 'align'> & TableHeaderProps) {\r\n const componentToRender = asComponent ?? TABLE_HEADER_DEFAULT_ELEMENT\r\n\r\n return React.createElement(\r\n componentToRender,\r\n {\r\n ...props,\r\n className: classnames(\r\n props.className,\r\n 'whitespace-nowrap font-normal h-5 hover:first:rounded-l-md hover:last:rounded-r-md',\r\n {\r\n [TABLE_STICKY_CELL_CLASS_NAME]: isSticky,\r\n 'cursor-pointer hover:select-none hover:bg-gray-200/30 dark:hover:bg-gray-500/30':\r\n hasHover && !props.disabled,\r\n 'text-gray-500 dark:text-gray-300': props.disabled,\r\n 'text-gray-600 dark:text-gray-200': !isActive && !props.disabled,\r\n 'font-medium text-gray-800 dark:text-gray-50': isActive,\r\n 'text-left': align === TableAlign.Left,\r\n 'text-center': align === TableAlign.Center,\r\n 'text-right': align === TableAlign.Right,\r\n 'px-1': hasPadding,\r\n 'p-0': !hasPadding,\r\n }\r\n ),\r\n },\r\n children\r\n )\r\n}\r\n\r\nexport function TableHeaderSortable({\r\n direction,\r\n ...props\r\n}: Omit, 'align'> & Partial & TableHeaderProps) {\r\n const isDisabled = props.disabled === true\r\n\r\n return (\r\n \r\n \r\n {props.align === TableAlign.Right && (\r\n \r\n )}\r\n {props.children}\r\n {props.align !== TableAlign.Right && (\r\n \r\n )}\r\n \r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\ninterface TableRowProps extends React.PropsWithChildren> {\r\n isFirst?: boolean\r\n isLast?: boolean\r\n isHoverable?: boolean\r\n isRounded?: boolean\r\n}\r\n\r\nexport const TableRow = React.forwardRef(\r\n (\r\n { isFirst, isLast, isHoverable = true, isRounded = false, ...props }: TableRowProps,\r\n ref: React.ForwardedRef\r\n ) => (\r\n \r\n )\r\n)\r\n","import * as React from 'react'\r\nimport { useEffect } from 'react'\r\nimport { useSearchParams } from 'react-router-dom'\r\n\r\nimport { usePrevious } from '../../hooks/use-previous'\r\nimport { SortByShape, SortableColumn, useSortData } from '../../hooks/use-sort-data'\r\nimport { SortDirection, SortableValue } from '../../types'\r\nimport { SortByColumnOptions } from '../../util'\r\nimport { encodeSort, getDefaultSort, getDefaultSortFromUrl, saveSortToUrl } from './utils'\r\n\r\ninterface UseTableSortProps<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n> {\r\n data: DataType[]\r\n columns: readonly ColumnType[]\r\n\r\n /**\r\n * You can either provide id of the column or whole shape\r\n * defaultSort: { column: columns[0], direction: -1 }\r\n * If your ids are constants (or enums), you will get name suggestions\r\n */\r\n defaultSort?: DefaultSort\r\n\r\n /**\r\n * Custom value getter. By default, these can be defined on every column using `getValueForSort`\r\n */\r\n valueGetter?: (column: ColumnType) => (row: DataType) => SortableValue\r\n\r\n /**\r\n * Additional options for sorting, including ignoring null values or sorting null as last\r\n */\r\n options?: SortByColumnOptions\r\n\r\n /**\r\n * Value which reinits defaults if changed\r\n */\r\n key?: string | number\r\n}\r\n\r\n/**\r\n * This hook has multiple\r\n */\r\nexport function useTableSort<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n SortType extends DefaultSort extends null ? ColumnType | null : ColumnType,\r\n>({\r\n data,\r\n columns,\r\n defaultSort,\r\n valueGetter,\r\n options,\r\n key,\r\n}: UseTableSortProps) {\r\n const [sort, setSort] = React.useState(() => getDefaultSort(columns, defaultSort) as SortByShape)\r\n const isMountedRef = React.useRef(false)\r\n\r\n React.useMemo(() => {\r\n if (!isMountedRef.current) {\r\n isMountedRef.current = true\r\n return\r\n }\r\n\r\n setSort(getDefaultSort(columns, defaultSort) as SortByShape)\r\n // We want to run it only on key change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [key])\r\n\r\n const changeSort = React.useCallback((newSort: SortType, direction?: SortDirection) => {\r\n setSort((prevSort) => {\r\n if (newSort && direction) {\r\n return { column: newSort, direction }\r\n }\r\n\r\n if (newSort && prevSort.column?.id === newSort.id) {\r\n return { ...prevSort, direction: prevSort.direction * -1 }\r\n }\r\n\r\n return { column: newSort, direction: SortDirection.Ascending }\r\n })\r\n }, [])\r\n\r\n const sortedData = useSortData({\r\n columns,\r\n data,\r\n sortBy: sort as unknown as SortByShape,\r\n valueGetter,\r\n options,\r\n })\r\n\r\n return {\r\n data: sortedData,\r\n sort,\r\n changeSort,\r\n }\r\n}\r\n\r\ninterface UseTableSortWithAutoupdateProps<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n> extends UseTableSortProps {\r\n tableOrder: string\r\n}\r\n\r\n/**\r\n * This hook will monitor changes in `tableOrder` and update its sort order by it\r\n * Useful if we need to keep sort order of multiple tables in sync\r\n */\r\nexport function useTableSortWithAutoupdate<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n>({\r\n data,\r\n columns,\r\n defaultSort,\r\n valueGetter,\r\n options,\r\n tableOrder,\r\n}: UseTableSortWithAutoupdateProps) {\r\n const { data: sortedData, changeSort, sort } = useTableSort({ data, columns, defaultSort, valueGetter, options })\r\n const previousTableOrder = usePrevious(tableOrder)\r\n\r\n useEffect(() => {\r\n if (previousTableOrder && tableOrder !== previousTableOrder) {\r\n let sortName\r\n let sortDirection\r\n if (tableOrder.startsWith('-')) {\r\n sortName = tableOrder.slice(1)\r\n sortDirection = SortDirection.Descending\r\n } else {\r\n sortName = tableOrder\r\n sortDirection = SortDirection.Ascending\r\n }\r\n const column = columns.find((column) => column.id === sortName)\r\n if (column) {\r\n changeSort(column, sortDirection)\r\n }\r\n }\r\n }, [changeSort, columns, previousTableOrder, tableOrder])\r\n\r\n return {\r\n data: sortedData,\r\n sort,\r\n changeSort,\r\n }\r\n}\r\n\r\ninterface UseTableSortWithUrlProps<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n> extends UseTableSortProps {\r\n /**\r\n * When set, the sorting will be persisted in the URL. Loading the\r\n *\r\n * @default \"o\"\r\n */\r\n urlPersistKey?: string\r\n\r\n /**\r\n * Key to get value of the URL sort from a column\r\n * @default \"id\"\r\n */\r\n idKey?: keyof ColumnType\r\n}\r\n\r\nexport function useTableSortWithUrl<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n DefaultSort extends ColumnType['id'] | SortByShape | null,\r\n SortType extends DefaultSort extends null ? ColumnType | null : ColumnType,\r\n>({\r\n data,\r\n columns,\r\n defaultSort,\r\n valueGetter,\r\n urlPersistKey = 'o',\r\n idKey = 'id',\r\n options,\r\n key,\r\n}: UseTableSortWithUrlProps) {\r\n const [searchParams, setSearchParams] = useSearchParams()\r\n const defaultSortRef = React.useRef(\r\n urlPersistKey && typeof defaultSort === 'string'\r\n ? getDefaultSortFromUrl(columns, searchParams.get(urlPersistKey) ?? defaultSort, idKey)\r\n : getDefaultSort(columns, defaultSort)\r\n )\r\n const {\r\n data: sortedData,\r\n changeSort: changeSortState,\r\n sort,\r\n } = useTableSort({\r\n data,\r\n columns,\r\n defaultSort: defaultSortRef.current.column === null ? null : (defaultSortRef.current as SortByShape),\r\n valueGetter,\r\n options,\r\n key,\r\n })\r\n\r\n const changeSort = React.useCallback(\r\n (newSort: SortType, additionalUrlParams?: URLSearchParams) => {\r\n if (urlPersistKey) {\r\n const defaultSort: ColumnType | null = defaultSortRef.current.column\r\n setSearchParams(\r\n (prev) => {\r\n const newSearchParams = saveSortToUrl(\r\n prev,\r\n urlPersistKey,\r\n newSort,\r\n idKey,\r\n defaultSort === null ? null : encodeSort(`${defaultSort[idKey]}`, defaultSortRef.current.direction)\r\n )\r\n additionalUrlParams?.forEach((value, key) => {\r\n newSearchParams.set(key, value)\r\n })\r\n return newSearchParams\r\n },\r\n {\r\n preventScrollReset: true,\r\n }\r\n )\r\n }\r\n\r\n changeSortState(newSort)\r\n },\r\n [idKey, setSearchParams, urlPersistKey, changeSortState]\r\n )\r\n\r\n /**\r\n * Update sort from url\r\n */\r\n React.useEffect(() => {\r\n if (!urlPersistKey) return\r\n\r\n const newSort = searchParams.get(urlPersistKey)\r\n if (newSort) {\r\n const sort = getDefaultSortFromUrl(columns, newSort, idKey)\r\n changeSortState(sort.column, sort.direction)\r\n }\r\n }, [columns, idKey, searchParams, urlPersistKey, changeSortState])\r\n\r\n return {\r\n data: sortedData,\r\n sort,\r\n changeSort,\r\n }\r\n}\r\n","import { SortByShape, SortableColumn, isSortByShape, isSortableColumnShape } from '../../hooks/use-sort-data'\r\nimport { SortDirection } from '../../types'\r\n\r\n/**\r\n * Default sort getter which either gets column matching by `defaultSortId` or returns the first column\r\n */\r\n\r\nexport function getDefaultSort, DefaultSort>(\r\n columns: readonly ColumnType[],\r\n defaultSort?: DefaultSort\r\n): SortByShape {\r\n if (defaultSort === null) return { column: null as unknown as ColumnType, direction: SortDirection.Ascending }\r\n\r\n if (isSortByShape(defaultSort)) {\r\n if (isSortableColumnShape(defaultSort.column)) {\r\n return defaultSort as unknown as SortByShape\r\n }\r\n\r\n return { ...defaultSort, column: columns.find((column) => column.id === defaultSort.column) ?? columns[0] }\r\n }\r\n\r\n const foundColumn = columns.find(\r\n (column) => column.id === (isSortableColumnShape(defaultSort) ? defaultSort.id : defaultSort)\r\n )\r\n\r\n return { column: foundColumn ?? columns[0], direction: SortDirection.Ascending }\r\n}\r\n/**\r\n * Get default sorting from url when persisting sort\r\n */\r\n\r\nexport function getDefaultSortFromUrl, OrderType extends string | null>(\r\n columns: readonly ColumnType[],\r\n order?: OrderType,\r\n idKey: keyof ColumnType = 'id'\r\n): SortByShape {\r\n if (order === null) return { column: null as unknown as ColumnType, direction: SortDirection.Ascending }\r\n\r\n const isDesc = order?.startsWith('-')\r\n const queryParam = isDesc ? order?.substring(1) : order\r\n const column = columns.find((column) => column[idKey] === queryParam)\r\n\r\n if (column) {\r\n return { column, direction: isDesc ? SortDirection.Descending : SortDirection.Ascending }\r\n } else {\r\n return { column: columns[0], direction: SortDirection.Ascending }\r\n }\r\n}\r\n\r\nexport function encodeSort(sortedColumn: string, sortDir: SortDirection) {\r\n return `${sortDir === SortDirection.Descending ? '-' : ''}${sortedColumn}`\r\n}\r\n\r\nexport function saveSortToUrl>(\r\n prev: URLSearchParams,\r\n urlPersistKey: string,\r\n newSort: ColumnType | null,\r\n idKey: keyof ColumnType = 'id',\r\n defaultSort: unknown = null\r\n) {\r\n const newParams = new URLSearchParams(prev)\r\n const previousOrder = newParams.get(urlPersistKey) ?? defaultSort\r\n const isDescOrder = previousOrder?.toString().startsWith('-')\r\n\r\n if (newSort === null) {\r\n newParams.delete(urlPersistKey)\r\n } else {\r\n newParams.set(\r\n urlPersistKey,\r\n encodeSort(\r\n `${newSort[idKey]}`,\r\n !isDescOrder && previousOrder === newSort[idKey] ? SortDirection.Descending : SortDirection.Ascending\r\n )\r\n )\r\n }\r\n\r\n return newParams\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button, ButtonRounding, ButtonRoundingType } from '../button'\r\n\r\nexport enum GroupTheme {\r\n light,\r\n dark,\r\n}\r\n\r\nexport interface ButtonGroupProps {\r\n children: React.ReactNode\r\n\r\n /**\r\n * Border radius of entire group wrapper\r\n *\r\n * @default \"regular\"\r\n */\r\n rounding?: ButtonRoundingType\r\n\r\n className?: string\r\n\r\n /**\r\n * If a pipe divider between buttons should be rendered\r\n *\r\n * @default true\r\n */\r\n hasDivider?: boolean\r\n\r\n /**\r\n * If group wrapper has a border\r\n *\r\n * @default true\r\n */\r\n hasBorder?: boolean\r\n\r\n /**\r\n * Group color theme\r\n *\r\n * @default \"light\"\r\n */\r\n theme?: keyof typeof GroupTheme\r\n\r\n /**\r\n * Custom button component which extends Button\r\n *\r\n * @default undefined\r\n */\r\n childComponent?: string | React.JSXElementConstructor\r\n}\r\n\r\nfunction getGroupTheme(theme: GroupTheme) {\r\n switch (theme) {\r\n case GroupTheme.dark:\r\n return {\r\n wrapper: 'bg-gray-800 border-gray-600',\r\n divider: 'bg-gray-600',\r\n }\r\n default:\r\n return {\r\n wrapper: 'bg-white dark:bg-gray-800 border-gray-100 dark:border-gray-600',\r\n divider: 'bg-gray-100 dark:bg-gray-600',\r\n }\r\n }\r\n}\r\n\r\nexport function ButtonGroup({\r\n className,\r\n children,\r\n theme = 'light',\r\n hasDivider = true,\r\n hasBorder = true,\r\n rounding = 'regular',\r\n childComponent,\r\n}: ButtonGroupProps) {\r\n const buttonRounding = ButtonRounding[rounding]\r\n const groupTheme = React.useMemo(() => getGroupTheme(GroupTheme[theme]), [theme])\r\n const numberOfChildren = React.Children.count(children)\r\n\r\n return (\r\n \r\n {React.Children.map(children, (child, index) => {\r\n if (!React.isValidElement(child) || ![Button, childComponent].filter(Boolean).includes(child.type)) {\r\n return child\r\n }\r\n\r\n const isButtonRounded = !hasBorder && rounding !== 'none'\r\n const isSideButton = index === 0 || index === numberOfChildren - 1\r\n const givenRounding = isButtonRounded && isSideButton ? rounding : 'none'\r\n const givenTheme = GroupTheme[theme] === GroupTheme.dark ? 'menuItemDark' : 'menuItem'\r\n\r\n return (\r\n \r\n {hasDivider && index > 0 &&
}\r\n {React.cloneElement(child as React.ReactElement>, {\r\n rounding: child.props.rounding ?? givenRounding,\r\n theme: child.props.theme ?? givenTheme,\r\n className: classnames(child.props.className, 'hover:relative', {\r\n 'hover:z-10': !child.props.disabled,\r\n relative: child.props.active,\r\n 'rounded-r-none': !child.props.rounding && isButtonRounded && index === 0,\r\n 'rounded-l-none': !child.props.rounding && isButtonRounded && index === numberOfChildren - 1,\r\n }),\r\n })}\r\n \r\n )\r\n })}\r\n
\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { CalendarProps } from 'react-calendar'\r\n\r\nimport { Box } from '../box'\r\nimport { Popover, PopoverTrigger, usePopoverState } from '../popover'\r\nimport { Spinner } from '../spinner'\r\n\r\nconst DatePickerComponent = React.lazy(() => import('./picker'))\r\n\r\ntype RangePickerCallback = (value: [Date, Date], ev: React.ChangeEvent) => void\r\ntype PickerCallback = (value: Date, ev: React.ChangeEvent) => void\r\n\r\ninterface DatePickerProps extends Omit {\r\n /**\r\n * Trigger element for the picker\r\n */\r\n children: JSX.Element\r\n\r\n onChange: PickerCallback | RangePickerCallback\r\n}\r\n\r\nexport function StatelessDatePicker({\r\n state,\r\n children,\r\n ...props\r\n}: DatePickerProps & { state: ReturnType; zIndex?: string }) {\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n \r\n }\r\n >\r\n ) => {\r\n state.hide()\r\n props.onChange?.(value, ev)\r\n }}\r\n />\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport function DatePicker(props: DatePickerProps) {\r\n const popover = usePopoverState()\r\n\r\n return \r\n}\r\n","import * as React from 'react'\r\n\r\nexport interface DelayedProps {\r\n /**\r\n * The delay in milliseconds before the component is rendered.\r\n *\r\n * @default 300\r\n */\r\n delay?: number\r\n\r\n /**\r\n * Delay in milliseconds before rendering timeout state.\r\n */\r\n timeout?: number\r\n\r\n /**\r\n * Throw on timeout (suspense)\r\n */\r\n throwOnTimeout?: boolean\r\n\r\n /**\r\n * Component visible during the delay.\r\n * If rendering text, wrap it in a `span` to prevent error — see PR#608\r\n */\r\n delayComponent?: React.ReactNode\r\n\r\n /**\r\n * Component visible when timeout is over.\r\n * If rendering text, wrap it in a `span` to prevent error — see PR#608\r\n */\r\n timeoutComponent?: React.ReactNode\r\n\r\n /**\r\n * Component visible when delay is over.\r\n * If rendering text, wrap it in a `span` to prevent error — see PR#608\r\n */\r\n children?: React.ReactNode\r\n}\r\n\r\nexport function Delayed({\r\n delay = 300,\r\n timeout = 0,\r\n throwOnTimeout = false,\r\n delayComponent,\r\n timeoutComponent,\r\n children,\r\n}: DelayedProps) {\r\n const [visible, setVisible] = React.useState(false)\r\n const [hasTimedOut, setHasTimedOut] = React.useState(false)\r\n\r\n React.useEffect(() => {\r\n const visibilityTimeout = window.setTimeout(() => setVisible(true), delay)\r\n\r\n let failedTimeout: number\r\n if (timeout > 0) {\r\n failedTimeout = window.setTimeout(() => {\r\n setHasTimedOut(true)\r\n if (throwOnTimeout) throw new Error()\r\n }, timeout)\r\n }\r\n\r\n return () => {\r\n clearTimeout(visibilityTimeout)\r\n clearTimeout(failedTimeout)\r\n }\r\n }, [delay, timeout, throwOnTimeout])\r\n\r\n if (!visible) return <>{delayComponent}\r\n\r\n if (hasTimedOut) {\r\n return <>{timeoutComponent}\r\n }\r\n\r\n return <>{children}\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { useElementMeasure } from '../../hooks/use-element-measure'\r\nimport { Box, BoxProps } from '../box'\r\nimport { DialogDragContext } from './hooks'\r\n\r\n/**\r\n * Public props for the component\r\n */\r\nexport type DialogBoxProps = BoxProps\r\n\r\ninterface DialogBoxOwnProps extends DialogBoxProps {\r\n /**\r\n * This callback serves as a way to account for the time between dialog close\r\n * and animation finish. The box isn’t rendered when the dialog closes but we still\r\n * want to display content when the dialog is closing\r\n */\r\n onUnmount?: () => void\r\n}\r\n\r\n/**\r\n * Dialog content container\r\n */\r\nexport function DialogBox({ onUnmount, style, ...props }: React.PropsWithChildren) {\r\n const wrapperRef = React.useRef(null)\r\n const { setElementRef, elementHeight } = useElementMeasure()\r\n const dialogDrag = React.useContext(DialogDragContext)\r\n\r\n React.useEffect(() => {\r\n const onResize = () => {\r\n const { top = 0, bottom = 0, left = 0, right = 0 } = dialogDrag.handleRef?.current?.getBoundingClientRect() ?? {}\r\n const { clientHeight, clientWidth } = window.document.documentElement\r\n if (top < 0 || bottom > clientHeight || left < 0 || right > clientWidth) {\r\n dialogDrag.resetBoxPosition()\r\n }\r\n }\r\n\r\n window.addEventListener('resize', onResize)\r\n onResize()\r\n\r\n return () => {\r\n window.removeEventListener('resize', onResize)\r\n onUnmount?.()\r\n }\r\n // Set up an effect which only calls resetBoxPosition which is ref fn with state setter call and the unmount callback\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n React.useEffect(() => {\r\n setElementRef(wrapperRef.current)\r\n }, [setElementRef])\r\n\r\n React.useEffect(() => {\r\n dialogDrag.setBoxPosition((prevPosition) => {\r\n const { top = 0 } = dialogDrag.handleRef?.current?.getBoundingClientRect() ?? {}\r\n return { ...prevPosition, y: prevPosition.y - Math.min(top, 0) }\r\n })\r\n // We want to call it only on elementHeight change\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [elementHeight])\r\n\r\n const dialogBoxStyle = React.useMemo(() => {\r\n if (dialogDrag.enabled) {\r\n return { ...style, transform: `translate3d(${dialogDrag.boxPosition.x}px, ${dialogDrag.boxPosition.y}px, 0)` }\r\n }\r\n return style\r\n }, [style, dialogDrag])\r\n\r\n return (\r\n \r\n {props.children}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { isIpad, isMobile } from '../../../app/shared/isMobile'\r\nimport { useScreenSize } from '../../hooks/use-screen-size'\r\nimport { useVisualViewport } from '../../hooks/useVisualViewport'\r\nimport { ChildPosition, blurWithoutScroll, getFlexAlignClasses } from '../../util'\r\nimport { DialogBox, DialogBoxProps } from './dialog-box'\r\nimport { DialogDragContext, DialogStateReturn, ZIndexContext, useDrag, useZIndex } from './hooks'\r\n\r\nexport enum DialogType {\r\n modal,\r\n drawer,\r\n}\r\n\r\nexport interface DialogProps extends DialogBoxProps {\r\n /**\r\n * The returned object from `useDialogState`\r\n */\r\n state: DialogStateReturn\r\n\r\n /**\r\n * When true, all outside elements won’t be interactable\r\n *\r\n * @default true\r\n */\r\n modal?: boolean\r\n\r\n /**\r\n * Sets if the dialog can be dragged across the screen\r\n *\r\n * @default false\r\n */\r\n isDraggable?: boolean\r\n\r\n /**\r\n * Type of dialog\r\n *\r\n * @default modal\r\n */\r\n type?: keyof typeof DialogType\r\n\r\n /**\r\n * Dialog position on the screen\r\n *\r\n * @default center\r\n */\r\n position?: keyof typeof ChildPosition\r\n\r\n /**\r\n * Hide the dialog when user presses ESC\r\n *\r\n * @default true\r\n */\r\n hideOnEsc?: Ariakit.DialogProps['hideOnEscape']\r\n\r\n /**\r\n * Show backdrop on the dialog. Provide your own element if you want to add background or animation\r\n *\r\n */\r\n backdrop?: false | JSX.Element\r\n\r\n /**\r\n * Callback which is called when the dialog opens and all animations complete\r\n */\r\n onFullyOpen?: () => void\r\n\r\n /**\r\n * Callback which is called when the dialog closes and all animations complete\r\n */\r\n onFullyClosed?: () => void\r\n\r\n /**\r\n * Callback before the dialog starts hiding. Event can be prevented which keeps the dialog open\r\n * This callback isn’t called on backdrop click. Use `backdrop={
}` to react on backdrop clicks\r\n */\r\n onClose?: (event: Event) => void\r\n}\r\n\r\nexport function Dialog({\r\n state,\r\n modal = true,\r\n isDraggable = false,\r\n type = 'modal',\r\n position = 'center',\r\n hideOnEsc = true,\r\n backdrop,\r\n onFullyOpen,\r\n onFullyClosed,\r\n onClose,\r\n children,\r\n 'data-testid': dataTestId,\r\n 'aria-label': ariaLabel,\r\n ...props\r\n}: React.PropsWithChildren) {\r\n const zIndex = useZIndex('z-dialog')\r\n const dialogDrag = useDrag(isDraggable)\r\n const isOpen = state.useState('open')\r\n const [isFullyOpen, setIsFullyOpen] = React.useState(false)\r\n const { viewport } = useVisualViewport({ enabled: isOpen, onScroll: false })\r\n const screenSize = useScreenSize()\r\n\r\n const dialogStyle = React.useMemo(() => {\r\n if (isMobile() && !isIpad() && viewport.scale !== 1) {\r\n return {\r\n left: viewport.left,\r\n top: viewport.top,\r\n width: viewport.unscaledWidth,\r\n height: viewport.unscaledHeight,\r\n minWidth: screenSize.width,\r\n minHeight: screenSize.width,\r\n willChange: 'auto',\r\n }\r\n }\r\n return\r\n }, [screenSize, viewport])\r\n\r\n return (\r\n state.hide()} />}\r\n autoFocusOnHide={blurWithoutScroll}\r\n aria-label={ariaLabel}\r\n // E2E tests don’t wait for transitions to complete and it could lead to bugs with other popover components (ResizeObserver loop exceeded)\r\n // or visual diffs due a screenshot being captured while the dialog still in transition\r\n // If you encounter this problem, just do `cy.get('[data-fully-open=true]').should('exist')` before continuing to wait for the dialog\r\n data-fully-open={isFullyOpen}\r\n data-testid={dataTestId}\r\n style={dialogStyle}\r\n className={classnames(\r\n 'group/dialog pointer-events-none fixed bottom-0 left-0 right-0 top-0 flex max-w-full outline-none transition duration-[250ms] ipad-fullscreen:pt-5',\r\n zIndex,\r\n DialogType[type] === DialogType.modal && getFlexAlignClasses(ChildPosition[position]),\r\n {\r\n 'p-2 opacity-0 data-[enter]:scale-100 data-[enter]:opacity-100 motion-safe:scale-95 sm:p-5':\r\n DialogType[type] === DialogType.modal,\r\n 'justify-end data-[enter]:translate-x-0 motion-safe:translate-x-full': DialogType[type] === DialogType.drawer,\r\n }\r\n )}\r\n onTransitionEnd={(ev) => {\r\n if (ev.target === ev.currentTarget && isOpen) {\r\n setIsFullyOpen(true)\r\n onFullyOpen?.()\r\n }\r\n }}\r\n onClose={(ev) => {\r\n onClose?.(ev)\r\n // prevented means the dialog didn’t close\r\n if (!ev.defaultPrevented) setIsFullyOpen(false)\r\n }}\r\n >\r\n \r\n \r\n {\r\n onFullyClosed?.()\r\n dialogDrag.resetBoxPosition()\r\n }}\r\n >\r\n {children}\r\n \r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport const DialogDismiss = Ariakit.DialogDismiss\r\n","import { isMobile } from '../../app/shared/isMobile'\r\n\r\nexport function useScreenSize() {\r\n return {\r\n width: isMobile() ? window.screen.width : window.innerWidth,\r\n height: isMobile() ? window.screen.height : window.innerHeight,\r\n }\r\n}\r\n","import { disableBodyScroll, enableBodyScroll } from 'body-scroll-lock'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\n\r\ninterface DialogBodyProps extends React.HTMLProps {\r\n /**\r\n * Whether or not the dialog body will have padding\r\n *\r\n * @default true\r\n */\r\n hasPadding?: boolean\r\n}\r\n\r\n/**\r\n * Content wrapper which handles scrolling on mobile\r\n */\r\nexport function DialogBody({ hasPadding = true, ...props }: React.PropsWithChildren) {\r\n const scrollDivRef = React.useRef(null)\r\n\r\n React.useEffect(() => {\r\n const scrollBox = scrollDivRef.current\r\n\r\n if (isMobile() && scrollBox) {\r\n disableBodyScroll(scrollBox)\r\n\r\n return () => enableBodyScroll(scrollBox)\r\n }\r\n }, [])\r\n\r\n return (\r\n \r\n {props.children}\r\n
\r\n )\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { Heading, Paragraph } from '../typography'\r\nimport { Dialog, DialogProps } from './dialog'\r\nimport { DialogBody } from './dialog-body'\r\nimport { DialogStateReturn } from './hooks'\r\n\r\ninterface ConfirmationDialogProps {\r\n state: DialogStateReturn\r\n title: React.ReactNode\r\n actions: React.ReactNode\r\n 'aria-label': string\r\n position?: DialogProps['position']\r\n}\r\n\r\nexport function ConfirmationDialog({ position, ...props }: React.PropsWithChildren) {\r\n return (\r\n }\r\n data-testid=\"confirmation-dialog\"\r\n >\r\n \r\n \r\n {props.title}\r\n \r\n {props.children}\r\n
{props.actions}
\r\n
\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\ninterface DialogFooterProps extends React.HTMLProps {\r\n padding?: boolean\r\n}\r\n\r\n/**\r\n * Footer container which renders border and aligns items to right\r\n */\r\nexport function DialogFooter({ padding = true, ...props }: React.PropsWithChildren) {\r\n return (\r\n \r\n {props.children}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button } from '../button'\r\nimport { Icon } from '../icon'\r\nimport { Heading } from '../typography'\r\nimport { DialogDragContext } from './hooks'\r\n\r\ninterface DialogHeaderProps {\r\n /**\r\n * Hide the close button\r\n * @default true\r\n */\r\n isCloseButtonVisible?: boolean\r\n\r\n /**\r\n * Callback when user clicks on close button. The button will be hidden if not set\r\n */\r\n onCloseClick?: () => void\r\n\r\n /**\r\n * Additional class names for the component\r\n */\r\n className?: string\r\n\r\n /**\r\n * Whether or not the dialog header will have default horizontal padding\r\n *\r\n * @default true\r\n */\r\n hasHorizontalPadding?: boolean\r\n\r\n /**\r\n * Whether or not the dialog header will have default min height\r\n *\r\n * @default true\r\n */\r\n hasMinHeight?: boolean\r\n\r\n /**\r\n * Whether or not the dialog header children should be rendered as Heading\r\n *\r\n * @default true\r\n */\r\n asHeading?: boolean\r\n}\r\n\r\n/**\r\n * Component which renders title and a close button\r\n */\r\nexport function DialogHeader({\r\n children,\r\n className,\r\n hasHorizontalPadding = true,\r\n hasMinHeight = true,\r\n asHeading = true,\r\n isCloseButtonVisible = true,\r\n onCloseClick,\r\n}: React.PropsWithChildren) {\r\n const dialogDrag = React.useContext(DialogDragContext)\r\n\r\n return (\r\n \r\n {children &&\r\n (asHeading ? (\r\n \r\n {children}\r\n \r\n ) : (\r\n children\r\n ))}\r\n {isCloseButtonVisible && (\r\n onCloseClick?.()}\r\n >\r\n \r\n \r\n )}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Delayed } from './delayed'\r\nimport { Spinner } from './spinner'\r\n\r\ninterface Props {\r\n label: React.ReactNode\r\n isLoading: boolean\r\n}\r\n\r\nexport function LabelWithDelayedSpinner({ label, isLoading }: Props) {\r\n return (\r\n <>\r\n {label}\r\n {isLoading && (\r\n
\r\n {label}}>\r\n \r\n \r\n
\r\n )}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classnames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { usePopoverPlacement } from '../../hooks/usePopoverPlacement'\r\nimport { blurWithoutScroll, focusWithoutScroll } from '../../util'\r\nimport { ZIndexContext } from '../dialog'\r\nimport { PopoverStateReturn } from './hooks'\r\n\r\nexport enum PopoverRounding {\r\n none = '',\r\n regular = 'rounded-lg',\r\n}\r\n\r\nexport enum PopoverTheme {\r\n none = '',\r\n default = 'flex flex-col overflow-hidden border border-primary bg-primary shadow-modal dark:shadow-modal-dark',\r\n}\r\n\r\nexport interface PopoverProps extends Omit, 'ref'>, Ariakit.PopoverProps {\r\n // State is intentionally not marked as optional so you get error when you don’t provide it\r\n /**\r\n * Returned state from `usePopoverState`. Set `undefined` if you use a `PopoverProvider` wrapper\r\n */\r\n state: PopoverStateReturn | undefined\r\n\r\n /**\r\n * When true, the popover will be rendered in a portal and all outside elements won’t be interactable\r\n *\r\n * @default true\r\n */\r\n modal?: boolean\r\n\r\n /**\r\n * Set rounding for the popover\r\n *\r\n * @default regular\r\n */\r\n rounding?: keyof typeof PopoverRounding\r\n\r\n /**\r\n * Popover theme\r\n */\r\n theme?: keyof typeof PopoverTheme\r\n\r\n /**\r\n * The amount of space between button and its popover\r\n *\r\n * @default 4\r\n */\r\n gutter?: number\r\n\r\n /**\r\n * Hide the popover when user presses ESC\r\n *\r\n * @default true\r\n */\r\n hideOnEsc?: boolean\r\n\r\n /**\r\n * Show backdrop on the popover. Provide your own element if you want to add background or animation\r\n *\r\n */\r\n backdrop?: false | JSX.Element\r\n\r\n /**\r\n * Do not render the items when the popover is not visible\r\n *\r\n * @default true\r\n */\r\n unmountOnHide?: boolean\r\n\r\n /**\r\n * By default the popover hides when backdrop is clicked. When backdrop is disabled you can use this prop to\r\n * enable hiding when clicking outside of the popover\r\n */\r\n hideOnInteractOutside?: boolean\r\n\r\n /**\r\n * Callback before the popover starts hiding. Event can be prevented which keeps the popover open\r\n * This callback isn’t called on backdrop click. Use `backdrop={
}` to react on backdrop clicks\r\n */\r\n onClose?: (event: Event) => void\r\n\r\n /**\r\n * Set which element gets focus when the dialog visibility changes. If `false`, the focus stays on the previous element.\r\n * Defaults to focusing without scrolling the page or keeping the focus on trigger if input-like.\r\n */\r\n autoFocusOnShow?: false | (() => boolean)\r\n\r\n /**\r\n * Set which element gets focus when the dialog visibility changes. If `false`, the focus stays on the previous element.\r\n * Defaults to focusing without scrolling the page or keeping the focus on trigger if input-like.\r\n */\r\n autoFocusOnHide?: false | (() => boolean)\r\n}\r\n\r\nexport function Popover({\r\n state,\r\n modal = true,\r\n rounding = 'regular',\r\n theme = 'default',\r\n gutter = 4,\r\n hideOnEsc = true,\r\n backdrop,\r\n unmountOnHide = true,\r\n onClose,\r\n 'aria-label': ariaLabel,\r\n hideOnInteractOutside,\r\n autoFocusOnShow,\r\n autoFocusOnHide,\r\n children,\r\n ...props\r\n}: PopoverProps) {\r\n const context = Ariakit.usePopoverContext()\r\n const popoverState = state ?? context\r\n const { placement, zIndex, updatePosition } = usePopoverPlacement(popoverState)\r\n const isPopoverOpen = popoverState?.useState('open')\r\n const [isFullyOpen, setIsFullyOpen] = React.useState(isPopoverOpen)\r\n\r\n // Check if the trigger element is input-like so we can keep it focused\r\n const triggerElement = React.useMemo(\r\n () => (isPopoverOpen ? popoverState!.getState().disclosureElement : null),\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [isPopoverOpen]\r\n )\r\n const isTriggerInput = triggerElement instanceof HTMLInputElement || triggerElement instanceof HTMLTextAreaElement\r\n\r\n return (\r\n [triggerElement!] : undefined}\r\n hideOnInteractOutside={hideOnInteractOutside ?? (!modal && !backdrop)}\r\n // Update zIndex when popover position changes\r\n updatePosition={updatePosition}\r\n // E2E tests don’t wait for transitions to complete and it could lead to bugs with other popover components (ResizeObserver loop exceeded)\r\n // or visual diffs due a screenshot being captured while the popover still in transition\r\n // If you encounter this problem, just do `cy.get('[data-fully-open=true]').should('exist')` before continuing to wait for the popover\r\n data-fully-open={isFullyOpen}\r\n aria-label={ariaLabel}\r\n onTransitionEnd={(ev) => {\r\n if (ev.target === ev.currentTarget && isPopoverOpen) setIsFullyOpen(true)\r\n }}\r\n onClose={(ev) => {\r\n onClose?.(ev)\r\n // prevented means the dialog didn’t close\r\n if (!ev.defaultPrevented) setIsFullyOpen(false)\r\n }}\r\n // Custom event prevents scrolling issues\r\n // See website PR #1968\r\n backdrop={\r\n backdrop ?? (\r\n {\r\n ev.preventDefault()\r\n popoverState?.hide()\r\n }}\r\n />\r\n )\r\n }\r\n className={classnames(\r\n props.className,\r\n zIndex,\r\n PopoverRounding[rounding],\r\n PopoverTheme[theme],\r\n 'custom-scrollbar absolute max-w-[--popover-available-width] overscroll-contain outline-none',\r\n // Animations\r\n 'opacity-0 transition duration-[250ms] data-[enter]:translate-y-0 data-[enter]:opacity-100',\r\n {\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-bottom))] motion-safe:-translate-y-1':\r\n placement?.startsWith('bottom'),\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-top))] motion-safe:translate-y-1':\r\n placement?.startsWith('top'),\r\n }\r\n )}\r\n >\r\n {children}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\n\r\ninterface PopoverProviderProps extends Omit {\r\n state?: Ariakit.PopoverProviderProps['store']\r\n}\r\n\r\nexport function PopoverProvider({ state, ...props }: PopoverProviderProps) {\r\n return \r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\n\r\nexport type PopoverStateReturn = ReturnType\r\n\r\n/**\r\n * Hook which provides state to dialogs\r\n */\r\nexport function usePopoverState({ placement = 'bottom-start', ...settings }: Ariakit.PopoverStoreProps = {}) {\r\n return Ariakit.usePopoverStore({ placement, ...settings })\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\ninterface PopoverTriggerProps extends Omit {\r\n // State is intentionally not marked as optional so you get error when you don’t provide it\r\n /**\r\n * Returned state from `usePopoverState`. Set `undefined` if you use a `PopoverProvider` wrapper\r\n */\r\n state: Ariakit.PopoverStore | undefined\r\n}\r\n\r\nexport const PopoverTrigger = React.forwardRef(\r\n ({ state, ...props }: PopoverTriggerProps, ref: React.ForwardedRef) => (\r\n \r\n )\r\n)\r\n\r\nexport const PopoverAnchor = Ariakit.PopoverAnchor\r\n","import * as React from 'react'\r\nimport { useNavigate } from 'react-router-dom'\r\n\r\nimport { SelectItem, SelectItemGroup } from './types'\r\nimport { flattenItems, isSelectItemGroup } from './utils'\r\n\r\ninterface NativeSelectProps extends Omit, 'onChange'> {\r\n items: ItemType[]\r\n onChange?: (item: ItemType) => void\r\n}\r\n\r\nexport function NativeSelect | SelectItem>({\r\n items,\r\n onChange,\r\n placeholder = 'Select value',\r\n ...props\r\n}: NativeSelectProps) {\r\n const showPlaceholder = props.value === -1\r\n const handleNativeSelectChange = React.useCallback(\r\n (e: React.ChangeEvent) => {\r\n const itemIndex = e.target.selectedIndex + (showPlaceholder ? -1 : 0)\r\n const selectedItem = flattenItems(items)[itemIndex] as SelectItem\r\n\r\n if (!selectedItem) return\r\n\r\n onChange?.(selectedItem as any)\r\n\r\n if (!selectedItem.href || !selectedItem.reloadDocument) {\r\n return\r\n }\r\n\r\n if (typeof selectedItem.href === 'string') {\r\n window.location.href = selectedItem.href\r\n return\r\n }\r\n\r\n const newUrl = new URL(selectedItem.href.pathname!, window.location.href)\r\n newUrl.search = selectedItem.href.search ?? ''\r\n newUrl.hash = selectedItem.href.hash ?? ''\r\n\r\n window.location.href = newUrl.toString()\r\n },\r\n [items, onChange, showPlaceholder]\r\n )\r\n\r\n return (\r\n \r\n {showPlaceholder && }\r\n {items.map((item, itemIndex) => {\r\n if (isSelectItemGroup(item)) {\r\n return (\r\n \r\n {item.items.map((option, optionIndex) => (\r\n \r\n ))}\r\n \r\n )\r\n }\r\n\r\n return (\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n\r\nexport function NativeSelectInRouterContext | SelectItem>(\r\n props: NativeSelectProps\r\n) {\r\n const navigate = useNavigate()\r\n\r\n const onChangeWithNavigate = React.useCallback(\r\n (item: SelectItem) => {\r\n props.onChange?.(item as any)\r\n\r\n if (item.href) navigate(item.href)\r\n },\r\n // We don’t need the whole props here, just onChange and items\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [navigate, props.onChange, props.items]\r\n )\r\n\r\n return \r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\nimport { OptionButton, OptionButtonProps } from '../OptionButton'\r\nimport { BUTTON_DEFAULT_ELEMENT, ButtonComponentProps } from '../button'\r\n\r\ninterface SelectOptionProps extends OptionButtonProps {\r\n value: ValueType\r\n}\r\n\r\nexport const SelectOption = React.forwardRef(function SelectOption<\r\n ValueType,\r\n TagType extends React.ElementType = typeof BUTTON_DEFAULT_ELEMENT,\r\n>(\r\n { as, ...props }: Omit, 'value' | 'theme'> & SelectOptionProps,\r\n ref: React.ForwardedRef\r\n) {\r\n const context = Ariakit.useSelectContext()!\r\n const isComboBox = !!context.combobox\r\n const isMultiSelect = Array.isArray(context.getState().value)\r\n\r\n return (\r\n } />\r\n ) : (\r\n \r\n )\r\n }\r\n />\r\n )\r\n})\r\n","import { SelectRenderer, SelectRendererItemProps } from '@ariakit/react-core/select/select-renderer'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\nimport { useInRouterContext } from 'react-router-dom'\r\n\r\nimport { MenuGroup } from '../MenuGroup'\r\nimport { ButtonRoundingType } from '../button'\r\nimport { SelectOption } from './SelectOption'\r\nimport { SelectItem, SelectItemGroup } from './types'\r\nimport { filterSelectOptions, getSelectItemProps, isSelectItem } from './utils'\r\n\r\ninterface SelectItemsVirtualizedProps {\r\n hasGroups: boolean\r\n itemRenderer: (item: SelectItem, providedProps?: any) => React.ReactNode\r\n}\r\n\r\nfunction SelectItemsVirtualized(props: SelectItemsVirtualizedProps) {\r\n return (\r\n \r\n {({ value: groupOritem, index, label, ...restProps }: any) => {\r\n if (isSelectItem(groupOritem)) {\r\n return props.itemRenderer(groupOritem, { key: index, ...restProps })\r\n }\r\n\r\n return (\r\n (\r\n \r\n {rendererProps.children}\r\n \r\n )}\r\n >\r\n {({ value, index, ...restItem }: SelectRendererItemProps<{ value: SelectItem }>) =>\r\n props.itemRenderer(value, { key: index, ...restItem })\r\n }\r\n \r\n )\r\n }}\r\n \r\n )\r\n}\r\n\r\ninterface SelectItemsProps {\r\n searchValue: string\r\n items?: ItemType[]\r\n rounding?: ButtonRoundingType\r\n parentTestId?: string\r\n}\r\n\r\nexport function SelectItems | SelectItemGroup>({\r\n items,\r\n rounding,\r\n searchValue,\r\n parentTestId,\r\n virtualized,\r\n}: SelectItemsProps & { virtualized?: boolean }) {\r\n const isInRouterContext = useInRouterContext()\r\n const filteredItems = React.useMemo(() => filterSelectOptions(items, searchValue), [items, searchValue])\r\n\r\n const getItem = React.useCallback(\r\n (innerItem: SelectItem, providedProps?: any) => (\r\n \r\n {innerItem.label}\r\n \r\n ),\r\n [isInRouterContext, parentTestId, rounding, virtualized]\r\n )\r\n\r\n if (!filteredItems.length) {\r\n return
Nothing to select
\r\n }\r\n\r\n if (virtualized) {\r\n const hasGroups = isSelectItem(items?.[0]) === false\r\n return \r\n }\r\n\r\n return (\r\n <>\r\n {filteredItems.map((item, index) => {\r\n if (isSelectItem(item)) {\r\n return getItem(item, { key: index })\r\n }\r\n\r\n return (\r\n \r\n {item.items.map((item, itemIndex) => getItem(item, { key: itemIndex }))}\r\n \r\n )\r\n })}\r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { usePopoverPlacement } from '../../hooks/usePopoverPlacement'\r\nimport { blurWithoutScroll, focusWithoutScroll, preventDefault } from '../../util'\r\nimport { Input } from '../input'\r\n\r\nenum ListRounding {\r\n none = '',\r\n regular = 'rounded-lg',\r\n}\r\n\r\nenum ListTheme {\r\n none = '',\r\n default = 'border border-primary bg-primary',\r\n}\r\n\r\nexport interface SelectListProps {\r\n /**\r\n * Internal prop which enables input at the top of the popover list\r\n */\r\n isComboBox?: boolean\r\n\r\n /**\r\n * Set rounding for the popover list\r\n *\r\n * @default regular\r\n */\r\n rounding?: keyof typeof ListRounding\r\n\r\n /**\r\n * Popover theme\r\n */\r\n theme?: keyof typeof ListTheme\r\n\r\n /**\r\n * The amount of space between button and its popover\r\n *\r\n * @default 4\r\n */\r\n gutter?: number\r\n\r\n /**\r\n * Change how the items are laid out\r\n *\r\n * @default vertical\r\n */\r\n orientation?: 'vertical' | 'horizontal'\r\n\r\n /**\r\n * Custom popover class\r\n */\r\n className?: string\r\n\r\n /**\r\n * Internal prop used to display no results when automatic `item` filtering doesn’t return any items\r\n */\r\n hasItemChildren?: boolean\r\n\r\n /**\r\n * Do not render the items when the popover is not visible\r\n *\r\n * @default false\r\n */\r\n unmountOnHide?: boolean\r\n\r\n /**\r\n * Test id to use\r\n */\r\n parentTestId?: string\r\n}\r\n\r\nexport function SelectList({\r\n isComboBox,\r\n rounding = 'regular',\r\n theme = 'default',\r\n gutter = 4,\r\n orientation = 'vertical',\r\n className,\r\n unmountOnHide = false,\r\n hasItemChildren,\r\n parentTestId,\r\n children,\r\n}: React.PropsWithChildren) {\r\n const context = Ariakit.useSelectContext()!\r\n const { placement, zIndex, updatePosition } = usePopoverPlacement(context)\r\n const ListElement = React.useMemo(\r\n () => (isComboBox ? Ariakit.ComboboxList : (wrapperProps: any) =>
),\r\n [isComboBox]\r\n )\r\n const [isFullyOpen, setIsFullyOpen] = React.useState(false)\r\n const hasChildren = hasItemChildren || React.Children.count(children) > 0\r\n\r\n return (\r\n }\r\n // Update zIndex when popover position changes\r\n updatePosition={updatePosition}\r\n data-testid={parentTestId ? `${parentTestId}-list` : `select-list`}\r\n // E2E tests don’t wait for transitions to complete and it could lead to bugs with other popover components (ResizeObserver loop exceeded)\r\n // or visual diffs due a screenshot being captured while the popover still in transition\r\n // If you encounter this problem, just do `cy.get('[data-fully-open=true]').should('exist')` before continuing to wait for the popover\r\n data-fully-open={isFullyOpen}\r\n onTransitionEnd={(ev) => {\r\n if (ev.target === ev.currentTarget && context.getState().open) setIsFullyOpen(true)\r\n }}\r\n onClose={(ev) => {\r\n // prevented means the dialog didn’t close\r\n if (!ev.defaultPrevented) setIsFullyOpen(false)\r\n }}\r\n className={classNames(\r\n className,\r\n zIndex,\r\n ListRounding[rounding],\r\n ListTheme[theme],\r\n 'custom-scrollbar absolute flex flex-col overflow-hidden shadow-modal outline-none dark:shadow-modal-dark',\r\n // These are set by popper, we just need to make sure we don’t encroach on the safe insets\r\n 'min-w-[--popover-anchor-width] max-w-[--popover-available-width]',\r\n // Animations\r\n 'opacity-0 transition duration-[250ms] data-[enter]:translate-y-0 data-[enter]:opacity-100',\r\n {\r\n // When in combobox mode, the padding is smaller so we can render a gradient under the combobox input.\r\n // Change the custom scrollbar offset so the top of the first item fits the top of our scrollbar\r\n '[--scrollbar-offset-top:theme(spacing.1)]': isComboBox,\r\n '[--scrollbar-radius:0]': ListRounding[rounding] === ListRounding.none,\r\n // Direction based styles\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-bottom))] motion-safe:-translate-y-1':\r\n placement?.startsWith('bottom'),\r\n 'max-h-[calc(var(--popover-available-height)-env(safe-area-inset-top))] motion-safe:translate-y-1':\r\n placement?.startsWith('top'),\r\n }\r\n )}\r\n >\r\n {isComboBox && (\r\n
\r\n
\r\n \r\n }\r\n />\r\n
\r\n
\r\n
\r\n )}\r\n \r\n {hasChildren ? children :
Nothing to select
}\r\n \r\n \r\n )\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\nimport { notifyOnVisibilityChange } from '../../../app/shared/documentVisibility'\r\nimport { Tooltip, TooltipTrigger, useTooltipState } from '../tooltip'\r\n\r\nexport function SelectTooltip({ content, children }: { content: React.ReactNode; children: JSX.Element }) {\r\n const tooltipState = useTooltipState({ placement: 'bottom', showTimeout: 300 })\r\n const context = Ariakit.useSelectContext()\r\n const isSelectOpen = context?.useState('open')\r\n const hasShownTooltip = React.useRef(false)\r\n\r\n React.useEffect(() => {\r\n if (isSelectOpen) hasShownTooltip.current = true\r\n }, [isSelectOpen])\r\n\r\n /**\r\n * Ignore focus re-trigger (do not show tooltip) when page visibility/focus state changes\r\n * - some browsers re-trigger focus on `activeElement` when document becomes visible\r\n */\r\n React.useEffect(() => {\r\n const subscription = notifyOnVisibilityChange((visible) => {\r\n if (!visible) tooltipState?.hide()\r\n })\r\n return () => {\r\n subscription.unsubscribe()\r\n }\r\n // Changing this to `tooltip` dependency will run this effect on every render\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n }, [])\r\n\r\n return (\r\n <>\r\n {\r\n // Do not open again unless user focuses the button again (or presses another ESC)\r\n if (hasShownTooltip.current) ev.preventDefault()\r\n hasShownTooltip.current = false\r\n }}\r\n />\r\n {content}\r\n \r\n )\r\n}\r\n\r\nexport function SelectTooltipWrapper({ content, children }: { content?: React.ReactNode; children: JSX.Element }) {\r\n if (!content) return null\r\n\r\n return {children}\r\n}\r\n","import * as Ariakit from '@ariakit/react'\r\nimport * as React from 'react'\r\n\r\nimport { PopoverPlacement } from '../popover'\r\nimport { SelectButtonProps } from './SelectButton'\r\nimport { SelectItems } from './SelectItems'\r\nimport { SelectList, SelectListProps } from './SelectList'\r\nimport { SelectTooltipWrapper } from './SelectTooltipWrapper'\r\nimport { SelectHandle, SelectItem, SelectItemGroup } from './types'\r\nimport { isSelectItem } from './utils'\r\n\r\ntype OnChangeItemParam =\r\n ItemType extends SelectItemGroup\r\n ? ValueType extends SelectItem\r\n ? ValueType\r\n : SelectItem\r\n : ItemType\r\n\r\nexport interface DesktopSelectProps\r\n extends Omit<\r\n SelectButtonProps,\r\n // Fix clash with `button` element html props\r\n 'value' | 'defaultValue' | 'onChange' | 'label' | 'name' | 'valueOverride'\r\n >,\r\n Pick {\r\n /**\r\n * Name of the select which coudl be used to distinguish onChange events.\r\n * Passed as 2nd argument to `onChange`\r\n */\r\n name?: Name\r\n\r\n /**\r\n * Set value for the select\r\n */\r\n value?: ValueType\r\n\r\n /**\r\n * Set default value for an uncontrolled select\r\n */\r\n defaultValue?: ValueType\r\n\r\n /**\r\n * Label to display above the select\r\n */\r\n label?: React.ReactNode\r\n\r\n /**\r\n * Callback when item changes. Called for both controlled and uncontrolled selects\r\n */\r\n onChange?: (\r\n item: ValueType extends Array\r\n ? OnChangeItemParam[]\r\n : OnChangeItemParam,\r\n name: Name\r\n ) => void\r\n\r\n /**\r\n * Options to select from. When defined, the options are constructed automatically\r\n * so you don’t have to pass children to the select.\r\n *\r\n * When `nativeSelect` is set to \"mobile\", children take precedence on desktop\r\n */\r\n items?: ItemType[]\r\n\r\n /**\r\n * Enable virtualization of select items to improve performance of long lists\r\n *\r\n * @default items.length > 50\r\n */\r\n virtualized?: boolean\r\n\r\n /**\r\n * Custom button renderer for the select\r\n */\r\n trigger?: JSX.Element\r\n\r\n /**\r\n * Text for the button (usually the selected value). Falls back to placeholder if not set\r\n */\r\n triggerContent?: React.ReactNode\r\n\r\n /**\r\n * Show tooltip on the select\r\n */\r\n tooltip?: React.ReactNode\r\n\r\n /**\r\n * Popover placement\r\n *\r\n * @default \"bottom-start\"\r\n */\r\n placement?: PopoverPlacement\r\n\r\n /**\r\n * Change the direction of the items placement in popover\r\n *\r\n * @default vertical\r\n */\r\n orientation?: 'vertical' | 'horizontal'\r\n\r\n /**\r\n * Set whether or not the Select is interactive to save resources. If not interactive,\r\n * the select only renders a placeholder button\r\n *\r\n * @default true\r\n */\r\n isInteractive?: boolean\r\n\r\n /**\r\n * Callback when the select opens or closes\r\n */\r\n onInteractionChange?: (open: boolean) => void\r\n\r\n /**\r\n * ### Only applicable for desktop selects without `children`, when passing `items`.\r\n * ### If you want to pass `children`, use the `onSearch` prop instead.\r\n *\r\n * Specifies whether or not to show a search input inside of the popover. Number\r\n * specifies the >= number of items after which search will be visible.\r\n * Search is made for both value and label props\r\n *\r\n * @default 10\r\n */\r\n comboBox?: boolean | number\r\n\r\n /**\r\n * ### Only applicable for desktop selects with `children`.\r\n * ### Use `comboBox` if you have `items` prop\r\n * When defined, the select is considered being a combobox and will display\r\n * input for filtering items. The filtering is up to the user.\r\n */\r\n onSearch?: (value: string) => void\r\n\r\n /**\r\n * When combined with `items` the children will automatically have testid assigned.\r\n * Otherwise just passed to the trigger button\r\n */\r\n 'data-testid'?: string\r\n\r\n listProps?: SelectListProps\r\n}\r\n\r\nfunction getCollectionItem(item: SelectItem, index: number) {\r\n return {\r\n id: `item-${index}-${String(item.value).replace(/\\W/g, '')}`,\r\n label: item.label,\r\n value: item,\r\n children: item.label,\r\n }\r\n}\r\n\r\nfunction DesktopSelectComponent<\r\n ValueType,\r\n ItemType extends SelectItem | SelectItemGroup,\r\n Name = never,\r\n>(\r\n {\r\n name,\r\n label,\r\n value,\r\n defaultValue,\r\n onChange,\r\n items,\r\n virtualized = (items?.length ?? 0) > 50,\r\n trigger,\r\n tooltip,\r\n onInteractionChange,\r\n comboBox,\r\n onSearch,\r\n children,\r\n gutter,\r\n placement = 'bottom-start',\r\n orientation,\r\n listProps,\r\n ...props\r\n }: React.PropsWithChildren>,\r\n ref: React.ForwardedRef\r\n) {\r\n // Used when `items` are passed to construct a desktop select with comboBox\r\n const [internalSearch, setInternalSearch] = React.useState('')\r\n\r\n // Setup combobox if enabled\r\n const isComboBox =\r\n !!onSearch || comboBox === true || (typeof comboBox === 'number' && !!items && items.length > comboBox)\r\n const SelectWrapper = isComboBox ? Ariakit.ComboboxProvider : React.Fragment\r\n const wrapperProps = React.useMemo(\r\n () =>\r\n isComboBox ? { resetValueOnHide: true, includesBaseElement: false, setValue: onSearch ?? setInternalSearch } : {},\r\n [isComboBox, onSearch]\r\n )\r\n\r\n // Handle tooltip prop\r\n const ButtonWrapper = tooltip ? SelectTooltipWrapper : React.Fragment\r\n const buttonWrapperProps = React.useMemo(() => (tooltip ? { content: tooltip } : {}), [tooltip])\r\n\r\n if (isComboBox && !!children && !onSearch) {\r\n console.warn(\r\n 'ComboBoxes with children options require `onSearch` prop, otherwise searching will not work. \\n Either provide `onSearch` or disable this behavior by passing `comboBox={false}`'\r\n )\r\n }\r\n\r\n const listItems = React.useMemo(\r\n () =>\r\n items?.map((item, index) =>\r\n isSelectItem(item) ? getCollectionItem(item, index) : { ...item, items: item.items.map(getCollectionItem) }\r\n ) as ItemType[],\r\n [items]\r\n )\r\n\r\n // @ts-expect-error - The types are wrong here, the select allows any values, not just strings or ints\r\n const selectStore = Ariakit.useSelectStore({\r\n // Loop to the first item after pressing arrow down on last item\r\n focusLoop: true,\r\n virtualFocus: true,\r\n value: value,\r\n defaultValue: defaultValue ?? '',\r\n setValue: (item) => setTimeout(() => onChange?.(item as any, name!), 50),\r\n setOpen: onInteractionChange,\r\n placement: placement,\r\n orientation: orientation,\r\n defaultItems: listItems,\r\n })\r\n\r\n React.useImperativeHandle(\r\n ref,\r\n () => ({\r\n open: () => selectStore.show(),\r\n close: () => selectStore.hide(),\r\n }),\r\n // Optimize re-runs\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [selectStore.show, selectStore.hide]\r\n )\r\n\r\n return (\r\n \r\n {/* @ts-expect-error - The types are wrong here, the select allows any values, not just strings or ints */}\r\n store={selectStore}>\r\n {label && {label}}\r\n\r\n \r\n \r\n \r\n\r\n \r\n {/* Either construct options from children or provided items prop */}\r\n {children ?? (\r\n \r\n )}\r\n \r\n \r\n \r\n )\r\n}\r\n\r\nexport const DesktopSelect = React.forwardRef(DesktopSelectComponent)\r\n","import * as Ariakit from '@ariakit/react'\r\nimport classNames from 'classnames'\r\nimport * as React from 'react'\r\n\r\nimport { Button, ButtonHTMLProps, ButtonProps, ButtonSize } from '../button'\r\nimport { Delayed } from '../delayed'\r\nimport { Icon, IconNameType, isValidIconName } from '../icon'\r\nimport { Spinner } from '../spinner'\r\nimport { SelectItem } from './types'\r\nimport { isSelectItem } from './utils'\r\n\r\ntype ValueType = SelectItem | string\r\n\r\nconst DEFAULT_RIGHT_ICON = 'caretDown'\r\n\r\nexport interface SelectButtonProps extends Omit, Omit {\r\n /**\r\n * Show a spinner in place of the button caret. The spinner is wrapped in Delayed\r\n * and uses the default timeout\r\n */\r\n isLoading?: boolean\r\n\r\n /**\r\n * Placeholder when no value is selected\r\n */\r\n placeholder?: string\r\n\r\n /**\r\n * Override for the select value from context. Used to provide value for native\r\n * select trigger\r\n */\r\n valueOverride?: ValueType\r\n\r\n rightContent?: boolean | IconNameType | JSX.Element\r\n}\r\n\r\nexport const SelectButton = React.forwardRef>(\r\n function SelectButton(\r\n {\r\n isLoading,\r\n placeholder = 'Select value',\r\n children,\r\n valueOverride,\r\n theme = 'outline',\r\n rightContent = DEFAULT_RIGHT_ICON,\r\n ...props\r\n },\r\n ref\r\n ) {\r\n const context = Ariakit.useSelectContext()\r\n const contextValue = context?.useState('value') as ValueType\r\n const isOpen = context?.useState('open')\r\n const selectedValue = valueOverride ?? contextValue\r\n\r\n let buttonText = placeholder\r\n if (Array.isArray(selectedValue)) {\r\n if (selectedValue.length === 0) buttonText = placeholder\r\n else buttonText = `${selectedValue.length} item${selectedValue.length === 1 ? '' : 's'} selected`\r\n } else if (isSelectItem(selectedValue)) buttonText = selectedValue.label ?? selectedValue.value\r\n else if (typeof selectedValue === 'string' && selectedValue.length) buttonText = selectedValue\r\n else if (selectedValue) buttonText = String(selectedValue)\r\n\r\n const rightIcon =\r\n isValidIconName(rightContent) || rightContent === true ? (\r\n \r\n ) : React.isValidElement(rightContent) ? (\r\n rightContent\r\n ) : undefined\r\n\r\n return (\r\n \r\n \r\n \r\n ) : (\r\n rightIcon\r\n )\r\n }\r\n >\r\n {children ?? buttonText}\r\n \r\n )\r\n }\r\n)\r\n","import * as React from 'react'\r\nimport { useInRouterContext } from 'react-router-dom'\r\n\r\nimport { isMobile } from '../../../app/shared/isMobile'\r\nimport { DesktopSelect, DesktopSelectProps } from './DesktopSelect'\r\nimport { NativeSelect, NativeSelectInRouterContext } from './NativeSelect'\r\nimport { SelectButton } from './SelectButton'\r\nimport { SelectHandle } from './types'\r\nimport { SelectItem } from './types'\r\nimport { findSelectedIndex, findSelectedValue } from './utils'\r\n\r\nconst isMobileDevice = isMobile()\r\n\r\nexport interface SelectProps extends DesktopSelectProps {\r\n /**\r\n * Whether or not to show a native select when clicking the button.\r\n * When rendering native select, you must provide `items`, `value` and `onChange`\r\n *\r\n * @default false\r\n */\r\n nativeSelect?: boolean | 'mobile'\r\n}\r\n\r\nfunction SelectComponent(\r\n {\r\n name,\r\n label,\r\n value: providedValue,\r\n defaultValue: providedDefaultValue,\r\n onChange,\r\n items,\r\n trigger,\r\n gutter,\r\n orientation,\r\n triggerContent,\r\n isInteractive = true,\r\n onInteractionChange,\r\n nativeSelect = false,\r\n comboBox = 10,\r\n onSearch,\r\n 'data-testid': dataTestid,\r\n listProps,\r\n virtualized,\r\n ...props\r\n }: React.PropsWithChildren>,\r\n ref: React.ForwardedRef\r\n) {\r\n // Used by native select to handle navigation for link items\r\n const isInRouterContext = useInRouterContext()\r\n // Let users either provide the selected item or its value. Items can also be grouped so we need to find the correct value\r\n const value = findSelectedValue(items, providedValue) ?? providedValue\r\n const defaultValue = findSelectedValue(items, providedDefaultValue) ?? providedDefaultValue\r\n\r\n // Extracted trigger to a variable because it is used in every branch\r\n const selectTrigger = trigger ?? (\r\n ) : undefined\r\n }\r\n data-testid={dataTestid}\r\n >\r\n {triggerContent}\r\n \r\n )\r\n\r\n // Save some resources by rendering the trigger only\r\n if (!isInteractive) {\r\n return selectTrigger\r\n }\r\n\r\n const renderNativeSelect = nativeSelect === true || (nativeSelect === 'mobile' && isMobileDevice)\r\n if (renderNativeSelect) {\r\n const NativeSelectComponent = isInRouterContext ? NativeSelectInRouterContext : NativeSelect\r\n const selectedIndex = findSelectedIndex(items, providedValue ?? providedDefaultValue)\r\n\r\n return (\r\n
\r\n {selectTrigger}\r\n
\r\n )\r\n }\r\n\r\n return (\r\n \r\n )\r\n}\r\n\r\nexport const Select = React.forwardRef(SelectComponent) as (\r\n props: React.PropsWithChildren> & {\r\n ref?: React.ForwardedRef\r\n }\r\n) => ReturnType\r\n","import { Link } from 'react-router-dom'\r\n\r\nimport { SelectItem, SelectItemGroup } from './types'\r\n\r\nexport function getSelectItemProps(item: SelectItem, inRouterContext?: boolean) {\r\n if (item.href) {\r\n if (inRouterContext) return { as: Link, to: item.href, reloadDocument: item.reloadDocument }\r\n else return { as: 'a', href: item.href }\r\n }\r\n\r\n return {}\r\n}\r\n\r\nexport function isSelectItem(item: unknown): item is SelectItem {\r\n return !!(item?.hasOwnProperty('label') && item?.hasOwnProperty('value')) && !item?.hasOwnProperty('items')\r\n}\r\n\r\nexport function isSelectItemGroup(item: unknown): item is SelectItemGroup {\r\n return !!item?.hasOwnProperty('items')\r\n}\r\n\r\nfunction matchesSearchTerm(item: SelectItem, searchTerm: string) {\r\n const lowerSearch = searchTerm.toLowerCase()\r\n\r\n return (\r\n (typeof item.value === 'string' && item.value.toLowerCase().includes(lowerSearch)) ||\r\n item.label.toLowerCase().includes(lowerSearch)\r\n )\r\n}\r\n\r\nfunction isSameItem(obj1: unknown, obj2?: unknown) {\r\n if (isSelectItem(obj1) && isSelectItem(obj2)) return obj1.value === obj2.value\r\n else if (isSelectItem(obj1)) return obj1.value === obj2\r\n return obj1 === obj2\r\n}\r\n\r\n/**\r\n * Used in combobox to find matching items\r\n */\r\nexport function filterSelectOptions | SelectItemGroup>(\r\n items: ItemType[] | undefined,\r\n searchTerm: string\r\n) {\r\n const finalResults: ItemType[] = []\r\n\r\n items?.forEach((item) => {\r\n if (isSelectItemGroup(item)) {\r\n const filtered = item.items.filter((option) => matchesSearchTerm(option, searchTerm))\r\n if (filtered.length) finalResults.push({ ...item, items: filtered })\r\n } else if (matchesSearchTerm(item, searchTerm)) {\r\n finalResults.push(item)\r\n }\r\n })\r\n\r\n return finalResults\r\n}\r\n\r\n/**\r\n * Used in select to allow users to pass any kind of valid value\r\n */\r\nexport function findSelectedValue(\r\n items: ItemType[] = [],\r\n value?: ValueType | SelectItem\r\n) {\r\n for (const item of items) {\r\n if (isSelectItemGroup(item)) {\r\n const foundItem = item.items.find((option) => isSameItem(option, value)) as SelectItem\r\n if (foundItem) return foundItem\r\n } else if (isSameItem(item, value)) {\r\n return item as SelectItem\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Used for native selects to match against user provided value\r\n */\r\nexport function findSelectedIndex(\r\n items: ItemType[] = [],\r\n value?: ValueType | SelectItem\r\n) {\r\n for (let index = 0; index < items.length; index++) {\r\n const item = items[index]\r\n\r\n if (isSelectItemGroup(item)) {\r\n const itemIndex = item.items.findIndex((option) => isSameItem(option, value))\r\n if (itemIndex > -1) return `${index}${itemIndex}`\r\n } else if (isSameItem(item, value)) {\r\n return index\r\n }\r\n }\r\n\r\n return -1\r\n}\r\n\r\nexport function flattenItems(items: ItemType[]) {\r\n return items.flatMap((itemOrGroup) =>\r\n isSelectItemGroup(itemOrGroup) ? (itemOrGroup.items as ItemType[]) : itemOrGroup\r\n )\r\n}\r\n","import * as React from 'react'\r\nimport { Link, To } from 'react-router-dom'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { MenuGroup } from '../MenuGroup'\r\nimport { ButtonRoundingType, ButtonSizeType } from '../button'\r\nimport { Icon } from '../icon'\r\nimport { Select, SelectOption } from '../select'\r\nimport { SelectItem } from '../select/types'\r\n\r\nexport interface DateRangeBaseOption extends SelectItem {\r\n timeframe?: TIMEFRAME\r\n href?: To\r\n withReload?: boolean\r\n}\r\n\r\ninterface Props {\r\n chartIndex: number\r\n dateRangeGroups: Array<{ label?: string; dateRanges: DateRange[] }>\r\n selectedDateRange: string | null\r\n onDateRangeSelect: (value: DateRange) => void\r\n onCustomDateRangeClick?: () => void\r\n rounding?: ButtonRoundingType\r\n size?: ButtonSizeType\r\n}\r\n\r\nconst DATERANGE_TOOLTIP = 'Range'\r\n\r\nexport function DateRangeSelect({\r\n size,\r\n chartIndex,\r\n dateRangeGroups,\r\n selectedDateRange,\r\n onDateRangeSelect,\r\n onCustomDateRangeClick,\r\n rounding,\r\n}: Props) {\r\n const flatDateRanges = React.useMemo(() => dateRangeGroups.flatMap(({ dateRanges }) => dateRanges), [dateRangeGroups])\r\n\r\n return (\r\n {\r\n onDateRangeSelect(flatDateRanges.find((item) => item.value === value)!)\r\n }}\r\n rounding={rounding}\r\n appearance=\"square\"\r\n theme=\"chip\"\r\n size={size}\r\n triggerContent={}\r\n rightContent={false}\r\n active={selectedDateRange ? true : undefined}\r\n data-testid={`chart-${chartIndex}-date-range-select`}\r\n >\r\n {dateRangeGroups.flatMap(({ label, dateRanges }, index) => (\r\n \r\n {dateRanges.map(({ href, value, label, withReload, timeframe }) => {\r\n let linkProps = {}\r\n if (href) {\r\n linkProps = {\r\n as: Link,\r\n to: href,\r\n reloadDocument: withReload ?? !FinvizSettings.hasUserPremium,\r\n }\r\n }\r\n return (\r\n {\r\n if (!timeframe) onCustomDateRangeClick?.()\r\n }}\r\n >\r\n {label}\r\n \r\n )\r\n })}\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import classNames from 'classnames'\r\nimport * as React from 'react'\r\nimport { Link, To } from 'react-router-dom'\r\n\r\nimport { MenuGroup } from '../MenuGroup'\r\nimport { Button, ButtonProps, ButtonRoundingType, ButtonSizeType } from '../button'\r\nimport { Icon } from '../icon'\r\nimport { LabelWithDelayedSpinner } from '../label-with-delayed-spinner'\r\nimport { SelectItem } from '../select'\r\nimport { Select, SelectOption } from '../select'\r\n\r\nexport type TimeframeBaseOption = SelectItem & {\r\n labelShort?: string\r\n labelPageTitle?: string\r\n href?: To\r\n withReload?: boolean\r\n}\r\n\r\ninterface Props {\r\n chartIndex: number\r\n isCompactView: boolean\r\n isCompactOnly: boolean\r\n timeFrameGroups: Array<{ label: string; timeframes: TimeFrame[] }>\r\n selectedTimeframe: string\r\n onTimeframeSelect: (value: TimeFrame) => void\r\n favoriteTimeframes: string[]\r\n onFavoriteTimeframeToggle: (value: TimeFrame) => void\r\n rounding?: ButtonRoundingType\r\n size?: ButtonSizeType\r\n isLoading?: boolean\r\n isFavoritesEnabled: boolean\r\n theme?: ButtonProps['theme']\r\n}\r\n\r\nconst TIMEFRAME_TOOLTIP = 'Interval'\r\n\r\nexport function TimeframeSelect({\r\n size,\r\n chartIndex,\r\n timeFrameGroups,\r\n selectedTimeframe,\r\n favoriteTimeframes,\r\n isLoading = false,\r\n isCompactView,\r\n isCompactOnly,\r\n onTimeframeSelect,\r\n onFavoriteTimeframeToggle,\r\n rounding,\r\n isFavoritesEnabled,\r\n theme = 'chip',\r\n}: Props) {\r\n const flatTimeframes = React.useMemo(() => timeFrameGroups.flatMap(({ timeframes }) => timeframes), [timeFrameGroups])\r\n\r\n const getSelectedTimeframeLabel = React.useCallback(() => {\r\n if (isCompactView) {\r\n const selectedTimeframeItem = flatTimeframes.find(({ value }) => value === selectedTimeframe)\r\n return selectedTimeframeItem?.labelShort ?? selectedTimeframeItem?.label\r\n }\r\n return ''\r\n }, [flatTimeframes, isCompactView, selectedTimeframe])\r\n\r\n return (\r\n item.value === selectedTimeframe)}\r\n leftContent={\r\n
\r\n } isLoading={isLoading && isCompactView} />\r\n
\r\n }\r\n onChange={(item) => onTimeframeSelect(item as TimeFrame)}\r\n data-testid={`chart-${chartIndex}-timeframe-select`}\r\n >\r\n {timeFrameGroups.flatMap(({ timeframes }, groupIndex) => (\r\n \r\n {timeframes.map((item) => {\r\n const isIconButtonActive = favoriteTimeframes.includes(item.value)\r\n let linkProps = {}\r\n if (item.href) {\r\n linkProps = {\r\n as: Link,\r\n to: item.href,\r\n reloadDocument: !!item.withReload,\r\n }\r\n }\r\n return (\r\n ) => {\r\n ev.stopPropagation()\r\n ev.preventDefault()\r\n onFavoriteTimeframeToggle(item)\r\n }}\r\n className={classNames('group -mr-2', {\r\n 'text-gray-300': !isIconButtonActive,\r\n 'text-yellow-200': isIconButtonActive,\r\n })}\r\n >\r\n \r\n \r\n \r\n ) : undefined\r\n }\r\n >\r\n {item.label}\r\n \r\n )\r\n })}\r\n \r\n ))}\r\n \r\n )\r\n}\r\n","import classnames from 'classnames'\r\nimport * as React from 'react'\r\nimport { Link } from 'react-router-dom'\r\n\r\nimport { useElementMeasure } from '../../hooks/use-element-measure'\r\nimport { Button, ButtonPadding, ButtonProps, ButtonRoundingType, ButtonSize, ButtonSizeType } from '../button'\r\nimport { LabelWithDelayedSpinner } from '../label-with-delayed-spinner'\r\nimport { DateRangeBaseOption, DateRangeSelect } from './daterange-select'\r\nimport { TimeframeBaseOption, TimeframeSelect } from './timeframe-select'\r\n\r\ninterface Props {\r\n isPremium?: boolean\r\n chartIndex?: number\r\n compactViewMaxBreakpointPx?: number\r\n timeFrameGroups: Array<{ label: string; timeframes: TimeFrame[] }>\r\n dateRangeGroups: Array<{ label?: string; dateRanges: DateRange[] }>\r\n selectedTimeframe: string\r\n selectedDateRange: string | null\r\n onTimeframeSelect: (value: TimeFrame) => void\r\n onDateRangeSelect: (value: DateRange) => void\r\n onCustomDateRangeClick?: () => void\r\n favoriteTimeframes: string[]\r\n onFavoriteTimeframeToggle: (value: TimeFrame) => void\r\n size?: ButtonSizeType\r\n loadingTimeframe?: string\r\n rounding?: ButtonRoundingType\r\n isDateRangeAvailable?: boolean\r\n containerElement?: HTMLElement\r\n className?: string\r\n isFavoritesEnabled?: boolean\r\n isScrollIntoViewEnabled?: boolean\r\n isTimeframeSelectEnabled?: boolean\r\n isCompactOnly?: boolean\r\n theme?: ButtonProps['theme']\r\n}\r\n\r\nfunction getTimeframeChipElementId({ timeframe, chartIndex }: { timeframe: string; chartIndex: number }) {\r\n return `${chartIndex}-${timeframe}`\r\n}\r\n\r\nfunction getButtonPadding(size: ButtonSize): keyof typeof ButtonPadding {\r\n switch (size) {\r\n case ButtonSize.xxsmall:\r\n case ButtonSize.xsmall:\r\n case ButtonSize.small:\r\n case ButtonSize.regular:\r\n return 'small'\r\n case ButtonSize.medium:\r\n return 'regular'\r\n case ButtonSize.large:\r\n case ButtonSize.xlarge:\r\n return 'medium'\r\n case ButtonSize.none:\r\n return 'none'\r\n }\r\n}\r\n\r\nexport function TimeframeBar({\r\n isPremium = FinvizSettings.hasUserPremium,\r\n chartIndex = 0,\r\n compactViewMaxBreakpointPx = 400,\r\n timeFrameGroups,\r\n dateRangeGroups,\r\n selectedTimeframe,\r\n selectedDateRange,\r\n favoriteTimeframes,\r\n loadingTimeframe,\r\n onTimeframeSelect,\r\n onDateRangeSelect,\r\n onCustomDateRangeClick,\r\n onFavoriteTimeframeToggle,\r\n size,\r\n rounding,\r\n isDateRangeAvailable = true,\r\n containerElement,\r\n className,\r\n isFavoritesEnabled = true,\r\n isScrollIntoViewEnabled = true,\r\n isTimeframeSelectEnabled,\r\n isCompactOnly = false,\r\n theme,\r\n}: Props) {\r\n const [scrollWrapperElement, setScrollWrapperElement] = React.useState(null)\r\n const [timeframeButtonsScrollLocation, setTimeframeButtonsScrollLocation] = React.useState({\r\n isOnLeftEdge: true,\r\n isOnRightEdge: true,\r\n })\r\n const { setElementRef, elementWidth } = useElementMeasure(containerElement)\r\n const flatTimeframes = React.useMemo(() => timeFrameGroups.flatMap(({ timeframes }) => timeframes), [timeFrameGroups])\r\n\r\n const timeframesInExpandedPanel = React.useMemo(\r\n () =>\r\n isFavoritesEnabled\r\n ? flatTimeframes.filter(({ value }) => value === selectedTimeframe || favoriteTimeframes.includes(value))\r\n : flatTimeframes,\r\n [flatTimeframes, selectedTimeframe, favoriteTimeframes, isFavoritesEnabled]\r\n )\r\n\r\n const isCompactView =\r\n isCompactOnly || elementWidth < compactViewMaxBreakpointPx || timeframesInExpandedPanel.length <= 1\r\n const checkTimeframeWrapperScrollPosition = React.useCallback(() => {\r\n if (scrollWrapperElement) {\r\n const isOnLeftEdge = scrollWrapperElement.scrollLeft === 0\r\n const isOnRightEdge =\r\n Math.ceil(scrollWrapperElement.offsetWidth + scrollWrapperElement.scrollLeft) >=\r\n scrollWrapperElement.scrollWidth\r\n\r\n if (\r\n timeframeButtonsScrollLocation.isOnLeftEdge !== isOnLeftEdge ||\r\n timeframeButtonsScrollLocation.isOnRightEdge !== isOnRightEdge\r\n ) {\r\n setTimeframeButtonsScrollLocation({ isOnLeftEdge, isOnRightEdge })\r\n }\r\n }\r\n }, [timeframeButtonsScrollLocation, scrollWrapperElement])\r\n\r\n React.useEffect(() => {\r\n checkTimeframeWrapperScrollPosition()\r\n }, [checkTimeframeWrapperScrollPosition, scrollWrapperElement, elementWidth])\r\n\r\n React.useEffect(() => {\r\n if (!isCompactView && isScrollIntoViewEnabled) {\r\n const timeframeElement = document.getElementById(\r\n getTimeframeChipElementId({ chartIndex, timeframe: selectedTimeframe })\r\n )\r\n\r\n if (timeframeElement && scrollWrapperElement) {\r\n const leftOffset =\r\n timeframeElement.offsetLeft + timeframeElement.clientWidth / 2 - scrollWrapperElement.clientWidth / 2\r\n\r\n scrollWrapperElement.scrollTo(Math.max(0, Math.min(leftOffset, scrollWrapperElement.scrollWidth)), 0)\r\n }\r\n }\r\n }, [isCompactView, chartIndex, selectedTimeframe, elementWidth, isScrollIntoViewEnabled, scrollWrapperElement])\r\n\r\n return (\r\n \r\n {(isTimeframeSelectEnabled ?? isFavoritesEnabled) && (\r\n
\r\n \r\n
\r\n )}\r\n {!isCompactView && (\r\n
\r\n \r\n {\r\n /*\r\n * Vertical scrolling doesn't scroll horizontally by default (it's possible when holding shift)\r\n * When using touchpad we may get values in both delatX and deltaY, so if someone's scrolling horizontally we don't want to do anything\r\n * but if they are scrolling vertically (deltaY > deltaX) we want to scroll horizontally the value they would nativally scroll in vertical direction\r\n * */\r\n const absDx = Math.abs(event.deltaX)\r\n const absDy = Math.abs(event.deltaY)\r\n if (absDy > absDx) {\r\n event.currentTarget.scrollLeft += event.deltaY\r\n }\r\n }}\r\n >\r\n {timeframesInExpandedPanel.map((timeframe) => {\r\n let linkProps = {}\r\n if (timeframe.href) {\r\n linkProps = {\r\n as: Link,\r\n to: timeframe.href,\r\n reloadDocument: timeframe.withReload ?? !isPremium,\r\n onClick: () => onTimeframeSelect(timeframe),\r\n }\r\n } else {\r\n linkProps = {\r\n onClick: (ev: React.MouseEvent) => {\r\n ev.preventDefault()\r\n onTimeframeSelect(timeframe)\r\n },\r\n }\r\n }\r\n return (\r\n \r\n \r\n \r\n )\r\n })}\r\n
\r\n \r\n
\r\n )}\r\n {isDateRangeAvailable && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n )\r\n}\r\n","import { type To } from 'react-router-dom'\r\n\r\nimport { decodeQueryString, encodeQueryString } from '../../../app/queryString'\r\nimport { SpecificChartFunctionality, TIMEFRAME } from '../../constants'\r\nimport { DateRangeType, Instrument } from '../../types'\r\nimport { CUSTOM_DATE_RANGE, CustomDateRangePrefixEnum, DATE_RANGE_PREFIX_DELMITER } from './custom-date-range-utils'\r\n\r\ninterface ITimeFrame {\r\n value: TIMEFRAME | 'intraday'\r\n label: string\r\n labelShort: string\r\n labelPageTitle?: string\r\n}\r\n\r\nexport interface ITimeframeGroup {\r\n label: string\r\n timeframes: ITimeFrame[]\r\n}\r\n\r\ninterface IDateRange {\r\n value: string\r\n label: string\r\n timeframe?: TIMEFRAME\r\n}\r\n\r\nexport interface IRangeGroup {\r\n label?: string\r\n dateRanges: IDateRange[]\r\n}\r\n\r\nexport const generateTimeframeGroups = (isPremium = true): ITimeframeGroup[] => {\r\n const premiumTimeframes: ITimeframeGroup[] = [\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.i1, label: '1 Minute', labelShort: '1M' },\r\n { value: TIMEFRAME.i2, label: '2 Minutes', labelShort: '2M' },\r\n { value: TIMEFRAME.i3, label: '3 Minutes', labelShort: '3M' },\r\n { value: TIMEFRAME.i5, label: '5 Minutes', labelShort: '5M' },\r\n { value: TIMEFRAME.i10, label: '10 Minutes', labelShort: '10M' },\r\n { value: TIMEFRAME.i15, label: '15 Minutes', labelShort: '15M' },\r\n { value: TIMEFRAME.i30, label: '30 Minutes', labelShort: '30M' },\r\n ],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.h, label: '1 Hour', labelShort: '1H', labelPageTitle: 'Hourly' },\r\n { value: TIMEFRAME.h2, label: '2 Hours', labelShort: '2H' },\r\n { value: TIMEFRAME.h4, label: '4 Hours', labelShort: '4H' },\r\n ],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.d, label: '1 Day', labelShort: 'D', labelPageTitle: 'Daily' },\r\n { value: TIMEFRAME.w, label: '1 Week', labelShort: 'W', labelPageTitle: 'Weekly' },\r\n { value: TIMEFRAME.m, label: '1 Month', labelShort: 'M', labelPageTitle: 'Monthly' },\r\n ],\r\n },\r\n ]\r\n\r\n const freeTimeframes = [\r\n {\r\n // intradayTimeframe is only for non premium users used as redirect to elite subscription\r\n label: '',\r\n timeframes: [{ value: 'intraday' as const, label: 'Intraday', labelShort: 'Intraday' }],\r\n },\r\n {\r\n label: '',\r\n timeframes: [\r\n { value: TIMEFRAME.d, label: '1 Day', labelShort: 'Daily' },\r\n { value: TIMEFRAME.w, label: '1 Week', labelShort: 'Weekly' },\r\n { value: TIMEFRAME.m, label: '1 Month', labelShort: 'Monthly' },\r\n ],\r\n },\r\n ]\r\n\r\n return isPremium ? premiumTimeframes : freeTimeframes\r\n}\r\n\r\nexport function getTimeframeGroups(isPremium: boolean) {\r\n return generateTimeframeGroups(isPremium)\r\n}\r\n\r\nexport const generateDateRangeGroups = ({\r\n isPremium,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n instrument: Instrument\r\n}): IRangeGroup[] => {\r\n const isStock = instrument === Instrument.Stock\r\n const rangeGroups: Array<{ label?: string; dateRanges: IDateRange[] }> = [\r\n {\r\n label: 'Days',\r\n dateRanges: [\r\n { value: DateRangeType.d1, label: '1 Day', timeframe: isStock ? TIMEFRAME.i1 : TIMEFRAME.i5 },\r\n { value: DateRangeType.d5, label: '5 Days', timeframe: isStock ? TIMEFRAME.i5 : TIMEFRAME.i30 },\r\n ],\r\n },\r\n {\r\n label: 'Months',\r\n dateRanges: [\r\n { value: DateRangeType.m1, label: '1 Month', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.m3, label: '3 Months', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.m6, label: '6 Months', timeframe: TIMEFRAME.d },\r\n ],\r\n },\r\n {\r\n label: 'Years',\r\n dateRanges: [\r\n { value: DateRangeType.ytd, label: 'Year to Date', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.y1, label: '1 Year', timeframe: TIMEFRAME.d },\r\n { value: DateRangeType.y2, label: '2 Years', timeframe: TIMEFRAME.w },\r\n { value: DateRangeType.y5, label: '5 Years', timeframe: isPremium ? TIMEFRAME.w : TIMEFRAME.m },\r\n { value: DateRangeType.max, label: 'Max', timeframe: TIMEFRAME.m },\r\n ],\r\n },\r\n ]\r\n\r\n return rangeGroups\r\n}\r\n\r\nexport function getDateRangeGroups({\r\n isPremium,\r\n customRange,\r\n isCustomAvailable = true,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n customRange?: string\r\n isCustomAvailable?: boolean\r\n instrument: Instrument\r\n}) {\r\n const rangeGroups = generateDateRangeGroups({ isPremium, instrument })\r\n\r\n if (isPremium && isCustomAvailable !== false) {\r\n const [dateRangePrefix] = customRange?.split(DATE_RANGE_PREFIX_DELMITER) ?? []\r\n rangeGroups.push({\r\n dateRanges: [\r\n {\r\n value:\r\n customRange && Object.values(CustomDateRangePrefixEnum).includes(dateRangePrefix)\r\n ? customRange\r\n : CUSTOM_DATE_RANGE,\r\n label: 'Custom',\r\n },\r\n ],\r\n })\r\n }\r\n\r\n return rangeGroups\r\n}\r\n\r\nexport function getDateRangeGroupsWithHref({\r\n isPremium,\r\n customRange,\r\n generatePath,\r\n withReload,\r\n isCustomAvailable,\r\n instrument,\r\n}: {\r\n isPremium: boolean\r\n isCustomAvailable?: boolean\r\n customRange?: string\r\n withReload?: boolean\r\n instrument: Instrument\r\n generatePath: (dateRange: IDateRange) => To\r\n}) {\r\n return getDateRangeGroups({\r\n isPremium,\r\n isCustomAvailable,\r\n customRange,\r\n instrument,\r\n }).map((dateRangeGroup: IRangeGroup) => ({\r\n label: dateRangeGroup.label,\r\n dateRanges: dateRangeGroup.dateRanges.map((dateRange) => ({\r\n ...dateRange,\r\n href:\r\n !isPremium || Object.values(DateRangeType).includes(dateRange.value as DateRangeType)\r\n ? generatePath(dateRange)\r\n : undefined,\r\n withReload: withReload ?? !isPremium,\r\n })),\r\n }))\r\n}\r\n\r\nconst FREE_PERIODS_STOCK = ['d', 'w', 'm']\r\n\r\nexport function generatePathForTimeframeDateRange({\r\n isPremium,\r\n pathname,\r\n timeframe,\r\n dateRange,\r\n utmCampaign,\r\n freeTimeframes = FREE_PERIODS_STOCK,\r\n dateRangeQueryKey = 'r',\r\n}: {\r\n isPremium: boolean\r\n pathname: string\r\n timeframe: TIMEFRAME | 'intraday'\r\n dateRange?: string | null\r\n utmCampaign?: string\r\n freeTimeframes?: string[]\r\n dateRangeQueryKey?: string\r\n}) {\r\n if (isPremium || freeTimeframes.includes(timeframe)) {\r\n return {\r\n pathname,\r\n search: `?${encodeQueryString({\r\n ...decodeQueryString(),\r\n i: undefined,\r\n p: timeframe,\r\n [dateRangeQueryKey]: dateRange ?? undefined,\r\n })}`,\r\n }\r\n }\r\n\r\n return {\r\n pathname: '/elite.ashx',\r\n search: `?${encodeQueryString({\r\n utm_source: 'finviz',\r\n utm_medium: 'banner',\r\n utm_campaign: utmCampaign || window.location.pathname,\r\n })}`,\r\n }\r\n}\r\n\r\nexport const timeframeUtm: Partial> = {\r\n [SpecificChartFunctionality.quotePage]: 'quote-timeframe',\r\n [SpecificChartFunctionality.futuresPage]: 'futures-timeframe',\r\n [SpecificChartFunctionality.forexPage]: 'forex-timeframe',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-timeframe',\r\n}\r\n\r\nexport const daterangeUtm: Partial> = {\r\n [SpecificChartFunctionality.futuresPage]: 'futures-timeframe-daterange',\r\n [SpecificChartFunctionality.forexPage]: 'forex-timeframe-daterange',\r\n [SpecificChartFunctionality.cryptoPage]: 'crypto-timeframe-daterange',\r\n}\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { formatDateToStringUS } from '../../../app/shared/utils'\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { Instrument } from '../../types'\r\nimport { generateDateRangeGroups } from './utils'\r\n\r\n// **************START**************\r\n// Functions from here until END have to be in sync with\r\n// charts: app/utils/chart-date-range-utils.ts\r\n// *********************************\r\n\r\nexport enum CustomDateRangePrefixEnum {\r\n Range = 'range',\r\n Prev = 'prev',\r\n}\r\n\r\nexport const CUSTOM_DATE_RANGE = 'custom'\r\nexport const DATE_RANGE_PREFIX_DELMITER = '_'\r\nconst CUSTOM_DATE_RANGE_DELIMITER = 'x'\r\nconst CUSTOM_PREV_RANGE_DELIMITER = '-'\r\n\r\nexport function getParsedDateRange(dateRange?: string) {\r\n return dateRange?.split(DATE_RANGE_PREFIX_DELMITER) ?? []\r\n}\r\n\r\nexport function parseCustomDateRangeUrlParam({ dateRange, anchorDate }: { dateRange: string; anchorDate: Date }) {\r\n const [dateRangePrefix, dateRangeValue] = getParsedDateRange(dateRange)\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n const [dateFromString, dateToString] = dateRangeValue.replace(/-/g, '/').split(CUSTOM_DATE_RANGE_DELIMITER)\r\n const dateFrom = dateFromString ? new Date(dateFromString) : null\r\n const dateTo = dateToString ? new Date(dateToString) : null\r\n return {\r\n start: dateFrom && !Number.isNaN(dateFrom.getTime()) ? dateFrom : null,\r\n end: dateTo && !Number.isNaN(dateTo.getTime()) ? dateFns.endOfDay(dateTo) : null,\r\n }\r\n }\r\n\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n const [years, months, days] = dateRangeValue.split(CUSTOM_PREV_RANGE_DELIMITER).map(Number)\r\n\r\n if ([years, months, days].some(Number.isNaN)) {\r\n return { start: null, end: null }\r\n }\r\n\r\n return {\r\n start: dateFns.startOfDay(dateFns.sub(anchorDate, { years, months, days: days - 1 })),\r\n end: anchorDate,\r\n }\r\n }\r\n\r\n return { start: null, end: anchorDate }\r\n}\r\n\r\nexport function getDefaultDateRangeAnchorDate() {\r\n // Uncomment for testing purposes\r\n // return dateFns.endOfDay(new Date('02-02-2023'))\r\n\r\n return new Date()\r\n}\r\n\r\n// **************END**************\r\n// Functions below don't need to be\r\n// in sync with Website repository\r\n// *******************************\r\n\r\nconst DAYS_IN_YEAR = 365\r\n\r\nexport function getCustomStartEndDateRangeUrlParam({ start, end }: { start: Date | null; end: Date | null }) {\r\n const startString = start ? formatDateToStringUS(start) : ''\r\n const endString = end ? formatDateToStringUS(end) : ''\r\n\r\n const stringParts = [\r\n CustomDateRangePrefixEnum.Range,\r\n DATE_RANGE_PREFIX_DELMITER,\r\n startString,\r\n CUSTOM_DATE_RANGE_DELIMITER,\r\n endString,\r\n ]\r\n\r\n return stringParts.join('').replace(/\\//g, '-')\r\n}\r\n\r\nexport function getPrevPeriodDateRangeUrlParam({\r\n years,\r\n months,\r\n days,\r\n}: {\r\n years: number\r\n months: number\r\n days: number\r\n}) {\r\n const stringParts = [\r\n CustomDateRangePrefixEnum.Prev,\r\n DATE_RANGE_PREFIX_DELMITER,\r\n years,\r\n CUSTOM_PREV_RANGE_DELIMITER,\r\n months,\r\n CUSTOM_PREV_RANGE_DELIMITER,\r\n days,\r\n ]\r\n\r\n return stringParts.join('')\r\n}\r\n\r\nexport function getTimeframeForDateRangeType({\r\n dateRange,\r\n isPremium = true,\r\n instrument,\r\n}: {\r\n dateRange: string\r\n isPremium?: boolean\r\n instrument: Instrument\r\n}) {\r\n const dateRanges = generateDateRangeGroups({ isPremium, instrument }).flatMap(({ dateRanges }) => dateRanges)\r\n return dateRanges.find(({ value }) => value === dateRange)?.timeframe ?? null\r\n}\r\n\r\nexport function getTimeframeFromDateRange({\r\n dateRange,\r\n anchorDate,\r\n instrument,\r\n isPremium,\r\n}: {\r\n dateRange: string\r\n anchorDate: Date\r\n instrument: Instrument\r\n isPremium: boolean\r\n}) {\r\n const dateRangeTimeframe = getTimeframeForDateRangeType({ dateRange, instrument })\r\n if (dateRangeTimeframe) {\r\n return dateRangeTimeframe\r\n }\r\n const { start, end } = parseCustomDateRangeUrlParam({ dateRange, anchorDate })\r\n const startNyTime = start ?? new Date(0)\r\n const startToReferenceDateNumOfDays = dateFns.differenceInCalendarDays(anchorDate, startNyTime) + 1\r\n const rangeNumOfDays = dateFns.differenceInCalendarDays(end ?? anchorDate, startNyTime) + 1\r\n /**\r\n * DB_BARS_LIMIT - code below is dependent on amount of data we store for specific timeframes\r\n * Search DB_BARS_LIMIT in the project to find other places with such code.\r\n */\r\n if (rangeNumOfDays > 6 * DAYS_IN_YEAR) {\r\n return TIMEFRAME.m\r\n }\r\n\r\n if (rangeNumOfDays > 4 * DAYS_IN_YEAR) {\r\n return isPremium ? TIMEFRAME.w : TIMEFRAME.m\r\n }\r\n\r\n if (rangeNumOfDays > 1.5 * DAYS_IN_YEAR) {\r\n return TIMEFRAME.w\r\n }\r\n\r\n // Keep these values in sync with values in FetchQuoteIntraday in quote.cs\r\n if (instrument === Instrument.Stock) {\r\n if (rangeNumOfDays <= 1 && startToReferenceDateNumOfDays <= 11) {\r\n return TIMEFRAME.i1\r\n }\r\n\r\n if (rangeNumOfDays <= 5 && startToReferenceDateNumOfDays <= 16) {\r\n return TIMEFRAME.i5\r\n }\r\n\r\n if (rangeNumOfDays <= 7 && startToReferenceDateNumOfDays <= 200) {\r\n return TIMEFRAME.i30\r\n }\r\n } else {\r\n if (startToReferenceDateNumOfDays <= 2) {\r\n return TIMEFRAME.i5\r\n }\r\n if (startToReferenceDateNumOfDays <= 7) {\r\n return TIMEFRAME.i30\r\n }\r\n }\r\n\r\n return TIMEFRAME.d\r\n}\r\n","import * as dateFns from 'date-fns'\r\nimport * as React from 'react'\r\n\r\nimport { parseInputAsDate } from '../../modules/portfolio/utils'\r\nimport { DateInputWithPicker } from '../DateInputWithPicker'\r\nimport { Button } from '../button'\r\nimport { ButtonGroup } from '../button-group'\r\nimport { Delayed } from '../delayed'\r\nimport { Dialog, DialogBody, DialogDismiss, DialogFooter, DialogHeader } from '../dialog'\r\nimport { Input } from '../input'\r\nimport { Spinner } from '../spinner'\r\nimport {\r\n CustomDateRangePrefixEnum,\r\n getCustomStartEndDateRangeUrlParam,\r\n getParsedDateRange,\r\n getPrevPeriodDateRangeUrlParam,\r\n parseCustomDateRangeUrlParam,\r\n} from './custom-date-range-utils'\r\n\r\nconst DATA_YEAR_START = 1980\r\nconst DATE_PICKER_MIN_DATE = new Date(`01/01/${DATA_YEAR_START}`)\r\nconst YEARS_MAX_VALUE = new Date().getFullYear() - DATA_YEAR_START\r\n\r\nconst TAB_BUTTON_COMMON_PROPS = { type: 'button', className: 'flex-1', contentClass: 'text-center' } as const\r\n\r\nexport enum CustomRangeType {\r\n StartEnd,\r\n Manual,\r\n}\r\n\r\ninterface StartEndRange {\r\n kind: CustomRangeType.StartEnd\r\n start: string\r\n end: string\r\n}\r\n\r\ninterface ManualRange {\r\n kind: CustomRangeType.Manual\r\n days?: number\r\n months?: number\r\n years?: number\r\n}\r\n\r\nexport type CustomDateRangeType = StartEndRange | ManualRange\r\n\r\ninterface DialogContentProps {\r\n /**\r\n * Dialog state\r\n */\r\n dialogState: any\r\n dateRange?: string\r\n anchorDate: Date\r\n onDialogSubmit: (args: { dateRange: string | null }) => void\r\n isFetching?: boolean\r\n}\r\n\r\nconst DEFAULT_MANUAL_RANGE: ManualRange = {\r\n kind: CustomRangeType.Manual,\r\n days: 0,\r\n months: 0,\r\n years: 0,\r\n}\r\n\r\nconst DEFAULT_START_END_RANGE: StartEndRange = {\r\n kind: CustomRangeType.StartEnd,\r\n start: '',\r\n end: '',\r\n}\r\n\r\nconst DATE_FORMAT_VIEW = 'MM/dd/yyyy'\r\nconst DATE_FORMAT_VIEW_PLACEHOLDER = DATE_FORMAT_VIEW.toUpperCase()\r\n\r\nfunction isValidManualRangeState({ years = 0, months = 0, days = 0 }: ManualRange) {\r\n return years + months + days > 0\r\n}\r\n\r\nfunction isValidStartEndRangeState({ start, end }: StartEndRange) {\r\n return !!(start || end)\r\n}\r\n\r\nfunction getDefaultSelectedTab(dateRange?: string) {\r\n if (dateRange) {\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n return CustomRangeType.StartEnd\r\n }\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev) {\r\n return CustomRangeType.Manual\r\n }\r\n }\r\n return CustomRangeType.StartEnd\r\n}\r\n\r\nfunction getDefaultSelectedDate({\r\n dateRange,\r\n anchorDate,\r\n}: {\r\n dateRange?: string\r\n anchorDate: Date\r\n}): CustomDateRangeType {\r\n if (dateRange) {\r\n const [dateRangePrefix] = getParsedDateRange(dateRange)\r\n const { start, end } = parseCustomDateRangeUrlParam({ dateRange, anchorDate })\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Range) {\r\n return {\r\n kind: CustomRangeType.StartEnd,\r\n start: start ? dateFns.format(start, DATE_FORMAT_VIEW) : '',\r\n end: end ? dateFns.format(end, DATE_FORMAT_VIEW) : '',\r\n }\r\n }\r\n if (dateRangePrefix === CustomDateRangePrefixEnum.Prev && start && end) {\r\n const { years, months, days } = dateFns.intervalToDuration({\r\n start: dateFns.sub(start, { days: 1 }),\r\n end,\r\n })\r\n return { kind: CustomRangeType.Manual, years, months, days }\r\n }\r\n }\r\n\r\n return DEFAULT_START_END_RANGE\r\n}\r\n\r\nexport function CustomDateRange({\r\n dialogState,\r\n dateRange,\r\n anchorDate,\r\n onDialogSubmit,\r\n isFetching,\r\n}: DialogContentProps) {\r\n const [errors, setErrors] = React.useState({\r\n start: false,\r\n end: false,\r\n })\r\n const [selectedTab, setSelectedTab] = React.useState(getDefaultSelectedTab(dateRange))\r\n\r\n const [state, setState] = React.useState(getDefaultSelectedDate({ dateRange, anchorDate }))\r\n\r\n const { current: onChange } = React.useRef((kind: CustomRangeType, newValue: Partial) => {\r\n setState((prevState) => {\r\n if (kind === CustomRangeType.Manual) {\r\n const defaults = prevState?.kind === CustomRangeType.Manual ? prevState : DEFAULT_MANUAL_RANGE\r\n return { ...defaults, ...newValue } as ManualRange\r\n }\r\n if (kind === CustomRangeType.StartEnd) {\r\n const defaults = prevState?.kind === CustomRangeType.StartEnd ? prevState : DEFAULT_START_END_RANGE\r\n\r\n const newState = { ...defaults, ...newValue }\r\n const parsedStartDate = newState.start\r\n ? parseInputAsDate({ input: newState.start, format: DATE_FORMAT_VIEW })\r\n : null\r\n const parsedEndDate = newState.end ? parseInputAsDate({ input: newState.end, format: DATE_FORMAT_VIEW }) : null\r\n\r\n const isParsedStartDateValid = parsedStartDate && dateFns.isValid(parsedStartDate)\r\n const isParsedEndDateValid = parsedEndDate && dateFns.isValid(parsedEndDate)\r\n\r\n if (isParsedStartDateValid) {\r\n newState.start = dateFns.format(parsedStartDate, DATE_FORMAT_VIEW)\r\n }\r\n\r\n if (isParsedEndDateValid) {\r\n newState.end = dateFns.format(parsedEndDate, DATE_FORMAT_VIEW)\r\n }\r\n\r\n if (isParsedStartDateValid && isParsedEndDateValid && parsedStartDate.getTime() > parsedEndDate.getTime()) {\r\n const newEnd = newState.start\r\n newState.start = newState.end\r\n newState.end = newEnd\r\n }\r\n return newState\r\n }\r\n return prevState\r\n })\r\n })\r\n\r\n const handleSubmit = (ev: React.FormEvent) => {\r\n ev.preventDefault()\r\n\r\n let dateRange = null\r\n\r\n if (state?.kind === CustomRangeType.StartEnd && isValidStartEndRangeState(state)) {\r\n const parsedStartDate = state.start ? parseInputAsDate({ input: state.start, format: DATE_FORMAT_VIEW }) : null\r\n const parsedEndDate = state.end ? parseInputAsDate({ input: state.end, format: DATE_FORMAT_VIEW }) : null\r\n const hasStartError = !!(state.start && !dateFns.isValid(parsedStartDate))\r\n const hasEndError = !!(state.end && !dateFns.isValid(parsedEndDate))\r\n setErrors((prevErrors) => ({\r\n ...prevErrors,\r\n start: hasStartError,\r\n end: hasEndError,\r\n }))\r\n\r\n if (hasStartError || hasEndError) {\r\n return\r\n }\r\n\r\n dateRange = getCustomStartEndDateRangeUrlParam({ start: parsedStartDate, end: parsedEndDate })\r\n } else if (state?.kind === CustomRangeType.Manual && isValidManualRangeState(state)) {\r\n dateRange = getPrevPeriodDateRangeUrlParam({\r\n days: state.days ?? 0,\r\n months: state.months ?? 0,\r\n years: state.years ?? 0,\r\n })\r\n }\r\n\r\n onDialogSubmit({ dateRange })\r\n }\r\n\r\n const isAbsolute = state?.kind === CustomRangeType.StartEnd\r\n const fromDate = isAbsolute ? state.start : DEFAULT_START_END_RANGE.start\r\n const toDate = isAbsolute ? state.end : DEFAULT_START_END_RANGE.end\r\n\r\n const manualRange = {\r\n ...DEFAULT_MANUAL_RANGE,\r\n ...(state?.kind === CustomRangeType.Manual ? state : {}),\r\n }\r\n\r\n return (\r\n \r\n Custom Date Range\r\n
\r\n \r\n \r\n setSelectedTab(CustomRangeType.StartEnd)}\r\n >\r\n Start / End\r\n \r\n setSelectedTab(CustomRangeType.Manual)}\r\n >\r\n Range\r\n \r\n \r\n\r\n {selectedTab === CustomRangeType.StartEnd ? (\r\n
\r\n \r\n }\r\n inputValue={fromDate}\r\n minDate={DATE_PICKER_MIN_DATE}\r\n onChange={(start) => {\r\n onChange(CustomRangeType.StartEnd, { start })\r\n }}\r\n onErrorChange={(hasError) => {\r\n setErrors((prevErrors) => ({ ...prevErrors, start: hasError }))\r\n }}\r\n hasError={errors.start}\r\n viewDateFormat={DATE_FORMAT_VIEW}\r\n dataDateFormat={DATE_FORMAT_VIEW}\r\n />\r\n\r\n \r\n }\r\n inputValue={toDate}\r\n minDate={DATE_PICKER_MIN_DATE}\r\n onChange={(end) => {\r\n onChange(CustomRangeType.StartEnd, { end })\r\n }}\r\n onErrorChange={(hasError) => {\r\n setErrors((prevErrors) => ({ ...prevErrors, end: hasError }))\r\n }}\r\n hasError={errors.end}\r\n viewDateFormat={DATE_FORMAT_VIEW}\r\n dataDateFormat={DATE_FORMAT_VIEW}\r\n />\r\n
\r\n ) : (\r\n
\r\n ) =>\r\n onChange(CustomRangeType.Manual, { years: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n ) =>\r\n onChange(CustomRangeType.Manual, { months: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n ) =>\r\n onChange(CustomRangeType.Manual, { days: Number.parseInt(ev.currentTarget.value) })\r\n }\r\n />\r\n
\r\n )}\r\n
\r\n \r\n
\r\n \r\n setState(state.kind === CustomRangeType.Manual ? DEFAULT_MANUAL_RANGE : DEFAULT_START_END_RANGE)\r\n }\r\n >\r\n Reset\r\n \r\n
\r\n \r\n \r\n
\r\n
\r\n
\r\n )\r\n}\r\n","import React from 'react'\r\nimport { To, useNavigate } from 'react-router-dom'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { Instrument } from '../../types'\r\nimport { useDialogState } from '../dialog'\r\nimport { getTimeframeFromDateRange } from './custom-date-range-utils'\r\n\r\ninterface IPathForTimeframeDateRangeProps {\r\n timeframe: TIMEFRAME | 'intraday'\r\n dateRange?: string | null\r\n ticker?: string\r\n}\r\n\r\ninterface IUseCustomDateRangeDialogSubmitProps {\r\n anchorDate?: Date\r\n instrument?: Instrument\r\n shouldReloadOnNavigate?: boolean\r\n pathGenerator?: ({ ticker, timeframe, dateRange }: IPathForTimeframeDateRangeProps) => {\r\n pathname: string\r\n search: string\r\n }\r\n}\r\n\r\ntype HandleDateRangeSelectFn = (\r\n props: WithHref extends true\r\n ? { value: string; timeframe?: TIMEFRAME; href?: To }\r\n : { value: string; timeframe?: TIMEFRAME },\r\n callback?: ({ value, timeframe, href }: { value: string; timeframe: TIMEFRAME; href?: To }) => void\r\n) => void\r\n\r\nexport function useCustomDateRangeDialog({\r\n anchorDate,\r\n instrument,\r\n pathGenerator,\r\n shouldReloadOnNavigate = false,\r\n}: IUseCustomDateRangeDialogSubmitProps) {\r\n const navigate = useNavigate()\r\n const customDateRangeDialogState = useDialogState()\r\n\r\n const isPremium = FinvizSettings.hasUserPremium\r\n\r\n const handleDateRangeSelect = React.useCallback(\r\n ({ value, timeframe, href }, callback) => {\r\n if (!timeframe) return\r\n\r\n if (!href && pathGenerator) {\r\n const path = pathGenerator({ timeframe, dateRange: value })\r\n if (shouldReloadOnNavigate) {\r\n window.location.href = `${path.pathname}?${path.search}`\r\n } else {\r\n navigate(path)\r\n }\r\n }\r\n\r\n callback?.({ value, timeframe, href })\r\n },\r\n [navigate, pathGenerator, shouldReloadOnNavigate]\r\n )\r\n\r\n const getDateRangeTimeframe = React.useCallback(\r\n (dateRange: string | null) => {\r\n if (!anchorDate || !instrument || !dateRange) return null\r\n\r\n return {\r\n value: dateRange,\r\n timeframe: getTimeframeFromDateRange({\r\n dateRange: dateRange!,\r\n anchorDate,\r\n isPremium,\r\n instrument,\r\n }),\r\n }\r\n },\r\n [anchorDate, instrument, isPremium]\r\n )\r\n\r\n const onDialogSubmit = React.useCallback>(\r\n ({ value: dateRange, timeframe: newTimeframe }, callback) => {\r\n handleDateRangeSelect(\r\n {\r\n value: dateRange,\r\n timeframe: newTimeframe,\r\n },\r\n callback\r\n )\r\n customDateRangeDialogState.hide()\r\n },\r\n // We only want `customDateRangeDialogState.hide`, not the whole dialog\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [customDateRangeDialogState.hide, handleDateRangeSelect]\r\n )\r\n\r\n return { onDialogSubmit, customDateRangeDialogState, handleDateRangeSelect, getDateRangeTimeframe }\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { TIMEFRAME } from '../../constants'\r\nimport { useSyncLocalStorage } from '../../hooks/use-sync-local-storage'\r\n\r\ntype FavoriteTimeframesMap = { [K in TIMEFRAME | 'intraday']?: boolean }\r\n\r\nexport const TIMEFRAME_FAVORITE_DEFAULTS = {\r\n [TIMEFRAME.i1]: true,\r\n [TIMEFRAME.i2]: false,\r\n [TIMEFRAME.i3]: true,\r\n [TIMEFRAME.i5]: true,\r\n [TIMEFRAME.i10]: false,\r\n [TIMEFRAME.i15]: true,\r\n [TIMEFRAME.i30]: true,\r\n [TIMEFRAME.h]: true,\r\n [TIMEFRAME.h2]: false,\r\n [TIMEFRAME.h4]: false,\r\n [TIMEFRAME.d]: true,\r\n [TIMEFRAME.w]: true,\r\n [TIMEFRAME.m]: true,\r\n}\r\n\r\nexport const TIMEFRAME_FAVORITE_DEFAULTS_FREE = {\r\n ...TIMEFRAME_FAVORITE_DEFAULTS,\r\n intraday: true,\r\n}\r\n\r\nconst LOCAL_STORAGE_KEY = 'favoriteTimeframesMap'\r\n\r\nexport function useFavoriteTimeframes(isPremium = true) {\r\n const { state, setState } = useSyncLocalStorage(\r\n LOCAL_STORAGE_KEY,\r\n isPremium ? TIMEFRAME_FAVORITE_DEFAULTS : TIMEFRAME_FAVORITE_DEFAULTS_FREE\r\n )\r\n\r\n const toggleFavoriteTimeframe = React.useCallback(\r\n (timeframe: TIMEFRAME | 'intraday') => {\r\n setState((prevState) => ({\r\n ...prevState,\r\n [timeframe]: !prevState[timeframe],\r\n }))\r\n },\r\n [setState]\r\n )\r\n\r\n const favoriteTimeframes = React.useMemo(\r\n () => Object.keys(state).filter((key) => state[key as keyof FavoriteTimeframesMap]),\r\n [state]\r\n )\r\n\r\n return {\r\n favoriteTimeframes: isPremium ? favoriteTimeframes : Object.keys(TIMEFRAME_FAVORITE_DEFAULTS_FREE),\r\n toggleFavoriteTimeframe,\r\n }\r\n}\r\n","import * as React from 'react'\r\n\r\nimport * as storage from '../services/local-storage'\r\n\r\n/**\r\n * Hook to synchronize localStorage.setItem across all components on the page on all open tabs\r\n */\r\nexport function useSyncLocalStorage(storageKey: string, defaultValue: ValueType) {\r\n const [state, setState] = React.useState(storage.getValue(storageKey, defaultValue))\r\n\r\n React.useEffect(() => {\r\n const subscription = storage.subscribeToChanges(storageKey, defaultValue, setState)\r\n\r\n return () => {\r\n subscription.unsubscribe()\r\n }\r\n }, [storageKey, defaultValue])\r\n\r\n const setValue = React.useCallback(\r\n (valueGetter: React.SetStateAction) => storage.setValue(storageKey, valueGetter, defaultValue),\r\n [defaultValue, storageKey]\r\n )\r\n\r\n return {\r\n state,\r\n setState: setValue,\r\n }\r\n}\r\n","import debounce from 'lodash.debounce'\r\nimport * as React from 'react'\r\n\r\nimport { useIsMounted } from './use-is-mounted'\r\nimport { useResizeObserver } from './use-resize-observer'\r\n\r\nexport function useElementMeasure(elementOverride: HTMLElement | null = null) {\r\n const ResizeObserver = useResizeObserver()\r\n const getIsMounted = useIsMounted()\r\n const [elementRef, setElementRef] = React.useState(elementOverride)\r\n const [elementWidth, setElementWidth] = React.useState(elementRef?.offsetWidth ?? 0)\r\n const [elementHeight, setElementHeight] = React.useState(elementRef?.offsetHeight ?? 0)\r\n\r\n React.useEffect(() => {\r\n if (!ResizeObserver) {\r\n return\r\n }\r\n\r\n const measureElement = () => {\r\n if (!getIsMounted()) {\r\n return\r\n }\r\n const newElementWidth = elementRef?.offsetWidth\r\n const newElementHeight = elementRef?.offsetHeight\r\n if (newElementWidth !== elementWidth) {\r\n setElementWidth(newElementWidth ?? 0)\r\n }\r\n if (newElementHeight !== elementHeight) {\r\n setElementHeight(newElementHeight ?? 0)\r\n }\r\n }\r\n const measureElementDebounced = debounce(measureElement, 200)\r\n\r\n const resizeObserver = new ResizeObserver((entries) => {\r\n /**\r\n * the reason for requestAnimationFrame is described here https://github.com/quasarframework/quasar/issues/2233\r\n * their approach was mostly to intercept and silence the error but I managed to avoid the error using requestAnimationFrame\r\n * */\r\n window.requestAnimationFrame(() => {\r\n if (Array.isArray(entries) && entries.length > 0) {\r\n measureElementDebounced()\r\n }\r\n })\r\n })\r\n\r\n if (elementRef) {\r\n resizeObserver.observe(elementRef)\r\n }\r\n\r\n measureElement()\r\n\r\n return () => {\r\n measureElementDebounced.cancel()\r\n resizeObserver?.disconnect()\r\n }\r\n }, [ResizeObserver, elementWidth, elementRef, elementHeight, getIsMounted])\r\n\r\n return { setElementRef: elementOverride ? () => {} : setElementRef, elementWidth, elementHeight }\r\n}\r\n","// Copy if this file is in charts repo in app/utils/ folder\r\nimport * as React from 'react'\r\n\r\nexport function useIsMounted() {\r\n const isMountedRef = React.useRef(false)\r\n const getIsMounted = React.useCallback(() => isMountedRef.current, [])\r\n\r\n React.useEffect(() => {\r\n isMountedRef.current = true\r\n return () => {\r\n isMountedRef.current = false\r\n }\r\n }, [])\r\n\r\n return getIsMounted\r\n}\r\n","import React from 'react'\r\n\r\nexport function usePrevious(value: TValue) {\r\n const ref = React.useRef()\r\n\r\n React.useEffect(() => {\r\n ref.current = value\r\n }, [value])\r\n\r\n return ref.current\r\n}\r\n","import * as React from 'react'\r\n\r\nimport { SortDirection, SortableValue } from '../types'\r\nimport { SortByColumnOptions, sortByColumn } from '../util'\r\n\r\nexport interface SortableColumn {\r\n id: IdType\r\n\r\n compoundSort?: IdType[]\r\n\r\n /**\r\n * Provide value calculation for sort when value is computed in column renderer\r\n */\r\n getValueForSort?: (row: DataType) => SortableValue\r\n}\r\n\r\nexport function isSortableColumnShape(\r\n maybeColumn?: unknown\r\n): maybeColumn is SortableColumn {\r\n return typeof maybeColumn === 'object' && maybeColumn?.hasOwnProperty?.('id') === true\r\n}\r\n\r\nexport interface SortByShape {\r\n column: ColumnType\r\n direction: SortDirection\r\n}\r\n\r\nexport function isSortByShape(maybeSort?: unknown): maybeSort is SortByShape {\r\n return maybeSort?.hasOwnProperty?.('column') === true && maybeSort?.hasOwnProperty?.('direction') === true\r\n}\r\n\r\n/**\r\n * Default value getter which gets row data by `getValueForSort` defined on the column\r\n * If no sort value getter is provided, it falls back to getting data by column.id or returns the whole row\r\n */\r\nexport function getDefaultValueGetter(column: SortBy) {\r\n return (row: DataType): SortableValue => {\r\n let value = null\r\n\r\n if (isSortableColumnShape(column)) {\r\n if (typeof column.getValueForSort === 'function') value = column.getValueForSort(row)\r\n else if (typeof row === 'object') value = row?.[column.id as keyof typeof row]\r\n } else {\r\n value = row\r\n }\r\n\r\n return (value as SortableValue) ?? null\r\n }\r\n}\r\n\r\ninterface SortDataOptions {\r\n columns: readonly ColumnType[]\r\n data: DataType[]\r\n sortBy?: SortBy\r\n valueGetter?: (column: ColumnType) => (row: DataType) => SortableValue\r\n options?: SortByColumnOptions\r\n}\r\n\r\nexport function sortDataByColumn<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n SortBy extends SortByShape,\r\n>({\r\n columns,\r\n data,\r\n sortBy,\r\n valueGetter = getDefaultValueGetter,\r\n options,\r\n}: SortDataOptions) {\r\n if (!sortBy?.column) return [...data]\r\n\r\n let sortedColumns: SortByShape[] = [sortBy]\r\n if (sortBy.column.compoundSort) {\r\n sortedColumns = sortBy.column.compoundSort.map((compoundColumn) => ({\r\n column: columns.find((column) => column.id === compoundColumn)!,\r\n direction: sortBy.direction,\r\n }))\r\n }\r\n\r\n return [...data].sort((_a, _b) => {\r\n for (const columnSortBy of sortedColumns) {\r\n const a = valueGetter(columnSortBy.column)(_a)\r\n const b = valueGetter(columnSortBy.column)(_b)\r\n const sortResult = sortByColumn({ ...options, a, b, direction: columnSortBy.direction })\r\n\r\n if (sortResult === 0) continue\r\n\r\n return sortResult\r\n }\r\n\r\n return 0\r\n })\r\n}\r\n\r\nexport function useSortData<\r\n IdType,\r\n DataType,\r\n ColumnType extends SortableColumn,\r\n SortBy extends SortByShape,\r\n>(options: SortDataOptions) {\r\n return React.useMemo(\r\n () => {\r\n if (options.data.length === 0) return options.data\r\n return sortDataByColumn(options)\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [options.columns, options.data, options.sortBy, options.valueGetter, options.options]\r\n )\r\n}\r\n","import throttle from 'lodash.throttle'\r\nimport * as React from 'react'\r\n\r\nexport function getVisualViewport(visualViewport: VisualViewport | null) {\r\n const width = visualViewport?.width ?? window.innerWidth\r\n const height = visualViewport?.height ?? window.innerHeight\r\n const scale = visualViewport?.scale ?? 1\r\n\r\n return {\r\n top: visualViewport?.offsetTop ?? 0,\r\n left: visualViewport?.offsetLeft ?? 0,\r\n scale: Math.round((1 / scale) * 100) / 100,\r\n width: Math.round(width * scale),\r\n height: Math.round(height * scale),\r\n unscaledWidth: width,\r\n unscaledHeight: height,\r\n }\r\n}\r\n\r\nexport function useVisualViewport({ enabled = true, onScroll = true }: { enabled?: boolean; onScroll?: boolean } = {}) {\r\n const [viewport, setViewport] = React.useState(getVisualViewport(window.visualViewport))\r\n\r\n React.useEffect(() => {\r\n if (!enabled) return\r\n\r\n const handleChange = throttle((ev: Event) => {\r\n const viewport = ev.currentTarget as VisualViewport\r\n if (viewport) {\r\n setViewport(() => getVisualViewport(viewport))\r\n }\r\n }, 50)\r\n\r\n window.visualViewport?.addEventListener('resize', handleChange)\r\n if (onScroll) window.visualViewport?.addEventListener('scroll', handleChange)\r\n handleChange({ currentTarget: window.visualViewport } as Event)\r\n\r\n return () => {\r\n window.visualViewport?.removeEventListener('resize', handleChange)\r\n window.visualViewport?.removeEventListener('scroll', handleChange)\r\n }\r\n }, [enabled, onScroll])\r\n\r\n return React.useMemo(() => ({ viewport, setViewport }), [viewport])\r\n}\r\n","import classNames from 'classnames'\r\nimport * as dateFns from 'date-fns'\r\n\r\nimport { RedGreenMultiline, RedGreenText } from '../../../components/RedGreenText'\r\nimport { TableAlign } from '../../../components/Table'\r\nimport { formatNumber } from '../../../util'\r\nimport { ColumnId, PortfolioSymbolType, PortfolioTransaction, RowKind, TableColumnDefinition } from '../types'\r\nimport { PORTFOLIO_DATE_FORMAT_VIEW, TRANSACTION_LABEL } from './general'\r\n\r\nexport const columnMap: Record = Object.freeze({\r\n [ColumnId.Spacer]: {\r\n id: ColumnId.Spacer,\r\n urlSort: '',\r\n name: '',\r\n renderColumn: () => null,\r\n },\r\n [ColumnId.Ticker]: {\r\n id: ColumnId.Ticker,\r\n urlSort: 'ticker',\r\n name: 'Ticker',\r\n align: TableAlign.Left,\r\n renderColumn: (args) => {\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Summary:\r\n return null\r\n case RowKind.Group:\r\n case RowKind.Trade:\r\n if (args.row.type === PortfolioSymbolType.Stock && !args.row.isDelisted) {\r\n return (\r\n ev.stopPropagation()}\r\n >\r\n {args.row.ticker}\r\n \r\n )\r\n }\r\n\r\n return {args.row.ticker}\r\n default:\r\n return {args.row.ticker}\r\n }\r\n },\r\n },\r\n [ColumnId.Company]: {\r\n id: ColumnId.Company,\r\n urlSort: 'company',\r\n name: 'Company',\r\n align: TableAlign.Left,\r\n renderColumn: (args) => {\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n return null\r\n case RowKind.Summary:\r\n return (\r\n \r\n Summary:{' '}\r\n \r\n {args.row.tickers} Ticker{args.row.tickers === 1 ? '' : 's'}\r\n \r\n / \r\n \r\n {args.row.transactions} Transaction{args.row.transactions === 1 ? '' : 's'}\r\n \r\n \r\n )\r\n default:\r\n return
{args.row.company}
\r\n }\r\n },\r\n },\r\n [ColumnId.CostAvg]: {\r\n id: ColumnId.CostAvg,\r\n urlSort: 'costavg',\r\n name: 'Avg. Cost',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Summary:\r\n return null\r\n case RowKind.Trade: {\r\n if (args.row.transaction === PortfolioTransaction.Watch) return null\r\n return formatNumber(args.row.costAvg)\r\n }\r\n default:\r\n return formatNumber(args.row.costAvg)\r\n }\r\n },\r\n },\r\n [ColumnId.LastClose]: {\r\n id: ColumnId.LastClose,\r\n urlSort: 'price',\r\n name: 'Price',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Summary:\r\n return null\r\n default:\r\n return formatNumber(args.row.lastClose)\r\n }\r\n },\r\n },\r\n [ColumnId.LastChange]: {\r\n id: ColumnId.LastChange,\r\n urlSort: 'lastchange',\r\n name: 'Change $',\r\n align: TableAlign.Right,\r\n getValueForSort: (args) => (args.kind === RowKind.Group ? args.row.lastClose - args.row.prevClose : null),\r\n renderColumn: (args) => {\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Summary:\r\n return null\r\n default:\r\n if (args.row.isDelisted) return '-'\r\n\r\n const lastChange = args.row.lastClose - args.row.prevClose\r\n return (\r\n \r\n {formatNumber(lastChange, {\r\n showPlusSign: true,\r\n fractions: args.row.lastClose < 1 ? 4 : 2,\r\n })}\r\n \r\n )\r\n }\r\n },\r\n },\r\n [ColumnId.LastChangePct]: {\r\n id: ColumnId.LastChangePct,\r\n urlSort: 'changepct',\r\n name: 'Change %',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n return null\r\n default:\r\n return (\r\n \r\n {formatNumber(args.row.lastChangePct, { showPlusSign: true })}\r\n \r\n )\r\n }\r\n },\r\n },\r\n [ColumnId.LastVolume]: {\r\n id: ColumnId.LastVolume,\r\n urlSort: 'volume',\r\n name: 'Volume',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Group:\r\n case RowKind.Trade:\r\n return formatNumber(args.row.lastVolume, { fractions: 0 })\r\n default:\r\n return null\r\n }\r\n },\r\n },\r\n [ColumnId.Transaction]: {\r\n id: ColumnId.Transaction,\r\n urlSort: 'transaction',\r\n name: 'Transaction',\r\n align: TableAlign.Left,\r\n renderColumn: (args) => {\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Trade:\r\n return TRANSACTION_LABEL[args.row.transaction]\r\n default:\r\n return null\r\n }\r\n },\r\n },\r\n [ColumnId.Date]: {\r\n id: ColumnId.Date,\r\n urlSort: 'date',\r\n name: 'Date',\r\n align: TableAlign.Left,\r\n renderColumn: (args) => {\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Trade:\r\n return (\r\n \r\n {dateFns.format(new Date(args.row.date), PORTFOLIO_DATE_FORMAT_VIEW)}\r\n
\r\n )\r\n default:\r\n return null\r\n }\r\n },\r\n },\r\n [ColumnId.Shares]: {\r\n id: ColumnId.Shares,\r\n urlSort: 'shares',\r\n name: 'Shares',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Summary:\r\n return null\r\n case RowKind.Trade: {\r\n if (args.row.transaction === PortfolioTransaction.Watch) return null\r\n return formatNumber(args.row.shares, { fractions: 0 })\r\n }\r\n default:\r\n return formatNumber(args.row.shares, { fractions: 0 })\r\n }\r\n },\r\n },\r\n [ColumnId.Price]: {\r\n id: ColumnId.Price,\r\n urlSort: 'cost',\r\n name: 'Cost / Share',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n\r\n switch (args.kind) {\r\n case RowKind.Transaction:\r\n case RowKind.Trade:\r\n return formatNumber(args.row.price)\r\n default:\r\n return null\r\n }\r\n },\r\n },\r\n [ColumnId.ValuePaid]: {\r\n id: ColumnId.ValuePaid,\r\n urlSort: 'totalcost',\r\n name: 'Total Cost',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n if (args.kind === RowKind.Trade && args.row.transaction === PortfolioTransaction.Watch) return null\r\n return formatNumber(args.row.valuePaid)\r\n },\r\n },\r\n [ColumnId.Amount]: {\r\n id: ColumnId.Amount,\r\n urlSort: 'amount',\r\n name: 'Amount',\r\n align: TableAlign.Right,\r\n getValueForSort: (args) => args.row.valuePaid,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Trade && args.kind !== RowKind.Transaction) return null\r\n return formatNumber(args.row.price)\r\n },\r\n },\r\n [ColumnId.ValueMarket]: {\r\n id: ColumnId.ValueMarket,\r\n urlSort: 'marketvalue',\r\n name: 'Market Value',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind === RowKind.Trade && args.row.transaction === PortfolioTransaction.Watch) return null\r\n return formatNumber(args.row.valueMarket)\r\n },\r\n },\r\n [ColumnId.GainMarketUsd]: {\r\n id: ColumnId.GainMarketUsd,\r\n urlSort: 'gainusd',\r\n name: 'Total Gain $',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n if (args.kind === RowKind.Trade && args.row.transaction === PortfolioTransaction.Watch) return null\r\n return (\r\n \r\n {formatNumber(args.row.gainMarketUsd)}\r\n \r\n )\r\n },\r\n },\r\n [ColumnId.GainMarketPct]: {\r\n id: ColumnId.GainMarketPct,\r\n urlSort: 'gainpct',\r\n name: 'Total Gain %',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n if (args.kind === RowKind.Trade && args.row.transaction === PortfolioTransaction.Watch) return null\r\n return (\r\n \r\n {formatNumber(args.row.gainMarketPct)}\r\n \r\n )\r\n },\r\n },\r\n [ColumnId.GainMarketCombined]: {\r\n id: ColumnId.GainMarketCombined,\r\n urlSort: 'gainmarket',\r\n name: 'Total Gain',\r\n align: TableAlign.Right,\r\n getValueForSort: (args) => args.row.gainMarketPct,\r\n renderColumn: (args) => (\r\n \r\n {formatNumber(args.row.gainMarketUsd)}\r\n \r\n {formatNumber(args.row.gainMarketPct)}\r\n \r\n \r\n ),\r\n },\r\n [ColumnId.GainTodayUsd]: {\r\n id: ColumnId.GainTodayUsd,\r\n urlSort: 'changeusd',\r\n name: 'Today’s Gain $',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.kind !== RowKind.Summary && args.row.type === PortfolioSymbolType.Cash) return null\r\n if (args.kind === RowKind.Trade && args.row.transaction === PortfolioTransaction.Watch) return null\r\n return (\r\n \r\n {formatNumber(args.row.gainTodayUsd)}\r\n \r\n )\r\n },\r\n },\r\n [ColumnId.GainTodayCombined]: {\r\n id: ColumnId.GainTodayCombined,\r\n urlSort: 'gaintoday',\r\n name: 'Today’s Gain',\r\n align: TableAlign.Right,\r\n getValueForSort: (args) => args.row.lastChangePct,\r\n renderColumn: (args) => (\r\n \r\n {formatNumber(args.row.gainTodayUsd)}\r\n \r\n {formatNumber(args.row.lastChangePct)}\r\n \r\n \r\n ),\r\n },\r\n [ColumnId.Order]: {\r\n id: ColumnId.Order,\r\n urlSort: 'order',\r\n name: 'No.',\r\n align: TableAlign.Right,\r\n renderColumn: (args) => {\r\n if (args.rowIndex === undefined || args.kind === RowKind.Summary) return null\r\n return {args.rowIndex + 1}.\r\n },\r\n },\r\n})\r\n\r\nexport const columns = Object.values(columnMap)\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { PortfolioEntryTransaction, PortfolioSymbolType, PortfolioTransaction } from '../types'\r\n\r\nexport const PORTFOLIO_CASH_SYMBOL = '$CASH'\r\n\r\nexport const PORTFOLIO_DATE_FORMAT_VIEW = 'MM-dd-yyyy'\r\nexport const PORTFOLIO_DATE_FORMAT_DATA = \"yyyy-MM-dd'T00:00:00'\"\r\n\r\nexport const PORTFOLIO_REFRESH_INTERVAL_ELITE = 20 * 1000\r\nexport const PORTFOLIO_REFRESH_INTERVAL_FREE = 60 * 1000\r\n\r\nexport const TRANSACTION_LABEL: Record = {\r\n [PortfolioTransaction.Watch]: 'Watch',\r\n\r\n // Stock transactions\r\n [PortfolioTransaction.Buy]: 'Buy',\r\n [PortfolioTransaction.Short]: 'Short Sell',\r\n\r\n // Cash transactions\r\n [PortfolioTransaction.CashDeposit]: 'Cash Deposit',\r\n [PortfolioTransaction.CashWithdraw]: 'Cash Withdraw',\r\n [PortfolioTransaction.CashIncome]: 'Income',\r\n [PortfolioTransaction.CashFee]: 'Fee',\r\n}\r\n\r\nexport const STOCK_TRANSACTIONS = [PortfolioTransaction.Buy, PortfolioTransaction.Short]\r\n\r\nexport const CASH_TRANSACTIONS = [\r\n PortfolioTransaction.CashDeposit,\r\n PortfolioTransaction.CashWithdraw,\r\n PortfolioTransaction.CashIncome,\r\n PortfolioTransaction.CashFee,\r\n]\r\n\r\nexport const EMPTY_FORM_ENTRY = {\r\n ticker: '',\r\n date: `${dateFns.format(new Date(), PORTFOLIO_DATE_FORMAT_DATA)}`,\r\n shares: undefined,\r\n price: undefined,\r\n transaction: PortfolioTransaction.Buy,\r\n}\r\n\r\nexport const EMPTY_TRANSACTION: Omit = {\r\n ...EMPTY_FORM_ENTRY,\r\n shares: 0,\r\n price: 0,\r\n type: PortfolioSymbolType.Stock,\r\n valuePaid: null,\r\n valueMarket: null,\r\n valueMarketPrev: null,\r\n gainMarket: null,\r\n gainMarketPct: null,\r\n gainMarketUsd: null,\r\n gainTodayUsd: null,\r\n lastChangePct: null,\r\n}\r\n\r\nexport const PORTFOLIO_INPUT_NAME = 'portfolio_name'\r\nexport const PORTFOLIO_INPUT_EMPTY_ERROR = 'Please enter portfolio name.'\r\nexport const PORTFOLIO_INPUT_EXISTS_ERROR = 'Portfolio with that name already exists.'\r\nexport const TICKERS_INPUT_NAME = 'tickers'\r\nexport const TICKERS_INPUT_FORMAT_TIP = 'Separate multiple tickers by a comma, e.g.: AAPL, MSFT, GOOG.'\r\n\r\n// Keep in sync with PortfolioSizeEnum in Website/App_Code/User.cs & config/types/globals.d.ts\r\nexport enum PortfolioSizeEnum {\r\n Default = 'default',\r\n Compact = 'compact',\r\n}\r\n","import { getSanitizedTicker } from '../../../../app/shared/ticker-sanitizer'\r\nimport { ContentType, apiRequest } from '../../../services/api'\r\nimport { PORTFOLIO_CASH_SYMBOL } from '../constants/general'\r\nimport {\r\n PortfolioDefinition,\r\n PortfolioEntryBase,\r\n PortfolioFormGroup,\r\n PortfolioInitData,\r\n PortfolioSymbolType,\r\n PortfolioTransaction,\r\n PortfolioTransactionWatch,\r\n} from '../types'\r\nimport { getSymbolType } from '../utils'\r\n\r\nexport const EMPTY_RESPONSE: PortfolioInitData = {\r\n limit: 0,\r\n selectedPortfolio: 0,\r\n limitTransactions: 0,\r\n portfolio: [],\r\n news: [],\r\n portfolios: [],\r\n}\r\n\r\nexport function portfolioData(portfolioId?: string | number | null) {\r\n return apiRequest('/api/portfolio_data.ashx', { query: { pid: portfolioId ?? '' } })\r\n}\r\n\r\nexport function deletePortfolio(portfolioId?: string | number) {\r\n return apiRequest('/request_portfolio_delete.ashx', { query: { pid: portfolioId }, method: 'DELETE' })\r\n}\r\n\r\nexport function portfolioEntry(\r\n query?: Record,\r\n method?: string,\r\n body?: Omit, 'type'>\r\n) {\r\n return apiRequest(\r\n '/api/portfolio_entry.ashx',\r\n {\r\n query,\r\n method,\r\n body: JSON.stringify(body),\r\n },\r\n true\r\n )\r\n}\r\n\r\nexport const QUOTE_INVALID_TICKER_REQUEST = '_UNKNOWN'\r\nexport const QUOTE_INVALID_TICKER_RESPONSE = 'NA'\r\nexport const QUOTE_TICKER_DELIMITER = ','\r\n\r\nexport function quoteData(tickers: string[]) {\r\n return apiRequest('request_quote.ashx', {\r\n query: { t: tickers.filter((ticker) => ticker.length).join(',') },\r\n headers: { 'Content-Type': ContentType.Html },\r\n })\r\n}\r\n\r\nexport async function validateTickers(tickers: string[]) {\r\n const response = await apiRequest<{ tickers: string; specialSymbols: Record }>(\r\n '/portfolio_tickers.ashx',\r\n {\r\n query: { json: true },\r\n },\r\n true\r\n )\r\n\r\n const parsedTickers = response?.tickers.split('|') ?? []\r\n const specialTickers = Object.keys(response?.specialSymbols ?? [])\r\n\r\n return tickers.map((ticker) => [...specialTickers, ...parsedTickers].includes(ticker))\r\n}\r\n\r\nexport async function recalculatePortfolio(\r\n rows: PortfolioFormGroup[],\r\n totalValue = 100000.0\r\n): Promise {\r\n const tickers: string[] = []\r\n let numberOfTransactions = 0\r\n\r\n rows.forEach((row) => {\r\n const ticker = getSanitizedTicker(row.ticker.trim(), false, [PORTFOLIO_CASH_SYMBOL])\r\n\r\n if (getSymbolType(ticker) === PortfolioSymbolType.Stock) numberOfTransactions += row.transactions.length\r\n tickers.push(ticker.length ? ticker : QUOTE_INVALID_TICKER_REQUEST)\r\n })\r\n\r\n const pricePerColumn = totalValue / numberOfTransactions\r\n\r\n const response = await quoteData(tickers)\r\n const prices = response?.split(QUOTE_TICKER_DELIMITER)\r\n\r\n if (prices?.length !== tickers.length) {\r\n window.Sentry?.captureMessage('Invalid recalculated data', {\r\n extra: {\r\n requestTickers: tickers,\r\n requestTickersLength: tickers.length,\r\n responseLength: prices?.length,\r\n },\r\n })\r\n\r\n return []\r\n }\r\n\r\n const tickerPrices = Object.fromEntries(\r\n prices.map((price, index) => {\r\n const tickerPrice = price === QUOTE_INVALID_TICKER_RESPONSE ? NaN : parseFloat(price)\r\n\r\n return [tickers[index], isNaN(tickerPrice) ? NaN : tickerPrice]\r\n })\r\n )\r\n\r\n return rows.map((row) => ({\r\n id: row.id,\r\n ticker: row.ticker,\r\n transactions: row.transactions.map((transaction) => {\r\n const price = tickerPrices[row.ticker]\r\n const shares = Math.round((pricePerColumn / price) * 10000) / 10000\r\n\r\n const calculatedPrice = isNaN(price) ? transaction.price : price\r\n const calculatedShares = isNaN(shares) ? transaction.shares : shares\r\n\r\n return {\r\n ...transaction,\r\n transaction:\r\n transaction.transaction === PortfolioTransaction.Watch ? PortfolioTransaction.Buy : transaction.transaction,\r\n price: transaction.type === PortfolioSymbolType.Cash ? 0 : calculatedPrice,\r\n shares: transaction.type === PortfolioSymbolType.Cash ? 0 : calculatedShares,\r\n }\r\n }),\r\n }))\r\n}\r\n\r\nexport function submitForm(data: URLSearchParams) {\r\n return apiRequest('/portfolio_submit.ashx', {\r\n method: 'POST',\r\n body: data.toString(),\r\n headers: { 'Content-Type': ContentType.FormUrlEncoded },\r\n })\r\n}\r\n\r\nexport type TickersApiResponse = {\r\n portfolioId: number\r\n message?: string\r\n portfolioEntries: Record>\r\n}\r\n\r\nexport enum ErrorSource {\r\n Portfolio,\r\n Tickers,\r\n}\r\n\r\nexport type TickersApiErrorResponse = {\r\n source: ErrorSource\r\n message: string\r\n isNotification?: boolean\r\n}\r\n\r\nexport function portfolioTickers({\r\n tickers,\r\n portfolioName,\r\n portfolioId,\r\n}: {\r\n tickers: string\r\n portfolioName?: string\r\n portfolioId?: number\r\n}) {\r\n const query = Object.assign(\r\n { tickers },\r\n typeof portfolioName !== 'undefined' && { portfolio_name: portfolioName },\r\n typeof portfolioId !== 'undefined' && { pid: portfolioId }\r\n )\r\n\r\n return apiRequest(\r\n '/api/portfolio_tickers.ashx',\r\n {\r\n method: 'POST',\r\n query,\r\n },\r\n true\r\n )\r\n}\r\n\r\nexport function submitEditForm(data: string | URLSearchParams) {\r\n return apiRequest('/portfolio_submit.ashx', {\r\n method: 'POST',\r\n body: data.toString(),\r\n headers: { 'Content-Type': ContentType.FormUrlEncoded },\r\n })\r\n}\r\n\r\nexport function reorderPortfolios(body: PortfolioDefinition[]) {\r\n return apiRequest('/api/portfolio_reorder.ashx', {\r\n method: 'PUT',\r\n body: JSON.stringify(body),\r\n })\r\n}\r\n","import { TableAlign } from '../../components/Table'\r\nimport { SortableColumn } from '../../hooks/use-sort-data'\r\nimport { NullableNumbers } from '../../types'\r\n\r\nexport enum PortfolioQuery {\r\n View = 'v',\r\n TableView = 'tv',\r\n PortfolioId = 'pid',\r\n Order = 'o',\r\n Tickers = 't',\r\n Map = 'map',\r\n Size = 'mapSize',\r\n Subtype = 'subtype',\r\n Group = 'group',\r\n}\r\n\r\nexport enum PortfolioMapSizeKey {\r\n MarketValue = 'market',\r\n Gain = 'gain',\r\n}\r\n\r\nexport enum PortfolioView {\r\n View = '1',\r\n Edit = '2',\r\n}\r\n\r\nexport enum PortfolioTableView {\r\n Ticker = '1',\r\n Trade = '2',\r\n}\r\n\r\nexport const PortfolioTableViewLabels = {\r\n [PortfolioTableView.Ticker]: 'Tickers',\r\n [PortfolioTableView.Trade]: 'Trades',\r\n}\r\n\r\nexport enum PortfolioSymbolType {\r\n Stock = 'stock',\r\n Cash = 'cash',\r\n}\r\n\r\nexport enum PortfolioTransaction {\r\n Watch = 0,\r\n\r\n // Stock transactions\r\n Buy = 1,\r\n Short = 2,\r\n\r\n // Cash transactions\r\n CashDeposit = 200,\r\n CashWithdraw = 201,\r\n CashIncome = 202,\r\n CashFee = 203,\r\n}\r\n\r\nexport enum NumberOfShares {\r\n None = 0,\r\n /**\r\n * The usage of this is technically incorrect. The value for `PositiveNumber` is 1.\r\n * But we don’t care in this context, because we only want to differentiate betwen zero/non-zero values,\r\n * which helps us get correct types.\r\n *\r\n * # Don’t compare `entry.shares === NumberOfShares.PositiveNumber`\r\n */\r\n PositiveNumber = 1,\r\n}\r\n\r\nexport interface PortfolioEntryBase {\r\n id: number\r\n ticker: string\r\n date: string\r\n transaction: PortfolioTransaction\r\n shares: number\r\n price: number\r\n type: PortfolioSymbolType\r\n}\r\n\r\n/**\r\n * Base type which lists all common properties\r\n */\r\nexport interface PortfolioEntryComputed {\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketPrev: number\r\n gainMarket: number\r\n gainMarketPct: number\r\n gainMarketUsd: number\r\n gainTodayUsd: number\r\n lastChangePct: number\r\n}\r\n\r\n/**\r\n * Transaction with > 0 shares\r\n */\r\nexport interface PortfolioTransactionStake extends PortfolioEntryBase, PortfolioEntryComputed {\r\n shares: NumberOfShares.PositiveNumber\r\n}\r\n\r\n/**\r\n * Transaction with 0 shares\r\n */\r\nexport interface PortfolioTransactionWatch\r\n extends Omit,\r\n NullableNumbers {\r\n shares: NumberOfShares.None\r\n transaction: PortfolioTransaction\r\n}\r\n\r\nexport type PortfolioEntryTransaction = PortfolioTransactionStake | PortfolioTransactionWatch\r\n\r\nexport type PortfolioActionType = PortfolioEntryTransaction & { isNotification?: boolean; message?: string }\r\n\r\n/**\r\n * Top level portfolio entry\r\n */\r\nexport interface PortfolioGroup extends PortfolioEntryComputed {\r\n ticker: string\r\n shares: number\r\n industry: string\r\n country: string\r\n company: string\r\n marketCap: number | null\r\n aum: number | null\r\n prevClose: number\r\n lastClose: number\r\n lastVolume: number\r\n perfWeek: number\r\n costAvg: number\r\n transactions: PortfolioEntryTransaction[]\r\n order: number\r\n id: number\r\n date: string\r\n type: PortfolioSymbolType\r\n isDelisted?: true\r\n}\r\n\r\nexport type PortfolioTrade = Omit & PortfolioEntryTransaction\r\n\r\nexport type PortfolioMapEntry = Omit & PortfolioTransactionStake\r\n\r\n/**\r\n * Summary row for the whole portfolio\r\n */\r\nexport interface PortfolioSummary {\r\n tickers: number\r\n transactions: number\r\n shares: number\r\n lastChangePct: number\r\n valuePaid: number\r\n valueMarket: number\r\n valueMarketStocks: number\r\n valueMarketStocksPrev: number\r\n gainMarketUsd: number\r\n gainMarketPct: number\r\n gainTodayUsd: number\r\n}\r\n\r\nexport interface PortfolioDefinition {\r\n id: number\r\n name: string\r\n order: number\r\n}\r\n\r\nexport interface PortfolioInitData {\r\n limit: number\r\n limitTransactions: number\r\n selectedPortfolio: number\r\n portfolios: PortfolioDefinition[]\r\n portfolio: PortfolioGroup[]\r\n news: string[]\r\n version?: number\r\n}\r\n\r\nexport interface PortfolioFormEntry\r\n extends Pick,\r\n Partial> {\r\n uuid: string\r\n}\r\n\r\nexport interface PortfolioFormGroup extends Pick {\r\n id: string\r\n transactions: PortfolioFormEntry[]\r\n}\r\n\r\nexport enum ColumnId {\r\n Spacer = 'spacer',\r\n Ticker = 'ticker',\r\n Company = 'company',\r\n LastClose = 'lastClose',\r\n CostAvg = 'costAvg',\r\n LastChange = 'lastChange',\r\n LastChangePct = 'lastChangePct',\r\n LastVolume = 'lastVolume',\r\n Transaction = 'transaction',\r\n Date = 'date',\r\n Shares = 'shares',\r\n Price = 'price',\r\n ValuePaid = 'valuePaid',\r\n Amount = 'amount',\r\n ValueMarket = 'valueMarket',\r\n GainMarketUsd = 'gainMarketUsd',\r\n GainMarketPct = 'gainMarketPct',\r\n GainMarketCombined = 'gainMarketCombined',\r\n GainTodayUsd = 'gainTodayUsd',\r\n GainTodayCombined = 'gainTodayCombined',\r\n Order = 'order',\r\n}\r\n\r\nexport enum RowKind {\r\n Group, // A group of transactions\r\n Transaction, // A transaction made inside ticker\r\n Summary, // Portfolio summary\r\n Watchlist, // Charts portfolio watchlist table\r\n Trade,\r\n}\r\n\r\ninterface GroupProps {\r\n kind: RowKind.Group\r\n row: PortfolioGroup\r\n}\r\n\r\ninterface TradeProps {\r\n kind: RowKind.Trade\r\n row: PortfolioTrade\r\n}\r\n\r\ninterface TransactionProps {\r\n kind: RowKind.Transaction\r\n row: PortfolioEntryTransaction\r\n}\r\n\r\ninterface SummaryProps {\r\n kind: RowKind.Summary\r\n row: PortfolioSummary\r\n}\r\n\r\ninterface WatchlistProps {\r\n index: number\r\n kind: RowKind.Watchlist\r\n row: PortfolioGroup\r\n}\r\n\r\nexport interface TableColumnDefinition<\r\n PropsType = (GroupProps | TradeProps | TransactionProps | SummaryProps | WatchlistProps) & { rowIndex?: number },\r\n> extends SortableColumn {\r\n urlSort: string\r\n name: string\r\n align?: TableAlign\r\n\r\n /**\r\n * Get the value of the column and render it\r\n */\r\n renderColumn: (props: PropsType) => React.ReactNode\r\n}\r\n\r\nexport enum ActionKind {\r\n AddTickers,\r\n RemoveTicker,\r\n AddTransaction,\r\n EditTransaction,\r\n RemoveTransaction,\r\n ReorderTickers,\r\n PortfoliosReorder,\r\n}\r\n\r\nexport interface Action {\r\n kind: ActionKind\r\n payload: PayloadType\r\n}\r\n\r\nexport type AddTickersError = {\r\n tickers?: string\r\n}\r\n\r\nexport interface CreatePortfolioErrors extends AddTickersError {\r\n portfolioName?: string\r\n}\r\n\r\nexport interface CreatePortfolioData {\r\n tickers: string\r\n portfolioName: string\r\n}\r\n\r\nexport type FormErrors = Partial>\r\n\r\nexport interface PortfolioBulkEditErrors {\r\n portfolioName: boolean\r\n rows: Record\r\n}\r\n\r\nexport type NotificationPayload = { isNotification?: boolean; message?: string }\r\nexport type ActionPayload = CreatePortfolioErrors | NotificationPayload\r\n","import * as dateFns from 'date-fns'\r\n\r\nimport { MapDataNode, MapDataRoot, MapSubtypeId, PerfData } from '../../../app/maps/types'\r\nimport { getMapsRefreshInterval } from '../../../app/maps/utils'\r\nimport { getSanitizedTicker } from '../../../app/shared/ticker-sanitizer'\r\nimport { parseInitData } from '../../../app/shared/utils'\r\nimport * as storage from '../../services/local-storage'\r\nimport { formatNumber, getUuid } from '../../util'\r\nimport { columnMap } from './constants/columns'\r\nimport {\r\n CASH_TRANSACTIONS,\r\n EMPTY_FORM_ENTRY,\r\n PORTFOLIO_CASH_SYMBOL,\r\n PORTFOLIO_DATE_FORMAT_DATA,\r\n PORTFOLIO_DATE_FORMAT_VIEW,\r\n PORTFOLIO_REFRESH_INTERVAL_ELITE,\r\n PORTFOLIO_REFRESH_INTERVAL_FREE,\r\n STOCK_TRANSACTIONS,\r\n} from './constants/general'\r\nimport * as api from './services/api'\r\nimport {\r\n ColumnId,\r\n FormErrors,\r\n PortfolioEntryBase,\r\n PortfolioEntryTransaction,\r\n PortfolioFormEntry,\r\n PortfolioFormGroup,\r\n PortfolioGroup,\r\n PortfolioInitData,\r\n PortfolioMapEntry,\r\n PortfolioMapSizeKey,\r\n PortfolioQuery,\r\n PortfolioSummary,\r\n PortfolioSymbolType,\r\n PortfolioTableView,\r\n PortfolioTransaction,\r\n PortfolioTransactionStake,\r\n PortfolioView,\r\n} from './types'\r\n\r\nexport enum PortfolioDataKey {\r\n Cash = 'cash',\r\n LongGainers = 'longGainers',\r\n LongLosers = 'longLosers',\r\n ShortGainers = 'shortGainers',\r\n ShortLosers = 'shortLosers',\r\n}\r\n\r\nconst industryLabelKey = 'description'\r\n\r\nconst groupPrefix = {\r\n long: 'Long',\r\n short: 'Short',\r\n}\r\n\r\nconst groupLabel = {\r\n gainers: 'Gainers',\r\n losers: 'Losers',\r\n}\r\n\r\nexport const LOCAL_STORAGE_KEY = 'portfolio-map'\r\n\r\ntype PortfolioMapData = { [key in PortfolioDataKey]: MapDataNode[] }\r\n\r\nexport interface PortfolioSavedSettings {\r\n tableView: PortfolioTableView\r\n showMap: boolean\r\n showIndustries: boolean\r\n subtype: MapSubtypeId\r\n tableOrder: string\r\n}\r\n\r\nexport const DEFAULT_SETTINGS: PortfolioSavedSettings = {\r\n tableView: PortfolioTableView.Ticker,\r\n showMap: true,\r\n showIndustries: true,\r\n subtype: MapSubtypeId.PortfolioGainPct,\r\n tableOrder: columnMap[ColumnId.Order].urlSort,\r\n}\r\n\r\n/**\r\n * Map param in query/local storage is string but we need a boolean\r\n */\r\nexport function parseBoolFromValue(value?: string | null) {\r\n try {\r\n if (value) {\r\n return Boolean(JSON.parse(value))\r\n }\r\n } catch {\r\n return false\r\n }\r\n}\r\n\r\nexport function getMapSettingFromLocalStorage() {\r\n const savedSettings = storage.getValue(LOCAL_STORAGE_KEY, DEFAULT_SETTINGS)\r\n\r\n return { ...DEFAULT_SETTINGS, ...savedSettings }\r\n}\r\n\r\nexport function saveMapSettingToLocalStorage(\r\n key: keyof PortfolioSavedSettings,\r\n value: PortfolioSavedSettings[typeof key]\r\n) {\r\n storage.setValue(\r\n LOCAL_STORAGE_KEY,\r\n (prevState) => {\r\n const itemToStore = { ...prevState, [key]: value }\r\n // TODO: remove - temporary code to remove removed property from settings\r\n if ('customTickersOrder' in itemToStore) delete itemToStore.customTickersOrder\r\n return itemToStore\r\n },\r\n DEFAULT_SETTINGS\r\n )\r\n}\r\n\r\nconst SUMMARY_DEFAULT: PortfolioSummary = {\r\n tickers: 0,\r\n transactions: 0,\r\n shares: 0,\r\n lastChangePct: 0,\r\n valuePaid: 0,\r\n valueMarket: 0,\r\n valueMarketStocks: 0,\r\n valueMarketStocksPrev: 0,\r\n gainMarketUsd: 0,\r\n gainMarketPct: 0,\r\n gainTodayUsd: 0,\r\n}\r\n\r\nexport function getSummary(data: PortfolioGroup[]) {\r\n let allTransactions = 0\r\n let nonWatchTransactions = 0\r\n\r\n const computed = data.reduce((prev, current) => {\r\n allTransactions += current.transactions.length || 1\r\n nonWatchTransactions += current.transactions.length\r\n\r\n if (current.isDelisted) return prev\r\n\r\n const valueMarket = prev.valueMarket + current.valueMarket\r\n const valueMarketStocks =\r\n prev.valueMarketStocks + (current.type === PortfolioSymbolType.Cash ? 0 : current.valueMarket)\r\n const valueMarketStocksPrev =\r\n prev.valueMarketStocksPrev + (current.type === PortfolioSymbolType.Cash ? 0 : current.valueMarketPrev)\r\n const valuePaid = prev.valuePaid + current.valuePaid\r\n const lastChangePct = valueMarketStocksPrev <= 0 ? 0 : (valueMarketStocks / valueMarketStocksPrev - 1) * 100\r\n const gainMarketPct = valuePaid <= 0 ? 0 : (valueMarketStocks / valuePaid - 1) * 100\r\n\r\n return {\r\n ...prev,\r\n valueMarket: valueMarket,\r\n valueMarketStocks,\r\n valueMarketStocksPrev,\r\n lastChangePct,\r\n gainMarketPct,\r\n shares: prev.shares + current.shares,\r\n valuePaid: prev.valuePaid + current.valuePaid,\r\n gainMarketUsd: prev.gainMarketUsd + current.gainMarketUsd,\r\n gainTodayUsd: prev.gainTodayUsd + current.gainTodayUsd,\r\n }\r\n }, SUMMARY_DEFAULT)\r\n\r\n return {\r\n ...computed,\r\n transactions: nonWatchTransactions,\r\n allTransactions,\r\n tickers: data.length,\r\n }\r\n}\r\n\r\nfunction isMapTransaction(entry: PortfolioEntryTransaction): entry is PortfolioTransactionStake {\r\n return entry.shares > 0 || entry.type === PortfolioSymbolType.Cash\r\n}\r\n\r\n/**\r\n * Goes through all the items and merges them together so that we don’t end up\r\n * with multiple map tiles with same ticker & transaction\r\n */\r\nexport function flattenAndDedupe(data: PortfolioGroup[]) {\r\n const result: PortfolioMapEntry[] = []\r\n\r\n data.forEach((group) => {\r\n group.transactions.forEach((entry) => {\r\n if (!isMapTransaction(entry)) return\r\n\r\n const previouslyAdded = result.findIndex(\r\n (prev) =>\r\n prev.ticker === entry.ticker &&\r\n (entry.type === PortfolioSymbolType.Cash ? true : prev.transaction === entry.transaction)\r\n )\r\n\r\n if (previouslyAdded < 0) {\r\n const newEntry = { ...group, ...entry, transactions: undefined }\r\n delete newEntry.transactions\r\n result.push(newEntry)\r\n } else {\r\n const prevEntry = result[previouslyAdded]\r\n const valueMarket = prevEntry.valueMarket + entry.valueMarket\r\n const valuePaid = prevEntry.valuePaid + entry.valuePaid\r\n\r\n result[previouslyAdded] = {\r\n ...prevEntry,\r\n valuePaid,\r\n valueMarket,\r\n shares: prevEntry.shares + entry.shares,\r\n valueMarketPrev: prevEntry.valueMarketPrev + entry.valueMarketPrev,\r\n gainMarketUsd: prevEntry.gainMarketUsd + entry.gainMarketUsd,\r\n gainMarketPct: (valueMarket / valuePaid - 1) * 100,\r\n gainTodayUsd: prevEntry.gainTodayUsd + entry.gainTodayUsd,\r\n }\r\n }\r\n })\r\n })\r\n\r\n return Object.values(result)\r\n}\r\n\r\n/**\r\n * Checks if item is loser/gainer and returns the appropriate flag\r\n */\r\nfunction getEntryGroup(type: PortfolioSymbolType, gain: number, transaction: PortfolioTransaction) {\r\n if (type === PortfolioSymbolType.Cash) return PortfolioDataKey.Cash\r\n\r\n switch (transaction) {\r\n case PortfolioTransaction.Short: {\r\n return gain > 0 ? PortfolioDataKey.ShortGainers : PortfolioDataKey.ShortLosers\r\n }\r\n\r\n default:\r\n case PortfolioTransaction.Buy: {\r\n return gain >= 0 ? PortfolioDataKey.LongGainers : PortfolioDataKey.LongLosers\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Creates industry node with children\r\n */\r\nexport function getIndustries(industries: Record) {\r\n return Object.keys(industries).map((industry) => ({\r\n name: industry,\r\n children: industries[industry],\r\n }))\r\n}\r\n\r\n/**\r\n * Group items by key\r\n * @see https://stackoverflow.com/a/47385953\r\n */\r\nexport function groupByKey(list: Item[], key: keyof Item) {\r\n return list.reduce>((hash, obj) => {\r\n if (obj[key] === undefined) return hash\r\n return Object.assign(hash, { [obj[key] as string]: (hash[obj[key] as string] || []).concat(obj) })\r\n }, {})\r\n}\r\n\r\n/**\r\n * Creates long/short gainers/losers group with all the children, optionally grouping them by industry\r\n */\r\nfunction createGroup(key: PortfolioDataKey, data: PortfolioMapData, groupByIndustry = true) {\r\n let groupName = ''\r\n switch (key) {\r\n case PortfolioDataKey.Cash:\r\n groupName = 'Other'\r\n break\r\n default:\r\n const isLong = [PortfolioDataKey.LongGainers, PortfolioDataKey.LongLosers].includes(key)\r\n const isGainer = [PortfolioDataKey.LongGainers, PortfolioDataKey.ShortGainers].includes(key)\r\n const longPrefix = data.shortGainers.length || data.shortLosers.length ? `${groupPrefix.long}: ` : ''\r\n const shortPrefix = data.longGainers.length || data.longLosers.length ? `${groupPrefix.short}: ` : ''\r\n groupName = `${isLong ? longPrefix : shortPrefix}${isGainer ? groupLabel.gainers : groupLabel.losers}`\r\n break\r\n }\r\n\r\n if (groupByIndustry) {\r\n let children: Array<{ name: string; children: MapDataNode[] }> = []\r\n if (key === PortfolioDataKey.Cash && data[key].length) children = [{ name: 'Cash', children: data[key] }]\r\n else children = getIndustries(groupByKey(data[key], industryLabelKey))\r\n return { name: groupName, children }\r\n }\r\n\r\n return { name: groupName, children: data[key] }\r\n}\r\n\r\nexport function getPerfText(node: PortfolioMapEntry, subtype: MapSubtypeId) {\r\n switch (subtype) {\r\n case MapSubtypeId.PortfolioGainPct:\r\n return node.gainMarketPct\r\n case MapSubtypeId.PortfolioGainUsd:\r\n return node.gainMarketUsd\r\n case MapSubtypeId.PortfolioChangePct:\r\n return node.lastChangePct\r\n case MapSubtypeId.PortfolioChangeUsd:\r\n return node.gainTodayUsd\r\n }\r\n}\r\n\r\nfunction getPerfForTicker | any[]>(\r\n ticker: string,\r\n list?: ListType,\r\n group?: PortfolioDataKey\r\n) {\r\n if (Array.isArray(list)) {\r\n return list.find((item) => item.name === ticker && item.data?.group === group)?.perf\r\n }\r\n\r\n return list?.[ticker]\r\n}\r\n\r\n/**\r\n * Returns data for the map. This data is deduped and split into gainers/losers & industries\r\n */\r\nexport function getMapData({\r\n data,\r\n perfData,\r\n size,\r\n subtype,\r\n groupByIndustry,\r\n}: {\r\n data?: PortfolioGroup[]\r\n perfData?: PerfData\r\n size: PortfolioMapSizeKey\r\n subtype: MapSubtypeId\r\n groupByIndustry?: boolean\r\n}) {\r\n if (!data) return { hasData: false }\r\n\r\n const dedupedData = flattenAndDedupe(data)\r\n\r\n const isPortfolioSubtype = subtype.startsWith('portfolio')\r\n const parsedData = dedupedData.reduce(\r\n (prev: PortfolioMapData, current) => {\r\n const group = getEntryGroup(current.type, current.gainMarketPct / 100, current.transaction)\r\n // The map can’t display negative values so we need to Math.abs\r\n let value = Math.abs(size === PortfolioMapSizeKey.MarketValue ? current.valueMarket : current.gainMarketUsd)\r\n if (!Number.isFinite(value)) value = 0\r\n\r\n const subtypePerf = getPerfText(current, subtype)\r\n const perfText = isPortfolioSubtype ? subtypePerf : getPerfForTicker(current.ticker, perfData?.nodes, group)\r\n\r\n const entry = {\r\n name: current.ticker,\r\n value,\r\n perf: current.type === PortfolioSymbolType.Cash ? null : (perfText ?? subtypePerf),\r\n additional:\r\n current.type === PortfolioSymbolType.Cash\r\n ? formatNumber(current.valueMarket)\r\n : getPerfForTicker(current.ticker, perfData?.additional, group),\r\n description: current.industry,\r\n data: { perfWeek: current.perfWeek, group },\r\n } as MapDataNode\r\n\r\n if (value > 0) {\r\n return { ...prev, [group]: [...prev[group], entry] }\r\n }\r\n\r\n return prev\r\n },\r\n {\r\n [PortfolioDataKey.Cash]: [],\r\n [PortfolioDataKey.LongGainers]: [],\r\n [PortfolioDataKey.LongLosers]: [],\r\n [PortfolioDataKey.ShortGainers]: [],\r\n [PortfolioDataKey.ShortLosers]: [],\r\n }\r\n )\r\n\r\n return {\r\n dataHash: new Date().getTime().toString(),\r\n hasData: Object.values(parsedData).some((arr) => arr.length > 0),\r\n data: {\r\n name: 'Portfolio',\r\n children: Object.keys(parsedData)\r\n .map((key) => createGroup(key as PortfolioDataKey, parsedData, groupByIndustry))\r\n .filter((category) => category.children.length),\r\n } as MapDataRoot,\r\n }\r\n}\r\n\r\nexport function parsePortfolioQuery(params: URLSearchParams, defaultPortfolioId: number) {\r\n const currentPortfolio = Number.parseInt(params.get(PortfolioQuery.PortfolioId) ?? '')\r\n const portfolioId =\r\n Number.isFinite(currentPortfolio) && currentPortfolio !== 0 ? currentPortfolio : defaultPortfolioId\r\n\r\n return {\r\n portfolioId,\r\n params: Object.fromEntries(params.entries()) as Record, // Re-export the original query as key/val\r\n view: params.get(PortfolioQuery.View) ?? PortfolioView.View,\r\n tableView: (params.get(PortfolioQuery.TableView) as PortfolioTableView) ?? undefined,\r\n map: parseBoolFromValue(params.get(PortfolioQuery.Map)) ?? getMapSettingFromLocalStorage().showMap,\r\n size: (params.get(PortfolioQuery.Size) ?? PortfolioMapSizeKey.MarketValue) as PortfolioMapSizeKey,\r\n subtype: (params.get(PortfolioQuery.Subtype) ?? getMapSettingFromLocalStorage().subtype) as MapSubtypeId,\r\n group: params.get(PortfolioQuery.Group)?.toUpperCase().split(',') ?? [],\r\n tickers: params.get(PortfolioQuery.Tickers)?.split(',') ?? [],\r\n }\r\n}\r\n\r\nexport function getColumnsByKeys(keys: ColumnId[]) {\r\n return keys.map((key) => columnMap[key])\r\n}\r\n\r\nexport function getFormattedDate(format = PORTFOLIO_DATE_FORMAT_DATA) {\r\n return `${dateFns.format(new Date(), format)}`\r\n}\r\n\r\nexport function validateEditRow(\r\n state: Partial,\r\n dateFormat = PORTFOLIO_DATE_FORMAT_DATA,\r\n checkFormat = true\r\n) {\r\n const formErrors: FormErrors = {}\r\n\r\n if (state.ticker !== undefined && state.ticker.trim().length === 0) {\r\n formErrors.ticker = true\r\n }\r\n\r\n if (\r\n state.transaction !== PortfolioTransaction.Watch &&\r\n (!state.date || !dateFns.isValid(parseInputAsDate({ input: state.date, format: dateFormat, checkFormat })))\r\n ) {\r\n formErrors.date = true\r\n }\r\n\r\n if (\r\n state.transaction !== PortfolioTransaction.Watch &&\r\n (state.shares === undefined || isNaN(state.shares) || state.shares < 0)\r\n ) {\r\n formErrors.shares = true\r\n }\r\n\r\n if (\r\n state.transaction !== PortfolioTransaction.Watch &&\r\n (state.price === undefined || isNaN(state.price) || state.price <= 0)\r\n ) {\r\n formErrors.price = true\r\n }\r\n\r\n return { isValid: Object.keys(formErrors).length === 0, errors: formErrors }\r\n}\r\n\r\nexport function parseInputAsDate({\r\n input,\r\n format = PORTFOLIO_DATE_FORMAT_VIEW,\r\n checkFormat = true,\r\n}: {\r\n input: Date | string\r\n format?: string\r\n checkFormat?: boolean\r\n}) {\r\n if (checkFormat && typeof input === 'string' && input.length !== format.length) {\r\n return new Date('Invalid Date')\r\n }\r\n if (input instanceof Date && dateFns.isValid(input)) return input\r\n\r\n return dateFns.parse(input.toString(), format, new Date())\r\n}\r\n\r\nexport const FORM_ENTRY_KEYS = Object.keys(EMPTY_FORM_ENTRY)\r\n\r\nfunction appendRowToFormData(serializer: URLSearchParams, row: Partial, index: number) {\r\n FORM_ENTRY_KEYS.forEach((key) => serializer.append(`${key}${index}`, `${row[key as keyof PortfolioEntryBase] ?? ''}`))\r\n}\r\n\r\nexport function getBulkEditData(\r\n data: Array,\r\n options: { resetCash?: boolean } = {}\r\n): Record {\r\n return data.reduce(\r\n (acc, row) => {\r\n const id = getUuid()\r\n const transactions =\r\n row.transactions.length === 0 || (options.resetCash && getSymbolType(row.ticker) === PortfolioSymbolType.Cash)\r\n ? [getNewTransaction(row.ticker, PortfolioTransaction.Watch)]\r\n : row.transactions.map((transaction) => ({\r\n ...transaction,\r\n uuid: transaction.id ? `${transaction.id}` : getUuid(),\r\n }))\r\n return {\r\n ...acc,\r\n [id]: { id, ticker: row.ticker, transactions },\r\n }\r\n },\r\n {} as Record\r\n )\r\n}\r\n\r\nexport function serializeFormData<\r\n EntryType extends { ticker: string; transactions?: Array> },\r\n>(entries: EntryType[]) {\r\n const serializer = new URLSearchParams()\r\n entries\r\n .flatMap((entry) => {\r\n if (!entry.transactions || entry.transactions?.length === 0) {\r\n return getNewTransaction(entry.ticker, PortfolioTransaction.Watch)\r\n }\r\n\r\n return entry.transactions\r\n })\r\n .forEach((entry, index) => {\r\n if (entry.ticker.length) appendRowToFormData(serializer, entry, index)\r\n })\r\n\r\n return serializer\r\n}\r\n\r\nexport async function validateFormData(data: PortfolioFormGroup[], validateFields = true) {\r\n if (data.length === 0) return { isValid: true, errors: {} }\r\n\r\n let isValid = true\r\n const errors: Record = {}\r\n\r\n try {\r\n const tickers = data.map((row) => {\r\n const ticker = getSanitizedTicker(row.ticker.trim(), false, [PORTFOLIO_CASH_SYMBOL])\r\n return ticker.length ? ticker : api.QUOTE_INVALID_TICKER_REQUEST\r\n })\r\n const validatedTickers = await api.validateTickers(tickers)\r\n\r\n isValid = tickers.length === validatedTickers.length\r\n\r\n // Validate fields\r\n if (validateFields) {\r\n data.forEach((row, index) => {\r\n const validationResult = row.transactions.map((transaction) =>\r\n validateEditRow(transaction, PORTFOLIO_DATE_FORMAT_DATA, false)\r\n )\r\n\r\n const hasInvalidEntries = validationResult.some((result) => !result.isValid)\r\n const isInvalidTicker = validatedTickers[index] !== true\r\n\r\n if (hasInvalidEntries || isInvalidTicker) {\r\n isValid = false\r\n }\r\n\r\n errors[row.id] = validationResult.map((result) => ({ ...result.errors, ticker: isInvalidTicker }))\r\n })\r\n }\r\n } catch {\r\n return {\r\n isValid: false,\r\n errors: {},\r\n }\r\n }\r\n\r\n return { isValid, errors }\r\n}\r\n\r\nexport function getNewTransaction(ticker: string, transaction = PortfolioTransaction.Buy): PortfolioFormEntry {\r\n const symbolType = getSymbolType(ticker)\r\n const allowedTransactions = getTransactionsForSymbolType(symbolType)\r\n\r\n return {\r\n ...EMPTY_FORM_ENTRY,\r\n uuid: getUuid() as string,\r\n ticker,\r\n type: getSymbolType(ticker),\r\n date: getFormattedDate(PORTFOLIO_DATE_FORMAT_DATA),\r\n transaction: [PortfolioTransaction.Watch, ...allowedTransactions].includes(transaction)\r\n ? transaction\r\n : allowedTransactions[0],\r\n shares: transaction === PortfolioTransaction.Watch || symbolType === PortfolioSymbolType.Cash ? 0 : undefined,\r\n price: transaction === PortfolioTransaction.Watch ? 0 : undefined,\r\n }\r\n}\r\n\r\nexport function getPortfolioInitData() {\r\n let returnData = { isInitData: false, initData: api.EMPTY_RESPONSE }\r\n const initDataElement = document.getElementById('portfolio-init-data')\r\n if (initDataElement) {\r\n const initData = parseInitData('portfolio-init-data')\r\n initDataElement.remove()\r\n returnData = { isInitData: !!initData, initData: initData ?? api.EMPTY_RESPONSE }\r\n }\r\n return returnData\r\n}\r\n\r\nconst EMPTY_TRANSACTION = { transaction: PortfolioTransaction.Watch, index: 0, price: 0 }\r\n\r\nexport function getTradesStructureData(portfolioData: PortfolioGroup[]) {\r\n return portfolioData\r\n .flatMap((ticker) => {\r\n const transactions = [...ticker.transactions]\r\n if (transactions.length === 0) {\r\n transactions.push(EMPTY_TRANSACTION as unknown as PortfolioEntryTransaction)\r\n }\r\n return transactions.map((transaction) => {\r\n const obj = { ...ticker } as Omit & {\r\n transactions?: PortfolioEntryTransaction[]\r\n }\r\n delete obj.transactions\r\n return { ...obj, ...transaction }\r\n })\r\n })\r\n .sort((a, b) => a.id - b.id)\r\n}\r\n\r\nexport function getSymbolType(symbol?: string) {\r\n if (symbol?.toUpperCase() === PORTFOLIO_CASH_SYMBOL) return PortfolioSymbolType.Cash\r\n\r\n return PortfolioSymbolType.Stock\r\n}\r\n\r\nexport function isStockTransaction(transaction: PortfolioTransaction) {\r\n return STOCK_TRANSACTIONS.includes(transaction)\r\n}\r\n\r\nexport function isCashTransaction(transaction: PortfolioTransaction) {\r\n return CASH_TRANSACTIONS.includes(transaction)\r\n}\r\n\r\nexport function getTransactionsForSymbolType(symbolType: PortfolioSymbolType) {\r\n switch (symbolType) {\r\n case PortfolioSymbolType.Cash:\r\n return CASH_TRANSACTIONS\r\n default:\r\n return STOCK_TRANSACTIONS\r\n }\r\n}\r\n\r\nexport function getPortfolioRefreshInterval() {\r\n return getMapsRefreshInterval({\r\n base: PORTFOLIO_REFRESH_INTERVAL_ELITE,\r\n free: PORTFOLIO_REFRESH_INTERVAL_FREE,\r\n })\r\n}\r\n","import { EventEmitter } from 'events'\r\nimport * as React from 'react'\r\n\r\nlet emitter: EventEmitter | undefined\r\n\r\n/**\r\n * Get the emitter which is used to sync components across the page, subscibe to\r\n * changes and attach event which handles changes across windows\r\n */\r\nexport function subscribeToChanges(\r\n key: string,\r\n defaultValue: ValueType,\r\n changeCallback?: (value: React.SetStateAction) => void\r\n) {\r\n if (!emitter) emitter = new EventEmitter()\r\n\r\n const onChange = (value: React.SetStateAction) => {\r\n const newValue = value ?? getValue(key, defaultValue)\r\n setValue(key, newValue, defaultValue, false)\r\n changeCallback?.(newValue)\r\n }\r\n\r\n const onStorageChange = (ev: StorageEvent) => {\r\n if (ev.key === key) {\r\n try {\r\n const value = ev.newValue ? JSON.parse(ev.newValue) : null\r\n onChange(value ?? defaultValue)\r\n } catch {\r\n onChange(defaultValue)\r\n }\r\n }\r\n }\r\n\r\n emitter.addListener(key, onChange)\r\n window.addEventListener('storage', onStorageChange)\r\n\r\n return {\r\n emitter,\r\n unsubscribe: () => {\r\n emitter?.removeListener(key, onChange)\r\n window.removeEventListener('storage', onStorageChange)\r\n },\r\n }\r\n}\r\n\r\n/**\r\n * Get value from local storage or fall back to `defaultValue`\r\n */\r\nexport function getValue(key: string, defaultValue: ValueType): ValueType {\r\n try {\r\n const value = localStorage.getItem(key)\r\n const parsedValue = value ? JSON.parse(value) : null\r\n return parsedValue ?? defaultValue\r\n } catch {\r\n return defaultValue\r\n }\r\n}\r\n\r\n/**\r\n * Set value to local storage. Optionally emits the change to all other components\r\n * which are subscribed with the same `key`\r\n */\r\nexport function setValue(\r\n key: string,\r\n valueGetter: React.SetStateAction,\r\n defaultValue: ValueType,\r\n emit = true\r\n) {\r\n try {\r\n const state = getValue(key, defaultValue)\r\n const valueToStore = valueGetter instanceof Function ? valueGetter(state) : valueGetter\r\n\r\n localStorage.setItem(key, JSON.stringify(valueToStore))\r\n if (emit) emitter?.emit(key, valueToStore)\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Removes value from local storage. Optionally emits the change to all other components\r\n * which are subscribed with the same `key`\r\n */\r\nexport function removeValue(key: string, emit = true) {\r\n try {\r\n localStorage.removeItem(key)\r\n if (emit) emitter?.emit(key, undefined)\r\n } catch {}\r\n}\r\n\r\n/**\r\n * Helper function to migrate old value type to new one (eg. boolean to object)\r\n */\r\nexport function migrateValue(\r\n key: string,\r\n /**\r\n * The migrate function might get called multiple times on the page, so `oldValue` in the callback\r\n * can actually be the already migrated value. Make sure to add a condition to only migrate once.\r\n */\r\n transformValue: NewValue | ((oldValue: PrevValue | NewValue) => NewValue),\r\n defaultValue: NewValue\r\n) {\r\n try {\r\n const oldValue = getValue(key, undefined)\r\n if (typeof oldValue === 'undefined') return\r\n const migratedValue = transformValue instanceof Function ? transformValue(oldValue) : transformValue\r\n setValue(key, migratedValue, defaultValue, false) // don’t emit to other components\r\n } catch {}\r\n}\r\n","/**\r\n * Ignore any subsequent callback calls until the previous callback has finished\r\n */\r\n\r\nexport function waitForPreviousPromise(callback: () => void | Promise) {\r\n let callbackPromise: Promise | void | null = null\r\n\r\n return async function () {\r\n if (callbackPromise !== null) return\r\n\r\n callbackPromise = callback()\r\n await callbackPromise\r\n callbackPromise = null\r\n }\r\n}\r\n"],"names":["module","exports","white","black","inherit","transparent","current","finviz","blue","gray","red","orange","amber","tangerine","yellow","brightYellow","lime","green","emerald","teal","violet","purple","pink","EXPANDED_MAP_BODY_CLASSS","FALLBACK_PERF_RESPONSE","nodes","additional","subtype","MapSubtypeId","DayPerf","hash","MAP_SUBTYPES_INTRADAY_BY_ID","IntradayPerf1m","value","label","scaleId","ScaleId","IntradayReduced","tooltip","countIndustryPerf","countSectorPerf","IntradayPerf2m","IntradayPerf3m","IntradayPerf5m","IntradayPerf10m","IntradayPerf15m","IntradayPerf30m","IntradayPerf1h","IntradayPerf2h","IntradayPerf4h","IntradayPerfAH","MAP_SUBTYPES_INTERDAY_BY_ID","WeekPerf","MonthPerf","ThreeMonthPerf","SixMonthPerf","YearPerf","YearToDatePerf","MAP_SUBTYPES_GENERAL","RelativeVolume","PriceToEarnings","ForwardPriceToEearnings","PriceEarningsToGrowth","PriceToSellsRatio","PriceToBookRatio","DividendYield","EPSGrowth5y","FloatShort","AnalystRecommendation","EarningsPerf","EarningsDate","MAP_SUBTYPE_DAY_PERF","MAP_SUBTYPE_MANAGERS_FUNDS","ManagersAndFunds","PercentHundred","MAP_SUBTYPES_INTRADAY","items","Object","values","MAP_SUBTYPES_INTERDAY","MAP_SUBTYPES_TIMEFRAMES","FinvizSettings","hasUserPremium","href","reloadDocument","MAP_SUBTYPES_COMPANIES","MAP_SUBTYPES_ETF","MAP_TYPES","name","pageTitle","description","type","MapTypeId","Sector","subtypes","World","SectorFull","nameShort","ETF","MAP_TYPE_SCREENER","Screener","MAP_TYPE_ETF_HOLDINGS_WIDGET","ETFHoldings","MAP_TYPE_MANAGERS_FUNDS_WIDGET","MAP_MIN_WIDTH","MAP_MIN_HEIGHT","SECTOR_MIN_HEIGHT","LEGEND_HEIGHT","LARGE_MAP_HEIGHT_RATIO","SMALL_MAP_GEO_HEIGHT_RATIO","SMALL_MAP_HEIGHT_RATIO","LARGE_NODE_SIZE","dx","dy","LARGE_NODE_MIN_HEIGHT","ORDER_SP500","Technology","Financial","Healthcare","Industrials","Energy","Utilities","Semiconductors","ORDER_SP500_SMALL","ORDER_SEC_ALL","ORDER_ETF","US","Global","International","Commodity","Strategy","Forex","ORDER_SCREENER","ORDER_WORLD","Ireland","Spain","France","Belgium","Netherlands","Switzerland","China","Japan","India","Taiwan","Panama","Peru","Chile","Colombia","Argentina","Brazil","WORLD_INDUSTRIES","x","y","countries","scaleMinMax","_5","_10","_15","_20","_25","_relvol","_pe","_fpe","_peg","_ps","_pb","_div","_eps5y","_short","_rec","_earndate","_portfolioPct","_portfolioUsd","_percentHundred","scaleStepFormat","Settings","padding","top","right","bottom","left","background","tailwindColors","sector","border","header","color","height","fontSize","fontWeight","margin","industry","hover","scaleFontSizes","fontSizePadding","fontSizePairs","SettingsSmall","SettingsSmallDark","SettingsSmallGeo","SettingsSmallGeoDark","SettingsScreener","SettingsScreenerDark","LayoutGenerator","isNodeHeaderVisible","node","settings","_node$dx","_node$dy","deltaX","Math","round","x1","x0","deltaY","y1","y0","isLargeNode","constants","showHeader","constructor","width","isSmall","arguments","length","undefined","_defineProperty","arr","filter","_node$children","isVisible","this","isNodeVisible","children","filterVisibleNodes","d","depth","NodeDepth","Root","Industry","smallIndustryPadding","smallIndustryGeoPadding","a","b","order","heightB","Number","isFinite","minSectorHeight","hasOwnProperty","data","d3","sum","sort","_getHierarchySort","paddingFn","_getPaddingGeo","_getPadding","size","tile","ratio","paddingTop","paddingRight","paddingBottom","paddingLeft","industryIndex","industryX","industryY","industryWidth","industryHeight","countriesRoots","_getIndustriesRoots","root","_rootsToRoot","hierarchy","_getHierarchy","treemapNodes","_getTreemap","treemap","each","concat","descendants","getExportData","mapRoot","_this$layout","industries","layout","find","stringified","JSON","stringify","key","parse","getLayoutData","sectors","getLayout","_this$layout2","_generateSP500","_generateFull","Portfolio","_generateScreener","_generateSectorSizeOrdered","_generateWorld","_generateETF","forEach","_transformNode","parent","push","assign","perf","roots","duplicateTickers","some","i","_getSectorsRoots","s","_generateLayout","recountSectors","treemapHeight","calculateHeight","recalculateHeight","financialSector","technologySector","financialHeight","technologyHeight","eachAfter","consumerDefensiveSector","consumerCyclicalSector","consumerDefensiveWidth","consumerCyclicalWidth","consumerCyclical","consumerDefensive","_LayoutGenerator","getSizeRatio","getOffset","e","rect","currentTarget","getBoundingClientRect","offsetX","clientX","offsetY","clientY","getIsSmall","URLSearchParams","window","location","search","get","getSettingsForMapType","restoreDataKeys","perfData","map","row","newRow","getMapData","mapData","_mapData$children","_sector$children","_industry$children","company","splitData","getIndexMapData","hasRedesignEnabled","getMapBaseData","mapType","getRatioSizeForWidth","mapWidth","max","getSize","element","canvasWrapper","document","getElementById","query","has","parsedRatio","parseFloat","body","classList","contains","wrapper","style","removeProperty","clientWidth","elementHeight","innerHeight","newWidth","calculateWidth","maxWidth","getSizeForExpandedMap","clientHeight","scrollbarWidth","innerWidth","documentElement","getSizeRatioBasedMap","getDefaultZoomLevels","isMobile","test","navigator","userAgent","parseInitDataAsPerf","version","MAX_SPARKLINES","HOVER_TOP_ROW_HEIGHT","HOVER_BORDER_WIDTH","ROW_HEIGHT","ROW_HEIGHT_SMALL","ROW_HEIGHT_BREAKPOINT","getVisibleTooltipNodes","industryTickers","rowHeight","visibleRows","floor","slice","min","onNodeClick","_ref","open","set","ScreenerQuery","View","ScreenerView","Overview","toString","tickers","flatMap","Tickers","join","id","replace","toLowerCase","Filters","MapsPollingIntervalInMs","getMapsRefreshInterval","base","Elite","reduced","Reduced","free","Free","customRefreshInterval","isStockFastRefreshAvailable","decodeQueryString","vars","substring","split","obj","pair","delimiterPos","indexOf","decodeURIComponent","encodeQueryString","whitelistedValues","keys","reduce","prev","includes","encodeURIComponent","ScreenerFilter","ScreenerAddtionalQuery","eventListenerRegister","el","eventName","handler","addEventListener","removeEventListener","textContent","innerText","ScreenerRenderCustomModal","select","getAttribute","customWrapper","display","input","options","_select$getAttribute$","_select$getAttribute","result","len","option","j","optionEl","ScreenerGetOptionsList","DATE_REGEX","getIsOptionDateRange","from","to","isValidFromDate","isValidToDate","isNaN","Date","getTime","getInitialDateFromSelectedValues","selectedValues","initialDate","date","dateRangeToFilterString","getQueryForView","view","_query$get$match","_query$get","allowedParams","baseQuery","allowList","Array","delete","originalView","match","parseScreenerFilters","filtersString","fromEntries","f","lastUnderscore","lastIndexOf","stringifyScreenerFilters","filters","entries","_ref2","String","_ref3","rangesToFilter","ranges","rangeSuffixes","delimiter","rangeDelimiter","range","index","_rangeSuffixes$index","rangeStr","currentFilter","DECAY_FACTOR","getCurrentDateInMs","valueOf","getIsDocumentVisible","visibilityState","hidden","notifyOnVisibilityChange","callback","promisifiedCallback","waitForPreviousPromise","unsubscribe","getInterval","interval","intervalCallbackOnWindowVisible","initOptions","_initOptions$decayFac","_initOptions$maxDecay","decay","decayFactor","maxDecayInterval","refreshPromise","nextRefresh","refreshTimeout","async","refresh","currentDateMs","setTimeout","handleVisibilityChange","clearTimeout","decayedInterval","maxTimeout","decayRefreshInterval","PREMARKET_AFTERMARKET_HOURS","MARKET_START","hours","minutes","MARKET_END","hasPremarket","hasAftermarket","bufferMinutes","getMinutes","getDate","dayOfWeek","getDay","currentDayMinutes","getHours","premarketMinutes","aftermarketMinutes","isWeekend","isOpen","isClosed","formatDateToStringUS","toLocaleDateString","day","month","year","parseInitData","elementId","initDataElement","Sentry","captureException","getSidebarFromCookie","chartsUrl","getCookie","decodedCookie","sidebar","useDateInputWithPickerValue","inputValue","dataDateFormat","viewDateFormat","React","parsedDate","parseInputAsDate","format","checkFormat","dateFns","picker","getDateInputWithPickerValue","DEFAULT_DATE_FORMAT","DateInputWithPicker","trigger","minDate","onChange","hasError","onErrorChange","onIsInteractingChange","pickerState","usePopoverState","isPickerMounted","useState","tooltipState","useTooltipState","placement","isTooltipMounted","WrapperComponent","TooltipTrigger","wrapperProps","state","tabIndex","hideOnBlur","showOnHover","isInteractingWithDateInput","onDateChange","dateValue","hide","handleBlur","_value$input","_jsxs","_jsx","StatelessDatePicker","ev","onKeyDown","onBlur","onFocus","show","Tooltip","hideOnHoverOutside","className","gutter","toUpperCase","MenuGroup","ref","virtualized","hasBorder","props","Ariakit","classNames","getDefaultTheme","isHovered","OptionButton","_props$active","_props$size","_props$leftContent","subtitle","ariaSelected","dataActiveItem","rounding","activeTheme","theme","isMultiSelect","isSelected","defaultTheme","iconTheme","Button","align","ButtonPadding","regular","contentClass","active","leftContent","isValidIconName","Icon","rightContent","RedGreenText","rightClass","hasValue","showArrow","classnames","RedGreenMultiline","child","ShadowPosition","TableScrollShadow","side","position","TableStickyColumnWrapper","shouldScrollToEnd","cropFillerClassName","hasHeaderShadow","setElementRef","useElementMeasure","tableWrapperRef","shadowPosition","setShadowPosition","none","shadowDimensions","setShadowDimensions","tableShadowMargin","tableWrapperElement","onScroll","throttle","tableWrapperElementScrollLeft","ceil","scrollLeft","newShadowPosition","hasScrollSpaceToLeft","hasScrollSpaceToRight","offsetWidth","scrollWidth","leftAndRight","scrollTo","_financialsTable$quer","_financialsTable$quer2","_firstColum$getBoundi","_financialsTable$clie","financialsTable","querySelector","headHeight","firstColum","firstColumnWidth","topOffset","radiusCropFillerStyle","shadowLeftStyle","shadowRightStyle","Table","_props$cellPadding","isFullWidth","cellPadding","TableHead","TableBody","spacing","TableFooter","TABLE_STICKY_CELL_CLASS_NAME","TableAlign","TableCell","isFirst","isLast","Left","hasPadding","hasLeading","isSticky","Center","Right","TABLE_HEADER_DEFAULT_ELEMENT","TableSortIndicator","isActive","direction","invisible","TableHeader","as","asComponent","hasHover","componentToRender","disabled","TableHeaderSortable","isDisabled","TableRow","isHoverable","isRounded","useTableSort","columns","defaultSort","valueGetter","setSort","getDefaultSort","isMountedRef","changeSort","newSort","prevSort","_prevSort$column","column","SortDirection","Ascending","useSortData","sortBy","useTableSortWithAutoupdate","tableOrder","sortedData","previousTableOrder","usePrevious","useEffect","sortName","sortDirection","startsWith","Descending","useTableSortWithUrl","_searchParams$get","urlPersistKey","idKey","searchParams","setSearchParams","useSearchParams","defaultSortRef","getDefaultSortFromUrl","changeSortState","additionalUrlParams","newSearchParams","saveSortToUrl","encodeSort","preventScrollReset","_columns$find","isSortByShape","isSortableColumnShape","foundColumn","isDesc","queryParam","sortedColumn","sortDir","_newParams$get","newParams","previousOrder","isDescOrder","GroupTheme","ButtonGroup","hasDivider","childComponent","buttonRounding","ButtonRounding","groupTheme","dark","divider","getGroupTheme","numberOfChildren","count","role","_child$props$rounding","_child$props$theme","Boolean","isButtonRounded","givenRounding","givenTheme","relative","DatePickerComponent","_Fragment","PopoverTrigger","render","Popover","fallback","Box","Spinner","locale","minDetail","_props$onChange","call","DatePicker","popover","Delayed","delay","timeout","throwOnTimeout","delayComponent","timeoutComponent","visible","setVisible","hasTimedOut","setHasTimedOut","visibilityTimeout","failedTimeout","Error","DialogBox","onUnmount","wrapperRef","dialogDrag","DialogDragContext","onResize","_dialogDrag$handleRef","_dialogDrag$handleRef2","handleRef","resetBoxPosition","setBoxPosition","prevPosition","_dialogDrag$handleRef3","_dialogDrag$handleRef4","dialogBoxStyle","enabled","transform","boxPosition","DialogType","Dialog","modal","isDraggable","hideOnEsc","backdrop","onFullyOpen","onFullyClosed","onClose","dataTestId","ariaLabel","zIndex","useZIndex","useDrag","isFullyOpen","setIsFullyOpen","viewport","useVisualViewport","screenSize","screen","dialogStyle","isIpad","scale","unscaledWidth","unscaledHeight","minWidth","minHeight","willChange","unmountOnHide","store","portal","preventBodyScroll","hideOnEscape","hideOnInteractOutside","onMouseDown","autoFocusOnHide","blurWithoutScroll","getFlexAlignClasses","ChildPosition","drawer","onTransitionEnd","target","defaultPrevented","Provider","ZIndexContext","DialogDismiss","DialogBody","scrollDivRef","scrollBox","disableBodyScroll","enableBodyScroll","ConfirmationDialog","Heading","level","title","Paragraph","actions","DialogFooter","DialogHeader","hasHorizontalPadding","hasMinHeight","asHeading","isCloseButtonVisible","onCloseClick","appearance","onClick","LabelWithDelayedSpinner","isLoading","PopoverRounding","PopoverTheme","autoFocusOnShow","context","popoverState","updatePosition","usePopoverPlacement","isPopoverOpen","triggerElement","getState","disclosureElement","isTriggerInput","HTMLInputElement","HTMLTextAreaElement","focusWithoutScroll","getPersistentElements","preventDefault","PopoverProvider","PopoverAnchor","NativeSelect","placeholder","showPlaceholder","handleNativeSelectChange","_selectedItem$href$se","_selectedItem$href$ha","itemIndex","selectedIndex","selectedItem","flattenItems","newUrl","URL","pathname","item","isSelectItemGroup","optionIndex","NativeSelectInRouterContext","navigate","useNavigate","onChangeWithNavigate","SelectOption","isComboBox","combobox","isArray","SelectItemsVirtualized","SelectRenderer","itemSize","hasGroups","overscan","gap","groupOritem","restProps","isSelectItem","itemRenderer","paddingStart","paddingEnd","rendererProps","restItem","SelectItems","searchValue","parentTestId","isInRouterContext","useInRouterContext","filteredItems","filterSelectOptions","getItem","innerItem","providedProps","_createElement","icon","getSelectItemProps","truncate","ListRounding","ListTheme","SelectList","orientation","hasItemChildren","ListElement","hasChildren","autoSelect","Input","inputClass","SelectTooltip","content","showTimeout","isSelectOpen","hasShownTooltip","subscription","focusable","onFocusVisible","SelectTooltipWrapper","getCollectionItem","DesktopSelectComponent","_items$length","_listProps$unmountOnH","defaultValue","onInteractionChange","comboBox","onSearch","listProps","internalSearch","setInternalSearch","SelectWrapper","resetValueOnHide","includesBaseElement","setValue","ButtonWrapper","buttonWrapperProps","console","warn","listItems","selectStore","focusLoop","virtualFocus","setOpen","defaultItems","close","DesktopSelect","DEFAULT_RIGHT_ICON","SelectButton","_selectedValue$label","valueOverride","contextValue","selectedValue","buttonText","rightIcon","ButtonSize","xxsmall","isMobileDevice","SelectComponent","_findSelectedValue","_findSelectedValue2","providedValue","providedDefaultValue","triggerContent","isInteractive","nativeSelect","dataTestid","findSelectedValue","selectTrigger","NativeSelectComponent","findSelectedIndex","Select","inRouterContext","Link","matchesSearchTerm","searchTerm","lowerSearch","isSameItem","obj1","obj2","finalResults","filtered","foundItem","findIndex","itemOrGroup","DATERANGE_TOOLTIP","DateRangeSelect","chartIndex","dateRangeGroups","selectedDateRange","onDateRangeSelect","onCustomDateRangeClick","flatDateRanges","dateRanges","_ref4","withReload","timeframe","linkProps","TIMEFRAME_TOOLTIP","TimeframeSelect","timeFrameGroups","selectedTimeframe","favoriteTimeframes","isCompactView","isCompactOnly","onTimeframeSelect","onFavoriteTimeframeToggle","isFavoritesEnabled","flatTimeframes","timeframes","getSelectedTimeframeLabel","_selectedTimeframeIte","selectedTimeframeItem","labelShort","groupIndex","isIconButtonActive","stopPropagation","getTimeframeChipElementId","getButtonPadding","xsmall","small","medium","large","xlarge","TimeframeBar","isPremium","compactViewMaxBreakpointPx","loadingTimeframe","isDateRangeAvailable","containerElement","isScrollIntoViewEnabled","isTimeframeSelectEnabled","scrollWrapperElement","setScrollWrapperElement","timeframeButtonsScrollLocation","setTimeframeButtonsScrollLocation","isOnLeftEdge","isOnRightEdge","elementWidth","timeframesInExpandedPanel","checkTimeframeWrapperScrollPosition","timeframeElement","leftOffset","offsetLeft","onWheel","event","absDx","abs","_timeframe$withReload","generateTimeframeGroups","premiumTimeframes","TIMEFRAME","i1","i2","i3","i5","i10","i15","i30","h","labelPageTitle","h2","h4","w","m","freeTimeframes","getTimeframeGroups","generateDateRangeGroups","instrument","isStock","Instrument","Stock","DateRangeType","d1","d5","m1","m3","m6","ytd","y2","y5","getDateRangeGroups","customRange","isCustomAvailable","rangeGroups","_customRange$split","dateRangePrefix","DATE_RANGE_PREFIX_DELMITER","CustomDateRangePrefixEnum","CUSTOM_DATE_RANGE","getDateRangeGroupsWithHref","generatePath","dateRangeGroup","dateRange","FREE_PERIODS_STOCK","generatePathForTimeframeDateRange","utmCampaign","dateRangeQueryKey","p","utm_source","utm_medium","utm_campaign","timeframeUtm","SpecificChartFunctionality","quotePage","futuresPage","forexPage","cryptoPage","daterangeUtm","CUSTOM_DATE_RANGE_DELIMITER","CUSTOM_PREV_RANGE_DELIMITER","getParsedDateRange","_dateRange$split","parseCustomDateRangeUrlParam","anchorDate","dateRangeValue","Range","dateFromString","dateToString","dateFrom","dateTo","start","end","Prev","years","months","days","getDefaultDateRangeAnchorDate","DAYS_IN_YEAR","getTimeframeFromDateRange","_ref7","dateRangeTimeframe","_dateRanges$find$time","_dateRanges$find","_ref5","_ref6","getTimeframeForDateRangeType","startNyTime","startToReferenceDateNumOfDays","rangeNumOfDays","DATE_PICKER_MIN_DATE","YEARS_MAX_VALUE","getFullYear","TAB_BUTTON_COMMON_PROPS","CustomRangeType","DEFAULT_MANUAL_RANGE","kind","Manual","DEFAULT_START_END_RANGE","StartEnd","DATE_FORMAT_VIEW","DATE_FORMAT_VIEW_PLACEHOLDER","CustomDateRange","dialogState","onDialogSubmit","isFetching","errors","setErrors","selectedTab","setSelectedTab","getDefaultSelectedTab","setState","getDefaultSelectedDate","newValue","prevState","newState","parsedStartDate","parsedEndDate","isParsedStartDateValid","isParsedEndDateValid","newEnd","isAbsolute","fromDate","toDate","manualRange","onSubmit","isValidStartEndRangeState","hasStartError","hasEndError","prevErrors","startString","endString","getCustomStartEndDateRangeUrlParam","isValidManualRangeState","_state$days","_state$months","_state$years","getPrevPeriodDateRangeUrlParam","error","parseInt","useCustomDateRangeDialog","pathGenerator","shouldReloadOnNavigate","customDateRangeDialogState","useDialogState","handleDateRangeSelect","path","getDateRangeTimeframe","newTimeframe","TIMEFRAME_FAVORITE_DEFAULTS","TIMEFRAME_FAVORITE_DEFAULTS_FREE","intraday","LOCAL_STORAGE_KEY","useFavoriteTimeframes","storageKey","storage","useSyncLocalStorage","toggleFavoriteTimeframe","_elementRef$offsetWid","_elementRef$offsetHei","elementOverride","ResizeObserver","useResizeObserver","getIsMounted","useIsMounted","elementRef","setElementWidth","setElementHeight","offsetHeight","measureElement","newElementWidth","newElementHeight","measureElementDebounced","debounce","resizeObserver","requestAnimationFrame","observe","cancel","disconnect","maybeColumn","_maybeColumn$hasOwnPr","maybeSort","_maybeSort$hasOwnProp","_maybeSort$hasOwnProp2","getDefaultValueGetter","getValueForSort","sortedColumns","compoundSort","compoundColumn","_a","_b","columnSortBy","sortResult","sortByColumn","sortDataByColumn","getVisualViewport","visualViewport","_visualViewport$width","_visualViewport$heigh","_visualViewport$scale","_visualViewport$offse","_visualViewport$offse2","offsetTop","setViewport","_window$visualViewpor","_window$visualViewpor2","handleChange","_window$visualViewpor3","_window$visualViewpor4","columnMap","freeze","ColumnId","Spacer","urlSort","renderColumn","Ticker","args","RowKind","Transaction","Summary","Group","Trade","PortfolioSymbolType","isDelisted","ticker","Company","transactions","CostAvg","Cash","transaction","PortfolioTransaction","Watch","formatNumber","costAvg","LastClose","lastClose","LastChange","prevClose","lastChange","showPlusSign","fractions","LastChangePct","lastChangePct","LastVolume","lastVolume","TRANSACTION_LABEL","PORTFOLIO_DATE_FORMAT_VIEW","Shares","shares","Price","price","ValuePaid","valuePaid","Amount","ValueMarket","valueMarket","GainMarketUsd","gainMarketUsd","GainMarketPct","gainMarketPct","GainMarketCombined","GainTodayUsd","gainTodayUsd","GainTodayCombined","Order","rowIndex","PORTFOLIO_CASH_SYMBOL","PORTFOLIO_DATE_FORMAT_DATA","PORTFOLIO_REFRESH_INTERVAL_ELITE","PORTFOLIO_REFRESH_INTERVAL_FREE","Buy","Short","CashDeposit","CashWithdraw","CashIncome","CashFee","STOCK_TRANSACTIONS","CASH_TRANSACTIONS","EMPTY_FORM_ENTRY","EMPTY_TRANSACTION","valueMarketPrev","gainMarket","PORTFOLIO_INPUT_NAME","PORTFOLIO_INPUT_EMPTY_ERROR","PORTFOLIO_INPUT_EXISTS_ERROR","TICKERS_INPUT_NAME","TICKERS_INPUT_FORMAT_TIP","PortfolioSizeEnum","EMPTY_RESPONSE","limit","selectedPortfolio","limitTransactions","portfolio","news","portfolios","portfolioData","portfolioId","apiRequest","pid","deletePortfolio","method","portfolioEntry","QUOTE_INVALID_TICKER_REQUEST","QUOTE_INVALID_TICKER_RESPONSE","QUOTE_TICKER_DELIMITER","quoteData","t","headers","ContentType","Html","validateTickers","_response$tickers$spl","_response$specialSymb","response","json","parsedTickers","specialTickers","specialSymbols","recalculatePortfolio","rows","totalValue","numberOfTransactions","getSanitizedTicker","trim","getSymbolType","pricePerColumn","prices","_window$Sentry","captureMessage","extra","requestTickers","requestTickersLength","responseLength","tickerPrices","tickerPrice","NaN","calculatedPrice","calculatedShares","submitForm","FormUrlEncoded","ErrorSource","portfolioTickers","portfolioName","portfolio_name","submitEditForm","reorderPortfolios","PortfolioQuery","PortfolioMapSizeKey","PortfolioView","PortfolioTableView","PortfolioTableViewLabels","ActionKind","PortfolioDataKey","industryLabelKey","groupPrefix","long","short","groupLabel","gainers","losers","DEFAULT_SETTINGS","tableView","showMap","showIndustries","PortfolioGainPct","parseBoolFromValue","getMapSettingFromLocalStorage","savedSettings","saveMapSettingToLocalStorage","itemToStore","customTickersOrder","SUMMARY_DEFAULT","valueMarketStocks","valueMarketStocksPrev","getSummary","allTransactions","nonWatchTransactions","flattenAndDedupe","group","entry","isMapTransaction","previouslyAdded","newEntry","prevEntry","getIndustries","groupByKey","list","getPerfForTicker","_list$find","_item$data","groupByIndustry","hasData","dedupedData","isPortfolioSubtype","parsedData","gain","ShortGainers","ShortLosers","LongGainers","LongLosers","getEntryGroup","MarketValue","subtypePerf","PortfolioGainUsd","PortfolioChangePct","PortfolioChangeUsd","getPerfText","perfText","perfWeek","dataHash","groupName","isLong","isGainer","longPrefix","shortGainers","shortLosers","shortPrefix","longGainers","longLosers","createGroup","category","parsePortfolioQuery","params","defaultPortfolioId","_params$get","_params$get2","_parseBoolFromValue","_params$get3","_params$get4","_params$get$toUpperCa","_params$get5","_params$get$split","_params$get6","currentPortfolio","PortfolioId","TableView","Map","Size","Subtype","getColumnsByKeys","getFormattedDate","validateEditRow","dateFormat","formErrors","isValid","FORM_ENTRY_KEYS","getBulkEditData","acc","getUuid","resetCash","getNewTransaction","uuid","serializeFormData","serializer","_entry$transactions","_row","append","appendRowToFormData","validateFormData","validateFields","api","validatedTickers","validationResult","hasInvalidEntries","isInvalidTicker","symbolType","allowedTransactions","getTransactionsForSymbolType","getPortfolioInitData","returnData","isInitData","initData","remove","getTradesStructureData","symbol","getPortfolioRefreshInterval","emitter","subscribeToChanges","changeCallback","EventEmitter","getValue","onStorageChange","addListener","_emitter","removeListener","localStorage","parsedValue","emit","_emitter2","valueToStore","Function","setItem","removeValue","_emitter3","removeItem","migrateValue","transformValue","oldValue","callbackPromise"],"sourceRoot":""}