|
255 | 255 | return clamp(0.88 + Math.sqrt(Math.max(0, input.economicTradeDiversity)) / 58, 0.88, 1.22); |
256 | 256 | } |
257 | 257 |
|
| 258 | + function valueAddedStrength(input) { |
| 259 | + const industryScale = input.civilianFactories + input.militaryFactories * 0.35 + input.shipyards * 2.5; |
| 260 | + const diversityScore = clamp(Math.sqrt(Math.max(0, input.economicTradeDiversity)) / 12, 0, 1.18); |
| 261 | + const developmentScore = clamp(input.developmentLevel / 20, 0, 1); |
| 262 | + const industryScore = clamp(Math.log10(Math.max(industryScale, 1)) / 3, 0, 1); |
| 263 | + const shipyardScore = clamp(Math.sqrt(Math.max(input.shipyards, 0)) / 10, 0, 1); |
| 264 | + const stabilityScore = clamp(number(input.governmentalStability, 70) / 100, 0, 1); |
| 265 | + const corruptionScore = clamp((100 - number(input.corruption, 0)) / 100, 0, 1); |
| 266 | + return clamp( |
| 267 | + diversityScore * 30 |
| 268 | + + developmentScore * 22 |
| 269 | + + industryScore * 18 |
| 270 | + + shipyardScore * 12 |
| 271 | + + stabilityScore * 10 |
| 272 | + + corruptionScore * 8, |
| 273 | + 0, |
| 274 | + 100 |
| 275 | + ); |
| 276 | + } |
| 277 | + |
| 278 | + function valueAddedProfile(input) { |
| 279 | + const strength = valueAddedStrength(input); |
| 280 | + const strengthRatio = strength / 100; |
| 281 | + const autarkyRatio = clamp(input.autarkyIndex, 0, 100) / 100; |
| 282 | + const tradeAccess = clamp(1.1 - autarkyRatio * 0.55, 0.38, 1.08); |
| 283 | + const exportMultiplier = clamp(0.76 + Math.pow(strengthRatio, 1.18) * 1.45 - autarkyRatio * 0.22, 0.72, 2.08); |
| 284 | + const capacityMultiplier = clamp(0.78 + strengthRatio * 0.55 - autarkyRatio * 0.25, 0.72, 1.32); |
| 285 | + const productiveImportShare = clamp(Math.pow(strengthRatio, 1.08) * tradeAccess, 0, 0.82); |
| 286 | + return { |
| 287 | + strength, |
| 288 | + strengthRatio, |
| 289 | + exportMultiplier, |
| 290 | + capacityMultiplier, |
| 291 | + productiveImportShare |
| 292 | + }; |
| 293 | + } |
| 294 | + |
258 | 295 | function physicalTradeBase(input) { |
259 | 296 | const populationMarket = Math.sqrt(Math.max(input.population, 0) / 1000000) * 5200; |
260 | 297 | const industrialMarket = input.civilianFactories * 1500 + input.militaryFactories * 340 + input.shipyards * 3000; |
|
283 | 320 | const reliance = Math.pow(Math.max(0, input.exportReliance) / 100, 1.32); |
284 | 321 | const production = input.civilianFactories * 850 + input.shipyards * 2500 + input.developmentLevel * 1750; |
285 | 322 | const policy = tradePolicyProfile(input.tradePolicy); |
| 323 | + const valueAdded = valueAddedProfile(input); |
286 | 324 | return Math.max( |
287 | 325 | 1, |
288 | 326 | (physicalTradeBase(input) * reliance * 0.92 + production) |
289 | 327 | * diversityResilience(input) |
| 328 | + * valueAdded.exportMultiplier |
290 | 329 | * policy.exportSupply |
291 | 330 | * sanctionNetworkAccess(input.sanctionsLevel) |
292 | 331 | * autarkyTradeAccess(input, "export") |
|
312 | 351 | function worldPoolCapacityScore(input) { |
313 | 352 | const policy = tradePolicyProfile(input.tradePolicy); |
314 | 353 | const logistics = 0.58 + tradeLogisticsProfile(input).overall / 82; |
| 354 | + const valueAdded = valueAddedProfile(input); |
315 | 355 | return Math.max( |
316 | 356 | 1, |
317 | 357 | physicalTradeBase(input) |
|
320 | 360 | * autarkyTradeAccess(input) |
321 | 361 | * logistics |
322 | 362 | * diversityResilience(input) |
| 363 | + * valueAdded.capacityMultiplier |
323 | 364 | ); |
324 | 365 | } |
325 | 366 |
|
|
2123 | 2164 | const totalFlow = Math.max(0, importFlow + exportFlow); |
2124 | 2165 | const policy = tradePolicyProfile(current.tradePolicy); |
2125 | 2166 | const logistics = tradeLogisticsProfile(current); |
| 2167 | + const valueAdded = valueAddedProfile(current); |
2126 | 2168 | const relianceGap = number(current.exportReliance, 0) - number(current.importReliance, 0); |
2127 | 2169 | const relianceGapSignal = Math.sign(relianceGap) * Math.pow(Math.abs(relianceGap), 0.88); |
2128 | 2170 | const relianceAverage = Math.max(1, (number(current.exportReliance, 0) + number(current.importReliance, 0)) / 2); |
2129 | 2171 | const normalizedGap = relianceGap / relianceAverage; |
2130 | 2172 | const balanceScale = 70 + Math.sqrt(Math.max(totalFlow, 0)) * 0.24 + Math.sqrt(Math.max(current.budgetCapacity, 0)) * 3.2; |
2131 | 2173 | const structuralBalance = relianceGapSignal * balanceScale * policy.balanceRisk; |
2132 | | - const flowBalance = exportFlow * 0.014 - importFlow * 0.015; |
| 2174 | + const exportValuePremium = exportFlow * valueAdded.strengthRatio * 0.1; |
| 2175 | + const productiveImportCredit = importFlow * valueAdded.productiveImportShare * 0.038; |
| 2176 | + const rawImportCost = importFlow * (0.018 + clamp(current.autarkyIndex, 0, 100) / 10000); |
| 2177 | + const flowBalance = exportFlow * 0.022 + exportValuePremium + productiveImportCredit - rawImportCost; |
2133 | 2178 | const tariffBalance = number(impact.tariffRevenueDelta, 0) * 0.55 - number(impact.importCostDelta, 0) * 0.36; |
2134 | | - const imbalancePenalty = -Math.pow(Math.abs(normalizedGap), 1.35) * balanceScale * 0.72 * (relianceGap < 0 ? 1.14 : 0.34); |
| 2179 | + const importGapPressure = relianceGap < 0 ? clamp(1.2 - valueAdded.productiveImportShare * 0.78, 0.46, 1.2) : 0.34; |
| 2180 | + const imbalancePenalty = -Math.pow(Math.abs(normalizedGap), 1.35) * balanceScale * 0.72 * importGapPressure; |
2135 | 2181 | const tradeBalance = roundCurrency(flowBalance + structuralBalance + tariffBalance + imbalancePenalty + number(impact.tradeBalanceDelta, 0)); |
2136 | 2182 | const tradeCapacity = roundCurrency( |
2137 | 2183 | worldPoolCapacityScore(current) / 600 |
2138 | 2184 | + logistics.overall * 140 |
2139 | 2185 | + diversityResilience(current) * 1800 |
| 2186 | + + valueAdded.strength * 42 |
2140 | 2187 | ); |
2141 | 2188 | const tradeFlow = roundCurrency(totalFlow); |
2142 | 2189 | const economicImpactScore = Math.max( |
|
0 commit comments