react-pert 1.0.1 → 1.0.3

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/README.md CHANGED
@@ -1,4 +1,11 @@
1
- <h1 align="center">react-pert</h1>
1
+ # react-pert
2
+
3
+ <img src="public/cover.jpg" />
4
+
5
+ [![-](https://img.shields.io/github/stars/ucfx/react-pert?style=for-the-badge&colorA=000000&colorB=6868ff)](https://github.com/ucfx/react-pert/stargazers)
6
+ [![-](https://img.shields.io/npm/v/react-pert?style=for-the-badge&colorA=000000&colorB=6868ff)](https://www.npmjs.com/package/react-pert)
7
+ [![Build Size](https://img.shields.io/bundlephobia/minzip/react-pert?label=bundle%20size&style=for-the-badge&colorA=000000&colorB=6868ff)](https://bundlephobia.com/result?p=react-pert)
8
+ [![Downloads](https://img.shields.io/npm/dt/react-pert.svg?style=for-the-badge&colorA=000000&colorB=6868ff)](https://www.npmjs.com/package/react-pert)
2
9
 
3
10
  ## :star2: Overview
4
11
 
@@ -17,6 +24,8 @@ This package provides tools to calculate and visualize a PERT (Program Evaluatio
17
24
 
18
25
  Check out the live demo [here](https://ucfx.github.io/react-pert/).
19
26
 
27
+ <img src="public/demo.jpg" />
28
+
20
29
  ---
21
30
 
22
31
  ## :clipboard: Installation
package/dist/index.d.ts CHANGED
@@ -103,7 +103,7 @@ export declare interface PertStyles {
103
103
  taskBackground?: string;
104
104
  /**
105
105
  * Color of the grid lines in the chart.
106
- * @default "#00000030"
106
+ * @default "#83838350"
107
107
  */
108
108
  gridColor?: string;
109
109
  /**
package/dist/index.js CHANGED
@@ -1,8 +1,8 @@
1
- import './main.css';var J = Object.defineProperty;
2
- var W = (r, t, s) => t in r ? J(r, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : r[t] = s;
3
- var x = (r, t, s) => W(r, typeof t != "symbol" ? t + "" : t, s);
4
- import { jsx as h, jsxs as L, Fragment as Z } from "react/jsx-runtime";
5
- import b, { createContext as j, useContext as C, useState as D, useCallback as F, useMemo as P, useRef as K, useEffect as q } from "react";
1
+ import './main.css';var W = Object.defineProperty;
2
+ var Z = (r, t, s) => t in r ? W(r, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : r[t] = s;
3
+ var x = (r, t, s) => Z(r, typeof t != "symbol" ? t + "" : t, s);
4
+ import { jsx as h, jsxs as L, Fragment as q } from "react/jsx-runtime";
5
+ import b, { createContext as j, useState as D, useCallback as F, useContext as S, useMemo as _, useRef as K, useEffect as Q } from "react";
6
6
  const N = () => Math.random().toString(36).substring(7);
7
7
  let G = class {
8
8
  constructor(t) {
@@ -88,7 +88,7 @@ let G = class {
88
88
  calculateLateTimes(t, s) {
89
89
  var o;
90
90
  const e = this.tasksMap.get(t), n = this.getSuccessors(e);
91
- n.length === 0 && ((o = this.tasksMap.get(this.lastTaskKey).dependsOn) == null || o.push(t));
91
+ e.key !== this.lastTaskKey && n.length === 0 && ((o = this.tasksMap.get(this.lastTaskKey).dependsOn) == null || o.push(t));
92
92
  let i = n.length === 0 ? s : Math.min(...n.map((l) => l.lateFinish - l.duration));
93
93
  e.lateFinish = i, e.lateStart = e.lateFinish - e.duration, e.critical = e.earlyFinish === e.lateFinish, e.critical ? (e.freeFloat = 0, e.totalFloat = 0) : (e.freeFloat = (n.length === 0 ? s : Math.min(...n.map((l) => l.earlyStart))) - e.earlyFinish, e.totalFloat = e.lateFinish - e.earlyFinish);
94
94
  }
@@ -212,8 +212,8 @@ const I = {
212
212
  children: t
213
213
  }
214
214
  );
215
- }, Ft = U(A), Q = U(B), Lt = (r = { bounds: !0 }) => {
216
- const t = C(A);
215
+ }, Ft = U(A), z = U(B), Lt = (r = { bounds: !0 }) => {
216
+ const t = S(A);
217
217
  if (!t)
218
218
  throw new Error("usePertData must be used within a PertProvider");
219
219
  const s = Array.from(t.pertData.tasks.values()), e = r != null && r.bounds ? s.slice(1, -1).map((n) => {
@@ -230,9 +230,9 @@ const I = {
230
230
  projectDuration: t.pertData.projectDuration
231
231
  };
232
232
  }, Y = () => {
233
- const r = C(A);
233
+ const r = S(A);
234
234
  if (!r) {
235
- const t = C(B);
235
+ const t = S(B);
236
236
  if (!t)
237
237
  throw new Error(
238
238
  "usePertData must be used within a PertProvider or InternalPertProvider"
@@ -240,13 +240,12 @@ const I = {
240
240
  return t;
241
241
  }
242
242
  return r;
243
- }, z = "_arrows_62ntr_1", tt = "_arrow_62ntr_1", et = "_critical_62ntr_8", st = "_onHover_62ntr_13", rt = "_onSelect_62ntr_17", nt = "_hover_62ntr_24", it = "_visible_62ntr_25", $ = {
244
- arrows: z,
245
- arrow: tt,
246
- critical: et,
247
- onHover: st,
248
- onSelect: rt,
249
- hover: nt,
243
+ }, tt = "_arrows_62ntr_1", et = "_arrow_62ntr_1", st = "_critical_62ntr_8", rt = "_onHover_62ntr_13", nt = "_onSelect_62ntr_17", it = "_visible_62ntr_25", $ = {
244
+ arrows: tt,
245
+ arrow: et,
246
+ critical: st,
247
+ onHover: rt,
248
+ onSelect: nt,
250
249
  visible: it
251
250
  }, lt = ({
252
251
  arrows: r,
@@ -260,32 +259,32 @@ const I = {
260
259
  arrowStyles: a
261
260
  }) => {
262
261
  const c = (u, f) => o === u || o === f || l === u || l === f, y = (u, f = !1) => {
263
- const d = i.get(u), v = d.level, k = s.get(v).findIndex((R) => R === u), m = s.get(v).length, p = m * t + (m - 1) * n.y, E = (e.height - p) / 2 + t / 2, w = v * (t + n.x) + (f ? t * (3 / 2) : t / 2), T = k * (t + n.y) + E;
264
- return { x: w, y: T, level: v, task: d };
262
+ const d = i.get(u), k = d.level, v = s.get(k).findIndex((P) => P === u), m = s.get(k).length, p = m * t + (m - 1) * n.y, E = (e.height - p) / 2 + t / 2, w = k * (t + n.x) + (f ? t * (3 / 2) : t / 2), T = v * (t + n.y) + E;
263
+ return { x: w, y: T, level: k, task: d };
265
264
  }, g = `${$.arrows} ${o ? $.onSelect : ""} ${l ? $.onHover : ""}`;
266
265
  return /* @__PURE__ */ h("g", { className: g, children: r.map((u, f) => {
267
266
  const {
268
267
  x: d,
269
- y: v,
270
- level: k,
268
+ y: k,
269
+ level: v,
271
270
  task: m
272
271
  } = y(u.from, !0), {
273
272
  x: p,
274
273
  y: E,
275
274
  level: w,
276
275
  task: T
277
- } = y(u.to), R = `${$.arrow} ${c(m.key, T.key) ? $.visible : ""} ${u.critical ? $.critical : ""}`;
276
+ } = y(u.to), P = `${$.arrow} ${c(m.key, T.key) ? $.visible : ""} ${u.critical ? $.critical : ""}`;
278
277
  return /* @__PURE__ */ h(
279
278
  "path",
280
279
  {
281
- className: R,
282
- d: `M ${d} ${v} C ${d + 20 * (w - k) + (p - d) / 1.2} ${v} ${d + 20 * (w - k) + (p - d) / 4} ${E} ${p} ${E}`,
280
+ className: P,
281
+ d: `M ${d} ${k} C ${d + 20 * (w - v) + (p - d) / 1.2} ${k} ${d + 20 * (w - v) + (p - d) / 4} ${E} ${p} ${E}`,
283
282
  style: a
284
283
  },
285
284
  f
286
285
  );
287
286
  }) });
288
- }, at = "_tasks_1slwh_1", ot = "_task_1slwh_1", ct = "_critical_1slwh_22", ht = "_selected_1slwh_35", dt = "_visible_1slwh_44", S = {
287
+ }, at = "_tasks_1slwh_1", ot = "_task_1slwh_1", ct = "_critical_1slwh_22", ht = "_selected_1slwh_35", dt = "_visible_1slwh_44", R = {
289
288
  tasks: at,
290
289
  task: ot,
291
290
  critical: ct,
@@ -293,7 +292,7 @@ const I = {
293
292
  visible: dt
294
293
  }, ut = ({ task: r, x: t, y: s, dimensions: e }) => {
295
294
  const { halfRadius: n, twoThirdsRadius: i } = e;
296
- return /* @__PURE__ */ L(Z, { children: [
295
+ return /* @__PURE__ */ L(q, { children: [
297
296
  /* @__PURE__ */ h("text", { x: t - n, y: s - i, fill: "black", children: r.earlyStart }),
298
297
  /* @__PURE__ */ h("text", { x: t + n, y: s - i, fill: "black", children: r.earlyFinish }),
299
298
  /* @__PURE__ */ h("text", { x: t - n, y: s + i, fill: "black", children: r.lateStart }),
@@ -310,7 +309,7 @@ const I = {
310
309
  isSelected: l,
311
310
  taskStyles: a
312
311
  }) => {
313
- const { radius: c } = e, y = P(
312
+ const { radius: c } = e, y = _(
314
313
  () => `
315
314
  M ${t - c} ${s - c / 3}
316
315
  L ${t + c} ${s - c / 3}
@@ -326,7 +325,7 @@ const I = {
326
325
  return /* @__PURE__ */ L(
327
326
  "g",
328
327
  {
329
- className: `${S.task} ${l ? S.selected : ""} ${o ? S.visible : ""} ${r.critical ? S.critical : ""}`,
328
+ className: `${R.task} ${l ? R.selected : ""} ${o ? R.visible : ""} ${r.critical ? R.critical : ""}`,
330
329
  onMouseEnter: () => n(r.key, !0),
331
330
  onMouseLeave: () => n(r.key, !1),
332
331
  onClick: () => i(r.key),
@@ -349,7 +348,7 @@ const I = {
349
348
  ]
350
349
  }
351
350
  );
352
- }, yt = b.memo(ft), vt = ({
351
+ }, yt = b.memo(ft), kt = ({
353
352
  level: r,
354
353
  keyList: t,
355
354
  tasks: s,
@@ -365,23 +364,23 @@ const I = {
365
364
  var p, E, w;
366
365
  const f = s.get(g);
367
366
  if (!f) return null;
368
- const d = r * e + e + n.x * r, v = u * (e + n.y) + i, k = !!(l && ((p = f.dependsOn) != null && p.includes(l) || (w = (E = s.get(l)) == null ? void 0 : E.dependsOn) != null && w.includes(f.key))), m = f.key === l;
367
+ const d = r * e + e + n.x * r, k = u * (e + n.y) + i, v = !!(l && ((p = f.dependsOn) != null && p.includes(l) || (w = (E = s.get(l)) == null ? void 0 : E.dependsOn) != null && w.includes(f.key))), m = f.key === l;
369
368
  return /* @__PURE__ */ h(
370
369
  yt,
371
370
  {
372
371
  task: f,
373
372
  x: d,
374
- y: v,
373
+ y: k,
375
374
  dimensions: o,
376
375
  onHover: a,
377
376
  onTaskClick: c,
378
377
  isSelected: m,
379
- isVisible: k,
378
+ isVisible: v,
380
379
  taskStyles: y
381
380
  },
382
381
  f.key
383
382
  );
384
- }) }), kt = b.memo(vt), gt = ({
383
+ }) }), vt = b.memo(kt), gt = ({
385
384
  tasks: r,
386
385
  levels: t,
387
386
  taskSize: s,
@@ -391,7 +390,7 @@ const I = {
391
390
  setHoveredTask: o,
392
391
  taskStyles: l
393
392
  }) => {
394
- const a = P(
393
+ const a = _(
395
394
  () => ({
396
395
  radius: s / 2,
397
396
  halfRadius: s / 4,
@@ -405,20 +404,20 @@ const I = {
405
404
  [o]
406
405
  ), y = F(
407
406
  (u) => {
408
- _t(i !== u ? u : null);
407
+ X(i !== u ? u : null);
409
408
  },
410
409
  [i]
411
- ), g = P(() => Array.from(t.entries()).map(([u, f]) => {
412
- const d = f.length * s + (f.length - 1) * n.y, v = (e.height - d) / 2 + a.radius;
410
+ ), g = _(() => Array.from(t.entries()).map(([u, f]) => {
411
+ const d = f.length * s + (f.length - 1) * n.y, k = (e.height - d) / 2 + a.radius;
413
412
  return /* @__PURE__ */ h(
414
- kt,
413
+ vt,
415
414
  {
416
415
  level: u,
417
416
  keyList: f,
418
417
  tasks: r,
419
418
  taskSize: s,
420
419
  gap: n,
421
- offset: v,
420
+ offset: k,
422
421
  dimensions: a,
423
422
  selectedTask: i,
424
423
  onHover: c,
@@ -439,7 +438,7 @@ const I = {
439
438
  y,
440
439
  l
441
440
  ]);
442
- return /* @__PURE__ */ h("g", { className: S.tasks, children: g });
441
+ return /* @__PURE__ */ h("g", { className: R.tasks, children: g });
443
442
  }, mt = b.memo(gt), pt = {
444
443
  width: 300,
445
444
  height: 200
@@ -450,8 +449,7 @@ const I = {
450
449
  }, M = {
451
450
  CRITICAL: "#ff9147",
452
451
  TASK_BG: "#aaaeff",
453
- CHART_BG: "#fff",
454
- GRID: "#00000030",
452
+ GRID: "#83838350",
455
453
  TEXT: "#000",
456
454
  SELECTED: "#6868ff",
457
455
  STROKE: "#615f77"
@@ -499,8 +497,8 @@ const wt = ({
499
497
  criticalColor: u,
500
498
  arrowColor: f,
501
499
  arrowWidth: d,
502
- chartBackground: v,
503
- textColor: k,
500
+ chartBackground: k,
501
+ textColor: v,
504
502
  fontFamily: m,
505
503
  borderWidth: p,
506
504
  hoverBorderWidth: E,
@@ -508,7 +506,7 @@ const wt = ({
508
506
  gridColor: T
509
507
  }
510
508
  }) => {
511
- const R = {
509
+ const P = {
512
510
  "--task-bg": c ?? M.TASK_BG,
513
511
  "--task-bg-critical": u ?? M.CRITICAL,
514
512
  "--task-stroke-color": g ?? M.STROKE,
@@ -516,16 +514,16 @@ const wt = ({
516
514
  "--task-stroke-hover-width": E ?? O.HOVER_BORDER,
517
515
  "--task-selected-stroke-width": w ?? O.SELECTED_BORDER,
518
516
  "--task-selected-stroke-color": y ?? M.SELECTED,
519
- "--task-text-color": k ?? M.TEXT,
517
+ "--task-text-color": v ?? M.TEXT,
520
518
  "--task-font-family": m ?? "inherit"
521
- }, X = {
519
+ }, V = {
522
520
  "--arrow-stroke-color": f ?? M.STROKE,
523
521
  "--arrow-critical-stroke-color": u ?? M.CRITICAL,
524
522
  "--arrow-stroke-width": d ?? 2
525
- }, V = {
523
+ }, J = {
526
524
  ...Tt,
527
525
  fontSize: i,
528
- backgroundColor: v
526
+ backgroundColor: k
529
527
  };
530
528
  return /* @__PURE__ */ h(
531
529
  "svg",
@@ -534,7 +532,7 @@ const wt = ({
534
532
  height: r.height,
535
533
  viewBox: `0 0 ${r.width} ${r.height}`,
536
534
  xmlns: "http://www.w3.org/2000/svg",
537
- style: V,
535
+ style: J,
538
536
  dominantBaseline: "central",
539
537
  textAnchor: "middle",
540
538
  children: /* @__PURE__ */ L("g", { className: "content", children: [
@@ -550,7 +548,7 @@ const wt = ({
550
548
  tasks: t.tasks,
551
549
  selectedTask: s,
552
550
  hoveredTask: n,
553
- arrowStyles: X
551
+ arrowStyles: V
554
552
  }
555
553
  ),
556
554
  /* @__PURE__ */ h(
@@ -563,7 +561,7 @@ const wt = ({
563
561
  levels: t.levels,
564
562
  selectedTask: s,
565
563
  setHoveredTask: e,
566
- taskStyles: R
564
+ taskStyles: P
567
565
  }
568
566
  )
569
567
  ] })
@@ -590,7 +588,7 @@ const Mt = ({
590
588
  gap: t
591
589
  }) => {
592
590
  const { pertData: s } = Y();
593
- return P(() => {
591
+ return _(() => {
594
592
  const e = Array.from(s.levels.values());
595
593
  if (!e.length)
596
594
  return { width: 0, height: 0 };
@@ -611,31 +609,31 @@ const Mt = ({
611
609
  min: "0.75rem",
612
610
  max: "2rem"
613
611
  };
614
- let _ = null;
615
- const _t = (r) => {
616
- if (_) {
617
- if (!r)
618
- _.setter(null);
619
- else if (_.getTask) {
620
- const t = _.getTask(r);
621
- t && _.onSelect && _.onSelect(t), _.setter(r);
622
- }
612
+ let C = null;
613
+ const X = (r) => {
614
+ if (!C) return;
615
+ const { setter: t, onSelect: s, getTask: e } = C;
616
+ if (!r) {
617
+ t(null), s == null || s(null);
618
+ return;
623
619
  }
620
+ const n = (e == null ? void 0 : e(r)) ?? null;
621
+ s == null || s(n), t(n ? r : null);
624
622
  }, $t = ({ tasks: r, onSelect: t, styles: s }) => {
625
623
  const { pertData: e, calculatePertResults: n, error: i } = Y(), o = K(), [l, a] = D(null), [c, y] = D(null), g = (T) => e.tasks.get(T);
626
- _ = { setter: K(a).current, getTask: g, onSelect: t }, q(() => {
624
+ C = { setter: K(a).current, getTask: g, onSelect: t }, Q(() => {
627
625
  const T = JSON.stringify(r);
628
- o.current !== T && (n(r), o.current = T);
626
+ o.current !== T && (n(r), X(null), o.current = T);
629
627
  }, [r, n]);
630
628
  const f = F((T) => {
631
629
  y(T);
632
- }, []), { gap: d, taskSize: v, fontSize: k } = s, m = Math.max(v ?? 100, 70), p = P(
630
+ }, []), { gap: d, taskSize: k, fontSize: v } = s, m = Math.max(k ?? 100, 70), p = _(
633
631
  () => ({
634
632
  x: Math.max(m, (d == null ? void 0 : d.x) ?? 0),
635
633
  y: Math.max(m, (d == null ? void 0 : d.y) ?? 0)
636
634
  }),
637
635
  [d == null ? void 0 : d.x, d == null ? void 0 : d.y, m]
638
- ), E = Mt({ taskSize: m, gap: p }), w = P(() => k ? typeof k == "number" ? `${k}px` : H[k] || k : H.default, [k]);
636
+ ), E = Mt({ taskSize: m, gap: p }), w = _(() => v ? typeof v == "number" ? `${v}px` : H[v] || v : H.default, [v]);
639
637
  return i ? /* @__PURE__ */ h(xt, { error: i }) : /* @__PURE__ */ h(
640
638
  wt,
641
639
  {
@@ -647,7 +645,7 @@ const _t = (r) => {
647
645
  styles: { ...s, fontSize: w, taskSize: m, gap: p }
648
646
  }
649
647
  );
650
- }, Ot = ({ styles: r, ...t }) => /* @__PURE__ */ h(Q, { children: /* @__PURE__ */ h(
648
+ }, Ot = ({ styles: r, ...t }) => /* @__PURE__ */ h(z, { children: /* @__PURE__ */ h(
651
649
  "div",
652
650
  {
653
651
  style: {
@@ -661,6 +659,6 @@ const _t = (r) => {
661
659
  export {
662
660
  Ot as Pert,
663
661
  Ft as PertProvider,
664
- _t as setSelectedTask,
662
+ X as setSelectedTask,
665
663
  Lt as usePert
666
664
  };
@@ -1,5 +1,5 @@
1
- (function(f,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],n):(f=typeof globalThis<"u"?globalThis:f||self,n(f["react-pert"]={},f["react/jsx-runtime"],f.React))})(this,function(f,n,c){"use strict";var ct=Object.defineProperty;var ht=(f,n,c)=>n in f?ct(f,n,{enumerable:!0,configurable:!0,writable:!0,value:c}):f[n]=c;var m=(f,n,c)=>ht(f,typeof n!="symbol"?n+"":n,c);var O=document.createElement("style");O.textContent=`._arrows_62ntr_1 ._arrow_62ntr_1{fill:transparent;stroke:var(--arrow-stroke-color);stroke-width:var(--arrow-stroke-width);transition:stroke .2s,stroke-width .2s,opacity .2s}._arrows_62ntr_1 ._arrow_62ntr_1._critical_62ntr_8{stroke:var(--arrow-critical-stroke-color)}._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1{opacity:.3}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1{opacity:0}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._visible_62ntr_25,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._visible_62ntr_25{stroke-width:calc(var(--arrow-stroke-width) + 1);opacity:1}._tasks_1slwh_1 ._task_1slwh_1{-webkit-user-select:none;user-select:none;transition:filter .2s,opacity .2s}._tasks_1slwh_1 ._task_1slwh_1 text{fill:var(--task-text-color);font-family:var(--task-font-family)}._tasks_1slwh_1 ._task_1slwh_1 rect{transition:stroke-width .2s;stroke:var(--task-stroke-color);stroke-width:var(--task-stroke-width);fill:var(--task-bg)}._tasks_1slwh_1 ._task_1slwh_1 rect~path{stroke:var(--task-stroke-color)}._tasks_1slwh_1 ._task_1slwh_1._critical_1slwh_22 rect{fill:var(--task-bg-critical)}._tasks_1slwh_1 ._task_1slwh_1:hover{cursor:pointer;filter:brightness(.9)}._tasks_1slwh_1 ._task_1slwh_1:hover rect{stroke-width:var(--task-stroke-hover-width)}._tasks_1slwh_1 ._task_1slwh_1._selected_1slwh_35 rect{stroke:var(--task-selected-stroke-color);stroke-width:var(--task-selected-stroke-width)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44){opacity:.7;filter:brightness(.6)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover{cursor:pointer;filter:brightness(.9);opacity:1}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover rect{stroke:var(--task-stroke-color);stroke-linejoin:bevel}
2
- `,document.head.appendChild(O);const L=()=>Math.random().toString(36).substring(7);let B=class{constructor(t){m(this,"levels");m(this,"tasksMap");m(this,"initialData");m(this,"links");m(this,"criticalPaths");m(this,"lastTaskKey");m(this,"startTaskKey");m(this,"projectDuration");this.initialData=t,this.tasksMap=new Map,this.lastTaskKey=`Finish-${L()}`,this.startTaskKey=`Start-${L()}`,this.links=[],this.criticalPaths=[],this.levels=new Map,this.projectDuration=0}convertDataToMap(){this.tasksMap=new Map,this.tasksMap.set(this.startTaskKey,{key:this.startTaskKey,duration:0,text:"Start"}),this.initialData.forEach((t,s)=>{if(this.tasksMap.has(t.key))throw Error(`Duplicate keys found ${t.key}`);this.tasksMap.set(t.key,!t.dependsOn||t.dependsOn.length===0?{...t,dependsOn:[this.startTaskKey],index:s}:{...t,index:s})})}calculatePERT(){this.convertDataToMap(),this.calcLevels(),this.levels.forEach(s=>{s.forEach(e=>{this.calculateEarlyTimes(e)})});let t=Array.from(this.tasksMap.values()).reduce((s,e)=>s.earlyFinish>e.earlyFinish?s:e);t.lateFinish=t.earlyFinish,t.critical=!0,this.tasksMap.set(this.lastTaskKey,{key:this.lastTaskKey,text:"Finish",dependsOn:[t.key],duration:0,earlyStart:t.earlyFinish,earlyFinish:t.earlyFinish,lateFinish:t.earlyFinish,lateStart:t.earlyFinish,level:this.levels.size,critical:!0,freeFloat:0,totalFloat:0,index:this.tasksMap.size-1}),this.levels.set(this.levels.size,[this.lastTaskKey]),this.projectDuration=t.lateFinish;for(const[,s]of[...this.levels.entries()].reverse())s.forEach(e=>{this.calculateLateTimes(e,t.lateFinish)});this.levels.forEach((s,e)=>{this.levels.set(e,s.sort((l,a)=>this.tasksMap.get(l).index-this.tasksMap.get(a).index))})}getSuccessors(t){return Array.from(this.tasksMap.values()).filter(s=>s.dependsOn&&s.dependsOn.includes(t.key))}calculateEarlyTimes(t){const s=this.tasksMap.get(t);if(!s.dependsOn)s.earlyStart=0;else{let e=0;s.dependsOn.forEach(l=>{const a=this.tasksMap.get(l);e=Math.max(e,a.earlyStart+a.duration)}),s.earlyStart=e}s.earlyFinish=s.earlyStart+s.duration}calculateLateTimes(t,s){var h;const e=this.tasksMap.get(t),l=this.getSuccessors(e);l.length===0&&((h=this.tasksMap.get(this.lastTaskKey).dependsOn)==null||h.push(t));let a=l.length===0?s:Math.min(...l.map(o=>o.lateFinish-o.duration));e.lateFinish=a,e.lateStart=e.lateFinish-e.duration,e.critical=e.earlyFinish===e.lateFinish,e.critical?(e.freeFloat=0,e.totalFloat=0):(e.freeFloat=(l.length===0?s:Math.min(...l.map(o=>o.earlyStart)))-e.earlyFinish,e.totalFloat=e.lateFinish-e.earlyFinish)}calcLevels(){this.levels.clear();let t=[];const s=e=>{if(t.includes(e.key))throw new Error("Circular dependency detected");if(!e.dependsOn||e.dependsOn.length===0)e.level=0;else{let a=0;e.dependsOn.forEach(h=>{const o=this.tasksMap.get(h);if(!o)throw new Error(`Task with KEY '${h}' was not found.`);o.level===void 0&&(t.push(e.key),s(o)),a=Math.max(a,o.level+1)}),e.level=a}this.levels.has(e.level)||this.levels.set(e.level,[]);const l=this.levels.get(e.level);l.includes(e.key)||l.push(e.key)};this.tasksMap.forEach(e=>{e.level===void 0&&(t=[],s(e))})}calcNodeLinks(){const t=[],s=[];this.tasksMap.forEach((e,l)=>{e.dependsOn?e.dependsOn.forEach(a=>{s.push(a),t.push({from:a,to:e.key,critical:e.critical&&this.tasksMap.get(a).critical})}):l!==this.startTaskKey&&t.push({from:this.startTaskKey,to:e.key,critical:e.critical})}),this.tasksMap.forEach(e=>{!s.includes(e.key)&&e.key!==this.lastTaskKey&&t.push({from:e.key,to:this.lastTaskKey,critical:e.critical})}),this.links=t}calcCriticalPaths(){this.calcNodeLinks();const t=[];this.links.filter(e=>e.critical&&e.from===this.startTaskKey&&e.to!==this.lastTaskKey).forEach(e=>{const l=[e],a=h=>{const o=this.links.filter(i=>i.critical&&i.from===h.to&&i.to!==this.lastTaskKey);o.length===0?t.push(l.map(i=>({text:this.tasksMap.get(i.to).text,key:i.to}))):o.forEach(i=>{l.push(i),a(i),l.pop()})};a(e)}),this.criticalPaths=t}getTasks(){return this.calculatePERT(),this.tasksMap}getCriticalPaths(){return this.criticalPaths.length===0&&this.calcCriticalPaths(),this.criticalPaths}getLevels(){return this.levels}getNodeLinks(){return this.links}getProjectDuration(){return this.projectDuration}solve(){return{tasks:this.getTasks(),levels:this.getLevels(),criticalPaths:this.getCriticalPaths(),links:this.getNodeLinks(),projectDuration:this.getProjectDuration()}}};const A={tasks:new Map,levels:new Map,links:[],criticalPaths:[],projectDuration:0},D=c.createContext(null),H=c.createContext(null),K=r=>({children:t})=>{const[s,e]=c.useState(A),[l,a]=c.useState(null),h=c.useCallback(o=>{try{const i=new B(o).solve();e(i),a(null)}catch(i){console.error(i),e(A),a(i.message)}},[]);return n.jsx(r.Provider,{value:{pertData:s,calculatePertResults:h,error:l},children:t})},U=K(D),Y=K(H),X=(r={bounds:!0})=>{const t=c.useContext(D);if(!t)throw new Error("usePertData must be used within a PertProvider");const s=Array.from(t.pertData.tasks.values()),e=r!=null&&r.bounds?s.slice(1,-1).map(l=>{var a;return{...l,dependsOn:(a=l.dependsOn)!=null&&a.includes(s[0].key)?[]:l.dependsOn}}):s;return{...t.pertData,tasks:e,error:t.error,projectDuration:t.pertData.projectDuration}},N=()=>{const r=c.useContext(D);if(!r){const t=c.useContext(H);if(!t)throw new Error("usePertData must be used within a PertProvider or InternalPertProvider");return t}return r},$={arrows:"_arrows_62ntr_1",arrow:"_arrow_62ntr_1",critical:"_critical_62ntr_8",onHover:"_onHover_62ntr_13",onSelect:"_onSelect_62ntr_17",hover:"_hover_62ntr_24",visible:"_visible_62ntr_25"},V=({arrows:r,taskSize:t,levels:s,size:e,gap:l,tasks:a,selectedTask:h,hoveredTask:o,arrowStyles:i})=>{const _=(k,u)=>h===k||h===u||o===k||o===u,w=(k,u=!1)=>{const d=a.get(k),v=d.level,y=s.get(v).findIndex(C=>C===k),g=s.get(v).length,T=g*t+(g-1)*l.y,x=(e.height-T)/2+t/2,M=v*(t+l.x)+(u?t*(3/2):t/2),E=y*(t+l.y)+x;return{x:M,y:E,level:v,task:d}},p=`${$.arrows} ${h?$.onSelect:""} ${o?$.onHover:""}`;return n.jsx("g",{className:p,children:r.map((k,u)=>{const{x:d,y:v,level:y,task:g}=w(k.from,!0),{x:T,y:x,level:M,task:E}=w(k.to),C=`${$.arrow} ${_(g.key,E.key)?$.visible:""} ${k.critical?$.critical:""}`;return n.jsx("path",{className:C,d:`M ${d} ${v} C ${d+20*(M-y)+(T-d)/1.2} ${v} ${d+20*(M-y)+(T-d)/4} ${x} ${T} ${x}`,style:i},u)})})},b={tasks:"_tasks_1slwh_1",task:"_task_1slwh_1",critical:"_critical_1slwh_22",selected:"_selected_1slwh_35",visible:"_visible_1slwh_44"},q=({task:r,x:t,y:s,dimensions:e})=>{const{halfRadius:l,twoThirdsRadius:a}=e;return n.jsxs(n.Fragment,{children:[n.jsx("text",{x:t-l,y:s-a,fill:"black",children:r.earlyStart}),n.jsx("text",{x:t+l,y:s-a,fill:"black",children:r.earlyFinish}),n.jsx("text",{x:t-l,y:s+a,fill:"black",children:r.lateStart}),n.jsx("text",{x:t+l,y:s+a,fill:"black",children:r.lateFinish})]})},J=({task:r,x:t,y:s,dimensions:e,onHover:l,onTaskClick:a,isVisible:h,isSelected:o,taskStyles:i})=>{const{radius:_}=e,w=c.useMemo(()=>`
1
+ (function(f,n){typeof exports=="object"&&typeof module<"u"?n(exports,require("react/jsx-runtime"),require("react")):typeof define=="function"&&define.amd?define(["exports","react/jsx-runtime","react"],n):(f=typeof globalThis<"u"?globalThis:f||self,n(f["react-pert"]={},f["react/jsx-runtime"],f.React))})(this,function(f,n,c){"use strict";var ct=Object.defineProperty;var ht=(f,n,c)=>n in f?ct(f,n,{enumerable:!0,configurable:!0,writable:!0,value:c}):f[n]=c;var M=(f,n,c)=>ht(f,typeof n!="symbol"?n+"":n,c);var L=document.createElement("style");L.textContent=`._arrows_62ntr_1 ._arrow_62ntr_1{fill:transparent;stroke:var(--arrow-stroke-color);stroke-width:var(--arrow-stroke-width);transition:stroke .2s,stroke-width .2s,opacity .2s}._arrows_62ntr_1 ._arrow_62ntr_1._critical_62ntr_8{stroke:var(--arrow-critical-stroke-color)}._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1{opacity:.3}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1{opacity:0}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._visible_62ntr_25,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._visible_62ntr_25{stroke-width:calc(var(--arrow-stroke-width) + 1);opacity:1}._tasks_1slwh_1 ._task_1slwh_1{-webkit-user-select:none;-moz-user-select:none;user-select:none;transition:filter .2s,opacity .2s}._tasks_1slwh_1 ._task_1slwh_1 text{fill:var(--task-text-color);font-family:var(--task-font-family)}._tasks_1slwh_1 ._task_1slwh_1 rect{transition:stroke-width .2s;stroke:var(--task-stroke-color);stroke-width:var(--task-stroke-width);fill:var(--task-bg)}._tasks_1slwh_1 ._task_1slwh_1 rect~path{stroke:var(--task-stroke-color)}._tasks_1slwh_1 ._task_1slwh_1._critical_1slwh_22 rect{fill:var(--task-bg-critical)}._tasks_1slwh_1 ._task_1slwh_1:hover{cursor:pointer;filter:brightness(.9)}._tasks_1slwh_1 ._task_1slwh_1:hover rect{stroke-width:var(--task-stroke-hover-width)}._tasks_1slwh_1 ._task_1slwh_1._selected_1slwh_35 rect{stroke:var(--task-selected-stroke-color);stroke-width:var(--task-selected-stroke-width)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44){opacity:.7;filter:brightness(.6)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover{cursor:pointer;filter:brightness(.9);opacity:1}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover rect{stroke:var(--task-stroke-color);stroke-linejoin:bevel}
2
+ /*$vite$:1*/`,document.head.appendChild(L);const A=()=>Math.random().toString(36).substring(7);let B=class{constructor(t){M(this,"levels");M(this,"tasksMap");M(this,"initialData");M(this,"links");M(this,"criticalPaths");M(this,"lastTaskKey");M(this,"startTaskKey");M(this,"projectDuration");this.initialData=t,this.tasksMap=new Map,this.lastTaskKey=`Finish-${A()}`,this.startTaskKey=`Start-${A()}`,this.links=[],this.criticalPaths=[],this.levels=new Map,this.projectDuration=0}convertDataToMap(){this.tasksMap=new Map,this.tasksMap.set(this.startTaskKey,{key:this.startTaskKey,duration:0,text:"Start"}),this.initialData.forEach((t,s)=>{if(this.tasksMap.has(t.key))throw Error(`Duplicate keys found ${t.key}`);this.tasksMap.set(t.key,!t.dependsOn||t.dependsOn.length===0?{...t,dependsOn:[this.startTaskKey],index:s}:{...t,index:s})})}calculatePERT(){this.convertDataToMap(),this.calcLevels(),this.levels.forEach(s=>{s.forEach(e=>{this.calculateEarlyTimes(e)})});let t=Array.from(this.tasksMap.values()).reduce((s,e)=>s.earlyFinish>e.earlyFinish?s:e);t.lateFinish=t.earlyFinish,t.critical=!0,this.tasksMap.set(this.lastTaskKey,{key:this.lastTaskKey,text:"Finish",dependsOn:[t.key],duration:0,earlyStart:t.earlyFinish,earlyFinish:t.earlyFinish,lateFinish:t.earlyFinish,lateStart:t.earlyFinish,level:this.levels.size,critical:!0,freeFloat:0,totalFloat:0,index:this.tasksMap.size-1}),this.levels.set(this.levels.size,[this.lastTaskKey]),this.projectDuration=t.lateFinish;for(const[,s]of[...this.levels.entries()].reverse())s.forEach(e=>{this.calculateLateTimes(e,t.lateFinish)});this.levels.forEach((s,e)=>{this.levels.set(e,s.sort((l,a)=>this.tasksMap.get(l).index-this.tasksMap.get(a).index))})}getSuccessors(t){return Array.from(this.tasksMap.values()).filter(s=>s.dependsOn&&s.dependsOn.includes(t.key))}calculateEarlyTimes(t){const s=this.tasksMap.get(t);if(!s.dependsOn)s.earlyStart=0;else{let e=0;s.dependsOn.forEach(l=>{const a=this.tasksMap.get(l);e=Math.max(e,a.earlyStart+a.duration)}),s.earlyStart=e}s.earlyFinish=s.earlyStart+s.duration}calculateLateTimes(t,s){var h;const e=this.tasksMap.get(t),l=this.getSuccessors(e);e.key!==this.lastTaskKey&&l.length===0&&((h=this.tasksMap.get(this.lastTaskKey).dependsOn)==null||h.push(t));let a=l.length===0?s:Math.min(...l.map(i=>i.lateFinish-i.duration));e.lateFinish=a,e.lateStart=e.lateFinish-e.duration,e.critical=e.earlyFinish===e.lateFinish,e.critical?(e.freeFloat=0,e.totalFloat=0):(e.freeFloat=(l.length===0?s:Math.min(...l.map(i=>i.earlyStart)))-e.earlyFinish,e.totalFloat=e.lateFinish-e.earlyFinish)}calcLevels(){this.levels.clear();let t=[];const s=e=>{if(t.includes(e.key))throw new Error("Circular dependency detected");if(!e.dependsOn||e.dependsOn.length===0)e.level=0;else{let a=0;e.dependsOn.forEach(h=>{const i=this.tasksMap.get(h);if(!i)throw new Error(`Task with KEY '${h}' was not found.`);i.level===void 0&&(t.push(e.key),s(i)),a=Math.max(a,i.level+1)}),e.level=a}this.levels.has(e.level)||this.levels.set(e.level,[]);const l=this.levels.get(e.level);l.includes(e.key)||l.push(e.key)};this.tasksMap.forEach(e=>{e.level===void 0&&(t=[],s(e))})}calcNodeLinks(){const t=[],s=[];this.tasksMap.forEach((e,l)=>{e.dependsOn?e.dependsOn.forEach(a=>{s.push(a),t.push({from:a,to:e.key,critical:e.critical&&this.tasksMap.get(a).critical})}):l!==this.startTaskKey&&t.push({from:this.startTaskKey,to:e.key,critical:e.critical})}),this.tasksMap.forEach(e=>{!s.includes(e.key)&&e.key!==this.lastTaskKey&&t.push({from:e.key,to:this.lastTaskKey,critical:e.critical})}),this.links=t}calcCriticalPaths(){this.calcNodeLinks();const t=[];this.links.filter(e=>e.critical&&e.from===this.startTaskKey&&e.to!==this.lastTaskKey).forEach(e=>{const l=[e],a=h=>{const i=this.links.filter(o=>o.critical&&o.from===h.to&&o.to!==this.lastTaskKey);i.length===0?t.push(l.map(o=>({text:this.tasksMap.get(o.to).text,key:o.to}))):i.forEach(o=>{l.push(o),a(o),l.pop()})};a(e)}),this.criticalPaths=t}getTasks(){return this.calculatePERT(),this.tasksMap}getCriticalPaths(){return this.criticalPaths.length===0&&this.calcCriticalPaths(),this.criticalPaths}getLevels(){return this.levels}getNodeLinks(){return this.links}getProjectDuration(){return this.projectDuration}solve(){return{tasks:this.getTasks(),levels:this.getLevels(),criticalPaths:this.getCriticalPaths(),links:this.getNodeLinks(),projectDuration:this.getProjectDuration()}}};const K={tasks:new Map,levels:new Map,links:[],criticalPaths:[],projectDuration:0},C=c.createContext(null),H=c.createContext(null),N=r=>({children:t})=>{const[s,e]=c.useState(K),[l,a]=c.useState(null),h=c.useCallback(i=>{try{const o=new B(i).solve();e(o),a(null)}catch(o){console.error(o),e(K),a(o.message)}},[]);return n.jsx(r.Provider,{value:{pertData:s,calculatePertResults:h,error:l},children:t})},U=N(C),Y=N(H),X=(r={bounds:!0})=>{const t=c.useContext(C);if(!t)throw new Error("usePertData must be used within a PertProvider");const s=Array.from(t.pertData.tasks.values()),e=r!=null&&r.bounds?s.slice(1,-1).map(l=>{var a;return{...l,dependsOn:(a=l.dependsOn)!=null&&a.includes(s[0].key)?[]:l.dependsOn}}):s;return{...t.pertData,tasks:e,error:t.error,projectDuration:t.pertData.projectDuration}},j=()=>{const r=c.useContext(C);if(!r){const t=c.useContext(H);if(!t)throw new Error("usePertData must be used within a PertProvider or InternalPertProvider");return t}return r},P={arrows:"_arrows_62ntr_1",arrow:"_arrow_62ntr_1",critical:"_critical_62ntr_8",onHover:"_onHover_62ntr_13",onSelect:"_onSelect_62ntr_17",visible:"_visible_62ntr_25"},V=({arrows:r,taskSize:t,levels:s,size:e,gap:l,tasks:a,selectedTask:h,hoveredTask:i,arrowStyles:o})=>{const _=(u,k)=>h===u||h===k||i===u||i===k,w=(u,k=!1)=>{const d=a.get(u),v=d.level,y=s.get(v).findIndex(S=>S===u),g=s.get(v).length,T=g*t+(g-1)*l.y,m=(e.height-T)/2+t/2,x=v*(t+l.x)+(k?t*(3/2):t/2),E=y*(t+l.y)+m;return{x,y:E,level:v,task:d}},p=`${P.arrows} ${h?P.onSelect:""} ${i?P.onHover:""}`;return n.jsx("g",{className:p,children:r.map((u,k)=>{const{x:d,y:v,level:y,task:g}=w(u.from,!0),{x:T,y:m,level:x,task:E}=w(u.to),S=`${P.arrow} ${_(g.key,E.key)?P.visible:""} ${u.critical?P.critical:""}`;return n.jsx("path",{className:S,d:`M ${d} ${v} C ${d+20*(x-y)+(T-d)/1.2} ${v} ${d+20*(x-y)+(T-d)/4} ${m} ${T} ${m}`,style:o},k)})})},b={tasks:"_tasks_1slwh_1",task:"_task_1slwh_1",critical:"_critical_1slwh_22",selected:"_selected_1slwh_35",visible:"_visible_1slwh_44"},q=({task:r,x:t,y:s,dimensions:e})=>{const{halfRadius:l,twoThirdsRadius:a}=e;return n.jsxs(n.Fragment,{children:[n.jsx("text",{x:t-l,y:s-a,fill:"black",children:r.earlyStart}),n.jsx("text",{x:t+l,y:s-a,fill:"black",children:r.earlyFinish}),n.jsx("text",{x:t-l,y:s+a,fill:"black",children:r.lateStart}),n.jsx("text",{x:t+l,y:s+a,fill:"black",children:r.lateFinish})]})},J=({task:r,x:t,y:s,dimensions:e,onHover:l,onTaskClick:a,isVisible:h,isSelected:i,taskStyles:o})=>{const{radius:_}=e,w=c.useMemo(()=>`
3
3
  M ${t-_} ${s-_/3}
4
4
  L ${t+_} ${s-_/3}
5
5
  M ${t-_} ${s+_/3}
@@ -8,4 +8,4 @@
8
8
  L ${t} ${s+_}
9
9
  M ${t} ${s-_}
10
10
  L ${t} ${s-_/3}
11
- `,[t,s,_]);return n.jsxs("g",{className:`${b.task} ${o?b.selected:""} ${h?b.visible:""} ${r.critical?b.critical:""}`,onMouseEnter:()=>l(r.key,!0),onMouseLeave:()=>l(r.key,!1),onClick:()=>a(r.key),style:i,children:[n.jsx("rect",{x:t-_,y:s-_,rx:"20",ry:"20",width:_*2,height:_*2}),n.jsx("text",{x:t,y:s,children:r.text}),n.jsx(q,{task:r,x:t,y:s,dimensions:e}),n.jsx("path",{d:w,fill:"none"})]})},W=c.memo(J),Z=({level:r,keyList:t,tasks:s,taskSize:e,gap:l,offset:a,dimensions:h,selectedTask:o,onHover:i,onTaskClick:_,taskStyles:w})=>n.jsx("g",{children:t.map((p,k)=>{var T,x,M;const u=s.get(p);if(!u)return null;const d=r*e+e+l.x*r,v=k*(e+l.y)+a,y=!!(o&&((T=u.dependsOn)!=null&&T.includes(o)||(M=(x=s.get(o))==null?void 0:x.dependsOn)!=null&&M.includes(u.key))),g=u.key===o;return n.jsx(W,{task:u,x:d,y:v,dimensions:h,onHover:i,onTaskClick:_,isSelected:g,isVisible:y,taskStyles:w},u.key)})}),G=c.memo(Z),Q=({tasks:r,levels:t,taskSize:s,size:e,gap:l,selectedTask:a,setHoveredTask:h,taskStyles:o})=>{const i=c.useMemo(()=>({radius:s/2,halfRadius:s/4,twoThirdsRadius:s/6*2}),[s]),_=c.useCallback((k,u)=>{h(u?k:null)},[h]),w=c.useCallback(k=>{I(a!==k?k:null)},[a]),p=c.useMemo(()=>Array.from(t.entries()).map(([k,u])=>{const d=u.length*s+(u.length-1)*l.y,v=(e.height-d)/2+i.radius;return n.jsx(G,{level:k,keyList:u,tasks:r,taskSize:s,gap:l,offset:v,dimensions:i,selectedTask:a,onHover:_,onTaskClick:w,taskStyles:o},k)}),[t,r,s,l,e.height,i,a,_,w,o]);return n.jsx("g",{className:b.tasks,children:p})},R=c.memo(Q),z={width:300,height:200},tt={display:"block",boxSizing:"border-box",transition:"width 0.3s ease, height 0.3s ease"},P={CRITICAL:"#ff9147",TASK_BG:"#aaaeff",CHART_BG:"#fff",GRID:"#00000030",TEXT:"#000",SELECTED:"#6868ff",STROKE:"#615f77"},F={BORDER:1,HOVER_BORDER:2,SELECTED_BORDER:3};function et({size:r,taskSize:t,strokeColor:s}){const e=Math.ceil(r.height/t)+1,l=Math.ceil(r.width/t)+1,a=(h,o,i)=>Array.from({length:h},(_,w)=>{const p=w*t;return n.jsx("line",{x1:o?p:0,y1:o?0:p,x2:o?p:i,y2:o?i:p,style:{stroke:s??P.GRID}},w)});return n.jsxs("g",{children:[n.jsx("g",{children:a(e,!1,r.width)}),n.jsx("g",{children:a(l,!0,r.height)})]})}const st=({size:r,pertData:t,selectedTask:s,setHoveredTask:e,hoveredTask:l,styles:{fontSize:a,taskSize:h,gap:o,disableGrid:i,taskBackground:_,selectedBorderColor:w,borderColor:p,criticalColor:k,arrowColor:u,arrowWidth:d,chartBackground:v,textColor:y,fontFamily:g,borderWidth:T,hoverBorderWidth:x,selectedBorderWidth:M,gridColor:E}})=>{const C={"--task-bg":_??P.TASK_BG,"--task-bg-critical":k??P.CRITICAL,"--task-stroke-color":p??P.STROKE,"--task-stroke-width":T??F.BORDER,"--task-stroke-hover-width":x??F.HOVER_BORDER,"--task-selected-stroke-width":M??F.SELECTED_BORDER,"--task-selected-stroke-color":w??P.SELECTED,"--task-text-color":y??P.TEXT,"--task-font-family":g??"inherit"},ot={"--arrow-stroke-color":u??P.STROKE,"--arrow-critical-stroke-color":k??P.CRITICAL,"--arrow-stroke-width":d??2},it={...tt,fontSize:a,backgroundColor:v};return n.jsx("svg",{width:r.width,height:r.height,viewBox:`0 0 ${r.width} ${r.height}`,xmlns:"http://www.w3.org/2000/svg",style:it,dominantBaseline:"central",textAnchor:"middle",children:n.jsxs("g",{className:"content",children:[!i&&n.jsx(et,{size:r,taskSize:h,strokeColor:E}),n.jsx(V,{gap:o,arrows:t.links,taskSize:h,size:r,levels:t.levels,tasks:t.tasks,selectedTask:s,hoveredTask:l,arrowStyles:ot}),n.jsx(R,{gap:o,size:r,taskSize:h,tasks:t.tasks,levels:t.levels,selectedTask:s,setHoveredTask:e,taskStyles:C})]})})};function rt({error:r}){return n.jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",fontSize:"1.5rem",padding:"3rem"},children:r})}const lt=({taskSize:r,gap:t})=>{const{pertData:s}=N();return c.useMemo(()=>{const e=Array.from(s.levels.values());if(!e.length)return{width:0,height:0};const l=Math.max(...e.map(a=>a.length));return{width:(e.length+1)*r+(e.length-1)*t.x,height:(l+1)*r+(l-1)*t.y}},[s.levels,r,t])},j={sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem","2xl":"1.75rem","3xl":"2rem",default:"1rem",min:"0.75rem",max:"2rem"};let S=null;const I=r=>{if(S){if(!r)S.setter(null);else if(S.getTask){const t=S.getTask(r);t&&S.onSelect&&S.onSelect(t),S.setter(r)}}},at=({tasks:r,onSelect:t,styles:s})=>{const{pertData:e,calculatePertResults:l,error:a}=N(),h=c.useRef(),[o,i]=c.useState(null),[_,w]=c.useState(null),p=E=>e.tasks.get(E);S={setter:c.useRef(i).current,getTask:p,onSelect:t},c.useEffect(()=>{const E=JSON.stringify(r);h.current!==E&&(l(r),h.current=E)},[r,l]);const u=c.useCallback(E=>{w(E)},[]),{gap:d,taskSize:v,fontSize:y}=s,g=Math.max(v??100,70),T=c.useMemo(()=>({x:Math.max(g,(d==null?void 0:d.x)??0),y:Math.max(g,(d==null?void 0:d.y)??0)}),[d==null?void 0:d.x,d==null?void 0:d.y,g]),x=lt({taskSize:g,gap:T}),M=c.useMemo(()=>y?typeof y=="number"?`${y}px`:j[y]||y:j.default,[y]);return a?n.jsx(rt,{error:a}):n.jsx(st,{size:a?z:x,pertData:e,selectedTask:o,hoveredTask:_,setHoveredTask:u,styles:{...s,fontSize:M,taskSize:g,gap:T}})},nt=({styles:r,...t})=>n.jsx(Y,{children:n.jsx("div",{style:{width:"fit-content",height:"fit-content",boxSizing:"border-box"},children:n.jsx(at,{...t,styles:r??{}})})});f.Pert=nt,f.PertProvider=U,f.setSelectedTask=I,f.usePert=X,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
11
+ `,[t,s,_]);return n.jsxs("g",{className:`${b.task} ${i?b.selected:""} ${h?b.visible:""} ${r.critical?b.critical:""}`,onMouseEnter:()=>l(r.key,!0),onMouseLeave:()=>l(r.key,!1),onClick:()=>a(r.key),style:o,children:[n.jsx("rect",{x:t-_,y:s-_,rx:"20",ry:"20",width:_*2,height:_*2}),n.jsx("text",{x:t,y:s,children:r.text}),n.jsx(q,{task:r,x:t,y:s,dimensions:e}),n.jsx("path",{d:w,fill:"none"})]})},W=c.memo(J),Z=({level:r,keyList:t,tasks:s,taskSize:e,gap:l,offset:a,dimensions:h,selectedTask:i,onHover:o,onTaskClick:_,taskStyles:w})=>n.jsx("g",{children:t.map((p,u)=>{var T,m,x;const k=s.get(p);if(!k)return null;const d=r*e+e+l.x*r,v=u*(e+l.y)+a,y=!!(i&&((T=k.dependsOn)!=null&&T.includes(i)||(x=(m=s.get(i))==null?void 0:m.dependsOn)!=null&&x.includes(k.key))),g=k.key===i;return n.jsx(W,{task:k,x:d,y:v,dimensions:h,onHover:o,onTaskClick:_,isSelected:g,isVisible:y,taskStyles:w},k.key)})}),Q=c.memo(Z),G=({tasks:r,levels:t,taskSize:s,size:e,gap:l,selectedTask:a,setHoveredTask:h,taskStyles:i})=>{const o=c.useMemo(()=>({radius:s/2,halfRadius:s/4,twoThirdsRadius:s/6*2}),[s]),_=c.useCallback((u,k)=>{h(k?u:null)},[h]),w=c.useCallback(u=>{O(a!==u?u:null)},[a]),p=c.useMemo(()=>Array.from(t.entries()).map(([u,k])=>{const d=k.length*s+(k.length-1)*l.y,v=(e.height-d)/2+o.radius;return n.jsx(Q,{level:u,keyList:k,tasks:r,taskSize:s,gap:l,offset:v,dimensions:o,selectedTask:a,onHover:_,onTaskClick:w,taskStyles:i},u)}),[t,r,s,l,e.height,o,a,_,w,i]);return n.jsx("g",{className:b.tasks,children:p})},z=c.memo(G),R={width:300,height:200},tt={display:"block",boxSizing:"border-box",transition:"width 0.3s ease, height 0.3s ease"},$={CRITICAL:"#ff9147",TASK_BG:"#aaaeff",GRID:"#83838350",TEXT:"#000",SELECTED:"#6868ff",STROKE:"#615f77"},D={BORDER:1,HOVER_BORDER:2,SELECTED_BORDER:3};function et({size:r,taskSize:t,strokeColor:s}){const e=Math.ceil(r.height/t)+1,l=Math.ceil(r.width/t)+1,a=(h,i,o)=>Array.from({length:h},(_,w)=>{const p=w*t;return n.jsx("line",{x1:i?p:0,y1:i?0:p,x2:i?p:o,y2:i?o:p,style:{stroke:s??$.GRID}},w)});return n.jsxs("g",{children:[n.jsx("g",{children:a(e,!1,r.width)}),n.jsx("g",{children:a(l,!0,r.height)})]})}const st=({size:r,pertData:t,selectedTask:s,setHoveredTask:e,hoveredTask:l,styles:{fontSize:a,taskSize:h,gap:i,disableGrid:o,taskBackground:_,selectedBorderColor:w,borderColor:p,criticalColor:u,arrowColor:k,arrowWidth:d,chartBackground:v,textColor:y,fontFamily:g,borderWidth:T,hoverBorderWidth:m,selectedBorderWidth:x,gridColor:E}})=>{const S={"--task-bg":_??$.TASK_BG,"--task-bg-critical":u??$.CRITICAL,"--task-stroke-color":p??$.STROKE,"--task-stroke-width":T??D.BORDER,"--task-stroke-hover-width":m??D.HOVER_BORDER,"--task-selected-stroke-width":x??D.SELECTED_BORDER,"--task-selected-stroke-color":w??$.SELECTED,"--task-text-color":y??$.TEXT,"--task-font-family":g??"inherit"},it={"--arrow-stroke-color":k??$.STROKE,"--arrow-critical-stroke-color":u??$.CRITICAL,"--arrow-stroke-width":d??2},ot={...tt,fontSize:a,backgroundColor:v};return n.jsx("svg",{width:r.width,height:r.height,viewBox:`0 0 ${r.width} ${r.height}`,xmlns:"http://www.w3.org/2000/svg",style:ot,dominantBaseline:"central",textAnchor:"middle",children:n.jsxs("g",{className:"content",children:[!o&&n.jsx(et,{size:r,taskSize:h,strokeColor:E}),n.jsx(V,{gap:i,arrows:t.links,taskSize:h,size:r,levels:t.levels,tasks:t.tasks,selectedTask:s,hoveredTask:l,arrowStyles:it}),n.jsx(z,{gap:i,size:r,taskSize:h,tasks:t.tasks,levels:t.levels,selectedTask:s,setHoveredTask:e,taskStyles:S})]})})};function rt({error:r}){return n.jsx("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",fontSize:"1.5rem",padding:"3rem"},children:r})}const lt=({taskSize:r,gap:t})=>{const{pertData:s}=j();return c.useMemo(()=>{const e=Array.from(s.levels.values());if(!e.length)return{width:0,height:0};const l=Math.max(...e.map(a=>a.length));return{width:(e.length+1)*r+(e.length-1)*t.x,height:(l+1)*r+(l-1)*t.y}},[s.levels,r,t])},I={sm:"0.75rem",md:"1rem",lg:"1.25rem",xl:"1.5rem","2xl":"1.75rem","3xl":"2rem",default:"1rem",min:"0.75rem",max:"2rem"};let F=null;const O=r=>{if(!F)return;const{setter:t,onSelect:s,getTask:e}=F;if(!r){t(null),s==null||s(null);return}const l=(e==null?void 0:e(r))??null;s==null||s(l),t(l?r:null)},at=({tasks:r,onSelect:t,styles:s})=>{const{pertData:e,calculatePertResults:l,error:a}=j(),h=c.useRef(),[i,o]=c.useState(null),[_,w]=c.useState(null),p=E=>e.tasks.get(E);F={setter:c.useRef(o).current,getTask:p,onSelect:t},c.useEffect(()=>{const E=JSON.stringify(r);h.current!==E&&(l(r),O(null),h.current=E)},[r,l]);const k=c.useCallback(E=>{w(E)},[]),{gap:d,taskSize:v,fontSize:y}=s,g=Math.max(v??100,70),T=c.useMemo(()=>({x:Math.max(g,(d==null?void 0:d.x)??0),y:Math.max(g,(d==null?void 0:d.y)??0)}),[d==null?void 0:d.x,d==null?void 0:d.y,g]),m=lt({taskSize:g,gap:T}),x=c.useMemo(()=>y?typeof y=="number"?`${y}px`:I[y]||y:I.default,[y]);return a?n.jsx(rt,{error:a}):n.jsx(st,{size:a?R:m,pertData:e,selectedTask:i,hoveredTask:_,setHoveredTask:k,styles:{...s,fontSize:x,taskSize:g,gap:T}})},nt=({styles:r,...t})=>n.jsx(Y,{children:n.jsx("div",{style:{width:"fit-content",height:"fit-content",boxSizing:"border-box"},children:n.jsx(at,{...t,styles:r??{}})})});f.Pert=nt,f.PertProvider=U,f.setSelectedTask=O,f.usePert=X,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
package/dist/main.css CHANGED
@@ -1 +1 @@
1
- ._arrows_62ntr_1 ._arrow_62ntr_1{fill:transparent;stroke:var(--arrow-stroke-color);stroke-width:var(--arrow-stroke-width);transition:stroke .2s,stroke-width .2s,opacity .2s}._arrows_62ntr_1 ._arrow_62ntr_1._critical_62ntr_8{stroke:var(--arrow-critical-stroke-color)}._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1{opacity:.3}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1{opacity:0}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._visible_62ntr_25,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._visible_62ntr_25{stroke-width:calc(var(--arrow-stroke-width) + 1);opacity:1}._tasks_1slwh_1 ._task_1slwh_1{-webkit-user-select:none;user-select:none;transition:filter .2s,opacity .2s}._tasks_1slwh_1 ._task_1slwh_1 text{fill:var(--task-text-color);font-family:var(--task-font-family)}._tasks_1slwh_1 ._task_1slwh_1 rect{transition:stroke-width .2s;stroke:var(--task-stroke-color);stroke-width:var(--task-stroke-width);fill:var(--task-bg)}._tasks_1slwh_1 ._task_1slwh_1 rect~path{stroke:var(--task-stroke-color)}._tasks_1slwh_1 ._task_1slwh_1._critical_1slwh_22 rect{fill:var(--task-bg-critical)}._tasks_1slwh_1 ._task_1slwh_1:hover{cursor:pointer;filter:brightness(.9)}._tasks_1slwh_1 ._task_1slwh_1:hover rect{stroke-width:var(--task-stroke-hover-width)}._tasks_1slwh_1 ._task_1slwh_1._selected_1slwh_35 rect{stroke:var(--task-selected-stroke-color);stroke-width:var(--task-selected-stroke-width)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44){opacity:.7;filter:brightness(.6)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover{cursor:pointer;filter:brightness(.9);opacity:1}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover rect{stroke:var(--task-stroke-color);stroke-linejoin:bevel}
1
+ ._arrows_62ntr_1 ._arrow_62ntr_1{fill:transparent;stroke:var(--arrow-stroke-color);stroke-width:var(--arrow-stroke-width);transition:stroke .2s,stroke-width .2s,opacity .2s}._arrows_62ntr_1 ._arrow_62ntr_1._critical_62ntr_8{stroke:var(--arrow-critical-stroke-color)}._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1{opacity:.3}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1{opacity:0}._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onSelect_62ntr_17 ._arrow_62ntr_1._visible_62ntr_25,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._hover_62ntr_24,._arrows_62ntr_1._onHover_62ntr_13 ._arrow_62ntr_1._visible_62ntr_25{stroke-width:calc(var(--arrow-stroke-width) + 1);opacity:1}._tasks_1slwh_1 ._task_1slwh_1{-webkit-user-select:none;-moz-user-select:none;user-select:none;transition:filter .2s,opacity .2s}._tasks_1slwh_1 ._task_1slwh_1 text{fill:var(--task-text-color);font-family:var(--task-font-family)}._tasks_1slwh_1 ._task_1slwh_1 rect{transition:stroke-width .2s;stroke:var(--task-stroke-color);stroke-width:var(--task-stroke-width);fill:var(--task-bg)}._tasks_1slwh_1 ._task_1slwh_1 rect~path{stroke:var(--task-stroke-color)}._tasks_1slwh_1 ._task_1slwh_1._critical_1slwh_22 rect{fill:var(--task-bg-critical)}._tasks_1slwh_1 ._task_1slwh_1:hover{cursor:pointer;filter:brightness(.9)}._tasks_1slwh_1 ._task_1slwh_1:hover rect{stroke-width:var(--task-stroke-hover-width)}._tasks_1slwh_1 ._task_1slwh_1._selected_1slwh_35 rect{stroke:var(--task-selected-stroke-color);stroke-width:var(--task-selected-stroke-width)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44){opacity:.7;filter:brightness(.6)}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover{cursor:pointer;filter:brightness(.9);opacity:1}._tasks_1slwh_1:has(._task_1slwh_1._selected_1slwh_35) ._task_1slwh_1:not(._selected_1slwh_35):not(._visible_1slwh_44):hover rect{stroke:var(--task-stroke-color);stroke-linejoin:bevel}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-pert",
3
- "version": "1.0.1",
3
+ "version": "1.0.3",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Interactive PERT chart component for React",
@@ -38,28 +38,49 @@
38
38
  "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
39
39
  "semantic-release": "semantic-release"
40
40
  },
41
- "dependencies": {
42
- "react": "^18.3.1",
43
- "react-dom": "^18.3.1"
41
+ "peerDependencies": {
42
+ "react": "*",
43
+ "react-dom": "*"
44
44
  },
45
45
  "devDependencies": {
46
- "@eslint/js": "^9.11.1",
47
- "@types/node": "^22.7.5",
48
- "@types/react": "^18.3.10",
49
- "@types/react-dom": "^18.3.0",
50
- "@vitejs/plugin-react": "^4.3.2",
51
- "eslint": "^9.11.1",
52
- "eslint-plugin-react-hooks": "^5.1.0-rc.0",
53
- "eslint-plugin-react-refresh": "^0.4.12",
54
- "globals": "^15.9.0",
46
+ "@eslint/js": "^9.19.0",
47
+ "@radix-ui/react-label": "^2.1.2",
48
+ "@radix-ui/react-popover": "^1.1.6",
49
+ "@radix-ui/react-scroll-area": "^1.2.3",
50
+ "@radix-ui/react-select": "^2.1.6",
51
+ "@radix-ui/react-separator": "^1.1.2",
52
+ "@radix-ui/react-slider": "^1.2.3",
53
+ "@radix-ui/react-slot": "^1.1.2",
54
+ "@radix-ui/react-switch": "^1.1.3",
55
+ "@radix-ui/react-tabs": "^1.1.3",
56
+ "@types/node": "^22.13.1",
57
+ "@types/react": "^18.3.18",
58
+ "@types/react-dom": "^18.3.5",
59
+ "@vitejs/plugin-react": "^4.3.4",
60
+ "autoprefixer": "^10.4.20",
61
+ "class-variance-authority": "^0.7.1",
62
+ "clsx": "^2.1.1",
63
+ "eslint": "^9.19.0",
64
+ "eslint-plugin-react-hooks": "^5.1.0",
65
+ "eslint-plugin-react-refresh": "^0.4.18",
66
+ "globals": "^15.14.0",
67
+ "lucide-react": "^0.475.0",
68
+ "postcss": "^8.5.1",
69
+ "react-colorful": "^5.6.1",
55
70
  "rimraf": "^6.0.1",
56
- "semantic-release": "^24.1.2",
57
- "typescript": "^5.5.3",
58
- "typescript-eslint": "^8.7.0",
59
- "vite": "^5.4.8",
60
- "vite-plugin-dts": "^4.2.4",
71
+ "semantic-release": "^24.2.1",
72
+ "tailwind-merge": "^3.0.1",
73
+ "tailwindcss": "3",
74
+ "tailwindcss-animate": "^1.0.7",
75
+ "typescript": "^5.7.3",
76
+ "typescript-eslint": "^8.23.0",
77
+ "vaul": "^1.1.2",
78
+ "vite": "^6.1.0",
79
+ "vite-plugin-dts": "^4.5.0",
61
80
  "vite-plugin-lib-inject-css": "^2.2.1",
62
- "vite-tsconfig-paths": "^5.0.1"
81
+ "vite-tsconfig-paths": "^5.1.4",
82
+ "react": "^18.3.1",
83
+ "react-dom": "^18.3.1"
63
84
  },
64
85
  "keywords": [
65
86
  "react",