{"version":3,"file":"819.ae706161.js","mappings":"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","sources":["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/store/action-creators.ts","webpack://@finviz/website/./js/app/maps/store/appDispatcher.ts","webpack://@finviz/website/./js/app/maps/store/constants.ts","webpack://@finviz/website/./js/app/maps/store/store.ts","webpack://@finviz/website/./js/app/maps/store/mapStore.ts","webpack://@finviz/website/./js/app/maps/utils.ts","webpack://@finviz/website/./js/app/screener/utils.ts"],"sourcesContent":["import { MapSubtype, MapSubtypeId, MapType, MapTypeId, ScaleId } from '../types'\r\n\r\nexport const MAP_DATA_FETCH_INTERVAL = (FinvizSettings.hasUserPremium ? 20 : 120) * 1000\r\nexport const EXPANDED_MAP_BODY_CLASSS = 'is-map-expanded'\r\n\r\nexport const MAP_SUBTYPES_COMPANIES: MapSubtype[] = [\r\n {\r\n id: MapSubtypeId.DayPerf,\r\n name: '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 {\r\n id: MapSubtypeId.WeekPerf,\r\n name: '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 {\r\n id: MapSubtypeId.MonthPerf,\r\n name: '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 {\r\n id: MapSubtypeId.ThreeMonthPerf,\r\n name: '3 Months 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 {\r\n id: MapSubtypeId.SixMonthPerf,\r\n name: '6 Months 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 {\r\n id: MapSubtypeId.YearPerf,\r\n name: '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 {\r\n id: MapSubtypeId.YearToDatePerf,\r\n name: '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 id: MapSubtypeId.RelativeVolume,\r\n name: '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 {\r\n id: MapSubtypeId.PriceToEarnings,\r\n name: '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 {\r\n id: MapSubtypeId.ForwardPriceToEearnings,\r\n name: '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 {\r\n id: MapSubtypeId.PriceEarningsToGrowth,\r\n name: '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 {\r\n id: MapSubtypeId.PriceToSellsRatio,\r\n name: '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 {\r\n id: MapSubtypeId.PriceToBookRatio,\r\n name: '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 {\r\n id: MapSubtypeId.DividendYield,\r\n name: '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 {\r\n id: MapSubtypeId.EPSGrowth5y,\r\n name: '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 {\r\n id: MapSubtypeId.FloatShort,\r\n name: '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 {\r\n id: MapSubtypeId.AnalystRecommendation,\r\n name: '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 {\r\n id: MapSubtypeId.EarningsPerf,\r\n name: '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 {\r\n id: MapSubtypeId.EarningsDate,\r\n name: '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_SUBTYPES_ETF: MapSubtype[] = [\r\n {\r\n id: MapSubtypeId.DayPerf,\r\n name: '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 {\r\n id: MapSubtypeId.WeekPerf,\r\n name: '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 {\r\n id: MapSubtypeId.MonthPerf,\r\n name: '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 {\r\n id: MapSubtypeId.ThreeMonthPerf,\r\n name: '3 Months 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 {\r\n id: MapSubtypeId.SixMonthPerf,\r\n name: '6 Months 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 {\r\n id: MapSubtypeId.YearPerf,\r\n name: '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 {\r\n id: MapSubtypeId.YearToDatePerf,\r\n name: '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 id: MapSubtypeId.RelativeVolume,\r\n name: '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]\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. Size represents market cap.',\r\n type: MapTypeId.Screener,\r\n subtypes: MAP_SUBTYPES_COMPANIES,\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.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: 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_SEC_ALL: 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_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_SCREENER_ETF: MapOrder = {\r\n ...ORDER_SCREENER,\r\n Financial: 1000,\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 India: 19,\r\n 'Hong Kong': 18,\r\n 'South Korea': 15,\r\n Taiwan: 14,\r\n\r\n Colombia: 30,\r\n Chile: 29,\r\n Argentina: 28,\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 { 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.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}\r\n\r\nexport const scaleStepFormat: Record = {\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}\r\n\r\nexport const Settings: ISettings = {\r\n padding: { top: 0, right: 0, bottom: 1, left: 1 },\r\n background: '#262931',\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: '#262931',\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 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 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","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 = (width: number, type: MapTypeId, isSmall: boolean) => {\r\n const ratio = LayoutGenerator.getSizeRatio(type, isSmall)\r\n\r\n return ~~(width / ratio)\r\n }\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, options: Record = {}) {\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 this.layout = this._generateScreener(data, options).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.name === 'Root') {\r\n this.sectors.push(d)\r\n } else if (d.parent && d.parent.name !== 'Root' && 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: Record\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: Record) =>\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: any, 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 return this._generateLayout(data, constants.ORDER_SP500)\r\n }\r\n\r\n _generateFull(data: MapDataRoot) {\r\n return this._generateLayout(data, constants.ORDER_SEC_ALL)\r\n }\r\n\r\n _generateScreener(data: MapDataRoot, { showETF }: Record) {\r\n const order = showETF ? constants.ORDER_SCREENER_ETF : constants.ORDER_SCREENER\r\n\r\n return this._generateLayout(data, order, 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 // SWITCH BRAZIL AND OTHERS\r\n if (industry.name === 'South America') {\r\n const brazil = treemapNodes.find((d) => d.data.name === 'Brazil')!\r\n const colombia = treemapNodes.find((d) => d.data.name === 'Colombia')!\r\n const brazilWidth = brazil.x1 - brazil.x0\r\n const colombiaWidth = colombia.x1 - colombia.x0\r\n\r\n treemapNodes.each((d) => {\r\n if ([d.parent?.data.name, d.data.name].includes('Brazil')) {\r\n d.x0 += colombiaWidth\r\n d.x1 += colombiaWidth\r\n } else {\r\n d.x0 -= brazilWidth\r\n d.x1 -= brazilWidth\r\n }\r\n })\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","import debounce from 'lodash.debounce'\r\n\r\nimport { CancelablePromise, apiRequest } from '../../../main/services/api'\r\nimport { getDate } from '../../header/utils'\r\nimport Treemap from '../treemap'\r\nimport { MapData, MapDataNode, MapTypeId, PerfData } from '../types'\r\nimport { getVisibleTooltipTickers } from '../utils'\r\nimport AppDispatcher from './appDispatcher'\r\nimport { ActionTypes } from './constants'\r\nimport mapStore from './mapStore'\r\n\r\nvar _targetScale = 1\r\nfunction zoomIn(treemap: Treemap, scale: number, tx: number, ty: number) {\r\n _targetScale = scale\r\n animate()\r\n function animate() {\r\n treemap.zoom.scale(+(treemap.zoom.scale() + 0.05).toFixed(2), { x: tx, y: ty })\r\n AppDispatcher.handleViewAction({ type: ActionTypes.RENDER_TREEMAP })\r\n if (treemap.zoom.scale() + 0.05 < _targetScale + 0.00001) {\r\n requestAnimationFrame(animate)\r\n }\r\n }\r\n}\r\n\r\nfunction zoomOut(treemap: Treemap, scale: number, tx: number, ty: number) {\r\n _targetScale = scale\r\n animate()\r\n function animate() {\r\n treemap.zoom.scale(+(treemap.zoom.scale() - 0.05).toFixed(2), { x: tx, y: ty })\r\n AppDispatcher.handleViewAction({ type: ActionTypes.RENDER_TREEMAP })\r\n if (treemap.zoom.scale() - 0.05 > _targetScale - 0.00001) {\r\n requestAnimationFrame(animate)\r\n }\r\n }\r\n}\r\n\r\nfunction updateVisibleSparklines(treemap: Treemap) {\r\n const hoveredNode = mapStore.getHoveredNode()\r\n if (hoveredNode) {\r\n const tickersToLoad = getVisibleTooltipTickers(hoveredNode)\r\n\r\n if (!tickersToLoad.includes(hoveredNode.name)) {\r\n tickersToLoad.push(hoveredNode.name)\r\n }\r\n\r\n if (tickersToLoad.length) {\r\n debouncedLoadSparklines(tickersToLoad, treemap.type)\r\n }\r\n }\r\n}\r\n\r\nlet _lastSparklinesRequest: CancelablePromise | null = null\r\nasync function loadSparklines(tickers: string[], mapType: string) {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.LOAD_SPARKLINES_STARTED,\r\n })\r\n _lastSparklinesRequest?.cancel?.()\r\n _lastSparklinesRequest = apiRequest(\r\n '/api/map_sparklines.ashx',\r\n { query: { t: tickers.join(','), ty: mapType } },\r\n true\r\n )\r\n\r\n try {\r\n const data = await _lastSparklinesRequest\r\n AppDispatcher.handleServerAction({\r\n type: ActionTypes.LOAD_SPARKLINES_COMPLETED,\r\n data: data,\r\n })\r\n } catch (error) {\r\n AppDispatcher.handleServerAction({\r\n type: ActionTypes.LOAD_SPARKLINES_FAILED,\r\n error,\r\n })\r\n }\r\n}\r\n\r\nconst debouncedLoadSparklines = debounce(loadSparklines, 200, { trailing: true })\r\n\r\nconst actions = {\r\n setHoveredNode(node: MapDataNode | undefined) {\r\n if (!node) {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.RESET_SPARKLINE_DATA,\r\n })\r\n }\r\n\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.SET_HOVERED_NODE,\r\n node,\r\n })\r\n },\r\n\r\n loadSparklineData(tickers: string[], mapType: MapTypeId) {\r\n if (tickers) {\r\n debouncedLoadSparklines(tickers, mapType)\r\n }\r\n },\r\n\r\n loadSparklinesCancel() {\r\n _lastSparklinesRequest?.cancel?.()\r\n },\r\n\r\n resetSparklineData() {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.RESET_SPARKLINE_DATA,\r\n })\r\n },\r\n\r\n changeTranslate(treemap: Treemap, tx: number, ty: number) {\r\n treemap.zoom.translate([tx, ty])\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.CHANGE_TRANSLATE,\r\n })\r\n },\r\n\r\n zoom(treemap: Treemap, direction: number, offsetX: number, offsetY: number) {\r\n if (direction > 0) {\r\n const zoomLevel = treemap.getNextZoomLevel()\r\n if (zoomLevel !== treemap.zoom.scale()) {\r\n zoomIn(treemap, zoomLevel, offsetX, offsetY)\r\n }\r\n } else {\r\n const zoomLevel = treemap.getPreviousZoomLevel()\r\n if (zoomLevel !== treemap.zoom.scale()) {\r\n zoomOut(treemap, zoomLevel, offsetX, offsetY)\r\n }\r\n }\r\n },\r\n\r\n render() {\r\n AppDispatcher.handleViewAction({ type: ActionTypes.RENDER_TREEMAP })\r\n },\r\n\r\n zoomAndTranslate(treemap: Treemap, scale: number, tx: number, ty: number) {\r\n treemap.zoom.scale(1, { x: tx, y: ty })\r\n treemap.zoom.scale(scale, { x: tx, y: ty })\r\n AppDispatcher.handleViewAction({ type: ActionTypes.RENDER_TREEMAP })\r\n },\r\n\r\n updateLayout(treemap: Treemap, props: { width: number; height: number; data: MapData }) {\r\n treemap.updateData(props)\r\n treemap.zoom.updateDimensions(props)\r\n AppDispatcher.handleViewAction({ type: ActionTypes.RENDER_TREEMAP })\r\n\r\n // Update hovered node if any\r\n const hoveredNode = mapStore.getHoveredNode()\r\n if (hoveredNode) {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.SET_HOVERED_NODE,\r\n node: treemap.nodes.find((node) => node.name === hoveredNode.name),\r\n })\r\n updateVisibleSparklines(treemap)\r\n }\r\n },\r\n\r\n updatePerfData(treemap?: Treemap, data?: PerfData) {\r\n if (!treemap || !data) return\r\n\r\n treemap.updatePerf(data)\r\n AppDispatcher.handleServerAction({\r\n type: ActionTypes.UPDATE_DATA,\r\n version: data.version,\r\n timestamp: getDate(),\r\n })\r\n\r\n updateVisibleSparklines(treemap)\r\n },\r\n\r\n _setOnPublish(getPublishCanvas: () => HTMLCanvasElement) {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.SET_PUBLISH_CANVAS,\r\n getPublishCanvas,\r\n })\r\n },\r\n\r\n setupWidget() {\r\n AppDispatcher.handleViewAction({\r\n type: ActionTypes.SET_WIDGET,\r\n isWidget: true,\r\n })\r\n },\r\n}\r\n\r\nexport default actions\r\n","import { Dispatcher } from 'flux'\r\n\r\nimport { PayloadSources } from './constants'\r\n\r\nclass AppDispatcher extends Dispatcher {\r\n handleServerAction(action: any) {\r\n var payload = {\r\n source: PayloadSources.SERVER_ACTION,\r\n action: action,\r\n }\r\n //console.log(action, payload);\r\n this.dispatch(payload)\r\n }\r\n\r\n handleViewAction(action: any) {\r\n var payload = {\r\n source: PayloadSources.VIEW_ACTION,\r\n action: action,\r\n }\r\n //console.log(action, payload);\r\n this.dispatch(payload)\r\n }\r\n}\r\n\r\nexport default new AppDispatcher()\r\n","import keyMirror from 'keymirror'\r\n\r\nconst ActionTypes = keyMirror({\r\n RENDER_TREEMAP: null,\r\n CHANGE_TRANSLATE: null,\r\n SET_HOVERED_NODE: null,\r\n\r\n LOAD_SPARKLINES_STARTED: null,\r\n LOAD_SPARKLINES_COMPLETED: null,\r\n LOAD_SPARKLINES_FAILED: null,\r\n RESET_SPARKLINE_DATA: null,\r\n\r\n INIT_STARTED: null,\r\n INIT_FAILED: null,\r\n\r\n UPDATE_DATA: null,\r\n\r\n SET_PUBLISH_CANVAS: null,\r\n\r\n SET_WIDGET: null,\r\n})\r\n\r\nconst PayloadSources = keyMirror({\r\n SERVER_ACTION: null,\r\n VIEW_ACTION: null,\r\n})\r\n\r\nexport { ActionTypes, PayloadSources }\r\n","import { EventEmitter } from 'events'\r\n\r\nclass Store extends EventEmitter {\r\n static CHANGE_EVENT = 'change'\r\n\r\n emitChange() {\r\n this.emit(Store.CHANGE_EVENT)\r\n }\r\n\r\n addChangeListener(callback: (...args: any[]) => void) {\r\n this.on(Store.CHANGE_EVENT, callback)\r\n }\r\n\r\n removeChangeListener(callback: (...args: any[]) => void) {\r\n this.removeListener(Store.CHANGE_EVENT, callback)\r\n }\r\n}\r\n\r\nexport default Store\r\n","import { MapDataNode } from '../types'\r\nimport AppDispatcher from './appDispatcher'\r\nimport { ActionTypes } from './constants'\r\nimport Store from './store'\r\n\r\nlet _hoveredNode: MapDataNode\r\nlet _sparklinesData: Record = {}\r\nlet _dataVersion: number\r\nlet _dataTimestamp: Date\r\nlet _isWidget = false\r\nlet _getPublishCanvas: () => HTMLCanvasElement\r\n\r\nclass MapStore extends Store {\r\n getHoveredNode() {\r\n return _hoveredNode\r\n }\r\n\r\n getSparklines() {\r\n return _sparklinesData\r\n }\r\n\r\n getDataVersion() {\r\n return _dataVersion\r\n }\r\n\r\n getDataTimestamp() {\r\n return _dataTimestamp\r\n }\r\n\r\n isWidget() {\r\n return _isWidget\r\n }\r\n\r\n getPublishCanvas() {\r\n return _getPublishCanvas()\r\n }\r\n}\r\n\r\nvar mapStore = new MapStore()\r\n\r\n// @ts-ignore\r\nmapStore.dispatchToken = AppDispatcher.register(function (payload: any) {\r\n var action = payload.action\r\n\r\n switch (action.type) {\r\n case ActionTypes.RENDER_TREEMAP:\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.SET_HOVERED_NODE:\r\n if (action.node !== _hoveredNode) {\r\n _hoveredNode = action.node\r\n mapStore.emitChange()\r\n }\r\n break\r\n\r\n case ActionTypes.CHANGE_TRANSLATE:\r\n // @ts-ignore\r\n _hoveredNode = undefined\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.LOAD_SPARKLINES_STARTED:\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.LOAD_SPARKLINES_COMPLETED:\r\n _sparklinesData = { ..._sparklinesData, ...action.data }\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.RESET_SPARKLINE_DATA:\r\n case ActionTypes.LOAD_SPARKLINES_FAILED:\r\n _sparklinesData = {}\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.UPDATE_DATA:\r\n _dataVersion = action.version\r\n _dataTimestamp = action.timestamp\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.SET_PUBLISH_CANVAS:\r\n _getPublishCanvas = action.getPublishCanvas\r\n mapStore.emitChange()\r\n break\r\n\r\n case ActionTypes.SET_WIDGET:\r\n _isWidget = action.isWidget\r\n mapStore.emitChange()\r\n break\r\n }\r\n})\r\n\r\nexport default mapStore\r\n","import * as React from 'react'\r\n\r\nimport { ScreenerQuery, ScreenerView } from '../screener/utils'\r\nimport { isMobile } from '../shared/isMobile'\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 { MapDataIndustry, MapDataNode, MapDataRoot, MapDataRow, MapDataSector, MapTypeId, PerfData } 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 async function fetchBaseData(filename: string, cacheBuster: number) {\r\n const response = await fetch(`/maps/${filename}?rev=${cacheBuster}`)\r\n\r\n return response.json()\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 && window.innerWidth < 1450 && !document.body.classList.contains('is-screener')\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 return {\r\n width,\r\n height: LayoutGenerator.calculateHeight(width, type, isSmall),\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 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 version: 1,\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 getVisibleTooltipTickers(node?: MapDataNode) {\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 .map((n) => n.name)\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","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"],"names":["MAP_DATA_FETCH_INTERVAL","FinvizSettings","hasUserPremium","EXPANDED_MAP_BODY_CLASSS","MAP_SUBTYPES_COMPANIES","id","MapSubtypeId","name","scaleId","ScaleId","tooltip","countIndustryPerf","countSectorPerf","MAP_SUBTYPES_ETF","MAP_TYPES","pageTitle","description","type","MapTypeId","subtypes","nameShort","MAP_TYPE_SCREENER","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","ORDER_SEC_ALL","ORDER_ETF","US","Global","International","Commodity","Strategy","Forex","ORDER_SCREENER","ORDER_SCREENER_ETF","ORDER_WORLD","Ireland","Spain","France","Belgium","Netherlands","Switzerland","India","Taiwan","Colombia","Chile","Argentina","WORLD_INDUSTRIES","x","y","countries","scaleMinMax","_5","_10","_15","_20","_25","_relvol","_pe","_fpe","_peg","_ps","_pb","_div","_eps5y","_short","_rec","_earndate","_portfolioPct","_portfolioUsd","scaleStepFormat","Settings","padding","top","right","bottom","left","background","sector","border","header","color","height","fontSize","fontWeight","margin","industry","hover","scaleFontSizes","fontSizePadding","fontSizePairs","SettingsSmall","SettingsSmallGeo","SettingsScreener","LayoutGenerator","static","node","settings","deltaX","Math","round","x1","x0","deltaY","y1","y0","isLargeNode","constants","showHeader","constructor","width","isSmall","arr","filter","isVisible","this","isNodeVisible","children","length","filterVisibleNodes","d","depth","NodeDepth","isNodeHeaderVisible","smallIndustryPadding","smallIndustryGeoPadding","a","b","order","heightB","Number","isFinite","minSectorHeight","value","hasOwnProperty","data","d3","sum","sort","_getHierarchySort","paddingFn","_getPaddingGeo","_getPadding","size","tile","paddingTop","paddingRight","paddingBottom","paddingLeft","ratio","nodes","industryIndex","industryX","industryY","industryWidth","industryHeight","countriesRoots","_getIndustriesRoots","root","_rootsToRoot","hierarchy","_getHierarchy","treemapNodes","_getTreemap","treemap","each","brazil","find","colombia","brazilWidth","colombiaWidth","parent","includes","concat","descendants","getExportData","mapRoot","industries","layout","stringified","JSON","stringify","key","parse","getLayoutData","sectors","getLayout","options","_generateSP500","_generateFull","_generateScreener","_generateWorld","_generateETF","forEach","_transformNode","push","Object","assign","perf","additional","roots","duplicateTickers","some","i","_getSectorsRoots","s","_generateLayout","recountSectors","treemapHeight","calculateHeight","recalculateHeight","showETF","getSizeRatio","_targetScale","updateVisibleSparklines","hoveredNode","mapStore","tickersToLoad","getVisibleTooltipTickers","debouncedLoadSparklines","_lastSparklinesRequest","debounce","async","tickers","mapType","AppDispatcher","ActionTypes","_lastSparklinesReques","cancel","apiRequest","query","t","join","ty","error","trailing","setHoveredNode","loadSparklineData","loadSparklinesCancel","resetSparklineData","changeTranslate","tx","zoom","translate","direction","offsetX","offsetY","zoomLevel","getNextZoomLevel","scale","animate","toFixed","requestAnimationFrame","zoomIn","getPreviousZoomLevel","zoomOut","render","zoomAndTranslate","updateLayout","props","updateData","updateDimensions","updatePerfData","updatePerf","version","timestamp","getDate","_setOnPublish","getPublishCanvas","setupWidget","isWidget","Dispatcher","handleServerAction","action","payload","source","PayloadSources","dispatch","handleViewAction","keyMirror","RENDER_TREEMAP","CHANGE_TRANSLATE","SET_HOVERED_NODE","LOAD_SPARKLINES_STARTED","LOAD_SPARKLINES_COMPLETED","LOAD_SPARKLINES_FAILED","RESET_SPARKLINE_DATA","INIT_STARTED","INIT_FAILED","UPDATE_DATA","SET_PUBLISH_CANVAS","SET_WIDGET","SERVER_ACTION","VIEW_ACTION","Store","EventEmitter","emitChange","emit","CHANGE_EVENT","addChangeListener","callback","on","removeChangeListener","removeListener","_hoveredNode","_dataVersion","_dataTimestamp","_getPublishCanvas","_sparklinesData","_isWidget","getHoveredNode","getSparklines","getDataVersion","getDataTimestamp","dispatchToken","undefined","getOffset","e","rect","currentTarget","getBoundingClientRect","clientX","clientY","getIsSmall","URLSearchParams","window","location","search","get","getSettingsForMapType","restoreDataKeys","perfData","map","row","newRow","getMapData","mapData","company","splitData","fetchBaseData","filename","cacheBuster","fetch","json","getRatioSizeForWidth","mapWidth","max","getSize","element","canvasWrapper","document","getElementById","has","body","classList","contains","wrapper","style","removeProperty","clientWidth","elementHeight","innerHeight","newWidth","maxWidth","getSizeForExpandedMap","scrollbarWidth","innerWidth","documentElement","getSizeRatioBasedMap","getDefaultZoomLevels","isMobile","test","navigator","userAgent","parseInitDataAsPerf","industryTickers","rowHeight","visibleRows","floor","slice","min","n","onNodeClick","open","set","ScreenerQuery","ScreenerView","flatMap","replace","toLowerCase","ScreenerFilter","ScreenerAddtionalQuery","eventListenerRegister","el","eventName","handler","addEventListener","removeEventListener","textContent","innerText","ScreenerRenderCustomModal","select","getAttribute","customWrapper","display","input","split","result","len","option","j","optionEl","ScreenerGetOptionsList","DATE_REGEX","getIsOptionDateRange","from","to","isValidFromDate","isValidToDate","isNaN","Date","getTime","getInitialDateFromSelectedValues","selectedValues","initialDate","date","dateRangeToFilterString","getQueryForView","view","allowedParams","baseQuery","allowList","values","keys","Array","delete","originalView","View","match","parseScreenerFilters","filtersString","Filters","fromEntries","f","lastUnderscore","lastIndexOf","substring","stringifyScreenerFilters","filters","entries","String"],"sourceRoot":""}