| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- import {cachedFetchJSON} from './cache';
- const username = document.querySelector('#username') as HTMLInputElement;
- const apiKey = document.querySelector('#api-key') as HTMLInputElement;
- const cxSelect = document.querySelector('#cx') as HTMLSelectElement;
- {
- const storedUsername = localStorage.getItem('fio-username');
- if (storedUsername)
- username.value = storedUsername;
- const storedApiKey = localStorage.getItem('fio-api-key');
- if (storedApiKey)
- apiKey.value = storedApiKey;
- }
- document.querySelector('#fetch')!.addEventListener('click', async () => {
- const loader = document.querySelector('#loader') as HTMLElement;
- loader.style.display = 'block';
- try {
- await calculate(username.value, apiKey.value, cxSelect.value);
- localStorage.setItem('fio-username', username.value);
- localStorage.setItem('fio-api-key', apiKey.value);
- } catch (e) {
- console.error(e);
- (document.querySelector('#junk') as HTMLElement).innerText = e instanceof Error ? e.message : String(e);
- }
- loader.style.display = 'none';
- });
- const format = new Intl.NumberFormat(undefined, {maximumFractionDigits: 2}).format;
- async function calculate(username: string, apiKey: string, cx: string): Promise<void> {
- const renderTarget = document.querySelector('#junk')!;
- renderTarget.innerHTML = '';
- const fioBurns: FIOBurn[] = await cachedFetchJSON('https://rest.fnar.net/fioweb/burn/user/' + username,
- {headers: {'Authorization': apiKey}});
- const totalConsumption = new Map<string, number>();
- for (const fioBurn of fioBurns) {
- const netConsumption = new Map<string, number>();
- for (const item of fioBurn.OrderProduction)
- netConsumption.set(item.MaterialTicker, -item.DailyAmount);
- for (const item of [...fioBurn.OrderConsumption, ...fioBurn.WorkforceConsumption])
- netConsumption.set(item.MaterialTicker, (netConsumption.get(item.MaterialTicker) ?? 0) + item.DailyAmount);
- for (const [ticker, consumption] of netConsumption)
- if (consumption > 0)
- totalConsumption.set(ticker, (totalConsumption.get(ticker) ?? 0) + consumption);
- }
- const warehouse = await warehouseInventory(username, apiKey, cx);
- const supplies = [...warehouse.entries()].map(([ticker, amount]) => {
- const consumption = totalConsumption.get(ticker);
- return {
- ticker,
- amount,
- days: consumption === undefined || consumption <= 0 ? Number.POSITIVE_INFINITY : amount / consumption,
- consumption: consumption ?? 0,
- };
- });
- supplies.sort((a, b) => b.days - a.days);
- const h2 = document.createElement('h2');
- h2.textContent = 'warehouse supply';
- renderTarget.appendChild(h2);
- const table = document.createElement('table');
- table.innerHTML = `
- <thead>
- <tr>
- <th>mat</th>
- <th>have</th>
- <th>consumption/day</th>
- <th>supply</th>
- </tr>
- </thead>`;
- const tbody = document.createElement('tbody');
- for (const supply of supplies) {
- const tr = document.createElement('tr');
- tr.innerHTML = `
- <td>${supply.ticker}</td>
- <td>${format(supply.amount)}</td>
- <td>${format(supply.consumption)}</td>
- <td>${Number.isFinite(supply.days) ? format(supply.days) + ' d' : '∞'}</td>
- `;
- tbody.appendChild(tr);
- }
- table.appendChild(tbody);
- renderTarget.appendChild(table);
- }
- async function warehouseInventory(username: string, apiKey: string, cx: string): Promise<Map<string, number>> {
- const warehouses: Warehouse[] = await cachedFetchJSON('https://rest.fnar.net/sites/warehouses/' + username,
- {headers: {'Authorization': apiKey}});
- const inventory = new Map<string, number>();
- for (const warehouse of warehouses)
- if (warehouse.LocationNaturalId === cx) {
- const storage: Storage = await cachedFetchJSON(`https://rest.fnar.net/storage/${username}/${warehouse.StoreId}`,
- {headers: {'Authorization': apiKey}});
- for (const item of storage.StorageItems)
- inventory.set(item.MaterialTicker, item.MaterialAmount);
- break;
- }
- return inventory;
- }
- interface StorageItem {
- MaterialTicker: string;
- MaterialAmount: number;
- }
- interface Storage {
- Name: string;
- StorageItems: StorageItem[];
- WeightLoad: number;
- VolumeLoad: number;
- Type: 'STORE' | 'WAREHOUSE_STORE' | 'FTL_FUEL_STORE' | 'STL_FUEL_STORE' | 'SHIP_STORE';
- }
- interface Warehouse {
- StoreId: string;
- LocationNaturalId: string;
- }
- interface Amount {
- MaterialTicker: string;
- DailyAmount: number;
- }
- interface FIOBurn {
- PlanetId: string;
- PlanetName: string;
- PlanetNaturalId: string;
- Error: any;
- OrderConsumption: Amount[];
- WorkforceConsumption: Amount[];
- Inventory: StorageItem[];
- OrderProduction: Amount[];
- }
|