add politician
This commit is contained in:
parent
7cc6f32c58
commit
f8049d2495
298
src/lib/utils.ts
298
src/lib/utils.ts
@ -1,10 +1,7 @@
|
||||
|
||||
import { formatDistanceToNow } from 'date-fns';
|
||||
|
||||
import { formatDistanceToNow } from "date-fns";
|
||||
|
||||
let pbCloudImage = import.meta.env.VITE_IMAGE_POCKETBASE_URL; // Set a default API URL
|
||||
|
||||
|
||||
import { clsx, type ClassValue } from "clsx";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
import { cubicOut } from "svelte/easing";
|
||||
@ -14,7 +11,6 @@ export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
|
||||
type FlyAndScaleParams = {
|
||||
y?: number;
|
||||
x?: number;
|
||||
@ -77,7 +73,6 @@ export const flyAndScale = (
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
export const formatDateRange = (lastDateStr) => {
|
||||
// Convert lastDateStr to Date object
|
||||
const lastDate = new Date(lastDateStr);
|
||||
@ -86,12 +81,21 @@ export const formatDateRange = (lastDateStr) => {
|
||||
const firstDate = new Date(lastDate.getFullYear(), lastDate.getMonth(), 1);
|
||||
|
||||
// Format first and last dates
|
||||
const firstDateFormatted = firstDate.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', day: '2-digit' });
|
||||
const lastDateFormatted = lastDate.toLocaleString('en-US', { month: 'short', day: 'numeric', year: 'numeric', day: '2-digit' });
|
||||
const firstDateFormatted = firstDate.toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
day: "2-digit",
|
||||
});
|
||||
const lastDateFormatted = lastDate.toLocaleString("en-US", {
|
||||
month: "short",
|
||||
day: "numeric",
|
||||
year: "numeric",
|
||||
day: "2-digit",
|
||||
});
|
||||
// Construct and return the formatted date range string
|
||||
return `${firstDateFormatted} - ${lastDateFormatted}`;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export const serializeNonPOJOs = (obj) => {
|
||||
return structuredClone(obj);
|
||||
@ -99,41 +103,36 @@ export const serializeNonPOJOs = (obj) => {
|
||||
|
||||
export const generateUsername = (name) => {
|
||||
const randomHex = Math.floor(Math.random() * 65536).toString(16);
|
||||
const id = randomHex.padStart(4, '0');
|
||||
const id = randomHex.padStart(4, "0");
|
||||
return `${name.slice(0, 5)}${id}`;
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
export const getImageURL = (collectionId, recordId, fileName, size = '0x0') => {
|
||||
export const getImageURL = (collectionId, recordId, fileName, size = "0x0") => {
|
||||
//For development or local storage or S3 bucket without CDN Cloudfront
|
||||
if(pbCloudImage === 'http://localhost:8090')
|
||||
{
|
||||
if (pbCloudImage === "http://localhost:8090") {
|
||||
return `${pbCloudImage}/api/files/${collectionId}/${recordId}/${fileName}?thumb=${size}`;
|
||||
}
|
||||
return `${pbCloudImage}/${collectionId}/${recordId}/${fileName}?thumb=${size}`;
|
||||
};
|
||||
|
||||
|
||||
export const validateData = async (formData, schema) => {
|
||||
const body = Object.fromEntries(formData)
|
||||
const body = Object.fromEntries(formData);
|
||||
|
||||
try {
|
||||
const data = schema.parse(body);
|
||||
return {
|
||||
formData: data,
|
||||
errors: null
|
||||
}
|
||||
} catch(err) {
|
||||
console.log('Error: ', err)
|
||||
const errors = err.flatten()
|
||||
errors: null,
|
||||
};
|
||||
} catch (err) {
|
||||
console.log("Error: ", err);
|
||||
const errors = err.flatten();
|
||||
return {
|
||||
formData: body,
|
||||
errors
|
||||
errors,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
const yearlySummaries = {};
|
||||
@ -143,21 +142,31 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
|
||||
// Define a Set of keys to exclude from summing
|
||||
// FMP sucks since these keys are up to date for every quarter hence no summation required
|
||||
const excludeKeys = new Set(['totalDebt','priceToEarnings', 'weightedAverageShsOut', 'weightedAverageShsOutDil']);
|
||||
const excludeKeys = new Set([
|
||||
"totalDebt",
|
||||
"priceToEarnings",
|
||||
"weightedAverageShsOut",
|
||||
"weightedAverageShsOutDil",
|
||||
]);
|
||||
|
||||
// Function to get the quarter number from the period string
|
||||
function getQuarterNumber(period) {
|
||||
switch (period) {
|
||||
case 'Q1': return 1;
|
||||
case 'Q2': return 2;
|
||||
case 'Q3': return 3;
|
||||
case 'Q4': return 4;
|
||||
default: return 0;
|
||||
case "Q1":
|
||||
return 1;
|
||||
case "Q2":
|
||||
return 2;
|
||||
case "Q3":
|
||||
return 3;
|
||||
case "Q4":
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// Iterate over each quarterly result
|
||||
quarterlyResults?.forEach(quarter => {
|
||||
quarterlyResults?.forEach((quarter) => {
|
||||
// Extract year and quarter from the data
|
||||
const year = quarter?.calendarYear;
|
||||
const quarterNum = getQuarterNumber(quarter?.period);
|
||||
@ -167,7 +176,7 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
yearlySummaries[year] = {
|
||||
calendarYear: `${year}`, // Use end of the year date
|
||||
lastQuarterProcessed: 0, // Keep track of the last quarter processed
|
||||
date: quarter?.date // Copy the 'date' field unchanged
|
||||
date: quarter?.date, // Copy the 'date' field unchanged
|
||||
};
|
||||
quarterCounts[year] = 0;
|
||||
}
|
||||
@ -183,9 +192,14 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
}
|
||||
|
||||
// Sum up the numeric fields for the year, excluding specific keys
|
||||
Object?.keys(quarter)?.forEach(key => {
|
||||
if (typeof quarter[key] === 'number' && !excludeKeys?.has(key) && !lastQuarterKeys.has(key)) {
|
||||
yearlySummaries[year][key] = (yearlySummaries[year][key] || 0) + quarter[key];
|
||||
Object?.keys(quarter)?.forEach((key) => {
|
||||
if (
|
||||
typeof quarter[key] === "number" &&
|
||||
!excludeKeys?.has(key) &&
|
||||
!lastQuarterKeys.has(key)
|
||||
) {
|
||||
yearlySummaries[year][key] =
|
||||
(yearlySummaries[year][key] || 0) + quarter[key];
|
||||
} else if (excludeKeys.has(key)) {
|
||||
// Directly copy the last quarter value for these keys
|
||||
yearlySummaries[year][key] = quarter[key];
|
||||
@ -197,8 +211,10 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
});
|
||||
|
||||
// Filter out years with less than 4 quarters
|
||||
const validYears = Object?.keys(quarterCounts)?.filter(year => quarterCounts[year] === 4);
|
||||
const annualResults = validYears?.map(year => yearlySummaries[year]);
|
||||
const validYears = Object?.keys(quarterCounts)?.filter(
|
||||
(year) => quarterCounts[year] === 4
|
||||
);
|
||||
const annualResults = validYears?.map((year) => yearlySummaries[year]);
|
||||
|
||||
// Sort the results by year in descending order
|
||||
annualResults.sort((a, b) => b?.calendarYear?.localeCompare(a?.calendarYear));
|
||||
@ -206,38 +222,66 @@ export function sumQuarterlyResultsByYear(quarterlyResults, namingList) {
|
||||
return annualResults;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const sortPostsByDate = (posts) => {
|
||||
return posts.sort(function(a, b) {
|
||||
return posts.sort(function (a, b) {
|
||||
return new Date(b.created) - new Date(a.created);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export function capitalizeFirstLetter(string) {
|
||||
return string.charAt(0).toUpperCase() + string.slice(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function formatString(inputString) {
|
||||
export function formatString(inputString) {
|
||||
// Split the input string into words using space as a delimiter
|
||||
const words = inputString?.split(' ');
|
||||
const words = inputString?.split(" ");
|
||||
|
||||
// Capitalize the first letter of each word and convert the rest to lowercase
|
||||
const formattedWords = words?.map((word, index) => {
|
||||
if (word.length > 0) {
|
||||
// Check if the word is "LTG" or "LLC" and keep them uppercase
|
||||
const excludedList = ['n/a','CEO','U.S.','NGL','ETF','SPDR','S&P','USD','US','JPMORGAN','SRS','AQR','XN','TIG','HAP','AB','AKRE','LTG', 'LLC','JVL', 'NJ', 'FMR', 'LP', 'NNS','BPS','BNP','PCG','CTC','IMC', 'PLC','WIT'];
|
||||
const excludedList = [
|
||||
"n/a",
|
||||
"CEO",
|
||||
"U.S.",
|
||||
"NGL",
|
||||
"ETF",
|
||||
"SPDR",
|
||||
"S&P",
|
||||
"USD",
|
||||
"US",
|
||||
"JPMORGAN",
|
||||
"SRS",
|
||||
"AQR",
|
||||
"XN",
|
||||
"TIG",
|
||||
"HAP",
|
||||
"AB",
|
||||
"AKRE",
|
||||
"LTG",
|
||||
"LLC",
|
||||
"JVL",
|
||||
"NJ",
|
||||
"FMR",
|
||||
"LP",
|
||||
"NNS",
|
||||
"BPS",
|
||||
"BNP",
|
||||
"PCG",
|
||||
"CTC",
|
||||
"IMC",
|
||||
"PLC",
|
||||
"WIT",
|
||||
];
|
||||
|
||||
// Check if the word is "black-rock" and format it accordingly
|
||||
if (index < words?.length - 1 && word?.toLowerCase() === 'black' && words[index + 1]?.toLowerCase() === 'rock') {
|
||||
return 'Black Rock';
|
||||
}
|
||||
else if (excludedList?.includes(word)) {
|
||||
if (
|
||||
index < words?.length - 1 &&
|
||||
word?.toLowerCase() === "black" &&
|
||||
words[index + 1]?.toLowerCase() === "rock"
|
||||
) {
|
||||
return "Black Rock";
|
||||
} else if (excludedList?.includes(word)) {
|
||||
return word;
|
||||
} else {
|
||||
return word?.charAt(0)?.toUpperCase() + word?.slice(1)?.toLowerCase();
|
||||
@ -247,20 +291,23 @@ export function capitalizeFirstLetter(string) {
|
||||
});
|
||||
|
||||
// Join the formatted words back together with spaces
|
||||
const formattedString = formattedWords?.join(' ');
|
||||
const formattedString = formattedWords?.join(" ");
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export function abbreviateNumber(number, addDollarSign = false) {
|
||||
export function abbreviateNumber(number, addDollarSign = false) {
|
||||
const negative = number < 0;
|
||||
|
||||
// Handle special case for exactly 1000
|
||||
if (Math.abs(number) === 1000) {
|
||||
return addDollarSign ? (negative ? '-$1K' : '$1K') : (negative ? '-1K' : '1K');
|
||||
return addDollarSign
|
||||
? negative
|
||||
? "-$1K"
|
||||
: "$1K"
|
||||
: negative
|
||||
? "-1K"
|
||||
: "1K";
|
||||
}
|
||||
|
||||
if (Math.abs(number) !== 0 && Math.abs(number) > 1000) {
|
||||
@ -276,81 +323,89 @@ export function capitalizeFirstLetter(string) {
|
||||
abbreviation = abbreviation.toFixed(2);
|
||||
}
|
||||
|
||||
abbreviation = abbreviation.toLocaleString('en-US', { maximumFractionDigits: 2, minimumFractionDigits: 2 });
|
||||
abbreviation = abbreviation.toLocaleString("en-US", {
|
||||
maximumFractionDigits: 2,
|
||||
minimumFractionDigits: 2,
|
||||
});
|
||||
|
||||
if (Math.abs(number) % 1000 === 0) {
|
||||
abbreviation = abbreviation.replace('-', '');
|
||||
abbreviation = abbreviation.replace("-", "");
|
||||
}
|
||||
|
||||
if (abbreviation?.slice(-3) === '.00') {
|
||||
if (abbreviation?.slice(-3) === ".00") {
|
||||
abbreviation = abbreviation.slice(0, -3);
|
||||
}
|
||||
|
||||
const formattedNumber = abbreviation + suffixes[index];
|
||||
|
||||
if (addDollarSign) {
|
||||
return (negative ? '-$' : '$') + formattedNumber;
|
||||
return (negative ? "-$" : "$") + formattedNumber;
|
||||
} else {
|
||||
return negative ? '-' + formattedNumber : formattedNumber;
|
||||
return negative ? "-" + formattedNumber : formattedNumber;
|
||||
}
|
||||
}
|
||||
else if (Math.abs(number) >= 0 && Math.abs(number) < 1000) {
|
||||
} else if (Math.abs(number) >= 0 && Math.abs(number) < 1000) {
|
||||
if (addDollarSign) {
|
||||
return (negative ? '-$' : '$') + number;
|
||||
return (negative ? "-$" : "$") + number;
|
||||
} else {
|
||||
return number;
|
||||
}
|
||||
}
|
||||
|
||||
else {
|
||||
return addDollarSign ? '$0' : '0';
|
||||
} else {
|
||||
return addDollarSign ? "$0" : "0";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const formatDate = (dateString) => {
|
||||
const date = new Date(dateString)
|
||||
return formatDistanceToNow(date, { addSuffix: false, includeSeconds: false })?.replace(/about /i, '')
|
||||
}
|
||||
const date = new Date(dateString);
|
||||
return formatDistanceToNow(date, {
|
||||
addSuffix: false,
|
||||
includeSeconds: false,
|
||||
})?.replace(/about /i, "");
|
||||
};
|
||||
|
||||
export const formatRuleValue = (rule) => {
|
||||
if (['interestIncome', 'interestExpenses'].includes(rule.name)) {
|
||||
if (["interestIncome", "interestExpenses"].includes(rule.name)) {
|
||||
return `$${rule.value === 1000 ? `${rule.value / 1000} Bn` : `${rule.value} Mio`}`;
|
||||
} else if (['revenue', 'costOfRevenue', 'costAndExpenses', 'netIncome', 'grossProfit', 'researchAndDevelopmentExpenses', 'marketCap', 'operatingExpenses', 'operatingIncome', 'ebitda'].includes(rule.name)) {
|
||||
} else if (
|
||||
[
|
||||
"revenue",
|
||||
"costOfRevenue",
|
||||
"costAndExpenses",
|
||||
"netIncome",
|
||||
"grossProfit",
|
||||
"researchAndDevelopmentExpenses",
|
||||
"marketCap",
|
||||
"operatingExpenses",
|
||||
"operatingIncome",
|
||||
"ebitda",
|
||||
].includes(rule.name)
|
||||
) {
|
||||
return `${rule.condition} $${rule.value} Bn`;
|
||||
} else if (rule.name === 'aiSignal') {
|
||||
return `${rule.value === '2' ? 'Buy' : rule.value === '1' ? 'Hold' : rule.value === '0' ? 'Sell' : 'n/a'} Signal`;
|
||||
}
|
||||
else if (['avgVolume'].includes(rule.name)) {
|
||||
} else if (rule.name === "aiSignal") {
|
||||
return `${rule.value === "2" ? "Buy" : rule.value === "1" ? "Hold" : rule.value === "0" ? "Sell" : "n/a"} Signal`;
|
||||
} else if (["avgVolume"].includes(rule.name)) {
|
||||
return `${rule.condition} ${rule.value} Mio`;
|
||||
}
|
||||
else if (['var'].includes(rule.name)) {
|
||||
} else if (["var"].includes(rule.name)) {
|
||||
return `${rule.condition} ${rule.value}%`;
|
||||
}
|
||||
else if (['ratingRecommendation'].includes(rule.name)) {
|
||||
return rule.value === 2 ? 'Buy' : rule.value === 1 ? 'Hold' : 'Sell';
|
||||
}
|
||||
else if (['trendAnalysis','fundamentalAnalysis'].includes(rule.name)) {
|
||||
} else if (["ratingRecommendation"].includes(rule.name)) {
|
||||
return rule.value === 2 ? "Buy" : rule.value === 1 ? "Hold" : "Sell";
|
||||
} else if (["trendAnalysis", "fundamentalAnalysis"].includes(rule.name)) {
|
||||
return `${rule.condition} ${rule.value}% Accuracy`;
|
||||
} else {
|
||||
return `${rule.condition} ${rule.value}${rule.name.includes("Growth") ? " %" : ""}`;
|
||||
}
|
||||
else {
|
||||
return `${rule.condition} ${rule.value}${rule.name.includes('Growth') ? ' %' : ''}`;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export function formatETFName(inputString) {
|
||||
// Define special cases
|
||||
const specialCases = {
|
||||
"etf-mg": "ETFMG",
|
||||
"ark": "ARK",
|
||||
ark: "ARK",
|
||||
"index-iq": "IndexIQ",
|
||||
"bny-mellon": "BNY Mellon",
|
||||
"ssc": "SS&C",
|
||||
"pgim": "PGIM",
|
||||
ssc: "SS&C",
|
||||
pgim: "PGIM",
|
||||
"jpmorgan-chase": "JPMorgan Chase",
|
||||
"us-global-investors": "US Global Investors"
|
||||
"us-global-investors": "US Global Investors",
|
||||
// Add more special cases as needed
|
||||
};
|
||||
|
||||
@ -361,18 +416,19 @@ export function formatETFName(inputString) {
|
||||
}
|
||||
|
||||
// Split the input string into an array of words
|
||||
const words = inputString?.split('-');
|
||||
const words = inputString?.split("-");
|
||||
|
||||
// Capitalize the first letter of each word
|
||||
const capitalizedWords = words?.map(word => word.charAt(0)?.toUpperCase() + word?.slice(1));
|
||||
const capitalizedWords = words?.map(
|
||||
(word) => word.charAt(0)?.toUpperCase() + word?.slice(1)
|
||||
);
|
||||
|
||||
// Join the words back together with a space between them
|
||||
const formattedString = capitalizedWords?.join(' ');
|
||||
const formattedString = capitalizedWords?.join(" ");
|
||||
|
||||
return formattedString;
|
||||
}
|
||||
|
||||
|
||||
// Function to add days to a given date
|
||||
export function addDays(data, days, state) {
|
||||
let result;
|
||||
@ -381,19 +437,20 @@ export function addDays(data, days, state) {
|
||||
result = new Date(createdDate);
|
||||
result.setDate(result.getDate() + days);
|
||||
|
||||
if(state === 'date') {
|
||||
if (state === "date") {
|
||||
return result;
|
||||
} else {
|
||||
const differenceInTime = result - createdDate;
|
||||
const differenceInDays = Math.round(differenceInTime / (1000 * 60 * 60 * 24));
|
||||
const differenceInDays = Math.round(
|
||||
differenceInTime / (1000 * 60 * 60 * 24)
|
||||
);
|
||||
return Math.abs(differenceInDays);
|
||||
}
|
||||
}
|
||||
|
||||
export function pageTransitionIn(node, { duration, screenWidth }) {
|
||||
if (screenWidth >= 640)
|
||||
{
|
||||
return
|
||||
if (screenWidth >= 640) {
|
||||
return;
|
||||
}
|
||||
return {
|
||||
duration,
|
||||
@ -408,7 +465,7 @@ export function pageTransitionIn(node, { duration, screenWidth }) {
|
||||
z-index: 9999;
|
||||
transition: transform ${duration}ms ease-out;
|
||||
`;
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@ -419,7 +476,7 @@ export function pageTransitionOut(node, { duration }) {
|
||||
const eased = cubicOut(t);
|
||||
|
||||
return `
|
||||
transform: translateX(${(1-eased) * 100}%);
|
||||
transform: translateX(${(1 - eased) * 100}%);
|
||||
opacity: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@ -430,7 +487,6 @@ export function pageTransitionOut(node, { duration }) {
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
function convertNYTimeToLocalTime(nyTimeString) {
|
||||
// New York Time Zone
|
||||
@ -714,17 +770,15 @@ export function getPartyForPoliticians(name) {
|
||||
"Buddy Carter": "Republican",
|
||||
"John Fetterman": "Democratic",
|
||||
"Sharice Davids": "Democratic",
|
||||
"Jake Auchincloss": "Democratic",
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
// Combine first and last name to form the key
|
||||
// Combine first and last name to form the key
|
||||
const nameKey = `${name}`?.trim();
|
||||
// Return the party, or 'Unknown' if not found
|
||||
return senatorPartyMap[nameKey] || "Other";
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const listOfCountries = [
|
||||
"Afghanistan",
|
||||
"Albania",
|
||||
@ -921,5 +975,5 @@ export const listOfCountries = [
|
||||
"Vietnam",
|
||||
"Yemen",
|
||||
"Zambia",
|
||||
"Zimbabwe"
|
||||
"Zimbabwe",
|
||||
];
|
||||
Loading…
x
Reference in New Issue
Block a user