@elite-dangerous-almanac/core 0.2.7 → 0.2.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/PROVENANCE/equipment/SOURCES.md +149 -27
  2. package/PROVENANCE/i18n/SOURCES.md +176 -27
  3. package/PROVENANCE/ships/SOURCES.md +10 -18
  4. package/README.md +20 -5
  5. package/THIRD_PARTY_NOTICES.md +4 -1
  6. package/dist/{chunk-AAU7OM47.js → chunk-2OBUSQA7.js} +1 -1
  7. package/dist/{chunk-AAU7OM47.js.map → chunk-2OBUSQA7.js.map} +1 -1
  8. package/dist/{chunk-MVBVXK3G.js → chunk-3GNYPM6J.js} +1 -1
  9. package/dist/{chunk-MVBVXK3G.js.map → chunk-3GNYPM6J.js.map} +1 -1
  10. package/dist/{chunk-A6OINYNP.js → chunk-3WGXGBW5.js} +1 -1
  11. package/dist/{chunk-NZXSIHAW.js → chunk-5YEHJM6V.js} +1 -1
  12. package/dist/{chunk-NZXSIHAW.js.map → chunk-5YEHJM6V.js.map} +1 -1
  13. package/dist/{chunk-7S7ZTZZY.js → chunk-7EWZGDWY.js} +1 -1
  14. package/dist/chunk-DAQ3PJ4R.js +1 -0
  15. package/dist/chunk-DAQ3PJ4R.js.map +1 -0
  16. package/dist/chunk-DHACRCLI.js +1 -0
  17. package/dist/chunk-DHACRCLI.js.map +1 -0
  18. package/dist/chunk-FJIWJYKO.js +1 -0
  19. package/dist/chunk-FJIWJYKO.js.map +1 -0
  20. package/dist/chunk-GIGRBFIJ.js +1 -0
  21. package/dist/{chunk-MGRDB2BZ.js.map → chunk-GIGRBFIJ.js.map} +1 -1
  22. package/dist/{chunk-FMA36V6A.js → chunk-IMNOEFUE.js} +1 -1
  23. package/dist/{chunk-FMA36V6A.js.map → chunk-IMNOEFUE.js.map} +1 -1
  24. package/dist/chunk-IN36YSS4.js +1 -0
  25. package/dist/chunk-IN36YSS4.js.map +1 -0
  26. package/dist/chunk-IUSMAX5T.js +1 -0
  27. package/dist/{chunk-6GJHUWMO.js.map → chunk-IUSMAX5T.js.map} +1 -1
  28. package/dist/{chunk-XQJERZUS.js → chunk-JCYOE3C4.js} +1 -1
  29. package/dist/{chunk-XQJERZUS.js.map → chunk-JCYOE3C4.js.map} +1 -1
  30. package/dist/chunk-LWNBWRKL.js +1 -0
  31. package/dist/{chunk-B7EYTZRK.js.map → chunk-LWNBWRKL.js.map} +1 -1
  32. package/dist/chunk-MT5AHPNP.js +1 -0
  33. package/dist/{chunk-ZEN5K3GE.js.map → chunk-MT5AHPNP.js.map} +1 -1
  34. package/dist/chunk-OLKOWR7S.js +1 -0
  35. package/dist/chunk-OLKOWR7S.js.map +1 -0
  36. package/dist/chunk-SC4MEHVY.js +1 -0
  37. package/dist/chunk-SC4MEHVY.js.map +1 -0
  38. package/dist/chunk-W5ULI75F.js +1 -0
  39. package/dist/chunk-W5ULI75F.js.map +1 -0
  40. package/dist/chunk-WV7QCDL5.js +1 -0
  41. package/dist/chunk-WV7QCDL5.js.map +1 -0
  42. package/dist/{chunk-F7VWRDSL.js → chunk-YJAH6DFY.js} +1 -1
  43. package/dist/chunk-YJAH6DFY.js.map +1 -0
  44. package/dist/equipment/engineering.d.ts +53 -1
  45. package/dist/equipment/engineering.js +1 -1
  46. package/dist/equipment/index.d.ts +13 -2
  47. package/dist/equipment/index.js +1 -1
  48. package/dist/equipment/modification-journal.js +1 -1
  49. package/dist/equipment/modifications.d.ts +32 -9
  50. package/dist/equipment/modifications.js +1 -1
  51. package/dist/equipment/suits.d.ts +32 -2
  52. package/dist/equipment/suits.js +1 -1
  53. package/dist/equipment/upgrade-costs.js +1 -1
  54. package/dist/equipment/weapons.d.ts +16 -2
  55. package/dist/equipment/weapons.js +1 -1
  56. package/dist/i18n/index.d.ts +76 -0
  57. package/dist/i18n/index.js +1 -1
  58. package/dist/i18n/personal-modifications.d.ts +68 -0
  59. package/dist/i18n/personal-modifications.js +1 -0
  60. package/dist/i18n/personal-modifications.js.map +1 -0
  61. package/dist/i18n/personal-weapons.d.ts +33 -0
  62. package/dist/i18n/personal-weapons.js +1 -0
  63. package/dist/i18n/personal-weapons.js.map +1 -0
  64. package/dist/i18n/suits.d.ts +59 -0
  65. package/dist/i18n/suits.js +1 -0
  66. package/dist/i18n/suits.js.map +1 -0
  67. package/dist/materials/index.js +1 -1
  68. package/dist/materials/micro-resources-all.js +1 -1
  69. package/dist/materials/micro-resources.js +1 -1
  70. package/dist/ships/build-metrics.js +1 -1
  71. package/dist/ships/index.js +1 -1
  72. package/dist/ships/loadout-validation.d.ts +7 -2
  73. package/dist/ships/loadout-validation.js +1 -1
  74. package/dist/ships/modules-all.js +1 -1
  75. package/dist/ships/modules-internal.d.ts +17 -6
  76. package/dist/ships/modules-internal.js +1 -1
  77. package/dist/ships/modules.d.ts +5 -1
  78. package/dist/ships/modules.js +1 -1
  79. package/dist/ships/pre-engineered-stats.js +1 -1
  80. package/dist/ships/shield-capacitor.js +1 -1
  81. package/dist/ships/ship-loadout.d.ts +6 -0
  82. package/dist/ships/ship-loadout.js +1 -1
  83. package/dist/ships/weapons.js +1 -1
  84. package/package.json +13 -1
  85. package/dist/chunk-4U7KYQGK.js +0 -1
  86. package/dist/chunk-4U7KYQGK.js.map +0 -1
  87. package/dist/chunk-6GJHUWMO.js +0 -1
  88. package/dist/chunk-B7EYTZRK.js +0 -1
  89. package/dist/chunk-C5HG4GJI.js +0 -1
  90. package/dist/chunk-C5HG4GJI.js.map +0 -1
  91. package/dist/chunk-F7VWRDSL.js.map +0 -1
  92. package/dist/chunk-KLC5XT6F.js +0 -1
  93. package/dist/chunk-KLC5XT6F.js.map +0 -1
  94. package/dist/chunk-MGRDB2BZ.js +0 -1
  95. package/dist/chunk-TSEDU73T.js +0 -1
  96. package/dist/chunk-TSEDU73T.js.map +0 -1
  97. package/dist/chunk-XRGECU7S.js +0 -1
  98. package/dist/chunk-XRGECU7S.js.map +0 -1
  99. package/dist/chunk-ZEN5K3GE.js +0 -1
  100. /package/dist/{chunk-A6OINYNP.js.map → chunk-3WGXGBW5.js.map} +0 -0
  101. /package/dist/{chunk-7S7ZTZZY.js.map → chunk-7EWZGDWY.js.map} +0 -0
@@ -1 +1 @@
1
- import{loadoutInternals,fittedThrusterParamsFor,preEngineeredVariantFor,powerConsumerFor,powerAvailable,heatInputResultFor,completeResult,cellBankInputsFor,armourInputFor,weaponStatsFor,weaponsCapacitorInputFor,mobilityInputResultFor,shieldInputResultFor,shieldCapacitorInputResultFor,shieldRecoveryInputResultFor,distributorInputResultFor,incompleteResult}from"./chunk-XRGECU7S.js";import{weaponsCapacitorMetrics}from"./chunk-M4FZRDAH.js";import{weaponMetrics,sumWeaponMetrics}from"./chunk-AAU7OM47.js";import{powerBudget}from"./chunk-GGQMIQPC.js";import{isNonOutfittingSlot,isBuiltInHullModule,orderBySlotLayout}from"./chunk-4U7KYQGK.js";import{shieldCapacitorMetrics}from"./chunk-XQJERZUS.js";import{cellBankSummary,shieldRecovery}from"./chunk-JMAXSXXQ.js";import{shieldMetrics}from"./chunk-5VWACBTN.js";import{heatMetrics}from"./chunk-6HA2YIKW.js";import{frameShiftDriveMassFactor,singleJumpRange,fuelPerJump,totalRange}from"./chunk-VTMCSCXV.js";import{calculateUnladenMass}from"./chunk-C3LLPLLD.js";import{mobilityCapacitorMetrics}from"./chunk-VEEBJFJ7.js";import{mobilityMetrics}from"./chunk-A4QKXXZD.js";import{distributorMetrics}from"./chunk-M2TCZKRT.js";import{getExperimentalEffectCost}from"./chunk-CJK2IBI2.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{armourMetrics}from"./chunk-Q5ALV3DI.js";import{requirePips,requireFiniteNonNegative}from"./chunk-65FZECUX.js";import{getBlueprintCost}from"./chunk-ETWMPMZP.js";import{sumMaterials}from"./chunk-A7IVMYNF.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var FACADE="BuildMetrics";function requireLoadOptions(scope,options){for(const field of["fuel","cargo"]){const value=options[field];if(value!==void 0)requireFiniteNonNegative(scope,field,value)}}var BuildMetrics=class _BuildMetrics{#build;#state;constructor(build,state){this.#build=build;this.#state=state}static of(build){return new _BuildMetrics(build,loadoutInternals(build,`${FACADE}.of: build`))}loadout(){return this.#build}frameShiftDrive(){const drive=this.#state.resolveDrive();if(drive===null){throw new TypeError(`${FACADE}: build has no frame shift drive`)}return drive}thrusters(){return fittedThrusterParamsFor(this.#state.modules(),this.#state.statsFor)}frameShiftDriveMassFactor(options={}){requireLoadOptions(`${FACADE}.frameShiftDriveMassFactor`,options);return frameShiftDriveMassFactor(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}maxJumpRange(){const fsd=this.frameShiftDrive();return singleJumpRange(this.#loadedMass(0),this.#maxJumpFuel(fsd),fsd)}jumpRange(options={}){requireLoadOptions(`${FACADE}.jumpRange`,options);return singleJumpRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}ladenJumpRange(){return this.jumpRange({cargo:this.#build.cargoCapacity})}fuelPerJump(distance,options={}){requireLoadOptions(`${FACADE}.fuelPerJump`,options);return fuelPerJump(distance,this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}totalRange(options={}){requireLoadOptions(`${FACADE}.totalRange`,options);return totalRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}standardLoadResult(load){return this.#standardLoad(load)}jumpRangeSummary(){const maximum=this.#require(this.standardLoadResult("maximum"),"maximum load");const unladen=this.#require(this.standardLoadResult("unladen"),"unladen load");const laden=this.#require(this.standardLoadResult("laden"),"laden load");return{max:this.jumpRange(maximum),unladen:this.jumpRange(unladen),laden:this.jumpRange(laden),totalMax:this.totalRange(maximum),totalUnladen:this.totalRange(unladen),totalLaden:this.totalRange(laden)}}buildMass(options={}){requireLoadOptions(`${FACADE}.buildMass`,options);const unladen=this.#build.unladenMass;const fuel=options.fuel??this.#build.fuelCapacity.main;const cargo=options.cargo??0;return Object.freeze({hull:this.#state.ship.hullMass,modules:calculateUnladenMass(0,this.#state.calculationModules()),unladen:unladen,fuel:fuel,cargo:cargo,total:unladen+fuel+cargo})}buildCost(){const hull=this.#state.ship.hullCost;let modules=0;let mercCoins=0;const unpriced=[];const materials=[];for(const module of this.#state.modules()){const stats=this.#state.statsFor(module);if(stats?.cost!==void 0){modules+=stats.cost}else if(stats!==null||!isNonOutfittingSlot(module.Slot)&&!isBuiltInHullModule(module)){unpriced.push({slot:module.Slot,symbol:module.Item})}const variant=preEngineeredVariantFor(module);mercCoins+=variant?.mercCoinCost??0;const engineering=module.Engineering;if(!engineering)continue;const grade=engineering.Level;const bought=variant?.grade??0;if(Number.isInteger(grade)&&grade>bought&&grade<=5){const climb=getBlueprintCost(engineering.BlueprintName,grade,bought);if(climb){materials.push(climb.materials);mercCoins+=climb.mercCoins}}const experimental=engineering.ExperimentalEffect;if(experimental!==void 0&&experimental.toLowerCase()!==variant?.experimentalEffectSymbol?.toLowerCase()){const cost=getExperimentalEffectCost(experimental);if(cost)materials.push(cost)}}return deepFreeze({credits:{total:hull+modules,hull:hull,modules:modules,rebuy:Math.trunc((hull+modules)*.05),unpriced:unpriced},mercCoins:mercCoins,materials:sumMaterials(...materials)})}powerBudget(){const modules=this.#state.modules();const consumers=[];for(const module of modules){const consumer=powerConsumerFor(module,this.#state.statsFor(module));if(consumer)consumers.push(consumer)}return powerBudget(powerAvailable(modules,this.#state.statsFor),consumers)}heatMetricsResult(){const input=heatInputResultFor(this.#state.ship,this.#state.effectiveModules(),this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(heatMetrics(input.value)):input}mobilityMetricsResult(options={}){return this.#mobility(options)}mobilityCapacitorMetricsResult(options={}){return this.#mobilityCapacitor(options)}shieldMetricsResult(){return this.#shields()}shieldCapacitorMetricsResult(options={}){return this.#shieldCapacitor(options)}shieldRecoveryResult(options={}){return this.#recovery(options)}cellBanks(){return cellBankSummary(orderBySlotLayout(cellBankInputsFor(this.#state.modules(),this.powerBudget(),this.#state.statsFor),this.#state.layout(),bank=>bank.slot))}armourMetrics(){return armourMetrics(armourInputFor(this.#state.ship,this.#state.modules(),this.#state.statsFor))}weaponMetrics(){const weapons=[];for(const module of this.#state.modules()){const record=this.#state.statsFor(module);const stats=weaponStatsFor(this.#state.effectiveModule(module),record);if(!stats)continue;weapons.push({slot:module.Slot,symbol:module.Item,name:record?.name??module.Item,enabled:module.On!==false,metrics:weaponMetrics(stats),ammunition:ammunitionCapacity(stats),...stats.maximumRange===void 0?{}:{maximumRange:stats.maximumRange},...stats.falloffRange===void 0?{}:{falloffRange:stats.falloffRange},...stats.projectileRange===void 0?{}:{projectileRange:{...stats.projectileRange}},...stats.armourPiercing===void 0?{}:{armourPiercing:stats.armourPiercing}})}const orderedWeapons=orderBySlotLayout(weapons,this.#state.layout(),weapon=>weapon.slot);return{weapons:orderedWeapons,total:sumWeaponMetrics(orderedWeapons.filter(weapon=>weapon.enabled).map(weapon=>weapon.metrics))}}weaponsCapacitorMetrics(options={}){const weaponsPips=requirePips(`${FACADE}.weaponsCapacitorMetrics`,"weaponsPips",options.weaponsPips??4);return weaponsCapacitorMetrics(weaponsCapacitorInputFor(this.#state.effectiveModules(),weaponsPips,this.powerBudget(),this.#state.statsFor))}distributorMetricsResult(options={}){return this.#distributor(options)}#mobility(options){const input=this.#mobilityInput(`${FACADE}.mobilityMetricsResult`,options);return input.complete?completeResult(mobilityMetrics(input.value)):input}#mobilityCapacitor(options){const scope=`${FACADE}.mobilityCapacitorMetricsResult`;const enginesPips=requirePips(scope,"enginesPips",options.enginesPips??4);const input=this.#mobilityInput(scope,options);return input.complete?completeResult(mobilityCapacitorMetrics({...input.value,enginesPips:enginesPips})):input}#mobilityInput(scope,options){requireLoadOptions(scope,options);return mobilityInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),()=>this.#loadedMass(options.cargo??0)+(options.fuel??this.#state.statedMainFuel()??this.#build.fuelCapacity.main),this.#state.statsFor)}#shields(){const input=shieldInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(shieldMetrics(input.value)):input}#shieldCapacitor(options){const systemsPips=requirePips(`${FACADE}.shieldCapacitorMetricsResult`,"systemsPips",options.systemsPips??4);const input=shieldCapacitorInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldCapacitorMetrics(input.value)):input}#recovery(options){const systemsPips=requirePips(`${FACADE}.shieldRecoveryResult`,"systemsPips",options.systemsPips??4);const input=shieldRecoveryInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldRecovery(input.value)):input}#distributor(options){const scope=`${FACADE}.distributorMetricsResult`;const pips={systemsPips:requirePips(scope,"systemsPips",options.systemsPips??4),enginesPips:requirePips(scope,"enginesPips",options.enginesPips??4),weaponsPips:requirePips(scope,"weaponsPips",options.weaponsPips??4)};const input=distributorInputResultFor(this.#state.effectiveModules(),pips,this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(distributorMetrics(input.value)):input}#standardLoad(load){if(load!=="maximum"&&load!=="unladen"&&load!=="laden"){throw new RangeError(`${FACADE}.standardLoadResult: load must be 'maximum', 'unladen', or 'laden'`)}const fuel=this.#build.fuelCapacity;const cargo=load==="laden"?this.#build.cargoCapacity:0;const mass=load==="maximum"?this.#build.unladenMass:0;let drive=null;let maximumFuel=null;if(load==="maximum"){const fitted=this.#state.frameShiftDriveModule();let driveError=null;try{drive=this.#state.resolveDrive();maximumFuel=drive?.maxFuel??null}catch(error){if(!(error instanceof Error))throw error;driveError=error}if(maximumFuel===null){return incompleteResult([{field:"frameShiftDrive",reason:fitted?"unresolved":"missing",slot:fitted?.Slot??"FrameShiftDrive",...fitted?{symbol:fitted.Item}:{},message:driveError?.message??"FrameShiftDrive: no frame shift drive is fitted",params:fitted?{field:"frameShiftDrive",reason:"unresolved",slot:fitted.Slot,symbol:fitted.Item}:{field:"frameShiftDrive",reason:"missing",slot:"FrameShiftDrive"}}])}}const carriedFuel=load==="maximum"?Math.min(fuel.main,maximumFuel):fuel.main;const value=Object.freeze({fuel:carriedFuel,cargo:cargo,mass:this.#build.unladenMass+carriedFuel+cargo});if(load==="maximum"){try{this.jumpRange(value)}catch(error){if(!(error instanceof RangeError))throw error;const fitted=this.#state.frameShiftDriveModule();const field=drive!==null&&(!Number.isFinite(drive.maxFuel)||drive.maxFuel<0)?"frameShiftDrive":!Number.isFinite(value.fuel)||value.fuel<0?"fuelCapacity":!Number.isFinite(mass)||mass<0?"mass":"frameShiftDrive";const driveParams=field==="frameShiftDrive"&&fitted?{slot:fitted.Slot,symbol:fitted.Item}:{};return incompleteResult([{field:field,reason:"invalid",...driveParams,message:error.message,params:{field:field,reason:"invalid",...driveParams}}])}}return completeResult(value)}#require(result,what){if(result.value===null){throw new TypeError(`${FACADE}: cannot determine ${what} (${result.issues.map(issue=>issue.message).join("; ")})`)}return result.value}#loadedMass(cargo){return this.#build.unladenMass+cargo}#maxJumpFuel(fsd){return Math.min(this.#build.fuelCapacity.main,fsd.maxFuel)}};export{BuildMetrics};//# sourceMappingURL=chunk-F7VWRDSL.js.map
1
+ import{weaponsCapacitorMetrics}from"./chunk-M4FZRDAH.js";import{shieldCapacitorMetrics}from"./chunk-JCYOE3C4.js";import{cellBankSummary,shieldRecovery}from"./chunk-JMAXSXXQ.js";import{loadoutInternals,fittedThrusterParamsFor,preEngineeredVariantFor,powerConsumerFor,powerAvailable,heatInputResultFor,completeResult,cellBankInputsFor,armourInputFor,weaponStatsFor,weaponsCapacitorInputFor,mobilityInputResultFor,shieldInputResultFor,shieldCapacitorInputResultFor,shieldRecoveryInputResultFor,distributorInputResultFor,incompleteResult}from"./chunk-DHACRCLI.js";import{weaponMetrics,sumWeaponMetrics}from"./chunk-2OBUSQA7.js";import{shieldMetrics}from"./chunk-5VWACBTN.js";import{powerBudget}from"./chunk-GGQMIQPC.js";import{isNonOutfittingSlot,isBuiltInHullModule,orderBySlotLayout}from"./chunk-IN36YSS4.js";import{mobilityCapacitorMetrics}from"./chunk-VEEBJFJ7.js";import{mobilityMetrics}from"./chunk-A4QKXXZD.js";import{getExperimentalEffectCost}from"./chunk-CJK2IBI2.js";import{heatMetrics}from"./chunk-6HA2YIKW.js";import{frameShiftDriveMassFactor,singleJumpRange,fuelPerJump,totalRange}from"./chunk-VTMCSCXV.js";import{calculateUnladenMass}from"./chunk-C3LLPLLD.js";import{armourMetrics}from"./chunk-Q5ALV3DI.js";import{getBlueprintCost}from"./chunk-ETWMPMZP.js";import{sumMaterials}from"./chunk-A7IVMYNF.js";import{distributorMetrics}from"./chunk-M2TCZKRT.js";import{requirePips,requireFiniteNonNegative}from"./chunk-65FZECUX.js";import{ammunitionCapacity}from"./chunk-AA3K5XUE.js";import{deepFreeze}from"./chunk-DURKO7JU.js";var FACADE="BuildMetrics";function requireLoadOptions(scope,options){for(const field of["fuel","cargo"]){const value=options[field];if(value!==void 0)requireFiniteNonNegative(scope,field,value)}}var BuildMetrics=class _BuildMetrics{#build;#state;constructor(build,state){this.#build=build;this.#state=state}static of(build){return new _BuildMetrics(build,loadoutInternals(build,`${FACADE}.of: build`))}loadout(){return this.#build}frameShiftDrive(){const drive=this.#state.resolveDrive();if(drive===null){throw new TypeError(`${FACADE}: build has no frame shift drive`)}return drive}thrusters(){return fittedThrusterParamsFor(this.#state.modules(),this.#state.statsFor)}frameShiftDriveMassFactor(options={}){requireLoadOptions(`${FACADE}.frameShiftDriveMassFactor`,options);return frameShiftDriveMassFactor(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}maxJumpRange(){const fsd=this.frameShiftDrive();return singleJumpRange(this.#loadedMass(0),this.#maxJumpFuel(fsd),fsd)}jumpRange(options={}){requireLoadOptions(`${FACADE}.jumpRange`,options);return singleJumpRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}ladenJumpRange(){return this.jumpRange({cargo:this.#build.cargoCapacity})}fuelPerJump(distance,options={}){requireLoadOptions(`${FACADE}.fuelPerJump`,options);return fuelPerJump(distance,this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}totalRange(options={}){requireLoadOptions(`${FACADE}.totalRange`,options);return totalRange(this.#loadedMass(options.cargo??0),options.fuel??this.#build.fuelCapacity.main,this.frameShiftDrive())}standardLoadResult(load){return this.#standardLoad(load)}jumpRangeSummary(){const maximum=this.#require(this.standardLoadResult("maximum"),"maximum load");const unladen=this.#require(this.standardLoadResult("unladen"),"unladen load");const laden=this.#require(this.standardLoadResult("laden"),"laden load");return{max:this.jumpRange(maximum),unladen:this.jumpRange(unladen),laden:this.jumpRange(laden),totalMax:this.totalRange(maximum),totalUnladen:this.totalRange(unladen),totalLaden:this.totalRange(laden)}}buildMass(options={}){requireLoadOptions(`${FACADE}.buildMass`,options);const unladen=this.#build.unladenMass;const fuel=options.fuel??this.#build.fuelCapacity.main;const cargo=options.cargo??0;return Object.freeze({hull:this.#state.ship.hullMass,modules:calculateUnladenMass(0,this.#state.calculationModules()),unladen:unladen,fuel:fuel,cargo:cargo,total:unladen+fuel+cargo})}buildCost(){const hull=this.#state.ship.hullCost;let modules=0;let mercCoins=0;const unpriced=[];const materials=[];for(const module of this.#state.modules()){const stats=this.#state.statsFor(module);if(stats?.cost!==void 0){modules+=stats.cost}else if(stats!==null||!isNonOutfittingSlot(module.Slot)&&!isBuiltInHullModule(module)){unpriced.push({slot:module.Slot,symbol:module.Item})}const variant=preEngineeredVariantFor(module);mercCoins+=variant?.mercCoinCost??0;const engineering=module.Engineering;if(!engineering)continue;const grade=engineering.Level;const bought=variant?.grade??0;if(Number.isInteger(grade)&&grade>bought&&grade<=5){const climb=getBlueprintCost(engineering.BlueprintName,grade,bought);if(climb){materials.push(climb.materials);mercCoins+=climb.mercCoins}}const experimental=engineering.ExperimentalEffect;if(experimental!==void 0&&experimental.toLowerCase()!==variant?.experimentalEffectSymbol?.toLowerCase()){const cost=getExperimentalEffectCost(experimental);if(cost)materials.push(cost)}}return deepFreeze({credits:{total:hull+modules,hull:hull,modules:modules,rebuy:Math.trunc((hull+modules)*.05),unpriced:unpriced},mercCoins:mercCoins,materials:sumMaterials(...materials)})}powerBudget(){const modules=this.#state.modules();const consumers=[];for(const module of modules){const consumer=powerConsumerFor(module,this.#state.statsFor(module));if(consumer)consumers.push(consumer)}return powerBudget(powerAvailable(modules,this.#state.statsFor),consumers)}heatMetricsResult(){const input=heatInputResultFor(this.#state.ship,this.#state.effectiveModules(),this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(heatMetrics(input.value)):input}mobilityMetricsResult(options={}){return this.#mobility(options)}mobilityCapacitorMetricsResult(options={}){return this.#mobilityCapacitor(options)}shieldMetricsResult(){return this.#shields()}shieldCapacitorMetricsResult(options={}){return this.#shieldCapacitor(options)}shieldRecoveryResult(options={}){return this.#recovery(options)}cellBanks(){return cellBankSummary(orderBySlotLayout(cellBankInputsFor(this.#state.modules(),this.powerBudget(),this.#state.statsFor),this.#state.layout(),bank=>bank.slot))}armourMetrics(){return armourMetrics(armourInputFor(this.#state.ship,this.#state.modules(),this.#state.statsFor))}weaponMetrics(){const weapons=[];for(const module of this.#state.modules()){const record=this.#state.statsFor(module);const stats=weaponStatsFor(this.#state.effectiveModule(module),record);if(!stats)continue;weapons.push({slot:module.Slot,symbol:module.Item,name:record?.name??module.Item,enabled:module.On!==false,metrics:weaponMetrics(stats),ammunition:ammunitionCapacity(stats),...stats.maximumRange===void 0?{}:{maximumRange:stats.maximumRange},...stats.falloffRange===void 0?{}:{falloffRange:stats.falloffRange},...stats.projectileRange===void 0?{}:{projectileRange:{...stats.projectileRange}},...stats.armourPiercing===void 0?{}:{armourPiercing:stats.armourPiercing}})}const orderedWeapons=orderBySlotLayout(weapons,this.#state.layout(),weapon=>weapon.slot);return{weapons:orderedWeapons,total:sumWeaponMetrics(orderedWeapons.filter(weapon=>weapon.enabled).map(weapon=>weapon.metrics))}}weaponsCapacitorMetrics(options={}){const weaponsPips=requirePips(`${FACADE}.weaponsCapacitorMetrics`,"weaponsPips",options.weaponsPips??4);return weaponsCapacitorMetrics(weaponsCapacitorInputFor(this.#state.effectiveModules(),weaponsPips,this.powerBudget(),this.#state.statsFor))}distributorMetricsResult(options={}){return this.#distributor(options)}#mobility(options){const input=this.#mobilityInput(`${FACADE}.mobilityMetricsResult`,options);return input.complete?completeResult(mobilityMetrics(input.value)):input}#mobilityCapacitor(options){const scope=`${FACADE}.mobilityCapacitorMetricsResult`;const enginesPips=requirePips(scope,"enginesPips",options.enginesPips??4);const input=this.#mobilityInput(scope,options);return input.complete?completeResult(mobilityCapacitorMetrics({...input.value,enginesPips:enginesPips})):input}#mobilityInput(scope,options){requireLoadOptions(scope,options);return mobilityInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),()=>this.#loadedMass(options.cargo??0)+(options.fuel??this.#state.statedMainFuel()??this.#build.fuelCapacity.main),this.#state.statsFor)}#shields(){const input=shieldInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(shieldMetrics(input.value)):input}#shieldCapacitor(options){const systemsPips=requirePips(`${FACADE}.shieldCapacitorMetricsResult`,"systemsPips",options.systemsPips??4);const input=shieldCapacitorInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldCapacitorMetrics(input.value)):input}#recovery(options){const systemsPips=requirePips(`${FACADE}.shieldRecoveryResult`,"systemsPips",options.systemsPips??4);const input=shieldRecoveryInputResultFor(this.#state.ship,this.#state.modules(),()=>this.powerBudget(),systemsPips,this.#state.statsFor);return input.complete?completeResult(shieldRecovery(input.value)):input}#distributor(options){const scope=`${FACADE}.distributorMetricsResult`;const pips={systemsPips:requirePips(scope,"systemsPips",options.systemsPips??4),enginesPips:requirePips(scope,"enginesPips",options.enginesPips??4),weaponsPips:requirePips(scope,"weaponsPips",options.weaponsPips??4)};const input=distributorInputResultFor(this.#state.effectiveModules(),pips,this.powerBudget(),this.#state.statsFor);return input.complete?completeResult(distributorMetrics(input.value)):input}#standardLoad(load){if(load!=="maximum"&&load!=="unladen"&&load!=="laden"){throw new RangeError(`${FACADE}.standardLoadResult: load must be 'maximum', 'unladen', or 'laden'`)}const fuel=this.#build.fuelCapacity;const cargo=load==="laden"?this.#build.cargoCapacity:0;const mass=load==="maximum"?this.#build.unladenMass:0;let drive=null;let maximumFuel=null;if(load==="maximum"){const fitted=this.#state.frameShiftDriveModule();let driveError=null;try{drive=this.#state.resolveDrive();maximumFuel=drive?.maxFuel??null}catch(error){if(!(error instanceof Error))throw error;driveError=error}if(maximumFuel===null){return incompleteResult([{field:"frameShiftDrive",reason:fitted?"unresolved":"missing",slot:fitted?.Slot??"FrameShiftDrive",...fitted?{symbol:fitted.Item}:{},message:driveError?.message??"FrameShiftDrive: no frame shift drive is fitted",params:fitted?{field:"frameShiftDrive",reason:"unresolved",slot:fitted.Slot,symbol:fitted.Item}:{field:"frameShiftDrive",reason:"missing",slot:"FrameShiftDrive"}}])}}const carriedFuel=load==="maximum"?Math.min(fuel.main,maximumFuel):fuel.main;const value=Object.freeze({fuel:carriedFuel,cargo:cargo,mass:this.#build.unladenMass+carriedFuel+cargo});if(load==="maximum"){try{this.jumpRange(value)}catch(error){if(!(error instanceof RangeError))throw error;const fitted=this.#state.frameShiftDriveModule();const field=drive!==null&&(!Number.isFinite(drive.maxFuel)||drive.maxFuel<0)?"frameShiftDrive":!Number.isFinite(value.fuel)||value.fuel<0?"fuelCapacity":!Number.isFinite(mass)||mass<0?"mass":"frameShiftDrive";const driveParams=field==="frameShiftDrive"&&fitted?{slot:fitted.Slot,symbol:fitted.Item}:{};return incompleteResult([{field:field,reason:"invalid",...driveParams,message:error.message,params:{field:field,reason:"invalid",...driveParams}}])}}return completeResult(value)}#require(result,what){if(result.value===null){throw new TypeError(`${FACADE}: cannot determine ${what} (${result.issues.map(issue=>issue.message).join("; ")})`)}return result.value}#loadedMass(cargo){return this.#build.unladenMass+cargo}#maxJumpFuel(fsd){return Math.min(this.#build.fuelCapacity.main,fsd.maxFuel)}};export{BuildMetrics};//# sourceMappingURL=chunk-YJAH6DFY.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/ships/build-metrics.ts"],"names":["weaponsCapacitorMetrics","shieldCapacitorMetrics","cellBankSummary","shieldRecovery","loadoutInternals","fittedThrusterParamsFor","preEngineeredVariantFor","powerConsumerFor","powerAvailable","heatInputResultFor","completeResult","cellBankInputsFor","armourInputFor","weaponStatsFor","weaponsCapacitorInputFor","mobilityInputResultFor","shieldInputResultFor","shieldCapacitorInputResultFor","shieldRecoveryInputResultFor","distributorInputResultFor","incompleteResult","weaponMetrics","sumWeaponMetrics","shieldMetrics","powerBudget","isNonOutfittingSlot","isBuiltInHullModule","orderBySlotLayout","mobilityCapacitorMetrics","mobilityMetrics","getExperimentalEffectCost","heatMetrics","frameShiftDriveMassFactor","singleJumpRange","fuelPerJump","totalRange","calculateUnladenMass","armourMetrics","getBlueprintCost","sumMaterials","distributorMetrics","requirePips","requireFiniteNonNegative","ammunitionCapacity","deepFreeze","FACADE","requireLoadOptions","scope","options","field","value","BuildMetrics","_BuildMetrics","build","state","constructor","this","of","loadout","frameShiftDrive","drive","resolveDrive","TypeError","thrusters","modules","statsFor","loadedMass","cargo","fuel","fuelCapacity","main","maxJumpRange","fsd","maxJumpFuel","jumpRange","ladenJumpRange","cargoCapacity","distance","standardLoadResult","load","standardLoad","jumpRangeSummary","maximum","require","unladen","laden","max","totalMax","totalUnladen","totalLaden","buildMass","unladenMass","Object","freeze","hull","ship","hullMass","calculationModules","total","buildCost","hullCost","mercCoins","unpriced","materials","module","stats","cost","Slot","push","slot","symbol","Item","variant","mercCoinCost","engineering","Engineering","grade","Level","bought","Number","isInteger","climb","BlueprintName","experimental","ExperimentalEffect","toLowerCase","experimentalEffectSymbol","credits","rebuy","Math","trunc","consumers","consumer","heatMetricsResult","input","effectiveModules","complete","mobilityMetricsResult","mobility","mobilityCapacitorMetricsResult","mobilityCapacitor","shieldMetricsResult","shields","shieldCapacitorMetricsResult","shieldCapacitor","shieldRecoveryResult","recovery","cellBanks","layout","bank","weapons","record","effectiveModule","name","enabled","On","metrics","ammunition","maximumRange","falloffRange","projectileRange","armourPiercing","orderedWeapons","weapon","filter","map","weaponsPips","distributorMetricsResult","distributor","mobilityInput","enginesPips","statedMainFuel","systemsPips","pips","RangeError","mass","maximumFuel","fitted","frameShiftDriveModule","driveError","maxFuel","error","Error","reason","message","params","carriedFuel","min","isFinite","driveParams","result","what","issues","issue","join"],"mappings":"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"}
@@ -25,5 +25,57 @@ interface PersonalEngineeringIngredient {
25
25
  * ```
26
26
  */
27
27
  declare function sumPersonalEngineeringIngredients(...recipes: readonly (readonly PersonalEngineeringIngredient[])[]): PersonalEngineeringIngredient[];
28
+ /**
29
+ * One stat multiplier an engineer-applied modification puts on a suit or a handheld
30
+ * weapon.
31
+ *
32
+ * @remarks
33
+ * A personal modification is applied in one step: it has no grade and no quality roll,
34
+ * so a modifier is a single factor rather than the `[min, max]` band a ship blueprint
35
+ * feature carries. `1` is the no-op value and is never stored — a recipe lists only the
36
+ * stats it actually moves.
37
+ */
38
+ interface PersonalModifier {
39
+ /**
40
+ * The stat the factor multiplies, named as the equipment catalogues name it —
41
+ * `"magazineSize"`, `"effectiveRange"`, `"batteryCapacity"`, `"goodsCapacity"`.
42
+ *
43
+ * @remarks
44
+ * Six stats the game shows on foot have no catalogue field, because the panel shows
45
+ * no base for them, and are named for what they are: `"meleeDamage"`,
46
+ * `"sprintDuration"`, `"toolEnergyDrain"`, `"reloadSpeed"`, and the pressurised and
47
+ * unpressurised firing audible ranges.
48
+ */
49
+ readonly stat: string;
50
+ /** The factor the stat is multiplied by, e.g. `1.5` for a 50% increase. */
51
+ readonly multiplier: number;
52
+ /** Whether the game rounds the result up to a whole number, as it does a magazine. */
53
+ readonly roundUp?: boolean;
54
+ }
55
+ /**
56
+ * Apply every modifier for one stat to its base value.
57
+ *
58
+ * A **resistance** is the exception, exactly as it is for ship engineering: the factor
59
+ * multiplies the *damage taken*, so a resistance compounds on `1 − r`. Damage Resistance
60
+ * is `×0.9` on damage taken, which turns a `0.5` resistance into `0.55` rather than
61
+ * `0.45`. Any stat whose name ends in `Resistance` is treated this way.
62
+ *
63
+ * @param stat - Stat to apply, e.g. `"magazineSize"`. Modifiers naming another stat are
64
+ * skipped, so a whole suit's or weapon's modifier list can be passed for each stat.
65
+ * @param base - The catalogue value before engineering.
66
+ * @param modifiers - Modifiers to fold in, in order.
67
+ * @returns The modified value, rounded to six decimals to keep binary floating-point
68
+ * noise out of a displayed stat.
69
+ * @throws {TypeError} If `stat` is not a string or `base` is not a finite number.
70
+ * @example
71
+ * ```ts
72
+ * import { applyPersonalModifiers } from '@elite-dangerous-almanac/core/equipment/engineering';
73
+ * import { getPersonalModification } from '@elite-dangerous-almanac/core/equipment/modifications';
74
+ *
75
+ * const clipSize = getPersonalModification('weapon_clipsize')?.modifiers ?? [];
76
+ * applyPersonalModifiers('magazineSize', 45, clipSize); // -> 68
77
+ * ```
78
+ */
79
+ declare function applyPersonalModifiers(stat: string, base: number, modifiers: readonly PersonalModifier[]): number;
28
80
 
29
- export { type PersonalEngineeringIngredient, sumPersonalEngineeringIngredients };
81
+ export { type PersonalEngineeringIngredient, type PersonalModifier, applyPersonalModifiers, sumPersonalEngineeringIngredients };
@@ -1 +1 @@
1
- export{sumPersonalEngineeringIngredients}from"../chunk-C5HG4GJI.js";//# sourceMappingURL=engineering.js.map
1
+ export{applyPersonalModifiers,sumPersonalEngineeringIngredients}from"../chunk-WV7QCDL5.js"; //# sourceMappingURL=engineering.js.map
@@ -1,5 +1,16 @@
1
+ /**
2
+ * Elite Dangerous personal equipment: Odyssey suits, handheld weapons, Pioneer Supplies
3
+ * grade progression and engineer-applied modifications.
4
+ *
5
+ * Material shopping lists are deliberately leaf-only: import grade-upgrade costs from
6
+ * `equipment/upgrade-costs` and modification costs from
7
+ * `equipment/modification-costs`. Keeping them off this barrel lets identity and stat
8
+ * lookups avoid bundling recipe ingredients.
9
+ *
10
+ * @packageDocumentation
11
+ */
1
12
  export { EquipmentGrade, SUITS, Suit, SuitGrade, getSuitByFamily, getSuitByName, getSuitBySymbol, getSuitGrade } from './suits.js';
2
- export { PERSONAL_WEAPONS, PersonalDamageType, PersonalFireMode, PersonalWeapon, PersonalWeaponClass, PersonalWeaponEngineeringType, PersonalWeaponGrade, PersonalWeaponSlot, WeaponUpgradeGroup, getPersonalWeaponByName, getPersonalWeaponBySymbol, getPersonalWeaponGrade } from './weapons.js';
3
- export { PersonalEngineeringIngredient, sumPersonalEngineeringIngredients } from './engineering.js';
13
+ export { PERSONAL_WEAPONS, PersonalDamageType, PersonalFireMode, PersonalWeapon, PersonalWeaponClass, PersonalWeaponEngineeringType, PersonalWeaponGrade, PersonalWeaponSlot, ScopeMagnification, WeaponUpgradeGroup, getPersonalWeaponByName, getPersonalWeaponBySymbol, getPersonalWeaponGrade } from './weapons.js';
14
+ export { PersonalEngineeringIngredient, PersonalModifier, applyPersonalModifiers, sumPersonalEngineeringIngredients } from './engineering.js';
4
15
  export { PERSONAL_MODIFICATIONS, PersonalModification, PersonalModificationTarget, getPersonalModification } from './modifications.js';
5
16
  export { resolvePersonalModificationForWeapon } from './modification-journal.js';
@@ -1 +1 @@
1
- export{resolvePersonalModificationForWeapon}from"../chunk-A6OINYNP.js";export{PERSONAL_MODIFICATIONS,getPersonalModification}from"../chunk-MGRDB2BZ.js";export{SUITS,getSuitByFamily,getSuitByName,getSuitBySymbol,getSuitGrade}from"../chunk-B7EYTZRK.js";export{PERSONAL_WEAPONS,getPersonalWeaponByName,getPersonalWeaponBySymbol,getPersonalWeaponGrade}from"../chunk-6GJHUWMO.js"; export{sumPersonalEngineeringIngredients}from"../chunk-C5HG4GJI.js"; //# sourceMappingURL=index.js.map
1
+ export{resolvePersonalModificationForWeapon}from"../chunk-3WGXGBW5.js";export{PERSONAL_MODIFICATIONS,getPersonalModification}from"../chunk-GIGRBFIJ.js";export{SUITS,getSuitByFamily,getSuitByName,getSuitBySymbol,getSuitGrade}from"../chunk-LWNBWRKL.js";export{PERSONAL_WEAPONS,getPersonalWeaponByName,getPersonalWeaponBySymbol,getPersonalWeaponGrade}from"../chunk-IUSMAX5T.js"; export{applyPersonalModifiers,sumPersonalEngineeringIngredients}from"../chunk-WV7QCDL5.js"; //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- export{resolvePersonalModificationForWeapon}from"../chunk-A6OINYNP.js"; //# sourceMappingURL=modification-journal.js.map
1
+ export{resolvePersonalModificationForWeapon}from"../chunk-3WGXGBW5.js"; //# sourceMappingURL=modification-journal.js.map
@@ -1,17 +1,20 @@
1
+ import { PersonalModifier } from './engineering.js';
2
+
1
3
  /**
2
4
  * Engineer-applied modification recipes for Odyssey suits and handheld weapons.
3
5
  *
4
6
  * The catalogue is keyed by recipe symbol, following the same pattern as ship
5
7
  * blueprints and experimental effects. Most keys are the exact symbol written by a
6
- * journal loadout. Greater Range, Headshot Damage and Higher Accuracy each have three
7
- * technology-specific recipes; use `equipment/modification-journal` to resolve those
8
- * journal symbols against a weapon.
8
+ * journal loadout. Greater Range, Headshot Damage and Improved Hip Fire Accuracy
9
+ * each have three technology-specific recipes; use `equipment/modification-journal`
10
+ * to resolve those journal symbols against a weapon.
9
11
  *
10
12
  * Material shopping lists live separately in `equipment/modification-costs`, so reading
11
13
  * names and engineer availability does not bundle every recipe ingredient.
12
14
  *
13
15
  * @packageDocumentation
14
16
  */
17
+
15
18
  /** Equipment kind a personal modification can be installed on. */
16
19
  type PersonalModificationTarget = 'suit' | 'weapon';
17
20
  /** One permanent personal-equipment engineering recipe. */
@@ -22,21 +25,41 @@ interface PersonalModification {
22
25
  readonly target: PersonalModificationTarget;
23
26
  /** English names of the on-foot engineers who offer the modification. */
24
27
  readonly engineers: readonly string[];
28
+ /**
29
+ * The stat multipliers the modification applies, in the order the game applies
30
+ * them. Fold one onto a base value with `applyPersonalModifiers` from
31
+ * `equipment/engineering`.
32
+ *
33
+ * A modifier names a stat of whatever it modifies, which is usually the equipment
34
+ * the recipe is installed on. Extra Ammo Capacity is the exception a consumer has
35
+ * to know about: it is a suit modification and it multiplies a *weapon's*
36
+ * `reserveAmmo`.
37
+ *
38
+ * @remarks
39
+ * **Empty** where the recipe changes nothing this catalogue names. Night Vision,
40
+ * Scope, Stowed reloading and Combat Movement Speed have no numeric magnitude at
41
+ * all — Scope swaps the sight, and each weapon's two magnifications are on its own
42
+ * `scopeMagnification`. Faster Handling, Improved Hip Fire
43
+ * Accuracy, Stability and Improved Jump Assist do change stats, ones the personal
44
+ * stats panel does not put a number on; see
45
+ * [`data/equipment/SOURCES.md`](https://github.com/DarkSession/Elite-Dangerous-Almanac/blob/main/data/equipment/SOURCES.md).
46
+ */
47
+ readonly modifiers: readonly PersonalModifier[];
25
48
  }
26
49
  /**
27
50
  * All 31 suit and weapon engineering recipes, keyed by recipe symbol.
28
51
  *
29
52
  * @remarks
30
- * There are 25 distinct display names. Greater Range, Headshot Damage and Higher
31
- * Accuracy each have separate Kinetic, Laser and Plasma recipes because their material
32
- * costs differ. Their keys end in `_kinetic`, `_laser` or `_plasma`; the journal omits
33
- * that suffix, so resolve its value with `resolvePersonalModificationForWeapon` from
34
- * `equipment/modification-journal`.
53
+ * There are 25 distinct display names. Greater Range, Headshot Damage and Improved
54
+ * Hip Fire Accuracy each have separate Kinetic, Laser and Plasma recipes because their
55
+ * material costs differ. Their keys end in `_kinetic`, `_laser` or `_plasma`; the
56
+ * journal omits that suffix, so resolve its value with
57
+ * `resolvePersonalModificationForWeapon` from `equipment/modification-journal`.
35
58
  *
36
59
  * @example
37
60
  * ```ts
38
61
  * import { PERSONAL_MODIFICATIONS } from '@elite-dangerous-almanac/core/equipment/modifications';
39
- * PERSONAL_MODIFICATIONS['suit_nightvision']?.name; // -> 'Night Vision'
62
+ * PERSONAL_MODIFICATIONS['suit_increasedo2capacity']?.modifiers[0]?.multiplier; // -> 5
40
63
  * ```
41
64
  */
42
65
  declare const PERSONAL_MODIFICATIONS: Readonly<Record<string, PersonalModification>>;
@@ -1 +1 @@
1
- export{PERSONAL_MODIFICATIONS,getPersonalModification}from"../chunk-MGRDB2BZ.js"; //# sourceMappingURL=modifications.js.map
1
+ export{PERSONAL_MODIFICATIONS,getPersonalModification}from"../chunk-GIGRBFIJ.js"; //# sourceMappingURL=modifications.js.map
@@ -1,5 +1,6 @@
1
1
  /**
2
- * Odyssey personal suits, their journal identifiers and grade-dependent defensive stats.
2
+ * Odyssey personal suits: their journal identifiers, the suit-wide component stats every
3
+ * grade shares, and the grade-dependent defensive stats.
3
4
  *
4
5
  * @packageDocumentation
5
6
  */
@@ -34,7 +35,36 @@ interface Suit {
34
35
  readonly primarySlots: number;
35
36
  /** Number of secondary-weapon slots. */
36
37
  readonly secondarySlots: number;
37
- /** Available grade records, keyed by `"1"` through `"5"`. */
38
+ /** Suit health in health points, the pool the shield protects. */
39
+ readonly health: number;
40
+ /** Suit mass in kilograms. */
41
+ readonly mass: number;
42
+ /** Battery capacity in energy units, the pool the suit's tools draw from. */
43
+ readonly batteryCapacity: number;
44
+ /** Emergency air, in seconds of life support. */
45
+ readonly oxygenTime: number;
46
+ /** Jump-assist boost acceleration, the bare figure the panel shows, which has no unit. */
47
+ readonly boostAcceleration: number;
48
+ /** Backpack goods capacity in items. */
49
+ readonly goodsCapacity: number;
50
+ /** Backpack assets capacity in components. */
51
+ readonly assetsCapacity: number;
52
+ /** Backpack data capacity in items. */
53
+ readonly dataCapacity: number;
54
+ /** How far footsteps carry, as a multiplier of the base audible range. */
55
+ readonly footstepAudibleRange: number;
56
+ /** Line-of-sight analysis range in metres. */
57
+ readonly losAnalysisRange: number;
58
+ /** Seconds of line of sight the suit needs to complete an analysis. */
59
+ readonly losAnalysisTime: number;
60
+ /**
61
+ * Available grade records, keyed by `"1"` through `"5"`.
62
+ *
63
+ * @remarks
64
+ * A grade changes exactly what {@link SuitGrade} carries — the four resistances,
65
+ * shield strength, shield regeneration, the modification slots and the item symbol.
66
+ * Every stat above is a property of the suit family and is the same at all five.
67
+ */
38
68
  readonly grades: Readonly<Partial<Record<`${EquipmentGrade}`, SuitGrade>>>;
39
69
  }
40
70
  /**
@@ -1 +1 @@
1
- export{SUITS,getSuitByFamily,getSuitByName,getSuitBySymbol,getSuitGrade}from"../chunk-B7EYTZRK.js"; //# sourceMappingURL=suits.js.map
1
+ export{SUITS,getSuitByFamily,getSuitByName,getSuitBySymbol,getSuitGrade}from"../chunk-LWNBWRKL.js"; //# sourceMappingURL=suits.js.map
@@ -1 +1 @@
1
- import{getSuitByFamily}from"../chunk-B7EYTZRK.js";import{getPersonalWeaponBySymbol}from"../chunk-6GJHUWMO.js"; import{sumPersonalEngineeringIngredients}from"../chunk-C5HG4GJI.js"; import{deepFreeze}from"../chunk-DURKO7JU.js";var upgrade_costs_default={suits:{utilitysuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"carbonfibreplating",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"carbonfibreplating",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"carbonfibreplating",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"carbonfibreplating",count:12},{symbol:"graphene",count:12}]},tacticalsuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"titaniumplating",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"titaniumplating",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"titaniumplating",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"titaniumplating",count:12},{symbol:"graphene",count:12}]},explorationsuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"aerogel",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"aerogel",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"aerogel",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"aerogel",count:12},{symbol:"graphene",count:12}]}},weaponGroups:{takada:{2:[{symbol:"weaponschematic",count:1},{symbol:"ionisedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"microelectrode",count:2},{symbol:"opticalfibre",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"ionisedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"microelectrode",count:5},{symbol:"opticalfibre",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"ionisedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"microelectrode",count:9},{symbol:"opticalfibre",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"ionisedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"microelectrode",count:12},{symbol:"opticalfibre",count:12}]},manticore:{2:[{symbol:"weaponschematic",count:1},{symbol:"ionisedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"microelectrode",count:2},{symbol:"chemicalsuperbase",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"ionisedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"microelectrode",count:5},{symbol:"chemicalsuperbase",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"ionisedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"microelectrode",count:9},{symbol:"chemicalsuperbase",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"ionisedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"microelectrode",count:12},{symbol:"chemicalsuperbase",count:12}]},karma:{2:[{symbol:"weaponschematic",count:1},{symbol:"compressionliquefiedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"weaponcomponent",count:2},{symbol:"tungstencarbide",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"compressionliquefiedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"weaponcomponent",count:5},{symbol:"tungstencarbide",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"compressionliquefiedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"weaponcomponent",count:9},{symbol:"tungstencarbide",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"compressionliquefiedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"weaponcomponent",count:12},{symbol:"tungstencarbide",count:12}]}}};var PERSONAL_UPGRADE_COSTS=deepFreeze(upgrade_costs_default);function getSuitUpgradeStepCost(family,targetGrade){assertTargetGrade(targetGrade,"getSuitUpgradeStepCost");const costs=getSuitUpgradeCosts(family);return costs?.[String(targetGrade)]??null}function getSuitUpgradeCost(family,targetGrade,currentGrade=1){assertGrade(targetGrade,"getSuitUpgradeCost: targetGrade");assertGrade(currentGrade,"getSuitUpgradeCost: currentGrade");const costs=getSuitUpgradeCosts(family);if(!costs)return null;return totalCosts(costs,targetGrade,currentGrade)}function getPersonalWeaponUpgradeStepCost(symbol,targetGrade){assertTargetGrade(targetGrade,"getPersonalWeaponUpgradeStepCost");const weapon=getPersonalWeaponBySymbol(symbol);if(!weapon)return null;return PERSONAL_UPGRADE_COSTS.weaponGroups[weapon.upgradeGroup][String(targetGrade)]??null}function getPersonalWeaponUpgradeCost(symbol,targetGrade,currentGrade=1){assertGrade(targetGrade,"getPersonalWeaponUpgradeCost: targetGrade");assertGrade(currentGrade,"getPersonalWeaponUpgradeCost: currentGrade");const weapon=getPersonalWeaponBySymbol(symbol);if(!weapon)return null;return totalCosts(PERSONAL_UPGRADE_COSTS.weaponGroups[weapon.upgradeGroup],targetGrade,currentGrade)}function totalCosts(costs,targetGrade,currentGrade){const steps=[];for(let grade=currentGrade+1;grade<=targetGrade;grade++){steps.push(costs[String(grade)])}return sumPersonalEngineeringIngredients(...steps)}function getSuitUpgradeCosts(family){const suit=getSuitByFamily(family);if(!suit||!Object.hasOwn(PERSONAL_UPGRADE_COSTS.suits,suit.family))return null;return PERSONAL_UPGRADE_COSTS.suits[suit.family]}function assertTargetGrade(grade,functionName){if(!Number.isInteger(grade)||grade<2||grade>5){throw new RangeError(`${functionName}: targetGrade must be an integer in [2, 5]`)}}function assertGrade(grade,label){if(!Number.isInteger(grade)||grade<1||grade>5){throw new RangeError(`${label} must be an integer in [1, 5]`)}}export{PERSONAL_UPGRADE_COSTS,getPersonalWeaponUpgradeCost,getPersonalWeaponUpgradeStepCost,getSuitUpgradeCost,getSuitUpgradeStepCost};//# sourceMappingURL=upgrade-costs.js.map
1
+ import{getSuitByFamily}from"../chunk-LWNBWRKL.js";import{getPersonalWeaponBySymbol}from"../chunk-IUSMAX5T.js"; import{sumPersonalEngineeringIngredients}from"../chunk-WV7QCDL5.js"; import{deepFreeze}from"../chunk-DURKO7JU.js";var upgrade_costs_default={suits:{utilitysuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"carbonfibreplating",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"carbonfibreplating",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"carbonfibreplating",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"carbonfibreplating",count:12},{symbol:"graphene",count:12}]},tacticalsuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"titaniumplating",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"titaniumplating",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"titaniumplating",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"titaniumplating",count:12},{symbol:"graphene",count:12}]},explorationsuit:{2:[{symbol:"suitschematic",count:1},{symbol:"healthmonitor",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"aerogel",count:2},{symbol:"graphene",count:2}],3:[{symbol:"suitschematic",count:2},{symbol:"healthmonitor",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"aerogel",count:5},{symbol:"graphene",count:5}],4:[{symbol:"suitschematic",count:4},{symbol:"healthmonitor",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"aerogel",count:9},{symbol:"graphene",count:9}],5:[{symbol:"suitschematic",count:5},{symbol:"healthmonitor",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"aerogel",count:12},{symbol:"graphene",count:12}]}},weaponGroups:{takada:{2:[{symbol:"weaponschematic",count:1},{symbol:"ionisedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"microelectrode",count:2},{symbol:"opticalfibre",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"ionisedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"microelectrode",count:5},{symbol:"opticalfibre",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"ionisedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"microelectrode",count:9},{symbol:"opticalfibre",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"ionisedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"microelectrode",count:12},{symbol:"opticalfibre",count:12}]},manticore:{2:[{symbol:"weaponschematic",count:1},{symbol:"ionisedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"microelectrode",count:2},{symbol:"chemicalsuperbase",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"ionisedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"microelectrode",count:5},{symbol:"chemicalsuperbase",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"ionisedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"microelectrode",count:9},{symbol:"chemicalsuperbase",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"ionisedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"microelectrode",count:12},{symbol:"chemicalsuperbase",count:12}]},karma:{2:[{symbol:"weaponschematic",count:1},{symbol:"compressionliquefiedgas",count:1},{symbol:"manufacturinginstructions",count:1},{symbol:"weaponcomponent",count:2},{symbol:"tungstencarbide",count:2}],3:[{symbol:"weaponschematic",count:2},{symbol:"compressionliquefiedgas",count:2},{symbol:"manufacturinginstructions",count:2},{symbol:"weaponcomponent",count:5},{symbol:"tungstencarbide",count:5}],4:[{symbol:"weaponschematic",count:4},{symbol:"compressionliquefiedgas",count:4},{symbol:"manufacturinginstructions",count:4},{symbol:"weaponcomponent",count:9},{symbol:"tungstencarbide",count:9}],5:[{symbol:"weaponschematic",count:5},{symbol:"compressionliquefiedgas",count:5},{symbol:"manufacturinginstructions",count:5},{symbol:"weaponcomponent",count:12},{symbol:"tungstencarbide",count:12}]}}};var PERSONAL_UPGRADE_COSTS=deepFreeze(upgrade_costs_default);function getSuitUpgradeStepCost(family,targetGrade){assertTargetGrade(targetGrade,"getSuitUpgradeStepCost");const costs=getSuitUpgradeCosts(family);return costs?.[String(targetGrade)]??null}function getSuitUpgradeCost(family,targetGrade,currentGrade=1){assertGrade(targetGrade,"getSuitUpgradeCost: targetGrade");assertGrade(currentGrade,"getSuitUpgradeCost: currentGrade");const costs=getSuitUpgradeCosts(family);if(!costs)return null;return totalCosts(costs,targetGrade,currentGrade)}function getPersonalWeaponUpgradeStepCost(symbol,targetGrade){assertTargetGrade(targetGrade,"getPersonalWeaponUpgradeStepCost");const weapon=getPersonalWeaponBySymbol(symbol);if(!weapon)return null;return PERSONAL_UPGRADE_COSTS.weaponGroups[weapon.upgradeGroup][String(targetGrade)]??null}function getPersonalWeaponUpgradeCost(symbol,targetGrade,currentGrade=1){assertGrade(targetGrade,"getPersonalWeaponUpgradeCost: targetGrade");assertGrade(currentGrade,"getPersonalWeaponUpgradeCost: currentGrade");const weapon=getPersonalWeaponBySymbol(symbol);if(!weapon)return null;return totalCosts(PERSONAL_UPGRADE_COSTS.weaponGroups[weapon.upgradeGroup],targetGrade,currentGrade)}function totalCosts(costs,targetGrade,currentGrade){const steps=[];for(let grade=currentGrade+1;grade<=targetGrade;grade++){steps.push(costs[String(grade)])}return sumPersonalEngineeringIngredients(...steps)}function getSuitUpgradeCosts(family){const suit=getSuitByFamily(family);if(!suit||!Object.hasOwn(PERSONAL_UPGRADE_COSTS.suits,suit.family))return null;return PERSONAL_UPGRADE_COSTS.suits[suit.family]}function assertTargetGrade(grade,functionName){if(!Number.isInteger(grade)||grade<2||grade>5){throw new RangeError(`${functionName}: targetGrade must be an integer in [2, 5]`)}}function assertGrade(grade,label){if(!Number.isInteger(grade)||grade<1||grade>5){throw new RangeError(`${label} must be an integer in [1, 5]`)}}export{PERSONAL_UPGRADE_COSTS,getPersonalWeaponUpgradeCost,getPersonalWeaponUpgradeStepCost,getSuitUpgradeCost,getSuitUpgradeStepCost};//# sourceMappingURL=upgrade-costs.js.map
@@ -1,7 +1,8 @@
1
1
  import { EquipmentGrade } from './suits.js';
2
2
 
3
3
  /**
4
- * Odyssey handheld weapons, their journal identifiers and grade-dependent damage.
4
+ * Odyssey handheld weapons: their journal identifiers, combat stats, sight
5
+ * magnification and grade-dependent damage.
5
6
  *
6
7
  * @packageDocumentation
7
8
  */
@@ -18,6 +19,13 @@ type PersonalWeaponSlot = 'primary' | 'secondary';
18
19
  type PersonalDamageType = 'kinetic' | 'thermal' | 'plasma' | 'explosive';
19
20
  /** A handheld weapon firing cycle. */
20
21
  type PersonalFireMode = 'automatic' | 'semi-automatic' | 'burst';
22
+ /** A weapon's aim-down-sights magnification, before and after the Scope modification. */
23
+ interface ScopeMagnification {
24
+ /** Magnification of the sight the weapon ships with, e.g. `1.12` for 1.12x. */
25
+ readonly default: number;
26
+ /** Magnification of the sight the Scope modification fits, e.g. `1.41` for 1.41x. */
27
+ readonly upgraded: number;
28
+ }
21
29
  /** Grade-dependent stats for one handheld weapon. */
22
30
  interface PersonalWeaponGrade {
23
31
  /** Damage per projectile or pellet. */
@@ -53,6 +61,12 @@ interface PersonalWeapon {
53
61
  readonly headshotMultiplier: number;
54
62
  /** Nominal effective range in metres. */
55
63
  readonly effectiveRange: number;
64
+ /**
65
+ * Aim-down-sights magnification with the stock sight and with the one the Scope
66
+ * modification fits. Scope carries no modifier of its own: this pair is its whole
67
+ * numeric effect, and it differs per weapon.
68
+ */
69
+ readonly scopeMagnification: ScopeMagnification;
56
70
  /**
57
71
  * Grade records keyed by `"1"` through `"5"` — every weapon carries all five,
58
72
  * unlike {@link Suit.grades}, and `equipment.test.ts` pins that. Read one through
@@ -118,4 +132,4 @@ declare function getPersonalWeaponByName(name: string): PersonalWeapon | null;
118
132
  */
119
133
  declare function getPersonalWeaponGrade(weapon: PersonalWeapon, grade: number): PersonalWeaponGrade | null;
120
134
 
121
- export { PERSONAL_WEAPONS, type PersonalDamageType, type PersonalFireMode, type PersonalWeapon, type PersonalWeaponClass, type PersonalWeaponEngineeringType, type PersonalWeaponGrade, type PersonalWeaponSlot, type WeaponUpgradeGroup, getPersonalWeaponByName, getPersonalWeaponBySymbol, getPersonalWeaponGrade };
135
+ export { PERSONAL_WEAPONS, type PersonalDamageType, type PersonalFireMode, type PersonalWeapon, type PersonalWeaponClass, type PersonalWeaponEngineeringType, type PersonalWeaponGrade, type PersonalWeaponSlot, type ScopeMagnification, type WeaponUpgradeGroup, getPersonalWeaponByName, getPersonalWeaponBySymbol, getPersonalWeaponGrade };
@@ -1 +1 @@
1
- export{PERSONAL_WEAPONS,getPersonalWeaponByName,getPersonalWeaponBySymbol,getPersonalWeaponGrade}from"../chunk-6GJHUWMO.js"; //# sourceMappingURL=weapons.js.map
1
+ export{PERSONAL_WEAPONS,getPersonalWeaponByName,getPersonalWeaponBySymbol,getPersonalWeaponGrade}from"../chunk-IUSMAX5T.js"; //# sourceMappingURL=weapons.js.map
@@ -1,3 +1,76 @@
1
+ /**
2
+ * Sparse, source-backed localized display names and descriptions for Elite Dangerous
3
+ * outfitting, personal-equipment and engineering catalogues.
4
+ *
5
+ * Each lookup takes the same Frontier symbol as its owning catalogue and a BCP 47
6
+ * locale. English is complete: for a name catalogue it is exactly the owning record's
7
+ * `name`, and for a description catalogue it is the game's own display prose, which no
8
+ * catalogue otherwise publishes.
9
+ * Other locales are intentionally sparse: the function returns `null` when its pinned
10
+ * sources carry no translation, leaving the application in control of fallback policy.
11
+ * A source-backed localized spelling can be identical to English; the lookup returns
12
+ * explicit source values verbatim but never manufactures an English fallback.
13
+ * The catalogues carry English, French, German, Portuguese, Russian and Spanish only,
14
+ * each stored under a bare language tag: a regional or script subtag is dropped
15
+ * (`de-DE` → `de`), and any other language is an unsupported locale.
16
+ *
17
+ * **How sparse, dataset by dataset.** Each column below is the percentage of that
18
+ * lookup's keys carrying a stored value for the locale, so a `0` would mean the dataset
19
+ * holds nothing in that language at all and the lookup returns `null` for every key:
20
+ * German module names are near-complete, while a quarter of the outfitting families —
21
+ * the ones the game does not name separately — have no locale at all. Plan fallback per
22
+ * lookup rather than per application. The table is generated from the
23
+ * [`data/i18n/` catalogues](https://github.com/DarkSession/Elite-Dangerous-Almanac/tree/main/data/i18n),
24
+ * so it moves when the data does.
25
+ *
26
+ * <!-- generated by scripts/i18n-coverage.mjs -->
27
+ * | Lookup | Keys | en | de | es | fr | pt | ru |
28
+ * | --- | ---: | ---: | ---: | ---: | ---: | ---: | ---: |
29
+ * | `getBlueprintName` | 107 | 100 | 100 | 100 | 100 | 100 | 100 |
30
+ * | `getExperimentalEffectDescription` | 86 | 100 | 100 | 100 | 100 | 100 | 100 |
31
+ * | `getExperimentalEffectName` | 86 | 100 | 100 | 100 | 100 | 100 | 100 |
32
+ * | `getMaterialName` | 146 | 100 | 100 | 100 | 100 | 100 | 100 |
33
+ * | `getMicroResourceName` | 226 | 100 | 100 | 100 | 100 | 100 | 100 |
34
+ * | `getModuleName` | 1194 | 100 | 100 | 100 | 100 | 100 | 100 |
35
+ * | `getPersonalModificationDescription` | 31 | 100 | 100 | 100 | 100 | 100 | 100 |
36
+ * | `getPersonalModificationName` | 31 | 100 | 100 | 100 | 100 | 100 | 100 |
37
+ * | `getPersonalWeaponDescription` | 11 | 100 | 100 | 100 | 100 | 100 | 100 |
38
+ * | `getSuitDescription` | 19 | 100 | 100 | 100 | 100 | 100 | 100 |
39
+ * | `getSuitName` | 19 | 100 | 100 | 100 | 100 | 100 | 100 |
40
+ * | `getPreEngineeredVariantName` | 76 | 100 | 92 | 89 | 89 | 100 | 100 |
41
+ * | `getOutfittingFamilyName` | 77 | 100 | 75 | 75 | 75 | 75 | 75 |
42
+ * <!-- end generated -->
43
+ *
44
+ * Each dataset lives in a separate runtime module. Import from this barrel for
45
+ * convenience or from the corresponding `i18n/*` subpath for an explicit bundle
46
+ * boundary.
47
+ *
48
+ * Structured diagnostic helpers expose their current English fallback only for English
49
+ * locales and return `null` otherwise, so a UI never mistakes English prose for a
50
+ * requested translation. Stable codes and `params` remain available for applications
51
+ * that supply their own message catalogues.
52
+ *
53
+ * @example
54
+ * ```ts
55
+ * import {
56
+ * getBlueprintName,
57
+ * getMaterialName,
58
+ * getModuleName,
59
+ * getOutfittingFamilyName,
60
+ * } from '@elite-dangerous-almanac/core/i18n';
61
+ *
62
+ * getModuleName('Int_Hyperdrive_Size6_Class5', 'de'); // -> 'Frameshiftantrieb'
63
+ * getBlueprintName('FSD_LongRange', 'de-DE'); // -> 'Erhöhte FSA-Reichweite'
64
+ * getMaterialName('GridResistors', 'de'); // -> 'Gitterwiderstände'
65
+ *
66
+ * // Sparseness is per dataset, not per locale: German module names are near-complete,
67
+ * // while no outfitting family the game does not name separately has any.
68
+ * getOutfittingFamilyName('shieldGenerators', 'de'); // -> 'Schildgeneratoren'
69
+ * getOutfittingFamilyName('xenoScanners', 'de'); // -> null
70
+ * ```
71
+ *
72
+ * @packageDocumentation
73
+ */
1
74
  export { getModuleName } from './modules.js';
2
75
  export { getOutfittingFamilyName } from './module-families.js';
3
76
  export { getBlueprintName } from './blueprints.js';
@@ -5,6 +78,9 @@ export { getExperimentalEffectName } from './experimental-effects.js';
5
78
  export { getExperimentalEffectDescription } from './experimental-effect-descriptions.js';
6
79
  export { getMaterialName } from './materials.js';
7
80
  export { getMicroResourceName } from './micro-resources.js';
81
+ export { getSuitDescription, getSuitName } from './suits.js';
82
+ export { getPersonalWeaponDescription } from './personal-weapons.js';
83
+ export { getPersonalModificationDescription, getPersonalModificationName } from './personal-modifications.js';
8
84
  export { getLoadoutSlotName, getSlotRestrictionLabel } from './slots.js';
9
85
  export { getCalculationIssueMessage, getLoadoutEditErrorMessage, getLoadoutIssueMessage, getSlefDiagnosticMessage } from './diagnostics.js';
10
86
  export { PreEngineeredVariantIdentity, getPreEngineeredVariantName } from './pre-engineered.js';
@@ -1 +1 @@
1
- export{getExperimentalEffectName}from"../chunk-BMQM4JBL.js";export{getMaterialName}from"../chunk-IZIIGK3W.js";export{getMicroResourceName}from"../chunk-XFDMCPDW.js";export{getOutfittingFamilyName}from"../chunk-SD6GNFDX.js";export{getModuleName}from"../chunk-QJECDMQQ.js";export{getPreEngineeredVariantName}from"../chunk-T7IQHFQ2.js";export{getLoadoutSlotName,getSlotRestrictionLabel}from"../chunk-ZRG35JSH.js"; export{getBlueprintName}from"../chunk-DBDCOHI4.js";export{getCalculationIssueMessage,getLoadoutEditErrorMessage,getLoadoutIssueMessage,getSlefDiagnosticMessage}from"../chunk-6G6TYW2D.js";export{getExperimentalEffectDescription}from"../chunk-MRLUWHGI.js"; //# sourceMappingURL=index.js.map
1
+ export{getPreEngineeredVariantName}from"../chunk-T7IQHFQ2.js";export{getLoadoutSlotName,getSlotRestrictionLabel}from"../chunk-ZRG35JSH.js"; export{getSuitDescription,getSuitName}from"../chunk-FJIWJYKO.js";export{getExperimentalEffectName}from"../chunk-BMQM4JBL.js";export{getMaterialName}from"../chunk-IZIIGK3W.js";export{getMicroResourceName}from"../chunk-XFDMCPDW.js";export{getOutfittingFamilyName}from"../chunk-SD6GNFDX.js";export{getModuleName}from"../chunk-QJECDMQQ.js";export{getPersonalModificationDescription,getPersonalModificationName}from"../chunk-OLKOWR7S.js";export{getPersonalWeaponDescription}from"../chunk-W5ULI75F.js";export{getBlueprintName}from"../chunk-DBDCOHI4.js";export{getCalculationIssueMessage,getLoadoutEditErrorMessage,getLoadoutIssueMessage,getSlefDiagnosticMessage}from"../chunk-6G6TYW2D.js";export{getExperimentalEffectDescription}from"../chunk-MRLUWHGI.js"; //# sourceMappingURL=index.js.map
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Localized personal-equipment modification names and descriptions, isolated from the
3
+ * recipes' modifiers and material costs.
4
+ */
5
+ /**
6
+ * Look up an engineer-applied personal-equipment modification's source-backed display
7
+ * name for a locale.
8
+ *
9
+ * @param modificationSymbol - The recipe symbol `PERSONAL_MODIFICATIONS` is keyed by,
10
+ * such as `"suit_increasedmeleedamage"` or the technology-specific
11
+ * `"weapon_range_laser"`. A journal line writes the unsuffixed `"weapon_range"`, which
12
+ * `resolvePersonalModificationForWeapon` turns into the specific symbol. Matching
13
+ * ignores case and surrounding whitespace.
14
+ * @param locale - A BCP 47 language or regional tag, such as `"de"`, `"de-DE"` or
15
+ * `"en-GB"`. Matching is case-insensitive; underscores are accepted in place of
16
+ * hyphens. A regional or script subtag is dropped: every stored locale is a bare
17
+ * language tag.
18
+ * @returns The localized modification name; the canonical `PersonalModification.name`
19
+ * for any English tag; or `null` when the recipe is unknown or the locale is not one of
20
+ * the six this catalogue stores.
21
+ * @remarks
22
+ * All six stored locales are complete for this dataset, so a supported locale always
23
+ * answers. The game offers Greater Range, Headshot Damage and Improved Hip Fire Accuracy
24
+ * as one menu entry each, so the three Kinetic, Laser and Plasma recipes this repository
25
+ * keys separately share that entry's record rather than storing it three times.
26
+ * @throws {TypeError} If `modificationSymbol` is present and not a string, or `locale`
27
+ * is not a string. A nullish `modificationSymbol` is a lookup miss and returns `null`.
28
+ * @example
29
+ * ```ts
30
+ * import { getPersonalModificationName } from '@elite-dangerous-almanac/core/i18n/personal-modifications';
31
+ *
32
+ * getPersonalModificationName('suit_nightvision', 'de'); // -> 'Nachtsicht'
33
+ * getPersonalModificationName('weapon_range_laser', 'fr'); // -> 'Portée améliorée'
34
+ * getPersonalModificationName('suit_nightvision', 'it'); // -> null
35
+ * ```
36
+ */
37
+ declare function getPersonalModificationName(modificationSymbol: string, locale: string): string | null;
38
+ /**
39
+ * Look up an engineer-applied personal-equipment modification's display description —
40
+ * the prose the game shows a player, in all six stored locales.
41
+ *
42
+ * @param modificationSymbol - The recipe symbol `PERSONAL_MODIFICATIONS` is keyed by,
43
+ * exactly as {@link getPersonalModificationName} accepts. Matching ignores case and
44
+ * surrounding whitespace.
45
+ * @param locale - A BCP 47 locale. All six stored locales are complete for this dataset.
46
+ * @returns The localized description, or `null` when the recipe is unknown or the
47
+ * requested locale is not one this catalogue stores.
48
+ * @remarks
49
+ * This is display prose, not a statement of the magnitudes a recipe applies: the game
50
+ * says a modification "allows more ammo to be carried for each weapon", never how much
51
+ * more. `PersonalModification.modifiers` answers that, and the two are deliberately not
52
+ * the same string. It is also the only account of the ten recipes whose `modifiers` list
53
+ * is empty, whether because the recipe switches a capability on or because it moves a
54
+ * stat the panel puts no number on. English is the game's own wording rather than a
55
+ * projection of `PersonalModification.name`.
56
+ * @throws {TypeError} If a present `modificationSymbol` or `locale` is not a string.
57
+ * @example
58
+ * ```ts
59
+ * import { getPersonalModificationDescription } from '@elite-dangerous-almanac/core/i18n/personal-modifications';
60
+ *
61
+ * getPersonalModificationDescription('suit_nightvision', 'en');
62
+ * // -> 'Adds Night Vision capabilities to the suit.'
63
+ * getPersonalModificationDescription('suit_nightvision', 'ja'); // -> null
64
+ * ```
65
+ */
66
+ declare function getPersonalModificationDescription(modificationSymbol: string, locale: string): string | null;
67
+
68
+ export { getPersonalModificationDescription, getPersonalModificationName };
@@ -0,0 +1 @@
1
+ export{getPersonalModificationDescription,getPersonalModificationName}from"../chunk-OLKOWR7S.js"; //# sourceMappingURL=personal-modifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"O"}
@@ -0,0 +1,33 @@
1
+ /** Localized handheld-weapon descriptions, isolated from weapon combat stats. */
2
+ /**
3
+ * Look up a handheld weapon's display description — the prose the game shows a player,
4
+ * in all six stored locales.
5
+ *
6
+ * @param symbol - Frontier's weapon symbol, such as `"wpn_s_pistol_kinetic_sauto"`.
7
+ * Matching ignores case and surrounding whitespace.
8
+ * @param locale - A BCP 47 language or regional tag, such as `"de"`, `"de-DE"` or
9
+ * `"en-GB"`. Matching is case-insensitive; underscores are accepted in place of
10
+ * hyphens. A regional or script subtag is dropped: every stored locale is a bare
11
+ * language tag. All six stored locales are complete for this dataset.
12
+ * @returns The localized description, or `null` when the weapon is unknown or the
13
+ * requested locale is not one this catalogue stores.
14
+ * @remarks
15
+ * **There is no matching name lookup, and that is not a gap.** A handheld weapon's name
16
+ * is a product name — "Karma P-15", "TK Aphelion" — that the game leaves in English in
17
+ * every locale, so `PersonalWeapon.name` is the name in all six. This is display prose
18
+ * and not a statement of the weapon's mechanics: it names no damage figure, rate of fire
19
+ * or effective range, which are the stats `PERSONAL_WEAPONS` carries.
20
+ * @throws {TypeError} If `symbol` is present and not a string, or `locale` is not a
21
+ * string. A nullish `symbol` is a lookup miss and returns `null`.
22
+ * @example
23
+ * ```ts
24
+ * import { getPersonalWeaponDescription } from '@elite-dangerous-almanac/core/i18n/personal-weapons';
25
+ *
26
+ * getPersonalWeaponDescription('wpn_m_sniper_plasma_charged', 'en');
27
+ * // -> 'A semi-automatic, long-range plasma rifle with high damage output and a low rate of fire.'
28
+ * getPersonalWeaponDescription('wpn_m_sniper_plasma_charged', 'it'); // -> null
29
+ * ```
30
+ */
31
+ declare function getPersonalWeaponDescription(symbol: string, locale: string): string | null;
32
+
33
+ export { getPersonalWeaponDescription };
@@ -0,0 +1 @@
1
+ export{getPersonalWeaponDescription}from"../chunk-W5ULI75F.js"; //# sourceMappingURL=personal-weapons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"O"}