@classytic/ca-tax 0.0.14 → 0.0.15

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.
package/dist/t2.mjs CHANGED
@@ -262,7 +262,6 @@ const AT1_SCHEDULES_WITH_BUILDERS = Object.freeze([
262
262
  "008",
263
263
  "009",
264
264
  "010",
265
- "011",
266
265
  "012",
267
266
  "013",
268
267
  "015",
@@ -275,18 +274,20 @@ const AT1_SCHEDULES_WITH_BUILDERS = Object.freeze([
275
274
  "4970"
276
275
  ]);
277
276
  /**
278
- * Schedules the engine computes but cannot yet file.
279
- *
280
- * **014** (cumulative eligible capital) is here for a different reason from the
281
- * rest: eligible capital property was repealed on 1 January 2017 and a certified
282
- * preparer does not offer the schedule for a current year at all, so its field
283
- * numbers cannot be verified the way every other schedule's were. It applies only
284
- * to the 2016/2017 straddling year.
285
- *
286
- * Every other schedule has been verified line by line against the live certified
287
- * form.
277
+ * Schedules the engine computes but cannot yet file — currently empty.
278
+ *
279
+ * Its one member, Schedule 14 (cumulative eligible capital), was removed
280
+ * entirely rather than left here: it had no server wiring and no UI to begin
281
+ * with, and applies only to a corporation whose tax year straddles
282
+ * 2016-12-31 (eligible capital property's repeal date) see
283
+ * `research/findings/alberta/AT1-schedule14-cec.md`.
284
+ *
285
+ * Every implemented schedule has been verified line by line against the live
286
+ * certified form. Kept as a named, tested concept (not deleted outright)
287
+ * since a future schedule may legitimately land here again before its
288
+ * builder does.
288
289
  */
289
- const AT1_SCHEDULES_WITHOUT_BUILDERS = Object.freeze(["014"]);
290
+ const AT1_SCHEDULES_WITHOUT_BUILDERS = Object.freeze([]);
290
291
  /** `SSSFFFOOO` — schedule id, field id, occurrence. Occurrence is 1-based. */
291
292
  function at1LineItemId(scheduleId, fieldId, occurrence = 1) {
292
293
  return `${scheduleId}${fieldId}${String(occurrence).padStart(3, "0")}`;
@@ -304,6 +305,8 @@ function schedule13Values(result) {
304
305
  value
305
306
  });
306
307
  put("001", c.ccaClass);
308
+ put("035", c.alberta.aiipEnhancement);
309
+ put("037", c.alberta.halfYearAdjustment);
307
310
  put("019", c.alberta.ccaClaimed);
308
311
  put("015", c.alberta.recapture);
309
312
  put("017", c.alberta.terminalLoss);
@@ -512,6 +515,7 @@ function schedule29Values(result, agreement, eligible, primaryFieldCode) {
512
515
  put("031", eligible.totalEligibleExpenditures);
513
516
  }
514
517
  if (primaryFieldCode !== void 0) put("040", primaryFieldCode);
518
+ put("100", agreement ? 1 : 2);
515
519
  put("110", result.creditAtBaseRate);
516
520
  put(result.enhancedRateBasis === "associated" ? "125" : "112", result.creditAtEnhancedRate);
517
521
  put("126", result.taxableCapital);
@@ -673,13 +677,26 @@ function schedule12Values(input) {
673
677
  pair("004", "005", input.cca);
674
678
  pair("006", "007", input.recapture);
675
679
  pair("008", "009", input.terminalLoss);
680
+ pair("022", "023", input.depletion);
681
+ pair("026", "027", input.cee);
682
+ pair("028", "029", input.cde);
683
+ pair("030", "031", input.foreignExploration);
684
+ pair("032", "033", input.cogpe);
676
685
  pair("036", "037", input.reservesDeductedPriorYear);
677
686
  pair("038", "039", input.reservesClaimedCurrentYear);
687
+ const alwaysPair = (albertaField, federalField, p) => {
688
+ if (!p) return;
689
+ put(albertaField, p.alberta);
690
+ put(federalField, p.federal);
691
+ };
678
692
  const d = input.lossDeductions;
679
- pair("064", "065", d?.nonCapital);
680
- pair("066", "067", d?.netCapital);
681
- pair("068", "069", d?.restrictedFarm);
682
- pair("070", "071", d?.farm);
693
+ alwaysPair("064", "065", d?.nonCapital);
694
+ alwaysPair("066", "067", d?.netCapital);
695
+ alwaysPair("068", "069", d?.restrictedFarm);
696
+ alwaysPair("070", "071", d?.farm);
697
+ alwaysPair("072", "073", d?.limitedPartnership);
698
+ alwaysPair("056", "057", input.donations?.charitable);
699
+ alwaysPair("058", "059", input.donations?.gifts);
683
700
  put("054", input.albertaNetIncomeForTax);
684
701
  return {
685
702
  scheduleId: "012",
@@ -816,7 +833,6 @@ function schedule1Values(input) {
816
833
  lineItemId: at1LineItemId("001", fieldId, occurrence),
817
834
  value
818
835
  });
819
- if (input.isAssociated !== void 0) put("001", input.isAssociated ? 1 : 2);
820
836
  const abi = Math.max(0, input.activeBusinessIncome ?? 0);
821
837
  const taxable = Math.max(0, input.albertaTaxableIncome ?? 0);
822
838
  const royalty = Math.max(0, input.royaltyTaxDeduction ?? 0);
@@ -2196,130 +2212,6 @@ function schedule9Values(result, group) {
2196
2212
  };
2197
2213
  }
2198
2214
  //#endregion
2199
- //#region src/t2/at1/schedules/schedule11-manufacturing-processing.ts
2200
- const nn$26 = (v) => Math.max(0, Math.round(v ?? 0));
2201
- function computeSchedule11(input) {
2202
- const issues = [];
2203
- const dateEligible = input.taxYearStart < "2001-04-01";
2204
- if (!dateEligible) issues.push(`Schedule 11: the Alberta Manufacturing and Processing Profits Deduction applies only where the tax year begins before 2001-04-01 (TRA-spec lines 9135-9146). This tax year begins ${input.taxYearStart}, so no deduction applies; line 011042 is reported as nil regardless of the workings below.`);
2205
- let grossRevenueRatio;
2206
- let revenueEligible = true;
2207
- if (dateEligible) if (input.manufacturingGrossRevenue == null || input.totalGrossRevenue == null) {
2208
- revenueEligible = false;
2209
- issues.push("Schedule 11: the 10% manufacturing gross-revenue test (TRA-spec lines 9138-9142) could not be run because gross revenue figures were not supplied, so form 011 is treated as not applicable.");
2210
- } else {
2211
- const total = nn$26(input.totalGrossRevenue);
2212
- grossRevenueRatio = total > 0 ? nn$26(input.manufacturingGrossRevenue) / total : 0;
2213
- if (grossRevenueRatio < .1) {
2214
- revenueEligible = false;
2215
- issues.push(`Schedule 11: manufacturing gross revenue is ${(grossRevenueRatio * 100).toFixed(1)}% of total gross revenue, below the 10% threshold in the AT1 spec, so form 011 is not applicable.`);
2216
- }
2217
- }
2218
- const eligible = dateEligible && revenueEligible;
2219
- let albertaAdjubi;
2220
- if (input.albertaAdjubiFromSchedule12) albertaAdjubi = Math.max(0, Math.round(input.albertaAdjubiFromSchedule12.line112 + input.albertaAdjubiFromSchedule12.line114));
2221
- else {
2222
- albertaAdjubi = nn$26(input.federalAdjubi);
2223
- if (input.federalAdjubi == null && eligible) issues.push("Schedule 11: neither `federalAdjubi` (fed 027130) nor `albertaAdjubiFromSchedule12` was supplied; line 011001 defaults to nil.");
2224
- }
2225
- let aggregateInvestmentIncome;
2226
- if (input.isCcpc) if (input.schedule12Exists) aggregateInvestmentIncome = nn$26(input.albertaAggregateInvestmentIncome);
2227
- else {
2228
- aggregateInvestmentIncome = nn$26(input.federalAggregateInvestmentIncome);
2229
- if (input.federalAggregateInvestmentIncome == null) issues.push("Schedule 11: the corp is a CCPC and no Alberta Schedule 12 exists, so line 011013 must equal fed 200440, but `federalAggregateInvestmentIncome` was not supplied; line 011013 defaults to nil.");
2230
- }
2231
- const isSmallManufacturingCorp = input.isSmallManufacturingCorp ?? false;
2232
- let costOfCapital = 0;
2233
- let albertaCostOfCapital = 0;
2234
- let costOfLabour = 0;
2235
- let albertaCostOfLabour = 0;
2236
- let albertaManufacturingProcessingProfits = 0;
2237
- if (isSmallManufacturingCorp) {
2238
- if (input.costOfCapital != null || input.albertaCostOfCapital != null || input.costOfLabour != null || input.albertaCostOfLabour != null) issues.push("Schedule 11: lines 011031-011039 must not exist for a small manufacturing corp, but capital/labour figures were supplied; they are ignored for line 011042.");
2239
- if (input.smallManufacturerAmpp != null) albertaManufacturingProcessingProfits = nn$26(input.smallManufacturerAmpp);
2240
- else if (eligible) issues.push("Schedule 11: the small-manufacturing-corp formula for line 011042 is not stated in the transcribed spec range (TRA-spec lines 9082-9397); supply `smallManufacturerAmpp` directly per the AT1 Guide criteria. Line 011042 defaults to nil.");
2241
- } else {
2242
- costOfCapital = nn$26(input.costOfCapital);
2243
- albertaCostOfCapital = nn$26(input.albertaCostOfCapital);
2244
- costOfLabour = nn$26(input.costOfLabour);
2245
- albertaCostOfLabour = nn$26(input.albertaCostOfLabour);
2246
- if (albertaCostOfCapital > costOfCapital) {
2247
- issues.push(`Schedule 11: line 011033 (Alberta Cost of Manufacturing and Processing Capital, ${albertaCostOfCapital}) exceeds line 011031 (Cost of Capital, ${costOfCapital}); the AT1 spec requires 011033 ≤ 011031. Clamped to ${costOfCapital}.`);
2248
- albertaCostOfCapital = costOfCapital;
2249
- }
2250
- if (albertaCostOfLabour > costOfLabour) {
2251
- issues.push(`Schedule 11: line 011039 (Alberta Cost of Manufacturing and Processing Labour, ${albertaCostOfLabour}) exceeds line 011037 (Cost of Labour, ${costOfLabour}); the AT1 spec requires 011039 ≤ 011037. Clamped to ${costOfLabour}.`);
2252
- albertaCostOfLabour = costOfLabour;
2253
- }
2254
- const denominator = costOfCapital + costOfLabour;
2255
- if (denominator === 0) {
2256
- if (albertaAdjubi > 0 && eligible) issues.push("Schedule 11: Cost of Capital (011031) and Cost of Labour (011037) are both nil, so the line 011042 proration cannot be computed; supply them. Line 011042 defaults to nil.");
2257
- } else {
2258
- const factor = (Math.min(albertaCostOfCapital * 100 / 85, costOfCapital) + Math.min(albertaCostOfLabour * 100 / 75, costOfLabour)) / denominator;
2259
- albertaManufacturingProcessingProfits = Math.round(albertaAdjubi * factor);
2260
- }
2261
- }
2262
- if (!eligible && albertaManufacturingProcessingProfits > 0) issues.push(`Schedule 11: the workings above yield ${albertaManufacturingProcessingProfits}, but the deduction is not applicable this year (see the eligibility issue above); line 011042 is reported as nil.`);
2263
- if (!eligible) albertaManufacturingProcessingProfits = 0;
2264
- return {
2265
- eligible,
2266
- isSmallManufacturingCorp,
2267
- albertaAdjubi,
2268
- ...aggregateInvestmentIncome !== void 0 ? { aggregateInvestmentIncome } : {},
2269
- costOfCapital,
2270
- albertaCostOfCapital,
2271
- costOfLabour,
2272
- albertaCostOfLabour,
2273
- albertaManufacturingProcessingProfits,
2274
- ...grossRevenueRatio !== void 0 ? { grossRevenueRatio } : {},
2275
- issues
2276
- };
2277
- }
2278
- function schedule11LineItemId(fieldId, occurrence = 1) {
2279
- return `011${fieldId}${String(occurrence).padStart(3, "0")}`;
2280
- }
2281
- /**
2282
- * Field ids per the spec transcription above: 001 (AMPPD/ADJUBI), 013 (CCPC
2283
- * aggregate investment income), 031/033/037/039 (cost of capital/labour, both
2284
- * jurisdictions) and 042 (Alberta M&P Profits).
2285
- *
2286
- * Line 042 is ALWAYS emitted, including when the historical-eligibility gate
2287
- * (pre-2001-04-01 tax year AND the 10% gross-revenue test) has forced it to
2288
- * nil — an ineligible year still has a line 011042 on the form, and it reads
2289
- * nil, so this files nil rather than omitting the line entirely. The REASON
2290
- * it is nil (a `Schedule 11: … applies only where the tax year begins before
2291
- * 2001-04-01 …` / `… below the 10% threshold …` entry) lives on
2292
- * `result.issues`, which this builder does not carry onto the wire itself —
2293
- * the caller already has `result` (this function's own input) and so already
2294
- * has `result.issues` sitting beside whatever this returns; duplicating it
2295
- * onto `At1ScheduleDataLike`, which has no field for prose, would only be
2296
- * losing information conversion by not adding any.
2297
- *
2298
- * Line 013 (CCPC aggregate investment income) is the one line legitimately
2299
- * OMITTED rather than filed as nil: it is undefined, not zero, for a non-CCPC
2300
- * corporation — the spec's own business rule gates it on `000029 = 1 or 2`,
2301
- * so a non-CCPC has no box to fill here at all, unlike line 042's "nil is a
2302
- * real answer" case above.
2303
- */
2304
- function schedule11Values(result) {
2305
- const values = [];
2306
- const put = (fieldId, value) => values.push({
2307
- lineItemId: schedule11LineItemId(fieldId),
2308
- value
2309
- });
2310
- put("001", result.albertaAdjubi);
2311
- if (result.aggregateInvestmentIncome !== void 0) put("013", result.aggregateInvestmentIncome);
2312
- put("031", result.costOfCapital);
2313
- put("033", result.albertaCostOfCapital);
2314
- put("037", result.costOfLabour);
2315
- put("039", result.albertaCostOfLabour);
2316
- put("042", result.albertaManufacturingProcessingProfits);
2317
- return {
2318
- scheduleId: "011",
2319
- values
2320
- };
2321
- }
2322
- //#endregion
2323
2215
  //#region src/t2/at1/schedules/schedule15-resource-related-deductions.ts
2324
2216
  /**
2325
2217
  * Alberta AT1 Schedule 15 — Alberta Resource Related Deductions.
@@ -2466,9 +2358,9 @@ function schedule11Values(result) {
2466
2358
  *
2467
2359
  * Whole dollars, pure functions, no I/O.
2468
2360
  */
2469
- const nn$25 = (v) => Math.max(0, v ?? 0);
2361
+ const nn$26 = (v) => Math.max(0, v ?? 0);
2470
2362
  const num$1 = (v) => v ?? 0;
2471
- const round = (v) => Math.round(v);
2363
+ const round$1 = (v) => Math.round(v);
2472
2364
  /** `override ?? federal`, tracking whether an Alberta-specific figure was actually entered. */
2473
2365
  function reconcile(federal, override) {
2474
2366
  return override !== void 0 ? {
@@ -2483,7 +2375,7 @@ function reconcile(federal, override) {
2483
2375
  * CDE / CCOGPE style short-tax-year proration: the full rate applies with NO
2484
2376
  * proration once the tax year reaches 357 days; below that, rate × days/365.
2485
2377
  */
2486
- function stepYearFactor(daysInTaxYear) {
2378
+ function stepYearFactor$1(daysInTaxYear) {
2487
2379
  const days = daysInTaxYear ?? 365;
2488
2380
  return days >= 357 ? 1 : Math.max(0, days) / 365;
2489
2381
  }
@@ -2492,18 +2384,18 @@ function linearYearFactor(daysInTaxYear) {
2492
2384
  return Math.max(0, daysInTaxYear ?? 365) / 365;
2493
2385
  }
2494
2386
  /** A discretionary claim capped at `cap` (≥ 0), defaulting to the maximum (`cap`) when omitted. */
2495
- function claimUpToCap(requested, cap, issues, label) {
2496
- const c = Math.max(0, round(cap));
2387
+ function claimUpToCap$1(requested, cap, issues, label) {
2388
+ const c = Math.max(0, round$1(cap));
2497
2389
  if (requested === void 0) return c;
2498
2390
  if (requested < 0) {
2499
2391
  issues.push(`${label}: a requested claim of ${requested} is negative; treated as 0.`);
2500
2392
  return 0;
2501
2393
  }
2502
- if (round(requested) > c) {
2394
+ if (round$1(requested) > c) {
2503
2395
  issues.push(`${label}: the requested claim of ${requested} exceeds the maximum allowable ${c} for the year; capped at ${c}.`);
2504
2396
  return c;
2505
2397
  }
2506
- return round(requested);
2398
+ return round$1(requested);
2507
2399
  }
2508
2400
  /**
2509
2401
  * CEE-style claim: when the pool subtotal is ≤ 0 the claim MUST equal that
@@ -2512,12 +2404,12 @@ function claimUpToCap(requested, cap, issues, label) {
2512
2404
  * claim up to the subtotal (100% claimable, no percentage rate), defaulting
2513
2405
  * to the maximum.
2514
2406
  */
2515
- function forcedOrCappedClaim(requested, subtotal, issues, label) {
2407
+ function forcedOrCappedClaim$1(requested, subtotal, issues, label) {
2516
2408
  if (subtotal <= 0) {
2517
- if (requested !== void 0 && round(requested) !== round(subtotal)) issues.push(`${label}: the pool subtotal is ${subtotal} (≤ 0), so the claim must equal the subtotal (an income inclusion) — overriding the requested ${requested}.`);
2518
- return round(subtotal);
2409
+ if (requested !== void 0 && round$1(requested) !== round$1(subtotal)) issues.push(`${label}: the pool subtotal is ${subtotal} (≤ 0), so the claim must equal the subtotal (an income inclusion) — overriding the requested ${requested}.`);
2410
+ return round$1(subtotal);
2519
2411
  }
2520
- return claimUpToCap(requested, subtotal, issues, label);
2412
+ return claimUpToCap$1(requested, subtotal, issues, label);
2521
2413
  }
2522
2414
  function computeEdaRegular(input) {
2523
2415
  const issues = [];
@@ -2542,12 +2434,12 @@ function computeEdaRegular(input) {
2542
2434
  }
2543
2435
  /** A reconciled figure that is ALSO capped by a pool — the EDA/CMEDB claim shape (015007, 015019). */
2544
2436
  function pool_cappedClaim(reconciled, pool, issues, label) {
2545
- const cap = Math.max(0, round(pool));
2437
+ const cap = Math.max(0, round$1(pool));
2546
2438
  if (pool <= 0) return {
2547
2439
  value: 0,
2548
2440
  differs: reconciled.differs
2549
2441
  };
2550
- if (round(reconciled.value) > cap) {
2442
+ if (round$1(reconciled.value) > cap) {
2551
2443
  issues.push(`${label}: the entered claim ${reconciled.value} exceeds the pool ${cap}; capped.`);
2552
2444
  return {
2553
2445
  value: cap,
@@ -2555,7 +2447,7 @@ function pool_cappedClaim(reconciled, pool, issues, label) {
2555
2447
  };
2556
2448
  }
2557
2449
  return {
2558
- value: Math.max(0, round(reconciled.value)),
2450
+ value: Math.max(0, round$1(reconciled.value)),
2559
2451
  differs: reconciled.differs
2560
2452
  };
2561
2453
  }
@@ -2591,7 +2483,7 @@ function computeCmedb(input) {
2591
2483
  const other = reconcile(f.otherTransfer, o.otherTransfer);
2592
2484
  const disposal = reconcile(f.disposalTransfer, o.disposalTransfer);
2593
2485
  const poolBeforeClaim = opening.value + amalg.value + other.value - disposal.value;
2594
- const claim = poolBeforeClaim <= 0 ? 0 : claimUpToCap(input.claimed, poolBeforeClaim, issues, "Schedule 15 CMEDB (015031)");
2486
+ const claim = poolBeforeClaim <= 0 ? 0 : claimUpToCap$1(input.claimed, poolBeforeClaim, issues, "Schedule 15 CMEDB (015031)");
2595
2487
  const closingBalance = poolBeforeClaim - claim;
2596
2488
  return {
2597
2489
  openingBalance: opening.value,
@@ -2622,7 +2514,7 @@ function computeCeeRegular(input) {
2622
2514
  const renouncedFlowThrough = num$1(f.renouncedFlowThrough);
2623
2515
  const renouncedLookBack = num$1(f.renouncedLookBack);
2624
2516
  const subtotal = opening.value + currentYearExpenses + lookBackExpenses + reclassifiedFromCde + amalg.value + renewableConservationExpenses + otherAdd.value - governmentAssistance - otherDed.value - renouncedFlowThrough - toSuccessor.value - renouncedLookBack;
2625
- const claim = forcedOrCappedClaim(input.claimed, subtotal, issues, "Schedule 15 CEE regular (015061)");
2517
+ const claim = forcedOrCappedClaim$1(input.claimed, subtotal, issues, "Schedule 15 CEE regular (015061)");
2626
2518
  const closingBalance = subtotal > 0 ? subtotal - claim : 0;
2627
2519
  return {
2628
2520
  openingBalance: opening.value,
@@ -2655,7 +2547,7 @@ function computeCeeSuccessor(input) {
2655
2547
  const otherDed = reconcile(f.otherDeductions, o.otherDeductions);
2656
2548
  const toSuccessor = reconcile(f.transferredToSuccessor, o.transferredToSuccessor);
2657
2549
  const subtotal = opening.value + reclassified + amalg.value + other.value - otherDed.value - toSuccessor.value;
2658
- const claim = forcedOrCappedClaim(input.claimed, subtotal, issues, "Schedule 15 CEE successor (015081)");
2550
+ const claim = forcedOrCappedClaim$1(input.claimed, subtotal, issues, "Schedule 15 CEE successor (015081)");
2659
2551
  const closingBalance = subtotal - claim;
2660
2552
  return {
2661
2553
  openingBalance: opening.value,
@@ -2689,7 +2581,7 @@ function computeCdeRegular(input, ccogpeRegular) {
2689
2581
  const receivable = reconcile(f.receivableOnDisposition, o.receivableOnDisposition);
2690
2582
  const creditBalanceReconciled = reconcile(f.creditBalanceInCogpePool, o.creditBalanceInCogpePool);
2691
2583
  const creditBalance = ccogpeRegular.subtotal < 0 ? {
2692
- value: round(ccogpeRegular.subtotal),
2584
+ value: round$1(ccogpeRegular.subtotal),
2693
2585
  differs: true
2694
2586
  } : creditBalanceReconciled;
2695
2587
  const otherDed = reconcile(f.otherDeductions, o.otherDeductions);
@@ -2698,7 +2590,7 @@ function computeCdeRegular(input, ccogpeRegular) {
2698
2590
  const renouncedLookBack = num$1(f.renouncedLookBack);
2699
2591
  const subtotal = opening.value + currentYearExpenses + lookBackExpenses + amalg.value + otherAdd.value - reclassified - governmentAssistance - receivable.value - creditBalance.value - otherDed.value - toSuccessor.value - renouncedFlowThrough - renouncedLookBack;
2700
2592
  if (f.otherDeductions !== void 0 || o.otherDeductions !== void 0) issues.push("Schedule 15 CDE regular (015107): the spec's own business rule for this line adds \"If 015139 is negative, include the amount at 015107 as a positive value\" — line 015139 does not exist anywhere else in Schedule 15 as extracted from the source text (source lines 13681-13691). Not modelled; verify against the live TRA form, which has no PDF in this engine's sources for Schedule 15.");
2701
- const claim = subtotal > 0 ? claimUpToCap(input.claimed, CDE_CLAIM_RATE * stepYearFactor(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CDE regular (015115)") : 0;
2593
+ const claim = subtotal > 0 ? claimUpToCap$1(input.claimed, CDE_CLAIM_RATE * stepYearFactor$1(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CDE regular (015115)") : 0;
2702
2594
  const closingBalance = Math.max(0, subtotal - claim);
2703
2595
  return {
2704
2596
  openingBalance: opening.value,
@@ -2731,14 +2623,14 @@ function computeCdeSuccessor(input, ccogpeSuccessor) {
2731
2623
  const reclassified = num$1(f.reclassifiedFromCee);
2732
2624
  const creditBalanceReconciled = reconcile(f.creditBalanceInCogpePool, o.creditBalanceInCogpePool);
2733
2625
  const creditBalance = ccogpeSuccessor.subtotal < 0 ? {
2734
- value: round(ccogpeSuccessor.subtotal),
2626
+ value: round$1(ccogpeSuccessor.subtotal),
2735
2627
  differs: true
2736
2628
  } : creditBalanceReconciled;
2737
2629
  if (creditBalance.value !== 0) issues.push("Schedule 15 CDE successor (015133): the \"value may not exceed amount A\" wording (source lines 13945-13962) is ambiguous — this module treats it as \"value = A\" (matching line 015105's unconditional wording) whenever the CCOGPE-successor subtotal is negative. Verify against the live TRA form.");
2738
2630
  const otherDed = reconcile(f.otherDeductions, o.otherDeductions);
2739
2631
  const toSuccessor = reconcile(f.transferredToSuccessor, o.transferredToSuccessor);
2740
2632
  const subtotal = opening.value + amalg.value + other.value - reclassified - creditBalance.value - otherDed.value - toSuccessor.value;
2741
- const claim = subtotal > 0 ? claimUpToCap(input.claimed, CDE_CLAIM_RATE * stepYearFactor(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CDE successor (015141)") : 0;
2633
+ const claim = subtotal > 0 ? claimUpToCap$1(input.claimed, CDE_CLAIM_RATE * stepYearFactor$1(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CDE successor (015141)") : 0;
2742
2634
  const closingBalance = Math.max(0, subtotal - claim);
2743
2635
  return {
2744
2636
  openingBalance: opening.value,
@@ -2770,7 +2662,7 @@ function computeCcogpeRegular(input) {
2770
2662
  const subtotal = opening.value + currentYearExpenses + amalg.value + otherAdd.value - receivable.value - governmentAssistance - toSuccessor.value - otherDed.value;
2771
2663
  let claim = 0;
2772
2664
  if (subtotal < 0) issues.push("Schedule 15 CCOGPE regular (015169): the pool subtotal is negative. Per source lines 14346-14359, this must be carried forward to line 015105 (CDE regular) if the corporation has made a designation under subparagraph 66.7(4)(a)(iii), or to line 015133 (CDE successor) if it has not. computeCdeRegular auto-applies the 015105 route unconditionally (see that function's doc comment) — confirm the designation status before relying on that routing when it should instead land on 015133.");
2773
- else if (subtotal > 0) claim = claimUpToCap(input.claimed, CCOGPE_CLAIM_RATE * stepYearFactor(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CCOGPE regular (015169)");
2665
+ else if (subtotal > 0) claim = claimUpToCap$1(input.claimed, CCOGPE_CLAIM_RATE * stepYearFactor$1(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CCOGPE regular (015169)");
2774
2666
  const closingBalance = subtotal > 0 ? subtotal - claim : 0;
2775
2667
  return {
2776
2668
  openingBalance: opening.value,
@@ -2801,7 +2693,7 @@ function computeCcogpeSuccessor(input) {
2801
2693
  const subtotal = opening.value + amalg.value + other.value - receivable.value - toSuccessor.value - otherDed.value;
2802
2694
  let claim = 0;
2803
2695
  if (subtotal < 0) issues.push("Schedule 15 CCOGPE successor (015189): the pool subtotal is negative. Per source lines 14646-14660, this must be carried forward to line 015133 (CDE successor) if the corporation has made a designation under subparagraph 66.7(4)(a)(iii), or included in line 015167 (this SAME pool's own regular-side deduction line) if it has not. Neither route is auto-applied by this function; supply the appropriate override manually. See module doc comment.");
2804
- else if (subtotal > 0) claim = claimUpToCap(input.claimed, CCOGPE_CLAIM_RATE * stepYearFactor(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CCOGPE successor (015189)");
2696
+ else if (subtotal > 0) claim = claimUpToCap$1(input.claimed, CCOGPE_CLAIM_RATE * stepYearFactor$1(input.daysInTaxYear) * subtotal, issues, "Schedule 15 CCOGPE successor (015189)");
2805
2697
  const closingBalance = Math.max(0, subtotal - claim);
2806
2698
  return {
2807
2699
  openingBalance: opening.value,
@@ -2830,7 +2722,7 @@ function computeFedeRegular(input) {
2830
2722
  if (pool < 0) issues.push("Schedule 15 FEDE regular (015209): the pool balance is negative. Per source lines 14855-14858 this is included in federal T2 line 012040 — outside AT1 Schedule 15 and this engine's scope. Claim and closing balance are zeroed per the schedule's own instruction.");
2831
2723
  else if (pool > 0) {
2832
2724
  const cap = Math.max(CCOGPE_CLAIM_RATE * linearYearFactor(input.daysInTaxYear) * pool, foreignResourceIncome);
2833
- claim = claimUpToCap(input.claimed, Math.min(pool, cap), issues, "Schedule 15 FEDE regular (015209)");
2725
+ claim = claimUpToCap$1(input.claimed, Math.min(pool, cap), issues, "Schedule 15 FEDE regular (015209)");
2834
2726
  }
2835
2727
  const closingBalance = pool - claim;
2836
2728
  return {
@@ -2857,7 +2749,7 @@ function computeFedeSuccessor(input) {
2857
2749
  const pool = opening.value + amalg.value + other.value - otherDed.value;
2858
2750
  let claim = 0;
2859
2751
  if (pool < 0) issues.push("Schedule 15 FEDE successor (015221): the pool balance is negative. Per source lines 14855-14858-style wording (successor variant, source lines ~15045-15048) this is included in federal T2 line 012040 — outside AT1 Schedule 15 and this engine's scope.");
2860
- else if (pool > 0) claim = claimUpToCap(input.claimed, Math.min(pool, foreignResourceIncome), issues, "Schedule 15 FEDE successor (015221)");
2752
+ else if (pool > 0) claim = claimUpToCap$1(input.claimed, Math.min(pool, foreignResourceIncome), issues, "Schedule 15 FEDE successor (015221)");
2861
2753
  const closingBalance = pool - claim;
2862
2754
  return {
2863
2755
  openingBalance: opening.value,
@@ -2886,7 +2778,7 @@ function computeSfedeCountryRegular(input) {
2886
2778
  if (pool < 0) issues.push(`Schedule 15 SFEDE regular, country ${f.countryCode} (015253): the pool balance is negative. Per the schedule's pattern for foreign pools (source lines 15262-15265), this is included in federal T2 line 012040 — outside this engine's scope.`);
2887
2779
  else if (pool > 0) {
2888
2780
  const cap = Math.max(CCOGPE_CLAIM_RATE * linearYearFactor(input.daysInTaxYear) * pool, foreignResourceIncome);
2889
- claim = claimUpToCap(input.claimed, Math.min(pool, cap), issues, `Schedule 15 SFEDE regular, country ${f.countryCode} (015253)`);
2781
+ claim = claimUpToCap$1(input.claimed, Math.min(pool, cap), issues, `Schedule 15 SFEDE regular, country ${f.countryCode} (015253)`);
2890
2782
  }
2891
2783
  const closingBalance = pool - claim;
2892
2784
  return {
@@ -2915,7 +2807,7 @@ function computeSfedeCountrySuccessor(input) {
2915
2807
  const pool = opening.value + amalg.value + other.value - otherDed.value;
2916
2808
  let claim = 0;
2917
2809
  if (pool < 0) issues.push(`Schedule 15 SFEDE successor, country ${f.countryCode} (015273): the pool balance is negative. Per the schedule's pattern for foreign pools this is included in federal T2 line 012040 — outside this engine's scope.`);
2918
- else if (pool > 0) claim = claimUpToCap(input.claimed, Math.min(pool, foreignResourceIncome), issues, `Schedule 15 SFEDE successor, country ${f.countryCode} (015273)`);
2810
+ else if (pool > 0) claim = claimUpToCap$1(input.claimed, Math.min(pool, foreignResourceIncome), issues, `Schedule 15 SFEDE successor, country ${f.countryCode} (015273)`);
2919
2811
  const closingBalance = pool - claim;
2920
2812
  return {
2921
2813
  countryCode: f.countryCode,
@@ -2970,8 +2862,8 @@ function computeCfreRegular(entries) {
2970
2862
  const partA = Math.max(CCOGPE_CLAIM_RATE * linear * pool, Math.min(CDE_CLAIM_RATE * linear * pool, foreignResourceIncome, sumForeignResourceIncome));
2971
2863
  const remainder = Math.max(0, pool - partA);
2972
2864
  if (e.globalForeignResourceLimit === void 0) issues.push(`Schedule 15 CFRE regular, country ${e.federal.countryCode} (015293): the "global foreign resource limit for the year designated for that country" (source lines 15703-15711) was not supplied — this quantity has no source anywhere in this engine, so the B-component of the claim is treated as 0 (conservative — the pool may be under-claimed relative to what the corporation is actually entitled to).`);
2973
- const partB = Math.min(remainder, nn$25(e.globalForeignResourceLimit));
2974
- claim = claimUpToCap(e.claimed, partA + partB, issues, `Schedule 15 CFRE regular, country ${e.federal.countryCode} (015293)`);
2865
+ const partB = Math.min(remainder, nn$26(e.globalForeignResourceLimit));
2866
+ claim = claimUpToCap$1(e.claimed, partA + partB, issues, `Schedule 15 CFRE regular, country ${e.federal.countryCode} (015293)`);
2975
2867
  }
2976
2868
  const closingBalance = pool - claim;
2977
2869
  return {
@@ -3116,7 +3008,7 @@ function computeCfreSuccessor(entries) {
3116
3008
  if (pool < 0) issues.push(`Schedule 15 CFRE successor, country ${e.federal.countryCode} (015313): the pool balance is negative. Per the schedule's pattern for foreign pools this is included in federal T2 line 012040 — outside this engine's scope.`);
3117
3009
  else if (pool > 0) {
3118
3010
  const cap = Math.min(CDE_CLAIM_RATE * linearYearFactor(e.daysInTaxYear) * pool, sumForeignResourceIncome);
3119
- claim = claimUpToCap(e.claimed, cap, issues, `Schedule 15 CFRE successor, country ${e.federal.countryCode} (015313)`);
3011
+ claim = claimUpToCap$1(e.claimed, cap, issues, `Schedule 15 CFRE successor, country ${e.federal.countryCode} (015313)`);
3120
3012
  }
3121
3013
  const closingBalance = pool - claim;
3122
3014
  return {
@@ -3402,15 +3294,15 @@ function schedule15Values(result) {
3402
3294
  function iegT661SourceLine(taxationYearEnd) {
3403
3295
  return taxationYearEnd >= "2024-12-16" ? "557" : "559";
3404
3296
  }
3405
- const nn$24 = (v) => Math.round(v ?? 0);
3297
+ const nn$25 = (v) => Math.round(v ?? 0);
3406
3298
  /** Line 031 = 005 − 007 + 009 + 011 + 025. Every term but 005 defaults to nil. */
3407
3299
  function computeIegEligibleExpenditures(input) {
3408
- const federalAmount = nn$24(input.federalAmount);
3409
- const albertaPortion = nn$24(input.albertaPortion);
3410
- const federalProxyAmount = nn$24(input.federalProxyAmount);
3411
- const albertaProxyAmount = nn$24(input.albertaProxyAmount);
3412
- const iegReducingFederalExpenditure = nn$24(input.iegReducingFederalExpenditure);
3413
- const repaymentOrContractPayment = nn$24(input.repaymentOrContractPayment);
3300
+ const federalAmount = nn$25(input.federalAmount);
3301
+ const albertaPortion = nn$25(input.albertaPortion);
3302
+ const federalProxyAmount = nn$25(input.federalProxyAmount);
3303
+ const albertaProxyAmount = nn$25(input.albertaProxyAmount);
3304
+ const iegReducingFederalExpenditure = nn$25(input.iegReducingFederalExpenditure);
3305
+ const repaymentOrContractPayment = nn$25(input.repaymentOrContractPayment);
3414
3306
  return {
3415
3307
  federalAmount,
3416
3308
  albertaPortion,
@@ -3630,7 +3522,7 @@ function computeIeg(input) {
3630
3522
  *
3631
3523
  * Whole dollars, pure.
3632
3524
  */
3633
- const nn$23 = (v) => Math.max(0, Math.round(v ?? 0));
3525
+ const nn$24 = (v) => Math.max(0, Math.round(v ?? 0));
3634
3526
  /**
3635
3527
  * The group's taxable capital and base level of spending, from every associated
3636
3528
  * member's own figures.
@@ -3641,11 +3533,11 @@ const nn$23 = (v) => Math.max(0, Math.round(v ?? 0));
3641
3533
  function computeIegGroupFigures(members, priorYears = IEG_2024.PRIOR_YEARS) {
3642
3534
  const issues = [];
3643
3535
  const detail = members.map((m) => {
3644
- const priorYearAlbertaExpenditures = (m.priorYearAlbertaExpenditures ?? []).map(nn$23);
3536
+ const priorYearAlbertaExpenditures = (m.priorYearAlbertaExpenditures ?? []).map(nn$24);
3645
3537
  if (priorYearAlbertaExpenditures.length > priorYears) issues.push(`Alberta Schedule 29: ${m.name} supplied ${priorYearAlbertaExpenditures.length} prior-year expenditure figures, but the base level of spending averages the prior ${priorYears} years. Every figure supplied was included, which raises the base — check that only the prior ${priorYears} taxation years were given.`);
3646
3538
  return {
3647
3539
  name: m.name,
3648
- taxableCapital: nn$23(m.taxableCapital),
3540
+ taxableCapital: nn$24(m.taxableCapital),
3649
3541
  priorYearAlbertaExpenditures,
3650
3542
  priorYearTotal: priorYearAlbertaExpenditures.reduce((a, b) => a + b, 0)
3651
3543
  };
@@ -3672,11 +3564,11 @@ function computeIegGroupFigures(members, priorYears = IEG_2024.PRIOR_YEARS) {
3672
3564
  function allocateIegExpenditureLimit(groupExpenditureLimit, requested) {
3673
3565
  const issues = [];
3674
3566
  const limit = Math.max(0, Math.round(groupExpenditureLimit));
3675
- const totalRequested = requested.reduce((s, a) => s + nn$23(a.allocated), 0);
3567
+ const totalRequested = requested.reduce((s, a) => s + nn$24(a.allocated), 0);
3676
3568
  if (totalRequested > limit) issues.push(`Alberta Schedule 29: the associated group allocated ${totalRequested} of an expenditure limit of ${limit}. The allocation cannot exceed the limit; members were capped in the order given and the group must agree a valid split.`);
3677
3569
  let remaining = limit;
3678
3570
  const allocations = requested.map((a) => {
3679
- const allocated = Math.min(nn$23(a.allocated), remaining);
3571
+ const allocated = Math.min(nn$24(a.allocated), remaining);
3680
3572
  remaining -= allocated;
3681
3573
  return {
3682
3574
  name: a.name,
@@ -3710,10 +3602,10 @@ function allocateIegEvenly(groupExpenditureLimit, names) {
3710
3602
  })));
3711
3603
  }
3712
3604
  function computeAgreementMember(m, index, issues) {
3713
- const allocatedExpenditureLimit = nn$23(m.allocatedExpenditureLimit);
3714
- const currentYearExpenditures = nn$23(m.currentYearExpenditures);
3715
- const priorYear1 = nn$23(m.priorYear1);
3716
- const priorYear2 = nn$23(m.priorYear2);
3605
+ const allocatedExpenditureLimit = nn$24(m.allocatedExpenditureLimit);
3606
+ const currentYearExpenditures = nn$24(m.currentYearExpenditures);
3607
+ const priorYear1 = nn$24(m.priorYear1);
3608
+ const priorYear2 = nn$24(m.priorYear2);
3717
3609
  const base = Math.round((priorYear1 + priorYear2) / 2);
3718
3610
  const individualMaximumAllowedAmount = currentYearExpenditures - base;
3719
3611
  const days = Math.max(0, Math.min(m.daysInTaxYear ?? 365, 366));
@@ -3732,7 +3624,7 @@ function computeAgreementMember(m, index, issues) {
3732
3624
  currentYearExpenditures,
3733
3625
  priorYear1,
3734
3626
  priorYear2,
3735
- taxableCapitalPriorYear: nn$23(m.taxableCapitalPriorYear),
3627
+ taxableCapitalPriorYear: nn$24(m.taxableCapitalPriorYear),
3736
3628
  hasAlbertaPermanentEstablishment,
3737
3629
  individualMaximumAllowedAmount,
3738
3630
  allocatedAllowedAmount
@@ -3893,10 +3785,6 @@ function computeAlbertaReturn(input) {
3893
3785
  issues.push(...sched.sredTaxCredit.result.issues);
3894
3786
  }
3895
3787
  if (sched?.lossCarryback) schedulePayloads.push(schedule10Values(sched.lossCarryback));
3896
- if (sched?.manufacturingProcessing) {
3897
- schedulePayloads.push(schedule11Values(sched.manufacturingProcessing));
3898
- issues.push(...sched.manufacturingProcessing.issues);
3899
- }
3900
3788
  if (sched?.reconciliation) schedulePayloads.push(schedule12Values(sched.reconciliation));
3901
3789
  if (sched?.cca) {
3902
3790
  schedulePayloads.push(schedule13Values(sched.cca));
@@ -3930,7 +3818,6 @@ function computeAlbertaReturn(input) {
3930
3818
  issues.push(...sched.losses.otherLossesByYearOfOrigin?.issues ?? []);
3931
3819
  }
3932
3820
  if (ieg) schedulePayloads.push(schedule29Values(ieg, iegAgreement, iegEligibleExpenditures, input.ieg?.primaryFieldCode));
3933
- if (at4970) schedulePayloads.push(schedule4970Values(at4970));
3934
3821
  return {
3935
3822
  allocationFactor,
3936
3823
  albertaTax,
@@ -4057,8 +3944,7 @@ var At1MandatoryFieldMissingError = class extends Error {
4057
3944
  * for Net File by the specification itself.
4058
3945
  */
4059
3946
  const AT1_MANDATORY_WITHOUT_DEFAULT = Object.freeze([
4060
- ["activeBusinessIncome", "000003 income from active business"],
4061
- ["federalTaxableIncome", "000009 taxable income"],
3947
+ ["associatedWithCcpcs", "000001 associated with CCPCs"],
4062
3948
  ["contactPerson", "000025 contact person"],
4063
3949
  ["contactTelephone", "000026 contact telephone"],
4064
3950
  ["natureOfBusiness", "000028 nature of business"],
@@ -4068,7 +3954,6 @@ const AT1_MANDATORY_WITHOUT_DEFAULT = Object.freeze([
4068
3954
  ["certificationDate", "000101 certification date"],
4069
3955
  ["certificationTelephone", "000103 certification telephone"],
4070
3956
  ["authorizedEmail", "000105 CIT authorized email"],
4071
- ["associatedWithCcpcs", "000001 associated with CCPCs"],
4072
3957
  ["windUpOfSubsidiary", "000031 wind-up of a subsidiary"],
4073
3958
  ["firstYearAfterAmalgamation", "000032 first year after amalgamation"],
4074
3959
  ["taxYearEndChanged", "000038 tax year end changed"],
@@ -4145,21 +4030,11 @@ const AT1_RETURN_LINE_ITEMS = [
4145
4030
  get: (d) => at1YesNo(d.associatedWithCcpcs),
4146
4031
  fmt: "text"
4147
4032
  },
4148
- {
4149
- id: "000003001",
4150
- get: (d) => d.activeBusinessIncome,
4151
- fmt: "amount"
4152
- },
4153
4033
  {
4154
4034
  id: "000005001",
4155
4035
  get: (d) => d.softwareCertCode,
4156
4036
  fmt: "text"
4157
4037
  },
4158
- {
4159
- id: "000009001",
4160
- get: (d) => d.federalTaxableIncome,
4161
- fmt: "amount"
4162
- },
4163
4038
  {
4164
4039
  id: "000010001",
4165
4040
  get: (d) => d.legalName,
@@ -4651,7 +4526,7 @@ var RsiLineItemError = class extends Error {
4651
4526
  }
4652
4527
  };
4653
4528
  /**
4654
- * Render one line item: `##` + nine digits + five spaces + value.
4529
+ * Render one line item: `##` + nine characters + five spaces + value.
4655
4530
  *
4656
4531
  * §3.2.1.5 — *"For a Line Item to be considered complete and therefore allowed to
4657
4532
  * be output to the AT1 RSI, it must contain both a Line Item ID and a Value"*. An
@@ -4659,7 +4534,7 @@ var RsiLineItemError = class extends Error {
4659
4534
  * not a line item the reader can interpret.
4660
4535
  */
4661
4536
  function renderRsiLineItem(item) {
4662
- if (!/^\d{9}$/.test(item.lineItemId)) throw new RsiLineItemError(`AT1 RSI: line item id "${item.lineItemId}" must be exactly nine digits (Schedule ID + Field ID + Occurrence ID).`);
4537
+ if (!/^\w{3}[0-9]{6}$/.test(item.lineItemId)) throw new RsiLineItemError(`AT1 RSI: line item id "${item.lineItemId}" must be a 3-character Schedule ID followed by six digits (Field ID + Occurrence ID).`);
4663
4538
  if (item.value === "") throw new RsiLineItemError(`AT1 RSI: line item ${item.lineItemId} has no value. A line item must carry both an id and a value to be printed.`);
4664
4539
  return `##${item.lineItemId}${RSI_COLUMN_GAP}${item.value}`;
4665
4540
  }
@@ -4697,6 +4572,82 @@ function renderAt1Rsi(header, schedules, options = {}) {
4697
4572
  return lines.join("\n");
4698
4573
  }
4699
4574
  //#endregion
4575
+ //#region src/t2/at1/filing/at1-rsi-adapter.ts
4576
+ /**
4577
+ * Bridge between the Net File shapes (`At1FilingData` / `At1ScheduleData`,
4578
+ * `at1-line-items.ts` / `at1-schedule-line-items.ts`) and the RSI print
4579
+ * renderer's own shapes (`RsiHeaderInput` / `RsiScheduleInput`,
4580
+ * `at1-rsi-renderer.ts`).
4581
+ *
4582
+ * The two formats share the same underlying data — the same computed return,
4583
+ * the same M/O/X-driven set of fields to emit — so this module does no new
4584
+ * arithmetic; it only reformats already-assembled values through
4585
+ * `at1-rsi-renderer.ts`'s own formatters (`formatRsiAmount`/`formatRsiText`/
4586
+ * `formatRsiDate`) instead of Net File's XML ones. Building the actual RSI
4587
+ * TEXT for a computed return is then `renderAt1Rsi(toRsiHeader(data),
4588
+ * [toRsiSchedule('000', AT1_RETURN_LINE_ITEMS, data), ...schedulePayloads.map(s
4589
+ * => toRsiScheduleData(s)), toRsiSchedule('EDI', AT1_EDI_LINE_ITEMS,
4590
+ * data.transmitter)])`.
4591
+ */
4592
+ /**
4593
+ * §3.2.1.16 — "Value of Line Item IDs where percentages apply are to use the
4594
+ * number of significant digits specified in the Cross-reference Tables."
4595
+ * Not a dollar value, so the "no decimals" rule (§3.2.1.17) does not apply —
4596
+ * reuses Net File's own six-decimal, leading-zero-stripped convention
4597
+ * (`fmtFactor` in `at1-line-items.ts`) since the spec gives no different one.
4598
+ */
4599
+ function formatRsiFactorValue(n) {
4600
+ const s = n.toFixed(6);
4601
+ return n >= 0 && n < 1 ? s.replace(/^0/, "") : s;
4602
+ }
4603
+ function formatByFmt(v, fmt) {
4604
+ if (v === void 0 || v === null) return void 0;
4605
+ if (fmt === "date") return formatRsiDate(v);
4606
+ if (fmt === "amount") return formatRsiAmount(v);
4607
+ if (fmt === "factor") return formatRsiFactorValue(v);
4608
+ return formatRsiText(String(v));
4609
+ }
4610
+ /** Convert one declarative line-item table (jacket or EDI) into RSI line items. */
4611
+ function toRsiLineItems(data, items) {
4612
+ const result = [];
4613
+ for (const li of items) {
4614
+ const value = formatByFmt(li.get(data), li.fmt);
4615
+ if (value !== void 0) result.push({
4616
+ lineItemId: li.id,
4617
+ value
4618
+ });
4619
+ }
4620
+ return result;
4621
+ }
4622
+ /** Convert an already-assembled supporting-schedule payload (Net File shape) to RSI shape. */
4623
+ function toRsiSchedule(schedule) {
4624
+ return {
4625
+ scheduleId: schedule.scheduleId,
4626
+ items: schedule.values.map((v) => ({
4627
+ lineItemId: v.lineItemId,
4628
+ value: typeof v.value === "number" ? formatRsiAmount(v.value) : formatRsiText(String(v.value))
4629
+ }))
4630
+ };
4631
+ }
4632
+ /** The AT1 jacket (schedule `000`) and the EDI transmitter block (schedule `EDI`), RSI-formatted. */
4633
+ function toRsiJacketSchedules(data) {
4634
+ return [{
4635
+ scheduleId: "000",
4636
+ items: toRsiLineItems(data, AT1_RETURN_LINE_ITEMS)
4637
+ }, {
4638
+ scheduleId: "EDI",
4639
+ items: toRsiLineItems(data.transmitter, AT1_EDI_LINE_ITEMS)
4640
+ }];
4641
+ }
4642
+ /** The RSI header identity fields (everything but pagination) from the same filing data Net File uses. */
4643
+ function toRsiHeader(data) {
4644
+ return {
4645
+ corporateAccountNumber: data.corporateAccountNumber,
4646
+ taxYearEnd: data.taxYearEnd,
4647
+ legalName: data.legalName
4648
+ };
4649
+ }
4650
+ //#endregion
4700
4651
  //#region src/t2/schedules/loss-carryback.ts
4701
4652
  var LossCarrybackError = class extends Error {
4702
4653
  constructor(message) {
@@ -4963,6 +4914,42 @@ function albertaReserveDifference(albertaNetEffect, federalNetEffect) {
4963
4914
  }
4964
4915
  };
4965
4916
  }
4917
+ /**
4918
+ * A resource-deduction pool (AT1 Schedule 15 vs federal Schedule 12) as a
4919
+ * Schedule 12 adjustment — same direction convention as CCA/reserves above:
4920
+ * a LARGER Alberta claim is a DEDUCTION (Alberta income lower), a smaller
4921
+ * one is an ADDITION. Shared across the five reconciling pairs Schedule 12
4922
+ * lines 022/023 (Depletion), 026/027 (CEE), 028/029 (CDE), 030/031
4923
+ * (Foreign exploration/development), 032/033 (COGPE) all follow — the
4924
+ * labels/refs differ per pool, everything else is identical, so this one
4925
+ * function replaces five near-duplicate hand-written diffs.
4926
+ */
4927
+ function albertaResourceDeductionDifference(label, ref, albertaClaim, federalClaim) {
4928
+ const diff = albertaClaim - federalClaim;
4929
+ if (diff > 0) return {
4930
+ side: "deduction",
4931
+ line: {
4932
+ label: `${label} — additional claim for Alberta`,
4933
+ amount: diff,
4934
+ ref
4935
+ }
4936
+ };
4937
+ if (diff < 0) return {
4938
+ side: "addition",
4939
+ line: {
4940
+ label: `${label} — claimed federally but not for Alberta`,
4941
+ amount: -diff,
4942
+ ref
4943
+ }
4944
+ };
4945
+ return {
4946
+ side: "none",
4947
+ line: {
4948
+ label: `No ${label.toLowerCase()} difference`,
4949
+ amount: 0
4950
+ }
4951
+ };
4952
+ }
4966
4953
  /** Reconcile from a list of directional adjustments (zero/'none' ones are dropped). */
4967
4954
  function reconcileAlbertaNetIncome(federalNetIncomeForTax, adjustments) {
4968
4955
  return computeSchedule12({
@@ -5256,6 +5243,42 @@ function computeClass141AdditionalAllowance(input) {
5256
5243
  issues
5257
5244
  };
5258
5245
  }
5246
+ /**
5247
+ * s.13(39): on a disposition of class 14.1 property that was eligible capital
5248
+ * property (ECP) before 1 January 2017, the taxpayer is deemed to have
5249
+ * acquired additional class 14.1 property with a capital cost equal to the
5250
+ * LEAST of three amounts: 1/4 of the proceeds of disposition, 1/4 of the
5251
+ * capital cost of the property disposed of, and (per the explanatory notes to
5252
+ * the enacting bill) a third amount tied to the property's own pre-2017
5253
+ * CEC-sourced history. Old CEC only pulled 75% of an expenditure into the
5254
+ * pool (and correspondingly only 75% of a disposition receipt reduced it,
5255
+ * with the other 25% capital-gain-like) — without this addback, the switch to
5256
+ * class 14.1's 100% inclusion would create MORE recapture on legacy goodwill
5257
+ * than the old regime ever intended.
5258
+ *
5259
+ * The FIRST TWO limbs are corroborated by two independent primary/near-primary
5260
+ * sources (Finance Canada's own explanatory notes to the enacting bill, cross-
5261
+ * checked against a summary of the statute). The THIRD limb's exact wording
5262
+ * could not be confirmed against the Act's own text (the retrieval tooling
5263
+ * available here truncates before s.13(39) — see this repo's
5264
+ * `research/findings/federal/CCA-straight-line-classes.md`), so — same
5265
+ * fail-closed convention as `computeClass141AdditionalAllowance` just above —
5266
+ * this function bounds the addback by a caller-supplied REMAINING transitional
5267
+ * balance instead of guessing at the statute's own third limb. A missing
5268
+ * balance behaves as zero, never as unlimited.
5269
+ *
5270
+ * The RESULT is a deemed capital-cost addition — the caller adds it to the
5271
+ * class 14.1 row's `netAdjustments` (or applies it directly against a
5272
+ * recapture already computed by `computeCcaClass`) for the SAME year as the
5273
+ * disposition; it is not itself a CCA claim.
5274
+ */
5275
+ const CLASS_14_1_RECAPTURE_REDUCTION_RATE = .25;
5276
+ function computeClass141RecaptureReduction(input) {
5277
+ if (!input.transitionalBalanceRemaining) return 0;
5278
+ const proceeds = Math.max(0, input.proceeds);
5279
+ const capitalCost = Math.max(0, input.capitalCost);
5280
+ return Math.round(Math.min(CLASS_14_1_RECAPTURE_REDUCTION_RATE * proceeds, CLASS_14_1_RECAPTURE_REDUCTION_RATE * capitalCost, Math.max(0, input.transitionalBalanceRemaining)));
5281
+ }
5259
5282
  //#endregion
5260
5283
  //#region src/t2/schedules/schedule8.ts
5261
5284
  /**
@@ -5651,155 +5674,34 @@ function computeAlbertaSchedule13(input) {
5651
5674
  };
5652
5675
  }
5653
5676
  //#endregion
5654
- //#region src/t2/at1/schedules/schedule14-cec.ts
5655
- /**
5656
- * Alberta AT1 Schedule 14 — Cumulative Eligible Capital Deduction.
5657
- *
5658
- * **Read this before using it.** Eligible capital property was REPEALED on
5659
- * 1 January 2017 and replaced by CCA class 14.1. The TRA keeps Schedule 14 only
5660
- * for tax years that **end on or after 1 January 2017 and include 31 December
5661
- * 2016** — the straddling year — for which the Schedule 14 Supplemental Worksheet
5662
- * must also be filed, separately from the Net File payload. For any wholly
5663
- * post-2016 tax year, class 14.1 on Schedule 8 / AT1 Schedule 13 replaces this
5664
- * schedule entirely and it must not be filed.
5665
- *
5666
- * It is implemented because prior-year returns and amendments are in scope, not
5667
- * because a current-year filing needs it. `appliesToTaxYear` states the rule.
5668
- *
5669
- * Same reconciliation shape as the other Alberta schedules: every figure defaults
5670
- * to the corresponding federal one (T2 Schedule 10, lines 010nnn), and the form is
5671
- * forbidden when the return declares no Alberta/federal divergence and required
5672
- * when the opening balance or the claim (014024 / 014040) differs from federal.
5673
- *
5674
- * Line map (TRA spec §3.2.3.15) and the specified arithmetic:
5675
- *
5676
- * 014002 CEC balance at the end of the preceding year ← fed 010220
5677
- * 014004 cost of eligible capital property acquired ← fed 010222
5678
- * 014006 transferred on amalgamation or wind-up ← fed 010224
5679
- * 014008 other adjustments (additions side) ← fed 010226
5680
- * 014011 non-taxable portion of a non-arm's-length
5681
- * transferor's gain, post-2002-12-20 ← fed 010228 × ½
5682
- * 014014 proceeds of sale, net of outlays ← fed 010242
5683
- * 014016 gross s.80(7) forgiven-debt reduction ← fed 010244
5684
- * 014018 other adjustments (deductions side) ← fed 010246
5685
- * 014023 CEC for property no longer owned after ceasing
5686
- * to carry on that business ← fed 010249
5687
- * 014024 current year deduction
5688
- * 014026 CEC closing balance
5689
- *
5690
- * A = ((014004 + 014008) × ¾) − 014011 floored at 0
5691
- * B = 014002 + A + 014006
5692
- * C = (014014 + 014016 + 014018) × ¾
5693
- * D = B − C floored at 0
5694
- *
5695
- * 014024 ≤ (D − 014023) × 7%, never negative
5696
- * 014026 = D − 014023 − 014024 when D is positive, otherwise nil
5697
- *
5698
- * The ¾ inclusion and the 7% declining rate are the old CEC regime's, not the
5699
- * federal 75%-of-income donation limit and not a CCA rate — they only look
5700
- * similar.
5701
- *
5702
- * When D is NEGATIVE the schedule's "Amount to be Included in Income Arising from
5703
- * Disposition" section must be completed instead, and the deduction section must
5704
- * not be; when D is non-negative that section must be left blank. Both directions
5705
- * are reported so a filer cannot complete the wrong half.
5706
- *
5707
- * Whole dollars, pure.
5708
- */
5709
- /** The ¾ inclusion rate of the repealed cumulative eligible capital regime. */
5710
- const CEC_INCLUSION_RATE = .75;
5711
- /** The 7% declining-balance rate of the repealed regime. */
5712
- const CEC_DEDUCTION_RATE = .07;
5713
- const nn$22 = (v) => Math.max(0, v ?? 0);
5714
- /**
5715
- * Schedule 14 applies only to a tax year that ENDS on or after 2017-01-01 and
5716
- * INCLUDES 2016-12-31 — the year straddling the repeal of eligible capital
5717
- * property. A wholly pre-2017 year used the federal Schedule 10 regime as it then
5718
- * stood; a wholly post-2016 year uses class 14.1.
5719
- */
5720
- function cecScheduleAppliesToTaxYear(taxYearStart, taxYearEnd) {
5721
- if (!taxYearStart || !taxYearEnd) return false;
5722
- const start = Date.parse(`${taxYearStart.slice(0, 10)}T00:00:00Z`);
5723
- const end = Date.parse(`${taxYearEnd.slice(0, 10)}T00:00:00Z`);
5724
- const repeal = Date.parse("2017-01-01T00:00:00Z");
5725
- const lastEcpDay = Date.parse("2016-12-31T00:00:00Z");
5726
- if (Number.isNaN(start) || Number.isNaN(end)) return false;
5727
- return end >= repeal && start <= lastEcpDay && end >= lastEcpDay;
5728
- }
5729
- function computeAlbertaSchedule14(input) {
5730
- const issues = [];
5731
- const openingBalance = nn$22(input.openingBalance);
5732
- const acquisitions = nn$22(input.acquisitions);
5733
- const transferredIn = nn$22(input.transferredIn);
5734
- const otherAdditions = nn$22(input.otherAdditions);
5735
- const nonArmsLength = nn$22(input.nonArmsLengthNonTaxablePortion);
5736
- const proceedsOfSale = nn$22(input.proceedsOfSale);
5737
- const forgivenDebt = nn$22(input.forgivenDebtReduction);
5738
- const otherDeductions = nn$22(input.otherDeductions);
5739
- const noLongerOwned = nn$22(input.cecForPropertyNoLongerOwned);
5740
- const a = Math.max(0, Math.round(CEC_INCLUSION_RATE * (acquisitions + otherAdditions)) - nonArmsLength);
5741
- const b = openingBalance + a + transferredIn;
5742
- const c = Math.round(CEC_INCLUSION_RATE * (proceedsOfSale + forgivenDebt + otherDeductions));
5743
- const rawD = b - c;
5744
- const d = Math.max(0, rawD);
5745
- const incomeInclusionSectionApplies = rawD < 0;
5746
- const deductionBase = Math.max(0, d - noLongerOwned);
5747
- const maxDeduction = incomeInclusionSectionApplies ? 0 : Math.round(CEC_DEDUCTION_RATE * deductionBase);
5748
- const amountClaimed = input.amountClaimed != null ? Math.max(0, Math.min(input.amountClaimed, maxDeduction)) : maxDeduction;
5749
- const closingBalance = incomeInclusionSectionApplies ? 0 : Math.max(0, deductionBase - amountClaimed);
5750
- if (incomeInclusionSectionApplies && !input.incomeInclusion) issues.push("Alberta Schedule 14: the pool is negative, so the deduction section must be left blank and the \"Amount to be Included in Income Arising from Disposition\" section (014032-014048) completed. No figures for that section were supplied.");
5751
- if (!incomeInclusionSectionApplies && input.incomeInclusion) issues.push("Alberta Schedule 14: the pool is not negative, so the \"Amount to be Included in Income Arising from Disposition\" section must NOT be completed. The figures supplied for it were ignored.");
5752
- const appliesToTaxYear = cecScheduleAppliesToTaxYear(input.taxYearStart, input.taxYearEnd);
5753
- if (input.taxYearStart && input.taxYearEnd && !appliesToTaxYear) issues.push("Alberta Schedule 14: eligible capital property was repealed on 1 January 2017. This schedule applies only to a tax year ending on or after that date that also includes 31 December 2016. For a wholly post-2016 year, use CCA class 14.1 on Schedule 13 instead.");
5754
- const formRequired = Boolean(input.differsFromFederal);
5755
- const formPermitted = (input.reportsDifferentAlbertaIncome ?? false) || (input.electsDifferentDiscretionaryAmounts ?? false);
5756
- if (formRequired && !formPermitted) issues.push("Alberta Schedule 14: the opening balance or the claim differs from federal, so the form is required, but neither line 000060 nor 000061 is set to 1. Set line 000061 and file a Schedule 12.");
5757
- return {
5758
- a,
5759
- b,
5760
- c,
5761
- d,
5762
- rawD,
5763
- amountClaimed,
5764
- maxDeduction,
5765
- closingBalance,
5766
- incomeInclusionSectionApplies,
5767
- appliesToTaxYear,
5768
- supplementalWorksheetRequired: appliesToTaxYear,
5769
- formRequired,
5770
- formPermitted,
5771
- issues
5772
- };
5773
- }
5774
- //#endregion
5775
5677
  //#region src/t2/at1/schedules/schedule16-sred.ts
5776
- const nn$21 = (v) => Math.max(0, Math.round(v ?? 0));
5678
+ const nn$23 = (v) => Math.max(0, Math.round(v ?? 0));
5777
5679
  /**
5778
5680
  * Line 016004 for federal T661 versions from 2008 onward: lines 429 + 431 + 432.
5779
5681
  * The 2007-and-earlier form used a single line 430, which can be passed to
5780
5682
  * `assistance` directly.
5781
5683
  */
5782
5684
  function assistanceFrom(line429, line431, line432) {
5783
- return nn$21(line429) + nn$21(line431) + nn$21(line432);
5685
+ return nn$23(line429) + nn$23(line431) + nn$23(line432);
5784
5686
  }
5785
5687
  function computeAlbertaSchedule16(input) {
5786
5688
  const issues = [];
5787
- const currentYearExpenditures = nn$21(input.currentYearExpenditures);
5788
- const assistance = nn$21(input.assistance);
5789
- const priorYearItcClaimed = nn$21(input.priorYearItcClaimed);
5790
- const saleOfCapitalAssetsAndOther = nn$21(input.saleOfCapitalAssetsAndOther);
5791
- const assistanceRepayments = nn$21(input.assistanceRepayments);
5792
- const openingPoolBalance = nn$21(input.openingPoolBalance);
5793
- const poolTransferredIn = nn$21(input.poolTransferredIn);
5794
- const priorYearItcRecaptured = nn$21(input.priorYearItcRecaptured);
5689
+ const currentYearExpenditures = nn$23(input.currentYearExpenditures);
5690
+ const assistance = nn$23(input.assistance);
5691
+ const priorYearItcClaimed = nn$23(input.priorYearItcClaimed);
5692
+ const saleOfCapitalAssetsAndOther = nn$23(input.saleOfCapitalAssetsAndOther);
5693
+ const assistanceRepayments = nn$23(input.assistanceRepayments);
5694
+ const openingPoolBalance = nn$23(input.openingPoolBalance);
5695
+ const poolTransferredIn = nn$23(input.poolTransferredIn);
5696
+ const priorYearItcRecaptured = nn$23(input.priorYearItcRecaptured);
5795
5697
  const totalDeductions = assistance + priorYearItcClaimed + saleOfCapitalAssetsAndOther;
5796
5698
  const totalAdditions = assistanceRepayments + openingPoolBalance + poolTransferredIn + priorYearItcRecaptured;
5797
5699
  const subtotal = currentYearExpenditures - totalDeductions + totalAdditions;
5798
5700
  const deductionAvailable = Math.max(0, subtotal);
5799
5701
  if (subtotal < 0) issues.push(`Alberta Schedule 16: assistance, prior-year credits and asset sales exceed the SR&ED expenditures by ${-subtotal}. No pool deduction is available and the pool carries forward at nil.`);
5800
5702
  const amountClaimed = input.amountClaimed != null ? Math.max(0, Math.min(Math.round(input.amountClaimed), deductionAvailable)) : deductionAvailable;
5801
- const openingDiffers = input.federalOpeningPoolBalance !== void 0 && nn$21(input.federalOpeningPoolBalance) !== openingPoolBalance;
5802
- const claimDiffers = input.federalAmountClaimed !== void 0 && nn$21(input.federalAmountClaimed) !== amountClaimed;
5703
+ const openingDiffers = input.federalOpeningPoolBalance !== void 0 && nn$23(input.federalOpeningPoolBalance) !== openingPoolBalance;
5704
+ const claimDiffers = input.federalAmountClaimed !== void 0 && nn$23(input.federalAmountClaimed) !== amountClaimed;
5803
5705
  const formRequired = openingDiffers || claimDiffers;
5804
5706
  const formPermitted = (input.reportsDifferentAlbertaIncome ?? false) || (input.electsDifferentDiscretionaryAmounts ?? false);
5805
5707
  if (formRequired && !formPermitted) issues.push("Alberta Schedule 16: the SR&ED opening pool balance or the deduction claimed differs from federal, so the form is required, but neither line 000060 nor 000061 is set to 1. Set line 000061 and file a Schedule 12.");
@@ -5927,10 +5829,10 @@ const AT1_RESERVE_LINES = Object.freeze({
5927
5829
  closing: "017077"
5928
5830
  }
5929
5831
  });
5930
- const nn$20 = (v) => Math.max(0, Math.round(v ?? 0));
5832
+ const nn$22 = (v) => Math.max(0, Math.round(v ?? 0));
5931
5833
  /** `undefined` falls back to federal; a `0` is a real Alberta override. */
5932
5834
  function pick(alberta, federal) {
5933
- return nn$20(alberta !== void 0 ? alberta : federal);
5835
+ return nn$22(alberta !== void 0 ? alberta : federal);
5934
5836
  }
5935
5837
  function computeAlbertaSchedule17(input) {
5936
5838
  const issues = [];
@@ -6033,7 +5935,7 @@ const AT1_DISPOSITION_CATEGORIES = [
6033
5935
  * Line 018076 then applies the inclusion rate once, to the total.
6034
5936
  */
6035
5937
  const SECTION_34_2_GROSS_UP = 2;
6036
- const nn$19 = (v) => Math.max(0, v ?? 0);
5938
+ const nn$21 = (v) => Math.max(0, v ?? 0);
6037
5939
  const num = (v) => v ?? 0;
6038
5940
  /** Merge one category: an omitted Alberta field takes federal; a `0` overrides. */
6039
5941
  function mergeCategory(federal, alberta) {
@@ -6044,9 +5946,9 @@ function mergeCategory(federal, alberta) {
6044
5946
  const o = f.outlays;
6045
5947
  return {
6046
5948
  totals: {
6047
- proceeds: nn$19(p),
5949
+ proceeds: nn$21(p),
6048
5950
  acb: num(c),
6049
- outlays: nn$19(o)
5951
+ outlays: nn$21(o)
6050
5952
  },
6051
5953
  differs: a.proceeds !== void 0 || a.acb !== void 0
6052
5954
  };
@@ -6068,17 +5970,17 @@ function computeAlbertaSchedule18(input) {
6068
5970
  const gainOf = (c) => categories.find((x) => x.category === c)?.gain ?? 0;
6069
5971
  const personalUseGain = gainOf("personalUse");
6070
5972
  const listedPersonalGain = gainOf("listedPersonal");
6071
- const lppLossesApplied = listedPersonalGain > 0 ? Math.min(nn$19(input.unappliedLppLosses), listedPersonalGain) : 0;
5973
+ const lppLossesApplied = listedPersonalGain > 0 ? Math.min(nn$21(input.unappliedLppLosses), listedPersonalGain) : 0;
6072
5974
  const ordinaryGains = gainOf("shares") + gainOf("realEstate") + gainOf("bonds") + gainOf("otherProperties");
6073
5975
  const lppComponent = listedPersonalGain >= 0 ? listedPersonalGain - lppLossesApplied : 0;
6074
- const reserveOpening = nn$19(input.albertaReserveOpening ?? input.federalReserveOpening);
6075
- const reserveClosing = nn$19(input.albertaReserveClosing ?? input.federalReserveClosing);
6076
- const netBeforeInclusionRate = ordinaryGains + personalUseGain + lppComponent + nn$19(input.capitalGainsDividends) + reserveOpening - reserveClosing - nn$19(input.gainOnDonatedSecurities) - nn$19(input.gainOnDonatedEcologicalLand) + Math.min(nn$19(input.exemptionThreshold), nn$19(input.capitalGainsFromActualProperty)) + 2 * nn$19(input.section342TaxableCapitalGains) - 2 * nn$19(input.section342AllowableCapitalLosses);
5976
+ const reserveOpening = nn$21(input.albertaReserveOpening ?? input.federalReserveOpening);
5977
+ const reserveClosing = nn$21(input.albertaReserveClosing ?? input.federalReserveClosing);
5978
+ const netBeforeInclusionRate = ordinaryGains + personalUseGain + lppComponent + nn$21(input.capitalGainsDividends) + reserveOpening - reserveClosing - nn$21(input.gainOnDonatedSecurities) - nn$21(input.gainOnDonatedEcologicalLand) + Math.min(nn$21(input.exemptionThreshold), nn$21(input.capitalGainsFromActualProperty)) + 2 * nn$21(input.section342TaxableCapitalGains) - 2 * nn$21(input.section342AllowableCapitalLosses);
6077
5979
  const taxableCapitalGain = Math.max(0, Math.round(inclusionRate * netBeforeInclusionRate));
6078
5980
  const abil = (input.abilEntries ?? []).map((e) => ({
6079
5981
  name: e.name,
6080
5982
  kind: e.kind,
6081
- businessInvestmentLoss: nn$19(e.proceeds) - (nn$19(e.acb) + nn$19(e.outlays))
5983
+ businessInvestmentLoss: nn$21(e.proceeds) - (nn$21(e.acb) + nn$21(e.outlays))
6082
5984
  }));
6083
5985
  const totalBil = abil.reduce((s, e) => s + Math.min(0, e.businessInvestmentLoss), 0);
6084
5986
  const allowableBusinessInvestmentLoss = -Math.round(inclusionRate * -totalBil);
@@ -6109,7 +6011,7 @@ function computeAlbertaSchedule18(input) {
6109
6011
  }
6110
6012
  //#endregion
6111
6013
  //#region src/t2/at1/schedules/schedule20-donations.ts
6112
- const nn$18 = (v) => Math.max(0, v ?? 0);
6014
+ const nn$20 = (v) => Math.max(0, v ?? 0);
6113
6015
  /**
6114
6016
  * Alberta figures default to federal, per-field. A `0` entered on the Alberta
6115
6017
  * side is a real override and must not be swallowed by the default, so the
@@ -6134,11 +6036,11 @@ function resolveCarryforward(federal, alberta) {
6134
6036
  return out;
6135
6037
  }
6136
6038
  function computeSchedule20(input) {
6137
- const openingBalance = nn$18(input.openingBalance);
6138
- const expired = nn$18(input.expired);
6139
- const transferredIn = nn$18(input.transferredIn);
6140
- const currentYearGifts = nn$18(input.currentYearGifts);
6141
- const acquisitionOfControlAdjustment = nn$18(input.acquisitionOfControlAdjustment);
6039
+ const openingBalance = nn$20(input.openingBalance);
6040
+ const expired = nn$20(input.expired);
6041
+ const transferredIn = nn$20(input.transferredIn);
6042
+ const currentYearGifts = nn$20(input.currentYearGifts);
6043
+ const acquisitionOfControlAdjustment = nn$20(input.acquisitionOfControlAdjustment);
6142
6044
  const availableBeforeClaim = Math.max(0, openingBalance - expired + transferredIn + currentYearGifts - acquisitionOfControlAdjustment);
6143
6045
  const issues = [];
6144
6046
  let ceiling;
@@ -6209,12 +6111,12 @@ function computeSchedule20(input) {
6209
6111
  const AT1_DONATION_INCOME_RATE = .75;
6210
6112
  /** Gains and recapture on gifted capital property add back at 25%. */
6211
6113
  const AT1_DONATION_GAIN_RATE = .25;
6212
- const nn$17 = (v) => Math.max(0, v ?? 0);
6114
+ const nn$19 = (v) => Math.max(0, v ?? 0);
6213
6115
  function computeDonationMaximum(input) {
6214
6116
  const incomeComponent = Math.round(AT1_DONATION_INCOME_RATE * Math.max(0, input.albertaNetIncomeForTax));
6215
- const lesserOfProceedsAndCost = Math.min(nn$17(input.proceedsNetOfOutlays), nn$17(input.capitalCost));
6216
- const allowableRecapture = Math.min(nn$17(input.recaptureOnGifts), lesserOfProceedsAndCost);
6217
- const gainsComponent = Math.round(AT1_DONATION_GAIN_RATE * (nn$17(input.taxableCapitalGainsOnGifts) + nn$17(input.deemedGiftGains) + allowableRecapture));
6117
+ const lesserOfProceedsAndCost = Math.min(nn$19(input.proceedsNetOfOutlays), nn$19(input.capitalCost));
6118
+ const allowableRecapture = Math.min(nn$19(input.recaptureOnGifts), lesserOfProceedsAndCost);
6119
+ const gainsComponent = Math.round(AT1_DONATION_GAIN_RATE * (nn$19(input.taxableCapitalGainsOnGifts) + nn$19(input.deemedGiftGains) + allowableRecapture));
6218
6120
  return {
6219
6121
  incomeComponent,
6220
6122
  lesserOfProceedsAndCost,
@@ -6658,6 +6560,35 @@ function computeSBD(input, rates = CORP_TAX_2024) {
6658
6560
  sbdAmount: Math.round(rates.SBD_RATE * sbdIncome)
6659
6561
  };
6660
6562
  }
6563
+ const nn$18 = (v) => v ?? 0;
6564
+ function computeAggregateInvestmentIncome(input) {
6565
+ const amountA = nn$18(input.allowableCapitalLosses) + nn$18(input.netCapitalLossesClaimed);
6566
+ const amountB = Math.max(0, nn$18(input.taxableCapitalGains) - amountA);
6567
+ const amountC = nn$18(input.exemptIncome) + nn$18(input.agriInvestFundReceived) + nn$18(input.taxableDividendsDeductible) + nn$18(input.trustPropertyIncome);
6568
+ const amountD = nn$18(input.incomeFromProperty) - amountC;
6569
+ const amountE = amountB + amountD;
6570
+ return {
6571
+ amountA,
6572
+ amountB,
6573
+ amountC,
6574
+ amountD,
6575
+ amountE,
6576
+ aggregateInvestmentIncome: Math.max(0, amountE - nn$18(input.lossesFromProperty))
6577
+ };
6578
+ }
6579
+ function computeAdjustedAggregateInvestmentIncome(input) {
6580
+ const amountF = Math.max(0, nn$18(input.taxableCapitalGains) - nn$18(input.allowableCapitalLosses));
6581
+ const amountG = nn$18(input.exemptIncome) + nn$18(input.agriInvestFundReceived) + nn$18(input.dividendsFromConnectedCorporations) + nn$18(input.trustPropertyIncome);
6582
+ const amountH = nn$18(input.incomeFromProperty) - amountG;
6583
+ const amountI = amountF + amountH;
6584
+ return {
6585
+ amountF,
6586
+ amountG,
6587
+ amountH,
6588
+ amountI,
6589
+ adjustedAggregateInvestmentIncome: Math.max(0, amountI - nn$18(input.lossesFromProperty) + nn$18(input.subsection91_4Deduction))
6590
+ };
6591
+ }
6661
6592
  //#endregion
6662
6593
  //#region src/t2/jacket/part1-tax.ts
6663
6594
  /**
@@ -6967,6 +6898,60 @@ function assessEifel(input, thresholds) {
6967
6898
  };
6968
6899
  }
6969
6900
  //#endregion
6901
+ //#region src/t2/schedules/part-vi-1-deduction.ts
6902
+ const PART_VI_1_DEDUCTION_BANDS = [
6903
+ {
6904
+ from: "0000-01-01",
6905
+ multiple: 3
6906
+ },
6907
+ {
6908
+ from: "2010-01-01",
6909
+ multiple: 3.2
6910
+ },
6911
+ {
6912
+ from: "2012-01-01",
6913
+ multiple: 3.5
6914
+ }
6915
+ ];
6916
+ function utcDay$1(iso) {
6917
+ return Date.parse(`${iso.slice(0, 10)}T00:00:00Z`);
6918
+ }
6919
+ /** The multiple in force for a taxation year ending on `taxYearEnd`. */
6920
+ function partVI1DeductionMultiple(taxYearEnd, bands = PART_VI_1_DEDUCTION_BANDS) {
6921
+ const end = utcDay$1(taxYearEnd);
6922
+ if (Number.isNaN(end)) return 0;
6923
+ let multiple = 0;
6924
+ for (const band of [...bands].sort((a, b) => utcDay$1(a.from) - utcDay$1(b.from))) if (end >= utcDay$1(band.from)) multiple = band.multiple;
6925
+ return multiple;
6926
+ }
6927
+ /**
6928
+ * The paragraph 110(1)(k) deduction.
6929
+ *
6930
+ * An unreadable year end yields nil and says so, rather than defaulting to the
6931
+ * current multiple — guessing the year would misstate taxable income, and this
6932
+ * deduction is large relative to the tax it follows.
6933
+ */
6934
+ function computePartVI1Deduction(partVI1Tax, taxYearEnd, bands = PART_VI_1_DEDUCTION_BANDS) {
6935
+ const issues = [];
6936
+ const tax = Math.max(0, Math.round(partVI1Tax));
6937
+ const multiple = partVI1DeductionMultiple(taxYearEnd, bands);
6938
+ if (multiple === 0) {
6939
+ issues.push(`ITA 110(1)(k): the taxation year end "${taxYearEnd}" could not be read, so no Part VI.1 deduction was computed. The multiple depends on the year end (3 before 2010, 3.2 to 2011, 3.5 after) and cannot be assumed.`);
6940
+ return {
6941
+ partVI1Tax: tax,
6942
+ multiple: 0,
6943
+ deduction: 0,
6944
+ issues
6945
+ };
6946
+ }
6947
+ return {
6948
+ partVI1Tax: tax,
6949
+ multiple,
6950
+ deduction: Math.round(multiple * tax),
6951
+ issues
6952
+ };
6953
+ }
6954
+ //#endregion
6970
6955
  //#region src/t2/schedules/schedule1.ts
6971
6956
  function computeSchedule1(input) {
6972
6957
  const additions = [...input.additions ?? []];
@@ -7095,10 +7080,10 @@ function assertSchedule1Fileable(result) {
7095
7080
  }
7096
7081
  //#endregion
7097
7082
  //#region src/t2/schedules/schedule2-donations.ts
7098
- const nn$16 = (v) => Math.max(0, v ?? 0);
7083
+ const nn$17 = (v) => Math.max(0, v ?? 0);
7099
7084
  function computeSchedule2(input, rates) {
7100
- const openingDonationPool = nn$16(input.openingDonationPool);
7101
- const currentYearDonations = nn$16(input.currentYearDonations);
7085
+ const openingDonationPool = nn$17(input.openingDonationPool);
7086
+ const currentYearDonations = nn$17(input.currentYearDonations);
7102
7087
  const available = openingDonationPool + currentYearDonations;
7103
7088
  const deductionLimit = Math.max(0, Math.round(rates.DONATION_INCOME_LIMIT_RATE * input.netIncomeForTax));
7104
7089
  const donationsClaimed = Math.min(available, deductionLimit);
@@ -7137,25 +7122,25 @@ function computeSchedule2(input, rates) {
7137
7122
  const PART_IV_RATE = 115 / 300;
7138
7123
  /** 30⅔% — the refundable portion of Part I tax on aggregate investment income. */
7139
7124
  const REFUNDABLE_PART_I_RATE = 92 / 300;
7140
- const nn$15 = (v) => Math.max(0, v ?? 0);
7125
+ const nn$16 = (v) => Math.max(0, v ?? 0);
7141
7126
  const DEFAULT_PART4_RATES = {
7142
7127
  PART_IV_RATE,
7143
7128
  REFUNDABLE_PART_I_RATE
7144
7129
  };
7145
7130
  function computePart4Rdtoh(input, rates = DEFAULT_PART4_RATES) {
7146
- const portfolio = nn$15(input.portfolioDividendsReceived);
7147
- const eligible = Math.min(portfolio, nn$15(input.eligiblePortfolioDividends));
7131
+ const portfolio = nn$16(input.portfolioDividendsReceived);
7132
+ const eligible = Math.min(portfolio, nn$16(input.eligiblePortfolioDividends));
7148
7133
  const nonEligible = portfolio - eligible;
7149
- const aaii = nn$15(input.aggregateInvestmentIncome);
7134
+ const aaii = nn$16(input.aggregateInvestmentIncome);
7150
7135
  const partIvOnEligible = Math.round(eligible * rates.PART_IV_RATE);
7151
7136
  const partIvOnNonEligible = Math.round(nonEligible * rates.PART_IV_RATE);
7152
7137
  const partIvTax = partIvOnEligible + partIvOnNonEligible;
7153
7138
  const refundablePartI = Math.round(aaii * rates.REFUNDABLE_PART_I_RATE);
7154
7139
  const erdtohAddition = partIvOnEligible;
7155
7140
  const nerdtohAddition = partIvOnNonEligible + refundablePartI;
7156
- const erdtohClosing = nn$15(input.openingErdtoh) + erdtohAddition;
7157
- const nerdtohClosing = nn$15(input.openingNerdtoh) + nerdtohAddition;
7158
- const refundClaim = Math.round(nn$15(input.taxableDividendsPaid) * PART_IV_RATE);
7141
+ const erdtohClosing = nn$16(input.openingErdtoh) + erdtohAddition;
7142
+ const nerdtohClosing = nn$16(input.openingNerdtoh) + nerdtohAddition;
7143
+ const refundClaim = Math.round(nn$16(input.taxableDividendsPaid) * PART_IV_RATE);
7159
7144
  return {
7160
7145
  partIvTax,
7161
7146
  refundablePartI,
@@ -7319,7 +7304,7 @@ const PROVINCE_NAMES = {
7319
7304
  AB: "Alberta",
7320
7305
  QC: "Quebec"
7321
7306
  };
7322
- const nn$14 = (v) => Math.max(0, v ?? 0);
7307
+ const nn$15 = (v) => Math.max(0, v ?? 0);
7323
7308
  function computeProvincialAllocation(input, rates = PROVINCE_RATES_2024) {
7324
7309
  const byProvince = /* @__PURE__ */ new Map();
7325
7310
  for (const pe of input.permanentEstablishments) {
@@ -7328,8 +7313,8 @@ function computeProvincialAllocation(input, rates = PROVINCE_RATES_2024) {
7328
7313
  grossRevenue: 0,
7329
7314
  salariesWages: 0
7330
7315
  };
7331
- cur.grossRevenue += nn$14(pe.grossRevenue);
7332
- cur.salariesWages += nn$14(pe.salariesWages);
7316
+ cur.grossRevenue += nn$15(pe.grossRevenue);
7317
+ cur.salariesWages += nn$15(pe.salariesWages);
7333
7318
  byProvince.set(key, cur);
7334
7319
  }
7335
7320
  const totalRevenue = [...byProvince.values()].reduce((s, p) => s + p.grossRevenue, 0);
@@ -7412,6 +7397,302 @@ function computeSchedule6(dispositions, inclusionRate) {
7412
7397
  };
7413
7398
  }
7414
7399
  //#endregion
7400
+ //#region src/t2/schedules/schedule12-resource-deductions.ts
7401
+ /**
7402
+ * T2 Schedule 12 — Resource-Related Deductions (2025 and later tax years).
7403
+ *
7404
+ * Federal T2 had ZERO tracking for any of this before this module — the
7405
+ * Alberta side (AT1 Schedule 15, `t2/at1/schedules/schedule15-resource-related-deductions.ts`)
7406
+ * has been fully built and wired for a while, computing an Alberta figure to
7407
+ * diff against a federal figure that was always silently 0. This module
7408
+ * closes that gap on the federal side.
7409
+ *
7410
+ * Source: `research/sources/cra-forms/pdf/T2SCH12-resource-related-deductions.pdf`
7411
+ * (T2 SCH 12 E (26), downloaded 2026-09-03 — canada.ca was unreachable
7412
+ * earlier in this project; re-verified reachable on this date), rendered
7413
+ * page-by-page and read directly, not run through `pdftotext` (this form is
7414
+ * a grid, the same class of layout `pdftotext -layout` has misaligned
7415
+ * elsewhere in this codebase — rendering avoided that risk from the start).
7416
+ *
7417
+ * ── Five claim totals, one per Schedule 1 line ──────────────────────────────
7418
+ *
7419
+ * Part 1+2+3 Depletion (EDA regular/successor + CMEDB) → line 344
7420
+ * Part 4 Cumulative Canadian exploration expenses → line 341
7421
+ * Part 5 Cumulative Canadian development expenses → line 340
7422
+ * Part 6 Cumulative Canadian oil & gas property exp. → line 342
7423
+ * Part 7+8+9 Foreign exploration/development + resource → line 345
7424
+ *
7425
+ * ── What this module deliberately does NOT model ────────────────────────────
7426
+ *
7427
+ * The real form's full continuity has columns this module has no input for:
7428
+ * amalgamation/wind-up transfers, transfers to/from a successor corporation,
7429
+ * flow-through share renunciations, the look-back rule (s.66(12.66)), and
7430
+ * CEE↔CDE reclassification (ss.66.1(9)/66.7(9)). These are real provisions,
7431
+ * genuinely rare for a typical filer, and each one entered as a bare "other
7432
+ * additions/deductions" figure risks silently misclassifying something the
7433
+ * form treats specially (e.g. a flow-through renunciation has its own
7434
+ * unique interaction with the pool). Each pool below accepts a plain
7435
+ * `otherAdditions`/`otherDeductions` catch-all instead and says so in its
7436
+ * own doc comment — an honest scope limit, not a silent gap. Successor
7437
+ * pools ARE modelled (the form structurally requires the split), but with
7438
+ * the same collapsed catch-all shape as the regular pools.
7439
+ *
7440
+ * ACDE (Accelerated Canadian development expenses, generally incurred
7441
+ * after November 20, 2018 and before 2025) is NOT modelled as a separate
7442
+ * input: this schedule version is titled "2025 and later tax years", so a
7443
+ * CURRENT-year expense entered here is, for the ordinary case, always
7444
+ * RCDE-eligible rather than ACDE-eligible (RCDE covers 2024-2034,
7445
+ * overlapping the day this schedule starts applying). The narrow exception
7446
+ * — a tax year straddling the 2024/2025 boundary with genuine pre-2025
7447
+ * current-year CDE/COGPE additions — is not separately split out; treating
7448
+ * 100% of current-year CDE/COGPE additions as RCDE-eligible is the correct
7449
+ * default for the mainline case this schedule version targets, not a guess.
7450
+ * Same logic for ACOGPE/RCOGPE (Part 6).
7451
+ *
7452
+ * The CCOGPE↔CDE cross-linkage (a negative CCOGPE subtotal routes to EITHER
7453
+ * CDE line 105/133 depending on an s.66.7(4)(a)(iii) designation this
7454
+ * engine has no source for) is the SAME ambiguity the AT1 module already
7455
+ * flags unresolved for its own mirror of this rule — this module raises the
7456
+ * identical class of `issues` entry rather than guessing a designation
7457
+ * status it cannot know.
7458
+ *
7459
+ * Whole dollars, pure functions, no I/O.
7460
+ */
7461
+ const nn$14 = (v) => Math.max(0, v ?? 0);
7462
+ const round = (v) => Math.round(v);
7463
+ /** CDE/CCOGPE-style short-tax-year proration: full rate at ≥357 days, else rate × days/365. */
7464
+ function stepYearFactor(daysInTaxYear) {
7465
+ const days = daysInTaxYear ?? 365;
7466
+ return days >= 357 ? 1 : Math.max(0, days) / 365;
7467
+ }
7468
+ /** A discretionary claim capped at `cap` (≥ 0); defaults to the maximum when omitted. */
7469
+ function claimUpToCap(requested, cap, issues, label) {
7470
+ const c = Math.max(0, round(cap));
7471
+ if (requested === void 0) return c;
7472
+ if (requested < 0) {
7473
+ issues.push(`${label}: a requested claim of ${requested} is negative; treated as 0.`);
7474
+ return 0;
7475
+ }
7476
+ if (round(requested) > c) {
7477
+ issues.push(`${label}: the requested claim of ${requested} exceeds the maximum allowable ${c}; capped at ${c}.`);
7478
+ return c;
7479
+ }
7480
+ return round(requested);
7481
+ }
7482
+ /**
7483
+ * CEE-style claim: at or below a zero/negative subtotal the claim MUST equal
7484
+ * that (negative) subtotal — an income inclusion, not a deduction. Above
7485
+ * zero, a discretionary claim up to the subtotal (no percentage rate).
7486
+ */
7487
+ function forcedOrCappedClaim(requested, subtotal, issues, label) {
7488
+ if (subtotal <= 0) {
7489
+ if (requested !== void 0 && round(requested) !== round(subtotal)) issues.push(`${label}: the pool subtotal is ${subtotal} (≤ 0), so the claim must equal the subtotal (an income inclusion) — overriding the requested ${requested}.`);
7490
+ return round(subtotal);
7491
+ }
7492
+ return claimUpToCap(requested, subtotal, issues, label);
7493
+ }
7494
+ function computeDepletion(input = {}) {
7495
+ const issues = [];
7496
+ const edaRegularPool = nn$14(input.edaRegularOpening);
7497
+ const edaRegularClaim = claimUpToCap(input.edaRegularClaim, edaRegularPool, issues, "Schedule 12 EDA regular (115)");
7498
+ const edaRegularClosing = edaRegularPool - edaRegularClaim;
7499
+ const edaSuccessorPool = nn$14(input.edaSuccessorOpening);
7500
+ const edaSuccessorClaim = claimUpToCap(input.edaSuccessorClaim, edaSuccessorPool, issues, "Schedule 12 EDA successor (140)");
7501
+ const edaSuccessorClosing = edaSuccessorPool - edaSuccessorClaim;
7502
+ const cmedbPool = nn$14(input.cmedbOpening);
7503
+ const cmedbClaim = claimUpToCap(input.cmedbClaim, cmedbPool, issues, "Schedule 12 CMEDB (170)");
7504
+ return {
7505
+ edaRegularPool,
7506
+ edaRegularClaim,
7507
+ edaRegularClosing,
7508
+ edaSuccessorPool,
7509
+ edaSuccessorClaim,
7510
+ edaSuccessorClosing,
7511
+ cmedbPool,
7512
+ cmedbClaim,
7513
+ cmedbClosing: cmedbPool - cmedbClaim,
7514
+ totalClaim: edaRegularClaim + edaSuccessorClaim + cmedbClaim,
7515
+ issues
7516
+ };
7517
+ }
7518
+ function computeCee(input = {}) {
7519
+ const issues = [];
7520
+ const regularSubtotal = nn$14(input.regularOpening) + nn$14(input.regularCurrentYearExpenses) + nn$14(input.regularOtherAdditions) - nn$14(input.regularGovernmentAssistance) - nn$14(input.regularOtherDeductions);
7521
+ const regularClaim = forcedOrCappedClaim(input.regularClaim, regularSubtotal, issues, "Schedule 12 CEE regular (245)");
7522
+ const regularClosing = regularSubtotal > 0 ? regularSubtotal - regularClaim : 0;
7523
+ const successorSubtotal = nn$14(input.successorOpening) - nn$14(input.successorOtherDeductions);
7524
+ const successorClaim = forcedOrCappedClaim(input.successorClaim, successorSubtotal, issues, "Schedule 12 CEE successor (295)");
7525
+ return {
7526
+ regularSubtotal,
7527
+ regularClaim,
7528
+ regularClosing,
7529
+ successorSubtotal,
7530
+ successorClaim,
7531
+ successorClosing: successorSubtotal > 0 ? successorSubtotal - successorClaim : 0,
7532
+ totalClaim: regularClaim + successorClaim,
7533
+ issues
7534
+ };
7535
+ }
7536
+ /** ITA s.66.2(2) base CDE rate. */
7537
+ const CDE_BASE_RATE = .3;
7538
+ /** The RCDE bonus rate on top of the base rate (s.66.2, 2024+ enhancement). */
7539
+ const CDE_RCDE_BONUS_RATE = .15;
7540
+ function computeCde(input = {}, daysInTaxYear, cogpe = {
7541
+ regularSubtotal: 0,
7542
+ successorSubtotal: 0
7543
+ }) {
7544
+ const issues = [];
7545
+ const regularCreditBalance = cogpe.regularSubtotal < 0 ? round(cogpe.regularSubtotal) : nn$14(input.regularCreditBalanceInCogpePool);
7546
+ const regularSubtotal = nn$14(input.regularOpening) + nn$14(input.regularCurrentYearExpenses) + nn$14(input.regularOtherAdditions) - nn$14(input.regularGovernmentAssistance) - nn$14(input.regularReceivableOnDisposition) - regularCreditBalance - nn$14(input.regularOtherDeductions);
7547
+ const rcdePortion = Math.min(nn$14(input.regularCurrentYearExpenses), Math.max(0, regularSubtotal));
7548
+ const regularCap = CDE_BASE_RATE * stepYearFactor(daysInTaxYear) * regularSubtotal + CDE_RCDE_BONUS_RATE * stepYearFactor(daysInTaxYear) * rcdePortion;
7549
+ const regularClaim = regularSubtotal > 0 ? claimUpToCap(input.regularClaim, regularCap, issues, "Schedule 12 CDE regular (345)") : 0;
7550
+ const regularClosing = Math.max(0, regularSubtotal - regularClaim);
7551
+ if (regularSubtotal < 0) issues.push("Schedule 12 CDE regular (345): the pool subtotal is negative — per the form, include it as income in \"Other additions\" on Schedule 1 (this module does not auto-apply that; add a manual Schedule 1 addition for the negative amount).");
7552
+ const successorCreditBalance = cogpe.successorSubtotal < 0 ? round(cogpe.successorSubtotal) : nn$14(input.successorCreditBalanceInCogpePool);
7553
+ const successorSubtotal = nn$14(input.successorOpening) - successorCreditBalance - nn$14(input.successorOtherDeductions);
7554
+ const successorCap = CDE_BASE_RATE * stepYearFactor(daysInTaxYear) * successorSubtotal;
7555
+ const successorClaim = successorSubtotal > 0 ? claimUpToCap(input.successorClaim, successorCap, issues, "Schedule 12 CDE successor (395)") : 0;
7556
+ return {
7557
+ regularSubtotal,
7558
+ regularClaim,
7559
+ regularClosing,
7560
+ successorSubtotal,
7561
+ successorClaim,
7562
+ successorClosing: Math.max(0, successorSubtotal - successorClaim),
7563
+ totalClaim: regularClaim + successorClaim,
7564
+ issues
7565
+ };
7566
+ }
7567
+ /** ITA s.66.4(2) base COGPE rate. */
7568
+ const COGPE_BASE_RATE = .1;
7569
+ /** The RCOGPE bonus rate on top of the base rate. */
7570
+ const COGPE_RCOGPE_BONUS_RATE = .05;
7571
+ function computeCogpe(input = {}, daysInTaxYear) {
7572
+ const issues = [];
7573
+ const regularSubtotal = nn$14(input.regularOpening) + nn$14(input.regularCurrentYearExpenses) + nn$14(input.regularOtherAdditions) - nn$14(input.regularReceivableOnDisposition) - nn$14(input.regularGovernmentAssistance) - nn$14(input.regularOtherDeductions);
7574
+ const rcogpePortion = Math.min(nn$14(input.regularCurrentYearExpenses), Math.max(0, regularSubtotal));
7575
+ const regularCap = COGPE_BASE_RATE * stepYearFactor(daysInTaxYear) * regularSubtotal + COGPE_RCOGPE_BONUS_RATE * stepYearFactor(daysInTaxYear) * rcogpePortion;
7576
+ const regularClaim = regularSubtotal > 0 ? claimUpToCap(input.regularClaim, regularCap, issues, "Schedule 12 COGPE regular (445)") : 0;
7577
+ const regularClosing = regularSubtotal > 0 ? regularSubtotal - regularClaim : 0;
7578
+ if (regularSubtotal < 0) issues.push("Schedule 12 COGPE regular (445): the pool subtotal is negative. Per the form this carries to CDE regular line 330 (no s.66.7(4)(a)(iii) designation) or CDE successor line 380 (with a designation) — computeCde auto-applies the 330 route unconditionally when this subtotal is negative; confirm the designation status before relying on that routing.");
7579
+ const successorSubtotal = nn$14(input.successorOpening) - nn$14(input.successorReceivableOnDisposition) - nn$14(input.successorOtherDeductions);
7580
+ const successorCap = COGPE_BASE_RATE * stepYearFactor(daysInTaxYear) * successorSubtotal;
7581
+ const successorClaim = successorSubtotal > 0 ? claimUpToCap(input.successorClaim, successorCap, issues, "Schedule 12 COGPE successor (495)") : 0;
7582
+ const successorClosing = Math.max(0, successorSubtotal - successorClaim);
7583
+ if (successorSubtotal < 0) issues.push("Schedule 12 COGPE successor (495): the pool subtotal is negative. Per the form this carries to CDE successor line 380 (with a s.66.7(4)(a)(iii) designation) or back into this SAME pool's own regular-side line 440 (without one) — neither route is auto-applied; supply the appropriate override manually.");
7584
+ return {
7585
+ regularSubtotal,
7586
+ regularClaim,
7587
+ regularClosing,
7588
+ successorSubtotal,
7589
+ successorClaim,
7590
+ successorClosing,
7591
+ totalClaim: regularClaim + successorClaim,
7592
+ issues
7593
+ };
7594
+ }
7595
+ /** Part 7 — Foreign exploration and development expenses (pre-2001 tax years; still a real, if rare, carryforward). */
7596
+ function computeForeignExploration(input = {}, daysInTaxYear) {
7597
+ const issues = [];
7598
+ const regularPool = nn$14(input.regularOpening) - nn$14(input.regularOtherDeductions);
7599
+ let regularClaim = 0;
7600
+ if (regularPool < 0) issues.push("Schedule 12 FEDE regular (520): the pool balance is negative — include it as income in \"Other additions\" on Schedule 1 (not auto-applied by this module).");
7601
+ else if (regularPool > 0) {
7602
+ const cap = Math.max(COGPE_BASE_RATE * stepYearFactor(daysInTaxYear) * regularPool, nn$14(input.regularForeignResourceIncome));
7603
+ regularClaim = claimUpToCap(input.regularClaim, Math.min(regularPool, cap), issues, "Schedule 12 FEDE regular (520)");
7604
+ }
7605
+ const regularClosing = regularPool - regularClaim;
7606
+ const successorPool = nn$14(input.successorOpening) - nn$14(input.successorOtherDeductions);
7607
+ let successorClaim = 0;
7608
+ if (successorPool < 0) issues.push("Schedule 12 FEDE successor (570): the pool balance is negative — include it as income in \"Other additions\" on Schedule 1 (not auto-applied by this module).");
7609
+ else if (successorPool > 0) successorClaim = claimUpToCap(input.successorClaim, Math.min(successorPool, nn$14(input.successorForeignResourceIncome)), issues, "Schedule 12 FEDE successor (570)");
7610
+ const successorClosing = successorPool - successorClaim;
7611
+ return {
7612
+ regularPool,
7613
+ regularClaim,
7614
+ regularClosing,
7615
+ successorPool,
7616
+ successorClaim,
7617
+ successorClosing,
7618
+ issues
7619
+ };
7620
+ }
7621
+ /** Part 8 — specified foreign exploration/development, regular OR successor (call once per column; rates are identical). */
7622
+ function computeSpecifiedForeignExploration(input = {}, label) {
7623
+ const issues = [];
7624
+ const pool = nn$14(input.openingBalance) - nn$14(input.otherDeductions);
7625
+ let claim = 0;
7626
+ if (pool < 0) issues.push(`${label}: a country-level pool is negative — include it as income on Schedule 1 manually.`);
7627
+ else if (pool > 0) claim = claimUpToCap(input.claim, Math.min(pool, Math.max(nn$14(input.foreignResourceIncome), pool)), issues, label);
7628
+ return {
7629
+ pool,
7630
+ claim,
7631
+ closing: pool - claim,
7632
+ issues
7633
+ };
7634
+ }
7635
+ /** Part 9 — cumulative foreign resource expenses, regular OR successor. */
7636
+ function computeCumulativeForeignResource(input = {}, daysInTaxYear, label) {
7637
+ const issues = [];
7638
+ const pool = nn$14(input.openingBalance) + nn$14(input.currentYearExpenses) - nn$14(input.otherDeductions);
7639
+ let claim = 0;
7640
+ if (pool < 0) issues.push(`${label}: a country-level pool is negative — include it as income on Schedule 1 manually.`);
7641
+ else if (pool > 0) {
7642
+ const a = Math.max(.1 * stepYearFactor(daysInTaxYear) * pool, Math.min(.3 * stepYearFactor(daysInTaxYear) * pool, nn$14(input.foreignResourceIncome)));
7643
+ const cap = a + Math.min(pool - a, nn$14(input.foreignResourceIncome));
7644
+ claim = claimUpToCap(input.claim, Math.min(pool, cap), issues, label);
7645
+ }
7646
+ return {
7647
+ pool,
7648
+ claim,
7649
+ closing: pool - claim,
7650
+ issues
7651
+ };
7652
+ }
7653
+ function computeSchedule12ResourceDeductions(input) {
7654
+ const cogpe = input.cogpe ? computeCogpe(input.cogpe, input.daysInTaxYear) : void 0;
7655
+ const depletion = input.depletion ? computeDepletion(input.depletion) : void 0;
7656
+ const cee = input.cee ? computeCee(input.cee) : void 0;
7657
+ const cde = input.cde ? computeCde(input.cde, input.daysInTaxYear, {
7658
+ regularSubtotal: cogpe?.regularSubtotal ?? 0,
7659
+ successorSubtotal: cogpe?.successorSubtotal ?? 0
7660
+ }) : void 0;
7661
+ const foreignExploration = input.foreignExploration ? computeForeignExploration(input.foreignExploration, input.daysInTaxYear) : void 0;
7662
+ const specifiedForeignRegular = input.specifiedForeignRegular ? computeSpecifiedForeignExploration(input.specifiedForeignRegular, "Schedule 12 SFEDE regular") : void 0;
7663
+ const specifiedForeignSuccessor = input.specifiedForeignSuccessor ? computeSpecifiedForeignExploration(input.specifiedForeignSuccessor, "Schedule 12 SFEDE successor") : void 0;
7664
+ const cumulativeForeignRegular = input.cumulativeForeignRegular ? computeCumulativeForeignResource(input.cumulativeForeignRegular, input.daysInTaxYear, "Schedule 12 CFRE regular") : void 0;
7665
+ const cumulativeForeignSuccessor = input.cumulativeForeignSuccessor ? computeCumulativeForeignResource(input.cumulativeForeignSuccessor, input.daysInTaxYear, "Schedule 12 CFRE successor") : void 0;
7666
+ const issues = [
7667
+ ...depletion?.issues ?? [],
7668
+ ...cee?.issues ?? [],
7669
+ ...cde?.issues ?? [],
7670
+ ...cogpe?.issues ?? [],
7671
+ ...foreignExploration?.issues ?? [],
7672
+ ...specifiedForeignRegular?.issues ?? [],
7673
+ ...specifiedForeignSuccessor?.issues ?? [],
7674
+ ...cumulativeForeignRegular?.issues ?? [],
7675
+ ...cumulativeForeignSuccessor?.issues ?? []
7676
+ ];
7677
+ return {
7678
+ ...depletion ? { depletion } : {},
7679
+ ...cee ? { cee } : {},
7680
+ ...cde ? { cde } : {},
7681
+ ...cogpe ? { cogpe } : {},
7682
+ ...foreignExploration ? { foreignExploration } : {},
7683
+ ...specifiedForeignRegular ? { specifiedForeignRegular } : {},
7684
+ ...specifiedForeignSuccessor ? { specifiedForeignSuccessor } : {},
7685
+ ...cumulativeForeignRegular ? { cumulativeForeignRegular } : {},
7686
+ ...cumulativeForeignSuccessor ? { cumulativeForeignSuccessor } : {},
7687
+ depletionClaim: depletion?.totalClaim ?? 0,
7688
+ ceeClaim: cee?.totalClaim ?? 0,
7689
+ cdeClaim: cde?.totalClaim ?? 0,
7690
+ cogpeClaim: cogpe?.totalClaim ?? 0,
7691
+ foreignClaim: (foreignExploration?.regularClaim ?? 0) + (foreignExploration?.successorClaim ?? 0) + (specifiedForeignRegular?.claim ?? 0) + (specifiedForeignSuccessor?.claim ?? 0) + (cumulativeForeignRegular?.claim ?? 0) + (cumulativeForeignSuccessor?.claim ?? 0),
7692
+ issues
7693
+ };
7694
+ }
7695
+ //#endregion
7415
7696
  //#region src/t2/schedules/schedule13-reserves.ts
7416
7697
  const nn$13 = (v) => Math.max(0, Math.round(v ?? 0));
7417
7698
  function computeSchedule13(rows = []) {
@@ -7672,11 +7953,11 @@ function computeSchedule31(input, rates) {
7672
7953
  * Part 2 Investment allowance = lines 401–407 → line 490
7673
7954
  * Part 3 Taxable capital = capital − investment allowance → line 500
7674
7955
  * Part 4 Taxable capital employed in Canada
7675
- * = taxable capital × (taxable income earned in Canada ÷ taxable income) → line 690
7956
+ * = taxable capital × (taxable income earned in Canada ÷ taxable income) → line 790
7676
7957
  *
7677
7958
  * Part 5 of the paper form (the 0.225% figure at line 415) is the SUPERSEDED
7678
7959
  * capital-tax-era grind; the CURRENT business-limit grind (straight-line $10M→$50M)
7679
- * lives in Schedule 7. This schedule therefore stops at line 690 and hands that
7960
+ * lives in Schedule 7. This schedule therefore stops at line 790 and hands that
7680
7961
  * figure to the Schedule 7 grind. The federal Part I.3 tax itself was repealed
7681
7962
  * (2006) and is not computed. Pure, integer whole dollars.
7682
7963
  */
@@ -8054,18 +8335,50 @@ function shortYearProrationFactor(periodStart, periodEnd) {
8054
8335
  if (days >= 365) return 1;
8055
8336
  return days / 365;
8056
8337
  }
8338
+ /** Same inclusive day count as `shortYearProrationFactor`, but the raw days — Schedule 12's ≥357-day step proration needs the count itself, not a pre-divided factor. */
8339
+ function daysInTaxYear(periodStart, periodEnd) {
8340
+ if (!periodStart || !periodEnd) return void 0;
8341
+ const start = periodStart instanceof Date ? periodStart : new Date(periodStart);
8342
+ const ms = (periodEnd instanceof Date ? periodEnd : new Date(periodEnd)).getTime() - start.getTime();
8343
+ if (!Number.isFinite(ms) || ms < 0) return void 0;
8344
+ return Math.round(ms / 864e5) + 1;
8345
+ }
8057
8346
  function computeFederalT2(input) {
8058
8347
  const book = input.rateBook ?? CORP_TAX_RATE_BOOK;
8059
8348
  const taxYear = input.taxYear ?? latestRateYear(book);
8060
8349
  const rates = input.rates ?? resolveCorpTaxRates(taxYear, book);
8061
8350
  const prorationFactor = shortYearProrationFactor(input.periodStart, input.periodEnd);
8062
- const cca = input.ccaClasses?.length ? computeCcaSchedule(input.ccaClasses, resolveCcaRates(taxYear), prorationFactor) : void 0;
8351
+ const ccaRaw = input.ccaClasses?.length ? computeCcaSchedule(input.ccaClasses, resolveCcaRates(taxYear), prorationFactor) : void 0;
8352
+ const class141RecaptureReduction = input.class141Disposition ? computeClass141RecaptureReduction(input.class141Disposition) : 0;
8353
+ const cca = ccaRaw && class141RecaptureReduction > 0 ? (() => {
8354
+ const idx = ccaRaw.classes.findIndex((c) => c.ccaClass === "14.1");
8355
+ const row = idx >= 0 ? ccaRaw.classes[idx] : void 0;
8356
+ const reduction = row ? Math.min(class141RecaptureReduction, row.recapture) : 0;
8357
+ if (!row || reduction === 0) return ccaRaw;
8358
+ const classes = ccaRaw.classes.slice();
8359
+ classes[idx] = {
8360
+ ...row,
8361
+ recapture: row.recapture - reduction
8362
+ };
8363
+ return {
8364
+ ...ccaRaw,
8365
+ classes,
8366
+ totalRecapture: ccaRaw.totalRecapture - reduction
8367
+ };
8368
+ })() : ccaRaw;
8063
8369
  const class13 = input.class13 ? computeClass13(input.class13) : void 0;
8064
8370
  const class14 = input.class14 ? computeClass14(input.class14) : void 0;
8371
+ const class141Row = cca?.classes.find((c) => c.ccaClass === "14.1");
8372
+ const class141AdditionalAllowance = input.class141Transitional && class141Row ? computeClass141AdditionalAllowance({
8373
+ ...input.class141Transitional,
8374
+ ordinaryClaim: class141Row.ccaClaimed,
8375
+ uccBeforeCca: class141Row.uccBeforeCca,
8376
+ taxYearEnd: isoDay(input.periodEnd)
8377
+ }) : void 0;
8065
8378
  const capitalGains = input.capitalDispositions?.length ? computeSchedule6(input.capitalDispositions, rates.CAPITAL_GAINS_INCLUSION_RATE) : void 0;
8066
8379
  const schedule1Additions = [...input.schedule1Additions ?? []];
8067
8380
  const schedule1Deductions = [...input.schedule1Deductions ?? []];
8068
- const totalCcaDeduction = (cca?.totalCca ?? 0) + (class13?.ccaClaimed ?? 0) + (class14?.ccaClaimed ?? 0);
8381
+ const totalCcaDeduction = (cca?.totalCca ?? 0) + (class13?.ccaClaimed ?? 0) + (class14?.ccaClaimed ?? 0) + (class141AdditionalAllowance?.additionalAllowance ?? 0);
8069
8382
  if (totalCcaDeduction > 0) schedule1Deductions.push({
8070
8383
  line: "403",
8071
8384
  label: "Capital cost allowance from Schedule 8",
@@ -8106,22 +8419,83 @@ function computeFederalT2(input) {
8106
8419
  ref: "s.20(1)"
8107
8420
  });
8108
8421
  }
8422
+ const resolvedResourceDeductionDays = input.resourceDeductions?.daysInTaxYear ?? daysInTaxYear(input.periodStart, input.periodEnd);
8423
+ const resourceDeductions = input.resourceDeductions ? computeSchedule12ResourceDeductions({
8424
+ ...input.resourceDeductions,
8425
+ ...resolvedResourceDeductionDays !== void 0 ? { daysInTaxYear: resolvedResourceDeductionDays } : {}
8426
+ }) : void 0;
8427
+ if (resourceDeductions) {
8428
+ if (resourceDeductions.cdeClaim > 0) schedule1Deductions.push({
8429
+ line: "340",
8430
+ label: "Canadian development expenses from Schedule 12",
8431
+ amount: resourceDeductions.cdeClaim,
8432
+ ref: "s.66.2(2)"
8433
+ });
8434
+ if (resourceDeductions.ceeClaim !== 0) schedule1Deductions.push({
8435
+ line: "341",
8436
+ label: "Canadian exploration expenses from Schedule 12",
8437
+ amount: resourceDeductions.ceeClaim,
8438
+ ref: "s.66.1(2)"
8439
+ });
8440
+ if (resourceDeductions.cogpeClaim > 0) schedule1Deductions.push({
8441
+ line: "342",
8442
+ label: "Canadian oil and gas property expenses from Schedule 12",
8443
+ amount: resourceDeductions.cogpeClaim,
8444
+ ref: "s.66.4(2)"
8445
+ });
8446
+ if (resourceDeductions.depletionClaim > 0) schedule1Deductions.push({
8447
+ line: "344",
8448
+ label: "Depletion from Schedule 12",
8449
+ amount: resourceDeductions.depletionClaim,
8450
+ ref: "Reg. 1201/1202/1203"
8451
+ });
8452
+ if (resourceDeductions.foreignClaim > 0) schedule1Deductions.push({
8453
+ line: "345",
8454
+ label: "Foreign exploration, development and resource expenses from Schedule 12",
8455
+ amount: resourceDeductions.foreignClaim,
8456
+ ref: "s.66(4)/66.7(2)"
8457
+ });
8458
+ }
8109
8459
  const schedule1 = computeSchedule1({
8110
8460
  bookNetIncome: input.bookNetIncome,
8111
8461
  ...schedule1Additions.length ? { additions: schedule1Additions } : {},
8112
8462
  ...schedule1Deductions.length ? { deductions: schedule1Deductions } : {}
8113
8463
  });
8464
+ const partVI1 = input.preferredShareDividends && ((input.preferredShareDividends.shortTermPreferredDividends ?? 0) > 0 || (input.preferredShareDividends.otherPreferredDividends ?? 0) > 0) ? computeSchedule43(input.preferredShareDividends, {
8465
+ SHORT_TERM_RATE: rates.PART_VI_1_SHORT_TERM_RATE,
8466
+ ELECTED_RATE: rates.PART_VI_1_ELECTED_RATE,
8467
+ BASE_RATE: rates.PART_VI_1_BASE_RATE,
8468
+ DIVIDEND_ALLOWANCE: rates.PART_VI_1_DIVIDEND_ALLOWANCE,
8469
+ ALLOWANCE_GRIND_THRESHOLD: rates.PART_VI_1_ALLOWANCE_GRIND_THRESHOLD
8470
+ }) : void 0;
8471
+ const partVI1Deduction = partVI1 ? computePartVI1Deduction(partVI1.partVI1Tax, isoDay(input.periodEnd)) : void 0;
8114
8472
  const donations = input.charitableDonations !== void 0 || input.openingDonationPool !== void 0 ? computeSchedule2({
8115
8473
  ...input.openingDonationPool !== void 0 ? { openingDonationPool: input.openingDonationPool } : {},
8116
8474
  ...input.charitableDonations !== void 0 ? { currentYearDonations: input.charitableDonations } : {},
8117
8475
  netIncomeForTax: schedule1.netIncomeForTax
8118
8476
  }, rates) : void 0;
8119
- const divisionCDeductions = [...donations && donations.donationsClaimed > 0 ? [{
8120
- line: "112",
8121
- label: "Charitable donations and gifts from Schedule 2",
8122
- amount: donations.donationsClaimed,
8123
- ref: "s.110.1"
8124
- }] : [], ...input.divisionCDeductions ?? []];
8477
+ const culturalEcologicalGiftsClaimed = Math.max(0, input.culturalEcologicalGifts ?? 0);
8478
+ const divisionCDeductions = [
8479
+ ...donations && donations.donationsClaimed > 0 ? [{
8480
+ line: "112",
8481
+ label: "Charitable donations and gifts from Schedule 2",
8482
+ amount: donations.donationsClaimed,
8483
+ ref: "s.110.1"
8484
+ }] : [],
8485
+ ...culturalEcologicalGiftsClaimed > 0 ? [{
8486
+ line: "112",
8487
+ label: "Gifts of certified cultural property and ecologically sensitive land from Schedule 2",
8488
+ amount: culturalEcologicalGiftsClaimed,
8489
+ ref: "s.110.1(1)(b)/(c) — not subject to the 75% income limit"
8490
+ }] : [],
8491
+ ...partVI1Deduction && partVI1Deduction.deduction > 0 ? [{
8492
+ line: "325",
8493
+ label: "Part VI.1 tax deduction",
8494
+ amount: partVI1Deduction.deduction,
8495
+ ref: `s.110(1)(k) — ${partVI1Deduction.multiple}× Part VI.1 tax payable`
8496
+ }] : [],
8497
+ ...input.divisionCDeductions ?? []
8498
+ ];
8125
8499
  const taxableIncomeCalc = computeTaxableIncome({
8126
8500
  netIncomeForTax: schedule1.netIncomeForTax,
8127
8501
  ...divisionCDeductions.length ? { deductions: divisionCDeductions } : {}
@@ -8152,10 +8526,15 @@ function computeFederalT2(input) {
8152
8526
  ...input.taxableCapitalDetail.taxableIncome === void 0 ? { taxableIncome } : {}
8153
8527
  }) : void 0;
8154
8528
  const grindTaxableCapital = input.taxableCapital ?? taxableCapitalSchedule?.taxableCapitalEmployedInCanada;
8529
+ const adjustedAggregateInvestmentIncomeSchedule = input.adjustedAggregateInvestmentIncomeDetail ? computeAdjustedAggregateInvestmentIncome(input.adjustedAggregateInvestmentIncomeDetail) : void 0;
8530
+ const resolvedAaii = input.aaii ?? adjustedAggregateInvestmentIncomeSchedule?.adjustedAggregateInvestmentIncome;
8531
+ const aggregateInvestmentIncomeSchedule = input.aggregateInvestmentIncomeDetail ? computeAggregateInvestmentIncome(input.aggregateInvestmentIncomeDetail) : void 0;
8532
+ const resolvedAggregateInvestmentIncome = input.aggregateInvestmentIncome ?? aggregateInvestmentIncomeSchedule?.aggregateInvestmentIncome;
8533
+ const rdtohAggregateInvestmentIncome = resolvedAggregateInvestmentIncome ?? resolvedAaii;
8155
8534
  const businessLimit = computeBusinessLimit({
8156
8535
  ...input.businessLimit !== void 0 ? { businessLimit: input.businessLimit } : {},
8157
8536
  ...grindTaxableCapital !== void 0 ? { taxableCapital: grindTaxableCapital } : {},
8158
- ...input.aaii !== void 0 ? { aaii: input.aaii } : {},
8537
+ ...resolvedAaii !== void 0 ? { aaii: resolvedAaii } : {},
8159
8538
  ...prorationFactor < 1 ? { prorationFactor } : {}
8160
8539
  }, rates);
8161
8540
  const sbd = input.isCcpc === true ? computeSBD({
@@ -8176,7 +8555,7 @@ function computeFederalT2(input) {
8176
8555
  const part4Rdtoh = computePart4Rdtoh({
8177
8556
  portfolioDividendsReceived: input.portfolioDividendsReceived ?? 0,
8178
8557
  ...input.eligiblePortfolioDividends !== void 0 ? { eligiblePortfolioDividends: input.eligiblePortfolioDividends } : {},
8179
- ...input.aaii !== void 0 ? { aggregateInvestmentIncome: input.aaii } : {},
8558
+ ...rdtohAggregateInvestmentIncome !== void 0 ? { aggregateInvestmentIncome: rdtohAggregateInvestmentIncome } : {},
8180
8559
  ...input.taxableDividendsPaid !== void 0 ? { taxableDividendsPaid: input.taxableDividendsPaid } : {},
8181
8560
  ...input.openingErdtoh !== void 0 ? { openingErdtoh: input.openingErdtoh } : {},
8182
8561
  ...input.openingNerdtoh !== void 0 ? { openingNerdtoh: input.openingNerdtoh } : {}
@@ -8209,7 +8588,7 @@ function computeFederalT2(input) {
8209
8588
  }, rates) : void 0;
8210
8589
  const grip = input.openingGrip !== void 0 || input.eligibleDividendsReceived !== void 0 || input.eligibleDividendsDesignated !== void 0 ? computeGrip({
8211
8590
  ...input.openingGrip !== void 0 ? { openingGrip: input.openingGrip } : {},
8212
- generalRateIncome: Math.max(0, taxableIncome - sbd.sbdIncome - (input.aaii ?? 0)),
8591
+ generalRateIncome: Math.max(0, taxableIncome - sbd.sbdIncome - (resolvedAggregateInvestmentIncome ?? resolvedAaii ?? 0)),
8213
8592
  ...input.eligibleDividendsReceived !== void 0 ? { eligibleDividendsReceived: input.eligibleDividendsReceived } : {},
8214
8593
  ...input.eligibleDividendsDesignated !== void 0 ? { eligibleDividendsDesignated: input.eligibleDividendsDesignated } : {}
8215
8594
  }, rates.GRIP_FACTOR) : void 0;
@@ -8223,13 +8602,6 @@ function computeFederalT2(input) {
8223
8602
  ...input.electedOrdinaryDividendAmount !== void 0 ? { electedAmount: input.electedOrdinaryDividendAmount } : {},
8224
8603
  ...input.electOrdinaryDividend !== void 0 ? { electsMaximum: input.electOrdinaryDividend } : {}
8225
8604
  }, rates.PART_III_1_RATE, rates.PART_III_1_PARAGRAPH_C_RATE) : void 0;
8226
- const partVI1 = input.preferredShareDividends && ((input.preferredShareDividends.shortTermPreferredDividends ?? 0) > 0 || (input.preferredShareDividends.otherPreferredDividends ?? 0) > 0) ? computeSchedule43(input.preferredShareDividends, {
8227
- SHORT_TERM_RATE: rates.PART_VI_1_SHORT_TERM_RATE,
8228
- ELECTED_RATE: rates.PART_VI_1_ELECTED_RATE,
8229
- BASE_RATE: rates.PART_VI_1_BASE_RATE,
8230
- DIVIDEND_ALLOWANCE: rates.PART_VI_1_DIVIDEND_ALLOWANCE,
8231
- ALLOWANCE_GRIND_THRESHOLD: rates.PART_VI_1_ALLOWANCE_GRIND_THRESHOLD
8232
- }) : void 0;
8233
8605
  const totalFederalTax = partIAfterCredits + (itcRecapture?.totalRecapture ?? 0) + part4Rdtoh.partIvTax - part4Rdtoh.dividendRefund - (sredItc?.totalItcBenefit ?? 0) + (partIII1?.partIII1Tax ?? 0) + (partVI1?.partVI1Tax ?? 0);
8234
8606
  const baseProvinceRates = resolveProvinceRates(taxYear);
8235
8607
  const provinceRates = input.provincialRateChanges && input.periodStart && input.periodEnd ? blendProvinceRateTable(baseProvinceRates, input.provincialRateChanges, input.periodStart, input.periodEnd) : baseProvinceRates;
@@ -8264,6 +8636,8 @@ function computeFederalT2(input) {
8264
8636
  schedule1,
8265
8637
  taxableIncomeCalc,
8266
8638
  businessLimit,
8639
+ ...adjustedAggregateInvestmentIncomeSchedule ? { adjustedAggregateInvestmentIncomeSchedule } : {},
8640
+ ...aggregateInvestmentIncomeSchedule ? { aggregateInvestmentIncomeSchedule } : {},
8267
8641
  sbd,
8268
8642
  partI,
8269
8643
  part4Rdtoh,
@@ -8273,6 +8647,8 @@ function computeFederalT2(input) {
8273
8647
  ...cca ? { cca } : {},
8274
8648
  ...class13 ? { class13 } : {},
8275
8649
  ...class14 ? { class14 } : {},
8650
+ ...class141AdditionalAllowance ? { class141AdditionalAllowance } : {},
8651
+ ...class141RecaptureReduction > 0 ? { class141RecaptureReduction } : {},
8276
8652
  ...capitalGains ? { capitalGains } : {},
8277
8653
  ...provincial ? { provincial } : {},
8278
8654
  ...provincialAllocation ? { provincialAllocation } : {},
@@ -8280,6 +8656,7 @@ function computeFederalT2(input) {
8280
8656
  ...lrip ? { lrip } : {},
8281
8657
  ...partIII1 ? { partIII1 } : {},
8282
8658
  ...partVI1 ? { partVI1 } : {},
8659
+ ...partVI1Deduction ? { partVI1Deduction } : {},
8283
8660
  eifel,
8284
8661
  ...internetBusiness ? { internetBusiness } : {},
8285
8662
  ...firstReturn ? { firstReturn } : {},
@@ -8290,6 +8667,7 @@ function computeFederalT2(input) {
8290
8667
  ...associatedAllocation ? { associatedAllocation } : {},
8291
8668
  ...reserves ? { reserves } : {},
8292
8669
  ...taxableCapitalSchedule ? { taxableCapitalSchedule } : {},
8670
+ ...resourceDeductions ? { resourceDeductions } : {},
8293
8671
  netIncomeForTax: schedule1.netIncomeForTax,
8294
8672
  taxableIncome,
8295
8673
  federalTaxPayable: partI.partITaxPayable,
@@ -8708,6 +9086,7 @@ const OPTIONAL_NUMERIC_FIELDS = [
8708
9086
  "businessLimit",
8709
9087
  "taxableCapital",
8710
9088
  "aaii",
9089
+ "aggregateInvestmentIncome",
8711
9090
  "portfolioDividendsReceived",
8712
9091
  "eligiblePortfolioDividends",
8713
9092
  "taxableDividendsPaid",
@@ -8826,19 +9205,19 @@ function renderT2DraftReturn(data, opts = {}) {
8826
9205
  if (data.questionnaire) {
8827
9206
  const q = data.questionnaire;
8828
9207
  out.push(" <Questionnaire>");
8829
- out.push(el(4, "AddressChanged", yn(q.addressChanged), "063"));
8830
- out.push(el(4, "FirstYearFiling", yn(q.firstYear), "067"));
8831
- out.push(el(4, "FinalReturn", yn(q.finalReturn)));
8832
- out.push(el(4, "FirstReturnAfterAmalgamation", yn(q.amalgamation), "072"));
8833
- out.push(el(4, "WindUpOfSubsidiary", yn(q.windUp), "076"));
8834
- out.push(el(4, "AcquisitionOfControl", yn(q.acquisitionOfControl)));
8835
- out.push(el(4, "NonResident", yn(q.nonResident), "071"));
9208
+ out.push(el(4, "AddressChanged", yn(q.addressChanged)));
9209
+ out.push(el(4, "FirstYearFiling", yn(q.firstYear), "070"));
9210
+ out.push(el(4, "FinalReturn", yn(q.finalReturn), "078"));
9211
+ out.push(el(4, "FirstReturnAfterAmalgamation", yn(q.amalgamation), "071"));
9212
+ out.push(el(4, "WindUpOfSubsidiary", yn(q.windUp), "072"));
9213
+ out.push(el(4, "AcquisitionOfControl", yn(q.acquisitionOfControl), "063"));
9214
+ out.push(el(4, "DeemedYearEnd", yn(q.deemedYearEnd), "066"));
8836
9215
  out.push(el(4, "ResidentOfCanada", yn(q.residentOfCanada), "080"));
8837
- out.push(el(4, "ProfessionalCorporation", yn(q.professionalCorp)));
9216
+ out.push(el(4, "ProfessionalCorporation", yn(q.professionalCorp), "067"));
8838
9217
  out.push(el(4, "Inactive", yn(q.inactive)));
8839
9218
  out.push(el(4, "AssociatedCCPC", yn(q.associated), "160"));
8840
9219
  out.push(el(4, "AssociatedClaimingExpenditureLimit", yn(q.associatedClaimingExpenditureLimit), "161"));
8841
- out.push(el(4, "RelatedCorporations", yn(q.relatedCorporations)));
9220
+ out.push(el(4, "RelatedCorporations", yn(q.relatedCorporations), "150"));
8842
9221
  out.push(el(4, "CharitableDonations", yn(q.charitableDonations), "201"));
8843
9222
  out.push(el(4, "Dividends", yn(q.dividends), "202"));
8844
9223
  out.push(el(4, "ClaimingLosses", yn(q.claimingLosses), "204"));
@@ -9188,7 +9567,7 @@ const EIFEL_FIRST_YEAR_START = "2023-10-01";
9188
9567
  /** The transitional 40% band ends when years beginning in 2024 start. */
9189
9568
  const EIFEL_STANDARD_RATIO_FROM = "2024-01-01";
9190
9569
  const nn$1 = (v) => Math.max(0, Math.round(v ?? 0));
9191
- function utcDay$1(iso) {
9570
+ function utcDay(iso) {
9192
9571
  return Date.parse(`${iso.slice(0, 10)}T00:00:00Z`);
9193
9572
  }
9194
9573
  /**
@@ -9196,9 +9575,9 @@ function utcDay$1(iso) {
9196
9575
  * Returns 0 for a year beginning before the regime applies at all.
9197
9576
  */
9198
9577
  function ratioOfPermissibleExpenses(taxYearStart) {
9199
- const start = utcDay$1(taxYearStart);
9200
- if (Number.isNaN(start) || start < utcDay$1("2023-10-01")) return 0;
9201
- return start < utcDay$1("2024-01-01") ? EIFEL_TRANSITIONAL_RATIO : EIFEL_STANDARD_RATIO;
9578
+ const start = utcDay(taxYearStart);
9579
+ if (Number.isNaN(start) || start < utcDay("2023-10-01")) return 0;
9580
+ return start < utcDay("2024-01-01") ? EIFEL_TRANSITIONAL_RATIO : EIFEL_STANDARD_RATIO;
9202
9581
  }
9203
9582
  function computeEifelLimitation(input) {
9204
9583
  const issues = [];
@@ -9238,60 +9617,6 @@ function computeEifelLimitation(input) {
9238
9617
  };
9239
9618
  }
9240
9619
  //#endregion
9241
- //#region src/t2/schedules/part-vi-1-deduction.ts
9242
- const PART_VI_1_DEDUCTION_BANDS = [
9243
- {
9244
- from: "0000-01-01",
9245
- multiple: 3
9246
- },
9247
- {
9248
- from: "2010-01-01",
9249
- multiple: 3.2
9250
- },
9251
- {
9252
- from: "2012-01-01",
9253
- multiple: 3.5
9254
- }
9255
- ];
9256
- function utcDay(iso) {
9257
- return Date.parse(`${iso.slice(0, 10)}T00:00:00Z`);
9258
- }
9259
- /** The multiple in force for a taxation year ending on `taxYearEnd`. */
9260
- function partVI1DeductionMultiple(taxYearEnd, bands = PART_VI_1_DEDUCTION_BANDS) {
9261
- const end = utcDay(taxYearEnd);
9262
- if (Number.isNaN(end)) return 0;
9263
- let multiple = 0;
9264
- for (const band of [...bands].sort((a, b) => utcDay(a.from) - utcDay(b.from))) if (end >= utcDay(band.from)) multiple = band.multiple;
9265
- return multiple;
9266
- }
9267
- /**
9268
- * The paragraph 110(1)(k) deduction.
9269
- *
9270
- * An unreadable year end yields nil and says so, rather than defaulting to the
9271
- * current multiple — guessing the year would misstate taxable income, and this
9272
- * deduction is large relative to the tax it follows.
9273
- */
9274
- function computePartVI1Deduction(partVI1Tax, taxYearEnd, bands = PART_VI_1_DEDUCTION_BANDS) {
9275
- const issues = [];
9276
- const tax = Math.max(0, Math.round(partVI1Tax));
9277
- const multiple = partVI1DeductionMultiple(taxYearEnd, bands);
9278
- if (multiple === 0) {
9279
- issues.push(`ITA 110(1)(k): the taxation year end "${taxYearEnd}" could not be read, so no Part VI.1 deduction was computed. The multiple depends on the year end (3 before 2010, 3.2 to 2011, 3.5 after) and cannot be assumed.`);
9280
- return {
9281
- partVI1Tax: tax,
9282
- multiple: 0,
9283
- deduction: 0,
9284
- issues
9285
- };
9286
- }
9287
- return {
9288
- partVI1Tax: tax,
9289
- multiple,
9290
- deduction: Math.round(multiple * tax),
9291
- issues
9292
- };
9293
- }
9294
- //#endregion
9295
9620
  //#region src/t2/schedules/schedule27-mp.ts
9296
9621
  /**
9297
9622
  * T2 Schedule 27 — Canadian Manufacturing and Processing Profits Deduction
@@ -9362,6 +9687,72 @@ const MP_RATES_2024 = Object.freeze({
9362
9687
  GENERAL_RATE_REDUCTION: .13
9363
9688
  });
9364
9689
  const nn = (v) => Math.max(0, Math.round(v ?? 0));
9690
+ /** The $200,000 combined-active-business-income ceiling, s.5201 of the Regulations. */
9691
+ const SMALL_MANUFACTURER_INCOME_THRESHOLD = 2e5;
9692
+ function computeSmallManufacturerTest(input) {
9693
+ const issues = [];
9694
+ const line100 = nn(input.activeBusinessIncome);
9695
+ const combinedActiveBusinessIncome = line100 + nn(input.associatedActiveBusinessIncome);
9696
+ const failures = [];
9697
+ if (!input.primarilyManufacturing) failures.push("activities during the year were not primarily manufacturing or processing");
9698
+ if (combinedActiveBusinessIncome > 2e5) failures.push(`combined active business income (${combinedActiveBusinessIncome}, line 110) exceeds the $${SMALL_MANUFACTURER_INCOME_THRESHOLD.toLocaleString()} ceiling under s.5201 of the Regulations`);
9699
+ if (input.excludedActivity) failures.push(`${input.excludedActivity} is an excluded activity under s.5201(c)-(c.3)`);
9700
+ if (input.activeBusinessOutsideCanada) failures.push("an active business was carried on outside Canada during the year");
9701
+ const qualifies = failures.length === 0;
9702
+ if (!qualifies) issues.push(`Schedule 27 Part 1: does not qualify as a small manufacturing corporation — ${failures.join("; ")}. Complete Part 2 (the labour-and-capital formula) instead.`);
9703
+ return {
9704
+ qualifies,
9705
+ combinedActiveBusinessIncome,
9706
+ canadianMPProfits: qualifies ? line100 : 0,
9707
+ issues
9708
+ };
9709
+ }
9710
+ function computePart2MPProfits(input) {
9711
+ const issues = [];
9712
+ const adjubi = nn(input.adjustedBusinessIncome);
9713
+ const c = nn(input.costOfCapital);
9714
+ const mc = Math.min(nn(input.costOfMPCapital), c);
9715
+ const l = nn(input.costOfLabour);
9716
+ const ml = Math.min(nn(input.costOfMPLabour), l);
9717
+ const denominator = c + l;
9718
+ if (denominator === 0) {
9719
+ issues.push("Schedule 27 Part 2: cost of capital (C) and cost of labour (L) are both nil, so the (MC+ML)/(C+L) ratio cannot be computed. No M&P profits claimed.");
9720
+ return {
9721
+ ratio: 0,
9722
+ canadianMPProfits: 0,
9723
+ issues
9724
+ };
9725
+ }
9726
+ const ratio = (mc + ml) / denominator;
9727
+ return {
9728
+ ratio,
9729
+ canadianMPProfits: Math.max(0, Math.round(adjubi * ratio)),
9730
+ issues
9731
+ };
9732
+ }
9733
+ /**
9734
+ * "Small manufacturing corporations that meet all requirements in Part 1
9735
+ * should begin with Part 1 ... all other corporations should begin with
9736
+ * Part 2" — the form's own routing (page 1), reproduced here.
9737
+ */
9738
+ function computeCanadianMPProfits(input) {
9739
+ const smallManufacturerTest = input.smallManufacturer ? computeSmallManufacturerTest(input.smallManufacturer) : void 0;
9740
+ if (smallManufacturerTest?.qualifies) return {
9741
+ method: "part1",
9742
+ canadianMPProfits: smallManufacturerTest.canadianMPProfits,
9743
+ smallManufacturerTest,
9744
+ issues: smallManufacturerTest.issues
9745
+ };
9746
+ const part2Result = input.part2 ? computePart2MPProfits(input.part2) : void 0;
9747
+ const issues = [...smallManufacturerTest?.issues ?? [], ...part2Result?.issues ?? []];
9748
+ return {
9749
+ ...part2Result ? { method: "part2" } : {},
9750
+ canadianMPProfits: part2Result?.canadianMPProfits ?? 0,
9751
+ ...smallManufacturerTest ? { smallManufacturerTest } : {},
9752
+ ...part2Result ? { part2Result } : {},
9753
+ issues
9754
+ };
9755
+ }
9365
9756
  function computeMpDeduction(input, rates = MP_RATES_2024) {
9366
9757
  const issues = [];
9367
9758
  const mpProfits = nn(input.manufacturingAndProcessingProfits);
@@ -9403,4 +9794,4 @@ function computeMpDeduction(input, rates = MP_RATES_2024) {
9403
9794
  };
9404
9795
  }
9405
9796
  //#endregion
9406
- export { computeProvincialAllocation as $, albertaBalanceUnpaid as $n, schedule4Values as $r, AT1_RESERVE_TOTAL_LINES as $t, runConformance as A, hasExactRateYear as Ai, albertaRecaptureDifference as An, computeFedeRegular as Ar, computeCcpcActiveBusinessTax as At, computeGrip as B, RSI_WORD_GAP as Bn, allocateSchedule9ExpenditureLimit as Br, computeLossSchedule as Bt, computeQuebecTax as C, AB_GENERAL_RATE_BANDS as Ci, resolveCcaRates as Cn, computeCeeRegular as Cr, blendProvinceRateTable as Ct, T2_LINE_META as D, resolveAlbertaTaxRates as Di, albertaCcaScheduleAdjustments as Dn, computeCmedb as Dr, dividendsDeductibleS112 as Dt, resolveQuebecTaxRates as E, AB_TAX_RATE_BOOK as Ei, albertaCcaDifference as En, computeCfreSuccessor as Er, computeTaxableIncome as Et, normalizeSchedule88 as F, LossCarrybackError as Fn, computeSchedule11 as Fr, CORP_TAX_RATE_BOOK as Ft, ITC_RECAPTURE_PERIOD_YEARS as G, renderAt1Rsi as Gn, schedule8Values as Gr, AT1_DONATION_INCOME_RATE as Gt, LARGE_CORPORATION_THRESHOLD as H, formatRsiAmount as Hn, computeSchedule9MaximumExpenditureLimit as Hr, computeLimitedPartnershipLossRow as Ht, computeSchedule55 as I, computeLossCarryback as In, schedule11Values as Ir, resolveCorpTaxRates as It, allocateEvenly as J, renderAt1NetFile as Jn, computeAlbertaSchedule6 as Jr, AT1_DISPOSITION_CATEGORIES as Jt, computeItcRecapture as K, renderRsiHeader as Kn, computeAlbertaSchedule7 as Kr, computeDonationMaximum as Kt, LRIP_INVESTMENT_CORPORATION_MULTIPLE as L, RSI_COLUMN_GAP as Ln, ALBERTA_SRED_EXPENDITURE_CUTOFF as Lr, T2_CERTIFICATION_FIXTURES as Lt, computeFederalT2 as M, resolveRates as Mi, albertaTerminalLossDifference as Mn, computeSfedeCountryRegular as Mr, computeBusinessLimit as Mt, computeSchedule101 as N, computeSchedule12 as Nn, computeSfedeCountrySuccessor as Nr, computeSBD as Nt, foldT2Lines as O, earliestRateYear as Oi, albertaCurrentYearLoss as On, computeEdaRegular as Or, netCapitalLossApplied as Ot, SCHEDULE_88_MAX_URLS as P, reconcileAlbertaNetIncome as Pn, schedule15Values as Pr, CORP_TAX_2024 as Pt, computeSchedule6 as Q, At1TaxPayableMismatchError as Qn, computeSchedule4 as Qr, AT1_RESERVE_LINES as Qt, LRIP_INVESTMENT_INCOME_FACTOR as R, RSI_DELIMITER as Rn, ALBERTA_SRED_PROGRAM_START as Rr, computeNonCapitalLossByYearOfOrigin as Rt, computeQuebecAllocationFactor as S, computeAlbertaSbd as Si, isDecliningBalanceClass as Sn, computeCdeSuccessor as Sr, resolveProvinceRates as St, QC_TAX_RATE_BOOK as T, AB_TAX_2024 as Ti, albertaCapitalGainDifference as Tn, computeCfreRegular as Tr, charitableDonationsDeduction as Tt, computeTaxableCapital as U, formatRsiDate as Un, schedule9Values as Ur, computeLimitedPartnershipLosses as Ut, computeSchedule43 as V, RsiLineItemError as Vn, computeAlbertaSchedule9 as Vr, computeLossContinuity as Vt, computeSchedule31 as W, formatRsiText as Wn, computeSchedule8$1 as Wr, AT1_DONATION_GAIN_RATE as Wt, computeSchedule21 as X, At1CriticalFieldMissingError as Xn, computeAlbertaSchedule5 as Xr, computeAlbertaSchedule18 as Xt, computeBusinessLimitAllocation as Y, AT1_CRITICAL_MANDATORY_FIELDS as Yn, schedule6Values as Yr, SECTION_34_2_GROSS_UP as Yt, computeSchedule13 as Z, At1MandatoryFieldMissingError as Zn, schedule5Values as Zr, AT1_RESERVE_KINDS as Zt, renderT2DraftReturn as _, schedule21Values as _i, computeClass14 as _n, iegT661SourceLine as _r, EIFEL_EFFECTIVE_FROM as _t, PART_VI_1_DEDUCTION_BANDS as a, AT1_SCHEDULES_WITHOUT_BUILDERS as ai, cecScheduleAppliesToTaxYear as an, xmlEscape as ar, computeSchedule2 as at, co17Engine as b, schedule4970Values as bi, CCA_DECLINING_BALANCE_RATES_2024 as bn, computeCcogpeSuccessor as br, PROVINCE_RATE_BOOK as bt, EIFEL_FIRST_YEAR_START as c, schedule10Values as ci, UnsupportedCcaClassError as cn, allocateIegEvenly as cr, assertSchedule1Fileable as ct, EIFEL_TRANSITIONAL_RATIO as d, schedule13Values as di, computeSchedule8 as dn, computeIegGroupFigures as dr, deferredIncomeTaxProvisionAddBack as dt, computeSchedule3 as ei, computeAlbertaSchedule17 as en, assertAt1MandatoryComplete as er, computeSchedule5 as et, computeEifelLimitation as f, schedule16Values as fi, CLASS_14_1_MINIMUM_DEDUCTION as fn, IEG_2024 as fr, findSchedule1LineDefects as ft, computeT2Settlement as g, schedule20Values as gi, computeClass13 as gn, computeIegEligibleExpenditures as gr, terminalLossDeduction as gt, computeAdjustedTaxableIncome as h, schedule1Values as hi, MIN_LEASEHOLD_PERIODS as hn, computeIegReductionFactor as hr, recaptureAddBack as ht, computeMpDeduction as i, computeAt4970 as ii, CEC_INCLUSION_RATE as in, at1YesNo as ir, computePart4Rdtoh as it, runConformanceSuite as j, latestRateYear as ji, albertaReserveDifference as jn, computeFedeSuccessor as jr, computePartITax as jt, formatConformanceReport as k, extendRateBook as ki, albertaDispositionAdjustments as kn, computeEdaSuccessor as kr, nonCapitalLossApplied as kt, EIFEL_STANDARD_RATIO as l, schedule12LossDeductions as li, computeCcaClass as ln, allocateIegExpenditureLimit as lr, ccaDeduction as lt, FOREIGN_TAX_CREDIT_GROSS_UP as m, schedule18Values as mi, MAX_LEASEHOLD_PERIODS as mn, computeIegBaseAmount as mr, mealsAndEntertainmentAddBack as mt, MP_GROSS_REVENUE_THRESHOLD as n, SINGLE_JURISDICTION_ALBERTA_FACTOR as ni, computeAlbertaSchedule16 as nn, assertCriticalFields as nr, PART_IV_RATE as nt, computePartVI1Deduction as o, AT1_SCHEDULES_WITH_BUILDERS as oi, computeAlbertaSchedule14 as on, at1Engine as or, Schedule1NotFileableError as ot, ratioOfPermissibleExpenses as p, schedule17Values as pi, CLASS_14_1_TRANSITIONAL_RATE as pn, computeIeg as pr, incomeTaxProvisionAddBack as pt, computeZetm as q, renderRsiLineItem as qn, schedule7Values as qr, computeSchedule20 as qt, MP_RATES_2024 as r, computeAllocationFactor as ri, CEC_DEDUCTION_RATE as rn, at1TaxPayableDeductions as rr, REFUNDABLE_PART_I_RATE as rt, partVI1DeductionMultiple as s, at1LineItemId as si, computeAlbertaSchedule13 as sn, computeAlbertaReturn as sr, amortizationAddBack as st, MP_EXCLUDED_ACTIVITIES as t, schedule3Values as ti, assistanceFrom as tn, assertAt1TaxPayableReconciles as tr, computeSchedule4Losses as tt, EIFEL_STANDARD_RATIO_FROM as u, schedule12Values as ui, computeCcaSchedule as un, computeIegAgreement as ur, computeSchedule1 as ut, t2Engine as v, schedule29Values as vi, computeClass141AdditionalAllowance as vn, computeAlbertaSchedule15 as vr, assessEifel as vt, QC_TAX_2024 as w, computeDayWeightedGeneralTax as wi, albertaAbilDifference as wn, computeCeeSuccessor as wr, dayWeightedRate as wt, computeQuebecReturn as x, computeAlbertaTax as xi, CCA_RATE_BOOK as xn, computeCdeRegular as xr, isSchedule5Province as xt, renderCo17DraftReturn as y, schedule2Values as yi, leaseholdPeriods as yn, computeCcogpeRegular as yr, PROVINCE_RATES_2024 as yt, computeSchedule54 as z, RSI_NEGATIVE_PREFIX as zn, ALBERTA_SRED_TAX_CREDIT_RATE as zr, computeOtherLossByYearOfOrigin as zt };
9797
+ export { computeCde as $, toRsiSchedule as $n, ALBERTA_SRED_PROGRAM_START as $r, computeOtherLossByYearOfOrigin as $t, formatConformanceReport as A, schedule1Values as Ai, computeClass141RecaptureReduction as An, computeIeg as Ar, assessEifel as At, computeSchedule54 as B, AB_TAX_2024 as Bi, albertaCurrentYearLoss as Bn, computeCeeRegular as Br, netCapitalLossApplied as Bt, computeQuebecAllocationFactor as C, schedule10Values as Ci, CLASS_14_1_RECAPTURE_REDUCTION_RATE as Cn, at1Engine as Cr, mealsAndEntertainmentAddBack as Ct, resolveQuebecTaxRates as D, schedule16Values as Di, computeClass13 as Dn, computeIegAgreement as Dr, computePartVI1Deduction as Dt, QC_TAX_RATE_BOOK as E, schedule13Values as Ei, MIN_LEASEHOLD_PERIODS as En, allocateIegExpenditureLimit as Er, PART_VI_1_DEDUCTION_BANDS as Et, SCHEDULE_88_MAX_URLS as F, schedule4970Values as Fi, resolveCcaRates as Fn, computeAlbertaSchedule15 as Fr, blendProvinceRateTable as Ft, computeSchedule31 as G, hasExactRateYear as Gi, albertaTerminalLossDifference as Gn, computeEdaRegular as Gr, computeAggregateInvestmentIncome as Gt, computeSchedule43 as H, resolveAlbertaTaxRates as Hi, albertaRecaptureDifference as Hn, computeCfreRegular as Hr, computeCcpcActiveBusinessTax as Ht, normalizeSchedule88 as I, computeAlbertaTax as Ii, albertaAbilDifference as In, computeCcogpeRegular as Ir, dayWeightedRate as It, computeZetm as J, LossCarrybackError as Jn, computeFedeSuccessor as Jr, CORP_TAX_2024 as Jt, ITC_RECAPTURE_PERIOD_YEARS as K, latestRateYear as Ki, computeSchedule12 as Kn, computeEdaSuccessor as Kr, computeBusinessLimit as Kt, computeSchedule55 as L, computeAlbertaSbd as Li, albertaCapitalGainDifference as Ln, computeCcogpeSuccessor as Lr, charitableDonationsDeduction as Lt, runConformanceSuite as M, schedule21Values as Mi, CCA_DECLINING_BALANCE_RATES_2024 as Mn, computeIegReductionFactor as Mr, PROVINCE_RATE_BOOK as Mt, computeFederalT2 as N, schedule29Values as Ni, CCA_RATE_BOOK as Nn, computeIegEligibleExpenditures as Nr, isSchedule5Province as Nt, T2_LINE_META as O, schedule17Values as Oi, computeClass14 as On, computeIegGroupFigures as Or, partVI1DeductionMultiple as Ot, computeSchedule101 as P, schedule2Values as Pi, isDecliningBalanceClass as Pn, iegT661SourceLine as Pr, resolveProvinceRates as Pt, computeSchedule13 as Q, toRsiLineItems as Qn, ALBERTA_SRED_EXPENDITURE_CUTOFF as Qr, computeNonCapitalLossByYearOfOrigin as Qt, LRIP_INVESTMENT_CORPORATION_MULTIPLE as R, AB_GENERAL_RATE_BANDS as Ri, albertaCcaDifference as Rn, computeCdeRegular as Rr, computeTaxableIncome as Rt, computeQuebecReturn as S, at1LineItemId as Si, CLASS_14_1_MINIMUM_DEDUCTION as Sn, xmlEscape as Sr, incomeTaxProvisionAddBack as St, QC_TAX_2024 as T, schedule12Values as Ti, MAX_LEASEHOLD_PERIODS as Tn, allocateIegEvenly as Tr, terminalLossDeduction as Tt, LARGE_CORPORATION_THRESHOLD as U, earliestRateYear as Ui, albertaReserveDifference as Un, computeCfreSuccessor as Ur, computePartITax as Ut, computeGrip as V, AB_TAX_RATE_BOOK as Vi, albertaDispositionAdjustments as Vn, computeCeeSuccessor as Vr, nonCapitalLossApplied as Vt, computeTaxableCapital as W, extendRateBook as Wi, albertaResourceDeductionDifference as Wn, computeCmedb as Wr, computeAdjustedAggregateInvestmentIncome as Wt, computeBusinessLimitAllocation as X, toRsiHeader as Xn, computeSfedeCountrySuccessor as Xr, resolveCorpTaxRates as Xt, allocateEvenly as Y, computeLossCarryback as Yn, computeSfedeCountryRegular as Yr, CORP_TAX_RATE_BOOK as Yt, computeSchedule21 as Z, toRsiJacketSchedules as Zn, schedule15Values as Zr, T2_CERTIFICATION_FIXTURES as Zt, computeT2Settlement as _, SINGLE_JURISDICTION_ALBERTA_FACTOR as _i, computeAlbertaSchedule13 as _n, assertAt1MandatoryComplete as _r, assertSchedule1Fileable as _t, computeCanadianMPProfits as a, computeSchedule8$1 as ai, AT1_DONATION_INCOME_RATE as an, formatRsiAmount as ar, computeSchedule12ResourceDeductions as at, renderCo17DraftReturn as b, AT1_SCHEDULES_WITHOUT_BUILDERS as bi, computeCcaSchedule as bn, at1TaxPayableDeductions as br, deferredIncomeTaxProvisionAddBack as bt, computeSmallManufacturerTest as c, schedule7Values as ci, AT1_DISPOSITION_CATEGORIES as cn, renderAt1Rsi as cr, computeProvincialAllocation as ct, EIFEL_STANDARD_RATIO_FROM as d, computeAlbertaSchedule5 as di, AT1_RESERVE_KINDS as dn, renderAt1NetFile as dr, PART_IV_RATE as dt, ALBERTA_SRED_TAX_CREDIT_RATE as ei, computeLossSchedule as en, RSI_COLUMN_GAP as er, computeCee as et, EIFEL_TRANSITIONAL_RATIO as f, schedule5Values as fi, AT1_RESERVE_LINES as fn, AT1_CRITICAL_MANDATORY_FIELDS as fr, REFUNDABLE_PART_I_RATE as ft, computeAdjustedTaxableIncome as g, schedule3Values as gi, computeAlbertaSchedule16 as gn, albertaBalanceUnpaid as gr, amortizationAddBack as gt, FOREIGN_TAX_CREDIT_GROSS_UP as h, computeSchedule3 as hi, assistanceFrom as hn, At1TaxPayableMismatchError as hr, Schedule1NotFileableError as ht, SMALL_MANUFACTURER_INCOME_THRESHOLD as i, schedule9Values as ii, AT1_DONATION_GAIN_RATE as in, RsiLineItemError as ir, computeForeignExploration as it, runConformance as j, schedule20Values as ji, leaseholdPeriods as jn, computeIegBaseAmount as jr, PROVINCE_RATES_2024 as jt, foldT2Lines as k, schedule18Values as ki, computeClass141AdditionalAllowance as kn, IEG_2024 as kr, EIFEL_EFFECTIVE_FROM as kt, EIFEL_FIRST_YEAR_START as l, computeAlbertaSchedule6 as li, SECTION_34_2_GROSS_UP as ln, renderRsiHeader as lr, computeSchedule5 as lt, ratioOfPermissibleExpenses as m, schedule4Values as mi, computeAlbertaSchedule17 as mn, At1MandatoryFieldMissingError as mr, computeSchedule2 as mt, MP_GROSS_REVENUE_THRESHOLD as n, computeAlbertaSchedule9 as ni, computeLimitedPartnershipLossRow as nn, RSI_NEGATIVE_PREFIX as nr, computeCumulativeForeignResource as nt, computeMpDeduction as o, schedule8Values as oi, computeDonationMaximum as on, formatRsiDate as or, computeSpecifiedForeignExploration as ot, computeEifelLimitation as p, computeSchedule4 as pi, AT1_RESERVE_TOTAL_LINES as pn, At1CriticalFieldMissingError as pr, computePart4Rdtoh as pt, computeItcRecapture as q, resolveRates as qi, reconcileAlbertaNetIncome as qn, computeFedeRegular as qr, computeSBD as qt, MP_RATES_2024 as r, computeSchedule9MaximumExpenditureLimit as ri, computeLimitedPartnershipLosses as rn, RSI_WORD_GAP as rr, computeDepletion as rt, computePart2MPProfits as s, computeAlbertaSchedule7 as si, computeSchedule20 as sn, formatRsiText as sr, computeSchedule6 as st, MP_EXCLUDED_ACTIVITIES as t, allocateSchedule9ExpenditureLimit as ti, computeLossContinuity as tn, RSI_DELIMITER as tr, computeCogpe as tt, EIFEL_STANDARD_RATIO as u, schedule6Values as ui, computeAlbertaSchedule18 as un, renderRsiLineItem as ur, computeSchedule4Losses as ut, renderT2DraftReturn as v, computeAllocationFactor as vi, UnsupportedCcaClassError as vn, assertAt1TaxPayableReconciles as vr, ccaDeduction as vt, computeQuebecTax as w, schedule12LossDeductions as wi, CLASS_14_1_TRANSITIONAL_RATE as wn, computeAlbertaReturn as wr, recaptureAddBack as wt, co17Engine as x, AT1_SCHEDULES_WITH_BUILDERS as xi, computeSchedule8 as xn, at1YesNo as xr, findSchedule1LineDefects as xt, t2Engine as y, computeAt4970 as yi, computeCcaClass as yn, assertCriticalFields as yr, computeSchedule1 as yt, LRIP_INVESTMENT_INCOME_FACTOR as z, computeDayWeightedGeneralTax as zi, albertaCcaScheduleAdjustments as zn, computeCdeSuccessor as zr, dividendsDeductibleS112 as zt };