'use strict';

var object = require('./object-8e0c0d37.js');
require('json-stringify-deterministic');
require('immer');
require('crypto');
require('fs');
require('https');
require('path');

// node_modules/@acaldas/document-model-graphql/dist/index-fe999334.js
var g = (e) => e != null;
var y = object.z.any().refine((e) => g(e));
var d = object.z.enum(["ADD_ACCOUNT"]);
var b = object.z.enum(["ADD_AUDIT_REPORT"]);
var f = object.z.enum(["ADD_COMMENT"]);
var _ = object.z.enum(["ADD_LINE_ITEM"]);
var A = object.z.enum(["ADD_VESTING"]);
function i() {
  return object.z.object({
    __typename: object.z.literal("Account").optional(),
    address: object.z.string(),
    lineItems: object.z.array(l()),
    name: object.z.string()
  });
}
function j() {
  return object.z.object({
    address: object.z.string(),
    lineItems: object.z.array(object.z.lazy(() => h())).nullish(),
    name: object.z.string().nullish()
  });
}
function I() {
  return object.z.object({
    address: object.z.string(),
    lineItems: object.z.array(l()).nullish(),
    name: object.z.string().nullish()
  });
}
function E() {
  return object.z.object({
    input: object.z.lazy(() => D()),
    type: d
  });
}
function D() {
  return object.z.object({
    accounts: object.z.array(object.z.lazy(() => j()))
  });
}
function T() {
  return object.z.object({
    attachments: object.z.array(object.z.lazy(() => et())),
    input: object.z.lazy(() => z2()),
    type: b
  });
}
function z2() {
  return object.z.object({
    reports: object.z.array(n())
  });
}
function C() {
  return object.z.object({
    input: object.z.lazy(() => L()),
    type: f
  });
}
function L() {
  return object.z.object({
    comments: object.z.array(object.z.lazy(() => P()))
  });
}
function O() {
  return object.z.object({
    input: object.z.lazy(() => U()),
    type: _
  });
}
function U() {
  return object.z.object({
    account: object.z.string(),
    lineItems: object.z.array(object.z.lazy(() => h()))
  });
}
function N() {
  return object.z.object({
    input: object.z.lazy(() => R()),
    type: A
  });
}
function R() {
  return object.z.object({
    vesting: object.z.array(object.z.lazy(() => Gt()))
  });
}
function n() {
  return object.z.object({
    __typename: object.z.literal("AuditReport").optional(),
    report: object.z.string(),
    status: v,
    timestamp: object.z.string().datetime()
  });
}
var v = object.z.enum(["Approved", "ApprovedWithComments", "Escalated", "NeedsAction"]);
function qt() {
  return object.z.object({
    __typename: object.z.literal("BudgetStatement").optional(),
    created: object.z.string().datetime(),
    data: M(),
    documentType: object.z.string(),
    lastModified: object.z.string().datetime(),
    name: object.z.string(),
    operations: object.z.array(y),
    revision: object.z.number()
  });
}
function Wt() {
  return object.z.union([E(), T(), C(), O(), N(), q(), H(), J(), X(), $(), jt(), It(), Et(), Dt(), Tt(), Ct(), Mt(), Vt(), wt(), Bt()]);
}
function M() {
  return object.z.object({
    __typename: object.z.literal("BudgetStatementData").optional(),
    accounts: object.z.array(i()),
    auditReports: object.z.array(n()),
    comments: object.z.array(a()),
    ftes: c().nullable(),
    month: object.z.string().nullable(),
    owner: p().nullable(),
    quoteCurrency: object.z.string().nullable(),
    vesting: object.z.array(S())
  });
}
function F() {
  return object.z.object({
    accounts: object.z.array(i()).nullish(),
    auditReports: object.z.array(n()).nullish(),
    comments: object.z.array(a()).nullish(),
    ftes: c().nullish(),
    month: object.z.string().nullish(),
    owner: p().nullish(),
    quoteCurrency: object.z.string().nullish(),
    vesting: object.z.array(S()).nullish()
  });
}
function Ht() {
  return object.z.object({
    created: object.z.string().datetime().nullish(),
    data: object.z.lazy(() => F()),
    documentType: object.z.string().nullish(),
    lastModified: object.z.string().datetime().nullish(),
    name: object.z.string().nullish(),
    revision: object.z.number().nullish()
  });
}
var r = object.z.enum(["Draft", "Escalated", "Final", "Review"]);
function a() {
  return object.z.object({
    __typename: object.z.literal("Comment").optional(),
    author: V(),
    comment: object.z.string(),
    key: object.z.string(),
    status: r,
    timestamp: object.z.string().datetime()
  });
}
function V() {
  return object.z.object({
    __typename: object.z.literal("CommentAuthor").optional(),
    id: object.z.string().nullable(),
    ref: object.z.string().nullable(),
    roleLabel: object.z.string().nullable(),
    username: object.z.string().nullable()
  });
}
function o() {
  return object.z.object({
    id: object.z.string().nullish(),
    ref: object.z.string().nullish(),
    roleLabel: object.z.string().nullish(),
    username: object.z.string().nullish()
  });
}
function P() {
  return object.z.object({
    author: object.z.lazy(() => o().nullish()),
    comment: object.z.string(),
    key: object.z.string().nullish(),
    status: r.nullish(),
    timestamp: object.z.string().datetime().nullish()
  });
}
function w() {
  return object.z.object({
    author: object.z.lazy(() => o().nullish()),
    comment: object.z.string().nullish(),
    key: object.z.string(),
    status: r.nullish(),
    timestamp: object.z.string().datetime().nullish()
  });
}
var x = object.z.enum(["DELETE_ACCOUNT"]);
var B = object.z.enum(["DELETE_AUDIT_REPORT"]);
var k = object.z.enum(["DELETE_COMMENT"]);
var G = object.z.enum(["DELETE_LINE_ITEM"]);
var Q = object.z.enum(["DELETE_VESTING"]);
function q() {
  return object.z.object({
    input: object.z.lazy(() => W()),
    type: x
  });
}
function W() {
  return object.z.object({
    accounts: object.z.array(object.z.string())
  });
}
function H() {
  return object.z.object({
    input: object.z.lazy(() => Y()),
    type: B
  });
}
function Y() {
  return object.z.object({
    reports: object.z.array(object.z.string())
  });
}
function J() {
  return object.z.object({
    input: object.z.lazy(() => K()),
    type: k
  });
}
function K() {
  return object.z.object({
    comments: object.z.array(object.z.string())
  });
}
function X() {
  return object.z.object({
    input: object.z.lazy(() => Z()),
    type: G
  });
}
function Z() {
  return object.z.object({
    account: object.z.string(),
    lineItems: object.z.array(object.z.lazy(() => at()))
  });
}
function $() {
  return object.z.object({
    input: object.z.lazy(() => tt()),
    type: Q
  });
}
function tt() {
  return object.z.object({
    vesting: object.z.array(object.z.string())
  });
}
function et() {
  return object.z.object({
    data: object.z.string(),
    extension: object.z.string().nullish(),
    fileName: object.z.string().nullish(),
    hash: object.z.string(),
    mimeType: object.z.string()
  });
}
function c() {
  return object.z.object({
    __typename: object.z.literal("Ftes").optional(),
    forecast: object.z.array(nt()),
    value: object.z.number()
  });
}
function nt() {
  return object.z.object({
    __typename: object.z.literal("FtesForecast").optional(),
    month: object.z.string(),
    value: object.z.number()
  });
}
function rt() {
  return object.z.object({
    month: object.z.string(),
    value: object.z.number()
  });
}
function ut() {
  return object.z.object({
    forecast: object.z.array(object.z.lazy(() => rt())),
    value: object.z.number()
  });
}
var it = object.z.enum(["LOAD_STATE"]);
function l() {
  return object.z.object({
    __typename: object.z.literal("LineItem").optional(),
    actual: object.z.number().nullable(),
    budgetCap: object.z.number().nullable(),
    category: m().nullable(),
    comment: object.z.string().nullable(),
    forecast: object.z.array(u()),
    group: s().nullable(),
    headcountExpense: object.z.boolean(),
    payment: object.z.number().nullable()
  });
}
function m() {
  return object.z.object({
    __typename: object.z.literal("LineItemCategory").optional(),
    id: object.z.string(),
    ref: object.z.string(),
    title: object.z.string()
  });
}
function at() {
  return object.z.object({
    category: object.z.string().nullish(),
    group: object.z.string().nullish()
  });
}
function u() {
  return object.z.object({
    __typename: object.z.literal("LineItemForecast").optional(),
    budgetCap: object.z.number(),
    month: object.z.string(),
    value: object.z.number()
  });
}
function s() {
  return object.z.object({
    __typename: object.z.literal("LineItemGroup").optional(),
    color: object.z.string(),
    id: object.z.string(),
    ref: object.z.string(),
    title: object.z.string()
  });
}
function h() {
  return object.z.object({
    actual: object.z.number().nullish(),
    budgetCap: object.z.number().nullish(),
    category: m().nullish(),
    comment: object.z.string().nullish(),
    forecast: object.z.array(u()).nullish(),
    group: s().nullish(),
    headcountExpense: object.z.boolean().nullish(),
    payment: object.z.number().nullish()
  });
}
function ot() {
  return object.z.object({
    actual: object.z.number().nullish(),
    budgetCap: object.z.number().nullish(),
    category: object.z.string().nullish(),
    comment: object.z.string().nullish(),
    forecast: object.z.array(u()).nullish(),
    group: object.z.string().nullish(),
    headcountExpense: object.z.boolean().nullish(),
    payment: object.z.number().nullish()
  });
}
function ct() {
  return object.z.object({
    category: object.z.string().nullish(),
    group: object.z.string().nullish()
  });
}
function Yt() {
  return object.z.object({
    input: object.z.lazy(() => lt()),
    type: it
  });
}
function lt() {
  return object.z.object({
    operations: object.z.number(),
    state: object.z.lazy(() => mt())
  });
}
function mt() {
  return object.z.object({
    data: object.z.unknown().nullish(),
    name: object.z.string()
  });
}
function Jt() {
  return object.z.object({
    __typename: object.z.literal("Operation").optional(),
    hash: object.z.string(),
    index: object.z.number(),
    timestamp: object.z.string().datetime(),
    type: object.z.string()
  });
}
function p() {
  return object.z.object({
    __typename: object.z.literal("Owner").optional(),
    id: object.z.string().nullable(),
    ref: object.z.string().nullable(),
    title: object.z.string().nullable()
  });
}
function st() {
  return object.z.object({
    id: object.z.string().nullish(),
    ref: object.z.string().nullish(),
    title: object.z.string().nullish()
  });
}
var ht = object.z.enum(["PRUNE"]);
function Kt() {
  return object.z.object({
    input: object.z.lazy(() => pt()),
    type: ht
  });
}
function pt() {
  return object.z.object({
    end: object.z.number().nullish(),
    start: object.z.number().nullish()
  });
}
var St = object.z.enum(["REDO"]);
function Xt() {
  return object.z.object({
    input: object.z.number(),
    type: St
  });
}
var gt = object.z.enum(["SET_FTES"]);
var yt = object.z.enum(["SET_MONTH"]);
var dt = object.z.enum(["SET_NAME"]);
var bt = object.z.enum(["SET_OWNER"]);
var ft = object.z.enum(["SET_QUOTE_CURRENCY"]);
var _t = object.z.enum(["SORT_ACCOUNTS"]);
var At = object.z.enum(["SORT_LINE_ITEMS"]);
function jt() {
  return object.z.object({
    input: object.z.lazy(() => ut()),
    type: gt
  });
}
function It() {
  return object.z.object({
    input: object.z.string(),
    type: yt
  });
}
function Zt() {
  return object.z.object({
    input: object.z.string(),
    type: dt
  });
}
function $t() {
  return object.z.object({
    __typename: object.z.literal("SetNameOperation").optional(),
    hash: object.z.string(),
    index: object.z.number(),
    input: object.z.string(),
    timestamp: object.z.string().datetime(),
    type: object.z.string()
  });
}
function Et() {
  return object.z.object({
    input: object.z.lazy(() => st()),
    type: bt
  });
}
function Dt() {
  return object.z.object({
    input: object.z.string(),
    type: ft
  });
}
function Tt() {
  return object.z.object({
    input: object.z.lazy(() => zt()),
    type: _t
  });
}
function zt() {
  return object.z.object({
    accounts: object.z.array(object.z.string())
  });
}
function Ct() {
  return object.z.object({
    input: object.z.lazy(() => Lt()),
    type: At
  });
}
function Lt() {
  return object.z.object({
    account: object.z.string(),
    lineItems: object.z.array(object.z.lazy(() => ct()))
  });
}
var Ot = object.z.enum(["UNDO"]);
var Ut = object.z.enum(["UPDATE_ACCOUNT"]);
var Nt = object.z.enum(["UPDATE_COMMENT"]);
var Rt = object.z.enum(["UPDATE_LINE_ITEM"]);
var vt = object.z.enum(["UPDATE_VESTING"]);
function te() {
  return object.z.object({
    input: object.z.number(),
    type: Ot
  });
}
function Mt() {
  return object.z.object({
    input: object.z.lazy(() => Ft()),
    type: Ut
  });
}
function Ft() {
  return object.z.object({
    accounts: object.z.array(object.z.lazy(() => I()))
  });
}
function Vt() {
  return object.z.object({
    input: object.z.lazy(() => Pt()),
    type: Nt
  });
}
function Pt() {
  return object.z.object({
    comments: object.z.array(object.z.lazy(() => w()))
  });
}
function wt() {
  return object.z.object({
    input: object.z.lazy(() => xt()),
    type: Rt
  });
}
function xt() {
  return object.z.object({
    account: object.z.string(),
    lineItems: object.z.array(object.z.lazy(() => ot()))
  });
}
function Bt() {
  return object.z.object({
    input: object.z.lazy(() => kt()),
    type: vt
  });
}
function kt() {
  return object.z.object({
    vesting: object.z.array(object.z.lazy(() => Qt()))
  });
}
function S() {
  return object.z.object({
    __typename: object.z.literal("Vesting").optional(),
    amount: object.z.string(),
    amountOld: object.z.string(),
    comment: object.z.string(),
    currency: object.z.string(),
    date: object.z.string(),
    key: object.z.string(),
    vested: object.z.boolean()
  });
}
function Gt() {
  return object.z.object({
    amount: object.z.string().nullish(),
    amountOld: object.z.string().nullish(),
    comment: object.z.string().nullish(),
    currency: object.z.string().nullish(),
    date: object.z.string().nullish(),
    key: object.z.string().nullish(),
    vested: object.z.boolean().nullish()
  });
}
function Qt() {
  return object.z.object({
    amount: object.z.string().nullish(),
    amountOld: object.z.string().nullish(),
    comment: object.z.string().nullish(),
    currency: object.z.string().nullish(),
    date: object.z.string().nullish(),
    key: object.z.string(),
    vested: object.z.boolean().nullish()
  });
}
var ee = Object.freeze(Object.defineProperty({
  __proto__: null,
  AccountInputSchema: j,
  AccountSchema: i,
  AccountUpdateInputSchema: I,
  AddAccountActionSchema: E,
  AddAccountInputSchema: D,
  AddAuditReportActionSchema: T,
  AddAuditReportInputSchema: z2,
  AddCommentActionSchema: C,
  AddCommentInputSchema: L,
  AddLineItemActionSchema: O,
  AddLineItemInputSchema: U,
  AddVestingActionSchema: N,
  AddVestingInputSchema: R,
  Add_AccountSchema: d,
  Add_Audit_ReportSchema: b,
  Add_CommentSchema: f,
  Add_Line_ItemSchema: _,
  Add_VestingSchema: A,
  AuditReportSchema: n,
  AuditReportStatusSchema: v,
  BudgetStatementActionSchema: Wt,
  BudgetStatementDataInputSchema: F,
  BudgetStatementDataSchema: M,
  BudgetStatementInputSchema: Ht,
  BudgetStatementSchema: qt,
  BudgetStatusSchema: r,
  CommentAuthorInputSchema: o,
  CommentAuthorSchema: V,
  CommentInputSchema: P,
  CommentSchema: a,
  CommentUpdateInputSchema: w,
  DeleteAccountActionSchema: q,
  DeleteAccountInputSchema: W,
  DeleteAuditReportActionSchema: H,
  DeleteAuditReportInputSchema: Y,
  DeleteCommentActionSchema: J,
  DeleteCommentInputSchema: K,
  DeleteLineItemActionSchema: X,
  DeleteLineItemInputSchema: Z,
  DeleteVestingActionSchema: $,
  DeleteVestingInputSchema: tt,
  Delete_AccountSchema: x,
  Delete_Audit_ReportSchema: B,
  Delete_CommentSchema: k,
  Delete_Line_ItemSchema: G,
  Delete_VestingSchema: Q,
  DocumentFileInputSchema: et,
  FtesForecastInputSchema: rt,
  FtesForecastSchema: nt,
  FtesInputSchema: ut,
  FtesSchema: c,
  LineItemCategorySchema: m,
  LineItemDeleteInputSchema: at,
  LineItemForecastSchema: u,
  LineItemGroupSchema: s,
  LineItemInputSchema: h,
  LineItemSchema: l,
  LineItemUpdateInputSchema: ot,
  LineItemsSortInputSchema: ct,
  LoadStateActionInputSchema: lt,
  LoadStateActionSchema: Yt,
  LoadStateActionStateInputSchema: mt,
  Load_StateSchema: it,
  OperationSchema: Jt,
  OwnerInputSchema: st,
  OwnerSchema: p,
  PruneActionInputSchema: pt,
  PruneActionSchema: Kt,
  PruneSchema: ht,
  RedoActionSchema: Xt,
  RedoSchema: St,
  SetFtesActionSchema: jt,
  SetMonthActionSchema: It,
  SetNameActionSchema: Zt,
  SetNameOperationSchema: $t,
  SetOwnerActionSchema: Et,
  SetQuoteCurrencyActionSchema: Dt,
  Set_FtesSchema: gt,
  Set_MonthSchema: yt,
  Set_NameSchema: dt,
  Set_OwnerSchema: bt,
  Set_Quote_CurrencySchema: ft,
  SortAccountsActionSchema: Tt,
  SortAccountsInputSchema: zt,
  SortLineItemsActionSchema: Ct,
  SortLineItemsInputSchema: Lt,
  Sort_AccountsSchema: _t,
  Sort_Line_ItemsSchema: At,
  UndoActionSchema: te,
  UndoSchema: Ot,
  UpdateAccountActionSchema: Mt,
  UpdateAccountInputSchema: Ft,
  UpdateCommentActionSchema: Vt,
  UpdateCommentInputSchema: Pt,
  UpdateLineItemActionSchema: wt,
  UpdateLineItemInputSchema: xt,
  UpdateVestingActionSchema: Bt,
  UpdateVestingInputSchema: kt,
  Update_AccountSchema: Ut,
  Update_CommentSchema: Nt,
  Update_Line_ItemSchema: Rt,
  Update_VestingSchema: vt,
  VestingInputSchema: Gt,
  VestingSchema: S,
  VestingUpdateInputSchema: Qt,
  definedNonNullAnySchema: y,
  isDefinedNonNullAny: g
}, Symbol.toStringTag, { value: "Module" }));
Object.freeze(Object.defineProperty({
  __proto__: null,
  z: ee
}, Symbol.toStringTag, { value: "Module" }));

const ADD_ACCOUNT = "ADD_ACCOUNT";
const UPDATE_ACCOUNT = "UPDATE_ACCOUNT";
const DELETE_ACCOUNT = "DELETE_ACCOUNT";
const SORT_ACCOUNTS = "SORT_ACCOUNTS";

const ADD_AUDIT_REPORT = "ADD_AUDIT_REPORT";
const DELETE_AUDIT_REPORT = "DELETE_AUDIT_REPORT";

const SET_OWNER = "SET_OWNER";
const SET_MONTH = "SET_MONTH";
const SET_QUOTE_CURRENCY = "SET_QUOTE_CURRENCY";
const SET_FTES = "SET_FTES";

const ADD_COMMENT = "ADD_COMMENT";
const UPDATE_COMMENT = "UPDATE_COMMENT";
const DELETE_COMMENT = "DELETE_COMMENT";

const ADD_LINE_ITEM = "ADD_LINE_ITEM";
const UPDATE_LINE_ITEM = "UPDATE_LINE_ITEM";
const DELETE_LINE_ITEM = "DELETE_LINE_ITEM";
const SORT_LINE_ITEMS = "SORT_LINE_ITEMS";

const ADD_VESTING = "ADD_VESTING";
const UPDATE_VESTING = "UPDATE_VESTING";
const DELETE_VESTING = "DELETE_VESTING";

function createBudgetStatement(initialState) {
  return object.createDocument({
    documentType: "powerhouse/budget-statement",
    ...initialState,
    state: {
      owner: {
        ref: null,
        id: null,
        title: null
      },
      month: null,
      quoteCurrency: null,
      vesting: [],
      ftes: null,
      accounts: [],
      auditReports: [],
      comments: [],
      ...initialState?.state
    }
  });
}
const createAccount = (input) => ({
  ...input,
  name: input.name ?? "",
  lineItems: input.lineItems?.map(createLineItem) ?? new Array()
});
const createLineItem = (input) => ({
  budgetCap: null,
  payment: null,
  actual: null,
  comment: null,
  ...input,
  forecast: input.forecast?.sort((f1, f2) => f1.month.localeCompare(f2.month)) ?? new Array(),
  headcountExpense: input.headcountExpense ?? false,
  group: input.group ?? null,
  category: input.category ?? null
});
const saveBudgetStatementToFile = (document, path, name) => {
  return object.saveToFile(document, path, "phbs", name);
};
const loadBudgetStatementFromFile = async (path) => {
  const document = await object.loadFromFile(path, reducer);
  return {
    ...document
    // fileRegistry
  };
};
const loadBudgetStatementFromInput = async (input) => {
  const document = await object.loadFromInput(input, reducer);
  return {
    ...document
    // fileRegistry
  };
};
const saveBudgetStatementToFileHandle = async (document, input) => {
  return object.saveToFileHandle(document, input);
};

var utils = /*#__PURE__*/Object.freeze({
  __proto__: null,
  createAccount: createAccount,
  createBudgetStatement: createBudgetStatement,
  createLineItem: createLineItem,
  loadBudgetStatementFromFile: loadBudgetStatementFromFile,
  loadBudgetStatementFromInput: loadBudgetStatementFromInput,
  saveBudgetStatementToFile: saveBudgetStatementToFile,
  saveBudgetStatementToFileHandle: saveBudgetStatementToFileHandle
});

const addAccountOperation = (state, action) => {
  action.input.accounts.forEach((input) => {
    if (state.accounts.find((account) => account.address === input.address)) {
      throw new Error(
        `Account with address ${input.address} already exists!`
      );
    }
    state.accounts.push(createAccount(input));
  });
};
const updateAccountOperation = (state, action) => {
  state.accounts = state.accounts.map((account) => {
    const accountUpdate = action.input.accounts.find(
      (a) => a.address === account.address
    );
    return {
      ...account,
      lineItems: accountUpdate?.lineItems ?? account.lineItems,
      name: accountUpdate?.name ?? account.name
    };
  });
};
const deleteAccountOperation = (state, action) => {
  state.accounts = state.accounts.filter(
    (account) => !action.input.accounts.find((address) => address === account.address)
  );
};
const sortAccountsOperation = (state, action) => {
  state.accounts.sort((a, b) => {
    const index1 = action.input.accounts.indexOf(a.address);
    const index2 = action.input.accounts.indexOf(b.address);
    return (index1 > -1 ? index1 : Infinity) - (index2 > -1 ? index2 : Infinity);
  });
};

function checkDuplicatedReport(state, report) {
  if (state.auditReports.find((audit) => audit.report === report)) {
    throw new Error(`Audit with report ${report} already exists`);
  }
}
const addAuditReportOperation = (state, action) => {
  action.input.reports.forEach((audit) => {
    checkDuplicatedReport(state, audit.report);
    state.auditReports.push(audit);
  });
};
const deleteAuditReportOperation = (state, action) => {
  action.input.reports.forEach((report) => {
    const index = state.auditReports.findIndex(
      (audit) => audit.report === report
    );
    if (index > -1) {
      state.auditReports.splice(index, 1);
    }
  });
};

const setOwnerOperation = (state, action) => {
  state.owner = {
    id: action.input.id ?? null,
    ref: action.input.ref ?? null,
    title: action.input.title ?? null
  };
};
const setMonthOperation = (state, action) => {
  state.month = action.input;
};
const setQuoteCurrencyOperation = (state, action) => {
  state.quoteCurrency = action.input;
};
const setFtesOperation = (state, action) => {
  state.ftes = action.input;
  state.ftes?.forecast.sort((f1, f2) => f1.month.localeCompare(f2.month));
};

function isEqual(lineItemInput, lineItem) {
  return lineItemInput.category === lineItem.category?.id && lineItemInput.group === lineItem.group?.id;
}
const addLineItemOperation = (state, action) => {
  const account = state.accounts.find(
    (a) => a.address === action.input.account
  );
  if (!account) {
    throw new Error(
      `Account with address ${action.input.account} not found`
    );
  }
  action.input.lineItems.forEach((input) => {
    if (account.lineItems.find(
      (item) => input.category?.id === item.category?.id && input.group?.id === item.group?.id
    )) {
      throw new Error(
        `Line item with category '${input.category?.id ?? "null"}' and group '${input.group?.id ?? "null"}' already exists`
      );
    }
    account.lineItems.push(createLineItem(input));
  });
};
const updateLineItemOperation = (state, action) => {
  const account = state.accounts.find(
    (a) => a.address === action.input.account
  );
  if (!account) {
    throw new Error(
      `Account with address ${action.input.account} not found`
    );
  }
  account.lineItems = account.lineItems.map((lineItem) => {
    const input = action.input.lineItems.find((l) => isEqual(l, lineItem));
    if (!input) {
      return lineItem;
    } else {
      return {
        ...lineItem,
        ...input,
        category: lineItem.category,
        headcountExpense: input.headcountExpense ?? false,
        group: lineItem.group,
        forecast: (input.forecast ?? lineItem.forecast).sort((f1, f2) => f1.month.localeCompare(f2.month))
      };
    }
  });
};
const deleteLineItemOperation = (state, action) => {
  const account = state.accounts.find(
    (a) => a.address === action.input.account
  );
  if (!account) {
    throw new Error(
      `Account with address ${action.input.account} not found`
    );
  }
  account.lineItems = account.lineItems.filter(
    (lineItem) => !action.input.lineItems.find((l) => isEqual(l, lineItem))
  );
};
const sortLineItemsOperation = (state, action) => {
  const account = state.accounts.find(
    (a) => a.address === action.input.account
  );
  if (!account) {
    throw new Error(
      `Account with address ${action.input.account} not found`
    );
  }
  account.lineItems.sort((a, b) => {
    const index1 = action.input.lineItems.findIndex((l) => isEqual(l, a));
    const index2 = action.input.lineItems.findIndex((l) => isEqual(l, b));
    return (index1 > -1 ? index1 : Infinity) - (index2 > -1 ? index2 : Infinity);
  });
};

const sortComment = (a, b) => a.timestamp < b.timestamp ? -1 : 1;
const addCommentOperation = (state, action) => {
  action.input.comments.forEach((input) => {
    const key = input.key ?? object.hashKey();
    const index = state.comments.findIndex((c) => c.key === input.key);
    if (index > -1) {
      throw new Error(`Comment with key ${key} already exists`);
    }
    state.comments.push({
      key,
      author: {
        ref: null,
        id: null,
        username: null,
        roleLabel: null,
        ...input.author
      },
      comment: input.comment,
      timestamp: input.timestamp || (/* @__PURE__ */ new Date()).toISOString(),
      status: input.status ?? "Draft"
    });
  });
  state.comments.sort(sortComment);
};
const updateCommentOperation = (state, action) => {
  action.input.comments.forEach((input) => {
    const index = state.comments.findIndex((c) => c.key === input.key);
    if (index === -1) {
      return;
    }
    const comment = state.comments[index];
    state.comments[index] = {
      ...comment,
      ...input,
      author: {
        id: input.author?.id ?? comment.author.id,
        ref: input.author?.ref ?? comment.author.ref,
        roleLabel: input.author?.roleLabel ?? comment.author.roleLabel,
        username: input.author?.username ?? comment.author.username
      },
      comment: input.comment ?? comment.comment,
      timestamp: input.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(),
      status: input.status ?? comment.status
    };
  });
  state.comments.sort(sortComment);
};
const deleteCommentOperation = (state, action) => {
  state.comments = state.comments.filter(
    (comment) => !action.input.comments.includes(comment.key)
  );
};

const sortVesting = (a, b) => a.date < b.date ? -1 : 1;
const addVestingOperation = (state, action) => {
  action.input.vesting.forEach((input) => {
    const key = input.key ?? object.hashKey();
    const index = state.vesting.findIndex((v) => v.key === input.key);
    if (index > -1) {
      throw new Error(`Vesting with key ${key} already exists`);
    }
    state.vesting.push({
      ...input,
      key,
      date: input.date ?? "",
      amount: input.amount ?? "",
      amountOld: input.amountOld ?? input.amount ?? "",
      comment: input.comment ?? "",
      currency: input.currency ?? "",
      vested: input.vested ?? false
    });
  });
  state.vesting.sort(sortVesting);
};
const updateVestingOperation = (state, action) => {
  action.input.vesting.forEach((input) => {
    const index = state.vesting.findIndex((v) => v.key === input.key);
    if (index === -1) {
      return;
    }
    const vesting = state.vesting[index];
    state.vesting[index] = {
      ...vesting,
      ...input,
      amount: input.amount ?? vesting.amount,
      amountOld: input.amountOld ?? vesting.amountOld,
      comment: input.comment ?? vesting.comment,
      currency: input.currency ?? vesting.currency,
      date: input.date ?? vesting.date,
      vested: input.vested ?? vesting.vested
    };
  });
  state.vesting.sort(sortVesting);
};
const deleteVestingOperation = (state, action) => {
  state.vesting = state.vesting.filter(
    (vesting) => !action.input.vesting.includes(vesting.key)
  );
};

const reducer = object.createReducer((state, action) => {
  if (object.isBaseAction(action)) {
    return state;
  }
  ee.BudgetStatementActionSchema().parse(action);
  switch (action.type) {
    case SET_OWNER:
      return setOwnerOperation(state, action);
    case SET_MONTH:
      return setMonthOperation(state, action);
    case SET_QUOTE_CURRENCY:
      return setQuoteCurrencyOperation(state, action);
    case SET_FTES:
      return setFtesOperation(state, action);
    case ADD_ACCOUNT:
      return addAccountOperation(state, action);
    case UPDATE_ACCOUNT:
      return updateAccountOperation(state, action);
    case DELETE_ACCOUNT:
      return deleteAccountOperation(state, action);
    case SORT_ACCOUNTS:
      return sortAccountsOperation(state, action);
    case ADD_LINE_ITEM:
      return addLineItemOperation(state, action);
    case UPDATE_LINE_ITEM:
      return updateLineItemOperation(state, action);
    case DELETE_LINE_ITEM:
      return deleteLineItemOperation(state, action);
    case SORT_LINE_ITEMS:
      return sortLineItemsOperation(state, action);
    case ADD_AUDIT_REPORT:
      return addAuditReportOperation(state, action);
    case DELETE_AUDIT_REPORT:
      return deleteAuditReportOperation(state, action);
    case ADD_VESTING:
      return addVestingOperation(state, action);
    case UPDATE_VESTING:
      return updateVestingOperation(state, action);
    case DELETE_VESTING:
      return deleteVestingOperation(state, action);
    case ADD_COMMENT:
      return addCommentOperation(state, action);
    case UPDATE_COMMENT:
      return updateCommentOperation(state, action);
    case DELETE_COMMENT:
      return deleteCommentOperation(state, action);
    default:
      return state;
  }
});

const addAccount = (accounts) => object.createAction(
  ADD_ACCOUNT,
  {
    accounts: accounts.map(createAccount)
  },
  void 0,
  ee.AddAccountActionSchema
);
const updateAccount = (accounts) => object.createAction(
  UPDATE_ACCOUNT,
  { accounts },
  void 0,
  ee.UpdateAccountActionSchema
);
const deleteAccount = (accounts) => object.createAction(
  DELETE_ACCOUNT,
  { accounts },
  void 0,
  ee.DeleteAccountActionSchema
);
const sortAccounts = (accounts) => object.createAction(
  SORT_ACCOUNTS,
  { accounts },
  void 0,
  ee.SortAccountsActionSchema
);

const addAuditReport = (reports, attachments) => {
  return object.createAction(
    ADD_AUDIT_REPORT,
    { reports },
    attachments,
    ee.AddAuditReportActionSchema
  );
};
const deleteAuditReport = (reports) => object.createAction(
  DELETE_AUDIT_REPORT,
  { reports },
  void 0,
  ee.DeleteAuditReportActionSchema
);

const setOwner = (owner) => object.createAction(
  SET_OWNER,
  owner,
  void 0,
  ee.SetOwnerActionSchema
);
const setMonth = (month) => object.createAction(
  SET_MONTH,
  month,
  void 0,
  ee.SetMonthActionSchema
);
const setQuoteCurrency = (currency) => object.createAction(
  SET_QUOTE_CURRENCY,
  currency,
  void 0,
  ee.SetQuoteCurrencyActionSchema
);
const setFtes = (ftes) => object.createAction(
  SET_FTES,
  ftes,
  void 0,
  ee.SetFtesActionSchema
);

const addComment = (comments) => object.createAction(
  ADD_COMMENT,
  { comments },
  void 0,
  ee.AddCommentActionSchema
);
const updateComment = (comments) => object.createAction(
  UPDATE_COMMENT,
  { comments },
  void 0,
  ee.UpdateCommentActionSchema
);
const deleteComment = (comments) => object.createAction(
  DELETE_COMMENT,
  { comments },
  void 0,
  ee.DeleteCommentActionSchema
);

const addLineItem = (account, lineItems) => object.createAction(
  ADD_LINE_ITEM,
  {
    account,
    lineItems: lineItems.map(createLineItem)
  },
  void 0,
  ee.AddLineItemActionSchema
);
const updateLineItem = (account, lineItems) => object.createAction(
  UPDATE_LINE_ITEM,
  {
    account,
    lineItems
  },
  void 0,
  ee.UpdateLineItemActionSchema
);
const deleteLineItem = (account, lineItems) => object.createAction(
  DELETE_LINE_ITEM,
  {
    account,
    lineItems
  },
  void 0,
  ee.DeleteLineItemActionSchema
);
const sortLineItems = (account, lineItems) => object.createAction(
  SORT_LINE_ITEMS,
  {
    account,
    lineItems
  },
  void 0,
  ee.SortLineItemsActionSchema
);

const addVesting = (vesting) => object.createAction(
  ADD_VESTING,
  { vesting },
  void 0,
  ee.AddVestingActionSchema
);
const updateVesting = (vesting) => object.createAction(
  UPDATE_VESTING,
  { vesting },
  void 0,
  ee.UpdateVestingActionSchema
);
const deleteVesting = (vesting) => object.createAction(
  DELETE_VESTING,
  { vesting },
  void 0,
  ee.DeleteVestingActionSchema
);

class AccountObject extends object.BaseDocument {
  /**
   * Adds one or more accounts to the budget statement.
   * @param accounts An array of AccountInput objects to add.
   *
   * @group Account
   */
  addAccount(accounts) {
    const action = addAccount(accounts);
    return this.dispatch(action);
  }
  /**
   * Updates one or more existing accounts in the budget statement.
   * @param accounts An array of AccountInput objects to update.
   *
   * @group Account
   */
  updateAccount(accounts) {
    return this.dispatch(updateAccount(accounts));
  }
  /**
   * Deletes one or more accounts from the budget statement.
   * @param accounts An array of addresses of the accounts to delete.
   *
   * @group Account
   */
  deleteAccount(accounts) {
    return this.dispatch(deleteAccount(accounts));
  }
  /**
   * Sorts the accounts inthe budget statement.
   * @param accounts An array of addresses of the accounts to sort.
   *
   * @group Account
   */
  sortAccounts(accounts) {
    return this.dispatch(sortAccounts(accounts));
  }
  /**
   * Returns an array of all accounts in the budget statement.
   *
   * @group Account
   */
  get accounts() {
    return this.state.accounts;
  }
  /**
   * Returns the Account object with the specified address.
   * @param address The address of the Account to retrieve.
   *
   * @group Account
   */
  getAccount(address) {
    return this.accounts.find((account) => account.address === address);
  }
}

class AuditObject extends object.BaseDocument {
  /**
   * Adds audit reports to the budget statement.
   * @param reports - An array of audit report objects to add.
   *
   * @group Audit
   */
  addAuditReport(reports, attachments) {
    return this.dispatch(addAuditReport(reports, attachments));
  }
  /**
   * Deletes audit reports from the budget statement.
   * @param reports - An array of objects that contain the report attachment name of the audits items to be deleted.
   *
   * @group Audit
   */
  deleteAuditReport(reports) {
    return this.dispatch(deleteAuditReport(reports));
  }
  /**
   * Retrieves all audit reports from the budget statement.
   * @returns An array of audit report objects.
   *
   * @group Audit
   */
  getAuditReports() {
    return this.state.auditReports;
  }
  /**
   * Retrieves a specific audit report from the budget statement.
   * @param report - The name of the attachment of the report to be retrieved.
   * @returns The audit report object if it exists, or undefined if not.
   *
   * @group Audit
   */
  getAuditReport(report) {
    return this.getAuditReports().find((audit) => audit.report === report);
  }
}

class BaseObject extends object.BaseDocument {
  /**
   * Gets the month of the budget statement.
   * @category Budget Statement
   */
  get month() {
    return this.state.month;
  }
  /**
   * Gets the owner of the budget statement.
   * @category Budget Statement
   */
  get owner() {
    return this.state.owner;
  }
  /**
   * Gets the quote currency of the budget statement.
   * @category Budget Statement
   */
  get quoteCurrency() {
    return this.state.quoteCurrency;
  }
  get ftes() {
    return this.state.ftes;
  }
  setOwner(owner) {
    return this.dispatch(setOwner(owner));
  }
  setMonth(month) {
    return this.dispatch(setMonth(month));
  }
  setQuoteCurrency(currency) {
    return this.dispatch(setQuoteCurrency(currency));
  }
  setFtes(ftes) {
    return this.dispatch(setFtes(ftes));
  }
}

class CommentObject extends object.BaseDocument {
  addComment(comments) {
    return this.dispatch(addComment(comments));
  }
  updateComment(comments) {
    return this.dispatch(updateComment(comments));
  }
  deleteComment(comments) {
    return this.dispatch(deleteComment(comments));
  }
  get comments() {
    return this.state.comments;
  }
  getComment(key) {
    return this.state.comments.find((v) => v.key === key);
  }
}

class LineItemObject extends object.BaseDocument {
  /**
   * Adds a line item to the specified account.
   * @param account The address of the account to which the line item will be added.
   * @param lineItems An array of line item objects to be added to the account.
   *
   * @group Line Item
   */
  addLineItem(account, lineItems) {
    return this.dispatch(addLineItem(account, lineItems));
  }
  /**
   * Updates line items for the specified account.
   * @param account The address of the account for which line items will be updated.
   * @param lineItems An array of line item input objects to be updated.
   *
   * @group Line Item
   */
  updateLineItem(account, lineItems) {
    return this.dispatch(updateLineItem(account, lineItems));
  }
  /**
   * Deletes line items for the specified account.
   * @param account The address of the account for which line items will be deleted.
   * @param lineItems An array of objects that contain the category and group of the line items to be deleted.
   *
   * @group Line Item
   */
  deleteLineItem(account, lineItems) {
    return this.dispatch(deleteLineItem(account, lineItems));
  }
  /**
   * Sorts the line items of an account.
   *
   * @param account - The account containing the line items to sort.
   * @param lineItems - An array of line items to sort.
   * @group Line Item
   */
  sortLineItems(account, lineItems) {
    return this.dispatch(sortLineItems(account, lineItems));
  }
  /**
   * Retrieves line items for the specified account.
   * @param account The address of the account for which line items will be retrieved.
   * @returns An array of line item objects for the specified account, or undefined if the account does not exist.
   *
   * @group Line Item
   */
  getLineItems(account) {
    return this.state.accounts.find(({ address }) => address === account)?.lineItems;
  }
  /**
   * Retrieves a specific line item for the specified account.
   * @param account The address of the account for which the line item will be retrieved.
   * @param lineItem An object that contains the category and group of the line item to be retrieved.
   * @returns The line item object that matches the specified category and group, or undefined if it does not exist.
   *
   * @group Line Item
   */
  getLineItem(account, lineItem) {
    return this.getLineItems(account)?.find(
      ({ category, group }) => category?.id === lineItem.category && group?.id === lineItem.group
    );
  }
}

class VestingObject extends object.BaseDocument {
  addVesting(vesting) {
    return this.dispatch(addVesting(vesting));
  }
  updateVesting(vesting) {
    return this.dispatch(updateVesting(vesting));
  }
  deleteVesting(vesting) {
    return this.dispatch(deleteVesting(vesting));
  }
  get vesting() {
    return this.state.vesting;
  }
  getVesting(key) {
    return this.state.vesting.find((v) => v.key === key);
  }
}

let BudgetStatement$2 = class BudgetStatement extends object.BaseDocument {
  /**
   * The file extension used to save budget statements.
   */
  static fileExtension = "phbs";
  /**
   *
   * Creates a new BudgetStatement instance.
   * @param initialState - An optional object representing the initial state of the BudgetStatement.
   */
  constructor(initialState) {
    const document = createBudgetStatement(initialState);
    super(reducer, document.extendedState);
  }
  /**
   * Saves the budget statement to a file.
   *
   * @param path The path to the file to save.
   * @returns A promise that resolves when the save operation completes.
   */
  saveToFile(path, name) {
    return super.saveToFile(path, BudgetStatement.fileExtension, name);
  }
  /**
   * Loads the budget statement from a file.
   *
   * @param path The path to the file to load.
   * @returns A promise that resolves with the loaded `BudgetStatement` instance.
   */
  loadFromFile(path) {
    return super.loadFromFile(path);
  }
  /**
   * Creates a new `BudgetStatement` instance from a file.
   *
   * @param path The path to the file to load.
   * @returns A promise that resolves with the loaded `BudgetStatement` instance.
   */
  static async fromFile(path) {
    const budgetStatement = new this();
    await budgetStatement.loadFromFile(path);
    return budgetStatement;
  }
};
object.applyMixins(BudgetStatement$2, [
  AccountObject,
  AuditObject,
  CommentObject,
  BaseObject,
  LineItemObject,
  VestingObject
]);

var gen = /*#__PURE__*/Object.freeze({
  __proto__: null,
  BudgetStatement: BudgetStatement$2,
  addAccount: addAccount,
  addAuditReport: addAuditReport,
  addComment: addComment,
  addLineItem: addLineItem,
  addVesting: addVesting,
  deleteAccount: deleteAccount,
  deleteAuditReport: deleteAuditReport,
  deleteComment: deleteComment,
  deleteLineItem: deleteLineItem,
  deleteVesting: deleteVesting,
  setFtes: setFtes,
  setMonth: setMonth,
  setOwner: setOwner,
  setQuoteCurrency: setQuoteCurrency,
  sortAccounts: sortAccounts,
  sortLineItems: sortLineItems,
  updateAccount: updateAccount,
  updateComment: updateComment,
  updateLineItem: updateLineItem,
  updateVesting: updateVesting
});

const { BudgetStatement, ...BudgetActions } = gen;
const actions = { ...object.BaseActions, ...BudgetActions };
var index = {
  actions,
  reducer,
  utils,
  BudgetStatement
};

var BudgetStatement$1 = /*#__PURE__*/Object.freeze({
  __proto__: null,
  BudgetStatement: BudgetStatement,
  actions: actions,
  default: index,
  reducer: reducer,
  utils: utils
});

exports.BudgetStatement = BudgetStatement$1;
exports.BudgetStatement$1 = BudgetStatement;
exports.actions = actions;
exports.index = index;
exports.reducer = reducer;
exports.utils = utils;
//# sourceMappingURL=index-0cbda368.js.map
