@invaro/opentax 0.11.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bundle/http.js +2546 -1359
- package/bundle/index.js +2540 -1353
- package/bundle/main.js +1520 -164
- package/package.json +5 -5
package/bundle/main.js
CHANGED
|
@@ -13337,45 +13337,45 @@ function generateCustomRefineCheck(doc, ctx, check2, accessor) {
|
|
|
13337
13337
|
throw new ZodCompileUnsupportedError("custom check without a predicate or check function");
|
|
13338
13338
|
}
|
|
13339
13339
|
function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
13340
|
-
const
|
|
13341
|
-
if (
|
|
13340
|
+
const fmt4 = def.format;
|
|
13341
|
+
if (fmt4 === "base64") {
|
|
13342
13342
|
const validator = addConstant(ctx, isValidBase64);
|
|
13343
13343
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13344
13344
|
return accessor;
|
|
13345
13345
|
}
|
|
13346
|
-
if (
|
|
13346
|
+
if (fmt4 === "base64url") {
|
|
13347
13347
|
const validator = addConstant(ctx, isValidBase64URL);
|
|
13348
13348
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13349
13349
|
return accessor;
|
|
13350
13350
|
}
|
|
13351
|
-
if (
|
|
13351
|
+
if (fmt4 === "jwt") {
|
|
13352
13352
|
const validator = addConstant(ctx, isValidJWT);
|
|
13353
13353
|
const alg = addConstant(ctx, def.alg ?? null);
|
|
13354
13354
|
doc.write(`if (!${validator}(${accessor}, ${alg})) return INVALID;`);
|
|
13355
13355
|
return accessor;
|
|
13356
13356
|
}
|
|
13357
|
-
if (
|
|
13357
|
+
if (fmt4 === "ipv6") {
|
|
13358
13358
|
const validator = addConstant(ctx, isValidIPv6);
|
|
13359
13359
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13360
13360
|
return accessor;
|
|
13361
13361
|
}
|
|
13362
|
-
if (
|
|
13362
|
+
if (fmt4 === "cidrv6") {
|
|
13363
13363
|
const validator = addConstant(ctx, isValidCIDRv6);
|
|
13364
13364
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13365
13365
|
return accessor;
|
|
13366
13366
|
}
|
|
13367
|
-
if (
|
|
13367
|
+
if (fmt4 === "credit_card") {
|
|
13368
13368
|
const validator = addConstant(ctx, isValidCreditCard);
|
|
13369
13369
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13370
13370
|
return accessor;
|
|
13371
13371
|
}
|
|
13372
|
-
if (
|
|
13372
|
+
if (fmt4 === "iban") {
|
|
13373
13373
|
const validator = addConstant(ctx, isValidIBAN);
|
|
13374
13374
|
doc.write(`if (!${validator}(${accessor})) return INVALID;`);
|
|
13375
13375
|
return accessor;
|
|
13376
13376
|
}
|
|
13377
13377
|
const formatDef = def;
|
|
13378
|
-
if (
|
|
13378
|
+
if (fmt4 === "url" || fmt4 === "httpurl" || formatDef.normalize || formatDef.hostname !== void 0 || formatDef.protocol !== void 0) {
|
|
13379
13379
|
const parseConst = addConstant(ctx, validateURL);
|
|
13380
13380
|
const defConst = addConstant(ctx, def);
|
|
13381
13381
|
const trimVar = newVar(ctx);
|
|
@@ -13401,12 +13401,12 @@ function generateStringFormatCheck(doc, ctx, def, accessor, needsValue = true) {
|
|
|
13401
13401
|
const customFn = def.fn;
|
|
13402
13402
|
if (customFn) {
|
|
13403
13403
|
if (isAsyncFunction(customFn))
|
|
13404
|
-
throw new ZodCompileUnsupportedError(`async string format ${
|
|
13404
|
+
throw new ZodCompileUnsupportedError(`async string format ${fmt4}`);
|
|
13405
13405
|
const fnConst = addConstant(ctx, customFn);
|
|
13406
13406
|
doc.write(`if (!${fnConst}(${accessor})) return INVALID;`);
|
|
13407
13407
|
return accessor;
|
|
13408
13408
|
}
|
|
13409
|
-
if (PATTERN_IS_COMPLETE.has(
|
|
13409
|
+
if (PATTERN_IS_COMPLETE.has(fmt4) && def.pattern) {
|
|
13410
13410
|
const patternConst = addConstant(ctx, def.pattern);
|
|
13411
13411
|
doc.write(`${patternConst}.lastIndex = 0;`);
|
|
13412
13412
|
doc.write(`if (!${patternConst}.test(${accessor})) return INVALID;`);
|
|
@@ -19924,21 +19924,21 @@ function visit(schema, fnOrHandlers) {
|
|
|
19924
19924
|
const h = fnOrHandlers[node2._zod.def.type];
|
|
19925
19925
|
return h ? h(node2, rewritten) : node2;
|
|
19926
19926
|
};
|
|
19927
|
-
const
|
|
19927
|
+
const cache2 = /* @__PURE__ */ new Map();
|
|
19928
19928
|
function run(s) {
|
|
19929
|
-
const cached3 =
|
|
19929
|
+
const cached3 = cache2.get(s);
|
|
19930
19930
|
if (cached3 === RESOLVING) {
|
|
19931
19931
|
return new $ZodLazy({
|
|
19932
19932
|
type: "lazy",
|
|
19933
|
-
getter: () =>
|
|
19933
|
+
getter: () => cache2.get(s)
|
|
19934
19934
|
});
|
|
19935
19935
|
}
|
|
19936
19936
|
if (cached3 !== void 0)
|
|
19937
19937
|
return cached3;
|
|
19938
|
-
|
|
19938
|
+
cache2.set(s, RESOLVING);
|
|
19939
19939
|
const inner = mapInner(s);
|
|
19940
19940
|
const mapped = fn(inner, inner !== s);
|
|
19941
|
-
|
|
19941
|
+
cache2.set(s, mapped);
|
|
19942
19942
|
return mapped;
|
|
19943
19943
|
}
|
|
19944
19944
|
function mapInner(s) {
|
|
@@ -23069,18 +23069,18 @@ var require_suggestSimilar = __commonJS({
|
|
|
23069
23069
|
}
|
|
23070
23070
|
return d3[a.length][b.length];
|
|
23071
23071
|
}
|
|
23072
|
-
function suggestSimilar(word,
|
|
23073
|
-
if (!
|
|
23074
|
-
|
|
23072
|
+
function suggestSimilar(word, candidates2) {
|
|
23073
|
+
if (!candidates2 || candidates2.length === 0) return "";
|
|
23074
|
+
candidates2 = Array.from(new Set(candidates2));
|
|
23075
23075
|
const searchingOptions = word.startsWith("--");
|
|
23076
23076
|
if (searchingOptions) {
|
|
23077
23077
|
word = word.slice(2);
|
|
23078
|
-
|
|
23078
|
+
candidates2 = candidates2.map((candidate) => candidate.slice(2));
|
|
23079
23079
|
}
|
|
23080
23080
|
let similar = [];
|
|
23081
23081
|
let bestDistance = maxDistance;
|
|
23082
23082
|
const minSimilarity = 0.4;
|
|
23083
|
-
|
|
23083
|
+
candidates2.forEach((candidate) => {
|
|
23084
23084
|
if (candidate.length <= 1) return;
|
|
23085
23085
|
const distance = editDistance(word, candidate);
|
|
23086
23086
|
const length = Math.max(word.length, candidate.length);
|
|
@@ -26209,29 +26209,29 @@ function evalRule(ruleId, ctx) {
|
|
|
26209
26209
|
const base = selectVersion(ctx.corpus, ruleId, ctx.asOf);
|
|
26210
26210
|
const overs = selectOverriders(ctx.corpus, ruleId, ctx.asOf);
|
|
26211
26211
|
const children = [];
|
|
26212
|
-
const
|
|
26212
|
+
const candidates2 = [];
|
|
26213
26213
|
let winner = null;
|
|
26214
26214
|
let poisoned = false;
|
|
26215
26215
|
for (const cand of overs) {
|
|
26216
26216
|
const guard = evalExpr(cand.applicability, cand, ctx, children);
|
|
26217
26217
|
if (guard === POISON) {
|
|
26218
|
-
|
|
26218
|
+
candidates2.push(candidateEntry(cand, "unknown"));
|
|
26219
26219
|
poisoned = true;
|
|
26220
26220
|
break;
|
|
26221
26221
|
}
|
|
26222
26222
|
expectType(guard, "bool", cand, "applicability");
|
|
26223
26223
|
if (guard.value) {
|
|
26224
|
-
|
|
26224
|
+
candidates2.push(candidateEntry(cand, true));
|
|
26225
26225
|
winner = cand;
|
|
26226
26226
|
break;
|
|
26227
26227
|
}
|
|
26228
|
-
|
|
26228
|
+
candidates2.push(candidateEntry(cand, false));
|
|
26229
26229
|
}
|
|
26230
26230
|
if (!winner && !poisoned) {
|
|
26231
26231
|
if (base.applicability) {
|
|
26232
26232
|
const guard = evalExpr(base.applicability, base, ctx, children);
|
|
26233
26233
|
if (guard === POISON) {
|
|
26234
|
-
|
|
26234
|
+
candidates2.push({ ...candidateEntry(base, "unknown"), priority: 0 });
|
|
26235
26235
|
poisoned = true;
|
|
26236
26236
|
} else {
|
|
26237
26237
|
expectType(guard, "bool", base, "applicability");
|
|
@@ -26244,12 +26244,12 @@ function evalRule(ruleId, ctx) {
|
|
|
26244
26244
|
}
|
|
26245
26245
|
]);
|
|
26246
26246
|
}
|
|
26247
|
-
|
|
26247
|
+
candidates2.push({ ...candidateEntry(base, true), priority: 0 });
|
|
26248
26248
|
winner = base;
|
|
26249
26249
|
}
|
|
26250
26250
|
} else {
|
|
26251
26251
|
if (overs.length > 0) {
|
|
26252
|
-
|
|
26252
|
+
candidates2.push({ ...candidateEntry(base, true), priority: 0 });
|
|
26253
26253
|
}
|
|
26254
26254
|
winner = base;
|
|
26255
26255
|
}
|
|
@@ -26299,7 +26299,7 @@ function evalRule(ruleId, ctx) {
|
|
|
26299
26299
|
title: winner.title,
|
|
26300
26300
|
citation: winner.citation,
|
|
26301
26301
|
...winner.id !== ruleId ? { resolvedFrom: ruleId } : {},
|
|
26302
|
-
...overs.length > 0 ? { candidatesConsidered:
|
|
26302
|
+
...overs.length > 0 ? { candidatesConsidered: candidates2 } : {},
|
|
26303
26303
|
...contributions.length > 0 ? { contributions } : {},
|
|
26304
26304
|
...ctx.excluded.size > 0 ? { excluding: [...ctx.excluded].sort() } : {},
|
|
26305
26305
|
inputs,
|
|
@@ -56546,6 +56546,433 @@ var init_tips_overtime = __esm({
|
|
|
56546
56546
|
}
|
|
56547
56547
|
});
|
|
56548
56548
|
|
|
56549
|
+
// ../corpus-us-federal/dist/projection-spec.js
|
|
56550
|
+
var PROJECTION_PARAMS, CG, derived2, eitc, pctSteps, TAX_TABLE, FIXED_LITERALS, gt011, NOT_PROJECTED;
|
|
56551
|
+
var init_projection_spec = __esm({
|
|
56552
|
+
"../corpus-us-federal/dist/projection-spec.js"() {
|
|
56553
|
+
"use strict";
|
|
56554
|
+
PROJECTION_PARAMS = [
|
|
56555
|
+
{ "kind": "indexed", "id": "brackets.single.12_bracket_start", "label": "brackets.single.12% bracket start (10% end)", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "952500", "ratio": ["2011421", "1495923"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "1280000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }] },
|
|
56556
|
+
{ "kind": "indexed", "id": "brackets.single.22_bracket_start", "label": "brackets.single.22% bracket start (12% end)", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "3870000", "ratio": ["2011421", "1495923"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "5202500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }] },
|
|
56557
|
+
{ "kind": "indexed", "id": "brackets.single.24_bracket_start", "label": "brackets.single.24% bracket start", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "8250000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "10912500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }] },
|
|
56558
|
+
{ "kind": "indexed", "id": "brackets.single.32_bracket_start", "label": "brackets.single.32% bracket start", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "15750000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "20832500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }] },
|
|
56559
|
+
{ "kind": "indexed", "id": "brackets.single.35_bracket_start", "label": "brackets.single.35% bracket start", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "20000000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "26455000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }] },
|
|
56560
|
+
{ "kind": "indexed", "id": "brackets.single.37_bracket_start", "label": "brackets.single.37% bracket start", "statute": "\xA7 1(j)(2)(C), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "50000000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "66137500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }, { "id": "us.federal.itemized_deductions", "statuses": ["single"] }] },
|
|
56561
|
+
{ "kind": "indexed", "id": "brackets.mfj.12_bracket_start", "label": "brackets.mfj.12% bracket start (10% end)", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "1905000", "ratio": ["2011421", "1495923"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "2560000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }] },
|
|
56562
|
+
{ "kind": "indexed", "id": "brackets.mfj.22_bracket_start", "label": "brackets.mfj.22% bracket start (12% end)", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "7740000", "ratio": ["2011421", "1495923"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "10405000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }] },
|
|
56563
|
+
{ "kind": "indexed", "id": "brackets.mfj.24_bracket_start", "label": "brackets.mfj.24% bracket start", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "16500000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "21825000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }] },
|
|
56564
|
+
{ "kind": "indexed", "id": "brackets.mfj.32_bracket_start", "label": "brackets.mfj.32% bracket start", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "31500000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "41665000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }] },
|
|
56565
|
+
{ "kind": "indexed", "id": "brackets.mfj.35_bracket_start", "label": "brackets.mfj.35% bracket start", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "40000000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "52910000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }] },
|
|
56566
|
+
{ "kind": "indexed", "id": "brackets.mfj.37_bracket_start", "label": "brackets.mfj.37% bracket start", "statute": "\xA7 1(j)(2)(A), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "60000000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "79365000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }, { "id": "us.federal.itemized_deductions", "statuses": ["mfj", "qss"] }] },
|
|
56567
|
+
{ "kind": "indexed", "id": "brackets.hoh.12_bracket_start", "label": "brackets.hoh.12% bracket start (10% end)", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "1360000", "ratio": ["2011421", "1495923"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "1825000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }] },
|
|
56568
|
+
{ "kind": "indexed", "id": "brackets.hoh.22_bracket_start", "label": "brackets.hoh.22% bracket start (12% end)", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "5180000", "ratio": ["2011421", "1495923"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "6965000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }] },
|
|
56569
|
+
{ "kind": "indexed", "id": "brackets.hoh.24_bracket_start", "label": "brackets.hoh.24% bracket start", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "8250000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "10910000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }] },
|
|
56570
|
+
{ "kind": "indexed", "id": "brackets.hoh.32_bracket_start", "label": "brackets.hoh.32% bracket start", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "15750000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "20830000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }] },
|
|
56571
|
+
{ "kind": "indexed", "id": "brackets.hoh.35_bracket_start", "label": "brackets.hoh.35% bracket start", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "20000000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "26455000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }] },
|
|
56572
|
+
{ "kind": "indexed", "id": "brackets.hoh.37_bracket_start", "label": "brackets.hoh.37% bracket start", "statute": "\xA7 1(j)(2)(B), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "50000000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "66135000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }, { "id": "us.federal.itemized_deductions", "statuses": ["hoh"] }] },
|
|
56573
|
+
{ "kind": "indexed", "id": "brackets.mfs.12_bracket_start", "label": "brackets.mfs.12% bracket start (10% end)", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "952500", "ratio": ["2011421", "1495923"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "1280000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }] },
|
|
56574
|
+
{ "kind": "indexed", "id": "brackets.mfs.22_bracket_start", "label": "brackets.mfs.22% bracket start (12% end)", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "3870000", "ratio": ["2011421", "1495923"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "5202500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }] },
|
|
56575
|
+
{ "kind": "indexed", "id": "brackets.mfs.24_bracket_start", "label": "brackets.mfs.24% bracket start", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "8250000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "10912500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }] },
|
|
56576
|
+
{ "kind": "indexed", "id": "brackets.mfs.32_bracket_start", "label": "brackets.mfs.32% bracket start", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "15750000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "20832500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }] },
|
|
56577
|
+
{ "kind": "indexed", "id": "brackets.mfs.35_bracket_start", "label": "brackets.mfs.35% bracket start", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "20000000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "26455000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }] },
|
|
56578
|
+
{ "kind": "indexed", "id": "brackets.mfs.37_bracket_start", "label": "brackets.mfs.37% bracket start", "statute": "\xA7 1(j)(2)(D), (j)(3)(B); \xA7 1(f)(3), (f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "30000000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "39682500", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfs"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfs"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfs"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfs"] }, { "id": "us.federal.itemized_deductions", "statuses": ["mfs"] }] },
|
|
56579
|
+
{ "kind": "indexed", "id": "brackets.estate.24_start", "label": "brackets.estate.24% start (10% end)", "statute": "\xA7 1(j)(2)(E), (j)(3)(B); \xA7 1(f)(7)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "255000", "ratio": ["2011421", "1495923"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "340000", "rules": [{ "id": "us.federal.fiduciary.income_tax" }] },
|
|
56580
|
+
{ "kind": "indexed", "id": "brackets.estate.35_start", "label": "brackets.estate.35% start", "statute": "\xA7 1(j)(2)(E), (j)(3)(B); \xA7 1(f)(7)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "915000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "1210000", "rules": [{ "id": "us.federal.fiduciary.income_tax" }] },
|
|
56581
|
+
{ "kind": "indexed", "id": "brackets.estate.37_start", "label": "brackets.estate.37% start", "statute": "\xA7 1(j)(2)(E), (j)(3)(B); \xA7 1(f)(7)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "1250000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "1650000", "rules": [{ "id": "us.federal.fiduciary.income_tax" }] },
|
|
56582
|
+
{ "kind": "indexed", "id": "capgains.mfj.zero", "label": "capgains.mfj.zero", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "7720000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "10210000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }, { "id": "us.federal.amt.tentative_minimum_tax", "statuses": ["mfj", "qss"] }] },
|
|
56583
|
+
{ "kind": "indexed", "id": "capgains.hoh.zero", "label": "capgains.hoh.zero", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "5170000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "6835000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }, { "id": "us.federal.amt.tentative_minimum_tax", "statuses": ["hoh"] }] },
|
|
56584
|
+
{ "kind": "indexed", "id": "capgains.estate.zero", "label": "capgains.estate.zero", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "260000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "340000", "rules": [] },
|
|
56585
|
+
{ "kind": "indexed", "id": "capgains.mfj.fifteen", "label": "capgains.mfj.fifteen", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "47900000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "63360000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["mfj", "qss"] }, { "id": "us.federal.kiddie_tax", "statuses": ["mfj", "qss"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["mfj", "qss"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["mfj", "qss"] }, { "id": "us.federal.amt.tentative_minimum_tax", "statuses": ["mfj", "qss"] }] },
|
|
56586
|
+
{ "kind": "indexed", "id": "capgains.hoh.fifteen", "label": "capgains.hoh.fifteen", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "45240000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "59840000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["hoh"] }, { "id": "us.federal.kiddie_tax", "statuses": ["hoh"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["hoh"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["hoh"] }, { "id": "us.federal.amt.tentative_minimum_tax", "statuses": ["hoh"] }] },
|
|
56587
|
+
{ "kind": "indexed", "id": "capgains.single.fifteen", "label": "capgains.single.fifteen", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "42580000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "56320000", "rules": [{ "id": "us.federal.income_tax_before_credits", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.tax_table", "statuses": ["single"] }, { "id": "us.federal.kiddie_tax", "statuses": ["single"] }, { "id": "us.federal.income_tax_before_credits.feie", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q1", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q2", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q3", "statuses": ["single"] }, { "id": "us.federal.estimated.annualized_installment_q4", "statuses": ["single"] }, { "id": "us.federal.amt.tentative_minimum_tax", "statuses": ["single"] }] },
|
|
56588
|
+
{ "kind": "indexed", "id": "capgains.estate.fifteen", "label": "capgains.estate.fifteen", "statute": "\xA7 1(j)(5)(B), (C)", "index": "c-cpi-u", "comps": [{ "baseCents": "1270000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "1675000", "rules": [] },
|
|
56589
|
+
{ "kind": "indexed", "id": "standardDeduction.single", "label": "standardDeduction.single (MFS same; MFJ/QSS = 200%)", "statute": "\xA7 63(c)(2)(C), (c)(7)(A)(ii), (c)(7)(B)(ii)", "index": "c-cpi-u", "comps": [{ "baseCents": "1575000", "ratio": ["12068526", "11419045"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "1660000", "rules": [{ "id": "us.federal.standard_deduction.base_amount", "statuses": ["single", "mfs"] }] },
|
|
56590
|
+
{ "kind": "indexed", "id": "standardDeduction.hoh", "label": "standardDeduction.hoh", "statute": "\xA7 63(c)(2)(B), (c)(7)(A)(i), (c)(7)(B)(ii)", "index": "c-cpi-u", "comps": [{ "baseCents": "2362500", "ratio": ["12068526", "11419045"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "2492500", "rules": [{ "id": "us.federal.standard_deduction.base_amount", "statuses": ["hoh"] }] },
|
|
56591
|
+
{ "kind": "indexed", "id": "dependentStdDed.floor", "label": "dependentStdDed.floor ($500) [= \xA7 1(g)(4)(A)(ii)(I) kiddie amount]", "statute": "\xA7 63(c)(5)(A), (c)(4)(B)(i); \xA7 1(f)(7)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "50000", "ratio": ["480023610229", "167518443950"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "140000", "rules": [{ "id": "us.federal.standard_deduction.dependent_limit" }, { "id": "us.federal.kiddie_tax" }] },
|
|
56592
|
+
{ "kind": "indexed", "id": "dependentStdDed.earnedIncomeAddOn", "label": "dependentStdDed.earnedIncomeAddOn ($250)", "statute": "\xA7 63(c)(5)(B), (c)(4)(B)(ii)", "index": "c-cpi-u", "comps": [{ "baseCents": "25000", "ratio": ["480023610229", "238587252475"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "50000", "rules": [{ "id": "us.federal.standard_deduction.dependent_limit" }] },
|
|
56593
|
+
{ "kind": "indexed", "id": "additionalStdDed.married", "label": "additionalStdDed.married (aged/blind)", "statute": "\xA7 63(f)(1),(2), (c)(4)(B)(i)", "index": "c-cpi-u", "comps": [{ "baseCents": "60000", "ratio": ["480023610229", "167518443950"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "170000", "rules": [{ "id": "us.federal.standard_deduction.additional", "path": "\\.parameters\\.amountMarried$" }] },
|
|
56594
|
+
{ "kind": "indexed", "id": "additionalStdDed.unmarried", "label": "additionalStdDed.unmarried", "statute": "\xA7 63(f)(3), (c)(4)(B)(i)", "index": "c-cpi-u", "comps": [{ "baseCents": "75000", "ratio": ["480023610229", "167518443950"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "210000", "rules": [{ "id": "us.federal.standard_deduction.additional", "path": "\\.parameters\\.amountUnmarried$" }] },
|
|
56595
|
+
{ "kind": "indexed", "id": "amt.exemption.joint", "label": "amt.exemption.joint (MFS = 50%)", "statute": "\xA7 55(d)(1)(A), (d)(4)(A)(i)(I), (d)(4)(B)", "index": "c-cpi-u", "comps": [{ "baseCents": "10940000", "ratio": ["8045684", "6082417"] }], "roundCents": "10000", "roundMode": "nearest", "on": "amount", "published2027": "14470000", "rules": [{ "id": "us.federal.amt.exemption", "path": "\\.parameters\\.exemptJoint$" }] },
|
|
56596
|
+
{ "kind": "indexed", "id": "amt.exemption.unmarried", "label": "amt.exemption.unmarried", "statute": "\xA7 55(d)(1)(B), (d)(4)(A)(i)(II), (d)(4)(B)", "index": "c-cpi-u", "comps": [{ "baseCents": "7030000", "ratio": ["8045684", "6082417"] }], "roundCents": "10000", "roundMode": "nearest", "on": "amount", "published2027": "9300000", "rules": [{ "id": "us.federal.amt.exemption", "path": "\\.parameters\\.exemptSingle$" }] },
|
|
56597
|
+
{ "kind": "indexed", "id": "amt.phaseoutThreshold.joint", "label": "amt.phaseoutThreshold.joint (single/MFS = 50%)", "statute": "\xA7 55(d)(2)(A), (d)(4)(A)(ii)(I), (d)(4)(B)(i)(II)(2)", "index": "c-cpi-u", "comps": [{ "baseCents": "100000000", "ratio": ["12068526", "11695585"] }], "roundCents": "10000", "roundMode": "nearest", "on": "amount", "published2027": "103190000", "rules": [{ "id": "us.federal.amt.exemption", "path": "\\.parameters\\.threshJoint$" }] },
|
|
56598
|
+
{ "kind": "indexed", "id": "amt.break28", "label": "amt.break28 (MFS = 50%)", "statute": "\xA7 55(b)(1)(A)(iii), (d)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "17500000", "ratio": ["960047220458", "665483785395"] }], "roundCents": "10000", "roundMode": "nearest", "on": "amount", "published2027": "25250000", "rules": [{ "id": "us.federal.amt.tentative_minimum_tax", "path": "\\.parameters\\.break28$" }] },
|
|
56599
|
+
{ "kind": "indexed", "id": "eitc.earnedIncomeAmount.0kids", "label": "eitc.earnedIncomeAmount.0kids", "statute": "\xA7 32(b)(2)(A), (j)(1)(B)(i), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "422000", "ratio": ["480023610229", "225996567225"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "896000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.eia0$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.eia0$" }] },
|
|
56600
|
+
{ "kind": "indexed", "id": "eitc.earnedIncomeAmount.1kid", "label": "eitc.earnedIncomeAmount.1kid", "statute": "\xA7 32(b)(2)(A), (j)(1)(B)(i), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "633000", "ratio": ["480023610229", "225996567225"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "1345000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.eia1$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.eia1$" }] },
|
|
56601
|
+
{ "kind": "indexed", "id": "eitc.earnedIncomeAmount.2_kids", "label": "eitc.earnedIncomeAmount.2+kids", "statute": "\xA7 32(b)(2)(A), (j)(1)(B)(i), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "889000", "ratio": ["480023610229", "225996567225"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "1888000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.eia[23]$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.eia[23]$" }] },
|
|
56602
|
+
{ "kind": "indexed", "id": "eitc.phaseoutThreshold.0kids.other", "label": "eitc.phaseoutThreshold.0kids.other", "statute": "\xA7 32(b)(2)(A), (j)(1)(B)(i), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "528000", "ratio": ["480023610229", "225996567225"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "1121000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.thresholdOther0$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.thresholdOther0$" }] },
|
|
56603
|
+
{ "kind": "indexed", "id": "eitc.phaseoutThreshold.kids.other", "label": "eitc.phaseoutThreshold.kids.other", "statute": "\xA7 32(b)(2)(A), (j)(1)(B)(i), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "1161000", "ratio": ["480023610229", "225996567225"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "2466000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.thresholdOtherKids$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.thresholdOtherKids$" }] },
|
|
56604
|
+
{ "kind": "indexed", "id": "eitc.phaseoutThreshold.0kids.mfj", "label": "eitc.phaseoutThreshold.0kids.mfj", "statute": "\xA7 32(b)(2)(A)+(B), (j)(1)(B)(i),(ii), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "528000", "ratio": ["480023610229", "225996567225"] }, { "baseCents": "500000", "ratio": ["480023610229", "319536632415"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "1873000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.thresholdMFJ0$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.thresholdMFJ0$" }] },
|
|
56605
|
+
{ "kind": "indexed", "id": "eitc.phaseoutThreshold.kids.mfj", "label": "eitc.phaseoutThreshold.kids.mfj", "statute": "\xA7 32(b)(2)(A)+(B), (j)(1)(B)(i),(ii), (j)(2)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "1161000", "ratio": ["480023610229", "225996567225"] }, { "baseCents": "500000", "ratio": ["480023610229", "319536632415"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "3217000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.thresholdMFJKids$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.thresholdMFJKids$" }] },
|
|
56606
|
+
{ "kind": "indexed", "id": "eitc.investmentIncomeLimit", "label": "eitc.investmentIncomeLimit", "statute": "\xA7 32(i)(1), (j)(1)(B)(iii), (j)(2)(B)", "index": "c-cpi-u", "comps": [{ "baseCents": "1000000", "ratio": ["24137052", "19115459"] }], "roundCents": "5000", "roundMode": "down", "on": "amount", "published2027": "1260000", "rules": [{ "id": "us.federal.eitc", "path": "\\.parameters\\.investmentLimit$" }, { "id": "us.federal.eitc_no_age_gate", "path": "\\.parameters\\.investmentLimit$" }] },
|
|
56607
|
+
{ "kind": "indexed", "id": "ctc.perChild", "label": "ctc.perChild", "statute": "\xA7 24(h)(2), (i)(2), (i)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "220000", "ratio": ["12068526", "11419045"] }], "roundCents": "10000", "roundMode": "down", "on": "increase", "published2027": "230000", "rules": [{ "id": "us.federal.ctc.tentative" }] },
|
|
56608
|
+
{ "kind": "indexed", "id": "actc.refundableCapPerChild", "label": "actc.refundableCapPerChild", "statute": "\xA7 24(h)(5), (i)(1), (i)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "140000", "ratio": ["8045684", "6082417"] }], "roundCents": "10000", "roundMode": "down", "on": "increase", "published2027": "180000", "rules": [{ "id": "us.federal.actc" }, { "id": "us.federal.actc.maximum" }] },
|
|
56609
|
+
{ "kind": "indexed", "id": "adoption.maxCredit", "label": "adoption.maxCredit (and special-needs amount)", "statute": "\xA7 23(a)(3), (b)(1), (h)(1),(2)", "index": "c-cpi-u", "comps": [{ "baseCents": "1000000", "ratio": ["480023610229", "263095457625"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "1825000", "rules": [{ "id": "us.federal.adoption.allowed" }] },
|
|
56610
|
+
{ "kind": "indexed", "id": "adoption.phaseoutStart", "label": "adoption.phaseoutStart", "statute": "\xA7 23(b)(2)(A)(i), (h)(1),(2)", "index": "c-cpi-u", "comps": [{ "baseCents": "15000000", "ratio": ["480023610229", "263095457625"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "27368000", "rules": [{ "id": "us.federal.adoption.allowed" }] },
|
|
56611
|
+
{ "kind": "indexed", "id": "adoption.refundableCap", "label": "adoption.refundableCap", "statute": "\xA7 23(a)(4), (h)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "500000", "ratio": ["12068526", "11419045"] }], "roundCents": "1000", "roundMode": "nearest", "on": "amount", "published2027": "528000", "rules": [{ "id": "us.federal.adoption.refundable" }] },
|
|
56612
|
+
{ "kind": "indexed", "id": "qbi.threshold.other", "label": "qbi.threshold.other (MFJ = 200%)", "statute": "\xA7 199A(e)(2)(A),(B); \xA7 1(f)(7)", "index": "c-cpi-u", "comps": [{ "baseCents": "15750000", "ratio": ["8045684", "6082417"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "20830000", "rules": [{ "id": "us.federal.qbi.threshold", "statuses": ["single", "hoh", "qss"] }] },
|
|
56613
|
+
{ "kind": "indexed", "id": "qbi.threshold.mfs", "label": "qbi.threshold.mfs", "statute": "\xA7 199A(e)(2); \xA7 1(f)(7)(B)", "index": "c-cpi-u", "comps": [{ "baseCents": "15750000", "ratio": ["8045684", "6082417"] }], "roundCents": "2500", "roundMode": "down", "on": "increase", "published2027": "20832500", "rules": [{ "id": "us.federal.qbi.threshold", "statuses": ["mfs"] }] },
|
|
56614
|
+
{ "kind": "indexed", "id": "qbi.minDeduction", "label": "qbi.minDeduction", "statute": "\xA7 199A(i)(1)(B), (i)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "40000", "ratio": ["12068526", "11695585"] }], "roundCents": "500", "roundMode": "nearest", "on": "increase", "published2027": "41500", "rules": [{ "id": "us.federal.qbi_deduction" }, { "id": "us.federal.estimated.annualized_installment_q1" }, { "id": "us.federal.estimated.annualized_installment_q2" }, { "id": "us.federal.estimated.annualized_installment_q3" }, { "id": "us.federal.estimated.annualized_installment_q4" }] },
|
|
56615
|
+
{ "kind": "indexed", "id": "qbi.minQbiFloor", "label": "qbi.minQbiFloor", "statute": "\xA7 199A(i)(2)(A), (i)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "100000", "ratio": ["12068526", "11695585"] }], "roundCents": "500", "roundMode": "nearest", "on": "increase", "published2027": "103000", "rules": [{ "id": "us.federal.qbi_deduction" }, { "id": "us.federal.estimated.annualized_installment_q1" }, { "id": "us.federal.estimated.annualized_installment_q2" }, { "id": "us.federal.estimated.annualized_installment_q3" }, { "id": "us.federal.estimated.annualized_installment_q4" }] },
|
|
56616
|
+
{ "kind": "indexed", "id": "studentLoan.phaseoutStart.other", "label": "studentLoan.phaseoutStart.other", "statute": "\xA7 221(b)(2)(B), (f)", "index": "c-cpi-u", "comps": [{ "baseCents": "5000000", "ratio": ["480023610229", "263095457625"] }], "roundCents": "500000", "roundMode": "down", "on": "amount", "published2027": "9000000", "rules": [{ "id": "us.federal.student_loan_interest_deduction", "path": "\\.parameters\\.threshold$" }] },
|
|
56617
|
+
{ "kind": "indexed", "id": "studentLoan.phaseoutStart.joint", "label": "studentLoan.phaseoutStart.joint", "statute": "\xA7 221(b)(2)(B), (f)", "index": "c-cpi-u", "comps": [{ "baseCents": "10000000", "ratio": ["480023610229", "263095457625"] }], "roundCents": "500000", "roundMode": "down", "on": "amount", "published2027": "18000000", "rules": [{ "id": "us.federal.student_loan_interest_deduction", "path": "\\.parameters\\.thresholdJoint$" }] },
|
|
56618
|
+
{ "kind": "indexed", "id": "educatorCap", "label": "educatorCap", "statute": "\xA7 62(a)(2)(D), (d)(3)", "index": "c-cpi-u", "comps": [{ "baseCents": "25000", "ratio": ["480023610229", "352566612255"] }], "roundCents": "5000", "roundMode": "nearest", "on": "increase", "published2027": "35000", "rules": [{ "id": "us.federal.above_the_line_adjustments" }] },
|
|
56619
|
+
{ "kind": "indexed", "id": "feie.exclusion", "label": "feie.exclusion", "statute": "\xA7 911(b)(2)(D)", "index": "c-cpi-u", "comps": [{ "baseCents": "8000000", "ratio": ["480023610229", "279675270875"] }], "roundCents": "10000", "roundMode": "down", "on": "increase", "published2027": "13730000", "rules": [{ "id": "us.federal.feie.exclusion" }, { "id": "us.federal.income_tax_before_credits.feie" }] },
|
|
56620
|
+
{ "kind": "indexed", "id": "qsbs.capNew", "label": "qsbs.capNew", "statute": "\xA7 1202(b)(4)(B), (b)(5)", "index": "c-cpi-u", "comps": [{ "baseCents": "1500000000", "ratio": ["12068526", "11695585"] }], "roundCents": "1000000", "roundMode": "nearest", "on": "increase", "published2027": "1548000000", "rules": [{ "id": "us.federal.qsbs_exclusion", "path": "\\.parameters\\.capNew$" }] },
|
|
56621
|
+
{ "kind": "indexed", "id": "section179.limit", "label": "section179.limit", "statute": "\xA7 179(b)(1), (b)(6)(A)(ii)(I), (b)(6)(B)", "index": "c-cpi-u", "comps": [{ "baseCents": "250000000", "ratio": ["12068526", "11419045"] }], "roundCents": "1000000", "roundMode": "nearest", "on": "increase", "published2027": "264000000", "rules": [{ "id": "us.federal.corp.section179_deduction" }, { "id": "us.federal.corp.section179_carryforward" }] },
|
|
56622
|
+
{ "kind": "indexed", "id": "section179.phaseoutThreshold", "label": "section179.phaseoutThreshold", "statute": "\xA7 179(b)(2), (b)(6)", "index": "c-cpi-u", "comps": [{ "baseCents": "400000000", "ratio": ["12068526", "11419045"] }], "roundCents": "1000000", "roundMode": "nearest", "on": "increase", "published2027": "423000000", "rules": [{ "id": "us.federal.corp.section179_deduction" }, { "id": "us.federal.corp.section179_carryforward" }] },
|
|
56623
|
+
{ "kind": "indexed", "id": "section179.suvLimit", "label": "section179.suvLimit", "statute": "\xA7 179(b)(5)(A), (b)(6)(A)(ii)(II)", "index": "c-cpi-u", "comps": [{ "baseCents": "2500000", "ratio": ["8045684", "6082417"] }], "roundCents": "10000", "roundMode": "nearest", "on": "increase", "published2027": "3310000", "rules": [] },
|
|
56624
|
+
{ "kind": "indexed", "id": "grossReceiptsTest", "label": "grossReceiptsTest", "statute": "\xA7 448(c)(1), (c)(4)", "index": "c-cpi-u", "comps": [{ "baseCents": "2500000000", "ratio": ["8045684", "6082417"] }], "roundCents": "100000000", "roundMode": "nearest", "on": "amount", "published2027": "3300000000", "rules": [{ "id": "us.federal.corp.interest_deduction" }] },
|
|
56625
|
+
{ "kind": "indexed", "id": "ebl.threshold", "label": "ebl.threshold (joint = 200%)", "statute": "\xA7 461(l)(3)(A)(ii)(II), (l)(3)(C)", "index": "c-cpi-u", "comps": [{ "baseCents": "25000000", "ratio": ["12068526", "11419045"] }], "roundCents": "100000", "roundMode": "nearest", "on": "amount", "published2027": "26400000", "rules": [{ "id": "us.federal.excess_business_loss_disallowed", "path": "\\.parameters\\.threshold$" }] },
|
|
56626
|
+
{ "kind": "indexed", "id": "qualifyingRelative.grossIncomeLimit", "label": "qualifyingRelative.grossIncomeLimit", "statute": "\xA7 152(d)(1)(B); \xA7 151(d)(1),(d)(4),(d)(5)(B); \xA7 1(f)(7)(A)", "index": "c-cpi-u", "comps": [{ "baseCents": "200000", "ratio": ["480023610229", "174449553850"] }], "roundCents": "5000", "roundMode": "down", "on": "increase", "published2027": "550000", "rules": [{ "id": "us.federal.dependent.qualifying_relative" }, { "id": "us.federal.dependent.qualifying_relative.multiple_support" }] },
|
|
56627
|
+
{ "kind": "indexed", "id": "hsa.limitSelf", "label": "hsa.limitSelf", "statute": "\xA7 223(b)(2), (g)(1)", "index": "c-cpi-u", "comps": [{ "baseCents": "225000", "ratio": ["472164898659", "236343367975"] }], "roundCents": "5000", "roundMode": "nearest", "on": "increase", "published2027": "450000", "rules": [{ "id": "us.federal.hsa_deduction", "path": "\\.parameters\\.limitSelf$" }] },
|
|
56628
|
+
{ "kind": "indexed", "id": "hsa.limitFamily", "label": "hsa.limitFamily", "statute": "\xA7 223(b)(2), (g)(1)", "index": "c-cpi-u", "comps": [{ "baseCents": "450000", "ratio": ["472164898659", "236343367975"] }], "roundCents": "5000", "roundMode": "nearest", "on": "increase", "published2027": "900000", "rules": [{ "id": "us.federal.hsa_deduction", "path": "\\.parameters\\.limitFamily$" }] },
|
|
56629
|
+
{ "kind": "indexed", "id": "ssWageBase", "label": "social security wage base", "statute": "\xA7 3121(a)(1), \xA7 1402(b)(1); Social Security Act \xA7 230(b)", "index": "awi", "comps": [{ "baseCents": "6060000", "ratio": ["7280033", "2293542"] }], "roundCents": "30000", "roundMode": "nearest", "on": "amount", "published2027": "19230000", "rules": [{ "id": "us.federal.employer.payroll_tax" }, { "id": "us.federal.se_tax.taxpayer" }, { "id": "us.federal.se_tax.spouse" }, { "id": "us.federal.estimated.annualized_installment_q4" }], "neverDecreases": true },
|
|
56630
|
+
{ "kind": "indexed", "id": "householdEmployeeThreshold", "label": "domestic employee coverage threshold", "statute": "\xA7 3121(x), (a)(7)(B); Social Security Act \xA7 215(a)(1)(B)(ii)", "index": "awi", "comps": [{ "baseCents": "100000", "ratio": ["7280033", "2313267"] }], "roundCents": "10000", "roundMode": "down", "on": "amount", "published2027": "310000", "rules": [{ "id": "us.federal.household_employment_taxes", "path": "\\.parameters\\.ficaThreshold$" }] }
|
|
56631
|
+
];
|
|
56632
|
+
CG = [
|
|
56633
|
+
"us.federal.income_tax_before_credits",
|
|
56634
|
+
"us.federal.income_tax_before_credits.tax_table",
|
|
56635
|
+
"us.federal.kiddie_tax",
|
|
56636
|
+
"us.federal.income_tax_before_credits.feie",
|
|
56637
|
+
"us.federal.estimated.annualized_installment_q1",
|
|
56638
|
+
"us.federal.estimated.annualized_installment_q2",
|
|
56639
|
+
"us.federal.estimated.annualized_installment_q3",
|
|
56640
|
+
"us.federal.estimated.annualized_installment_q4",
|
|
56641
|
+
"us.federal.amt.tentative_minimum_tax"
|
|
56642
|
+
];
|
|
56643
|
+
derived2 = (id2, label, statute, terms, published2027, rules, roundCents = "1", roundMode = "nearest") => ({
|
|
56644
|
+
kind: "derived",
|
|
56645
|
+
id: id2,
|
|
56646
|
+
label,
|
|
56647
|
+
statute,
|
|
56648
|
+
terms: terms.map(([param28, num, den]) => ({ param: param28, num: String(num), den: String(den) })),
|
|
56649
|
+
roundCents,
|
|
56650
|
+
roundMode,
|
|
56651
|
+
published2027,
|
|
56652
|
+
rules
|
|
56653
|
+
});
|
|
56654
|
+
eitc = (path) => ["us.federal.eitc", "us.federal.eitc_no_age_gate"].map((id2) => ({ id: id2, path }));
|
|
56655
|
+
PROJECTION_PARAMS.push(derived2("standardDeduction.joint", "standard deduction, joint (200% of single)", "\xA7 63(c)(2)(A)", [["standardDeduction.single", 2, 1]], "3320000", [{ id: "us.federal.standard_deduction.base_amount", statuses: ["mfj", "qss"] }]), derived2("capgains.single.zero", "0% capital gain bracket end, single/MFS (\xBD of joint)", "\xA7 1(j)(5)(B)(i)(III)", [["capgains.mfj.zero", 1, 2]], "5105000", CG.map((id2) => ({ id: id2, statuses: ["single", "mfs"] }))), derived2("capgains.mfs.fifteen", "15% capital gain bracket end, MFS (\xBD of joint)", "\xA7 1(j)(5)(B)(ii)(I)", [["capgains.mfj.fifteen", 1, 2]], "31680000", CG.map((id2) => ({ id: id2, statuses: ["mfs"] }))), derived2("amt.exemption.mfs", "AMT exemption, MFS (50% of joint)", "\xA7 55(d)(1)(C)", [["amt.exemption.joint", 1, 2]], "7235000", [
|
|
56656
|
+
{ id: "us.federal.amt.exemption", path: "\\.parameters\\.exemptMfs$" },
|
|
56657
|
+
{ id: "us.federal.amt.amti", path: "\\.parameters\\.exemptMfs$" }
|
|
56658
|
+
]), derived2("amt.phaseoutThreshold.unmarried", "AMT phase-out threshold, single and MFS (50% of joint)", "\xA7 55(d)(2)", [["amt.phaseoutThreshold.joint", 1, 2]], "51595000", [{ id: "us.federal.amt.exemption", path: "\\.parameters\\.thresh(Single|Mfs)$" }]), derived2("amt.mfsZeroAt", "AMTI at which the MFS exemption is fully phased out (threshold + 2 \xD7 exemption)", "\xA7 55(d)(1)(C), (d)(2)", [["amt.phaseoutThreshold.joint", 1, 2], ["amt.exemption.joint", 1, 1]], "66065000", [{ id: "us.federal.amt.amti", path: "\\.parameters\\.mfsZeroAt$" }]), derived2("amt.break28.mfs", "AMT 28% break, MFS (50%)", "\xA7 55(b)(1)(A)(iii)", [["amt.break28", 1, 2]], "12625000", [{ id: "us.federal.amt.tentative_minimum_tax", path: "\\.parameters\\.break28Mfs$" }]), derived2("amt.sub28", "2% of the AMT 28% break", "\xA7 55(b)(1)(A)(i)(II)", [["amt.break28", 2, 100]], "505000", [{ id: "us.federal.amt.tentative_minimum_tax", path: "\\.parameters\\.sub28$" }]), derived2("amt.sub28.mfs", "2% of the MFS AMT 28% break", "\xA7 55(b)(1)(A)(i)(II)", [["amt.break28", 1, 100]], "252500", [{ id: "us.federal.amt.tentative_minimum_tax", path: "\\.parameters\\.sub28Mfs$" }]), derived2("eitc.max0", "EITC maximum, no children (7.65% \xD7 earned income amount)", "\xA7 32(b)(1)", [["eitc.earnedIncomeAmount.0kids", 765, 1e4]], "68500", eitc("\\.parameters\\.max0$"), "100"), derived2("eitc.max1", "EITC maximum, one child (34%)", "\xA7 32(b)(1)", [["eitc.earnedIncomeAmount.1kid", 34, 100]], "457300", eitc("\\.parameters\\.max1$"), "100"), derived2("eitc.max2", "EITC maximum, two children (40%)", "\xA7 32(b)(1)", [["eitc.earnedIncomeAmount.2_kids", 40, 100]], "755200", eitc("\\.parameters\\.max2$"), "100"), derived2("eitc.max3", "EITC maximum, three or more children (45%)", "\xA7 32(b)(1)", [["eitc.earnedIncomeAmount.2_kids", 45, 100]], "849600", eitc("\\.parameters\\.max3$"), "100"), derived2("eitc.completedOther0", "EITC completed phase-out, no children (threshold + maximum \xF7 7.65%)", "\xA7 32(a)(2), (b)", [["eitc.phaseoutThreshold.0kids.other", 1, 1], ["eitc.max0", 1e4, 765]], "2016400", eitc("\\.parameters\\.completedOther0$"), "100"), derived2("eitc.completedMFJ0", "EITC completed phase-out, no children, joint", "\xA7 32(a)(2), (b)", [["eitc.phaseoutThreshold.0kids.mfj", 1, 1], ["eitc.max0", 1e4, 765]], "2768400", eitc("\\.parameters\\.completedMFJ0$"), "100"), derived2("kiddie.threshold", "kiddie tax threshold (2 \xD7 the \xA7 63(c)(5)(A) amount)", "\xA7 1(g)(4)(A)(ii)", [["dependentStdDed.floor", 2, 1]], "280000", [{ id: "us.federal.kiddie.net_unearned_income" }, { id: "us.federal.kiddie_tax" }]), derived2("qbi.threshold.joint", "QBI threshold, joint (200%)", "\xA7 199A(e)(2)(A)", [["qbi.threshold.other", 2, 1]], "41660000", [{ id: "us.federal.qbi.threshold", statuses: ["mfj"] }]), derived2("ebl.threshold.joint", "\xA7 461(l) threshold, joint (200%)", "\xA7 461(l)(3)(A)(ii)", [["ebl.threshold", 2, 1]], "52800000", [{ id: "us.federal.excess_business_loss_disallowed", path: "\\.parameters\\.thresholdJoint$" }]), derived2("ssWageBase.q1", "Schedule AI line 29 prorated limit, column (a) (\xBC of the wage base)", "Form 2210 Schedule AI line 29", [["ssWageBase", 1, 4]], "4807500", [{ id: "us.federal.estimated.annualized_installment_q1" }]), derived2("ssWageBase.q2", "Schedule AI line 29 prorated limit, column (b) (5/12)", "Form 2210 Schedule AI line 29", [["ssWageBase", 5, 12]], "8012500", [{ id: "us.federal.estimated.annualized_installment_q2" }]), derived2("ssWageBase.q3", "Schedule AI line 29 prorated limit, column (c) (2/3)", "Form 2210 Schedule AI line 29", [["ssWageBase", 2, 3]], "12820000", [{ id: "us.federal.estimated.annualized_installment_q3" }]));
|
|
56659
|
+
pctSteps = (start, from, year, lastYear) => {
|
|
56660
|
+
let v = start;
|
|
56661
|
+
for (let y = from + 1; y <= Math.min(year, lastYear); y++)
|
|
56662
|
+
v = (v * 101n * 2n + 100n) / 200n;
|
|
56663
|
+
return v;
|
|
56664
|
+
};
|
|
56665
|
+
PROJECTION_PARAMS.push({
|
|
56666
|
+
kind: "law",
|
|
56667
|
+
id: "salt.cap",
|
|
56668
|
+
label: "SALT limitation",
|
|
56669
|
+
statute: "\xA7 164(b)(7)(A)(ii), (b)(6)(B) (OBBBA \xA7 70120)",
|
|
56670
|
+
published2027: "4080400",
|
|
56671
|
+
byYear: (y) => y >= 2030 ? "1000000" : pctSteps(4080400n, 2027, y, 2029).toString(),
|
|
56672
|
+
rules: [{ id: "us.federal.salt_deduction", path: "\\.parameters\\.cap$" }]
|
|
56673
|
+
}, {
|
|
56674
|
+
kind: "law",
|
|
56675
|
+
id: "salt.threshold",
|
|
56676
|
+
label: "SALT phase-down threshold",
|
|
56677
|
+
statute: "\xA7 164(b)(7)(B)",
|
|
56678
|
+
published2027: "51005000",
|
|
56679
|
+
byYear: (y) => pctSteps(51005000n, 2027, y, 2029).toString(),
|
|
56680
|
+
rules: [{ id: "us.federal.salt_deduction", path: "\\.parameters\\.threshold$" }]
|
|
56681
|
+
}, {
|
|
56682
|
+
kind: "law",
|
|
56683
|
+
id: "salt.threshold.mfs",
|
|
56684
|
+
label: "SALT phase-down threshold, MFS (half)",
|
|
56685
|
+
statute: "\xA7 164(b)(7)(B)",
|
|
56686
|
+
published2027: "25502500",
|
|
56687
|
+
byYear: (y) => ((pctSteps(51005000n, 2027, y, 2029) + 1n) / 2n).toString(),
|
|
56688
|
+
rules: [{ id: "us.federal.salt_deduction", path: "\\.parameters\\.thresholdMfs$" }]
|
|
56689
|
+
});
|
|
56690
|
+
TAX_TABLE = ["250", "500", "1000", "1250", "1500", "2000", "2500", "5000", "300000", "10000000"];
|
|
56691
|
+
FIXED_LITERALS = {
|
|
56692
|
+
"us.federal.income_tax_before_credits": TAX_TABLE,
|
|
56693
|
+
"us.federal.income_tax_before_credits.tax_table": TAX_TABLE,
|
|
56694
|
+
"us.federal.income_tax_before_credits.feie": TAX_TABLE,
|
|
56695
|
+
"us.federal.kiddie_tax": TAX_TABLE,
|
|
56696
|
+
// Schedule AI: the Tax Table, and the ½-SE deduction's annualization factor written as den / (2 × num)
|
|
56697
|
+
"us.federal.estimated.annualized_installment_q1": [...TAX_TABLE, "1", "8"],
|
|
56698
|
+
"us.federal.estimated.annualized_installment_q2": [...TAX_TABLE, "5", "24"],
|
|
56699
|
+
"us.federal.estimated.annualized_installment_q3": [...TAX_TABLE, "2", "6"],
|
|
56700
|
+
"us.federal.estimated.annualized_installment_q4": [...TAX_TABLE, "1", "2"],
|
|
56701
|
+
"us.federal.qsbs_exclusion": ["1000000000"],
|
|
56702
|
+
// § 1202(b)(1)(A) $10,000,000 (only the § 1202(b)(4) $15M is indexed)
|
|
56703
|
+
"us.federal.salt_deduction": ["1000000"],
|
|
56704
|
+
// § 164(b)(7)(B) $10,000 floor
|
|
56705
|
+
"us.federal.ctc.tentative": ["50000"],
|
|
56706
|
+
// § 24(h)(4) $500 other-dependent credit, not indexed
|
|
56707
|
+
"us.federal.actc": ["250000"],
|
|
56708
|
+
// § 24(d)(1)(B)(i) $2,500 earned income floor
|
|
56709
|
+
"us.federal.actc.maximum": ["250000"],
|
|
56710
|
+
// § 21 as amended by OBBBA § 70405: $3,000/$6,000, 50%→35%→20%, $15,000 / $75,000 / $150,000 steps — none indexed
|
|
56711
|
+
"us.federal.cdcc.tentative": ["1", "20", "35", "50", "100", "300000", "600000", "1500000", "7500000", "15000000"],
|
|
56712
|
+
"us.federal.adoption.allowed": ["4000000"],
|
|
56713
|
+
// § 23(b)(2)(A)(ii) $40,000 phase-out range
|
|
56714
|
+
"us.federal.fiduciary.income_tax": ["10000", "30000", "60000"],
|
|
56715
|
+
// § 642(b) $600 / $300 / $100 exemptions
|
|
56716
|
+
"us.federal.household_employment_taxes": ["700000"],
|
|
56717
|
+
// § 3306(b)(1) $7,000 FUTA wage base
|
|
56718
|
+
"us.federal.employer.payroll_tax": ["700000"],
|
|
56719
|
+
"us.federal.eitc": ["2500", "5000"],
|
|
56720
|
+
// the printed EIC Table's $25 / $50 rows
|
|
56721
|
+
"us.federal.eitc_no_age_gate": ["2500", "5000"],
|
|
56722
|
+
"us.federal.se_tax.taxpayer": ["40000"],
|
|
56723
|
+
// § 6017 / § 1402(b) $400
|
|
56724
|
+
"us.federal.se_tax.spouse": ["40000"],
|
|
56725
|
+
"us.federal.hsa_deduction": ["100000"],
|
|
56726
|
+
// § 223(b)(3)(B) $1,000 catch-up
|
|
56727
|
+
"us.federal.student_loan_interest_deduction": ["250000", "1500000", "3000000"],
|
|
56728
|
+
// § 221(b)(1) $2,500; § 221(b)(2)(B) $15,000 / $30,000 ranges
|
|
56729
|
+
"us.federal.qbi.phase_in_range": ["7500000", "15000000"]
|
|
56730
|
+
// § 199A(b)(3)(B) as amended by OBBBA § 70105: $75,000 / $150,000
|
|
56731
|
+
};
|
|
56732
|
+
gt011 = (factId) => ({ kind: "cmp", op: "gt", left: { kind: "fact", factId }, right: { kind: "money", cents: "0" } });
|
|
56733
|
+
NOT_PROJECTED = {
|
|
56734
|
+
"us.federal.ptc": {
|
|
56735
|
+
usedWhen: { kind: "or", args: [gt011("marketplacePremiumsPaid"), gt011("advancePTC"), gt011("slcspAnnualPremium")] },
|
|
56736
|
+
reason: "the premium tax credit's applicable percentages are indexed to premium growth over income growth (\xA7 36B(b)(3)(A)(ii)) and its poverty line to HHS guidelines, neither of which is a price index the projection can carry forward"
|
|
56737
|
+
}
|
|
56738
|
+
};
|
|
56739
|
+
}
|
|
56740
|
+
});
|
|
56741
|
+
|
|
56742
|
+
// ../corpus-us-federal/dist/projection.js
|
|
56743
|
+
function percentToRational(p, label) {
|
|
56744
|
+
const m = /^(-?)(\d{1,2})(?:\.(\d{1,4}))?$/.exec(p.trim());
|
|
56745
|
+
if (!m)
|
|
56746
|
+
throw new Error(`${label}: expected a percent like 2.5 (at most 4 decimals), got "${p}"`);
|
|
56747
|
+
const frac = m[3] ?? "";
|
|
56748
|
+
const den = 100n * 10n ** BigInt(frac.length);
|
|
56749
|
+
const num = BigInt(m[2] + frac) * (m[1] ? -1n : 1n);
|
|
56750
|
+
if (num * 100n < -10n * den || num * 100n > 25n * den)
|
|
56751
|
+
throw new Error(`${label}: ${p}% is outside -10% to 25%`);
|
|
56752
|
+
return { num, den };
|
|
56753
|
+
}
|
|
56754
|
+
function roundTo(x, multiple, mode) {
|
|
56755
|
+
if (x.n < 0n)
|
|
56756
|
+
throw new Error("projection: negative amount");
|
|
56757
|
+
const d3 = x.d * multiple;
|
|
56758
|
+
const q = mode === "down" ? x.n / d3 : (2n * x.n + d3) / (2n * d3);
|
|
56759
|
+
return q * multiple;
|
|
56760
|
+
}
|
|
56761
|
+
function projectedValue(p, year, opts) {
|
|
56762
|
+
if (p.kind === "law")
|
|
56763
|
+
return BigInt(p.byYear(year));
|
|
56764
|
+
if (p.kind === "derived") {
|
|
56765
|
+
let sum = { n: 0n, d: 1n };
|
|
56766
|
+
for (const t of p.terms) {
|
|
56767
|
+
const q = PARAM_BY_ID.get(t.param);
|
|
56768
|
+
if (!q)
|
|
56769
|
+
throw new Error(`projection spec: unknown parameter ${t.param}`);
|
|
56770
|
+
const v2 = projectedValue(q, year, opts);
|
|
56771
|
+
const term = { n: v2 * BigInt(t.num), d: BigInt(t.den) };
|
|
56772
|
+
sum = { n: sum.n * term.d + term.n * sum.d, d: sum.d * term.d };
|
|
56773
|
+
}
|
|
56774
|
+
return roundTo(sum, BigInt(p.roundCents), p.roundMode);
|
|
56775
|
+
}
|
|
56776
|
+
const growth = percentToRational(p.index === "awi" ? opts.wageGrowthPercent ?? opts.inflationPercent : opts.inflationPercent, p.index === "awi" ? "wageGrowthPercent" : "inflationPercent");
|
|
56777
|
+
const g = { n: growth.den + growth.num, d: growth.den };
|
|
56778
|
+
const at = (y) => {
|
|
56779
|
+
const k = y - LAST_PUBLISHED_YEAR;
|
|
56780
|
+
let raw = { n: 0n, d: 1n };
|
|
56781
|
+
let base = 0n;
|
|
56782
|
+
for (const c2 of p.comps) {
|
|
56783
|
+
const term = mul({ n: BigInt(c2.baseCents), d: 1n }, mul({ n: BigInt(c2.ratio[0]), d: BigInt(c2.ratio[1]) }, pow(g, k)));
|
|
56784
|
+
raw = { n: raw.n * term.d + term.n * raw.d, d: raw.d * term.d };
|
|
56785
|
+
base += BigInt(c2.baseCents);
|
|
56786
|
+
}
|
|
56787
|
+
if (raw.n < base * raw.d)
|
|
56788
|
+
raw = { n: base, d: 1n };
|
|
56789
|
+
if (p.on === "amount")
|
|
56790
|
+
return roundTo(raw, BigInt(p.roundCents), p.roundMode);
|
|
56791
|
+
return base + roundTo({ n: raw.n - base * raw.d, d: raw.d }, BigInt(p.roundCents), p.roundMode);
|
|
56792
|
+
};
|
|
56793
|
+
let v = at(year);
|
|
56794
|
+
if (p.neverDecreases) {
|
|
56795
|
+
for (let y = LAST_PUBLISHED_YEAR; y < year; y++)
|
|
56796
|
+
if (at(y) > v)
|
|
56797
|
+
v = at(y);
|
|
56798
|
+
}
|
|
56799
|
+
return v;
|
|
56800
|
+
}
|
|
56801
|
+
function moneySlots(rule2) {
|
|
56802
|
+
const out = [];
|
|
56803
|
+
const walk = (x, path) => {
|
|
56804
|
+
if (Array.isArray(x))
|
|
56805
|
+
return x.forEach((v, i) => walk(v, `${path}[${i}]`));
|
|
56806
|
+
if (!x || typeof x !== "object")
|
|
56807
|
+
return;
|
|
56808
|
+
const o = x;
|
|
56809
|
+
if (o.kind === "money" && typeof o.cents === "string")
|
|
56810
|
+
out.push({ path, get: () => o.cents, set: (v) => o.cents = v });
|
|
56811
|
+
if (o.kind === "brackets" && Array.isArray(o.table))
|
|
56812
|
+
o.table.forEach((row2, i) => out.push({ path: `${path}.table[${i}]`, get: () => row2.threshold, set: (v) => row2.threshold = v }));
|
|
56813
|
+
if (o.type === "money" && typeof o.value === "string" && !("kind" in o))
|
|
56814
|
+
out.push({ path, get: () => o.value, set: (v) => o.value = v });
|
|
56815
|
+
for (const [k, v] of Object.entries(o)) {
|
|
56816
|
+
if (k === "citation")
|
|
56817
|
+
continue;
|
|
56818
|
+
if (k === "cases" && Array.isArray(v))
|
|
56819
|
+
v.forEach((c2, i) => walk(c2, `${path}.cases[${c2.when ?? i}]`));
|
|
56820
|
+
else
|
|
56821
|
+
walk(v, `${path}.${k}`);
|
|
56822
|
+
}
|
|
56823
|
+
};
|
|
56824
|
+
walk({ formula: rule2.formula, applicability: rule2.applicability, parameters: rule2.parameters }, "");
|
|
56825
|
+
return out;
|
|
56826
|
+
}
|
|
56827
|
+
function rulesEndingWith2027(base) {
|
|
56828
|
+
return base.rules.filter((r) => r.jurisdiction === "us.federal" && inWindow(r, `${LAST_PUBLISHED_YEAR}-06-30`) && r.effectiveTo === `${LAST_PUBLISHED_YEAR + 1}-01-01`);
|
|
56829
|
+
}
|
|
56830
|
+
function candidates(ruleId, cents2, path) {
|
|
56831
|
+
const cases = [...path.matchAll(/cases\[([^\]]+)\]/g)];
|
|
56832
|
+
const status = cases.length ? cases[cases.length - 1][1] : void 0;
|
|
56833
|
+
return PROJECTION_PARAMS.filter((p) => p.published2027 === cents2 && p.rules.some((r) => r.id === ruleId && (r.statuses === void 0 || status !== void 0 && r.statuses.includes(status)) && (r.path === void 0 || new RegExp(r.path).test(path))));
|
|
56834
|
+
}
|
|
56835
|
+
function classifyLiterals(base) {
|
|
56836
|
+
const out = [];
|
|
56837
|
+
for (const r of rulesEndingWith2027(base)) {
|
|
56838
|
+
if (NOT_PROJECTED[r.id])
|
|
56839
|
+
continue;
|
|
56840
|
+
for (const s of moneySlots(r)) {
|
|
56841
|
+
const cents2 = s.get();
|
|
56842
|
+
const c2 = candidates(r.id, cents2, s.path);
|
|
56843
|
+
const fixed = FIXED_LITERALS[r.id]?.includes(cents2) || cents2 === "0";
|
|
56844
|
+
if (c2.length === 1)
|
|
56845
|
+
out.push({ ruleId: r.id, path: s.path, cents: cents2, param: c2[0].id });
|
|
56846
|
+
else if (c2.length > 1)
|
|
56847
|
+
out.push({ ruleId: r.id, path: s.path, cents: cents2, error: `ambiguous: ${c2.map((p) => p.id).join(", ")}` });
|
|
56848
|
+
else if (fixed)
|
|
56849
|
+
out.push({ ruleId: r.id, path: s.path, cents: cents2, fixed: true });
|
|
56850
|
+
else
|
|
56851
|
+
out.push({ ruleId: r.id, path: s.path, cents: cents2, error: "neither an indexed parameter nor a declared fixed amount" });
|
|
56852
|
+
}
|
|
56853
|
+
}
|
|
56854
|
+
return out;
|
|
56855
|
+
}
|
|
56856
|
+
function projectCorpusInput(base, opts) {
|
|
56857
|
+
const { year } = opts;
|
|
56858
|
+
if (!Number.isInteger(year) || year <= LAST_PUBLISHED_YEAR || year > PROJECTION_HORIZON)
|
|
56859
|
+
throw new Error(`projection covers tax years ${LAST_PUBLISHED_YEAR + 1}\u2013${PROJECTION_HORIZON}; ${year} is published law or beyond the horizon`);
|
|
56860
|
+
const r = percentToRational(opts.inflationPercent, "inflationPercent");
|
|
56861
|
+
const w = opts.wageGrowthPercent === void 0 ? r : percentToRational(opts.wageGrowthPercent, "wageGrowthPercent");
|
|
56862
|
+
const fmtPct = (x) => {
|
|
56863
|
+
const scale = x.den / 100n;
|
|
56864
|
+
const neg3 = x.num < 0n;
|
|
56865
|
+
const a = neg3 ? -x.num : x.num;
|
|
56866
|
+
const digits = scale.toString().length - 1;
|
|
56867
|
+
const whole = (a / scale).toString();
|
|
56868
|
+
const frac = digits ? (a % scale).toString().padStart(digits, "0").replace(/0+$/, "") : "";
|
|
56869
|
+
return `${neg3 ? "-" : ""}${whole}${frac ? "." + frac : ""}`;
|
|
56870
|
+
};
|
|
56871
|
+
const tag = `projected.${year}.cpi-${fmtPct(r)}.awi-${fmtPct(w)}`;
|
|
56872
|
+
const from = `${year}-01-01`;
|
|
56873
|
+
const to = `${year + 1}-01-01`;
|
|
56874
|
+
const errors = classifyLiterals(base).filter((x) => x.error);
|
|
56875
|
+
if (errors.length)
|
|
56876
|
+
throw new Error(`projection spec is incomplete: ${errors.slice(0, 5).map((e) => `${e.ruleId} ${e.path} ${e.cents}: ${e.error}`).join("; ")}`);
|
|
56877
|
+
const added = [];
|
|
56878
|
+
for (const rule2 of rulesEndingWith2027(base)) {
|
|
56879
|
+
const clone2 = structuredClone(rule2);
|
|
56880
|
+
clone2.version = rule2.version + 1e3 * (year - LAST_PUBLISHED_YEAR);
|
|
56881
|
+
clone2.effectiveFrom = from;
|
|
56882
|
+
clone2.effectiveTo = to;
|
|
56883
|
+
const changed = [];
|
|
56884
|
+
if (NOT_PROJECTED[rule2.id]) {
|
|
56885
|
+
const np = NOT_PROJECTED[rule2.id];
|
|
56886
|
+
clone2.formula = { kind: "if", cond: np.usedWhen, then: { kind: "unsupported", reason: `${year} is a projection: ${np.reason}` }, else: clone2.formula };
|
|
56887
|
+
changed.push(`refuses when used \u2014 ${np.reason}`);
|
|
56888
|
+
} else {
|
|
56889
|
+
for (const s of moneySlots(clone2)) {
|
|
56890
|
+
const c2 = candidates(rule2.id, s.get(), s.path);
|
|
56891
|
+
if (c2.length !== 1)
|
|
56892
|
+
continue;
|
|
56893
|
+
const v = projectedValue(c2[0], year, opts).toString();
|
|
56894
|
+
if (v !== s.get())
|
|
56895
|
+
changed.push(`${c2[0].label}: ${s.get()} \u2192 ${v}`);
|
|
56896
|
+
s.set(v);
|
|
56897
|
+
}
|
|
56898
|
+
}
|
|
56899
|
+
clone2.title = `${rule2.title} \u2014 PROJECTED ${year}`;
|
|
56900
|
+
clone2.citation = {
|
|
56901
|
+
...rule2.citation,
|
|
56902
|
+
source: `PROJECTION, NOT PUBLISHED LAW (${year}; C-CPI-U +${fmtPct(r)}%/yr, average wage index +${fmtPct(w)}%/yr assumed after the indexes used for 2027): ${rule2.citation.source}`,
|
|
56903
|
+
excerpt: `${rule2.citation.excerpt} [Projected from 2027 by each amount's statutory indexing formula at the assumed rates. Projected amounts: ${changed.length ? [...new Set(changed)].join("; ") : "none in this rule"}.]`
|
|
56904
|
+
};
|
|
56905
|
+
added.push(clone2);
|
|
56906
|
+
}
|
|
56907
|
+
if (year > 2028) {
|
|
56908
|
+
for (const [id2, cite] of Object.entries(SUNSET_AFTER_2028)) {
|
|
56909
|
+
const last = base.rules.filter((r2) => r2.id === id2).sort((a, b) => b.version - a.version)[0];
|
|
56910
|
+
if (!last)
|
|
56911
|
+
continue;
|
|
56912
|
+
added.push({
|
|
56913
|
+
id: id2,
|
|
56914
|
+
version: last.version + 1e3 * (year - LAST_PUBLISHED_YEAR),
|
|
56915
|
+
jurisdiction: last.jurisdiction,
|
|
56916
|
+
title: `${last.title} \u2014 ended after 2028`,
|
|
56917
|
+
citation: { source: cite, section: last.citation.section, url: last.citation.url, excerpt: `The provision does not apply to ${year}: ${cite}.` },
|
|
56918
|
+
effectiveFrom: from,
|
|
56919
|
+
effectiveTo: to,
|
|
56920
|
+
output: last.output,
|
|
56921
|
+
formula: last.output.type === "bool" ? { kind: "bool", value: false } : { kind: "money", cents: "0" }
|
|
56922
|
+
});
|
|
56923
|
+
}
|
|
56924
|
+
}
|
|
56925
|
+
const covered = new Set([...base.rules.filter((r2) => inWindow(r2, `${year}-06-30`)), ...added].map((r2) => r2.id));
|
|
56926
|
+
const missing = [...new Set(base.rules.filter((r2) => r2.jurisdiction === "us.federal" && inWindow(r2, `${LAST_PUBLISHED_YEAR}-06-30`)).map((r2) => r2.id))].filter((id2) => !covered.has(id2));
|
|
56927
|
+
if (missing.length)
|
|
56928
|
+
throw new Error(`projection has no ${year} version of: ${missing.join(", ")}`);
|
|
56929
|
+
return { name: base.name, version: `${base.version}+${tag}`, rules: [...base.rules, ...added], facts: base.facts };
|
|
56930
|
+
}
|
|
56931
|
+
function getProjectedCorpus(base, opts) {
|
|
56932
|
+
const key = JSON.stringify([base.version, opts.year, opts.inflationPercent, opts.wageGrowthPercent ?? null]);
|
|
56933
|
+
let c2 = cache.get(key);
|
|
56934
|
+
if (!c2) {
|
|
56935
|
+
c2 = loadCorpus(projectCorpusInput(base, opts));
|
|
56936
|
+
if (cache.size > 32)
|
|
56937
|
+
cache.clear();
|
|
56938
|
+
cache.set(key, c2);
|
|
56939
|
+
}
|
|
56940
|
+
return c2;
|
|
56941
|
+
}
|
|
56942
|
+
function projectionFromVersion(version2) {
|
|
56943
|
+
const m = /\+projected\.(\d{4})\.cpi-(-?[\d.]+)\.awi-(-?[\d.]+)$/.exec(version2);
|
|
56944
|
+
return m ? { year: Number(m[1]), inflationPercent: m[2], wageGrowthPercent: m[3] } : null;
|
|
56945
|
+
}
|
|
56946
|
+
var LAST_PUBLISHED_YEAR, PROJECTION_HORIZON, mul, pow, PARAM_BY_ID, inWindow, SUNSET_AFTER_2028, cache;
|
|
56947
|
+
var init_projection = __esm({
|
|
56948
|
+
"../corpus-us-federal/dist/projection.js"() {
|
|
56949
|
+
"use strict";
|
|
56950
|
+
init_dist();
|
|
56951
|
+
init_projection_spec();
|
|
56952
|
+
LAST_PUBLISHED_YEAR = 2027;
|
|
56953
|
+
PROJECTION_HORIZON = 2035;
|
|
56954
|
+
mul = (a, b) => ({ n: a.n * b.n, d: a.d * b.d });
|
|
56955
|
+
pow = (a, k) => {
|
|
56956
|
+
let r = { n: 1n, d: 1n };
|
|
56957
|
+
for (let i = 0; i < k; i++)
|
|
56958
|
+
r = mul(r, a);
|
|
56959
|
+
return r;
|
|
56960
|
+
};
|
|
56961
|
+
PARAM_BY_ID = new Map(PROJECTION_PARAMS.map((p) => [p.id, p]));
|
|
56962
|
+
inWindow = (r, d3) => r.effectiveFrom <= d3 && (r.effectiveTo === void 0 || d3 < r.effectiveTo);
|
|
56963
|
+
SUNSET_AFTER_2028 = {
|
|
56964
|
+
"us.federal.tips_deduction": "26 U.S.C. \xA7 224(h) (OBBBA \xA7 70201): no deduction for taxable years beginning after December 31, 2028",
|
|
56965
|
+
"us.federal.eligible.tips_deduction": "26 U.S.C. \xA7 224(h) (OBBBA \xA7 70201): no deduction for taxable years beginning after December 31, 2028",
|
|
56966
|
+
"us.federal.eligible.tips_occupation": "26 U.S.C. \xA7 224(h) (OBBBA \xA7 70201): no deduction for taxable years beginning after December 31, 2028",
|
|
56967
|
+
"us.federal.overtime_deduction": "26 U.S.C. \xA7 225(e) (OBBBA \xA7 70202): no deduction for taxable years beginning after December 31, 2028",
|
|
56968
|
+
"us.federal.car_loan_interest_deduction": "26 U.S.C. \xA7 163(h)(4)(D) (OBBBA \xA7 70203): applies only to taxable years beginning before January 1, 2029",
|
|
56969
|
+
"us.federal.senior_deduction": "26 U.S.C. \xA7 151(f)(4) (OBBBA \xA7 70103): applies only to taxable years beginning before January 1, 2029",
|
|
56970
|
+
"us.federal.senior_deduction.magi_threshold": "26 U.S.C. \xA7 151(f)(4) (OBBBA \xA7 70103): applies only to taxable years beginning before January 1, 2029"
|
|
56971
|
+
};
|
|
56972
|
+
cache = /* @__PURE__ */ new Map();
|
|
56973
|
+
}
|
|
56974
|
+
});
|
|
56975
|
+
|
|
56549
56976
|
// ../corpus-us-federal/dist/extend.js
|
|
56550
56977
|
var init_extend = __esm({
|
|
56551
56978
|
"../corpus-us-federal/dist/extend.js"() {
|
|
@@ -56568,6 +56995,13 @@ function getCorpus() {
|
|
|
56568
56995
|
cached2 = loadCorpus(corpusInput);
|
|
56569
56996
|
return cached2;
|
|
56570
56997
|
}
|
|
56998
|
+
function getProjectedFederalCorpus(opts) {
|
|
56999
|
+
return getProjectedCorpus(corpusInput, opts);
|
|
57000
|
+
}
|
|
57001
|
+
function corpusForVersion(version2) {
|
|
57002
|
+
const p = projectionFromVersion(version2);
|
|
57003
|
+
return p ? getProjectedFederalCorpus(p) : getCorpus();
|
|
57004
|
+
}
|
|
56571
57005
|
var corpusInput, cached2, DEFAULT_TARGET;
|
|
56572
57006
|
var init_dist2 = __esm({
|
|
56573
57007
|
"../corpus-us-federal/dist/index.js"() {
|
|
@@ -56620,13 +57054,15 @@ var init_dist2 = __esm({
|
|
|
56620
57054
|
init_standard_deduction();
|
|
56621
57055
|
init_tips_eligibility();
|
|
56622
57056
|
init_tips_overtime();
|
|
57057
|
+
init_projection();
|
|
56623
57058
|
init_facts();
|
|
56624
57059
|
init_extend();
|
|
56625
57060
|
init_staleness();
|
|
56626
57061
|
init_occupations();
|
|
57062
|
+
init_projection();
|
|
56627
57063
|
corpusInput = {
|
|
56628
57064
|
name: "@invaro/opentax-corpus-us-federal",
|
|
56629
|
-
version: "0.
|
|
57065
|
+
version: "0.46.0",
|
|
56630
57066
|
rules: [
|
|
56631
57067
|
...corporateRules,
|
|
56632
57068
|
...corporate1120Rules,
|
|
@@ -60274,26 +60710,26 @@ function composeAR(input2, evalStateTax, notes) {
|
|
|
60274
60710
|
regular.notes.push(`AR line 26: Regular Income Tax Table kept \u2014 tax ${fmtD(regular.tax)} (net ${fmtD(regular.netTax)}) vs ${fmtD(lowOk.tax)} (net ${fmtD(lowOk.netTax)}) on the Low Income Tax Table (pass arUseLowIncomeTable: true to override)`);
|
|
60275
60711
|
return regular;
|
|
60276
60712
|
};
|
|
60277
|
-
const
|
|
60713
|
+
const candidates2 = [];
|
|
60278
60714
|
if (married && input2.arStatus4 !== false && (input2.arStatus4 === true || spouseGiven)) {
|
|
60279
60715
|
if (!spouseGiven)
|
|
60280
60716
|
notes.push("AR filing status 4: arSpouseIncome not given \u2014 the spouse's column B carries only line 18B (pass arSpouseIncome = the spouse's share of lines 8-22 and arSpouseAdjustments)");
|
|
60281
60717
|
const s4 = best(true);
|
|
60282
60718
|
if (s4)
|
|
60283
|
-
|
|
60719
|
+
candidates2.push(s4);
|
|
60284
60720
|
}
|
|
60285
|
-
if (!(married && input2.arStatus4 === true) ||
|
|
60721
|
+
if (!(married && input2.arStatus4 === true) || candidates2.length === 0) {
|
|
60286
60722
|
const s2 = best(false);
|
|
60287
60723
|
if (s2)
|
|
60288
|
-
|
|
60724
|
+
candidates2.push(s2);
|
|
60289
60725
|
}
|
|
60290
|
-
let chosen =
|
|
60291
|
-
for (const cand of
|
|
60726
|
+
let chosen = candidates2[0];
|
|
60727
|
+
for (const cand of candidates2)
|
|
60292
60728
|
if (cand.netTax < chosen.netTax)
|
|
60293
60729
|
chosen = cand;
|
|
60294
|
-
if (
|
|
60295
|
-
const s4 =
|
|
60296
|
-
const s2 =
|
|
60730
|
+
if (candidates2.length === 2) {
|
|
60731
|
+
const s4 = candidates2.find((x) => x.status4);
|
|
60732
|
+
const s2 = candidates2.find((x) => !x.status4);
|
|
60297
60733
|
notes.push(`AR filing status: married filing separately on the same return (status 4) nets ${fmtD(s4.netTax)}; married filing joint (status 2) nets ${fmtD(s2.netTax)} \u2014 status ${chosen.status4 ? "4" : "2"} composed ('Use the method that suits you best'; pass arStatus4 to force)`);
|
|
60298
60734
|
} else if (married && input2.arStatus4 === void 0 && !spouseGiven)
|
|
60299
60735
|
notes.push("AR filing status 2 (joint) composed \u2014 Arkansas has ONE rate table for every status, so a two-income couple usually saves with status 4 (separately on the same return); pass arSpouseIncome (the spouse's share of lines 8-22) to compare");
|
|
@@ -61453,12 +61889,12 @@ function composeME(input2, evalStateTax, notes) {
|
|
|
61453
61889
|
}
|
|
61454
61890
|
const fedEic = D6(input2.federalEITC);
|
|
61455
61891
|
const hasQc = input2.meHasQualifyingChild === true;
|
|
61456
|
-
const
|
|
61457
|
-
if (
|
|
61458
|
-
notes.push(`ME Schedule A line 4: earned income tax credit ${fmtD(
|
|
61892
|
+
const eitc2 = fedEic > 0n ? rd25(evalStateTax("us.me.eitc", 0n, { meFederalEic: fedEic, meHasQualifyingChild: hasQc })) : 0n;
|
|
61893
|
+
if (eitc2 > 0n)
|
|
61894
|
+
notes.push(`ME Schedule A line 4: earned income tax credit ${fmtD(eitc2)} = ${hasQc ? "25%" : "50% (no qualifying child)"} of the ${fmtD(fedEic)} federal EIC; refundable${!hasQc && deps > 0 && input2.meHasQualifyingChild === void 0 ? " \u2014 pass meHasQualifyingChild if a dependent is an EIC qualifying child (25%)" : ""}`);
|
|
61459
61895
|
const studentLoan = min22(D6(input2.meStudentLoanCredit), 250000n);
|
|
61460
61896
|
const otherRef = D6(input2.refundableCredits);
|
|
61461
|
-
const l25c = depCredit + ccRefundable + adcRefundable +
|
|
61897
|
+
const l25c = depCredit + ccRefundable + adcRefundable + eitc2 + studentLoan + otherRef;
|
|
61462
61898
|
const totalIncomeGiven = typeof input2.meTotalIncome === "number";
|
|
61463
61899
|
const totalIncome = totalIncomeGiven ? rd25(c(input2.meTotalIncome)) : l14;
|
|
61464
61900
|
let l25d = 0n;
|
|
@@ -61536,7 +61972,7 @@ function composeME(input2, evalStateTax, notes) {
|
|
|
61536
61972
|
...put("A1_dependent_exemption_credit", depCredit),
|
|
61537
61973
|
...put("A2_child_care_refundable", ccRefundable),
|
|
61538
61974
|
...put("A3_adult_care_refundable", adcRefundable),
|
|
61539
|
-
...put("A4_earned_income_credit",
|
|
61975
|
+
...put("A4_earned_income_credit", eitc2),
|
|
61540
61976
|
...put("A5_student_loan_credit", studentLoan),
|
|
61541
61977
|
...put("25c_refundable_credits", l25c),
|
|
61542
61978
|
...put("25d_property_tax_fairness_credit", l25d),
|
|
@@ -62615,17 +63051,17 @@ function composeVT(input2, evalStateTax, notes) {
|
|
|
62615
63051
|
const kids = Math.max(0, input2.vtChildrenSixOrUnder ?? 0);
|
|
62616
63052
|
const ctc = kids > 0 ? tryEval("us.vt.child_tax_credit", 0n, { ...agiFacts, vtChildrenSixOrUnder: kids }, "Schedule IN-112 line 4 (child tax credit)") ?? 0n : 0n;
|
|
62617
63053
|
const fedEic = D11(input2.federalEITC);
|
|
62618
|
-
const
|
|
63054
|
+
const eitc2 = fedEic > 0n ? tryEval("us.vt.eitc", 0n, { vtFederalEic: fedEic, vtEitcQualifyingChildren: Math.max(0, input2.vtEitcQualifyingChildren ?? 0) }, "Schedule IN-112 line 7 (earned income credit)") ?? 0n : 0n;
|
|
62619
63055
|
const veteran = input2.vtVeteranDischargeRecord === true ? tryEval("us.vt.veteran_credit", 0n, { ...agiFacts, vtVeteranDischargeRecord: true }, "Schedule IN-112 line 12 (veteran credit)") ?? 0n : 0n;
|
|
62620
63056
|
if (cdcc > 0n)
|
|
62621
63057
|
notes.push(`VT Schedule IN-112 line 2: child and dependent care credit ${fmtD(cdcc)} \u2014 72% of the federal credit, REFUNDABLE (\xA7 5828c)`);
|
|
62622
63058
|
if (kids > 0)
|
|
62623
63059
|
notes.push(ctc > 0n ? `VT Schedule IN-112 line 4: child tax credit ${fmtD(ctc)} for ${kids} child(ren) six or younger \u2014 $1,000 each less $20 per $1,000 or fraction of federal AGI over $125,000 regardless of filing status, REFUNDABLE (\xA7 5830f; 2025 Act 71 raised the age from five to six)` : `VT Schedule IN-112 line 4: no child tax credit \u2014 federal AGI ${fmtD(l1)} is above $174,000, where the $20-per-$1,000 reduction exhausts the $1,000`);
|
|
62624
63060
|
if (fedEic > 0n)
|
|
62625
|
-
notes.push(`VT Schedule IN-112 line 7: earned income credit ${fmtD(
|
|
63061
|
+
notes.push(`VT Schedule IN-112 line 7: earned income credit ${fmtD(eitc2)} \u2014 ${input2.vtEitcQualifyingChildren > 0 ? "38% of the federal credit with qualifying children" : "100% of the federal credit with NO qualifying children (2025 Act 71 \xA7 2, up from 38%)"}, REFUNDABLE`);
|
|
62626
63062
|
if (input2.vtVeteranDischargeRecord === true)
|
|
62627
63063
|
notes.push(veteran > 0n ? `VT Schedule IN-112 line 12: veteran tax credit ${fmtD(veteran)} \u2014 $250 less $5 per full $100 of federal AGI over $25,000, REFUNDABLE (\xA7 5830g, new for 2025)` : `VT Schedule IN-112 line 12: no veteran credit \u2014 federal AGI ${fmtD(l1)} is $30,000 or more`);
|
|
62628
|
-
const l26c = cdcc + ctc +
|
|
63064
|
+
const l26c = cdcc + ctc + eitc2 + veteran + D11(input2.refundableCredits);
|
|
62629
63065
|
const l26d = D11(input2.vtRealEstateWithholding);
|
|
62630
63066
|
const l26e = D11(input2.vtNonresidentEstimatedPayments);
|
|
62631
63067
|
const l26f = l26a + l26b + l26c + l26d + l26e;
|
|
@@ -62691,7 +63127,7 @@ function composeVT(input2, evalStateTax, notes) {
|
|
|
62691
63127
|
"26b_estimated_and_extension_payments": fmtD(l26b),
|
|
62692
63128
|
"IN112_II_2_child_dependent_care_credit": fmtD(cdcc),
|
|
62693
63129
|
"IN112_II_4_child_tax_credit": fmtD(ctc),
|
|
62694
|
-
"IN112_II_7_earned_income_credit": fmtD(
|
|
63130
|
+
"IN112_II_7_earned_income_credit": fmtD(eitc2),
|
|
62695
63131
|
"IN112_II_12_veteran_credit": fmtD(veteran),
|
|
62696
63132
|
"IN112_II_13_total_refundable_credits": fmtD(l26c),
|
|
62697
63133
|
"26c_refundable_credits": fmtD(l26c),
|
|
@@ -62906,11 +63342,11 @@ function composeHI(input2, evalStateTax, notes) {
|
|
|
62906
63342
|
if (l31 > 0n)
|
|
62907
63343
|
notes.push("HI line 31: $25 child passenger restraint system credit (\xA7 235-15; attach the invoice)");
|
|
62908
63344
|
const fedEic = D12(input2.federalEITC);
|
|
62909
|
-
const
|
|
62910
|
-
if (
|
|
62911
|
-
notes.push(`HI Schedule CR line 8 (Form N-356): earned income tax credit ${fmtD(
|
|
63345
|
+
const eitc2 = fedEic > 0n ? rd25(evalStateTax("us.hi.eitc", 0n, { hiFederalEic: fedEic })) : 0n;
|
|
63346
|
+
if (eitc2 > 0n)
|
|
63347
|
+
notes.push(`HI Schedule CR line 8 (Form N-356): earned income tax credit ${fmtD(eitc2)} = 40% of the ${fmtD(fedEic)} federal EIC; refundable (same filing status and dependents as the federal return${mfs ? " \u2014 a separate filer qualifies only when the federal EIC was allowed under \xA7 32(d)(2)" : ""})`);
|
|
62912
63348
|
const otherRef = D12(input2.refundableCredits);
|
|
62913
|
-
const l32 =
|
|
63349
|
+
const l32 = eitc2 + otherRef;
|
|
62914
63350
|
const l33 = l28 + l29 + l30 + l31 + l32;
|
|
62915
63351
|
const l34 = l27 - l33;
|
|
62916
63352
|
let osc = 0n;
|
|
@@ -62986,7 +63422,7 @@ function composeHI(input2, evalStateTax, notes) {
|
|
|
62986
63422
|
...put("29_renters_credit", l29),
|
|
62987
63423
|
...put("30_child_dependent_care_credit", l30),
|
|
62988
63424
|
...put("31_child_passenger_restraint_credit", l31),
|
|
62989
|
-
...put("CR8_earned_income_credit",
|
|
63425
|
+
...put("CR8_earned_income_credit", eitc2),
|
|
62990
63426
|
...put("32_schedule_cr_refundable_credits", l32),
|
|
62991
63427
|
"33_total_refundable_credits": fmtD(l33),
|
|
62992
63428
|
"34_adjusted_tax_liability": fmtD(l34),
|
|
@@ -64600,6 +65036,703 @@ var init_shape = __esm({
|
|
|
64600
65036
|
}
|
|
64601
65037
|
});
|
|
64602
65038
|
|
|
65039
|
+
// ../compose/dist/form2210.js
|
|
65040
|
+
function scopeFlags(facts2) {
|
|
65041
|
+
const out = [];
|
|
65042
|
+
const b = (id2) => facts2[id2]?.type === "bool" && facts2[id2].value === true;
|
|
65043
|
+
if (b("isClaimedAsDependent"))
|
|
65044
|
+
out.push("a dependent's standard deduction depends on the year's earned income (\xA7 63(c)(5)); line 7 takes the deduction in full, which the period's annualized earned income would change");
|
|
65045
|
+
if (b("isSubjectToKiddieTax"))
|
|
65046
|
+
out.push("Form 8615 uses the parent's annual taxable income");
|
|
65047
|
+
const month = facts2.rentalPlacedInServiceMonth;
|
|
65048
|
+
if (month && month.type === "int" && BigInt(month.value) > 0n && money43(facts2, "rentalDepreciableBasis") > 0n)
|
|
65049
|
+
out.push("rental property placed in service this year: its first-year depreciation depends on the month (Pub. 946 Table A-6), not on an annualized period");
|
|
65050
|
+
return out;
|
|
65051
|
+
}
|
|
65052
|
+
function nthWeekday(y, m, weekday, n) {
|
|
65053
|
+
const first = Date.UTC(y, m - 1, 1) / 864e5;
|
|
65054
|
+
const dow = new Date(first * 864e5).getUTCDay();
|
|
65055
|
+
return first + (weekday - dow + 7) % 7 + (n - 1) * 7;
|
|
65056
|
+
}
|
|
65057
|
+
function observed(y, m, d3) {
|
|
65058
|
+
const n = Date.UTC(y, m - 1, d3) / 864e5;
|
|
65059
|
+
const dow = new Date(n * 864e5).getUTCDay();
|
|
65060
|
+
return dow === 6 ? n - 1 : dow === 0 ? n + 1 : n;
|
|
65061
|
+
}
|
|
65062
|
+
function isLegalHoliday(n) {
|
|
65063
|
+
const y = Number(isoOf(n).slice(0, 4));
|
|
65064
|
+
return [
|
|
65065
|
+
observed(y, 1, 1),
|
|
65066
|
+
observed(y + 1, 1, 1),
|
|
65067
|
+
nthWeekday(y, 1, 1, 3),
|
|
65068
|
+
observed(y, 4, 16),
|
|
65069
|
+
observed(y, 6, 19),
|
|
65070
|
+
nthWeekday(y, 9, 1, 1)
|
|
65071
|
+
].includes(n);
|
|
65072
|
+
}
|
|
65073
|
+
function nextBusinessDay(n) {
|
|
65074
|
+
let d3 = n;
|
|
65075
|
+
for (; ; ) {
|
|
65076
|
+
const dow = new Date(d3 * 864e5).getUTCDay();
|
|
65077
|
+
if (dow !== 0 && dow !== 6 && !isLegalHoliday(d3))
|
|
65078
|
+
return d3;
|
|
65079
|
+
d3 += 1;
|
|
65080
|
+
}
|
|
65081
|
+
}
|
|
65082
|
+
function ratePeriods(year) {
|
|
65083
|
+
const q = (y2, n, from, to) => ({
|
|
65084
|
+
from: dayNum(from),
|
|
65085
|
+
to: dayNum(to),
|
|
65086
|
+
quarter: `${y2}-Q${n}`,
|
|
65087
|
+
divisor: isLeap(y2) ? 366 : 365
|
|
65088
|
+
});
|
|
65089
|
+
const y = year;
|
|
65090
|
+
return [
|
|
65091
|
+
q(y, 2, `${y}-04-16`, `${y}-06-30`),
|
|
65092
|
+
q(y, 3, `${y}-07-01`, `${y}-09-30`),
|
|
65093
|
+
q(y, 4, `${y}-10-01`, `${y}-12-31`),
|
|
65094
|
+
q(y + 1, 1, `${y + 1}-01-01`, `${y + 1}-03-31`),
|
|
65095
|
+
q(y + 1, 2, `${y + 1}-04-01`, `${y + 1}-04-15`)
|
|
65096
|
+
];
|
|
65097
|
+
}
|
|
65098
|
+
function composeForm2210(input2, run) {
|
|
65099
|
+
const { facts: facts2, taxYear: year } = input2;
|
|
65100
|
+
if (![2025, 2026, 2027].includes(year))
|
|
65101
|
+
throw new Error(`Form 2210 is composed for tax years 2025, 2026 and 2027, not ${year}`);
|
|
65102
|
+
const notes = [];
|
|
65103
|
+
const boxes = [];
|
|
65104
|
+
const get = (target) => run(facts2, target);
|
|
65105
|
+
const line1 = rd26(get("us.federal.income_tax_after_credits"));
|
|
65106
|
+
let other = get("us.federal.other_taxes");
|
|
65107
|
+
const withheld = money43(facts2, "federalTaxWithheld");
|
|
65108
|
+
const household = get("us.federal.household_employment_taxes");
|
|
65109
|
+
const line32 = rd26(get("us.federal.refundable_credits"));
|
|
65110
|
+
if (household > 0n && withheld === 0n && line1 + rd26(other - household) - line32 < 100000n) {
|
|
65111
|
+
other -= household;
|
|
65112
|
+
notes.push("line 2 leaves out the household employment taxes: no income tax was withheld and, without them, the year's tax is under $1,000 (Instructions for Form 2210, line 2)");
|
|
65113
|
+
}
|
|
65114
|
+
const line2 = rd26(other);
|
|
65115
|
+
const line4 = line1 + line2 - line32;
|
|
65116
|
+
const line5 = mulRate2(line4, 90n, 100n);
|
|
65117
|
+
const line6 = rd26(withheld);
|
|
65118
|
+
const line72 = line4 - line6;
|
|
65119
|
+
const partI = {
|
|
65120
|
+
"1_tax_after_credits": fmt2(line1),
|
|
65121
|
+
"2_other_taxes": fmt2(line2),
|
|
65122
|
+
"3_refundable_credits": fmt2(line32),
|
|
65123
|
+
"4_current_year_tax": fmt2(line4)
|
|
65124
|
+
};
|
|
65125
|
+
const result = { taxYear: year, partI, boxes, notes };
|
|
65126
|
+
if (line4 < 100000n) {
|
|
65127
|
+
result.noPenalty = "line 4 is less than $1,000: no penalty (\xA7 6654(e)(1))";
|
|
65128
|
+
return result;
|
|
65129
|
+
}
|
|
65130
|
+
partI["5_90_percent_of_line_4"] = fmt2(rd26(line5));
|
|
65131
|
+
partI["6_withholding"] = fmt2(line6);
|
|
65132
|
+
partI["7_line_4_minus_line_6"] = fmt2(line72);
|
|
65133
|
+
if (line72 < 100000n) {
|
|
65134
|
+
result.noPenalty = "line 7 is less than $1,000: no penalty (\xA7 6654(e)(1))";
|
|
65135
|
+
return result;
|
|
65136
|
+
}
|
|
65137
|
+
let line92;
|
|
65138
|
+
if (input2.noPriorYearReturn) {
|
|
65139
|
+
line92 = rd26(line5);
|
|
65140
|
+
partI["8_prior_year_tax"] = "not applicable (no prior-year return, or it covered under 12 months)";
|
|
65141
|
+
} else {
|
|
65142
|
+
const prior = facts2.priorYearTax;
|
|
65143
|
+
const priorAgi = facts2.priorYearAGI;
|
|
65144
|
+
if (!prior || prior.type !== "money")
|
|
65145
|
+
throw new MissingInput(["priorYearTax"]);
|
|
65146
|
+
if (!priorAgi || priorAgi.type !== "money")
|
|
65147
|
+
throw new MissingInput(["priorYearAGI"]);
|
|
65148
|
+
const mfs = facts2.filingStatus?.type === "enum" && facts2.filingStatus.value === "mfs";
|
|
65149
|
+
const high = BigInt(priorAgi.value) > (mfs ? 7500000n : 15000000n);
|
|
65150
|
+
const line8 = rd26(mulRate2(BigInt(prior.value), high ? 110n : 100n, 100n));
|
|
65151
|
+
partI["8_prior_year_tax"] = fmt2(line8) + (high ? ` (110% \u2014 prior-year AGI over ${mfs ? "$75,000" : "$150,000"})` : "");
|
|
65152
|
+
line92 = minC(rd26(line5), line8);
|
|
65153
|
+
}
|
|
65154
|
+
partI["9_required_annual_payment"] = fmt2(line92);
|
|
65155
|
+
if (line6 >= line92) {
|
|
65156
|
+
result.noPenalty = "line 6 (withholding) is at least line 9 (the required annual payment): no penalty";
|
|
65157
|
+
return result;
|
|
65158
|
+
}
|
|
65159
|
+
let annualized;
|
|
65160
|
+
if (input2.periods) {
|
|
65161
|
+
const ai = scheduleAI(input2, run, line92, notes);
|
|
65162
|
+
if ("refused" in ai)
|
|
65163
|
+
result.scheduleAI = ai;
|
|
65164
|
+
else {
|
|
65165
|
+
result.scheduleAI = { columns: ai.columns };
|
|
65166
|
+
annualized = ai.installments;
|
|
65167
|
+
}
|
|
65168
|
+
}
|
|
65169
|
+
const installments = [{ m: "regular", line10: Array(4).fill(rd26(mulRate2(line92, 25n, 100n))) }];
|
|
65170
|
+
if (annualized)
|
|
65171
|
+
installments.push({ m: "annualized", line10: annualized });
|
|
65172
|
+
const modes = input2.withholdingByDate ? ["even", "actual"] : ["even"];
|
|
65173
|
+
const runs = modes.map((w) => ({ w, notes: [], res: {} }));
|
|
65174
|
+
for (const r of runs)
|
|
65175
|
+
for (const { m, line10 } of installments)
|
|
65176
|
+
r.res[m] = partIII(input2, line10, r.notes, r.w, line4);
|
|
65177
|
+
const all = runs.flatMap((r) => installments.map(({ m }) => ({ w: r.w, m, r: r.res[m], run: r })));
|
|
65178
|
+
const unpriced = all.find((x) => x.r.penaltyCents === void 0);
|
|
65179
|
+
let chosen = runs[0];
|
|
65180
|
+
if (unpriced) {
|
|
65181
|
+
result.penalty = { refused: `${unpriced.m} method${modes.length > 1 ? `, withholding ${unpriced.w === "even" ? "spread evenly" : "on its actual dates"}` : ""}: ${unpriced.r.refused}` };
|
|
65182
|
+
} else {
|
|
65183
|
+
const best = all.reduce((a, b) => BigInt(b.r.penaltyCents) < BigInt(a.r.penaltyCents) ? b : a);
|
|
65184
|
+
chosen = best.run;
|
|
65185
|
+
result.penalty = { method: best.m, amount: best.r.penalty, amountCents: best.r.penaltyCents };
|
|
65186
|
+
if (best.m === "annualized")
|
|
65187
|
+
boxes.push("C");
|
|
65188
|
+
if (best.w === "actual")
|
|
65189
|
+
boxes.push("D");
|
|
65190
|
+
if (modes.length > 1)
|
|
65191
|
+
notes.push(best.w === "actual" ? "box D: treating withholding as paid on the dates it was actually withheld gives the lower penalty" : "withholding is treated as paid one-fourth on each due date: the actual withholding dates (box D) would not lower the penalty");
|
|
65192
|
+
}
|
|
65193
|
+
result.partIII = chosen.res;
|
|
65194
|
+
notes.push(...chosen.notes);
|
|
65195
|
+
result.notes = [...new Set(notes)];
|
|
65196
|
+
return result;
|
|
65197
|
+
}
|
|
65198
|
+
function scheduleAI(input2, run, line92, notes) {
|
|
65199
|
+
const { facts: facts2 } = input2;
|
|
65200
|
+
const periods = input2.periods;
|
|
65201
|
+
const refused = [];
|
|
65202
|
+
for (const [id2, kind] of Object.entries(SCHEDULE_AI_FACTS)) {
|
|
65203
|
+
if (typeof kind === "object" && money43(facts2, id2) !== 0n)
|
|
65204
|
+
refused.push(`${id2}: ${kind.refuse}`);
|
|
65205
|
+
}
|
|
65206
|
+
refused.push(...scopeFlags(facts2));
|
|
65207
|
+
if (refused.length)
|
|
65208
|
+
return { refused };
|
|
65209
|
+
const cols = [periods.mar31, periods.may31, periods.aug31];
|
|
65210
|
+
const names = ["mar31", "may31", "aug31"];
|
|
65211
|
+
const missing = [];
|
|
65212
|
+
cols.forEach((p, i) => {
|
|
65213
|
+
for (const id2 of Object.keys(p)) {
|
|
65214
|
+
const kind = SCHEDULE_AI_FACTS[id2];
|
|
65215
|
+
if (kind === void 0)
|
|
65216
|
+
throw new Error(`periods.${names[i]}.${id2}: not a fact Schedule AI reads`);
|
|
65217
|
+
if (kind !== "annualize")
|
|
65218
|
+
throw new Error(`periods.${names[i]}.${id2}: not a period amount (${kind === "keep" ? "it is used as is in every column" : "out of scope"})`);
|
|
65219
|
+
if (p[id2].type !== "money")
|
|
65220
|
+
throw new Error(`periods.${names[i]}.${id2}: must be money`);
|
|
65221
|
+
}
|
|
65222
|
+
for (const [id2, kind] of Object.entries(SCHEDULE_AI_FACTS)) {
|
|
65223
|
+
if (kind === "annualize" && money43(facts2, id2) !== 0n && p[id2] === void 0)
|
|
65224
|
+
missing.push(`periods.${names[i]}.${id2}`);
|
|
65225
|
+
}
|
|
65226
|
+
});
|
|
65227
|
+
if (missing.length)
|
|
65228
|
+
throw new MissingInput(missing);
|
|
65229
|
+
const columns = [];
|
|
65230
|
+
const installments = [];
|
|
65231
|
+
let prior27 = 0n;
|
|
65232
|
+
let prior26minus27 = 0n;
|
|
65233
|
+
const line24 = rd26(mulRate2(line92, 25n, 100n));
|
|
65234
|
+
for (let i = 0; i < 4; i++) {
|
|
65235
|
+
const a = ANNUALIZATION[i];
|
|
65236
|
+
const colFacts = { ...facts2 };
|
|
65237
|
+
if (i < 3) {
|
|
65238
|
+
for (const [id2, kind] of Object.entries(SCHEDULE_AI_FACTS)) {
|
|
65239
|
+
if (kind !== "annualize")
|
|
65240
|
+
continue;
|
|
65241
|
+
const period = cols[i][id2];
|
|
65242
|
+
const v = period && period.type === "money" ? BigInt(period.value) : 0n;
|
|
65243
|
+
if (v === 0n && colFacts[id2] === void 0)
|
|
65244
|
+
continue;
|
|
65245
|
+
colFacts[id2] = { type: "money", value: mulRate2(v, a.num, a.den).toString() };
|
|
65246
|
+
}
|
|
65247
|
+
for (const id2 of ["selfEmploymentNetProfit", "spouseSelfEmploymentNetProfit"]) {
|
|
65248
|
+
const p = cols[i][id2];
|
|
65249
|
+
const ne = p && p.type === "money" ? mulRate2(BigInt(p.value), 9235n, 10000n) : 0n;
|
|
65250
|
+
if (ne > 0n && ne < 40000n)
|
|
65251
|
+
return {
|
|
65252
|
+
refused: [
|
|
65253
|
+
`periods.${names[i]}.${id2}: the period's net earnings from self-employment are under $400, which Part II line 28 enters as zero while the period's income still counts on line 1 \u2014 not modeled`
|
|
65254
|
+
]
|
|
65255
|
+
};
|
|
65256
|
+
}
|
|
65257
|
+
}
|
|
65258
|
+
const g = (t) => run(colFacts, t);
|
|
65259
|
+
const saltPaid = money43(colFacts, "stateAndLocalTaxesPaid");
|
|
65260
|
+
if (i < 3 && saltPaid > 0n && g("us.federal.salt_deduction") < saltPaid && g("us.federal.itemized_deductions") >= g("us.federal.standard_deduction"))
|
|
65261
|
+
return {
|
|
65262
|
+
refused: [
|
|
65263
|
+
`column (${"abcd"[i]}): the annualized state and local taxes exceed the year's SALT limit, and the instructions don't say whether the period's itemized deductions (line 4) are limited before or after line 5's annualization`
|
|
65264
|
+
]
|
|
65265
|
+
};
|
|
65266
|
+
const agi2 = g("us.federal.agi");
|
|
65267
|
+
const deduction = g("us.federal.deduction_election");
|
|
65268
|
+
const ti = g("us.federal.taxable_income");
|
|
65269
|
+
const line14 = g("us.federal.income_tax_before_credits");
|
|
65270
|
+
const se = g("us.federal.se_tax");
|
|
65271
|
+
const amt = g("us.federal.amt");
|
|
65272
|
+
const otherTaxes = g("us.federal.other_taxes");
|
|
65273
|
+
const beforeNonref = g("us.federal.tax_before_nonrefundable_credits");
|
|
65274
|
+
const afterCredits = g("us.federal.income_tax_after_credits");
|
|
65275
|
+
const refundable = g("us.federal.refundable_credits");
|
|
65276
|
+
const line16 = amt + otherTaxes - se;
|
|
65277
|
+
const line17 = rd26(line14) + rd26(se) + rd26(line16);
|
|
65278
|
+
const line18 = rd26(beforeNonref - afterCredits) + rd26(refundable);
|
|
65279
|
+
const line19 = max029(line17 - line18);
|
|
65280
|
+
const line21 = rd26(mulRate2(line19, a.pct[0], a.pct[1]));
|
|
65281
|
+
const line22 = prior27;
|
|
65282
|
+
const line23 = max029(line21 - line22);
|
|
65283
|
+
const line25 = i === 0 ? 0n : prior26minus27;
|
|
65284
|
+
const line26 = line24 + line25;
|
|
65285
|
+
const line27 = minC(line23, line26);
|
|
65286
|
+
columns.push({
|
|
65287
|
+
column: `(${"abcd"[i]}) ${["1/1\u20133/31", "1/1\u20135/31", "1/1\u20138/31", "1/1\u201312/31"][i]}`,
|
|
65288
|
+
"2_annualization": a.label,
|
|
65289
|
+
"3_annualized_agi": D13(agi2),
|
|
65290
|
+
"8_deduction": D13(deduction),
|
|
65291
|
+
"13_annualized_taxable_income": D13(ti),
|
|
65292
|
+
"14_tax": D13(line14),
|
|
65293
|
+
"15_se_tax": D13(se),
|
|
65294
|
+
"16_other_taxes_incl_amt": D13(line16),
|
|
65295
|
+
"17_total_tax": fmt2(line17),
|
|
65296
|
+
"18_credits": fmt2(line18),
|
|
65297
|
+
"19_net": fmt2(line19),
|
|
65298
|
+
"20_applicable_percentage": `${Number(a.pct[0]) / (Number(a.pct[1]) / 100)}%`,
|
|
65299
|
+
"21": fmt2(line21),
|
|
65300
|
+
"22": fmt2(line22),
|
|
65301
|
+
"23": fmt2(line23),
|
|
65302
|
+
"24": fmt2(line24),
|
|
65303
|
+
...i > 0 ? { "25": fmt2(line25) } : {},
|
|
65304
|
+
"26": fmt2(line26),
|
|
65305
|
+
"27_required_installment": fmt2(line27)
|
|
65306
|
+
});
|
|
65307
|
+
installments.push(line27);
|
|
65308
|
+
prior27 += line27;
|
|
65309
|
+
prior26minus27 = line26 - line27;
|
|
65310
|
+
}
|
|
65311
|
+
notes.push("Schedule AI: each column is the full return evaluated on the period's cumulative amounts \xD7 the annualization amount (line 2), with the standard deduction in full (line 7); lines 14\u201319 are that evaluation's tax, self-employment tax, other taxes including AMT, and credits");
|
|
65312
|
+
return { columns, installments };
|
|
65313
|
+
}
|
|
65314
|
+
function partIII(input2, line10, notes, withholdingDates, line4) {
|
|
65315
|
+
const year = input2.taxYear;
|
|
65316
|
+
const printed = [`${year}-04-15`, `${year}-06-15`, `${year}-09-15`, `${year + 1}-01-15`].map(dayNum);
|
|
65317
|
+
const effective = printed.map(nextBusinessDay);
|
|
65318
|
+
const dueLabels = printed.map((n, i) => isoOf(n) + (effective[i] !== n ? ` (payable ${isoOf(effective[i])}, \xA7 7503)` : ""));
|
|
65319
|
+
const jan31 = dayNum(`${year + 1}-01-31`);
|
|
65320
|
+
const filedBy = input2.filedAndPaidInFullOn ? dayNum(input2.filedAndPaidInFullOn) : void 0;
|
|
65321
|
+
const section6654h = filedBy !== void 0 && filedBy <= jan31;
|
|
65322
|
+
const asMade = (day) => {
|
|
65323
|
+
for (let i = 0; i < 4; i++)
|
|
65324
|
+
if (day > printed[i] && day <= effective[i])
|
|
65325
|
+
return printed[i];
|
|
65326
|
+
return day;
|
|
65327
|
+
};
|
|
65328
|
+
const estimated = input2.payments.map((p) => ({ day: asMade(dayNum(p.date)), amount: p.amount })).filter((p) => {
|
|
65329
|
+
if (p.amount < 0n)
|
|
65330
|
+
throw new Error("a payment amount can't be negative");
|
|
65331
|
+
return p.amount > 0n;
|
|
65332
|
+
});
|
|
65333
|
+
let withholding;
|
|
65334
|
+
if (withholdingDates === "actual") {
|
|
65335
|
+
const list = input2.withholdingByDate;
|
|
65336
|
+
const total2 = list.reduce((t, p) => t + p.amount, 0n);
|
|
65337
|
+
if (total2 !== money43(input2.facts, "federalTaxWithheld"))
|
|
65338
|
+
throw new Error(`withholdingByDate totals ${fmt2(total2, true)} but federalTaxWithheld is ${fmt2(money43(input2.facts, "federalTaxWithheld"), true)} \u2014 they must agree`);
|
|
65339
|
+
withholding = list.map((p) => ({ day: asMade(dayNum(p.date)), amount: p.amount })).filter((p) => p.amount > 0n);
|
|
65340
|
+
} else {
|
|
65341
|
+
const w = money43(input2.facts, "federalTaxWithheld");
|
|
65342
|
+
const quarter = w / 4n;
|
|
65343
|
+
withholding = printed.map((day, i) => ({ day, amount: i < 3 ? quarter : w - 3n * quarter })).filter((p) => p.amount > 0n);
|
|
65344
|
+
}
|
|
65345
|
+
const windowOf = (day) => {
|
|
65346
|
+
for (let i = 0; i < 4; i++)
|
|
65347
|
+
if (day <= effective[i])
|
|
65348
|
+
return i;
|
|
65349
|
+
return section6654h && day <= filedBy ? 3 : 4;
|
|
65350
|
+
};
|
|
65351
|
+
const line112 = [0n, 0n, 0n, 0n];
|
|
65352
|
+
for (const p of [...estimated, ...withholding]) {
|
|
65353
|
+
const w = windowOf(p.day);
|
|
65354
|
+
if (w < 4)
|
|
65355
|
+
line112[w] += p.amount;
|
|
65356
|
+
}
|
|
65357
|
+
if (section6654h) {
|
|
65358
|
+
const paidByFiling = [...estimated, ...withholding].filter((p) => p.day <= filedBy).reduce((t, p) => t + p.amount, 0n);
|
|
65359
|
+
if (paidByFiling < line4)
|
|
65360
|
+
throw new Error(`filedAndPaidInFullOn: \xA7 6654(h) needs the tax paid in full by ${input2.filedAndPaidInFullOn}, but the payments and withholding through that date total ${fmt2(paidByFiling, true)}, less than line 4 (${fmt2(line4)}) \u2014 list the payment made with the return in payments`);
|
|
65361
|
+
}
|
|
65362
|
+
const L11 = line112.map(rd26);
|
|
65363
|
+
const A = { "10": line10, "11": L11, "12": [], "13": [], "14": [], "15": [], "16": [], "17": [], "18": [] };
|
|
65364
|
+
let prev18 = 0n;
|
|
65365
|
+
let prev16plus17 = 0n;
|
|
65366
|
+
for (let i = 0; i < 4; i++) {
|
|
65367
|
+
const l12 = i === 0 ? 0n : prev18;
|
|
65368
|
+
const l13 = L11[i] + l12;
|
|
65369
|
+
const l14 = i === 0 ? 0n : prev16plus17;
|
|
65370
|
+
const l15 = i === 0 ? L11[0] : max029(l13 - l14);
|
|
65371
|
+
const l16 = i === 0 ? 0n : l15 === 0n ? l14 - l13 : 0n;
|
|
65372
|
+
const l17 = line10[i] >= l15 ? line10[i] - l15 : 0n;
|
|
65373
|
+
const l18 = l15 > line10[i] ? l15 - line10[i] : 0n;
|
|
65374
|
+
A["12"].push(l12);
|
|
65375
|
+
A["13"].push(l13);
|
|
65376
|
+
A["14"].push(l14);
|
|
65377
|
+
A["15"].push(l15);
|
|
65378
|
+
A["16"].push(l16);
|
|
65379
|
+
A["17"].push(l17);
|
|
65380
|
+
A["18"].push(l18);
|
|
65381
|
+
prev18 = l18;
|
|
65382
|
+
prev16plus17 = l16 + l17;
|
|
65383
|
+
}
|
|
65384
|
+
const sectionA = Object.fromEntries(Object.entries(A).map(([k, v]) => [k, v.map((c2) => fmt2(c2))]));
|
|
65385
|
+
const out = { dueDates: dueLabels, sectionA, worksheet: [] };
|
|
65386
|
+
const under = [...A["17"]];
|
|
65387
|
+
if (section6654h) {
|
|
65388
|
+
if (under[3] > 0n)
|
|
65389
|
+
notes.push("\xA7 6654(h): the return was filed and the tax paid in full by January 31, so there's no penalty on the January 15 installment");
|
|
65390
|
+
under[3] = 0n;
|
|
65391
|
+
}
|
|
65392
|
+
const end = dayNum(`${year + 1}-04-15`);
|
|
65393
|
+
const balances = under.map((u, i) => ({ col: i, left: u }));
|
|
65394
|
+
const chunks = [];
|
|
65395
|
+
const all = [...estimated, ...withholding].sort((x, y) => x.day - y.day);
|
|
65396
|
+
for (const p of all) {
|
|
65397
|
+
let rest = p.amount;
|
|
65398
|
+
for (const b of balances) {
|
|
65399
|
+
if (rest === 0n)
|
|
65400
|
+
break;
|
|
65401
|
+
if (b.left === 0n || p.day <= effective[b.col])
|
|
65402
|
+
continue;
|
|
65403
|
+
const use = minC(rest, b.left);
|
|
65404
|
+
chunks.push({ col: b.col, amount: use, paid: Math.min(p.day, end) });
|
|
65405
|
+
b.left -= use;
|
|
65406
|
+
rest -= use;
|
|
65407
|
+
}
|
|
65408
|
+
}
|
|
65409
|
+
for (const b of balances)
|
|
65410
|
+
if (b.left > 0n)
|
|
65411
|
+
chunks.push({ col: b.col, amount: b.left, paid: end });
|
|
65412
|
+
const merged = /* @__PURE__ */ new Map();
|
|
65413
|
+
for (const ch of chunks) {
|
|
65414
|
+
const key = `${ch.col}|${ch.paid}`;
|
|
65415
|
+
const m = merged.get(key);
|
|
65416
|
+
if (m)
|
|
65417
|
+
m.amount += ch.amount;
|
|
65418
|
+
else
|
|
65419
|
+
merged.set(key, { ...ch });
|
|
65420
|
+
}
|
|
65421
|
+
const periods = ratePeriods(year);
|
|
65422
|
+
let total = 0n;
|
|
65423
|
+
let missingRate;
|
|
65424
|
+
for (const ch of [...merged.values()].sort((x, y) => x.col - y.col || x.paid - y.paid)) {
|
|
65425
|
+
if (ch.paid <= printed[ch.col])
|
|
65426
|
+
continue;
|
|
65427
|
+
for (const rp of periods) {
|
|
65428
|
+
const start = Math.max(printed[ch.col], rp.from - 1);
|
|
65429
|
+
const stop = Math.min(ch.paid, rp.to);
|
|
65430
|
+
const days = stop - start;
|
|
65431
|
+
if (days <= 0)
|
|
65432
|
+
continue;
|
|
65433
|
+
const rate2 = UNDERPAYMENT_RATES[rp.quarter];
|
|
65434
|
+
if (!rate2) {
|
|
65435
|
+
missingRate ??= rp.quarter;
|
|
65436
|
+
continue;
|
|
65437
|
+
}
|
|
65438
|
+
const num = ch.amount * BigInt(Math.round(rate2.percent * 100)) * BigInt(days);
|
|
65439
|
+
const den = 10000n * BigInt(rp.divisor);
|
|
65440
|
+
const cents2 = (num * 2n + den) / (2n * den);
|
|
65441
|
+
total += cents2;
|
|
65442
|
+
out.worksheet.push({
|
|
65443
|
+
column: "abcd"[ch.col],
|
|
65444
|
+
amount: fmt2(ch.amount, true),
|
|
65445
|
+
from: isoOf(start),
|
|
65446
|
+
paidOn: isoOf(ch.paid),
|
|
65447
|
+
days,
|
|
65448
|
+
ratePercent: rate2.percent,
|
|
65449
|
+
quarter: rp.quarter,
|
|
65450
|
+
penalty: fmt2(cents2, true)
|
|
65451
|
+
});
|
|
65452
|
+
}
|
|
65453
|
+
}
|
|
65454
|
+
if (missingRate) {
|
|
65455
|
+
out.refused = `the underpayment rate for ${missingRate} hasn't been announced (\xA7 6621(a)(2) rates are set each quarter); the underpayments in Section A are final, the penalty isn't`;
|
|
65456
|
+
return out;
|
|
65457
|
+
}
|
|
65458
|
+
if (year === 2025 && out.worksheet.some((w) => w.quarter === "2026-Q2"))
|
|
65459
|
+
notes.push(`the printed 2025 penalty worksheet applies 7% through April 15, 2026, but the \xA7 6621 rate for April 1\u201315, 2026 is 6% (Rev. Rul. 2026-5); the penalty here uses each quarter's actual rate, which the instructions allow ("You don't have to use the method used on Form 2210 as long as you enter the correct penalty amount")`);
|
|
65460
|
+
out.penalty = fmt2(total, true);
|
|
65461
|
+
out.penaltyCents = total.toString();
|
|
65462
|
+
return out;
|
|
65463
|
+
}
|
|
65464
|
+
function dollarsToCents(v, path) {
|
|
65465
|
+
const s = typeof v === "number" ? Number.isFinite(v) ? String(v) : "" : typeof v === "string" ? v.replace(/[$,\s]/g, "") : "";
|
|
65466
|
+
const m = /^(-?)(\d+)(?:\.(\d{1,2}))?$/.exec(s);
|
|
65467
|
+
if (!m)
|
|
65468
|
+
throw new Error(`${path}: expected a dollar amount like 1234.56, got ${JSON.stringify(v)}`);
|
|
65469
|
+
const cents2 = BigInt(m[2]) * 100n + BigInt((m[3] ?? "").padEnd(2, "0"));
|
|
65470
|
+
return m[1] ? -cents2 : cents2;
|
|
65471
|
+
}
|
|
65472
|
+
function parsePayments(raw, path) {
|
|
65473
|
+
if (!Array.isArray(raw))
|
|
65474
|
+
throw new Error(`${path}: expected an array of { date, amount }`);
|
|
65475
|
+
return raw.map((p, i) => {
|
|
65476
|
+
if (!isObj(p))
|
|
65477
|
+
throw new Error(`${path}[${i}]: expected { date, amount }`);
|
|
65478
|
+
const extra = Object.keys(p).filter((k) => k !== "date" && k !== "amount");
|
|
65479
|
+
if (extra.length)
|
|
65480
|
+
throw new Error(`${path}[${i}]: unknown key(s) ${extra.join(", ")}`);
|
|
65481
|
+
if (typeof p.date !== "string")
|
|
65482
|
+
throw new Error(`${path}[${i}].date: expected YYYY-MM-DD`);
|
|
65483
|
+
dayNum(p.date);
|
|
65484
|
+
const amount = dollarsToCents(p.amount, `${path}[${i}].amount`);
|
|
65485
|
+
if (amount < 0n)
|
|
65486
|
+
throw new Error(`${path}[${i}].amount: can't be negative`);
|
|
65487
|
+
return { date: p.date, amount };
|
|
65488
|
+
});
|
|
65489
|
+
}
|
|
65490
|
+
function form2210InputFromArgs(args, taxYear, facts2, coerce) {
|
|
65491
|
+
const known = /* @__PURE__ */ new Set(["payments", "periods", "withholdingByDate", "noPriorYearReturn", "filedAndPaidInFullOn"]);
|
|
65492
|
+
const unknown2 = Object.keys(args).filter((k) => !known.has(k));
|
|
65493
|
+
if (unknown2.length)
|
|
65494
|
+
throw new Error(`unknown Form 2210 option(s): ${unknown2.join(", ")}`);
|
|
65495
|
+
if (args.payments === void 0)
|
|
65496
|
+
throw new Error("payments is required: every estimated tax payment for the year with its date (an empty array if none) \u2014 the penalty depends on when each was paid");
|
|
65497
|
+
const input2 = { taxYear, facts: facts2, payments: parsePayments(args.payments, "payments") };
|
|
65498
|
+
if (args.withholdingByDate !== void 0)
|
|
65499
|
+
input2.withholdingByDate = parsePayments(args.withholdingByDate, "withholdingByDate");
|
|
65500
|
+
if (args.noPriorYearReturn !== void 0) {
|
|
65501
|
+
if (typeof args.noPriorYearReturn !== "boolean")
|
|
65502
|
+
throw new Error("noPriorYearReturn: expected true or false");
|
|
65503
|
+
input2.noPriorYearReturn = args.noPriorYearReturn;
|
|
65504
|
+
}
|
|
65505
|
+
if (args.filedAndPaidInFullOn !== void 0) {
|
|
65506
|
+
if (typeof args.filedAndPaidInFullOn !== "string")
|
|
65507
|
+
throw new Error("filedAndPaidInFullOn: expected YYYY-MM-DD");
|
|
65508
|
+
dayNum(args.filedAndPaidInFullOn);
|
|
65509
|
+
input2.filedAndPaidInFullOn = args.filedAndPaidInFullOn;
|
|
65510
|
+
}
|
|
65511
|
+
if (args.periods !== void 0) {
|
|
65512
|
+
const p = args.periods;
|
|
65513
|
+
if (!isObj(p))
|
|
65514
|
+
throw new Error("periods: expected { mar31, may31, aug31 }");
|
|
65515
|
+
const keys = ["mar31", "may31", "aug31"];
|
|
65516
|
+
const extra = Object.keys(p).filter((k) => !keys.includes(k));
|
|
65517
|
+
if (extra.length)
|
|
65518
|
+
throw new Error(`periods: unknown key(s) ${extra.join(", ")} (use mar31, may31, aug31)`);
|
|
65519
|
+
const out = {};
|
|
65520
|
+
for (const k of keys) {
|
|
65521
|
+
const v = p[k];
|
|
65522
|
+
if (!isObj(v))
|
|
65523
|
+
throw new Error(`periods.${k}: expected an object of cumulative amounts from January 1 (e.g. { "wages": 15000 })`);
|
|
65524
|
+
for (const [id2] of Object.entries(v)) {
|
|
65525
|
+
const kind = SCHEDULE_AI_FACTS[id2];
|
|
65526
|
+
if (kind !== "annualize")
|
|
65527
|
+
throw new Error(`periods.${k}.${id2}: ${kind === void 0 ? "not an amount Schedule AI annualizes" : kind === "keep" ? "used as is in every column, not a period amount" : "out of scope for Schedule AI"}`);
|
|
65528
|
+
}
|
|
65529
|
+
out[k] = coerce(v);
|
|
65530
|
+
}
|
|
65531
|
+
input2.periods = out;
|
|
65532
|
+
}
|
|
65533
|
+
return input2;
|
|
65534
|
+
}
|
|
65535
|
+
var SCHEDULE_AI_FACTS, money43, dayNum, isoOf, isLeap, UNDERPAYMENT_RATES, rd26, max029, minC, fmt2, D13, mulRate2, ANNUALIZATION, MissingInput, isObj;
|
|
65536
|
+
var init_form2210 = __esm({
|
|
65537
|
+
"../compose/dist/form2210.js"() {
|
|
65538
|
+
"use strict";
|
|
65539
|
+
SCHEDULE_AI_FACTS = {
|
|
65540
|
+
// income
|
|
65541
|
+
wages: "annualize",
|
|
65542
|
+
taxableInterest: "annualize",
|
|
65543
|
+
taxExemptInterest: "annualize",
|
|
65544
|
+
ordinaryDividends: "annualize",
|
|
65545
|
+
qualifiedDividends: "annualize",
|
|
65546
|
+
shortTermCapitalGains: "annualize",
|
|
65547
|
+
shortTermCapitalLoss: "annualize",
|
|
65548
|
+
longTermCapitalGains: "annualize",
|
|
65549
|
+
longTermCapitalLoss: "annualize",
|
|
65550
|
+
netCapitalLoss: "annualize",
|
|
65551
|
+
selfEmploymentNetProfit: "annualize",
|
|
65552
|
+
spouseSelfEmploymentNetProfit: "annualize",
|
|
65553
|
+
scheduleCNetLoss: "annualize",
|
|
65554
|
+
k1OrdinaryBusinessIncome: "annualize",
|
|
65555
|
+
taxableIraDistributions: "annualize",
|
|
65556
|
+
taxablePensionsAndAnnuities: "annualize",
|
|
65557
|
+
unemploymentCompensation: "annualize",
|
|
65558
|
+
otherOrdinaryIncome: "annualize",
|
|
65559
|
+
alimonyReceivedPre2019: "annualize",
|
|
65560
|
+
hsaDistributions: "annualize",
|
|
65561
|
+
hsaQualifiedMedicalExpenses: "annualize",
|
|
65562
|
+
scheduleENetIncome: "annualize",
|
|
65563
|
+
rentalIncomeBeforeDepreciation: "annualize",
|
|
65564
|
+
nonpassiveScheduleELoss: "annualize",
|
|
65565
|
+
socialSecurityBenefits: "annualize",
|
|
65566
|
+
socialSecurityWages: "annualize",
|
|
65567
|
+
spouseSocialSecurityWages: "annualize",
|
|
65568
|
+
medicareWages: "annualize",
|
|
65569
|
+
gamblingWinnings: "annualize",
|
|
65570
|
+
qualifiedTips: "annualize",
|
|
65571
|
+
qualifiedOvertimePremium: "annualize",
|
|
65572
|
+
scheduleRDisabilityIncome: "annualize",
|
|
65573
|
+
nontaxableBenefitsForScheduleR: "annualize",
|
|
65574
|
+
earlyDistributionSubjectToPenalty: "annualize",
|
|
65575
|
+
amtIsoExerciseSpread: "annualize",
|
|
65576
|
+
amtOtherPreferences: "annualize",
|
|
65577
|
+
// QBI (the businesses' income and W-2 wages are the period's; UBIA is basis)
|
|
65578
|
+
qbiBusiness2Income: "annualize",
|
|
65579
|
+
qbiBusiness3Income: "annualize",
|
|
65580
|
+
qbiBusiness4Income: "annualize",
|
|
65581
|
+
qbiBusiness5Income: "annualize",
|
|
65582
|
+
qbiBusiness6Income: "annualize",
|
|
65583
|
+
qbiLossOffset: "annualize",
|
|
65584
|
+
qbiW2Wages: "annualize",
|
|
65585
|
+
spouseQbiW2Wages: "annualize",
|
|
65586
|
+
qbiBusiness2W2Wages: "annualize",
|
|
65587
|
+
qbiBusiness3W2Wages: "annualize",
|
|
65588
|
+
qbiBusiness4W2Wages: "annualize",
|
|
65589
|
+
qbiBusiness5W2Wages: "annualize",
|
|
65590
|
+
qbiBusiness6W2Wages: "annualize",
|
|
65591
|
+
qbiUBIA: "keep",
|
|
65592
|
+
spouseQbiUBIA: "keep",
|
|
65593
|
+
qbiBusiness2UBIA: "keep",
|
|
65594
|
+
qbiBusiness3UBIA: "keep",
|
|
65595
|
+
qbiBusiness4UBIA: "keep",
|
|
65596
|
+
qbiBusiness5UBIA: "keep",
|
|
65597
|
+
qbiBusiness6UBIA: "keep",
|
|
65598
|
+
// adjustments
|
|
65599
|
+
hsaContribution: "annualize",
|
|
65600
|
+
sepContribution: "annualize",
|
|
65601
|
+
selfEmployedHealthPremiums: "annualize",
|
|
65602
|
+
educatorExpenses: "annualize",
|
|
65603
|
+
spouseEducatorExpenses: "annualize",
|
|
65604
|
+
earlyWithdrawalPenaltyPaid: "annualize",
|
|
65605
|
+
alimonyPaidPre2019: "annualize",
|
|
65606
|
+
otherAdjustments: "annualize",
|
|
65607
|
+
iraContribution: "annualize",
|
|
65608
|
+
studentLoanInterest: "annualize",
|
|
65609
|
+
// itemized and Schedule 1-A deductions
|
|
65610
|
+
stateAndLocalTaxesPaid: "annualize",
|
|
65611
|
+
mortgageInterestPaid: "annualize",
|
|
65612
|
+
mortgageAverageBalance: "keep",
|
|
65613
|
+
charitableCashContributions: "annualize",
|
|
65614
|
+
noncashCharitableContributions: "annualize",
|
|
65615
|
+
medicalExpenses: "annualize",
|
|
65616
|
+
casualtyFederalDisasterLosses: "annualize",
|
|
65617
|
+
casualtyQualifiedDisasterLosses: "annualize",
|
|
65618
|
+
investmentInterestDeduction: "annualize",
|
|
65619
|
+
gamblingLossesItemized: "annualize",
|
|
65620
|
+
otherItemizedDeductions: "annualize",
|
|
65621
|
+
carLoanInterest: "annualize",
|
|
65622
|
+
niitInvestmentExpenses: "annualize",
|
|
65623
|
+
// credits (Schedule AI line 18: the items used to figure each credit are annualized)
|
|
65624
|
+
dependentCareExpenses: "annualize",
|
|
65625
|
+
secondaryEarnedIncome: "annualize",
|
|
65626
|
+
aotcExpensesStudent1: "annualize",
|
|
65627
|
+
aotcExpensesStudent2: "annualize",
|
|
65628
|
+
aotcExpensesStudent3: "annualize",
|
|
65629
|
+
llcQualifiedExpenses: "annualize",
|
|
65630
|
+
saversContributions: "annualize",
|
|
65631
|
+
saversContributionsSpouse: "annualize",
|
|
65632
|
+
qualifiedAdoptionExpenses: "annualize",
|
|
65633
|
+
insulationAirSealingCosts: "annualize",
|
|
65634
|
+
exteriorDoorMostExpensiveCost: "annualize",
|
|
65635
|
+
exteriorDoorOtherCosts: "annualize",
|
|
65636
|
+
windowsSkylightsCosts: "annualize",
|
|
65637
|
+
centralAirConditionerCosts: "annualize",
|
|
65638
|
+
gasOilWaterHeaterCosts: "annualize",
|
|
65639
|
+
gasOilFurnaceBoilerCosts: "annualize",
|
|
65640
|
+
electricalPanelCosts: "annualize",
|
|
65641
|
+
homeEnergyAuditCosts: "annualize",
|
|
65642
|
+
heatPumpBiomassCosts: "annualize",
|
|
65643
|
+
solarElectricCosts: "annualize",
|
|
65644
|
+
solarWaterHeatingCosts: "annualize",
|
|
65645
|
+
smallWindEnergyCosts: "annualize",
|
|
65646
|
+
geothermalHeatPumpCosts: "annualize",
|
|
65647
|
+
batteryStorageCosts: "annualize",
|
|
65648
|
+
fuelCellPropertyCosts: "annualize",
|
|
65649
|
+
// bases and balances
|
|
65650
|
+
pensionCostBasis: "keep",
|
|
65651
|
+
pensionBasisPreviouslyRecovered: "keep",
|
|
65652
|
+
rentalDepreciableBasis: "keep",
|
|
65653
|
+
// payments are Part III inputs, never income
|
|
65654
|
+
federalTaxWithheld: "keep",
|
|
65655
|
+
federalEstimatedPayments: "keep",
|
|
65656
|
+
federalExtensionPayment: "keep",
|
|
65657
|
+
priorYearTax: "keep",
|
|
65658
|
+
priorYearAGI: "keep",
|
|
65659
|
+
// out of scope: the form or the statute treats these differently by period
|
|
65660
|
+
foreignEarnedIncome: { refuse: "the foreign earned income exclusion is prorated by qualifying days (\xA7 911(b)(2)(A)), which Schedule AI does not annualize by a single factor" },
|
|
65661
|
+
priorYearShortTermCapitalLossCarryover: { refuse: "a prior-year capital loss carryover is not an amount of the period; neither the form nor the instructions say whether it is annualized" },
|
|
65662
|
+
priorYearLongTermCapitalLossCarryover: { refuse: "a prior-year capital loss carryover is not an amount of the period; neither the form nor the instructions say whether it is annualized" },
|
|
65663
|
+
qbiLossCarryforward: { refuse: "a prior-year qualified business loss carryforward is not an amount of the period; the instructions don't say whether it is annualized" },
|
|
65664
|
+
residentialCleanEnergyCarryforward: { refuse: "a prior-year credit carryforward is not an amount of the period" },
|
|
65665
|
+
advancePTC: { refuse: "the premium tax credit is reconciled by coverage month (\xA7 36B(b)(2)), not by annualizing a period" },
|
|
65666
|
+
slcspAnnualPremium: { refuse: "the premium tax credit is reconciled by coverage month (\xA7 36B(b)(2)), not by annualizing a period" },
|
|
65667
|
+
marketplacePremiumsPaid: { refuse: "the premium tax credit is reconciled by coverage month (\xA7 36B(b)(2)), not by annualizing a period" },
|
|
65668
|
+
parentTaxableIncome: { refuse: "Form 8615 uses the parent's annual taxable income" },
|
|
65669
|
+
pensionGrossPayments: { refuse: "the simplified method's tax-free part is a per-payment amount (\xA7 72(d)), not an annualized one \u2014 enter taxablePensionsAndAnnuities instead" },
|
|
65670
|
+
householdEmployeeCashWages: { refuse: "Schedule H thresholds apply to the calendar year's wages (\xA7 3121(x)), and the instructions give no period method" }
|
|
65671
|
+
};
|
|
65672
|
+
money43 = (facts2, id2) => {
|
|
65673
|
+
const f = facts2[id2];
|
|
65674
|
+
return f && f.type === "money" ? BigInt(f.value) : 0n;
|
|
65675
|
+
};
|
|
65676
|
+
dayNum = (iso) => {
|
|
65677
|
+
if (!/^\d{4}-\d{2}-\d{2}$/.test(iso))
|
|
65678
|
+
throw new Error(`invalid date "${iso}" (use YYYY-MM-DD)`);
|
|
65679
|
+
const t = Date.UTC(Number(iso.slice(0, 4)), Number(iso.slice(5, 7)) - 1, Number(iso.slice(8, 10)));
|
|
65680
|
+
const d3 = new Date(t);
|
|
65681
|
+
if (d3.toISOString().slice(0, 10) !== iso)
|
|
65682
|
+
throw new Error(`invalid date "${iso}"`);
|
|
65683
|
+
return Math.round(t / 864e5);
|
|
65684
|
+
};
|
|
65685
|
+
isoOf = (n) => new Date(n * 864e5).toISOString().slice(0, 10);
|
|
65686
|
+
isLeap = (y) => y % 4 === 0 && y % 100 !== 0 || y % 400 === 0;
|
|
65687
|
+
UNDERPAYMENT_RATES = {
|
|
65688
|
+
"2025-Q2": { percent: 7, source: "Rev. Rul. 2025-7, I.R.B. 2025-13 (IR-2025-29)" },
|
|
65689
|
+
"2025-Q3": { percent: 7, source: "Rev. Rul. 2025-11, I.R.B. 2025-23 (IR-2025-59)" },
|
|
65690
|
+
"2025-Q4": { percent: 7, source: "Rev. Rul. 2025-18, I.R.B. 2025-37 (IR-2025-87)" },
|
|
65691
|
+
"2026-Q1": { percent: 7, source: "Rev. Rul. 2025-22, I.R.B. 2025-48 (IR-2025-112)" },
|
|
65692
|
+
"2026-Q2": { percent: 6, source: "Rev. Rul. 2026-5, I.R.B. 2026-8" },
|
|
65693
|
+
"2026-Q3": { percent: 7, source: "Rev. Rul. 2026-10, I.R.B. 2026-22" },
|
|
65694
|
+
"2026-Q4": { percent: 7, source: "Rev. Rul. 2026-15, I.R.B. 2026-36 (IR-2026-98)" }
|
|
65695
|
+
};
|
|
65696
|
+
rd26 = (x) => {
|
|
65697
|
+
const neg3 = x < 0n;
|
|
65698
|
+
const a = neg3 ? -x : x;
|
|
65699
|
+
const r = (a + 50n) / 100n * 100n;
|
|
65700
|
+
return neg3 ? -r : r;
|
|
65701
|
+
};
|
|
65702
|
+
max029 = (x) => x > 0n ? x : 0n;
|
|
65703
|
+
minC = (a, b) => a < b ? a : b;
|
|
65704
|
+
fmt2 = (cents2, withCents = false) => {
|
|
65705
|
+
const neg3 = cents2 < 0n;
|
|
65706
|
+
const a = neg3 ? -cents2 : cents2;
|
|
65707
|
+
const dollars6 = (a / 100n).toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
|
|
65708
|
+
return `${neg3 ? "-" : ""}$${dollars6}${withCents ? "." + (a % 100n).toString().padStart(2, "0") : ""}`;
|
|
65709
|
+
};
|
|
65710
|
+
D13 = (c2) => fmt2(rd26(c2));
|
|
65711
|
+
mulRate2 = (c2, num, den) => {
|
|
65712
|
+
const p = c2 * num;
|
|
65713
|
+
const neg3 = p < 0n;
|
|
65714
|
+
const a = neg3 ? -p : p;
|
|
65715
|
+
const q = (a * 2n + den) / (2n * den);
|
|
65716
|
+
return neg3 ? -q : q;
|
|
65717
|
+
};
|
|
65718
|
+
ANNUALIZATION = [
|
|
65719
|
+
{ num: 4n, den: 1n, label: "4", pct: [225n, 1000n] },
|
|
65720
|
+
{ num: 12n, den: 5n, label: "2.4", pct: [45n, 100n] },
|
|
65721
|
+
{ num: 3n, den: 2n, label: "1.5", pct: [675n, 1000n] },
|
|
65722
|
+
{ num: 1n, den: 1n, label: "1", pct: [90n, 100n] }
|
|
65723
|
+
];
|
|
65724
|
+
MissingInput = class extends Error {
|
|
65725
|
+
missing;
|
|
65726
|
+
constructor(missing) {
|
|
65727
|
+
super(`Form 2210 needs: ${missing.join(", ")}`);
|
|
65728
|
+
this.missing = missing;
|
|
65729
|
+
this.name = "MissingInput";
|
|
65730
|
+
}
|
|
65731
|
+
};
|
|
65732
|
+
isObj = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
65733
|
+
}
|
|
65734
|
+
});
|
|
65735
|
+
|
|
64603
65736
|
// ../compose/dist/index.js
|
|
64604
65737
|
function makeStateTaxEvaluator(runTarget, input2) {
|
|
64605
65738
|
return (target, stateTaxableIncomeCents, extraFacts) => {
|
|
@@ -64733,6 +65866,7 @@ var init_dist4 = __esm({
|
|
|
64733
65866
|
init_va();
|
|
64734
65867
|
init_shape();
|
|
64735
65868
|
init_incomplete();
|
|
65869
|
+
init_form2210();
|
|
64736
65870
|
}
|
|
64737
65871
|
});
|
|
64738
65872
|
|
|
@@ -64741,7 +65875,7 @@ var COMPOSER_VERSION;
|
|
|
64741
65875
|
var init_version = __esm({
|
|
64742
65876
|
"dist/version.js"() {
|
|
64743
65877
|
"use strict";
|
|
64744
|
-
COMPOSER_VERSION = "0.
|
|
65878
|
+
COMPOSER_VERSION = "0.12.0";
|
|
64745
65879
|
}
|
|
64746
65880
|
});
|
|
64747
65881
|
|
|
@@ -75192,8 +76326,8 @@ var require_utils = __commonJS({
|
|
|
75192
76326
|
if (separator === -1) return void 0;
|
|
75193
76327
|
const address = host.slice(0, separator);
|
|
75194
76328
|
const escaped = address + "%25" + zone;
|
|
75195
|
-
const
|
|
75196
|
-
if (
|
|
76329
|
+
const derived3 = normalizeIPv6("[" + escaped + "]");
|
|
76330
|
+
if (derived3.isIPV6 === true && derived3.host === host) {
|
|
75197
76331
|
return "[" + escaped + "]";
|
|
75198
76332
|
}
|
|
75199
76333
|
return void 0;
|
|
@@ -78425,11 +79559,11 @@ var require_format = __commonJS({
|
|
|
78425
79559
|
}
|
|
78426
79560
|
function getFormat(fmtDef) {
|
|
78427
79561
|
const code = fmtDef instanceof RegExp ? (0, codegen_1.regexpCode)(fmtDef) : opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(schema)}` : void 0;
|
|
78428
|
-
const
|
|
79562
|
+
const fmt4 = gen.scopeValue("formats", { key: schema, ref: fmtDef, code });
|
|
78429
79563
|
if (typeof fmtDef == "object" && !(fmtDef instanceof RegExp)) {
|
|
78430
|
-
return [fmtDef.type || "string", fmtDef.validate, (0, codegen_1._)`${
|
|
79564
|
+
return [fmtDef.type || "string", fmtDef.validate, (0, codegen_1._)`${fmt4}.validate`];
|
|
78431
79565
|
}
|
|
78432
|
-
return ["string", fmtDef,
|
|
79566
|
+
return ["string", fmtDef, fmt4];
|
|
78433
79567
|
}
|
|
78434
79568
|
function validCondition() {
|
|
78435
79569
|
if (typeof formatDef == "object" && !(formatDef instanceof RegExp) && formatDef.async) {
|
|
@@ -79091,8 +80225,8 @@ var require_limit = __commonJS({
|
|
|
79091
80225
|
ref: self.formats,
|
|
79092
80226
|
code: opts.code.formats
|
|
79093
80227
|
});
|
|
79094
|
-
const
|
|
79095
|
-
cxt.fail$data((0, codegen_1.or)((0, codegen_1._)`typeof ${
|
|
80228
|
+
const fmt4 = gen.const("fmt", (0, codegen_1._)`${fmts}[${fCxt.schemaCode}]`);
|
|
80229
|
+
cxt.fail$data((0, codegen_1.or)((0, codegen_1._)`typeof ${fmt4} != "object"`, (0, codegen_1._)`${fmt4} instanceof RegExp`, (0, codegen_1._)`typeof ${fmt4}.compare != "function"`, compareCode(fmt4)));
|
|
79096
80230
|
}
|
|
79097
80231
|
function validateFormat() {
|
|
79098
80232
|
const format = fCxt.schema;
|
|
@@ -79102,15 +80236,15 @@ var require_limit = __commonJS({
|
|
|
79102
80236
|
if (typeof fmtDef != "object" || fmtDef instanceof RegExp || typeof fmtDef.compare != "function") {
|
|
79103
80237
|
throw new Error(`"${keyword}": format "${format}" does not define "compare" function`);
|
|
79104
80238
|
}
|
|
79105
|
-
const
|
|
80239
|
+
const fmt4 = gen.scopeValue("formats", {
|
|
79106
80240
|
key: format,
|
|
79107
80241
|
ref: fmtDef,
|
|
79108
80242
|
code: opts.code.formats ? (0, codegen_1._)`${opts.code.formats}${(0, codegen_1.getProperty)(format)}` : void 0
|
|
79109
80243
|
});
|
|
79110
|
-
cxt.fail$data(compareCode(
|
|
80244
|
+
cxt.fail$data(compareCode(fmt4));
|
|
79111
80245
|
}
|
|
79112
|
-
function compareCode(
|
|
79113
|
-
return (0, codegen_1._)`${
|
|
80246
|
+
function compareCode(fmt4) {
|
|
80247
|
+
return (0, codegen_1._)`${fmt4}.compare(${data}, ${schemaCode}) ${KWDs[keyword].fail} 0`;
|
|
79114
80248
|
}
|
|
79115
80249
|
},
|
|
79116
80250
|
dependencies: ["format"]
|
|
@@ -81377,7 +82511,7 @@ function zodForFact(f) {
|
|
|
81377
82511
|
}
|
|
81378
82512
|
switch (f.type) {
|
|
81379
82513
|
case "money":
|
|
81380
|
-
return
|
|
82514
|
+
return money44.describe(f.description);
|
|
81381
82515
|
case "bool":
|
|
81382
82516
|
return external_exports.boolean().describe(f.description);
|
|
81383
82517
|
case "int":
|
|
@@ -81410,6 +82544,14 @@ function shapeFor(ids) {
|
|
|
81410
82544
|
function factIdsForDomain(domain2) {
|
|
81411
82545
|
return corpus.facts.filter((f) => domainOf(f.id) === domain2).map((f) => f.id);
|
|
81412
82546
|
}
|
|
82547
|
+
function corpusFor(asOf, projection) {
|
|
82548
|
+
const year = Number(asOf.slice(0, 4));
|
|
82549
|
+
if (year > LAST_PUBLISHED_YEAR && projection)
|
|
82550
|
+
return getProjectedFederalCorpus({ year, inflationPercent: projection.inflationPercent, wageGrowthPercent: projection.wageGrowthPercent });
|
|
82551
|
+
if (projection)
|
|
82552
|
+
throw new Error(`projection is for tax years after ${LAST_PUBLISHED_YEAR}; ${year} is published law \u2014 drop projection`);
|
|
82553
|
+
return corpus;
|
|
82554
|
+
}
|
|
81413
82555
|
function flattenFactsArg(input2) {
|
|
81414
82556
|
const flat = {};
|
|
81415
82557
|
const put = (key, value, from) => {
|
|
@@ -81478,6 +82620,17 @@ function buildFactsValidated(factsArg, defaultTarget) {
|
|
|
81478
82620
|
};
|
|
81479
82621
|
delete input2.refuseDefaults;
|
|
81480
82622
|
delete input2.allowDefaults;
|
|
82623
|
+
let projection;
|
|
82624
|
+
if (input2.projection !== void 0) {
|
|
82625
|
+
const parsedProjection = projectionParam.safeParse(input2.projection);
|
|
82626
|
+
if (!parsedProjection.success || !parsedProjection.data)
|
|
82627
|
+
throw new Error("projection: expected { inflationPercent, wageGrowthPercent? }");
|
|
82628
|
+
projection = {
|
|
82629
|
+
inflationPercent: String(parsedProjection.data.inflationPercent),
|
|
82630
|
+
...parsedProjection.data.wageGrowthPercent !== void 0 ? { wageGrowthPercent: String(parsedProjection.data.wageGrowthPercent) } : {}
|
|
82631
|
+
};
|
|
82632
|
+
}
|
|
82633
|
+
delete input2.projection;
|
|
81481
82634
|
const flat = flattenFactsArg(input2);
|
|
81482
82635
|
if (docsRaw !== void 0) {
|
|
81483
82636
|
const parsedDocs = documentsShape.safeParse(docsRaw);
|
|
@@ -81538,10 +82691,11 @@ function buildFactsValidated(factsArg, defaultTarget) {
|
|
|
81538
82691
|
documentMissing,
|
|
81539
82692
|
documentUnsupported,
|
|
81540
82693
|
...w2Box1Cents !== void 0 ? { w2Box1Cents } : {},
|
|
81541
|
-
defaults
|
|
82694
|
+
defaults,
|
|
82695
|
+
...projection ? { projection } : {}
|
|
81542
82696
|
};
|
|
81543
82697
|
}
|
|
81544
|
-
var corpus,
|
|
82698
|
+
var corpus, money44, targetParam, asOfParam, BUSINESS_EXTRAS, DEPENDENT_EXTRAS, INDIVIDUAL_GROUPS, GROUP_NAMES, factById, GROUP_DESCRIPTIONS, OTHER_EARNED_INCOME, strictParam, refuseDefaultsParam, allowDefaultsParam, includeProofParam, projectionParam, individualNestedShape, businessShape, fiduciaryShape, dependentShape, FACT_SHAPE, STRICT_FLAT, factsObjectParam, INT_FACTS;
|
|
81545
82699
|
var init_schema = __esm({
|
|
81546
82700
|
"dist/schema.js"() {
|
|
81547
82701
|
"use strict";
|
|
@@ -81550,7 +82704,7 @@ var init_schema = __esm({
|
|
|
81550
82704
|
init_dist2();
|
|
81551
82705
|
init_documents();
|
|
81552
82706
|
corpus = getCorpus();
|
|
81553
|
-
|
|
82707
|
+
money44 = external_exports.union([external_exports.number(), external_exports.string()]).describe('dollars, e.g. 50000 or "1234.56"');
|
|
81554
82708
|
targetParam = (defaultLabel, determinations) => external_exports.string().optional().describe(`rule to derive (default: ${defaultLabel}).${determinations ? ` ${determinations}` : ""}`);
|
|
81555
82709
|
asOfParam = external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional().describe(`REQUIRED for computation: the law-in-force date \u2014 use the intended tax year's year-end (e.g. "2025-12-31" for TY2025). Omitting it is an error, never a default.`);
|
|
81556
82710
|
BUSINESS_EXTRAS = /* @__PURE__ */ new Set([
|
|
@@ -82374,6 +83528,10 @@ var init_schema = __esm({
|
|
|
82374
83528
|
refuseDefaultsParam = external_exports.boolean().optional().describe("refuse defaults: every fact the answer needs must be given explicitly. A fact left out refuses with NEEDS_FACTS even when it has a documented default; each entry in error.data.missing carries that `default` so you can pass the value or accept it via allowDefaults. A missing enum can hide the facts behind it, so a second call may list more. Default false: defaults apply and are listed under assumptions.");
|
|
82375
83529
|
allowDefaultsParam = external_exports.array(external_exports.string().max(80)).max(300).optional().describe("with refuseDefaults: fact ids whose documented defaults you accept (they still appear under assumptions)");
|
|
82376
83530
|
includeProofParam = external_exports.boolean().optional().describe("include the full proof artifact in the response as `proof` (PROOF-FORMAT v2: every applied rule, input, assumption and rounding, verifiable offline against corpusMerkleRoot; ~200 KB). Default false \u2014 the hashes alone are returned.");
|
|
83531
|
+
projectionParam = external_exports.object({
|
|
83532
|
+
inflationPercent: external_exports.union([external_exports.number(), external_exports.string()]).describe("assumed annual C-CPI-U growth after the index the IRS used for 2027, in percent (e.g. 2.5)"),
|
|
83533
|
+
wageGrowthPercent: external_exports.union([external_exports.number(), external_exports.string()]).optional().describe("assumed annual growth of the national average wage index (social security wage base), in percent; defaults to inflationPercent")
|
|
83534
|
+
}).strict().optional().describe("PROJECTION for tax years 2028-2035 (asOf in that year): every inflation-indexed amount is projected from 2027 by its own statutory indexing formula at these ASSUMED rates; known law (the SALT limit's 101% steps and 2030 return to $10,000, the end of the tips/overtime/car-loan/senior deductions after 2028) is applied as law. The result is labeled projected and its proof cites the assumption. Omit for 2025-2027 (published law).");
|
|
82377
83535
|
individualNestedShape = (() => {
|
|
82378
83536
|
const shape = {};
|
|
82379
83537
|
for (const [group, ids] of Object.entries(INDIVIDUAL_GROUPS)) {
|
|
@@ -82386,6 +83544,7 @@ var init_schema = __esm({
|
|
|
82386
83544
|
shape.includeProof = includeProofParam;
|
|
82387
83545
|
shape.refuseDefaults = refuseDefaultsParam;
|
|
82388
83546
|
shape.allowDefaults = allowDefaultsParam;
|
|
83547
|
+
shape.projection = projectionParam;
|
|
82389
83548
|
return shape;
|
|
82390
83549
|
})();
|
|
82391
83550
|
businessShape = (() => {
|
|
@@ -82424,6 +83583,15 @@ var init_schema = __esm({
|
|
|
82424
83583
|
});
|
|
82425
83584
|
|
|
82426
83585
|
// dist/server.js
|
|
83586
|
+
function projectedLabel(asOf, projection, corpusVersion) {
|
|
83587
|
+
return {
|
|
83588
|
+
taxYear: Number(asOf.slice(0, 4)),
|
|
83589
|
+
inflationPercent: projection.inflationPercent,
|
|
83590
|
+
wageGrowthPercent: projection.wageGrowthPercent ?? projection.inflationPercent,
|
|
83591
|
+
corpusVersion,
|
|
83592
|
+
warning: "PROJECTED, NOT PUBLISHED LAW: every inflation-indexed amount is the 2027 amount carried forward by its statutory indexing formula at the assumed rates; tell the user these are assumptions. Known law after 2027 (the SALT limit's steps, the end of the tips/overtime/car-loan/senior deductions after 2028) is applied as law."
|
|
83593
|
+
};
|
|
83594
|
+
}
|
|
82427
83595
|
function versions() {
|
|
82428
83596
|
return {
|
|
82429
83597
|
engine: ENGINE.version,
|
|
@@ -82471,14 +83639,14 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
82471
83639
|
});
|
|
82472
83640
|
if (!present)
|
|
82473
83641
|
return null;
|
|
82474
|
-
const
|
|
83642
|
+
const rd27 = (c2) => {
|
|
82475
83643
|
const neg3 = c2 < 0n;
|
|
82476
83644
|
const abs = neg3 ? -c2 : c2;
|
|
82477
83645
|
const r = (abs + 50n) / 100n * 100n;
|
|
82478
83646
|
return neg3 ? -r : r;
|
|
82479
83647
|
};
|
|
82480
|
-
const d3 = (c2) =>
|
|
82481
|
-
const
|
|
83648
|
+
const d3 = (c2) => fmt3(rd27(c2));
|
|
83649
|
+
const money45 = (id2) => {
|
|
82482
83650
|
const f = facts2[id2];
|
|
82483
83651
|
return f && f.type === "money" ? BigInt(String(f.value)) : 0n;
|
|
82484
83652
|
};
|
|
@@ -82489,7 +83657,7 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
82489
83657
|
for (const id2 of FORM_5695_FACTS) {
|
|
82490
83658
|
if (id2 === "fuelCellHalfKilowatts" || id2 === "residentialCleanEnergyCarryforward")
|
|
82491
83659
|
continue;
|
|
82492
|
-
const c2 =
|
|
83660
|
+
const c2 = money45(id2);
|
|
82493
83661
|
if (c2 !== 0n)
|
|
82494
83662
|
costs[id2] = d3(c2);
|
|
82495
83663
|
}
|
|
@@ -82505,14 +83673,14 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
82505
83673
|
};
|
|
82506
83674
|
}
|
|
82507
83675
|
return {
|
|
82508
|
-
"1_solar_electric": d3(
|
|
82509
|
-
"2_solar_water_heating": d3(
|
|
82510
|
-
"3_small_wind": d3(
|
|
82511
|
-
"4_geothermal_heat_pump": d3(
|
|
82512
|
-
"5b_battery_storage": d3(
|
|
83676
|
+
"1_solar_electric": d3(money45("solarElectricCosts")),
|
|
83677
|
+
"2_solar_water_heating": d3(money45("solarWaterHeatingCosts")),
|
|
83678
|
+
"3_small_wind": d3(money45("smallWindEnergyCosts")),
|
|
83679
|
+
"4_geothermal_heat_pump": d3(money45("geothermalHeatPumpCosts")),
|
|
83680
|
+
"5b_battery_storage": d3(money45("batteryStorageCosts")),
|
|
82513
83681
|
"6a_total": d3(E("clean.line6a")),
|
|
82514
83682
|
"6b_30_percent": d3(E("clean.line6b")),
|
|
82515
|
-
"8_fuel_cell_costs": d3(
|
|
83683
|
+
"8_fuel_cell_costs": d3(money45("fuelCellPropertyCosts")),
|
|
82516
83684
|
"9_30_percent": d3(E("clean.line9")),
|
|
82517
83685
|
"10_kilowatt_capacity_x_1000": d3(E("clean.line10")),
|
|
82518
83686
|
"11_smaller_of_9_or_10": d3(E("clean.line11")),
|
|
@@ -82521,28 +83689,28 @@ function composeForm5695(facts2, asOf, get) {
|
|
|
82521
83689
|
"14_limitation": d3(E("clean.line14")),
|
|
82522
83690
|
"15_residential_clean_energy_credit": d3(E("clean_energy_credit")),
|
|
82523
83691
|
"16_carryforward_to_next_year": d3(E("clean.carryforward")),
|
|
82524
|
-
"18a_insulation_air_sealing": d3(
|
|
83692
|
+
"18a_insulation_air_sealing": d3(money45("insulationAirSealingCosts")),
|
|
82525
83693
|
"18b_30_percent_max_1200": d3(E("improvement.line18b")),
|
|
82526
|
-
"19a_most_expensive_door": d3(
|
|
83694
|
+
"19a_most_expensive_door": d3(money45("exteriorDoorMostExpensiveCost")),
|
|
82527
83695
|
"19c_30_percent_max_250": d3(E("improvement.line19c")),
|
|
82528
|
-
"19f_other_doors": d3(
|
|
83696
|
+
"19f_other_doors": d3(money45("exteriorDoorOtherCosts")),
|
|
82529
83697
|
"19g_30_percent": d3(E("improvement.line19g")),
|
|
82530
83698
|
"19h_doors_max_500": d3(E("improvement.line19h")),
|
|
82531
|
-
"20c_windows_skylights": d3(
|
|
83699
|
+
"20c_windows_skylights": d3(money45("windowsSkylightsCosts")),
|
|
82532
83700
|
"20d_30_percent_max_600": d3(E("improvement.line20d")),
|
|
82533
|
-
"22c_central_air_conditioners": d3(
|
|
83701
|
+
"22c_central_air_conditioners": d3(money45("centralAirConditionerCosts")),
|
|
82534
83702
|
"22d_30_percent_max_600": d3(E("improvement.line22d")),
|
|
82535
|
-
"23c_gas_oil_water_heaters": d3(
|
|
83703
|
+
"23c_gas_oil_water_heaters": d3(money45("gasOilWaterHeaterCosts")),
|
|
82536
83704
|
"23d_30_percent_max_600": d3(E("improvement.line23d")),
|
|
82537
|
-
"24c_gas_oil_furnaces_boilers": d3(
|
|
83705
|
+
"24c_gas_oil_furnaces_boilers": d3(money45("gasOilFurnaceBoilerCosts")),
|
|
82538
83706
|
"24d_30_percent_max_600": d3(E("improvement.line24d")),
|
|
82539
|
-
"25c_enabling_property": d3(
|
|
83707
|
+
"25c_enabling_property": d3(money45("electricalPanelCosts")),
|
|
82540
83708
|
"25e_30_percent_max_600": d3(E("improvement.line25e")),
|
|
82541
|
-
"26b_home_energy_audit": d3(
|
|
83709
|
+
"26b_home_energy_audit": d3(money45("homeEnergyAuditCosts")),
|
|
82542
83710
|
"26c_30_percent_max_150": d3(E("improvement.line26c")),
|
|
82543
83711
|
"27_total": d3(E("improvement.line27")),
|
|
82544
83712
|
"28_smaller_of_27_or_1200": d3(E("improvement.line28")),
|
|
82545
|
-
"29g_heat_pumps_biomass": d3(
|
|
83713
|
+
"29g_heat_pumps_biomass": d3(money45("heatPumpBiomassCosts")),
|
|
82546
83714
|
"29h_30_percent_max_2000": d3(E("improvement.line29h")),
|
|
82547
83715
|
"30_total": d3(E("improvement.line30")),
|
|
82548
83716
|
"31_limitation": d3(E("improvement.line31")),
|
|
@@ -82576,18 +83744,19 @@ function createServer(options = {}) {
|
|
|
82576
83744
|
inputSchema: legacyJsonSchema(external_exports.object(individualNestedShape).strict())
|
|
82577
83745
|
}, async (args) => {
|
|
82578
83746
|
try {
|
|
82579
|
-
const { facts: facts2, asOf, target, documentNotes, defaults } = buildFactsValidated(args);
|
|
82580
|
-
const { value, proof } = evaluate(
|
|
83747
|
+
const { facts: facts2, asOf, target, documentNotes, defaults, projection } = buildFactsValidated(args);
|
|
83748
|
+
const { value, proof } = evaluate(corpusFor(asOf, projection), facts2, { asOf, target, ...defaults });
|
|
82581
83749
|
const cents2 = value.type === "money" ? value.cents : 0n;
|
|
82582
83750
|
return ok({
|
|
82583
83751
|
ok: true,
|
|
82584
83752
|
target,
|
|
82585
83753
|
asOf,
|
|
82586
|
-
answer:
|
|
83754
|
+
answer: fmt3(cents2),
|
|
82587
83755
|
valueCents: cents2.toString(),
|
|
82588
83756
|
...documentNotes.length ? { documentNotes } : {},
|
|
82589
83757
|
meaning: target === "us.federal.balance_due" ? cents2 < 0n ? "refund expected at filing" : "balance due at filing" : cents2 < 0n ? "net refund (refundable credits exceed tax)" : "net federal income tax",
|
|
82590
83758
|
assumptions: proof.assumptions,
|
|
83759
|
+
...projection ? { projected: projectedLabel(asOf, projection, proof.corpus.version) } : {},
|
|
82591
83760
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
82592
83761
|
artifactHash: proof.artifactHash,
|
|
82593
83762
|
...args.includeProof === true ? { proof } : {},
|
|
@@ -82609,7 +83778,7 @@ function createServer(options = {}) {
|
|
|
82609
83778
|
ok: true,
|
|
82610
83779
|
target,
|
|
82611
83780
|
asOf,
|
|
82612
|
-
answer:
|
|
83781
|
+
answer: fmt3(cents2),
|
|
82613
83782
|
valueCents: cents2.toString(),
|
|
82614
83783
|
assumptions: proof.assumptions,
|
|
82615
83784
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
@@ -82633,7 +83802,7 @@ function createServer(options = {}) {
|
|
|
82633
83802
|
ok: true,
|
|
82634
83803
|
target,
|
|
82635
83804
|
asOf,
|
|
82636
|
-
answer:
|
|
83805
|
+
answer: fmt3(cents2),
|
|
82637
83806
|
valueCents: cents2.toString(),
|
|
82638
83807
|
assumptions: proof.assumptions,
|
|
82639
83808
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
@@ -82652,7 +83821,7 @@ function createServer(options = {}) {
|
|
|
82652
83821
|
try {
|
|
82653
83822
|
const { facts: facts2, asOf, target } = buildFactsValidated(args, "us.federal.dependent.is_dependent");
|
|
82654
83823
|
const { value, proof } = evaluate(corpus, facts2, { asOf, target });
|
|
82655
|
-
const answer = value.type === "bool" ? value.value ? "yes" : "no" :
|
|
83824
|
+
const answer = value.type === "bool" ? value.value ? "yes" : "no" : fmt3(value.type === "money" ? value.cents : 0n);
|
|
82656
83825
|
return ok({
|
|
82657
83826
|
ok: true,
|
|
82658
83827
|
target,
|
|
@@ -82713,7 +83882,7 @@ function createServer(options = {}) {
|
|
|
82713
83882
|
const incomplete = built.documentUnsupported;
|
|
82714
83883
|
if (args.strict === true && incomplete.length)
|
|
82715
83884
|
throw new IncompleteReturnError(incomplete);
|
|
82716
|
-
const
|
|
83885
|
+
const rd27 = (c2) => {
|
|
82717
83886
|
const neg3 = c2 < 0n;
|
|
82718
83887
|
const abs = neg3 ? -c2 : c2;
|
|
82719
83888
|
const r = (abs + 50n) / 100n * 100n;
|
|
@@ -82724,20 +83893,21 @@ function createServer(options = {}) {
|
|
|
82724
83893
|
for (const [id2, v] of Object.entries(built.facts)) {
|
|
82725
83894
|
if (v.type === "money") {
|
|
82726
83895
|
const cents2 = BigInt(v.value);
|
|
82727
|
-
const r =
|
|
83896
|
+
const r = rd27(cents2);
|
|
82728
83897
|
if (r !== cents2)
|
|
82729
83898
|
roundedInputs += 1;
|
|
82730
83899
|
facts2[id2] = { type: "money", value: r.toString() };
|
|
82731
83900
|
} else
|
|
82732
83901
|
facts2[id2] = v;
|
|
82733
83902
|
}
|
|
82734
|
-
const w2Box1Cents = built.w2Box1Cents === void 0 ? void 0 :
|
|
83903
|
+
const w2Box1Cents = built.w2Box1Cents === void 0 ? void 0 : rd27(built.w2Box1Cents);
|
|
82735
83904
|
if (roundedInputs > 0) {
|
|
82736
83905
|
documentNotes.push(`whole-dollar rounding: ${roundedInputs} money input(s) rounded to the nearest dollar (50 cents up) after summing documents, before computation \u2014 Form 1040 instructions, Rounding Off to Whole Dollars`);
|
|
82737
83906
|
}
|
|
82738
|
-
const
|
|
83907
|
+
const returnCorpus = corpusFor(asOf, built.projection);
|
|
83908
|
+
const { proof } = evaluate(returnCorpus, facts2, { asOf, target: "us.federal.net_tax", ...built.defaults });
|
|
82739
83909
|
const get = (target) => {
|
|
82740
|
-
const { value } = evaluate(
|
|
83910
|
+
const { value } = evaluate(returnCorpus, facts2, { asOf, target, ...built.defaults });
|
|
82741
83911
|
return value.type === "money" ? value.cents : 0n;
|
|
82742
83912
|
};
|
|
82743
83913
|
const gross = get("us.federal.gross_income");
|
|
@@ -82750,7 +83920,7 @@ function createServer(options = {}) {
|
|
|
82750
83920
|
const ctc = get("us.federal.ctc");
|
|
82751
83921
|
const after = get("us.federal.income_tax_after_credits");
|
|
82752
83922
|
const other = get("us.federal.other_taxes");
|
|
82753
|
-
const
|
|
83923
|
+
const eitc2 = get("us.federal.eitc");
|
|
82754
83924
|
const actc = get("us.federal.actc");
|
|
82755
83925
|
const aotcRef = get("us.federal.education.aotc_refundable");
|
|
82756
83926
|
const refundable = get("us.federal.refundable_credits");
|
|
@@ -82773,10 +83943,10 @@ function createServer(options = {}) {
|
|
|
82773
83943
|
const extension = extFact && extFact.type === "money" ? BigInt(extFact.value) : 0n;
|
|
82774
83944
|
const estFact = facts2.federalEstimatedPayments;
|
|
82775
83945
|
const estimated = estFact && estFact.type === "money" ? BigInt(estFact.value) : 0n;
|
|
82776
|
-
const total24 =
|
|
82777
|
-
const payments =
|
|
83946
|
+
const total24 = rd27(after) + rd27(other);
|
|
83947
|
+
const payments = rd27(withheld) + rd27(refundable) + rd27(extension) + rd27(estimated);
|
|
82778
83948
|
const balance = payments - total24;
|
|
82779
|
-
const d3 = (c2) =>
|
|
83949
|
+
const d3 = (c2) => fmt3(rd27(c2));
|
|
82780
83950
|
return ok({
|
|
82781
83951
|
ok: true,
|
|
82782
83952
|
asOf,
|
|
@@ -82801,21 +83971,22 @@ function createServer(options = {}) {
|
|
|
82801
83971
|
"20_other_nonrefundable_credits": d3(line20),
|
|
82802
83972
|
"22_tax_after_credits": d3(after),
|
|
82803
83973
|
"23_other_taxes": d3(other),
|
|
82804
|
-
"24_total_tax":
|
|
83974
|
+
"24_total_tax": fmt3(total24),
|
|
82805
83975
|
"25d_withholding": d3(withheld),
|
|
82806
83976
|
"26_estimated_payments": d3(estimated),
|
|
82807
|
-
"27a_eitc": d3(
|
|
83977
|
+
"27a_eitc": d3(eitc2),
|
|
82808
83978
|
"28_actc": d3(actc),
|
|
82809
83979
|
"29_aotc_refundable": d3(aotcRef),
|
|
82810
83980
|
"32_refundable_credits": d3(refundable),
|
|
82811
|
-
...extension > 0n ? { "31_other_payments_incl_extension":
|
|
82812
|
-
"33_total_payments":
|
|
82813
|
-
"34_refund_or_37_owed": balance >= 0n ? `refund ${
|
|
83981
|
+
...extension > 0n ? { "31_other_payments_incl_extension": fmt3(rd27(extension)) } : {},
|
|
83982
|
+
"33_total_payments": fmt3(payments),
|
|
83983
|
+
"34_refund_or_37_owed": balance >= 0n ? `refund ${fmt3(balance)}` : `owed ${fmt3(-balance)}`
|
|
82814
83984
|
},
|
|
82815
83985
|
schedule3: Object.fromEntries(Object.entries(sched3).map(([k, v]) => [k, d3(v)])),
|
|
82816
83986
|
...form5695 ? { forms: { "5695": form5695 } } : {},
|
|
82817
83987
|
note: "Lines 9-37 are engine-computed and whole-dollar rounded; senior/tips/overtime/QBI deductions sit between 12e and 15 (lines 13-14). Line 1a is W-2 box 1 ONLY (Form 1040); non-W-2 earned income (e.g. pre-retirement disability) is line 1h. Gross document lines (4a/5a/6a) come from your transcription. Line 20 is the sum of the modeled Schedule 3 nonrefundable credits (schedule3); when any Form 5695 input is given, forms['5695'] carries that form's printed lines. Report these numbers as-is.",
|
|
82818
83988
|
assumptions: proof.assumptions,
|
|
83989
|
+
...built.projection ? { projected: projectedLabel(asOf, built.projection, proof.corpus.version) } : {},
|
|
82819
83990
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
82820
83991
|
artifactHash: proof.artifactHash,
|
|
82821
83992
|
proofScope: "the proof artifact covers the us.federal.net_tax derivation (lines 9-24); other lines are separate cited targets evaluated on the same rounded facts \u2014 request each with calculate_tax + includeProof for its own tree",
|
|
@@ -82825,27 +83996,72 @@ function createServer(options = {}) {
|
|
|
82825
83996
|
return fail(err);
|
|
82826
83997
|
}
|
|
82827
83998
|
});
|
|
83999
|
+
server.registerTool("compute_form_2210", {
|
|
84000
|
+
description: "Form 2210 \u2014 the estimated tax underpayment penalty (26 U.S.C. \xA7 6654) for tax years 2025-2027, composed from the printed form: Part I (the required annual payment: 90% of this year's tax, or 100% / 110% of last year's \u2014 pass priorYearTax and priorYearAGI in facts, or noPriorYearReturn), Part III Section A (underpayment per installment) and the Section B penalty worksheet (payments applied to the earliest underpayment first; each quarter's \xA7 6621 underpayment rate, by days). Pass `payments`: EVERY estimated tax payment with its date (include last year's overpayment applied to this year, dated April 15, and any payment with the return, dated the earlier of filing and April 15); withholding (facts.federalTaxWithheld) is treated as paid one-fourth on each due date unless you pass `withholdingByDate` (box D). Pass `periods` to also run Schedule AI, the annualized income installment method (box C): the CUMULATIVE amounts from January 1 through March 31, May 31 and August 31 for every income, deduction and credit amount that is nonzero for the year (same fact ids as facts; the tool lists any it needs). Each Schedule AI column is the whole return computed on the period's amounts \xD7 4, 2.4, 1.5 and 1, with the standard deduction in full, so every income type, deduction and credit the engine models is annualized; the columns refuse, with the reason, where the form doesn't settle the period treatment (foreign earned income exclusion, prior-year carryovers, premium tax credit, kiddie tax, household employment taxes, a dependent filer, the SALT cap binding in a period). The tool reports both methods and the lower penalty. A penalty that would run into a quarter whose rate the IRS hasn't announced is refused, with Section A still shown. Report the lines and notes verbatim.",
|
|
84001
|
+
inputSchema: legacyJsonSchema(external_exports.object({
|
|
84002
|
+
facts: factsObjectParam,
|
|
84003
|
+
payments: external_exports.array(external_exports.object({ date: external_exports.string(), amount: external_exports.union([external_exports.number(), external_exports.string()]) }).strict()).describe("every estimated tax payment for the year: { date: 'YYYY-MM-DD', amount: dollars } (an empty array if none)"),
|
|
84004
|
+
periods: external_exports.object({
|
|
84005
|
+
mar31: external_exports.record(external_exports.string(), external_exports.union([external_exports.number(), external_exports.string()])),
|
|
84006
|
+
may31: external_exports.record(external_exports.string(), external_exports.union([external_exports.number(), external_exports.string()])),
|
|
84007
|
+
aug31: external_exports.record(external_exports.string(), external_exports.union([external_exports.number(), external_exports.string()]))
|
|
84008
|
+
}).strict().optional().describe("Schedule AI: cumulative amounts from January 1 through each date, keyed by fact id, in dollars"),
|
|
84009
|
+
withholdingByDate: external_exports.array(external_exports.object({ date: external_exports.string(), amount: external_exports.union([external_exports.number(), external_exports.string()]) }).strict()).optional().describe("box D: withholding by the date actually withheld; must total facts.federalTaxWithheld"),
|
|
84010
|
+
noPriorYearReturn: external_exports.boolean().optional().describe("no return for the prior year, or it covered under 12 months: line 9 is line 5"),
|
|
84011
|
+
filedAndPaidInFullOn: external_exports.string().optional().describe("\xA7 6654(h): the date the return was filed and the tax paid in full, when by January 31")
|
|
84012
|
+
}).strict())
|
|
84013
|
+
}, async (args) => {
|
|
84014
|
+
try {
|
|
84015
|
+
const { facts: factArgs, ...options2 } = args;
|
|
84016
|
+
const built = buildFactsValidated(factArgs);
|
|
84017
|
+
const { asOf, defaults } = built;
|
|
84018
|
+
if (built.projection)
|
|
84019
|
+
throw new Error("Form 2210 is composed for the published tax years 2025-2027; drop projection");
|
|
84020
|
+
const run = (f, target) => {
|
|
84021
|
+
const { value } = evaluate(corpus, f, { asOf, target, ...defaults });
|
|
84022
|
+
return value.type === "money" ? value.cents : 0n;
|
|
84023
|
+
};
|
|
84024
|
+
const input2 = form2210InputFromArgs(options2, Number(asOf.slice(0, 4)), built.facts, (plain) => coerceFacts(corpus, plain));
|
|
84025
|
+
const form = composeForm2210(input2, run);
|
|
84026
|
+
if (form.penalty && "refused" in form.penalty) {
|
|
84027
|
+
return {
|
|
84028
|
+
content: [{ type: "text", text: JSON.stringify({ ok: false, error: { code: "NOT_MODELED", message: `Form 2210 penalty refused: ${form.penalty.refused}`, data: { form: { asOf, ...form } } } }, null, 2) }],
|
|
84029
|
+
isError: true
|
|
84030
|
+
};
|
|
84031
|
+
}
|
|
84032
|
+
return ok({ ok: true, asOf, form: "2210", ...form, corpusMerkleRoot: corpus.merkleRoot });
|
|
84033
|
+
} catch (err) {
|
|
84034
|
+
if (err instanceof MissingInput)
|
|
84035
|
+
return fail(new NeedsFactsError(err.missing.map((id2) => ({
|
|
84036
|
+
factId: id2,
|
|
84037
|
+
type: "money",
|
|
84038
|
+
description: id2.startsWith("periods.") ? "Schedule AI: the cumulative amount from January 1 through the period end (0 if none)" : "Form 2210 Part I line 8 needs it (or pass noPriorYearReturn)"
|
|
84039
|
+
}))));
|
|
84040
|
+
return fail(err);
|
|
84041
|
+
}
|
|
84042
|
+
});
|
|
82828
84043
|
server.registerTool("verify_tax_claim", {
|
|
82829
84044
|
description: `Verify a claimed tax amount (yours, a user's, or another tool's) against the law. Returns verdict 'verified' or 'refuted' with the correct value. Use this as a self-check before presenting any tax number. Put asOf (and target, if any) INSIDE the facts object \u2014 e.g. facts: {..., "asOf": "2025-12-31"} \u2014 otherwise the claim is checked under today's law.`,
|
|
82830
84045
|
inputSchema: legacyJsonSchema(external_exports.object({
|
|
82831
84046
|
facts: factsObjectParam,
|
|
82832
|
-
claimedAmount:
|
|
84047
|
+
claimedAmount: money44.describe("the amount to verify (negative = refund)"),
|
|
82833
84048
|
toleranceDollars: external_exports.number().min(0).optional().describe("default 1")
|
|
82834
84049
|
}).strict())
|
|
82835
84050
|
}, async (args) => {
|
|
82836
84051
|
try {
|
|
82837
|
-
const { facts: facts2, asOf, target } = buildFactsValidated(args.facts);
|
|
82838
|
-
const { value, proof } = evaluate(
|
|
84052
|
+
const { facts: facts2, asOf, target, projection } = buildFactsValidated(args.facts);
|
|
84053
|
+
const { value, proof } = evaluate(corpusFor(asOf, projection), facts2, { asOf, target });
|
|
82839
84054
|
const actual = value.type === "money" ? value.cents : 0n;
|
|
82840
84055
|
const claimed = parseDollars(args.claimedAmount);
|
|
82841
84056
|
const tolerance = BigInt(Math.round((args.toleranceDollars ?? 1) * 100));
|
|
82842
84057
|
const diff = actual - claimed;
|
|
82843
84058
|
const abs = diff < 0n ? -diff : diff;
|
|
82844
84059
|
return ok({
|
|
84060
|
+
...projection ? { projected: projectedLabel(asOf, projection, corpusFor(asOf, projection).version) } : {},
|
|
82845
84061
|
ok: true,
|
|
82846
84062
|
verdict: abs <= tolerance ? "verified" : "refuted",
|
|
82847
|
-
claimed:
|
|
82848
|
-
correct:
|
|
84063
|
+
claimed: fmt3(claimed),
|
|
84064
|
+
correct: fmt3(actual),
|
|
82849
84065
|
differenceCents: diff.toString(),
|
|
82850
84066
|
assumptions: proof.assumptions,
|
|
82851
84067
|
corpusMerkleRoot: proof.corpus.merkleRoot
|
|
@@ -82921,8 +84137,8 @@ function createServer(options = {}) {
|
|
|
82921
84137
|
}).strict())
|
|
82922
84138
|
}, async (args) => {
|
|
82923
84139
|
try {
|
|
82924
|
-
const { facts: facts2, asOf, target } = buildFactsValidated(args.facts);
|
|
82925
|
-
const result = findCliffs(
|
|
84140
|
+
const { facts: facts2, asOf, target, projection } = buildFactsValidated(args.facts);
|
|
84141
|
+
const result = findCliffs(corpusFor(asOf, projection), facts2, {
|
|
82926
84142
|
vary: args.vary,
|
|
82927
84143
|
fromCents: BigInt(Math.round(args.fromDollars * 100)),
|
|
82928
84144
|
toCents: BigInt(Math.round(args.toDollars * 100)),
|
|
@@ -82932,10 +84148,11 @@ function createServer(options = {}) {
|
|
|
82932
84148
|
...options.hosted ? { limits: HOSTED_CLIFF_LIMITS } : {}
|
|
82933
84149
|
});
|
|
82934
84150
|
return ok({
|
|
84151
|
+
...projection ? { projected: projectedLabel(asOf, projection, corpusFor(asOf, projection).version) } : {},
|
|
82935
84152
|
ok: true,
|
|
82936
84153
|
cliffs: result.cliffs.map((c2) => ({
|
|
82937
|
-
at:
|
|
82938
|
-
oneMoreCentCosts:
|
|
84154
|
+
at: fmt3(c2.atCents),
|
|
84155
|
+
oneMoreCentCosts: fmt3(c2.jumpCents)
|
|
82939
84156
|
})),
|
|
82940
84157
|
...result.truncated ? { truncated: true, note: "stopped early: the scan hit its evaluation or cliff budget; narrow the range or raise the step" } : {},
|
|
82941
84158
|
corpusMerkleRoot: result.corpusMerkleRoot
|
|
@@ -82949,15 +84166,16 @@ function createServer(options = {}) {
|
|
|
82949
84166
|
inputSchema: legacyJsonSchema(external_exports.object({ facts: factsObjectParam }).strict())
|
|
82950
84167
|
}, async (args) => {
|
|
82951
84168
|
try {
|
|
82952
|
-
const { facts: facts2, asOf, target } = buildFactsValidated(args.facts);
|
|
82953
|
-
const result = compareAcross(
|
|
84169
|
+
const { facts: facts2, asOf, target, projection } = buildFactsValidated(args.facts);
|
|
84170
|
+
const result = compareAcross(corpusFor(asOf, projection), facts2, {
|
|
82954
84171
|
vary: "filingStatus",
|
|
82955
84172
|
asOf,
|
|
82956
84173
|
target
|
|
82957
84174
|
});
|
|
82958
84175
|
return ok({
|
|
84176
|
+
...projection ? { projected: projectedLabel(asOf, projection, corpusFor(asOf, projection).version) } : {},
|
|
82959
84177
|
ok: true,
|
|
82960
|
-
scenarios: result.scenarios.map((s) => s.ok ? { filingStatus: s.value, result:
|
|
84178
|
+
scenarios: result.scenarios.map((s) => s.ok ? { filingStatus: s.value, result: fmt3(s.valueCents) } : { filingStatus: s.value, error: s.errorCode, message: s.errorMessage }),
|
|
82961
84179
|
corpusMerkleRoot: result.corpusMerkleRoot
|
|
82962
84180
|
});
|
|
82963
84181
|
} catch (err) {
|
|
@@ -82982,8 +84200,8 @@ function createServer(options = {}) {
|
|
|
82982
84200
|
title: h.title,
|
|
82983
84201
|
citation: h.citation,
|
|
82984
84202
|
effective: `[${h.effectiveFrom}, ${h.effectiveTo ?? "open"})`,
|
|
82985
|
-
byFilingStatus: Object.fromEntries(Object.entries(h.byFilingStatus).map(([k, v]) => [k,
|
|
82986
|
-
parameters: Object.fromEntries(Object.entries(h.parameters).map(([k, v]) => [k,
|
|
84203
|
+
byFilingStatus: Object.fromEntries(Object.entries(h.byFilingStatus).map(([k, v]) => [k, fmt3(BigInt(v))])),
|
|
84204
|
+
parameters: Object.fromEntries(Object.entries(h.parameters).map(([k, v]) => [k, fmt3(BigInt(v))]))
|
|
82987
84205
|
})),
|
|
82988
84206
|
corpusMerkleRoot: corpus.merkleRoot
|
|
82989
84207
|
});
|
|
@@ -83018,7 +84236,7 @@ function createServer(options = {}) {
|
|
|
83018
84236
|
description: "Fact-check a claimed dollar amount about tax law ('the 2026 MFJ standard deduction is $32,200', 'CTC is $2,000 per child') against the corpus. Returns verified / refuted (with the correct value and citation) / unknown. Never states a verdict it cannot ground.",
|
|
83019
84237
|
inputSchema: legacyJsonSchema(external_exports.object({
|
|
83020
84238
|
query: external_exports.string().max(2e3).describe("what the amount is, e.g. 'standard deduction'"),
|
|
83021
|
-
claimedAmount:
|
|
84239
|
+
claimedAmount: money44,
|
|
83022
84240
|
filingStatus: external_exports.enum(["single", "mfj", "mfs", "hoh", "qss"]).optional(),
|
|
83023
84241
|
asOf: external_exports.string().regex(/^\d{4}-\d{2}-\d{2}$/).optional()
|
|
83024
84242
|
}).strict())
|
|
@@ -83033,7 +84251,7 @@ function createServer(options = {}) {
|
|
|
83033
84251
|
return ok({
|
|
83034
84252
|
ok: true,
|
|
83035
84253
|
verdict: "verified",
|
|
83036
|
-
claimed:
|
|
84254
|
+
claimed: fmt3(BigInt(result.claimedCents)),
|
|
83037
84255
|
rule: result.matchedRuleId,
|
|
83038
84256
|
field: result.matchedField,
|
|
83039
84257
|
citation: result.citation,
|
|
@@ -83042,24 +84260,24 @@ function createServer(options = {}) {
|
|
|
83042
84260
|
});
|
|
83043
84261
|
}
|
|
83044
84262
|
const nearby = [
|
|
83045
|
-
{ rule: result.matchedRuleId, field: result.matchedField, value:
|
|
84263
|
+
{ rule: result.matchedRuleId, field: result.matchedField, value: fmt3(BigInt(result.actualCents)) },
|
|
83046
84264
|
...result.alternatives.flatMap((h) => [
|
|
83047
84265
|
...Object.entries(h.byFilingStatus).map(([k, v]) => ({
|
|
83048
84266
|
rule: h.ruleId,
|
|
83049
84267
|
field: k,
|
|
83050
|
-
value:
|
|
84268
|
+
value: fmt3(BigInt(v))
|
|
83051
84269
|
})),
|
|
83052
84270
|
...Object.entries(h.parameters).map(([k, v]) => ({
|
|
83053
84271
|
rule: h.ruleId,
|
|
83054
84272
|
field: k,
|
|
83055
|
-
value:
|
|
84273
|
+
value: fmt3(BigInt(v))
|
|
83056
84274
|
}))
|
|
83057
84275
|
])
|
|
83058
84276
|
].slice(0, 8);
|
|
83059
84277
|
return ok({
|
|
83060
84278
|
ok: true,
|
|
83061
84279
|
verdict: "refuted",
|
|
83062
|
-
claimed:
|
|
84280
|
+
claimed: fmt3(BigInt(result.claimedCents)),
|
|
83063
84281
|
message: "no corpus value near this query equals the claim \u2014 the actual values are listed below",
|
|
83064
84282
|
nearbyValues: nearby,
|
|
83065
84283
|
citation: result.citation,
|
|
@@ -83105,7 +84323,7 @@ function createServer(options = {}) {
|
|
|
83105
84323
|
});
|
|
83106
84324
|
return server;
|
|
83107
84325
|
}
|
|
83108
|
-
var
|
|
84326
|
+
var fmt3, FORM_5695_FACTS;
|
|
83109
84327
|
var init_server3 = __esm({
|
|
83110
84328
|
"dist/server.js"() {
|
|
83111
84329
|
"use strict";
|
|
@@ -83119,7 +84337,7 @@ var init_server3 = __esm({
|
|
|
83119
84337
|
init_dist4();
|
|
83120
84338
|
init_dist2();
|
|
83121
84339
|
init_schema();
|
|
83122
|
-
|
|
84340
|
+
fmt3 = (cents2) => {
|
|
83123
84341
|
const sign = cents2 < 0n ? "-" : "";
|
|
83124
84342
|
const abs = cents2 < 0n ? -cents2 : cents2;
|
|
83125
84343
|
const digits = (abs / 100n).toString();
|
|
@@ -83700,8 +84918,8 @@ var init_dist5 = __esm({
|
|
|
83700
84918
|
#body;
|
|
83701
84919
|
#init;
|
|
83702
84920
|
[getResponseCache]() {
|
|
83703
|
-
const
|
|
83704
|
-
const liveHeaders =
|
|
84921
|
+
const cache2 = this[cacheKey];
|
|
84922
|
+
const liveHeaders = cache2 && cache2[2] instanceof Headers ? cache2[2] : void 0;
|
|
83705
84923
|
delete this[cacheKey];
|
|
83706
84924
|
return this[responseCache] ||= new GlobalResponse(this.#body, liveHeaders ? {
|
|
83707
84925
|
status: this.#init?.status,
|
|
@@ -83730,10 +84948,10 @@ var init_dist5 = __esm({
|
|
|
83730
84948
|
];
|
|
83731
84949
|
}
|
|
83732
84950
|
get headers() {
|
|
83733
|
-
const
|
|
83734
|
-
if (
|
|
83735
|
-
if (!(
|
|
83736
|
-
return
|
|
84951
|
+
const cache2 = this[cacheKey];
|
|
84952
|
+
if (cache2) {
|
|
84953
|
+
if (!(cache2[2] instanceof Headers)) cache2[2] = new Headers(cache2[2] || (cache2[1] === null ? void 0 : { "content-type": defaultContentType }));
|
|
84954
|
+
return cache2[2];
|
|
83737
84955
|
}
|
|
83738
84956
|
return this[getResponseCache]().headers;
|
|
83739
84957
|
}
|
|
@@ -85516,6 +86734,35 @@ init_dist();
|
|
|
85516
86734
|
init_dist2();
|
|
85517
86735
|
import { readFileSync, writeFileSync } from "node:fs";
|
|
85518
86736
|
|
|
86737
|
+
// ../cli/dist/projection.js
|
|
86738
|
+
init_dist2();
|
|
86739
|
+
function corpusForFlags(asOf, flags) {
|
|
86740
|
+
const year = Number(asOf.slice(0, 4));
|
|
86741
|
+
if (flags.projectInflation === void 0) {
|
|
86742
|
+
if (flags.projectWageGrowth !== void 0)
|
|
86743
|
+
throw new Error("--project-wage-growth needs --project-inflation");
|
|
86744
|
+
return getCorpus();
|
|
86745
|
+
}
|
|
86746
|
+
if (year <= LAST_PUBLISHED_YEAR)
|
|
86747
|
+
throw new Error(`--project-inflation is for tax years after ${LAST_PUBLISHED_YEAR}; ${year} is published law \u2014 drop the flag`);
|
|
86748
|
+
return getProjectedFederalCorpus({ year, inflationPercent: String(flags.projectInflation), wageGrowthPercent: flags.projectWageGrowth });
|
|
86749
|
+
}
|
|
86750
|
+
function projectionLabel(asOf, flags, corpus2) {
|
|
86751
|
+
if (flags.projectInflation === void 0)
|
|
86752
|
+
return void 0;
|
|
86753
|
+
return {
|
|
86754
|
+
taxYear: Number(asOf.slice(0, 4)),
|
|
86755
|
+
inflationPercent: String(flags.projectInflation),
|
|
86756
|
+
wageGrowthPercent: String(flags.projectWageGrowth ?? flags.projectInflation),
|
|
86757
|
+
corpusVersion: corpus2.version,
|
|
86758
|
+
warning: "PROJECTED, NOT PUBLISHED LAW: every inflation-indexed amount is the 2027 amount carried forward by its statutory indexing formula at the assumed rates"
|
|
86759
|
+
};
|
|
86760
|
+
}
|
|
86761
|
+
var PROJECTION_HELP = {
|
|
86762
|
+
inflation: "project a tax year after 2027: assumed annual C-CPI-U growth in percent (e.g. 2.5); the answer is labeled projected",
|
|
86763
|
+
wage: "with --project-inflation: assumed annual average wage index growth in percent (social security wage base); default: the inflation rate"
|
|
86764
|
+
};
|
|
86765
|
+
|
|
85519
86766
|
// ../cli/dist/flags.js
|
|
85520
86767
|
init_dist();
|
|
85521
86768
|
init_dist2();
|
|
@@ -91794,8 +93041,14 @@ function print(obj) {
|
|
|
91794
93041
|
|
|
91795
93042
|
// ../cli/dist/commands/check.js
|
|
91796
93043
|
function runCheck(flags) {
|
|
91797
|
-
const corpus2 = getCorpus();
|
|
91798
93044
|
const asOf = flags.asOf ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
93045
|
+
let corpus2;
|
|
93046
|
+
try {
|
|
93047
|
+
corpus2 = corpusForFlags(asOf, flags);
|
|
93048
|
+
} catch (err) {
|
|
93049
|
+
return emitError(err, flags.json);
|
|
93050
|
+
}
|
|
93051
|
+
const projected = projectionLabel(asOf, flags, corpus2);
|
|
91799
93052
|
let plain = {};
|
|
91800
93053
|
if (flags.facts) {
|
|
91801
93054
|
try {
|
|
@@ -91839,6 +93092,7 @@ function runCheck(flags) {
|
|
|
91839
93092
|
differenceCents: diff.toString(),
|
|
91840
93093
|
toleranceCents: tolerance.toString(),
|
|
91841
93094
|
assumptions: proof.assumptions,
|
|
93095
|
+
...projected ? { projected } : {},
|
|
91842
93096
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
91843
93097
|
artifactHash: proof.artifactHash
|
|
91844
93098
|
});
|
|
@@ -92004,25 +93258,25 @@ function renderSummary(proof) {
|
|
|
92004
93258
|
const statusNode = findNode(root, "us.federal.income_tax_before_credits");
|
|
92005
93259
|
const statusTag = statusNode?.inputs?.filingStatus?.value !== void 0 ? STATUS_LABEL[String(statusNode.inputs.filingStatus.value)] : null;
|
|
92006
93260
|
const year = proof.asOf.slice(0, 4);
|
|
92007
|
-
const
|
|
93261
|
+
const money45 = (c2) => formatMoney(c2).padStart(14);
|
|
92008
93262
|
const lines = [];
|
|
92009
93263
|
lines.push(import_picocolors4.default.bold(`${statusTag ?? "Taxpayer"} \xB7 tax year ${year}`));
|
|
92010
93264
|
lines.push("");
|
|
92011
|
-
lines.push(` Income ${
|
|
92012
|
-
lines.push(` \u2212 Deductions ${
|
|
92013
|
-
lines.push(` = Taxable income ${
|
|
92014
|
-
lines.push(` Tax before credits ${
|
|
93265
|
+
lines.push(` Income ${money45(agi2)}`);
|
|
93266
|
+
lines.push(` \u2212 Deductions ${money45(deductions)}${dedParts.length ? import_picocolors4.default.dim(` (${dedParts.join(" + ")})`) : ""}`);
|
|
93267
|
+
lines.push(` = Taxable income ${money45(taxable2)}`);
|
|
93268
|
+
lines.push(` Tax before credits ${money45(before)}`);
|
|
92015
93269
|
if (amt > 0n) {
|
|
92016
|
-
lines.push(` + Alternative min tax${
|
|
93270
|
+
lines.push(` + Alternative min tax${money45(amt)}${import_picocolors4.default.dim(" (Form 6251)")}`);
|
|
92017
93271
|
}
|
|
92018
93272
|
if (aptcRepayment > 0n) {
|
|
92019
|
-
lines.push(` + Excess APTC ${
|
|
93273
|
+
lines.push(` + Excess APTC ${money45(aptcRepayment)}${import_picocolors4.default.dim(" (Form 8962 repayment)")}`);
|
|
92020
93274
|
}
|
|
92021
|
-
lines.push(` \u2212 Credits ${
|
|
93275
|
+
lines.push(` \u2212 Credits ${money45(education + ctc + refundable)}${creditParts.length ? import_picocolors4.default.dim(` (${creditParts.join(" + ")})`) : ""}`);
|
|
92022
93276
|
if (otherTaxes > 0n) {
|
|
92023
|
-
lines.push(` + Other taxes ${
|
|
93277
|
+
lines.push(` + Other taxes ${money45(otherTaxes)}${import_picocolors4.default.dim(" (SE tax / Add'l Medicare / NIIT)")}`);
|
|
92024
93278
|
}
|
|
92025
|
-
const row2 = (label, amount, paint = (s) => s) => ` ${paint(label.padEnd(21))}${paint(
|
|
93279
|
+
const row2 = (label, amount, paint = (s) => s) => ` ${paint(label.padEnd(21))}${paint(money45(amount))}`;
|
|
92026
93280
|
lines.push(import_picocolors4.default.dim(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"));
|
|
92027
93281
|
if (net < 0n) {
|
|
92028
93282
|
lines.push(row2("Your refund", -net, (s) => import_picocolors4.default.bold(import_picocolors4.default.green(s))));
|
|
@@ -92110,8 +93364,14 @@ function renderNode(node2, prefix, isLast, lines, seen) {
|
|
|
92110
93364
|
|
|
92111
93365
|
// ../cli/dist/commands/eval.js
|
|
92112
93366
|
function runEval(flags) {
|
|
92113
|
-
const corpus2 = getCorpus();
|
|
92114
93367
|
const asOf = flags.asOf ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
93368
|
+
let corpus2;
|
|
93369
|
+
try {
|
|
93370
|
+
corpus2 = corpusForFlags(asOf, flags);
|
|
93371
|
+
} catch (err) {
|
|
93372
|
+
return emitError(err, flags.json);
|
|
93373
|
+
}
|
|
93374
|
+
const projected = projectionLabel(asOf, flags, corpus2);
|
|
92115
93375
|
let plain = {};
|
|
92116
93376
|
if (flags.facts) {
|
|
92117
93377
|
try {
|
|
@@ -92141,6 +93401,7 @@ function runEval(flags) {
|
|
|
92141
93401
|
value: proof.root.value,
|
|
92142
93402
|
formatted: formatValue(proof.root.value),
|
|
92143
93403
|
assumptions: proof.assumptions,
|
|
93404
|
+
...projected ? { projected } : {},
|
|
92144
93405
|
corpusMerkleRoot: proof.corpus.merkleRoot,
|
|
92145
93406
|
artifactHash: proof.artifactHash,
|
|
92146
93407
|
proof
|
|
@@ -92148,6 +93409,8 @@ function runEval(flags) {
|
|
|
92148
93409
|
} else {
|
|
92149
93410
|
const summary = renderSummary(proof);
|
|
92150
93411
|
console.log();
|
|
93412
|
+
if (projected)
|
|
93413
|
+
console.log(import_picocolors6.default.yellow(import_picocolors6.default.bold(`PROJECTED ${projected.taxYear} \u2014 not published law (C-CPI-U +${projected.inflationPercent}%/yr, wages +${projected.wageGrowthPercent}%/yr assumed)`)) + "\n");
|
|
92151
93414
|
if (summary) {
|
|
92152
93415
|
console.log(summary);
|
|
92153
93416
|
console.log();
|
|
@@ -92475,7 +93738,8 @@ init_dist3();
|
|
|
92475
93738
|
init_dist2();
|
|
92476
93739
|
import { readFileSync as readFileSync3 } from "node:fs";
|
|
92477
93740
|
function setup(flags) {
|
|
92478
|
-
const
|
|
93741
|
+
const asOf = flags.asOf ?? (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
93742
|
+
const corpus2 = corpusForFlags(asOf, flags);
|
|
92479
93743
|
let plain = {};
|
|
92480
93744
|
if (flags.facts)
|
|
92481
93745
|
plain = JSON.parse(readFileSync3(flags.facts, "utf8"));
|
|
@@ -92485,7 +93749,7 @@ function setup(flags) {
|
|
|
92485
93749
|
corpus: corpus2,
|
|
92486
93750
|
base,
|
|
92487
93751
|
vary: flags.vary ?? "wages",
|
|
92488
|
-
asOf
|
|
93752
|
+
asOf,
|
|
92489
93753
|
target: flags.target ?? DEFAULT_TARGET
|
|
92490
93754
|
};
|
|
92491
93755
|
}
|
|
@@ -92793,21 +94057,110 @@ function runState(flags) {
|
|
|
92793
94057
|
}
|
|
92794
94058
|
}
|
|
92795
94059
|
|
|
92796
|
-
// ../cli/dist/commands/
|
|
94060
|
+
// ../cli/dist/commands/form2210.js
|
|
92797
94061
|
var import_picocolors15 = __toESM(require_picocolors(), 1);
|
|
92798
94062
|
init_dist();
|
|
92799
94063
|
init_dist2();
|
|
94064
|
+
init_dist4();
|
|
92800
94065
|
import { readFileSync as readFileSync5 } from "node:fs";
|
|
94066
|
+
function runForm2210(flags) {
|
|
94067
|
+
const corpus2 = getCorpus();
|
|
94068
|
+
let args;
|
|
94069
|
+
try {
|
|
94070
|
+
args = JSON.parse(readFileSync5(flags.facts, "utf8"));
|
|
94071
|
+
if (!args || typeof args !== "object" || Array.isArray(args))
|
|
94072
|
+
throw new Error("expected a JSON object");
|
|
94073
|
+
} catch (err) {
|
|
94074
|
+
return emitError(new Error(`cannot read ${flags.facts}: ${err.message}`), flags.json);
|
|
94075
|
+
}
|
|
94076
|
+
const asOf = flags.asOf ?? (typeof args.asOf === "string" ? args.asOf : void 0);
|
|
94077
|
+
if (!asOf) {
|
|
94078
|
+
return emitError(new Error(`--as-of is required (the tax year's year-end, e.g. 2025-12-31), or put "asOf" in the file`), flags.json);
|
|
94079
|
+
}
|
|
94080
|
+
try {
|
|
94081
|
+
const { facts: plainFacts, asOf: _ignored, ...options } = args;
|
|
94082
|
+
const facts2 = coerceFacts(corpus2, plainFacts ?? {});
|
|
94083
|
+
const run = (f, target) => {
|
|
94084
|
+
const { value } = evaluate(corpus2, f, { asOf, target });
|
|
94085
|
+
return value.type === "money" ? value.cents : 0n;
|
|
94086
|
+
};
|
|
94087
|
+
const input2 = form2210InputFromArgs(options, Number(asOf.slice(0, 4)), facts2, (plain) => coerceFacts(corpus2, plain));
|
|
94088
|
+
const form = composeForm2210(input2, run);
|
|
94089
|
+
const refused = form.penalty && "refused" in form.penalty ? form.penalty.refused : void 0;
|
|
94090
|
+
if (flags.json && refused) {
|
|
94091
|
+
print({ ok: false, error: { code: "NOT_MODELED", message: `Form 2210 penalty refused: ${refused}`, data: { form: { asOf, ...form } } } });
|
|
94092
|
+
return EXIT.NOT_COVERED;
|
|
94093
|
+
}
|
|
94094
|
+
if (flags.json) {
|
|
94095
|
+
print({ ok: true, asOf, form: "2210", ...form, corpusMerkleRoot: corpus2.merkleRoot });
|
|
94096
|
+
return EXIT.OK;
|
|
94097
|
+
}
|
|
94098
|
+
const section = (title, lines) => {
|
|
94099
|
+
console.log(import_picocolors15.default.bold(title));
|
|
94100
|
+
const width = Math.max(...Object.keys(lines).map((k) => k.length)) + 2;
|
|
94101
|
+
for (const [k, v] of Object.entries(lines))
|
|
94102
|
+
console.log(` ${k.padEnd(width)}${v}`);
|
|
94103
|
+
console.log();
|
|
94104
|
+
};
|
|
94105
|
+
console.log();
|
|
94106
|
+
section(`Form 2210 (${form.taxYear}) \u2014 Part I`, form.partI);
|
|
94107
|
+
if (form.noPenalty)
|
|
94108
|
+
console.log(import_picocolors15.default.green(` ${form.noPenalty}
|
|
94109
|
+
`));
|
|
94110
|
+
if (form.scheduleAI && "columns" in form.scheduleAI) {
|
|
94111
|
+
for (const col of form.scheduleAI.columns)
|
|
94112
|
+
section(`Schedule AI ${col.column}`, Object.fromEntries(Object.entries(col).filter(([k]) => k !== "column")));
|
|
94113
|
+
} else if (form.scheduleAI) {
|
|
94114
|
+
console.log(import_picocolors15.default.yellow("Schedule AI refused:"));
|
|
94115
|
+
for (const r of form.scheduleAI.refused)
|
|
94116
|
+
console.log(import_picocolors15.default.yellow(` ${r}`));
|
|
94117
|
+
console.log();
|
|
94118
|
+
}
|
|
94119
|
+
for (const m of ["regular", "annualized"]) {
|
|
94120
|
+
const p = form.partIII?.[m];
|
|
94121
|
+
if (!p)
|
|
94122
|
+
continue;
|
|
94123
|
+
console.log(import_picocolors15.default.bold(`Part III \u2014 ${m === "regular" ? "regular installments" : "annualized (Schedule AI) installments"}`));
|
|
94124
|
+
console.log(` due dates ${p.dueDates.join(" ")}`);
|
|
94125
|
+
for (const [line2, cols] of Object.entries(p.sectionA))
|
|
94126
|
+
console.log(` line ${line2.padEnd(4)}${cols.map((c2) => c2.padStart(12)).join("")}`);
|
|
94127
|
+
for (const w of p.worksheet)
|
|
94128
|
+
console.log(import_picocolors15.default.dim(` (${w.column}) ${w.amount} from ${w.from} to ${w.paidOn}: ${w.days} days at ${w.ratePercent}% = ${w.penalty}`));
|
|
94129
|
+
console.log(p.penalty ? ` penalty: ${import_picocolors15.default.bold(p.penalty)}` : import_picocolors15.default.yellow(` ${p.refused}`));
|
|
94130
|
+
console.log();
|
|
94131
|
+
}
|
|
94132
|
+
if (form.penalty) {
|
|
94133
|
+
console.log("method" in form.penalty ? import_picocolors15.default.bold(`Line 19 penalty: ${form.penalty.amount} (${form.penalty.method} method${form.boxes.length ? `; box ${form.boxes.join(", ")}` : ""})`) : import_picocolors15.default.yellow(form.penalty.refused));
|
|
94134
|
+
console.log();
|
|
94135
|
+
}
|
|
94136
|
+
for (const n of form.notes)
|
|
94137
|
+
console.log(import_picocolors15.default.dim(` ${n}`));
|
|
94138
|
+
if (form.notes.length)
|
|
94139
|
+
console.log();
|
|
94140
|
+
return refused ? EXIT.NOT_COVERED : EXIT.OK;
|
|
94141
|
+
} catch (err) {
|
|
94142
|
+
if (err instanceof MissingInput) {
|
|
94143
|
+
return emitError(new NeedsFactsError(err.missing.map((id2) => ({ factId: id2, type: "money", description: "Form 2210 needs this amount" }))), flags.json);
|
|
94144
|
+
}
|
|
94145
|
+
return emitError(err, flags.json);
|
|
94146
|
+
}
|
|
94147
|
+
}
|
|
94148
|
+
|
|
94149
|
+
// ../cli/dist/commands/verify.js
|
|
94150
|
+
var import_picocolors16 = __toESM(require_picocolors(), 1);
|
|
94151
|
+
init_dist();
|
|
94152
|
+
init_dist2();
|
|
94153
|
+
import { readFileSync as readFileSync6 } from "node:fs";
|
|
92801
94154
|
function runVerify(proofPath, flags) {
|
|
92802
94155
|
let artifact;
|
|
92803
94156
|
try {
|
|
92804
|
-
artifact = JSON.parse(
|
|
94157
|
+
artifact = JSON.parse(readFileSync6(proofPath, "utf8"));
|
|
92805
94158
|
} catch (err) {
|
|
92806
94159
|
return emitError(new Error(`cannot read proof ${proofPath}: ${err.message}`), flags.json);
|
|
92807
94160
|
}
|
|
92808
94161
|
let result;
|
|
92809
94162
|
try {
|
|
92810
|
-
result = verifyProof(artifact,
|
|
94163
|
+
result = verifyProof(artifact, corpusForVersion(String(artifact?.corpus?.version ?? "")));
|
|
92811
94164
|
} catch (err) {
|
|
92812
94165
|
return emitError(err, flags.json);
|
|
92813
94166
|
}
|
|
@@ -92844,19 +94197,19 @@ function runVerify(proofPath, flags) {
|
|
|
92844
94197
|
}
|
|
92845
94198
|
if (result.ok) {
|
|
92846
94199
|
console.log();
|
|
92847
|
-
console.log(`${
|
|
92848
|
-
console.log(` value ${
|
|
94200
|
+
console.log(`${import_picocolors16.default.green("\u2713 VERIFIED")} ${import_picocolors16.default.bold(artifact.target)}`);
|
|
94201
|
+
console.log(` value ${import_picocolors16.default.green(formatValue(artifact.root.value))} (as of ${artifact.asOf})`);
|
|
92849
94202
|
console.log(` corpus ${result.corpusMerkleRoot}`);
|
|
92850
94203
|
console.log(` artifact ${artifact.artifactHash}`);
|
|
92851
|
-
console.log(
|
|
94204
|
+
console.log(import_picocolors16.default.dim(" independently re-derived from the corpus; every node matches the recorded derivation"));
|
|
92852
94205
|
console.log();
|
|
92853
94206
|
return EXIT.OK;
|
|
92854
94207
|
}
|
|
92855
94208
|
console.error();
|
|
92856
|
-
console.error(`${
|
|
94209
|
+
console.error(`${import_picocolors16.default.red("\u2717 VERIFICATION FAILED")} (${result.reason})`);
|
|
92857
94210
|
console.error(` ${result.message}`);
|
|
92858
94211
|
if (result.path)
|
|
92859
|
-
console.error(` divergence at: ${
|
|
94212
|
+
console.error(` divergence at: ${import_picocolors16.default.bold(result.path)}`);
|
|
92860
94213
|
if (result.expected)
|
|
92861
94214
|
console.error(` expected: ${result.expected}`);
|
|
92862
94215
|
if (result.actual)
|
|
@@ -92901,12 +94254,12 @@ Every command accepts --json (single JSON object on stdout, ok: true|false).
|
|
|
92901
94254
|
Exit codes: 0 ok \xB7 2 needs more facts (retry with them) \xB7 3 not covered by the corpus (don't retry) \xB7 1 other error.`).version("0.1.0");
|
|
92902
94255
|
var evalCmd = program2.command("eval").description("compute a tax answer and print its proof tree").option("--facts <file>", "JSON facts file (inline flags below override it)");
|
|
92903
94256
|
registerFactFlags(evalCmd);
|
|
92904
|
-
evalCmd.option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to derive (default: income tax after credits)").option("--proof <file>", "write the proof artifact JSON to this file").option("--brief", "plain-English summary only (skip the proof tree)").option("--assumptions", "list every default the engine relied on (folded by default)").option("--json", "print the proof artifact JSON instead of the tree").option("--refuse-defaults", "refuse instead of assuming: any fact not given exits 2 (NEEDS_FACTS), defaults included").option("--allow-default <factIds...>", "with --refuse-defaults: fact ids whose defaults you accept").action((flags) => {
|
|
94257
|
+
evalCmd.option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to derive (default: income tax after credits)").option("--proof <file>", "write the proof artifact JSON to this file").option("--brief", "plain-English summary only (skip the proof tree)").option("--assumptions", "list every default the engine relied on (folded by default)").option("--json", "print the proof artifact JSON instead of the tree").option("--refuse-defaults", "refuse instead of assuming: any fact not given exits 2 (NEEDS_FACTS), defaults included").option("--project-inflation <percent>", PROJECTION_HELP.inflation).option("--project-wage-growth <percent>", PROJECTION_HELP.wage).option("--allow-default <factIds...>", "with --refuse-defaults: fact ids whose defaults you accept").action((flags) => {
|
|
92905
94258
|
process.exitCode = runEval(flags);
|
|
92906
94259
|
});
|
|
92907
94260
|
var checkCmd = program2.command("check").description("verify a claimed tax amount (e.g. an AI agent's answer) against the law \u2014 exit 0 verified, 1 refuted").option("--facts <file>", "JSON facts file (inline flags below override it)");
|
|
92908
94261
|
registerFactFlags(checkCmd);
|
|
92909
|
-
checkCmd.requiredOption("--expect <dollars>", "the claimed amount to verify (negative = refund)").option("--tolerance <dollars>", "allowed absolute difference", "1").option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to check (default: net tax; balance due if --withheld)").option("--proof <file>", "write the proof artifact JSON to this file").option("--json", "machine-readable verdict").option("--refuse-defaults", "refuse instead of assuming: any fact not given exits 2 (NEEDS_FACTS), defaults included").option("--allow-default <factIds...>", "with --refuse-defaults: fact ids whose defaults you accept").action((flags) => {
|
|
94262
|
+
checkCmd.requiredOption("--expect <dollars>", "the claimed amount to verify (negative = refund)").option("--tolerance <dollars>", "allowed absolute difference", "1").option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to check (default: net tax; balance due if --withheld)").option("--proof <file>", "write the proof artifact JSON to this file").option("--json", "machine-readable verdict").option("--refuse-defaults", "refuse instead of assuming: any fact not given exits 2 (NEEDS_FACTS), defaults included").option("--project-inflation <percent>", PROJECTION_HELP.inflation).option("--project-wage-growth <percent>", PROJECTION_HELP.wage).option("--allow-default <factIds...>", "with --refuse-defaults: fact ids whose defaults you accept").action((flags) => {
|
|
92910
94263
|
process.exitCode = runCheck(flags);
|
|
92911
94264
|
});
|
|
92912
94265
|
program2.command("facts").description("list every input fact the corpus understands").option("--json", "machine-readable output").action((flags) => {
|
|
@@ -92954,6 +94307,9 @@ program2.command("occupation").description("is this a \xA7 224 tipped occupation
|
|
|
92954
94307
|
program2.command("state").description("compose a state return (IL-1040, VA 760, CA 540, NY IT-201, PA-40, NJ-1040, OH IT 1040, NC D-400, GA 500, MD 502, MO-1040, WI Form 1, MN M1, SC1040, AL Form 40, OR-40, OK Form 511, CT-1040, KS K-40, AR AR1000F, NM PIT-1, NE 1040N, ID Form 40, WV IT-140, ME 1040ME) from a composer-facts JSON file").requiredOption("--facts <file>", "composer facts JSON (same shape as the MCP compute_state_return tool)").option("--as-of <date>", "law in force on this ISO date (default: today)").option("--json", "machine-readable output").action((flags) => {
|
|
92955
94308
|
process.exitCode = runState({ facts: flags.facts, asOf: flags.asOf, json: flags.json });
|
|
92956
94309
|
});
|
|
94310
|
+
program2.command("form2210").description("Form 2210: the estimated tax underpayment penalty (\xA7 6654), with Schedule AI (the annualized income installment method), from a JSON file").requiredOption("--facts <file>", "JSON: { facts, payments, periods?, withholdingByDate?, noPriorYearReturn?, filedAndPaidInFullOn? } (same shape as the MCP compute_form_2210 tool)").option("--as-of <date>", "the tax year's rules (e.g. 2025-12-31); required unless the file has asOf").option("--json", "machine-readable output").action((flags) => {
|
|
94311
|
+
process.exitCode = runForm2210({ facts: flags.facts, asOf: flags.asOf, json: flags.json });
|
|
94312
|
+
});
|
|
92957
94313
|
program2.command("signup").description("get OpenTax updates by email (new features and other things worth knowing)").argument("<email>", "your email address").option("--json", "machine-readable output").action(async (email3, flags) => {
|
|
92958
94314
|
process.exitCode = await runSignup(email3, { json: flags.json });
|
|
92959
94315
|
});
|
|
@@ -92967,7 +94323,7 @@ function solverCommand(name, description) {
|
|
|
92967
94323
|
const cmd = program2.command(name).description(description);
|
|
92968
94324
|
cmd.option("--facts <file>", "JSON facts file (inline flags below override it)");
|
|
92969
94325
|
registerFactFlags(cmd);
|
|
92970
|
-
cmd.option("--vary <factId>", "fact to vary", "wages").option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to derive (default: net tax)").option("--json", "machine-readable output");
|
|
94326
|
+
cmd.option("--vary <factId>", "fact to vary", "wages").option("--as-of <date>", "evaluate rules as of this ISO date (default: today)").option("--target <ruleId>", "rule to derive (default: net tax)").option("--project-inflation <percent>", PROJECTION_HELP.inflation).option("--project-wage-growth <percent>", PROJECTION_HELP.wage).option("--json", "machine-readable output");
|
|
92971
94327
|
return cmd;
|
|
92972
94328
|
}
|
|
92973
94329
|
solverCommand("sweep", "evaluate the target across a range of one input").requiredOption("--from <dollars>", "range start").requiredOption("--to <dollars>", "range end").option("--step <dollars>", "step size", "1000").option("--csv", "CSV output").action((flags) => {
|
|
@@ -93001,7 +94357,7 @@ function runCli(argv) {
|
|
|
93001
94357
|
|
|
93002
94358
|
// dist/phone-home.js
|
|
93003
94359
|
init_version();
|
|
93004
|
-
import { mkdirSync, readFileSync as
|
|
94360
|
+
import { mkdirSync, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "node:fs";
|
|
93005
94361
|
import { homedir } from "node:os";
|
|
93006
94362
|
import { join } from "node:path";
|
|
93007
94363
|
var ENDPOINT = "https://opentax.invaro.ai/api/t";
|
|
@@ -93013,7 +94369,7 @@ function firstRunNotice() {
|
|
|
93013
94369
|
const dir = join(process.env.XDG_CONFIG_HOME || join(homedir(), ".config"), "opentax");
|
|
93014
94370
|
const flag = join(dir, "notice-shown");
|
|
93015
94371
|
try {
|
|
93016
|
-
|
|
94372
|
+
readFileSync7(flag);
|
|
93017
94373
|
return false;
|
|
93018
94374
|
} catch {
|
|
93019
94375
|
}
|