onroute-policy-engine 2.26.1 → 2.28.0

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 (38) hide show
  1. package/dist/constants/axle-spread-legal-limits.d.ts +30 -0
  2. package/dist/constants/axle-spread-legal-limits.js +33 -0
  3. package/dist/constants/axle-weight-legal-maximums.d.ts +9 -0
  4. package/dist/constants/axle-weight-legal-maximums.js +12 -0
  5. package/dist/constants/axle-weight-permittable-maximums.d.ts +7 -0
  6. package/dist/constants/axle-weight-permittable-maximums.js +10 -0
  7. package/dist/constants/interaxle-spacing-legal-minimums.d.ts +17 -0
  8. package/dist/constants/interaxle-spacing-legal-minimums.js +20 -0
  9. package/dist/constants/power-unit-axle-code-multiplier.d.ts +1 -0
  10. package/dist/constants/power-unit-axle-code-multiplier.js +4 -0
  11. package/dist/constants/semi-trailer-types.d.ts +2 -0
  12. package/dist/constants/semi-trailer-types.js +47 -0
  13. package/dist/enum/index.d.ts +1 -0
  14. package/dist/enum/index.js +3 -1
  15. package/dist/enum/overload-calculation-detail-kind.d.ts +4 -0
  16. package/dist/enum/overload-calculation-detail-kind.js +8 -0
  17. package/dist/enum/policy-check.d.ts +1 -0
  18. package/dist/enum/policy-check.js +1 -0
  19. package/dist/helper/axle-spread.helper.d.ts +13 -0
  20. package/dist/helper/axle-spread.helper.js +83 -0
  21. package/dist/helper/format-meters.helper.d.ts +1 -0
  22. package/dist/helper/format-meters.helper.js +6 -0
  23. package/dist/helper/interaxle-spacing.helper.d.ts +6 -0
  24. package/dist/helper/interaxle-spacing.helper.js +50 -0
  25. package/dist/helper/overload.helper.d.ts +5 -0
  26. package/dist/helper/overload.helper.js +90 -0
  27. package/dist/helper/policy-check.helper.d.ts +6 -1
  28. package/dist/helper/policy-check.helper.js +91 -114
  29. package/dist/policy-engine.js +9 -1
  30. package/dist/types/axle-calculation-results.d.ts +22 -1
  31. package/dist/types/axle-unit-type.d.ts +6 -0
  32. package/dist/types/axle-unit-type.js +8 -0
  33. package/dist/types/index.d.ts +1 -1
  34. package/dist/types/interaxle-spacing-requirement.d.ts +5 -0
  35. package/dist/types/interaxle-spacing-requirement.js +2 -0
  36. package/dist/version.d.ts +1 -1
  37. package/dist/version.js +1 -1
  38. package/package.json +1 -1
@@ -0,0 +1,30 @@
1
+ export declare const AXLE_SPREAD_LEGAL_LIMITS: {
2
+ SINGLE: {
3
+ MINIMUM: number;
4
+ MAXIMUM: number;
5
+ };
6
+ TANDEM: {
7
+ MINIMUM: number;
8
+ MAXIMUM: number;
9
+ SPREAD_TANDEM_SEMI_TRAILER: {
10
+ MINIMUM: number;
11
+ MAXIMUM: number;
12
+ };
13
+ };
14
+ TRIDEM: {
15
+ MINIMUM: number;
16
+ MAXIMUM: number;
17
+ PONY_TRAILER: {
18
+ MAXIMUM: number;
19
+ };
20
+ SEMI_TRAILER: {
21
+ MAXIMUM: number;
22
+ };
23
+ POLE_TRAILER: {
24
+ MAXIMUM: number;
25
+ };
26
+ OILFIELD_BED_TRUCK: {
27
+ MAXIMUM: number;
28
+ };
29
+ };
30
+ };
@@ -0,0 +1,33 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AXLE_SPREAD_LEGAL_LIMITS = void 0;
4
+ exports.AXLE_SPREAD_LEGAL_LIMITS = {
5
+ SINGLE: {
6
+ MINIMUM: 0,
7
+ MAXIMUM: 100,
8
+ },
9
+ TANDEM: {
10
+ MINIMUM: 100,
11
+ MAXIMUM: 185,
12
+ SPREAD_TANDEM_SEMI_TRAILER: {
13
+ MINIMUM: 186,
14
+ MAXIMUM: 307,
15
+ },
16
+ },
17
+ TRIDEM: {
18
+ MINIMUM: 240,
19
+ MAXIMUM: 280,
20
+ PONY_TRAILER: {
21
+ MAXIMUM: 250,
22
+ },
23
+ SEMI_TRAILER: {
24
+ MAXIMUM: 370,
25
+ },
26
+ POLE_TRAILER: {
27
+ MAXIMUM: 310,
28
+ },
29
+ OILFIELD_BED_TRUCK: {
30
+ MAXIMUM: 310,
31
+ },
32
+ },
33
+ };
@@ -0,0 +1,9 @@
1
+ export declare const AXLE_WEIGHT_LEGAL_MAXIMUMS: {
2
+ SINGLE_AXLE: number;
3
+ STANDARD_TRUCK_TRACTOR_STEER: number;
4
+ STANDARD_SINGLE_STEER_WITH_TRIDEM_DRIVE: number;
5
+ TANDEM_AXLE: number;
6
+ STANDARD_TANDEM_STEER_WITH_TRIDEM_DRIVE: number;
7
+ PME_TANDEM_STEER_WITH_TRIDEM_DRIVE: number;
8
+ TRIDEM_AXLE: number;
9
+ };
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AXLE_WEIGHT_LEGAL_MAXIMUMS = void 0;
4
+ exports.AXLE_WEIGHT_LEGAL_MAXIMUMS = {
5
+ SINGLE_AXLE: 9100,
6
+ STANDARD_TRUCK_TRACTOR_STEER: 6000,
7
+ STANDARD_SINGLE_STEER_WITH_TRIDEM_DRIVE: 7300,
8
+ TANDEM_AXLE: 17000,
9
+ STANDARD_TANDEM_STEER_WITH_TRIDEM_DRIVE: 13600,
10
+ PME_TANDEM_STEER_WITH_TRIDEM_DRIVE: 15200,
11
+ TRIDEM_AXLE: 24000,
12
+ };
@@ -0,0 +1,7 @@
1
+ export declare const AXLE_WEIGHT_PERMITTABLE_MAXIMUMS: {
2
+ SINGLE_STEER: number;
3
+ SINGLE_NON_STEER: number;
4
+ TANDEM: number;
5
+ STANDARD_TRIDEM: number;
6
+ QUALIFYING_TRIDEM: number;
7
+ };
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS = void 0;
4
+ exports.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS = {
5
+ SINGLE_STEER: 9100,
6
+ SINGLE_NON_STEER: 11000,
7
+ TANDEM: 23000,
8
+ STANDARD_TRIDEM: 28000,
9
+ QUALIFYING_TRIDEM: 29000,
10
+ };
@@ -0,0 +1,17 @@
1
+ export declare const INTERAXLE_SPACING_LEGAL_MINIMUMS: {
2
+ readonly SINGLE: {
3
+ readonly SINGLE: 300;
4
+ readonly TANDEM: 300;
5
+ readonly TRIDEM: 300;
6
+ };
7
+ readonly TANDEM: {
8
+ readonly SINGLE: 300;
9
+ readonly TANDEM: 500;
10
+ readonly TRIDEM: 550;
11
+ };
12
+ readonly TRIDEM: {
13
+ readonly SINGLE: 300;
14
+ readonly TANDEM: 550;
15
+ readonly TRIDEM: 600;
16
+ };
17
+ };
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.INTERAXLE_SPACING_LEGAL_MINIMUMS = void 0;
4
+ exports.INTERAXLE_SPACING_LEGAL_MINIMUMS = {
5
+ SINGLE: {
6
+ SINGLE: 300,
7
+ TANDEM: 300,
8
+ TRIDEM: 300,
9
+ },
10
+ TANDEM: {
11
+ SINGLE: 300,
12
+ TANDEM: 500,
13
+ TRIDEM: 550,
14
+ },
15
+ TRIDEM: {
16
+ SINGLE: 300,
17
+ TANDEM: 550,
18
+ TRIDEM: 600,
19
+ },
20
+ };
@@ -0,0 +1 @@
1
+ export declare const POWER_UNIT_AXLE_CODE_MULTIPLIER = 10;
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.POWER_UNIT_AXLE_CODE_MULTIPLIER = void 0;
4
+ exports.POWER_UNIT_AXLE_CODE_MULTIPLIER = 10;
@@ -0,0 +1,2 @@
1
+ export declare const SEMI_TRAILER_TYPES: Set<string>;
2
+ export declare function isSemiTrailerType(vehicleType: string): boolean;
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SEMI_TRAILER_TYPES = void 0;
4
+ exports.isSemiTrailerType = isSemiTrailerType;
5
+ exports.SEMI_TRAILER_TYPES = new Set([
6
+ // Expando Semi-Trailers
7
+ 'EXPANDO',
8
+ // Fixed Equipment - Conveyors
9
+ 'FECVYRX',
10
+ // Fixed Equipment - Counter Flow Asphalt Drum Mixers
11
+ 'FEDRMMX',
12
+ // Fixed Equipment - Portable Asphalt Baghouses
13
+ 'FEBGHSE',
14
+ // Fixed Equipment - Semi-Trailers
15
+ 'FESEMTR',
16
+ // Fixed Equipment - Wheeler Semi-Trailers
17
+ 'FEWHELR',
18
+ // Semi-Trailers - Hiboys/Expandos
19
+ 'HIBOEXP',
20
+ // Semi-Trailers - Hiboys/Flat Decks
21
+ 'HIBOFLT',
22
+ // Oil and Gas - Oversize Oilfield Flat Deck Semi-Trailers
23
+ 'OGOSFDT',
24
+ // Platform Trailer
25
+ 'PLATFRM',
26
+ // Platform Trailers - Wheelers
27
+ 'PLATWHE',
28
+ // Pole Trailers
29
+ 'POLETRL',
30
+ // Ready Mix Concrete Pump Semi-Trailers
31
+ 'REDIMIX',
32
+ // Semi-Trailers
33
+ 'SEMITRL',
34
+ // Semi-Trailers - Single Drop, Double Drop, Step Decks, Lowbed, Expandos, etc.
35
+ 'STSDBDK',
36
+ // Semi-Trailers with Crane
37
+ 'STCRANE',
38
+ // Semi-Trailers - Spread Tandem
39
+ 'STWDTAN',
40
+ // Semi-Trailers - Wheelers
41
+ 'STWHELR',
42
+ // Semi-Trailers - Wide Wheelers
43
+ 'STWIDWH',
44
+ ]);
45
+ function isSemiTrailerType(vehicleType) {
46
+ return exports.SEMI_TRAILER_TYPES.has(vehicleType);
47
+ }
@@ -2,6 +2,7 @@ export { AccessoryVehicleType } from './accessory-vehicle-type';
2
2
  export { CustomOperator } from './custom-operator';
3
3
  export { PolicyFacts, CostFacts } from './facts';
4
4
  export { PermitAppInfo } from './permit-app-info';
5
+ export { OverloadCalculationDetailKind } from './overload-calculation-detail-kind';
5
6
  export { PolicyCheckResultType, PolicyCheckId } from './policy-check';
6
7
  export { RelativePosition } from './relative-position';
7
8
  export { ValidationResultCode } from './validation-result-code';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.VehicleTypes = exports.VehicleCategory = exports.ValidationResultType = exports.ValidationResultCode = exports.RelativePosition = exports.PolicyCheckId = exports.PolicyCheckResultType = exports.PermitAppInfo = exports.CostFacts = exports.PolicyFacts = exports.CustomOperator = exports.AccessoryVehicleType = void 0;
3
+ exports.VehicleTypes = exports.VehicleCategory = exports.ValidationResultType = exports.ValidationResultCode = exports.RelativePosition = exports.PolicyCheckId = exports.PolicyCheckResultType = exports.OverloadCalculationDetailKind = exports.PermitAppInfo = exports.CostFacts = exports.PolicyFacts = exports.CustomOperator = exports.AccessoryVehicleType = void 0;
4
4
  var accessory_vehicle_type_1 = require("./accessory-vehicle-type");
5
5
  Object.defineProperty(exports, "AccessoryVehicleType", { enumerable: true, get: function () { return accessory_vehicle_type_1.AccessoryVehicleType; } });
6
6
  var custom_operator_1 = require("./custom-operator");
@@ -10,6 +10,8 @@ Object.defineProperty(exports, "PolicyFacts", { enumerable: true, get: function
10
10
  Object.defineProperty(exports, "CostFacts", { enumerable: true, get: function () { return facts_1.CostFacts; } });
11
11
  var permit_app_info_1 = require("./permit-app-info");
12
12
  Object.defineProperty(exports, "PermitAppInfo", { enumerable: true, get: function () { return permit_app_info_1.PermitAppInfo; } });
13
+ var overload_calculation_detail_kind_1 = require("./overload-calculation-detail-kind");
14
+ Object.defineProperty(exports, "OverloadCalculationDetailKind", { enumerable: true, get: function () { return overload_calculation_detail_kind_1.OverloadCalculationDetailKind; } });
13
15
  var policy_check_1 = require("./policy-check");
14
16
  Object.defineProperty(exports, "PolicyCheckResultType", { enumerable: true, get: function () { return policy_check_1.PolicyCheckResultType; } });
15
17
  Object.defineProperty(exports, "PolicyCheckId", { enumerable: true, get: function () { return policy_check_1.PolicyCheckId; } });
@@ -0,0 +1,4 @@
1
+ export declare enum OverloadCalculationDetailKind {
2
+ AxleWeight = "axle-weight",
3
+ LicensedGvw = "licensed-gvw"
4
+ }
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.OverloadCalculationDetailKind = void 0;
4
+ var OverloadCalculationDetailKind;
5
+ (function (OverloadCalculationDetailKind) {
6
+ OverloadCalculationDetailKind["AxleWeight"] = "axle-weight";
7
+ OverloadCalculationDetailKind["LicensedGvw"] = "licensed-gvw";
8
+ })(OverloadCalculationDetailKind || (exports.OverloadCalculationDetailKind = OverloadCalculationDetailKind = {}));
@@ -8,6 +8,7 @@ export declare enum PolicyCheckId {
8
8
  BoosterAxleLimit = "booster-axle-limit",
9
9
  BridgeFormula = "bridge-formula",
10
10
  DriveJeepLoadEqualization = "drive-jeep-load-equalization",
11
+ LegalAxleSpread = "legal-axle-spread",
11
12
  LegalInteraxleSpacing = "legal-interaxle-spacing",
12
13
  LegalWeight = "legal-weight",
13
14
  MaxTireLoad = "max-tire-load",
@@ -13,6 +13,7 @@ var PolicyCheckId;
13
13
  PolicyCheckId["BoosterAxleLimit"] = "booster-axle-limit";
14
14
  PolicyCheckId["BridgeFormula"] = "bridge-formula";
15
15
  PolicyCheckId["DriveJeepLoadEqualization"] = "drive-jeep-load-equalization";
16
+ PolicyCheckId["LegalAxleSpread"] = "legal-axle-spread";
16
17
  PolicyCheckId["LegalInteraxleSpacing"] = "legal-interaxle-spacing";
17
18
  PolicyCheckId["LegalWeight"] = "legal-weight";
18
19
  PolicyCheckId["MaxTireLoad"] = "max-tire-load";
@@ -0,0 +1,13 @@
1
+ import { AxleConfiguration } from '../types/axle-configuration';
2
+ export declare function getTandemAxleSpreadThreshold(vehicleConfiguration: Array<string>, vehicleIndex: number): {
3
+ minCm: number;
4
+ maxCm: number;
5
+ };
6
+ export declare function getTridemAxleSpreadThreshold(vehicleConfiguration: Array<string>, vehicleIndex: number, axleConfiguration: Array<AxleConfiguration>, axleIndex: number): {
7
+ minCm: number;
8
+ maxCm: number;
9
+ };
10
+ export declare function getAxleSpreadThreshold(vehicleConfiguration: Array<string>, axleUnitVehicleIndexes: Array<number>, axleConfiguration: Array<AxleConfiguration>, axleIndex: number): {
11
+ minCm: number;
12
+ maxCm: number;
13
+ } | undefined;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getTandemAxleSpreadThreshold = getTandemAxleSpreadThreshold;
4
+ exports.getTridemAxleSpreadThreshold = getTridemAxleSpreadThreshold;
5
+ exports.getAxleSpreadThreshold = getAxleSpreadThreshold;
6
+ const axle_spread_legal_limits_1 = require("../constants/axle-spread-legal-limits");
7
+ const semi_trailer_types_1 = require("../constants/semi-trailer-types");
8
+ function getTandemAxleSpreadThreshold(vehicleConfiguration, vehicleIndex) {
9
+ const vehicleType = vehicleConfiguration[vehicleIndex];
10
+ const isSpreadTandemSemiTrailer = vehicleType === 'STWDTAN';
11
+ if (isSpreadTandemSemiTrailer) {
12
+ return {
13
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TANDEM.SPREAD_TANDEM_SEMI_TRAILER.MINIMUM,
14
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TANDEM.SPREAD_TANDEM_SEMI_TRAILER.MAXIMUM,
15
+ };
16
+ }
17
+ return {
18
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TANDEM.MINIMUM,
19
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TANDEM.MAXIMUM,
20
+ };
21
+ }
22
+ function getTridemAxleSpreadThreshold(vehicleConfiguration, vehicleIndex, axleConfiguration, axleIndex) {
23
+ const vehicleType = vehicleConfiguration[vehicleIndex];
24
+ const isDriveAxle = axleIndex === 1;
25
+ const isTridemDrive = axleConfiguration[1].numberOfAxles === 3;
26
+ const isPonyTrailer = vehicleType === 'PONYTRL';
27
+ const isPoleTrailer = vehicleType === 'POLETRL';
28
+ const isOilfieldBedTruck = vehicleType === 'OGBEDTK';
29
+ const isPowerUnitTruckTractor = vehicleConfiguration[0] === 'TRKTRAC';
30
+ if (isOilfieldBedTruck && isDriveAxle) {
31
+ return {
32
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MINIMUM,
33
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.OILFIELD_BED_TRUCK.MAXIMUM,
34
+ };
35
+ }
36
+ if (isPonyTrailer) {
37
+ return {
38
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MINIMUM,
39
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.PONY_TRAILER.MAXIMUM,
40
+ };
41
+ }
42
+ if (isPowerUnitTruckTractor && (0, semi_trailer_types_1.isSemiTrailerType)(vehicleType)) {
43
+ return {
44
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MINIMUM,
45
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.SEMI_TRAILER.MAXIMUM,
46
+ };
47
+ }
48
+ if (isPowerUnitTruckTractor && isTridemDrive && isPoleTrailer) {
49
+ return {
50
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MINIMUM,
51
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.POLE_TRAILER.MAXIMUM,
52
+ };
53
+ }
54
+ return {
55
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MINIMUM,
56
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.TRIDEM.MAXIMUM,
57
+ };
58
+ }
59
+ function getAxleSpreadThreshold(vehicleConfiguration, axleUnitVehicleIndexes, axleConfiguration, axleIndex) {
60
+ const axleUnit = axleConfiguration[axleIndex];
61
+ if (!Number.isFinite(axleUnit.axleSpread)) {
62
+ return undefined;
63
+ }
64
+ const vehicleIndex = axleUnitVehicleIndexes[axleIndex];
65
+ const numberOfAxles = axleUnit.numberOfAxles;
66
+ const isSingleAxle = numberOfAxles === 1;
67
+ const isTandemAxle = numberOfAxles === 2;
68
+ const isTridemAxle = numberOfAxles === 3;
69
+ if (isSingleAxle) {
70
+ // the ASW table specifically disables the axleSpread input for single axle unit types, so this code will never run, but have left these in place in case something changes
71
+ return {
72
+ minCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.SINGLE.MINIMUM,
73
+ maxCm: axle_spread_legal_limits_1.AXLE_SPREAD_LEGAL_LIMITS.SINGLE.MAXIMUM,
74
+ };
75
+ }
76
+ if (isTandemAxle) {
77
+ return getTandemAxleSpreadThreshold(vehicleConfiguration, vehicleIndex);
78
+ }
79
+ if (isTridemAxle) {
80
+ return getTridemAxleSpreadThreshold(vehicleConfiguration, vehicleIndex, axleConfiguration, axleIndex);
81
+ }
82
+ return undefined;
83
+ }
@@ -0,0 +1 @@
1
+ export declare function formatMeters(cm: number): string;
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.formatMeters = formatMeters;
4
+ function formatMeters(cm) {
5
+ return (cm / 100).toFixed(2).replace(/(\.\d)0$/u, '$1');
6
+ }
@@ -0,0 +1,6 @@
1
+ import { INTERAXLE_SPACING_LEGAL_MINIMUMS } from '../constants/interaxle-spacing-legal-minimums';
2
+ import { AxleConfiguration } from '../types/axle-configuration';
3
+ import { InteraxleSpacingRequirement } from '../types/interaxle-spacing-requirement';
4
+ export declare function getAxleUnitType(numberOfAxles: number): keyof typeof INTERAXLE_SPACING_LEGAL_MINIMUMS;
5
+ export declare function getFailedInteraxleSpacingMessage(requirement: InteraxleSpacingRequirement, previousAxleUnitNumber: number, currentAxleUnitNumber: number): string;
6
+ export declare function getInteraxleSpacingRequirement(axleConfiguration: Array<AxleConfiguration>, axleIndex: number): InteraxleSpacingRequirement | undefined;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getAxleUnitType = getAxleUnitType;
4
+ exports.getFailedInteraxleSpacingMessage = getFailedInteraxleSpacingMessage;
5
+ exports.getInteraxleSpacingRequirement = getInteraxleSpacingRequirement;
6
+ const interaxle_spacing_legal_minimums_1 = require("../constants/interaxle-spacing-legal-minimums");
7
+ const format_meters_helper_1 = require("./format-meters.helper");
8
+ function getAxleUnitType(numberOfAxles) {
9
+ if (numberOfAxles === 1) {
10
+ return 'SINGLE';
11
+ }
12
+ if (numberOfAxles === 2) {
13
+ return 'TANDEM';
14
+ }
15
+ return 'TRIDEM';
16
+ }
17
+ function getFailedInteraxleSpacingMessage(requirement, previousAxleUnitNumber, currentAxleUnitNumber) {
18
+ if (requirement.groupLabel) {
19
+ if (requirement.min && requirement.max) {
20
+ return `Interaxle Spacing for ${requirement.groupLabel} must be between ${(0, format_meters_helper_1.formatMeters)(requirement.min)} m and ${(0, format_meters_helper_1.formatMeters)(requirement.max)} m.`;
21
+ }
22
+ if (requirement.min) {
23
+ return `Interaxle Spacing for ${requirement.groupLabel} must be at least ${(0, format_meters_helper_1.formatMeters)(requirement.min)} m.`;
24
+ }
25
+ }
26
+ if (requirement.min && requirement.max) {
27
+ return `Interaxle Spacing between Axle Unit ${previousAxleUnitNumber} and Axle Unit ${currentAxleUnitNumber} must be between ${(0, format_meters_helper_1.formatMeters)(requirement.min)} m and ${(0, format_meters_helper_1.formatMeters)(requirement.max)} m.`;
28
+ }
29
+ if (requirement.min) {
30
+ return `Interaxle Spacing between Axle Unit ${previousAxleUnitNumber} and Axle Unit ${currentAxleUnitNumber} must be at least ${(0, format_meters_helper_1.formatMeters)(requirement.min)} m.`;
31
+ }
32
+ return '';
33
+ }
34
+ function getInteraxleSpacingRequirement(axleConfiguration, axleIndex) {
35
+ // the first axle unit will never have an interaxle spacing value or previous axle unit to compare against
36
+ if (axleIndex === 0) {
37
+ return undefined;
38
+ }
39
+ const axleUnit = axleConfiguration[axleIndex];
40
+ const previousAxleUnit = axleConfiguration[axleIndex - 1];
41
+ if (!Number.isFinite(axleUnit.interaxleSpacing) ||
42
+ !Number.isFinite(previousAxleUnit.numberOfAxles)) {
43
+ return undefined;
44
+ }
45
+ const previousAxleUnitType = getAxleUnitType(previousAxleUnit.numberOfAxles);
46
+ const currentAxleUnitType = getAxleUnitType(axleUnit.numberOfAxles);
47
+ return {
48
+ min: interaxle_spacing_legal_minimums_1.INTERAXLE_SPACING_LEGAL_MINIMUMS[previousAxleUnitType][currentAxleUnitType],
49
+ };
50
+ }
@@ -0,0 +1,5 @@
1
+ import { AxleGroupPolicyCheckResult, OverloadCalculationDetail } from '../types';
2
+ export declare const calculateOverload: (results: Array<AxleGroupPolicyCheckResult>, totalGCVW: number, licensedGVW: number, axleUnitCount: number) => {
3
+ overload: number;
4
+ overloadDetails: Array<OverloadCalculationDetail>;
5
+ };
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.calculateOverload = void 0;
4
+ const enum_1 = require("../enum");
5
+ const EMPTY_SELECTION = {
6
+ details: [],
7
+ overload: 0,
8
+ individualCount: 0,
9
+ };
10
+ const compareSelections = (first, second) => {
11
+ if (first.overload !== second.overload) {
12
+ return first.overload > second.overload ? first : second;
13
+ }
14
+ if (first.individualCount !== second.individualCount) {
15
+ return first.individualCount > second.individualCount ? first : second;
16
+ }
17
+ // Keep output deterministic when equivalent policy checks are reordered.
18
+ const firstKey = first.details
19
+ .map(({ startAxleUnit, endAxleUnit }) => `${startAxleUnit}:${endAxleUnit}`)
20
+ .join('|');
21
+ const secondKey = second.details
22
+ .map(({ startAxleUnit, endAxleUnit }) => `${startAxleUnit}:${endAxleUnit}`)
23
+ .join('|');
24
+ return firstKey <= secondKey ? first : second;
25
+ };
26
+ const getAxleOverloadCandidates = (results) => results
27
+ .filter(({ id, result, actualWeight, thresholdWeight }) => ((id === enum_1.PolicyCheckId.LegalWeight &&
28
+ result === enum_1.PolicyCheckResultType.Warning) ||
29
+ (id === enum_1.PolicyCheckId.AxleGroupMaximumLegalWeightThreshold &&
30
+ result === enum_1.PolicyCheckResultType.Fail)) &&
31
+ Number.isFinite(actualWeight) &&
32
+ Number.isFinite(thresholdWeight) &&
33
+ thresholdWeight > 0 &&
34
+ actualWeight > thresholdWeight)
35
+ .map(({ startAxleUnit, endAxleUnit, actualWeight, thresholdWeight }) => ({
36
+ kind: enum_1.OverloadCalculationDetailKind.AxleWeight,
37
+ startAxleUnit,
38
+ endAxleUnit,
39
+ actualWeight: actualWeight,
40
+ legalMaxWeight: thresholdWeight,
41
+ overload: actualWeight - thresholdWeight,
42
+ }))
43
+ .sort((first, second) => first.endAxleUnit - second.endAxleUnit ||
44
+ first.startAxleUnit - second.startAxleUnit);
45
+ const selectAxleOverloadDetails = (candidates) => {
46
+ const bestThroughCandidate = new Array(candidates.length + 1);
47
+ bestThroughCandidate[0] = EMPTY_SELECTION;
48
+ candidates.forEach((candidate, candidateIndex) => {
49
+ let predecessorIndex = candidateIndex - 1;
50
+ while (predecessorIndex >= 0 &&
51
+ candidates[predecessorIndex].endAxleUnit >= candidate.startAxleUnit) {
52
+ predecessorIndex--;
53
+ }
54
+ const predecessor = bestThroughCandidate[predecessorIndex + 1];
55
+ const withCandidate = {
56
+ details: [...predecessor.details, candidate],
57
+ overload: predecessor.overload + candidate.overload,
58
+ individualCount: predecessor.individualCount +
59
+ Number(candidate.startAxleUnit === candidate.endAxleUnit),
60
+ };
61
+ bestThroughCandidate[candidateIndex + 1] = compareSelections(bestThroughCandidate[candidateIndex], withCandidate);
62
+ });
63
+ return bestThroughCandidate[candidates.length];
64
+ };
65
+ const calculateOverload = (results, totalGCVW, licensedGVW, axleUnitCount) => {
66
+ const axleSelection = selectAxleOverloadDetails(getAxleOverloadCandidates(results));
67
+ const licensedGvwOverload = Math.max(0, totalGCVW - licensedGVW);
68
+ // Licensed GVW intentionally wins an exact tie with the axle calculation. We have
69
+ // to pick one, so this one made sense.
70
+ if (licensedGvwOverload > 0 && licensedGvwOverload >= axleSelection.overload) {
71
+ return {
72
+ overload: licensedGvwOverload,
73
+ overloadDetails: [
74
+ {
75
+ kind: enum_1.OverloadCalculationDetailKind.LicensedGvw,
76
+ startAxleUnit: 1,
77
+ endAxleUnit: axleUnitCount,
78
+ licensedGVW,
79
+ totalGCVW,
80
+ overload: licensedGvwOverload,
81
+ },
82
+ ],
83
+ };
84
+ }
85
+ return {
86
+ overload: axleSelection.overload,
87
+ overloadDetails: axleSelection.details,
88
+ };
89
+ };
90
+ exports.calculateOverload = calculateOverload;
@@ -283,7 +283,7 @@ export declare function CheckBoosterAxleLimit(_policy: Policy, vehicleConfigurat
283
283
  /**
284
284
  * Validates wheelbase legal limits for supported power unit vehicle sub-types.
285
285
  */
286
- export declare function CheckWheelbaseLegalLimits(policy: Policy, vehicleConfiguration: Array<string>, axleConfiguration: Array<AxleConfiguration>): Array<PolicyCheckResult>;
286
+ export declare function CheckWheelbaseLegalLimits(_policy: Policy, vehicleConfiguration: Array<string>, axleConfiguration: Array<AxleConfiguration>): Array<PolicyCheckResult>;
287
287
  /**
288
288
  * Validates that the drive axle unit and first jeep axle unit are load equalized
289
289
  * within 1000 kg when they have the same number of axles.
@@ -303,6 +303,10 @@ export declare function CheckDriveJeepLoadEqualization(_policy: Policy, vehicleC
303
303
  * current axle unit and the next axle unit, per Table II.
304
304
  */
305
305
  export declare function CheckLegalInteraxleSpacing(_policy: Policy, _vehicleConfiguration: Array<string>, axleConfiguration: Array<AxleConfiguration>): Array<PolicyCheckResult>;
306
+ /**
307
+ * Validates each axle unit against its legal axle spread maximum.
308
+ */
309
+ export declare function CheckLegalAxleSpread(policy: Policy, vehicleConfiguration: Array<string>, axleConfiguration: Array<AxleConfiguration>): Array<PolicyCheckResult>;
306
310
  /**
307
311
  * Map of policy check functions keyed by their corresponding PolicyCheckId.
308
312
  *
@@ -315,6 +319,7 @@ export declare function CheckLegalInteraxleSpacing(_policy: Policy, _vehicleConf
315
319
  * - AxleGroupMaximumLegalWeightThreshold: Validates axle groups within 8 m against CTR 7.17
316
320
  * - BridgeFormula: Validates axle groups against bridge formula requirements
317
321
  * - CheckLegalWeight: Validates axle units against legal weight limits
322
+ * - CheckLegalAxleSpread: Validates axle units against legal axle spread limits
318
323
  * - CheckPermittableWeight: Validates total vehicle weight against permit limits
319
324
  * - MaxTireLoad: Validates tire load capacity for each axle unit
320
325
  * - MinDriveAxleWeight: Validates minimum weight requirements for drive axles
@@ -17,47 +17,17 @@ exports.CheckBoosterAxleLimit = CheckBoosterAxleLimit;
17
17
  exports.CheckWheelbaseLegalLimits = CheckWheelbaseLegalLimits;
18
18
  exports.CheckDriveJeepLoadEqualization = CheckDriveJeepLoadEqualization;
19
19
  exports.CheckLegalInteraxleSpacing = CheckLegalInteraxleSpacing;
20
+ exports.CheckLegalAxleSpread = CheckLegalAxleSpread;
20
21
  const dimensions_helper_1 = require("./dimensions.helper");
21
22
  const ctr_717_helper_1 = require("./ctr-717.helper");
22
23
  const enum_1 = require("../enum");
23
- const POWER_UNIT_AXLE_CODE_MULTIPLIER = 10;
24
- const LEGAL_WEIGHT_MAXIMUM_KG = {
25
- SINGLE_AXLE: 9100,
26
- STANDARD_TRUCK_TRACTOR_STEER: 6000,
27
- STANDARD_SINGLE_STEER_WITH_TRIDEM_DRIVE: 7300,
28
- TANDEM_AXLE: 17000,
29
- STANDARD_TANDEM_STEER_WITH_TRIDEM_DRIVE: 13600,
30
- PME_TANDEM_STEER_WITH_TRIDEM_DRIVE: 15200,
31
- TRIDEM_AXLE: 24000,
32
- };
33
- const PERMITTABLE_WEIGHT_MAXIMUM_KG = {
34
- SINGLE_STEER: 9100,
35
- SINGLE_NON_STEER: 11000,
36
- TANDEM: 23000,
37
- STANDARD_TRIDEM: 28000,
38
- QUALIFYING_TRIDEM: 29000,
39
- };
40
- const QUALIFYING_TRIDEM_SPREAD_CM = {
41
- MINIMUM: 240,
42
- MAXIMUM: 370,
43
- };
44
- const INTERAXLE_SPACING_MINIMUM_CM = {
45
- SINGLE: {
46
- SINGLE: 300,
47
- TANDEM: 300,
48
- TRIDEM: 300,
49
- },
50
- TANDEM: {
51
- SINGLE: 300,
52
- TANDEM: 500,
53
- TRIDEM: 550,
54
- },
55
- TRIDEM: {
56
- SINGLE: 300,
57
- TANDEM: 550,
58
- TRIDEM: 600,
59
- },
60
- };
24
+ const axle_weight_legal_maximums_1 = require("../constants/axle-weight-legal-maximums");
25
+ const axle_weight_permittable_maximums_1 = require("../constants/axle-weight-permittable-maximums");
26
+ const power_unit_axle_code_multiplier_1 = require("../constants/power-unit-axle-code-multiplier");
27
+ const axle_spread_helper_1 = require("./axle-spread.helper");
28
+ const semi_trailer_types_1 = require("../constants/semi-trailer-types");
29
+ const interaxle_spacing_helper_1 = require("./interaxle-spacing.helper");
30
+ const format_meters_helper_1 = require("./format-meters.helper");
61
31
  /** Applies the standard lower-of rule or the exact 7.16(g) exception. */
62
32
  function getMaximumLegalAxleGroupWeightThreshold(individualLegalWeightSum, ctr717TableValue, isTandemDriveSingleJeepException) {
63
33
  const tandemDriveSingleJeepMinimumKg = 24000;
@@ -74,7 +44,7 @@ function getApplicableLegalWeightThreshold(policy, vehicleConfiguration, axleCon
74
44
  return undefined;
75
45
  }
76
46
  const weights = vehicleIndex === 0
77
- ? policy.getDefaultPowerUnitWeight(vehicleType, axleConfiguration[0].numberOfAxles * POWER_UNIT_AXLE_CODE_MULTIPLIER +
47
+ ? policy.getDefaultPowerUnitWeight(vehicleType, axleConfiguration[0].numberOfAxles * power_unit_axle_code_multiplier_1.POWER_UNIT_AXLE_CODE_MULTIPLIER +
78
48
  axleConfiguration[1].numberOfAxles)
79
49
  : policy.getDefaultTrailerWeight(vehicleType, axle.numberOfAxles);
80
50
  if (weights.length === 0) {
@@ -101,7 +71,7 @@ function getConfiguredAxleUnitWeightThreshold(policy, vehicleConfiguration, axle
101
71
  return 0;
102
72
  }
103
73
  const weights = vehicleIndex === 0
104
- ? policy.getDefaultPowerUnitWeight(vehicleType, axleConfiguration[0].numberOfAxles * POWER_UNIT_AXLE_CODE_MULTIPLIER +
74
+ ? policy.getDefaultPowerUnitWeight(vehicleType, axleConfiguration[0].numberOfAxles * power_unit_axle_code_multiplier_1.POWER_UNIT_AXLE_CODE_MULTIPLIER +
105
75
  axleConfiguration[1].numberOfAxles)
106
76
  : policy.getDefaultTrailerWeight(vehicleType, axleUnit.numberOfAxles);
107
77
  if (weights.length === 0) {
@@ -123,28 +93,28 @@ function getFeatureLegalPowerUnitWeightThreshold(vehicleType, axleConfiguration,
123
93
  if (steerAxle.numberOfAxles === 1 &&
124
94
  (driveAxle.numberOfAxles === 1 || driveAxle.numberOfAxles === 2)) {
125
95
  return hasPme || vehicleType === 'REGTRCK'
126
- ? LEGAL_WEIGHT_MAXIMUM_KG.SINGLE_AXLE
127
- : LEGAL_WEIGHT_MAXIMUM_KG.STANDARD_TRUCK_TRACTOR_STEER;
96
+ ? axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.SINGLE_AXLE
97
+ : axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.STANDARD_TRUCK_TRACTOR_STEER;
128
98
  }
129
99
  if (steerAxle.numberOfAxles === 1 && driveAxle.numberOfAxles === 3) {
130
100
  return hasPme
131
- ? LEGAL_WEIGHT_MAXIMUM_KG.SINGLE_AXLE
132
- : LEGAL_WEIGHT_MAXIMUM_KG.STANDARD_SINGLE_STEER_WITH_TRIDEM_DRIVE;
101
+ ? axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.SINGLE_AXLE
102
+ : axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.STANDARD_SINGLE_STEER_WITH_TRIDEM_DRIVE;
133
103
  }
134
104
  if (steerAxle.numberOfAxles === 2 && driveAxle.numberOfAxles === 2) {
135
- return LEGAL_WEIGHT_MAXIMUM_KG.TANDEM_AXLE;
105
+ return axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.TANDEM_AXLE;
136
106
  }
137
107
  if (steerAxle.numberOfAxles === 2 && driveAxle.numberOfAxles === 3) {
138
108
  return hasPme
139
- ? LEGAL_WEIGHT_MAXIMUM_KG.PME_TANDEM_STEER_WITH_TRIDEM_DRIVE
140
- : LEGAL_WEIGHT_MAXIMUM_KG.STANDARD_TANDEM_STEER_WITH_TRIDEM_DRIVE;
109
+ ? axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.PME_TANDEM_STEER_WITH_TRIDEM_DRIVE
110
+ : axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.STANDARD_TANDEM_STEER_WITH_TRIDEM_DRIVE;
141
111
  }
142
112
  }
143
113
  if (axleIndex === 1) {
144
114
  return {
145
- 1: LEGAL_WEIGHT_MAXIMUM_KG.SINGLE_AXLE,
146
- 2: LEGAL_WEIGHT_MAXIMUM_KG.TANDEM_AXLE,
147
- 3: LEGAL_WEIGHT_MAXIMUM_KG.TRIDEM_AXLE,
115
+ 1: axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.SINGLE_AXLE,
116
+ 2: axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.TANDEM_AXLE,
117
+ 3: axle_weight_legal_maximums_1.AXLE_WEIGHT_LEGAL_MAXIMUMS.TRIDEM_AXLE,
148
118
  }[driveAxle.numberOfAxles];
149
119
  }
150
120
  return undefined;
@@ -171,7 +141,12 @@ function CheckLegalWeight(policy, vehicleConfiguration, axleConfiguration) {
171
141
  return {
172
142
  id: policyId,
173
143
  message: `Weight for axle unit ${axleUnitNumber} ${result ? 'is legal' : `must not exceed ${legalWeight} kgs`}`,
174
- result: result ? enum_1.PolicyCheckResultType.Pass : enum_1.PolicyCheckResultType.Fail,
144
+ // We intentionally only return Pass/Warning, as we should never
145
+ // show an error for being above legal amount, only permitable
146
+ // amount. But it's still useful info for things like OCD table.
147
+ result: result
148
+ ? enum_1.PolicyCheckResultType.Pass
149
+ : enum_1.PolicyCheckResultType.Warning,
175
150
  axleUnit: axleUnitNumber,
176
151
  actualWeight: axleUnit.axleUnitWeight,
177
152
  thresholdWeight: legalWeight,
@@ -511,20 +486,24 @@ function CheckNumTiresPerAxle(_policy, _vehicleConfiguration, axleConfiguration)
511
486
  function CheckPermittableWeight(policy, vehicleConfiguration, axleConfiguration) {
512
487
  const policyId = enum_1.PolicyCheckId.PermittableWeight;
513
488
  const axleUnitVehicleIndexes = getAxleUnitVehicleIndexLookup(policy, vehicleConfiguration, axleConfiguration);
489
+ const QUALIFYING_TRIDEM_SPREAD_CM = {
490
+ MINIMUM: 240,
491
+ MAXIMUM: 370,
492
+ };
514
493
  return axleConfiguration.map((axleUnit, axleIndex) => {
515
494
  const vehicleIndex = axleUnitVehicleIndexes[axleIndex];
516
495
  const isSingleSteer = axleIndex === 0 && vehicleIndex === 0 && axleUnit.numberOfAxles === 1;
517
496
  const isTandemSteer = axleIndex === 0 && vehicleIndex === 0 && axleUnit.numberOfAxles === 2;
518
497
  let permittableWeight;
519
498
  if (isSingleSteer) {
520
- permittableWeight = PERMITTABLE_WEIGHT_MAXIMUM_KG.SINGLE_STEER;
499
+ permittableWeight = axle_weight_permittable_maximums_1.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS.SINGLE_STEER;
521
500
  }
522
501
  else if (!isTandemSteer) {
523
502
  if (axleUnit.numberOfAxles === 1) {
524
- permittableWeight = PERMITTABLE_WEIGHT_MAXIMUM_KG.SINGLE_NON_STEER;
503
+ permittableWeight = axle_weight_permittable_maximums_1.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS.SINGLE_NON_STEER;
525
504
  }
526
505
  else if (axleUnit.numberOfAxles === 2) {
527
- permittableWeight = PERMITTABLE_WEIGHT_MAXIMUM_KG.TANDEM;
506
+ permittableWeight = axle_weight_permittable_maximums_1.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS.TANDEM;
528
507
  }
529
508
  else if (axleUnit.numberOfAxles === 3) {
530
509
  const spreadQualifies = axleUnit.axleSpread !== undefined &&
@@ -538,8 +517,8 @@ function CheckPermittableWeight(policy, vehicleConfiguration, axleConfiguration)
538
517
  const boosterQualifies = !hasImmediatelyFollowingBooster || (boosterAxle === null || boosterAxle === void 0 ? void 0 : boosterAxle.numberOfAxles) === 1;
539
518
  permittableWeight =
540
519
  spreadQualifies && boosterQualifies
541
- ? PERMITTABLE_WEIGHT_MAXIMUM_KG.QUALIFYING_TRIDEM
542
- : PERMITTABLE_WEIGHT_MAXIMUM_KG.STANDARD_TRIDEM;
520
+ ? axle_weight_permittable_maximums_1.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS.QUALIFYING_TRIDEM
521
+ : axle_weight_permittable_maximums_1.AXLE_WEIGHT_PERMITTABLE_MAXIMUMS.STANDARD_TRIDEM;
543
522
  }
544
523
  }
545
524
  permittableWeight !== null && permittableWeight !== void 0 ? permittableWeight : (permittableWeight = getConfiguredAxleUnitWeightThreshold(policy, vehicleConfiguration, axleConfiguration, axleUnitVehicleIndexes, axleIndex, 'permittable'));
@@ -772,9 +751,12 @@ function CheckMinDriveAxleWeight(_policy, vehicleConfiguration, axleConfiguratio
772
751
  const driveAxle = axleConfiguration[1];
773
752
  const isTandemDrive = driveAxle.numberOfAxles === 2;
774
753
  const isTridemDrive = driveAxle.numberOfAxles === 3;
775
- // TODO we need to add Truck with PME and Truck Tractor with PME when ready
776
754
  const isSupportedVehicleSubtype = (value) => {
777
- return value === 'REGTRCK' || value === 'TRKTRAC' || value === 'PICKRTT';
755
+ return (value === 'REGTRCK' ||
756
+ value === 'TRKTRAC' ||
757
+ value === 'PICKRTT' ||
758
+ value === 'TRCKPME' ||
759
+ value === 'TRACPME');
778
760
  };
779
761
  if ((isTandemDrive || isTridemDrive) &&
780
762
  isSupportedVehicleSubtype(powerUnitSubtype)) {
@@ -976,8 +958,10 @@ function CheckMaxTireLoad(_policy, _vehicleConfiguration, axleConfiguration) {
976
958
  return;
977
959
  }
978
960
  // ORV2-5903 keeps this exact configuration as a grandfathered TPS case.
961
+ // The application stores the 279.4 mm option as 279 to match f
962
+ const hasGrandfatheredTpsTireSize = tireSize === 279.4 || tireSize === 279;
979
963
  const hasGrandfatheredTpsTireLimit = ac.numberOfAxles === 2 &&
980
- tireSize === 279.4 &&
964
+ hasGrandfatheredTpsTireSize &&
981
965
  numberOfTires === 8 &&
982
966
  axleWeight <= 23000;
983
967
  if (hasGrandfatheredTpsTireLimit) {
@@ -1068,7 +1052,7 @@ function CheckBoosterAxleLimit(_policy, vehicleConfiguration, axleConfiguration)
1068
1052
  /**
1069
1053
  * Validates wheelbase legal limits for supported power unit vehicle sub-types.
1070
1054
  */
1071
- function CheckWheelbaseLegalLimits(policy, vehicleConfiguration, axleConfiguration) {
1055
+ function CheckWheelbaseLegalLimits(_policy, vehicleConfiguration, axleConfiguration) {
1072
1056
  var _a, _b, _c;
1073
1057
  const resultBase = {
1074
1058
  id: enum_1.PolicyCheckId.WheelbaseLegalLimits,
@@ -1078,12 +1062,13 @@ function CheckWheelbaseLegalLimits(policy, vehicleConfiguration, axleConfigurati
1078
1062
  const powerUnitSubtype = vehicleConfiguration[0];
1079
1063
  const steerAxle = Object.assign(Object.assign({}, axleConfiguration[0]), { axleSpread: (_a = axleConfiguration[0].axleSpread) !== null && _a !== void 0 ? _a : 0 });
1080
1064
  const driveAxle = Object.assign(Object.assign({}, axleConfiguration[1]), { axleSpread: (_b = axleConfiguration[1].axleSpread) !== null && _b !== void 0 ? _b : 0, interaxleSpacing: (_c = axleConfiguration[1].interaxleSpacing) !== null && _c !== void 0 ? _c : 0 });
1081
- // TODO we need to add Truck with PME and Truck Tractor with PME when ready
1082
1065
  const isSupportedVehicleSubtype = (value) => {
1083
1066
  return (value === 'REGTRCK' ||
1084
1067
  value === 'TRKTRAC' ||
1085
1068
  value === 'PICKRTT' ||
1086
- value === 'OGBEDTK');
1069
+ value === 'OGBEDTK' ||
1070
+ value === 'TRCKPME' ||
1071
+ value === 'TRACPME');
1087
1072
  };
1088
1073
  const isSingleSteer = steerAxle.numberOfAxles === 1;
1089
1074
  const isTandemSteer = steerAxle.numberOfAxles === 2;
@@ -1091,6 +1076,8 @@ function CheckWheelbaseLegalLimits(policy, vehicleConfiguration, axleConfigurati
1091
1076
  const isTridemDrive = driveAxle.numberOfAxles === 3;
1092
1077
  const isTruckTractor = powerUnitSubtype === 'TRKTRAC';
1093
1078
  const isPickerTruckTractor = powerUnitSubtype === 'PICKRTT';
1079
+ const isTruckWithPME = powerUnitSubtype === 'TRCKPME';
1080
+ const isTruckTractorWithPME = powerUnitSubtype === 'TRACPME';
1094
1081
  const isOilfieldBedTruck = powerUnitSubtype === 'OGBEDTK';
1095
1082
  const wheelbase = isSingleSteer
1096
1083
  ? driveAxle.interaxleSpacing + driveAxle.axleSpread / 2
@@ -1108,12 +1095,10 @@ function CheckWheelbaseLegalLimits(policy, vehicleConfiguration, axleConfigurati
1108
1095
  ];
1109
1096
  }
1110
1097
  if (wheelbase >= 620) {
1111
- const hasDisallowedTrailer = vehicleConfiguration.slice(1).some((v) => {
1112
- const trailer = policy.getTrailerDefinition(v);
1113
- const isSemiTrailer = (trailer === null || trailer === void 0 ? void 0 : trailer.id) === 'SEMITRL';
1114
- return !isSemiTrailer;
1115
- });
1116
1098
  const hasTrailer = vehicleConfiguration.length > 1;
1099
+ const hasDisallowedTrailer = vehicleConfiguration
1100
+ .slice(1)
1101
+ .some((vehicleType) => !(0, semi_trailer_types_1.isSemiTrailerType)(vehicleType));
1117
1102
  return [
1118
1103
  Object.assign(Object.assign({}, resultBase), { result: hasDisallowedTrailer
1119
1104
  ? enum_1.PolicyCheckResultType.Fail
@@ -1128,8 +1113,10 @@ function CheckWheelbaseLegalLimits(policy, vehicleConfiguration, axleConfigurati
1128
1113
  }
1129
1114
  if (isSupportedVehicleSubtype(powerUnitSubtype)) {
1130
1115
  if (isSingleSteer && isTridemDrive) {
1131
- // TODO we need to add Truck with PME and Truck Tractor with PME when ready
1132
- if (isTruckTractor || isPickerTruckTractor) {
1116
+ if (isTruckTractor ||
1117
+ isPickerTruckTractor ||
1118
+ isTruckWithPME ||
1119
+ isTruckTractorWithPME) {
1133
1120
  if (wheelbase < 660) {
1134
1121
  return [
1135
1122
  Object.assign(Object.assign({}, resultBase), { result: enum_1.PolicyCheckResultType.Fail, message: 'Wheelbase for Axle Unit 1 is less than 6.6 m.' }),
@@ -1234,49 +1221,6 @@ function CheckDriveJeepLoadEqualization(_policy, vehicleConfiguration, axleConfi
1234
1221
  });
1235
1222
  return policyCheckResults;
1236
1223
  }
1237
- function getAxleUnitType(numberOfAxles) {
1238
- if (numberOfAxles === 1) {
1239
- return 'SINGLE';
1240
- }
1241
- if (numberOfAxles === 2) {
1242
- return 'TANDEM';
1243
- }
1244
- return 'TRIDEM';
1245
- }
1246
- function getInteraxleSpacingRequirement(axleConfiguration, axleIndex) {
1247
- // the first axle unit will never have an interaxle spacing value or previous axle unit to compare against
1248
- if (axleIndex === 0) {
1249
- return undefined;
1250
- }
1251
- const axleUnit = axleConfiguration[axleIndex];
1252
- const previousAxleUnit = axleConfiguration[axleIndex - 1];
1253
- if (!Number.isFinite(axleUnit.interaxleSpacing) ||
1254
- !Number.isFinite(previousAxleUnit.numberOfAxles)) {
1255
- return undefined;
1256
- }
1257
- const previousAxleUnitType = getAxleUnitType(previousAxleUnit.numberOfAxles);
1258
- const currentAxleUnitType = getAxleUnitType(axleUnit.numberOfAxles);
1259
- return {
1260
- min: INTERAXLE_SPACING_MINIMUM_CM[previousAxleUnitType][currentAxleUnitType],
1261
- };
1262
- }
1263
- function formatMeters(cm) {
1264
- return (cm / 100).toFixed(2).replace(/\.0+$/u, '');
1265
- }
1266
- function getFailedInteraxleSpacingMessage(requirement, previousAxleUnitNumber, currentAxleUnitNumber) {
1267
- if (requirement.groupLabel) {
1268
- if (requirement.min && requirement.max) {
1269
- return `Interaxle Spacing for ${requirement.groupLabel} must be between ${formatMeters(requirement.min)} m and ${formatMeters(requirement.max)} m.`;
1270
- }
1271
- if (requirement.min) {
1272
- return `Interaxle Spacing for ${requirement.groupLabel} must be at least ${formatMeters(requirement.min)} m.`;
1273
- }
1274
- }
1275
- if (requirement.min) {
1276
- return `Interaxle Spacing between Axle Unit ${previousAxleUnitNumber} and Axle Unit ${currentAxleUnitNumber} must be at least ${formatMeters(requirement.min)} m.`;
1277
- }
1278
- return '';
1279
- }
1280
1224
  /**
1281
1225
  * Validates each axle unit against the minimum interaxle spacing for its
1282
1226
  * current axle unit and the next axle unit, per Table II.
@@ -1284,7 +1228,7 @@ function getFailedInteraxleSpacingMessage(requirement, previousAxleUnitNumber, c
1284
1228
  function CheckLegalInteraxleSpacing(_policy, _vehicleConfiguration, axleConfiguration) {
1285
1229
  const policyId = enum_1.PolicyCheckId.LegalInteraxleSpacing;
1286
1230
  return axleConfiguration.map((axleUnit, axleIndex) => {
1287
- const requirement = getInteraxleSpacingRequirement(axleConfiguration, axleIndex);
1231
+ const requirement = (0, interaxle_spacing_helper_1.getInteraxleSpacingRequirement)(axleConfiguration, axleIndex);
1288
1232
  // Pass when no requirement exists, interaxle spacing is missing, or interaxle spacing falls within the requirement's min/max bounds.
1289
1233
  const shouldPass = !requirement ||
1290
1234
  !axleUnit.interaxleSpacing ||
@@ -1294,7 +1238,7 @@ function CheckLegalInteraxleSpacing(_policy, _vehicleConfiguration, axleConfigur
1294
1238
  const previousAxleUnitNumber = axleIndex;
1295
1239
  const message = shouldPass
1296
1240
  ? ''
1297
- : getFailedInteraxleSpacingMessage(requirement, previousAxleUnitNumber, axleUnitNumber);
1241
+ : (0, interaxle_spacing_helper_1.getFailedInteraxleSpacingMessage)(requirement, previousAxleUnitNumber, axleUnitNumber);
1298
1242
  return {
1299
1243
  id: policyId,
1300
1244
  message,
@@ -1305,6 +1249,37 @@ function CheckLegalInteraxleSpacing(_policy, _vehicleConfiguration, axleConfigur
1305
1249
  };
1306
1250
  });
1307
1251
  }
1252
+ /**
1253
+ * Validates each axle unit against its legal axle spread maximum.
1254
+ */
1255
+ function CheckLegalAxleSpread(policy, vehicleConfiguration, axleConfiguration) {
1256
+ const policyId = enum_1.PolicyCheckId.LegalAxleSpread;
1257
+ const axleUnitVehicleIndexes = getAxleUnitVehicleIndexLookup(policy, vehicleConfiguration, axleConfiguration);
1258
+ return axleConfiguration.flatMap((axleUnit, axleIndex) => {
1259
+ const threshold = (0, axle_spread_helper_1.getAxleSpreadThreshold)(vehicleConfiguration, axleUnitVehicleIndexes, axleConfiguration, axleIndex);
1260
+ if (!axleUnit.axleSpread ||
1261
+ !threshold ||
1262
+ !Number.isFinite(axleUnit.axleSpread)) {
1263
+ return [];
1264
+ }
1265
+ const result = axleUnit.axleSpread >= threshold.minCm &&
1266
+ axleUnit.axleSpread <= threshold.maxCm;
1267
+ const axleUnitNumber = axleIndex + 1;
1268
+ const message = result
1269
+ ? ''
1270
+ : `Axle Spread for Axle Unit ${axleUnitNumber} must be between ${(0, format_meters_helper_1.formatMeters)(threshold.minCm)} m and ${(0, format_meters_helper_1.formatMeters)(threshold.maxCm)} m.`;
1271
+ return [
1272
+ {
1273
+ id: policyId,
1274
+ result: result
1275
+ ? enum_1.PolicyCheckResultType.Pass
1276
+ : enum_1.PolicyCheckResultType.Fail,
1277
+ message,
1278
+ axleUnit: axleUnitNumber,
1279
+ },
1280
+ ];
1281
+ });
1282
+ }
1308
1283
  /**
1309
1284
  * Map of policy check functions keyed by their corresponding PolicyCheckId.
1310
1285
  *
@@ -1317,6 +1292,7 @@ function CheckLegalInteraxleSpacing(_policy, _vehicleConfiguration, axleConfigur
1317
1292
  * - AxleGroupMaximumLegalWeightThreshold: Validates axle groups within 8 m against CTR 7.17
1318
1293
  * - BridgeFormula: Validates axle groups against bridge formula requirements
1319
1294
  * - CheckLegalWeight: Validates axle units against legal weight limits
1295
+ * - CheckLegalAxleSpread: Validates axle units against legal axle spread limits
1320
1296
  * - CheckPermittableWeight: Validates total vehicle weight against permit limits
1321
1297
  * - MaxTireLoad: Validates tire load capacity for each axle unit
1322
1298
  * - MinDriveAxleWeight: Validates minimum weight requirements for drive axles
@@ -1341,6 +1317,7 @@ exports.policyCheckMap = new Map([
1341
1317
  enum_1.PolicyCheckId.AxleGroupMaximumLegalWeightThreshold,
1342
1318
  CheckAxleGroupMaximumLegalWeightThreshold,
1343
1319
  ],
1320
+ [enum_1.PolicyCheckId.LegalAxleSpread, CheckLegalAxleSpread],
1344
1321
  [enum_1.PolicyCheckId.LegalWeight, CheckLegalWeight],
1345
1322
  [enum_1.PolicyCheckId.PermittableWeight, CheckPermittableWeight],
1346
1323
  [enum_1.PolicyCheckId.MaxTireLoad, CheckMaxTireLoad],
@@ -22,6 +22,7 @@ const dimensions_helper_2 = require("./helper/dimensions.helper");
22
22
  const display_code_helper_1 = require("./helper/display-code-helper");
23
23
  const policy_check_helper_1 = require("./helper/policy-check.helper");
24
24
  const cost_1 = require("./constants/cost");
25
+ const overload_helper_1 = require("./helper/overload.helper");
25
26
  /** Class representing commercial vehicle policy. */
26
27
  class Policy {
27
28
  /**
@@ -717,8 +718,14 @@ class Policy {
717
718
  const axleCalcResults = {
718
719
  results: [],
719
720
  overload: 0,
721
+ overloadDetails: [],
720
722
  totalGCVW: 0,
721
723
  };
724
+ const updateOverloadCalculation = () => {
725
+ const { overload, overloadDetails } = (0, overload_helper_1.calculateOverload)(axleCalcResults.results, axleCalcResults.totalGCVW, licensedGVW, axleConfiguration.length);
726
+ axleCalcResults.overload = overload;
727
+ axleCalcResults.overloadDetails = overloadDetails;
728
+ };
722
729
  // This is a little helper closure that just converts any PolicyCheckResult into an AxleGroupPolicyCheckResult,
723
730
  // basically giving us startAxleUnit and endAxleUnit, which can help with frontend form highlighting.
724
731
  const toAxleGroupPolicyCheckResult = (result) => {
@@ -731,11 +738,11 @@ class Policy {
731
738
  return Object.assign(Object.assign({}, result), { startAxleUnit: 1, endAxleUnit: axleConfiguration.length });
732
739
  };
733
740
  const gvcw = axleConfiguration.reduce((w, curr) => w + curr.axleUnitWeight, 0);
734
- axleCalcResults.overload = Math.max(axleCalcResults.overload, gvcw - licensedGVW);
735
741
  axleCalcResults.totalGCVW = gvcw;
736
742
  const axleCountResults = (0, policy_check_helper_1.CheckNumberOfAxles)(this, vehicleConfiguration, axleConfiguration);
737
743
  axleCalcResults.results.push(...axleCountResults.map(toAxleGroupPolicyCheckResult));
738
744
  if (axleCountResults.some((r) => r.result === enum_1.PolicyCheckResultType.Fail)) {
745
+ updateOverloadCalculation();
739
746
  return axleCalcResults;
740
747
  }
741
748
  for (const [policyCheckId, policyCheck] of policy_check_helper_1.policyCheckMap) {
@@ -744,6 +751,7 @@ class Policy {
744
751
  }
745
752
  axleCalcResults.results.push(...policyCheck(this, vehicleConfiguration, axleConfiguration).map(toAxleGroupPolicyCheckResult));
746
753
  }
754
+ updateOverloadCalculation();
747
755
  return axleCalcResults;
748
756
  }
749
757
  /**
@@ -4,7 +4,7 @@
4
4
  * These types define the structure for axle calculation results and policy check outcomes.
5
5
  * Used for validating vehicle configurations against weight and axle requirements.
6
6
  */
7
- import { PolicyCheckId, PolicyCheckResultType } from 'onroute-policy-engine/enum';
7
+ import { OverloadCalculationDetailKind, PolicyCheckId, PolicyCheckResultType } from 'onroute-policy-engine/enum';
8
8
  /**
9
9
  * Complete results from axle calculations including all policy checks and total overload
10
10
  */
@@ -13,9 +13,30 @@ export type AxleCalcResults = {
13
13
  results: Array<AxleGroupPolicyCheckResult>;
14
14
  /** Total weight overload across all axles in kilograms */
15
15
  overload: number;
16
+ /** Details for only the selected overload calculation */
17
+ overloadDetails: Array<OverloadCalculationDetail>;
16
18
  /** Total Gross Combined Vehicle Weight across all axles in kilograms */
17
19
  totalGCVW: number;
18
20
  };
21
+ /** Licensed-GVW overload selected across the complete axle configuration. */
22
+ export type LicensedGvwOverloadCalculationDetail = {
23
+ kind: OverloadCalculationDetailKind.LicensedGvw;
24
+ startAxleUnit: number;
25
+ endAxleUnit: number;
26
+ licensedGVW: number;
27
+ totalGCVW: number;
28
+ overload: number;
29
+ };
30
+ /** Legal-weight overload selected for an axle unit or axle-unit group. */
31
+ export type AxleWeightOverloadCalculationDetail = {
32
+ kind: OverloadCalculationDetailKind.AxleWeight;
33
+ startAxleUnit: number;
34
+ endAxleUnit: number;
35
+ actualWeight: number;
36
+ legalMaxWeight: number;
37
+ overload: number;
38
+ };
39
+ export type OverloadCalculationDetail = LicensedGvwOverloadCalculationDetail | AxleWeightOverloadCalculationDetail;
19
40
  /**
20
41
  * Individual policy check result for a specific validation rule
21
42
  */
@@ -0,0 +1,6 @@
1
+ export declare const AXLE_UNIT_TYPES: {
2
+ readonly SINGLE: 'SINGLE';
3
+ readonly TANDEM: 'TANDEM';
4
+ readonly TRIDEM: 'TRIDEM';
5
+ };
6
+ export type AxleUnitType = (typeof AXLE_UNIT_TYPES)[keyof typeof AXLE_UNIT_TYPES];
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.AXLE_UNIT_TYPES = void 0;
4
+ exports.AXLE_UNIT_TYPES = {
5
+ SINGLE: 'SINGLE',
6
+ TANDEM: 'TANDEM',
7
+ TRIDEM: 'TRIDEM',
8
+ };
@@ -1,4 +1,4 @@
1
- export type { AxleCalcResults, PolicyCheckResult, AxleUnitPolicyCheckResult, AxleGroupPolicyCheckResult, } from './axle-calculation-results';
1
+ export type { AxleCalcResults, PolicyCheckResult, AxleUnitPolicyCheckResult, AxleGroupPolicyCheckResult, OverloadCalculationDetail, LicensedGvwOverloadCalculationDetail, AxleWeightOverloadCalculationDetail, } from './axle-calculation-results';
2
2
  export type { AxleConfiguration, IndexedAxleConfiguration, } from './axle-configuration';
3
3
  export type { BridgeCalculationConstants } from './bridge-calculation-constants';
4
4
  export type { BridgeCalculationResult } from './bridge-calculation-result';
@@ -0,0 +1,5 @@
1
+ export interface InteraxleSpacingRequirement {
2
+ min?: number;
3
+ max?: number;
4
+ groupLabel?: string;
5
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "v2.26.1";
1
+ export declare const version = "v2.28.0";
package/dist/version.js CHANGED
@@ -2,4 +2,4 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.version = void 0;
4
4
  // Generated by genversion.
5
- exports.version = 'v2.26.1';
5
+ exports.version = 'v2.28.0';
package/package.json CHANGED
@@ -91,5 +91,5 @@
91
91
  ],
92
92
  "testEnvironment": "node"
93
93
  },
94
- "version": "v2.26.1"
94
+ "version": "v2.28.0"
95
95
  }