@salloomd/teeth-selector 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/teeth-preview.d.ts +1 -1
- package/dist/components/teeth-preview.d.ts.map +1 -1
- package/dist/components/teeth-selector.d.ts +2 -2
- package/dist/components/teeth-selector.d.ts.map +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/lib.d.ts +3 -0
- package/dist/lib.d.ts.map +1 -0
- package/dist/lib.js +391 -0
- package/dist/ui.d.ts +4 -0
- package/dist/ui.d.ts.map +1 -0
- package/dist/ui.js +797 -0
- package/package.json +12 -2
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import type { TeethPreviewProps } from "
|
|
2
|
+
import type { TeethPreviewProps } from "@lib/types";
|
|
3
3
|
declare const TeethPreview: React.ForwardRefExoticComponent<TeethPreviewProps & React.RefAttributes<SVGSVGElement>>;
|
|
4
4
|
export { TeethPreview };
|
|
5
5
|
//# sourceMappingURL=teeth-preview.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teeth-preview.d.ts","sourceRoot":"","sources":["../../src/components/teeth-preview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"teeth-preview.d.ts","sourceRoot":"","sources":["../../src/components/teeth-preview.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAMpD,QAAA,MAAM,YAAY,yFAiHjB,CAAC;AAIF,OAAO,EAAE,YAAY,EAAE,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
|
-
import { type Tooth } from "
|
|
3
|
-
import type { TeethSelectorProps, TeethSelectorState } from "
|
|
2
|
+
import { type Tooth } from "@lib/teeth";
|
|
3
|
+
import type { TeethSelectorProps, TeethSelectorState } from "@lib/types";
|
|
4
4
|
type SelectionAction = {
|
|
5
5
|
type: "toggle-tooth";
|
|
6
6
|
toothId: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teeth-selector.d.ts","sourceRoot":"","sources":["../../src/components/teeth-selector.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,KAAK,EACX,MAAM,
|
|
1
|
+
{"version":3,"file":"teeth-selector.d.ts","sourceRoot":"","sources":["../../src/components/teeth-selector.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAIL,KAAK,KAAK,EACX,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAMzE,KAAK,eAAe,GAChB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACvD;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,GACxB;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACrB;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,kBAAkB,CAAA;CAAE,CAAC;AA2G/C,UAAU,yBAAyB;IACjC,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC1C,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;CAC/D;AAKD,wBAAgB,uBAAuB,8BAQtC;AAMD,UAAU,SAAS;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAYD,QAAA,MAAM,aAAa,2FAwHlB,CAAC;AAQF,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CACZ,KAAK,EAAE;QAAE,KAAK,EAAE,KAAK,CAAC;QAAC,UAAU,EAAE,OAAO,CAAC;QAAC,aAAa,EAAE,OAAO,CAAA;KAAE,EACpE,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAC9B,KAAK,CAAC,SAAS,CAAC;IACrB,YAAY,CAAC,EAAE,CACb,KAAK,EAAE;QACL,MAAM,EAAE,MAAM,CAAC;QACf,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE;YACR,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,EAAE,EAAE,MAAM,CAAC;YACX,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH,EACD,cAAc,EAAE,KAAK,CAAC,GAAG,CAAC,OAAO,KAC9B,KAAK,CAAC,SAAS,CAAC;IACrB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,QAAA,MAAM,UAAU,uFA4Mf,CAAC;AAIF,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,CAAC"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { TeethSelector, TeethChart, useTeethSelectorContext, } from "
|
|
2
|
-
export { TeethPreview } from "
|
|
3
|
-
export { teethData, adjacentTeethPairs, getTeethInRange, parseTeethSelection, formatTeethSelection, sameSide, } from "
|
|
4
|
-
export type { Tooth } from "
|
|
5
|
-
export type { TeethSelectorProps, TeethSelectorState, TeethSelectorRenderProps, TeethChartProps, TeethPreviewProps, ToothRenderProps, BridgeRenderProps, } from "
|
|
1
|
+
export { TeethSelector, TeethChart, useTeethSelectorContext, } from "@components/teeth-selector";
|
|
2
|
+
export { TeethPreview } from "@components/teeth-preview";
|
|
3
|
+
export { teethData, adjacentTeethPairs, getTeethInRange, parseTeethSelection, formatTeethSelection, sameSide, } from "@lib/teeth";
|
|
4
|
+
export type { Tooth } from "@lib/teeth";
|
|
5
|
+
export type { TeethSelectorProps, TeethSelectorState, TeethSelectorRenderProps, TeethChartProps, TeethPreviewProps, ToothRenderProps, BridgeRenderProps, } from "@lib/types";
|
|
6
6
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,uBAAuB,GACxB,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,QAAQ,GACT,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/lib.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AACA,OAAO,EACL,SAAS,EACT,kBAAkB,EAClB,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,QAAQ,GACT,MAAM,YAAY,CAAC;AAGpB,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/lib.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
// src/lib/teeth.ts
|
|
2
|
+
var teethData = [
|
|
3
|
+
{
|
|
4
|
+
order: 0,
|
|
5
|
+
id: 18,
|
|
6
|
+
name: "Upper Right Third Molar",
|
|
7
|
+
position: "upper",
|
|
8
|
+
side: "right",
|
|
9
|
+
d: "m30 344c-1.8-0.6-3.4-1.6-4.7-3-1.5-1.6-2.7-3.7-3.6-6.5-0.63-2.1-0.94-4.2-0.94-6.1a16 16 0 0 1 0.73-4.7c0.87-2.8 2.3-4.7 3.4-6.2 0.78-1 1.3-1.8 1.4-2.4 0.026-1.2-0.17-2.8-0.37-4.5-0.4-3.4-0.86-7.3-0.044-9.8l5e-3 -0.015 3e-3 -0.015c0.51-2.5 2.5-4.7 6-6.4 2.8-1.4 5.8-2.1 7.1-2.4 0.21-0.049 0.37-0.088 0.48-0.12 4.7-1.1 10-0.73 14-0.23 4.9 0.62 9.3 1.7 12 2.4l0.1 0.034c7.1 2.3 14 7.5 18 14 4.3 7.1 5.5 15 3.3 23-1.1 3.7-2.7 7-4.8 9.8s-4.7 5-7.6 6.6c-5.6 3-12 3.3-19 1-2.4-0.76-4.8-1.8-7.2-3.2l-0.021-0.012-0.023-7e-3c-2.5-0.82-5.4-0.73-8.4-0.63-3.1 0.1-6.3 0.21-9.1-0.72z"
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
order: 1,
|
|
13
|
+
id: 17,
|
|
14
|
+
name: "Upper Right Second Molar",
|
|
15
|
+
position: "upper",
|
|
16
|
+
side: "right",
|
|
17
|
+
d: "m39 279c-3-0.96-6.3-2.5-8.5-6.2-1.5-2.9-2.2-10-1.8-21l6e-3 -0.19c0.026-1.2-0.17-2.8-0.37-4.5-0.4-3.4-0.86-7.3-0.045-9.8 0.4-1.1 1.9-2.4 4.2-3.7 1.8-1 3.9-1.9 4.6-2.1l6e-3 -1e-3 6e-3 -2e-3c6.5-2.1 24 2.2 29 4l0.13 0.043c3.6 1.2 6.7 2.7 9.3 4.7s4.7 4.3 6.2 6.9c1.5 2.7 2.4 5.8 2.6 9.1 0.22 3.4-0.26 7.2-1.4 11-1.9 6.6-5.5 11-11 14-3 1.6-6.6 2.4-11 2.5-3.7 0.027-7.8-0.66-12-2l-0.24-0.078c-2-0.63-3.9-1.1-5.7-1.6-1.7-0.43-3.4-0.83-4.9-1.3z"
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
order: 2,
|
|
21
|
+
id: 16,
|
|
22
|
+
name: "Upper Right First Molar",
|
|
23
|
+
position: "upper",
|
|
24
|
+
side: "right",
|
|
25
|
+
d: "m72 229c-0.72 0-1.5-0.018-2.2-0.053-8.3-0.39-16-2.8-21-6.7-3-2.1-5.3-4.7-6.9-7.5-1.7-3.1-2.6-6.6-2.6-10 0-2.7 0.77-5.6 2-7.3 0.41-0.58 1-1.2 1.7-1.9 1.2-1.2 2.6-2.7 3.4-4.4 0.41-0.98 0.45-2.4 0.5-4 0.072-2.5 0.16-5.6 1.8-8.1l4e-3 -7e-3 4e-3 -6e-3c1.4-2.4 3.6-4.1 6.6-5.1 2.4-0.79 5.4-1.1 9.5-1.1 4.7 0.79 9 2.2 13 4.3 3.9 2 7.3 4.6 10 7.5 2.8 3 4.9 6.4 6.3 10a27 27 0 0 1 1.6 12c-1.3 16-8.7 23-23 23z"
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
order: 3,
|
|
29
|
+
id: 15,
|
|
30
|
+
name: "Upper Right Second Premolar",
|
|
31
|
+
position: "upper",
|
|
32
|
+
side: "right",
|
|
33
|
+
d: "m73 168a39 39 0 0 1-0.2-0.1c-3.9-1.9-7.1-4.1-9.5-6.5-2.3-2.3-3.8-4.7-4.6-7.2a13 13 0 0 1-0.52-5.8c0.24-1.9 0.89-3.8 1.9-5.7 2.2-4.1 6.2-6.9 11-8 2.6-0.56 5.3-0.64 8.1-0.23 3 0.42 6 1.4 9 2.8 0.71 0.34 1.4 0.72 2.1 1.1 3.2 1.8 6.1 3.9 8.5 6.2 2.4 2.2 4.3 4.5 5.7 6.8s2.2 4.6 2.5 6.8c0.29 2.2-0.014 4.3-0.9 6.2-0.62 1.3-1.6 2.5-2.9 3.6-1.3 1-2.9 1.9-4.8 2.5-3.5 1.2-7.6 1.7-12 1.3-4.7-0.38-9.4-1.7-14-3.8z"
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
order: 4,
|
|
37
|
+
id: 14,
|
|
38
|
+
name: "Upper Right First Premolar",
|
|
39
|
+
position: "upper",
|
|
40
|
+
side: "right",
|
|
41
|
+
d: "m118 135a6.3 6.3 0 0 1-0.3 0.28c-2.4 2.1-6.6 2.8-12 2-5.4-0.85-11-3.3-16-6.8-5.7-4.1-9.3-9.3-9.7-14-0.28-3.4 0.92-6.6 3.5-9.2a16 16 0 0 1 1.6-1.4c8.7-6.6 22-4.9 29 3.7a26 26 0 0 1 4.2 7 27 27 0 0 1 1.8 7.4c0.47 4.9-0.57 9.1-2.8 11z"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
order: 5,
|
|
45
|
+
id: 13,
|
|
46
|
+
name: "Upper Right Canine",
|
|
47
|
+
position: "upper",
|
|
48
|
+
side: "right",
|
|
49
|
+
d: "m144 104c-0.09 0.084-0.19 0.17-0.29 0.24-1.2 0.9-2.9 1.5-5.1 1.8-2.2 0.33-4.9 0.3-7.7-0.086-6.4-0.88-13-3.5-19-7.5-2.2-1.6-4-3.4-5.2-5.4a13 13 0 0 1-1.8-5.8c-0.18-2.6 0.36-5.4 1.6-8 1.1-2.3 2.6-4.5 4.3-6.1 0.36-0.34 0.73-0.65 1.1-0.92 1.4-1.1 4.4-2.7 7.8-4 2.8-1.1 6.8-2.2 10-1.8h8e-3c2.5 0.26 4.4 1.4 5.8 3.6 1.3 2 2.1 4.4 2.9 6.8 0.19 0.58 0.36 1.1 0.55 1.7 0.52 1.5 1.1 3.1 1.7 4.7 1.6 4.3 3.2 8.8 3.9 12 0.83 4.1 0.48 6.9-1.1 8.3z"
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
order: 6,
|
|
53
|
+
id: 12,
|
|
54
|
+
name: "Upper Right Lateral Incisor",
|
|
55
|
+
position: "upper",
|
|
56
|
+
side: "right",
|
|
57
|
+
d: "m168 82c-2.9 1.2-6.4 0.91-11-1-3.7-1.7-7.9-4.5-13-8.8-0.54-0.44-1.1-0.86-1.6-1.3-2-1.6-3.8-3-5-4.4-1.3-1.5-1.9-2.7-1.7-4 0.17-1.6 1.4-3.3 3.9-5.3 2.6-2.1 6.8-4.5 13-7.4a105 105 0 0 1 5.9-2.8c6.4-2.7 10-3.3 13-2 2.5 1.6 2.7 5.7 3 11 0.073 1.5 0.15 3 0.28 4.6 0.61 7.4 0.52 12-0.3 15-0.86 3.2-2.6 5.2-5.8 6.6l-0.04 0.017z"
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
order: 7,
|
|
61
|
+
id: 11,
|
|
62
|
+
name: "Upper Right Central Incisor",
|
|
63
|
+
position: "upper",
|
|
64
|
+
side: "right",
|
|
65
|
+
d: "m205 74c-10 1.1-18-9.3-23-18l-0.3-0.5c-1.4-2.4-2.7-4.6-3.5-6.7-0.85-2.3-0.88-4.2-0.11-5.9 0.9-2 2.9-3.6 6.2-5.1 3.7-1.6 8.9-3 16-4.2a82 82 0 0 1 5-0.69c4.3-0.46 7.9-0.39 11 0.2 2.4 0.52 4.2 1.5 5.4 2.8 1.3 1.5 1.9 3.6 1.7 6.3-0.14 2.4-0.79 5-1.4 7.4-0.23 0.89-0.45 1.7-0.63 2.5l-0.29 1.3c-0.98 4.3-2.1 9.3-4.2 13-2.4 4.5-5.8 6.9-10 7.6-0.21 0.03-0.42 0.057-0.62 0.079z"
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
order: 8,
|
|
69
|
+
id: 21,
|
|
70
|
+
name: "Upper Left Central Incisor",
|
|
71
|
+
position: "upper",
|
|
72
|
+
side: "left",
|
|
73
|
+
d: "m246 32h1e-3c1.5 0.16 3.2 0.4 5 0.69 7 1.2 12 2.5 16 4.2 3.3 1.5 5.3 3.1 6.2 5.1 0.77 1.7 0.73 3.5-0.12 5.9-0.77 2.1-2.1 4.4-3.5 6.7l-0.3 0.5c-5.4 9.2-13 20-23 18a15 15 0 0 1-0.62-0.079c-4.5-0.66-7.9-3.2-10-7.6-2.1-3.9-3.2-8.9-4.2-13l-0.29-1.3c-0.18-0.81-0.4-1.7-0.63-2.5-0.63-2.5-1.3-5-1.4-7.4-0.15-2.7 0.41-4.8 1.7-6.3 1.2-1.3 3-2.3 5.4-2.8 2.7-0.58 6.3-0.65 11-0.19z"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
order: 9,
|
|
77
|
+
id: 22,
|
|
78
|
+
name: "Upper Left Lateral Incisor",
|
|
79
|
+
position: "upper",
|
|
80
|
+
side: "left",
|
|
81
|
+
d: "m292 47h1e-3c1.8 0.75 3.8 1.7 5.9 2.8 5.8 2.9 9.9 5.4 13 7.4 2.5 1.9 3.7 3.7 3.9 5.3 0.14 1.3-0.41 2.5-1.7 4-1.2 1.4-3 2.8-5 4.4-0.51 0.41-1 0.83-1.6 1.3-5.3 4.3-9.5 7.1-13 8.8-4.3 1.9-7.8 2.3-11 1l-0.04-0.018c-3.2-1.4-4.9-3.3-5.8-6.6-0.82-3.1-0.91-7.3-0.3-15 0.13-1.6 0.21-3.1 0.28-4.6 0.26-5.3 0.47-9.4 3-11 2.2-1.4 6.2-0.77 13 2z"
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
order: 10,
|
|
85
|
+
id: 23,
|
|
86
|
+
name: "Upper Left Canine",
|
|
87
|
+
position: "upper",
|
|
88
|
+
side: "left",
|
|
89
|
+
d: "m339 73c1.7 1.6 3.2 3.7 4.3 6.1 1.2 2.7 1.8 5.5 1.6 8a13 13 0 0 1-1.8 5.8c-1.2 2-2.9 3.8-5.2 5.4-5.6 3.9-12 6.6-19 7.5-2.8 0.38-5.4 0.41-7.7 0.086-2.2-0.32-3.9-0.96-5.1-1.8a4 4 0 0 1-0.29-0.24c-1.6-1.4-1.9-4.2-1.1-8.3 0.75-3.7 2.4-8.2 3.9-12a301 301 0 0 0 1.7-4.7c0.18-0.54 0.36-1.1 0.55-1.7 0.77-2.4 1.6-4.8 2.9-6.8 1.5-2.2 3.4-3.4 5.8-3.6h5e-3l4e-3 -1e-3c3.3-0.45 7.3 0.71 10 1.8 3.4 1.3 6.4 3 7.8 4 0.36 0.27 0.73 0.58 1.1 0.92z"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
order: 11,
|
|
93
|
+
id: 24,
|
|
94
|
+
name: "Upper Left First Premolar",
|
|
95
|
+
position: "upper",
|
|
96
|
+
side: "left",
|
|
97
|
+
d: "m367 107h1e-3c2.6 2.6 3.8 5.7 3.5 9.2-0.42 5-3.9 10-9.7 14-5 3.6-11 6-16 6.8-5.1 0.81-9.4 0.076-12-2a6.3 6.3 0 0 1-0.3-0.28c-2.2-2.2-3.3-6.5-2.8-11a27 27 0 0 1 1.8-7.4 26 26 0 0 1 4.2-7c7.4-8.7 21-10 29-3.7a16 16 0 0 1 1.6 1.4z"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
order: 12,
|
|
101
|
+
id: 25,
|
|
102
|
+
name: "Upper Left Second Premolar",
|
|
103
|
+
position: "upper",
|
|
104
|
+
side: "left",
|
|
105
|
+
d: "m362 137 2e-3 -1e-3c3-1.5 6-2.4 9-2.8 2.8-0.4 5.6-0.32 8.1 0.24 5 1.1 9 3.9 11 8 1 1.9 1.7 3.8 1.9 5.7a13 13 0 0 1-0.52 5.8c-0.8 2.5-2.4 5-4.6 7.2-2.4 2.4-5.6 4.6-9.5 6.5l-0.2 0.1c-4.3 2.1-9.1 3.4-14 3.8-4.3 0.35-8.5-0.11-12-1.3-1.9-0.65-3.5-1.5-4.8-2.5s-2.3-2.2-2.9-3.6c-0.89-1.9-1.2-4-0.9-6.2 0.28-2.2 1.1-4.5 2.5-6.8s3.3-4.6 5.7-6.8 5.3-4.3 8.5-6.2a37 37 0 0 1 2.1-1.1z"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
order: 13,
|
|
109
|
+
id: 26,
|
|
110
|
+
name: "Upper Left First Molar",
|
|
111
|
+
position: "upper",
|
|
112
|
+
side: "left",
|
|
113
|
+
d: "m378 229c-15 0-22-7.3-23-23-0.33-4.1 0.2-8 1.6-12 1.3-3.7 3.4-7 6.3-10 2.8-3 6.2-5.5 10-7.5 4-2.1 8.4-3.5 13-4.3 4.1 1e-3 7.1 0.36 9.5 1.1 3 0.98 5.2 2.6 6.6 5.1l4e-3 6e-3 4e-3 7e-3c1.6 2.4 1.7 5.5 1.8 8.1 0.046 1.6 0.087 3 0.5 4 0.76 1.8 2.1 3.2 3.4 4.4 0.65 0.66 1.3 1.3 1.7 1.9 1.2 1.7 2 4.5 2 7.3 0 3.8-0.87 7.2-2.6 10-1.6 2.9-3.9 5.4-6.9 7.5-5.5 3.9-13 6.3-21 6.7-0.76 0.035-1.5 0.053-2.2 0.053z"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
order: 14,
|
|
117
|
+
id: 27,
|
|
118
|
+
name: "Upper Left Second Molar",
|
|
119
|
+
position: "upper",
|
|
120
|
+
side: "left",
|
|
121
|
+
d: "m386 236c5.5-1.8 23-6.1 29-4l6e-3 2e-3 6e-3 1e-3c0.74 0.2 2.7 1 4.6 2.1 2.4 1.3 3.8 2.6 4.2 3.7 0.81 2.4 0.36 6.3-0.045 9.8-0.2 1.7-0.4 3.4-0.37 4.5l7e-3 0.2c0.36 11-0.3 18-1.8 21-2.2 3.8-5.6 5.3-8.5 6.2-1.5 0.5-3.2 0.9-4.9 1.3-1.9 0.48-3.9 0.97-6 1.6-4.2 1.4-8.3 2.1-12 2-4-0.028-7.5-0.86-11-2.5-5-2.7-8.6-7.4-11-14-1.2-4-1.7-7.8-1.4-11 0.22-3.3 1.1-6.4 2.6-9.1 1.5-2.6 3.5-5 6.2-6.9 2.6-1.9 5.7-3.5 9.3-4.7l0.13-0.043z"
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
order: 15,
|
|
125
|
+
id: 28,
|
|
126
|
+
name: "Upper Left Third Molar",
|
|
127
|
+
position: "upper",
|
|
128
|
+
side: "left",
|
|
129
|
+
d: "m384 294c2.3-0.74 6.7-1.8 12-2.4 4-0.5 9.7-0.87 14 0.23 0.11 0.03 0.28 0.068 0.48 0.12 1.3 0.3 4.3 1 7.1 2.4 3.5 1.7 5.5 3.9 6 6.4l3e-3 0.015 5e-3 0.015c0.82 2.4 0.36 6.3-0.044 9.8-0.2 1.7-0.4 3.4-0.37 4.5 0.021 0.63 0.58 1.4 1.4 2.4 1.1 1.4 2.6 3.4 3.4 6.2 0.48 1.5 0.72 3.1 0.73 4.7 8e-3 1.9-0.31 4-0.94 6.1-0.91 2.8-2.1 4.9-3.6 6.5-1.3 1.4-2.8 2.4-4.7 3-2.8 0.93-6 0.82-9.1 0.72-3-0.1-5.9-0.2-8.4 0.63l-0.023 7e-3 -0.021 0.011c-2.4 1.3-4.8 2.4-7.2 3.2-7 2.3-14 1.9-19-1-2.9-1.5-5.5-3.8-7.6-6.6s-3.8-6.1-4.8-9.8c-2.2-7.6-1.1-16 3.3-23 4-6.7 10-12 18-14l0.1-0.034z"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
order: 16,
|
|
133
|
+
id: 38,
|
|
134
|
+
name: "Lower Left Third Molar",
|
|
135
|
+
position: "lower",
|
|
136
|
+
side: "left",
|
|
137
|
+
d: "m420 406c1.8 0.6 3.4 1.6 4.7 3 1.5 1.6 2.7 3.7 3.6 6.5 0.63 2.1 0.94 4.2 0.94 6.1a16 16 0 0 1-0.73 4.7c-0.87 2.8-2.3 4.7-3.4 6.2-0.78 1-1.3 1.8-1.4 2.4-0.026 1.2 0.17 2.8 0.37 4.5 0.4 3.4 0.86 7.3 0.044 9.8l-5e-3 0.015-3e-3 0.015c-0.51 2.5-2.5 4.7-6 6.4-2.8 1.4-5.8 2.1-7.1 2.4-0.21 0.049-0.37 0.088-0.48 0.12-4.7 1.1-10 0.73-14 0.23-4.9-0.62-9.3-1.7-12-2.4l-0.1-0.034c-7.1-2.3-14-7.5-18-14-4.3-7.1-5.5-15-3.3-23 1.1-3.7 2.7-7 4.8-9.8s4.7-5 7.6-6.6c5.6-3 12-3.3 19-1 2.4 0.76 4.8 1.8 7.2 3.2l0.021 0.012 0.023 7e-3c2.5 0.82 5.4 0.73 8.4 0.63 3.1-0.1 6.3-0.21 9.1 0.72z"
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
order: 17,
|
|
141
|
+
id: 37,
|
|
142
|
+
name: "Lower Left Second Molar",
|
|
143
|
+
position: "lower",
|
|
144
|
+
side: "left",
|
|
145
|
+
d: "m411 471c3 0.96 6.3 2.5 8.5 6.2 1.5 2.9 2.2 10 1.8 21l-6e-3 0.19c-0.026 1.2 0.17 2.8 0.37 4.5 0.4 3.4 0.86 7.3 0.045 9.8-0.4 1.1-1.9 2.4-4.2 3.7-1.8 1-3.9 1.9-4.6 2.1l-6e-3 1e-3 -6e-3 2e-3c-6.5 2.1-24-2.2-29-4a32 32 0 0 1-0.13-0.043c-3.6-1.2-6.7-2.7-9.3-4.7s-4.7-4.3-6.2-6.9c-1.5-2.7-2.4-5.8-2.6-9.1-0.22-3.4 0.26-7.2 1.4-11 1.9-6.6 5.5-11 11-14 3-1.6 6.6-2.4 11-2.5 3.7-0.027 7.8 0.66 12 2l0.24 0.078c2 0.63 3.9 1.1 5.7 1.6 1.7 0.43 3.4 0.83 4.9 1.3z"
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
order: 18,
|
|
149
|
+
id: 36,
|
|
150
|
+
name: "Lower Left First Molar",
|
|
151
|
+
position: "lower",
|
|
152
|
+
side: "left",
|
|
153
|
+
d: "m386 578c-4.7-0.79-9-2.2-13-4.3-3.9-2-7.3-4.6-10-7.5-2.8-3-4.9-6.4-6.3-10a27 27 0 0 1-1.6-12c1.3-16 8.7-23 23-23 0.72 0 1.5 0.018 2.2 0.053 8.3 0.39 16 2.8 21 6.7 3 2.1 5.3 4.7 6.9 7.5 1.7 3.1 2.6 6.6 2.6 10 0 2.7-0.77 5.6-2 7.3-0.41 0.58-1 1.2-1.7 1.9-1.2 1.2-2.6 2.7-3.4 4.4-0.41 0.98-0.45 2.4-0.5 4-0.072 2.5-0.16 5.6-1.8 8.1l-8e-3 0.012c-1.4 2.4-3.6 4.1-6.6 5.1-2.4 0.79-5.4 1.1-9.5 1.1z"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
order: 19,
|
|
157
|
+
id: 35,
|
|
158
|
+
name: "Lower Left Second Premolar",
|
|
159
|
+
position: "lower",
|
|
160
|
+
side: "left",
|
|
161
|
+
d: "m377 582 0.2 0.1c3.9 1.9 7.1 4.1 9.5 6.5 2.3 2.3 3.8 4.7 4.6 7.2 0.59 1.9 0.77 3.8 0.52 5.8-0.24 1.9-0.89 3.8-1.9 5.7-2.2 4.1-6.2 6.9-11 8-2.6 0.56-5.3 0.64-8.1 0.23-3-0.42-6-1.4-9-2.8a37 37 0 0 1-2.1-1.1c-3.2-1.8-6.1-3.9-8.5-6.2-2.4-2.2-4.3-4.5-5.7-6.8s-2.2-4.6-2.5-6.8c-0.29-2.2 0.014-4.3 0.9-6.2 0.62-1.3 1.6-2.5 2.9-3.6 1.3-1 2.9-1.9 4.8-2.5 3.5-1.2 7.6-1.7 12-1.3 4.7 0.38 9.4 1.7 14 3.8z"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
order: 20,
|
|
165
|
+
id: 34,
|
|
166
|
+
name: "Lower Left First Premolar",
|
|
167
|
+
position: "lower",
|
|
168
|
+
side: "left",
|
|
169
|
+
d: "m332 615a6.3 6.3 0 0 1 0.3-0.28c2.4-2.1 6.6-2.8 12-2 5.4 0.85 11 3.3 16 6.8 5.7 4.1 9.3 9.3 9.7 14 0.28 3.4-0.92 6.6-3.5 9.2-0.49 0.49-1 0.96-1.6 1.4-8.7 6.6-22 4.9-29-3.7a26 26 0 0 1-4.2-7 27 27 0 0 1-1.8-7.4c-0.47-4.9 0.57-9.1 2.8-11z"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
order: 21,
|
|
173
|
+
id: 33,
|
|
174
|
+
name: "Lower Left Canine",
|
|
175
|
+
position: "lower",
|
|
176
|
+
side: "left",
|
|
177
|
+
d: "m307 647c0.09-0.084 0.19-0.17 0.29-0.24 1.2-0.9 2.9-1.5 5.1-1.8 2.2-0.33 4.9-0.3 7.7 0.086 6.4 0.88 13 3.5 19 7.5 2.2 1.6 4 3.4 5.2 5.4a13 13 0 0 1 1.8 5.8c0.18 2.6-0.36 5.4-1.6 8-1.1 2.3-2.6 4.5-4.3 6.1-0.36 0.34-0.73 0.65-1.1 0.92-1.4 1.1-4.4 2.7-7.8 4-2.8 1.1-6.8 2.2-10 1.8h-8e-3c-2.5-0.26-4.4-1.4-5.8-3.6-1.3-2-2.1-4.4-2.9-6.8-0.19-0.58-0.36-1.1-0.55-1.7a301 301 0 0 0-1.7-4.7c-1.6-4.3-3.2-8.8-3.9-12-0.83-4.1-0.48-6.9 1.1-8.3z"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
order: 22,
|
|
181
|
+
id: 32,
|
|
182
|
+
name: "Lower Left Lateral Incisor",
|
|
183
|
+
position: "lower",
|
|
184
|
+
side: "left",
|
|
185
|
+
d: "m283 669c2.9-1.2 6.4-0.91 11 1 3.7 1.7 7.9 4.5 13 8.8 0.54 0.44 1.1 0.86 1.6 1.3 2 1.6 3.8 3 5 4.4 1.3 1.5 1.9 2.7 1.7 4-0.17 1.6-1.4 3.3-3.9 5.3-2.6 2.1-6.8 4.5-13 7.4a105 105 0 0 1-5.9 2.8c-6.4 2.7-10 3.3-13 2-2.5-1.6-2.7-5.7-3-11-0.073-1.5-0.15-3-0.28-4.6-0.61-7.4-0.52-12 0.3-15 0.86-3.2 2.6-5.2 5.8-6.6l0.04-0.017z"
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
order: 23,
|
|
189
|
+
id: 31,
|
|
190
|
+
name: "Lower Left Central Incisor",
|
|
191
|
+
position: "lower",
|
|
192
|
+
side: "left",
|
|
193
|
+
d: "m245 677c10-1.1 18 9.3 23 18l0.3 0.5c1.4 2.4 2.7 4.6 3.5 6.7 0.85 2.3 0.88 4.2 0.11 5.9-0.9 2-2.9 3.6-6.2 5.1-3.7 1.6-8.9 3-16 4.2a82 82 0 0 1-5 0.69c-4.3 0.46-7.9 0.39-11-0.2-2.4-0.52-4.2-1.5-5.4-2.8-1.3-1.5-1.9-3.6-1.7-6.3 0.14-2.4 0.79-5 1.4-7.4a96 96 0 0 0 0.92-3.8c0.98-4.3 2.1-9.3 4.2-13 2.4-4.5 5.8-6.9 10-7.6 0.21-0.03 0.42-0.057 0.62-0.079z"
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
order: 24,
|
|
197
|
+
id: 41,
|
|
198
|
+
name: "Lower Right Central Incisor",
|
|
199
|
+
position: "lower",
|
|
200
|
+
side: "right",
|
|
201
|
+
d: "m205 718h-1e-3a82 82 0 0 1-5-0.69c-7-1.2-12-2.5-16-4.2-3.3-1.5-5.3-3.1-6.2-5.1-0.77-1.7-0.73-3.5 0.12-5.9 0.77-2.1 2.1-4.4 3.5-6.7l0.3-0.5c5.4-9.2 13-20 23-18 0.21 0.022 0.42 0.048 0.62 0.079 4.5 0.66 7.9 3.2 10 7.6 2.1 3.9 3.2 8.9 4.2 13l0.29 1.3c0.18 0.81 0.4 1.7 0.63 2.5 0.63 2.5 1.3 5 1.4 7.4 0.15 2.7-0.41 4.8-1.7 6.3-1.2 1.3-3 2.3-5.4 2.8-2.7 0.58-6.3 0.65-11 0.19z"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
order: 25,
|
|
205
|
+
id: 42,
|
|
206
|
+
name: "Lower Right Lateral Incisor",
|
|
207
|
+
position: "lower",
|
|
208
|
+
side: "right",
|
|
209
|
+
d: "m158 704h-1e-3a105 105 0 0 1-5.9-2.8c-5.8-2.9-9.9-5.4-13-7.4-2.5-1.9-3.7-3.7-3.9-5.3-0.14-1.3 0.41-2.5 1.7-4 1.2-1.4 3-2.8 5-4.4 0.51-0.41 1-0.83 1.6-1.3 5.3-4.3 9.5-7.1 13-8.8 4.3-1.9 7.8-2.3 11-1l0.04 0.018c3.2 1.4 4.9 3.3 5.8 6.6 0.82 3.1 0.91 7.3 0.3 15-0.13 1.6-0.21 3.1-0.28 4.6-0.26 5.3-0.47 9.4-3 11-2.2 1.4-6.2 0.77-13-2z"
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
order: 26,
|
|
213
|
+
id: 43,
|
|
214
|
+
name: "Lower Right Canine",
|
|
215
|
+
position: "lower",
|
|
216
|
+
side: "right",
|
|
217
|
+
d: "m111 677c-1.7-1.6-3.2-3.7-4.3-6.1-1.2-2.7-1.8-5.5-1.6-8a13 13 0 0 1 1.8-5.8c1.2-2 2.9-3.8 5.2-5.4 5.6-3.9 12-6.6 19-7.5 2.8-0.38 5.4-0.41 7.7-0.086 2.2 0.32 3.9 0.96 5.1 1.8 0.1 0.076 0.2 0.16 0.29 0.24 1.6 1.4 1.9 4.2 1.1 8.3-0.75 3.7-2.4 8.2-3.9 12a300 300 0 0 0-1.7 4.7c-0.18 0.54-0.36 1.1-0.55 1.7-0.77 2.4-1.6 4.8-2.9 6.8-1.5 2.2-3.4 3.4-5.8 3.6h-5e-3l-4e-3 1e-3c-3.3 0.45-7.3-0.71-10-1.8-3.4-1.3-6.4-3-7.8-4a13 13 0 0 1-1.1-0.92z"
|
|
218
|
+
},
|
|
219
|
+
{
|
|
220
|
+
order: 27,
|
|
221
|
+
id: 44,
|
|
222
|
+
name: "Lower Right First Premolar",
|
|
223
|
+
position: "lower",
|
|
224
|
+
side: "right",
|
|
225
|
+
d: "m83 643h-1e-3c-2.6-2.6-3.8-5.7-3.5-9.2 0.42-5 3.9-10 9.7-14 5-3.6 11-6 16-6.8 5.1-0.81 9.4-0.076 12 2 0.1 0.089 0.2 0.18 0.3 0.28 2.2 2.2 3.3 6.5 2.8 11a27 27 0 0 1-1.8 7.4 26 26 0 0 1-4.2 7c-7.4 8.7-21 10-29 3.7a16 16 0 0 1-1.6-1.4z"
|
|
226
|
+
},
|
|
227
|
+
{
|
|
228
|
+
order: 28,
|
|
229
|
+
id: 45,
|
|
230
|
+
name: "Lower Right Second Premolar",
|
|
231
|
+
position: "lower",
|
|
232
|
+
side: "right",
|
|
233
|
+
d: "m88 613-2e-3 1e-3c-3 1.5-6 2.4-9 2.8-2.8 0.4-5.6 0.32-8.1-0.24-5-1.1-9-3.9-11-8-1-1.9-1.7-3.8-1.9-5.7a13 13 0 0 1 0.52-5.8c0.8-2.5 2.4-5 4.6-7.2 2.4-2.4 5.6-4.6 9.5-6.5l0.2-0.1c4.3-2.1 9.1-3.4 14-3.8 4.3-0.35 8.5 0.11 12 1.3 1.9 0.65 3.5 1.5 4.8 2.5s2.3 2.2 2.9 3.6c0.89 1.9 1.2 4 0.9 6.2-0.28 2.2-1.1 4.5-2.5 6.8s-3.3 4.6-5.7 6.8-5.3 4.3-8.5 6.2c-0.7 0.4-1.4 0.78-2.1 1.1z"
|
|
234
|
+
},
|
|
235
|
+
{
|
|
236
|
+
order: 29,
|
|
237
|
+
id: 46,
|
|
238
|
+
name: "Lower Right First Molar",
|
|
239
|
+
position: "lower",
|
|
240
|
+
side: "right",
|
|
241
|
+
d: "m65 578c-4.1-1e-3 -7.1-0.36-9.5-1.1-3-0.98-5.2-2.6-6.6-5.1l-4e-3 -7e-3 -4e-3 -6e-3c-1.6-2.4-1.7-5.5-1.8-8.1-0.047-1.6-0.087-3-0.5-4-0.76-1.8-2.1-3.2-3.4-4.4-0.65-0.66-1.3-1.3-1.7-1.9-1.2-1.7-2-4.5-2-7.3 0-3.8 0.87-7.2 2.6-10 1.6-2.9 3.9-5.4 6.9-7.5 5.5-3.9 13-6.3 21-6.7 0.76-0.035 1.5-0.053 2.2-0.053 15 0 22 7.3 23 23 0.34 4.1-0.2 8-1.6 12-1.3 3.7-3.5 7-6.3 10s-6.2 5.5-10 7.5c-4 2.1-8.4 3.5-13 4.3z"
|
|
242
|
+
},
|
|
243
|
+
{
|
|
244
|
+
order: 30,
|
|
245
|
+
id: 47,
|
|
246
|
+
name: "Lower Right Second Molar",
|
|
247
|
+
position: "lower",
|
|
248
|
+
side: "right",
|
|
249
|
+
d: "m66 515c-5.5 1.8-23 6.1-29 4l-7e-3 -2e-3 -6e-3 -1e-3c-0.74-0.2-2.7-1-4.6-2.1-2.4-1.3-3.8-2.6-4.2-3.7-0.81-2.4-0.36-6.3 0.045-9.8 0.2-1.7 0.4-3.4 0.37-4.5l-7e-3 -0.2c-0.36-11 0.3-18 1.8-21 2.2-3.8 5.6-5.3 8.5-6.2 1.5-0.5 3.2-0.9 4.9-1.3 1.9-0.48 3.9-0.97 6-1.6 4.2-1.4 8.3-2.1 12-2 4 0.028 7.5 0.86 11 2.5 5 2.7 8.6 7.4 11 14 1.2 4 1.7 7.8 1.4 11-0.22 3.3-1.1 6.4-2.6 9.1-1.5 2.6-3.5 5-6.2 6.9-2.6 1.9-5.7 3.5-9.3 4.7l-0.13 0.043z"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
order: 31,
|
|
253
|
+
id: 48,
|
|
254
|
+
name: "Lower Right Third Molar",
|
|
255
|
+
position: "lower",
|
|
256
|
+
side: "right",
|
|
257
|
+
d: "m66 456c-2.3 0.74-6.7 1.8-12 2.4-4 0.5-9.7 0.87-14-0.23a21 21 0 0 0-0.48-0.12c-1.3-0.3-4.3-1-7.1-2.4-3.5-1.7-5.5-3.9-6-6.4l-3e-3 -0.015-5e-3 -0.015c-0.82-2.4-0.36-6.3 0.044-9.8 0.2-1.7 0.4-3.4 0.37-4.5-0.021-0.63-0.58-1.4-1.4-2.4-1.1-1.4-2.6-3.4-3.4-6.2a16 16 0 0 1-0.73-4.7c-8e-3 -1.9 0.31-4 0.94-6.1 0.91-2.8 2.1-4.9 3.6-6.5 1.3-1.4 2.8-2.4 4.7-3 2.8-0.93 6-0.82 9.1-0.72 3 0.1 5.9 0.2 8.4-0.63l0.023-7e-3 0.021-0.011c2.4-1.3 4.8-2.4 7.2-3.2 7-2.3 14-1.9 19 1 2.9 1.5 5.5 3.8 7.6 6.6s3.8 6.1 4.8 9.8c2.2 7.6 1.1 16-3.3 23-4 6.7-10 12-18 14l-0.1 0.034z"
|
|
258
|
+
}
|
|
259
|
+
];
|
|
260
|
+
var adjacentTeethPairs = [
|
|
261
|
+
[17, 18],
|
|
262
|
+
[16, 17],
|
|
263
|
+
[15, 16],
|
|
264
|
+
[14, 15],
|
|
265
|
+
[13, 14],
|
|
266
|
+
[12, 13],
|
|
267
|
+
[11, 12],
|
|
268
|
+
[11, 21],
|
|
269
|
+
[21, 22],
|
|
270
|
+
[22, 23],
|
|
271
|
+
[23, 24],
|
|
272
|
+
[24, 25],
|
|
273
|
+
[25, 26],
|
|
274
|
+
[26, 27],
|
|
275
|
+
[27, 28],
|
|
276
|
+
[37, 38],
|
|
277
|
+
[36, 37],
|
|
278
|
+
[35, 36],
|
|
279
|
+
[34, 35],
|
|
280
|
+
[33, 34],
|
|
281
|
+
[32, 33],
|
|
282
|
+
[31, 32],
|
|
283
|
+
[31, 41],
|
|
284
|
+
[41, 42],
|
|
285
|
+
[42, 43],
|
|
286
|
+
[43, 44],
|
|
287
|
+
[44, 45],
|
|
288
|
+
[45, 46],
|
|
289
|
+
[46, 47],
|
|
290
|
+
[47, 48]
|
|
291
|
+
];
|
|
292
|
+
function getTeethInRange(startId, endId) {
|
|
293
|
+
const startTooth = teethData.find((t) => t.id === startId);
|
|
294
|
+
const endTooth = teethData.find((t) => t.id === endId);
|
|
295
|
+
if (!startTooth || !endTooth)
|
|
296
|
+
return [];
|
|
297
|
+
const minOrder = Math.min(startTooth.order, endTooth.order);
|
|
298
|
+
const maxOrder = Math.max(startTooth.order, endTooth.order);
|
|
299
|
+
return teethData.filter((t) => t.order >= minOrder && t.order <= maxOrder).map((t) => t.id);
|
|
300
|
+
}
|
|
301
|
+
function sameSide(tooth1, tooth2) {
|
|
302
|
+
const [a, b] = [tooth1.toString(), tooth2.toString()];
|
|
303
|
+
return a[0] === b[0];
|
|
304
|
+
}
|
|
305
|
+
function parseTeethSelection(input) {
|
|
306
|
+
const selectedTeeth = [];
|
|
307
|
+
const bridges = [];
|
|
308
|
+
const regex = /\[(\d+)\s*,\s*(\d+)\]|(\d+)/g;
|
|
309
|
+
let match;
|
|
310
|
+
while ((match = regex.exec(input)) !== null) {
|
|
311
|
+
if (match[1] && match[2]) {
|
|
312
|
+
let start = Number(match[1]);
|
|
313
|
+
let end = Number(match[2]);
|
|
314
|
+
[start, end] = [Math.min(start, end), Math.max(start, end)];
|
|
315
|
+
const range = [];
|
|
316
|
+
if (sameSide(start, end)) {
|
|
317
|
+
for (let i = start;i <= end; i++) {
|
|
318
|
+
range.push(i);
|
|
319
|
+
}
|
|
320
|
+
} else {
|
|
321
|
+
const crossA = Number(`${start.toString()[0]}1`);
|
|
322
|
+
const crossB = Number(`${end.toString()[0]}1`);
|
|
323
|
+
for (let i = start;i >= crossA; i--) {
|
|
324
|
+
range.push(i);
|
|
325
|
+
}
|
|
326
|
+
for (let i = crossB;i <= end; i++) {
|
|
327
|
+
range.push(i);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
selectedTeeth.push(...range);
|
|
331
|
+
for (let i = 0;i < range.length - 1; i++) {
|
|
332
|
+
bridges.push([range[i], range[i + 1]]);
|
|
333
|
+
}
|
|
334
|
+
} else if (match[3]) {
|
|
335
|
+
selectedTeeth.push(Number(match[3]));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return { selectedTeeth, bridges };
|
|
339
|
+
}
|
|
340
|
+
function formatTeethSelection(selectedTeeth, bridges) {
|
|
341
|
+
if (!selectedTeeth || selectedTeeth.length === 0) {
|
|
342
|
+
return "";
|
|
343
|
+
}
|
|
344
|
+
const bridgeMap = new Map;
|
|
345
|
+
bridges.forEach(([tooth1, tooth2]) => {
|
|
346
|
+
if (!bridgeMap.has(tooth1))
|
|
347
|
+
bridgeMap.set(tooth1, []);
|
|
348
|
+
if (!bridgeMap.has(tooth2))
|
|
349
|
+
bridgeMap.set(tooth2, []);
|
|
350
|
+
bridgeMap.get(tooth1).push(tooth2);
|
|
351
|
+
bridgeMap.get(tooth2).push(tooth1);
|
|
352
|
+
});
|
|
353
|
+
const result = [];
|
|
354
|
+
let currentGroup = [];
|
|
355
|
+
selectedTeeth.forEach((tooth, index) => {
|
|
356
|
+
if (index === 0) {
|
|
357
|
+
currentGroup.push(tooth);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
const prevTooth = selectedTeeth[index - 1];
|
|
361
|
+
const hasBridge = bridgeMap.has(prevTooth) && bridgeMap.get(prevTooth).includes(tooth) && Math.abs(selectedTeeth.indexOf(tooth) - selectedTeeth.indexOf(prevTooth)) === 1;
|
|
362
|
+
if (hasBridge) {
|
|
363
|
+
currentGroup.push(tooth);
|
|
364
|
+
} else {
|
|
365
|
+
if (currentGroup.length > 0) {
|
|
366
|
+
if (currentGroup.length === 1) {
|
|
367
|
+
result.push(`${currentGroup[0]}`);
|
|
368
|
+
} else {
|
|
369
|
+
result.push(`[${currentGroup[0]}, ${currentGroup[currentGroup.length - 1]}]`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
currentGroup = [tooth];
|
|
373
|
+
}
|
|
374
|
+
});
|
|
375
|
+
if (currentGroup.length > 0) {
|
|
376
|
+
if (currentGroup.length === 1) {
|
|
377
|
+
result.push(`${currentGroup[0]}`);
|
|
378
|
+
} else {
|
|
379
|
+
result.push(`[${currentGroup[0]}, ${currentGroup[currentGroup.length - 1]}]`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
return result.join(", ");
|
|
383
|
+
}
|
|
384
|
+
export {
|
|
385
|
+
teethData,
|
|
386
|
+
sameSide,
|
|
387
|
+
parseTeethSelection,
|
|
388
|
+
getTeethInRange,
|
|
389
|
+
formatTeethSelection,
|
|
390
|
+
adjacentTeethPairs
|
|
391
|
+
};
|
package/dist/ui.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { TeethSelector, TeethChart, useTeethSelectorContext, } from "@components/teeth-selector";
|
|
2
|
+
export { TeethPreview } from "@components/teeth-preview";
|
|
3
|
+
export type { TeethSelectorProps, TeethSelectorState, TeethSelectorRenderProps, TeethChartProps, TeethPreviewProps, ToothRenderProps, BridgeRenderProps, } from "@lib/types";
|
|
4
|
+
//# sourceMappingURL=ui.d.ts.map
|
package/dist/ui.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ui.d.ts","sourceRoot":"","sources":["../src/ui.ts"],"names":[],"mappings":"AACA,OAAO,EACL,aAAa,EACb,UAAU,EACV,uBAAuB,GACxB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,YAAY,CAAC"}
|
package/dist/ui.js
ADDED
|
@@ -0,0 +1,797 @@
|
|
|
1
|
+
// src/components/teeth-selector.tsx
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
|
|
4
|
+
// src/lib/teeth.ts
|
|
5
|
+
var teethData = [
|
|
6
|
+
{
|
|
7
|
+
order: 0,
|
|
8
|
+
id: 18,
|
|
9
|
+
name: "Upper Right Third Molar",
|
|
10
|
+
position: "upper",
|
|
11
|
+
side: "right",
|
|
12
|
+
d: "m30 344c-1.8-0.6-3.4-1.6-4.7-3-1.5-1.6-2.7-3.7-3.6-6.5-0.63-2.1-0.94-4.2-0.94-6.1a16 16 0 0 1 0.73-4.7c0.87-2.8 2.3-4.7 3.4-6.2 0.78-1 1.3-1.8 1.4-2.4 0.026-1.2-0.17-2.8-0.37-4.5-0.4-3.4-0.86-7.3-0.044-9.8l5e-3 -0.015 3e-3 -0.015c0.51-2.5 2.5-4.7 6-6.4 2.8-1.4 5.8-2.1 7.1-2.4 0.21-0.049 0.37-0.088 0.48-0.12 4.7-1.1 10-0.73 14-0.23 4.9 0.62 9.3 1.7 12 2.4l0.1 0.034c7.1 2.3 14 7.5 18 14 4.3 7.1 5.5 15 3.3 23-1.1 3.7-2.7 7-4.8 9.8s-4.7 5-7.6 6.6c-5.6 3-12 3.3-19 1-2.4-0.76-4.8-1.8-7.2-3.2l-0.021-0.012-0.023-7e-3c-2.5-0.82-5.4-0.73-8.4-0.63-3.1 0.1-6.3 0.21-9.1-0.72z"
|
|
13
|
+
},
|
|
14
|
+
{
|
|
15
|
+
order: 1,
|
|
16
|
+
id: 17,
|
|
17
|
+
name: "Upper Right Second Molar",
|
|
18
|
+
position: "upper",
|
|
19
|
+
side: "right",
|
|
20
|
+
d: "m39 279c-3-0.96-6.3-2.5-8.5-6.2-1.5-2.9-2.2-10-1.8-21l6e-3 -0.19c0.026-1.2-0.17-2.8-0.37-4.5-0.4-3.4-0.86-7.3-0.045-9.8 0.4-1.1 1.9-2.4 4.2-3.7 1.8-1 3.9-1.9 4.6-2.1l6e-3 -1e-3 6e-3 -2e-3c6.5-2.1 24 2.2 29 4l0.13 0.043c3.6 1.2 6.7 2.7 9.3 4.7s4.7 4.3 6.2 6.9c1.5 2.7 2.4 5.8 2.6 9.1 0.22 3.4-0.26 7.2-1.4 11-1.9 6.6-5.5 11-11 14-3 1.6-6.6 2.4-11 2.5-3.7 0.027-7.8-0.66-12-2l-0.24-0.078c-2-0.63-3.9-1.1-5.7-1.6-1.7-0.43-3.4-0.83-4.9-1.3z"
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
order: 2,
|
|
24
|
+
id: 16,
|
|
25
|
+
name: "Upper Right First Molar",
|
|
26
|
+
position: "upper",
|
|
27
|
+
side: "right",
|
|
28
|
+
d: "m72 229c-0.72 0-1.5-0.018-2.2-0.053-8.3-0.39-16-2.8-21-6.7-3-2.1-5.3-4.7-6.9-7.5-1.7-3.1-2.6-6.6-2.6-10 0-2.7 0.77-5.6 2-7.3 0.41-0.58 1-1.2 1.7-1.9 1.2-1.2 2.6-2.7 3.4-4.4 0.41-0.98 0.45-2.4 0.5-4 0.072-2.5 0.16-5.6 1.8-8.1l4e-3 -7e-3 4e-3 -6e-3c1.4-2.4 3.6-4.1 6.6-5.1 2.4-0.79 5.4-1.1 9.5-1.1 4.7 0.79 9 2.2 13 4.3 3.9 2 7.3 4.6 10 7.5 2.8 3 4.9 6.4 6.3 10a27 27 0 0 1 1.6 12c-1.3 16-8.7 23-23 23z"
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
order: 3,
|
|
32
|
+
id: 15,
|
|
33
|
+
name: "Upper Right Second Premolar",
|
|
34
|
+
position: "upper",
|
|
35
|
+
side: "right",
|
|
36
|
+
d: "m73 168a39 39 0 0 1-0.2-0.1c-3.9-1.9-7.1-4.1-9.5-6.5-2.3-2.3-3.8-4.7-4.6-7.2a13 13 0 0 1-0.52-5.8c0.24-1.9 0.89-3.8 1.9-5.7 2.2-4.1 6.2-6.9 11-8 2.6-0.56 5.3-0.64 8.1-0.23 3 0.42 6 1.4 9 2.8 0.71 0.34 1.4 0.72 2.1 1.1 3.2 1.8 6.1 3.9 8.5 6.2 2.4 2.2 4.3 4.5 5.7 6.8s2.2 4.6 2.5 6.8c0.29 2.2-0.014 4.3-0.9 6.2-0.62 1.3-1.6 2.5-2.9 3.6-1.3 1-2.9 1.9-4.8 2.5-3.5 1.2-7.6 1.7-12 1.3-4.7-0.38-9.4-1.7-14-3.8z"
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
order: 4,
|
|
40
|
+
id: 14,
|
|
41
|
+
name: "Upper Right First Premolar",
|
|
42
|
+
position: "upper",
|
|
43
|
+
side: "right",
|
|
44
|
+
d: "m118 135a6.3 6.3 0 0 1-0.3 0.28c-2.4 2.1-6.6 2.8-12 2-5.4-0.85-11-3.3-16-6.8-5.7-4.1-9.3-9.3-9.7-14-0.28-3.4 0.92-6.6 3.5-9.2a16 16 0 0 1 1.6-1.4c8.7-6.6 22-4.9 29 3.7a26 26 0 0 1 4.2 7 27 27 0 0 1 1.8 7.4c0.47 4.9-0.57 9.1-2.8 11z"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
order: 5,
|
|
48
|
+
id: 13,
|
|
49
|
+
name: "Upper Right Canine",
|
|
50
|
+
position: "upper",
|
|
51
|
+
side: "right",
|
|
52
|
+
d: "m144 104c-0.09 0.084-0.19 0.17-0.29 0.24-1.2 0.9-2.9 1.5-5.1 1.8-2.2 0.33-4.9 0.3-7.7-0.086-6.4-0.88-13-3.5-19-7.5-2.2-1.6-4-3.4-5.2-5.4a13 13 0 0 1-1.8-5.8c-0.18-2.6 0.36-5.4 1.6-8 1.1-2.3 2.6-4.5 4.3-6.1 0.36-0.34 0.73-0.65 1.1-0.92 1.4-1.1 4.4-2.7 7.8-4 2.8-1.1 6.8-2.2 10-1.8h8e-3c2.5 0.26 4.4 1.4 5.8 3.6 1.3 2 2.1 4.4 2.9 6.8 0.19 0.58 0.36 1.1 0.55 1.7 0.52 1.5 1.1 3.1 1.7 4.7 1.6 4.3 3.2 8.8 3.9 12 0.83 4.1 0.48 6.9-1.1 8.3z"
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
order: 6,
|
|
56
|
+
id: 12,
|
|
57
|
+
name: "Upper Right Lateral Incisor",
|
|
58
|
+
position: "upper",
|
|
59
|
+
side: "right",
|
|
60
|
+
d: "m168 82c-2.9 1.2-6.4 0.91-11-1-3.7-1.7-7.9-4.5-13-8.8-0.54-0.44-1.1-0.86-1.6-1.3-2-1.6-3.8-3-5-4.4-1.3-1.5-1.9-2.7-1.7-4 0.17-1.6 1.4-3.3 3.9-5.3 2.6-2.1 6.8-4.5 13-7.4a105 105 0 0 1 5.9-2.8c6.4-2.7 10-3.3 13-2 2.5 1.6 2.7 5.7 3 11 0.073 1.5 0.15 3 0.28 4.6 0.61 7.4 0.52 12-0.3 15-0.86 3.2-2.6 5.2-5.8 6.6l-0.04 0.017z"
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
order: 7,
|
|
64
|
+
id: 11,
|
|
65
|
+
name: "Upper Right Central Incisor",
|
|
66
|
+
position: "upper",
|
|
67
|
+
side: "right",
|
|
68
|
+
d: "m205 74c-10 1.1-18-9.3-23-18l-0.3-0.5c-1.4-2.4-2.7-4.6-3.5-6.7-0.85-2.3-0.88-4.2-0.11-5.9 0.9-2 2.9-3.6 6.2-5.1 3.7-1.6 8.9-3 16-4.2a82 82 0 0 1 5-0.69c4.3-0.46 7.9-0.39 11 0.2 2.4 0.52 4.2 1.5 5.4 2.8 1.3 1.5 1.9 3.6 1.7 6.3-0.14 2.4-0.79 5-1.4 7.4-0.23 0.89-0.45 1.7-0.63 2.5l-0.29 1.3c-0.98 4.3-2.1 9.3-4.2 13-2.4 4.5-5.8 6.9-10 7.6-0.21 0.03-0.42 0.057-0.62 0.079z"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
order: 8,
|
|
72
|
+
id: 21,
|
|
73
|
+
name: "Upper Left Central Incisor",
|
|
74
|
+
position: "upper",
|
|
75
|
+
side: "left",
|
|
76
|
+
d: "m246 32h1e-3c1.5 0.16 3.2 0.4 5 0.69 7 1.2 12 2.5 16 4.2 3.3 1.5 5.3 3.1 6.2 5.1 0.77 1.7 0.73 3.5-0.12 5.9-0.77 2.1-2.1 4.4-3.5 6.7l-0.3 0.5c-5.4 9.2-13 20-23 18a15 15 0 0 1-0.62-0.079c-4.5-0.66-7.9-3.2-10-7.6-2.1-3.9-3.2-8.9-4.2-13l-0.29-1.3c-0.18-0.81-0.4-1.7-0.63-2.5-0.63-2.5-1.3-5-1.4-7.4-0.15-2.7 0.41-4.8 1.7-6.3 1.2-1.3 3-2.3 5.4-2.8 2.7-0.58 6.3-0.65 11-0.19z"
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
order: 9,
|
|
80
|
+
id: 22,
|
|
81
|
+
name: "Upper Left Lateral Incisor",
|
|
82
|
+
position: "upper",
|
|
83
|
+
side: "left",
|
|
84
|
+
d: "m292 47h1e-3c1.8 0.75 3.8 1.7 5.9 2.8 5.8 2.9 9.9 5.4 13 7.4 2.5 1.9 3.7 3.7 3.9 5.3 0.14 1.3-0.41 2.5-1.7 4-1.2 1.4-3 2.8-5 4.4-0.51 0.41-1 0.83-1.6 1.3-5.3 4.3-9.5 7.1-13 8.8-4.3 1.9-7.8 2.3-11 1l-0.04-0.018c-3.2-1.4-4.9-3.3-5.8-6.6-0.82-3.1-0.91-7.3-0.3-15 0.13-1.6 0.21-3.1 0.28-4.6 0.26-5.3 0.47-9.4 3-11 2.2-1.4 6.2-0.77 13 2z"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
order: 10,
|
|
88
|
+
id: 23,
|
|
89
|
+
name: "Upper Left Canine",
|
|
90
|
+
position: "upper",
|
|
91
|
+
side: "left",
|
|
92
|
+
d: "m339 73c1.7 1.6 3.2 3.7 4.3 6.1 1.2 2.7 1.8 5.5 1.6 8a13 13 0 0 1-1.8 5.8c-1.2 2-2.9 3.8-5.2 5.4-5.6 3.9-12 6.6-19 7.5-2.8 0.38-5.4 0.41-7.7 0.086-2.2-0.32-3.9-0.96-5.1-1.8a4 4 0 0 1-0.29-0.24c-1.6-1.4-1.9-4.2-1.1-8.3 0.75-3.7 2.4-8.2 3.9-12a301 301 0 0 0 1.7-4.7c0.18-0.54 0.36-1.1 0.55-1.7 0.77-2.4 1.6-4.8 2.9-6.8 1.5-2.2 3.4-3.4 5.8-3.6h5e-3l4e-3 -1e-3c3.3-0.45 7.3 0.71 10 1.8 3.4 1.3 6.4 3 7.8 4 0.36 0.27 0.73 0.58 1.1 0.92z"
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
order: 11,
|
|
96
|
+
id: 24,
|
|
97
|
+
name: "Upper Left First Premolar",
|
|
98
|
+
position: "upper",
|
|
99
|
+
side: "left",
|
|
100
|
+
d: "m367 107h1e-3c2.6 2.6 3.8 5.7 3.5 9.2-0.42 5-3.9 10-9.7 14-5 3.6-11 6-16 6.8-5.1 0.81-9.4 0.076-12-2a6.3 6.3 0 0 1-0.3-0.28c-2.2-2.2-3.3-6.5-2.8-11a27 27 0 0 1 1.8-7.4 26 26 0 0 1 4.2-7c7.4-8.7 21-10 29-3.7a16 16 0 0 1 1.6 1.4z"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
order: 12,
|
|
104
|
+
id: 25,
|
|
105
|
+
name: "Upper Left Second Premolar",
|
|
106
|
+
position: "upper",
|
|
107
|
+
side: "left",
|
|
108
|
+
d: "m362 137 2e-3 -1e-3c3-1.5 6-2.4 9-2.8 2.8-0.4 5.6-0.32 8.1 0.24 5 1.1 9 3.9 11 8 1 1.9 1.7 3.8 1.9 5.7a13 13 0 0 1-0.52 5.8c-0.8 2.5-2.4 5-4.6 7.2-2.4 2.4-5.6 4.6-9.5 6.5l-0.2 0.1c-4.3 2.1-9.1 3.4-14 3.8-4.3 0.35-8.5-0.11-12-1.3-1.9-0.65-3.5-1.5-4.8-2.5s-2.3-2.2-2.9-3.6c-0.89-1.9-1.2-4-0.9-6.2 0.28-2.2 1.1-4.5 2.5-6.8s3.3-4.6 5.7-6.8 5.3-4.3 8.5-6.2a37 37 0 0 1 2.1-1.1z"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
order: 13,
|
|
112
|
+
id: 26,
|
|
113
|
+
name: "Upper Left First Molar",
|
|
114
|
+
position: "upper",
|
|
115
|
+
side: "left",
|
|
116
|
+
d: "m378 229c-15 0-22-7.3-23-23-0.33-4.1 0.2-8 1.6-12 1.3-3.7 3.4-7 6.3-10 2.8-3 6.2-5.5 10-7.5 4-2.1 8.4-3.5 13-4.3 4.1 1e-3 7.1 0.36 9.5 1.1 3 0.98 5.2 2.6 6.6 5.1l4e-3 6e-3 4e-3 7e-3c1.6 2.4 1.7 5.5 1.8 8.1 0.046 1.6 0.087 3 0.5 4 0.76 1.8 2.1 3.2 3.4 4.4 0.65 0.66 1.3 1.3 1.7 1.9 1.2 1.7 2 4.5 2 7.3 0 3.8-0.87 7.2-2.6 10-1.6 2.9-3.9 5.4-6.9 7.5-5.5 3.9-13 6.3-21 6.7-0.76 0.035-1.5 0.053-2.2 0.053z"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
order: 14,
|
|
120
|
+
id: 27,
|
|
121
|
+
name: "Upper Left Second Molar",
|
|
122
|
+
position: "upper",
|
|
123
|
+
side: "left",
|
|
124
|
+
d: "m386 236c5.5-1.8 23-6.1 29-4l6e-3 2e-3 6e-3 1e-3c0.74 0.2 2.7 1 4.6 2.1 2.4 1.3 3.8 2.6 4.2 3.7 0.81 2.4 0.36 6.3-0.045 9.8-0.2 1.7-0.4 3.4-0.37 4.5l7e-3 0.2c0.36 11-0.3 18-1.8 21-2.2 3.8-5.6 5.3-8.5 6.2-1.5 0.5-3.2 0.9-4.9 1.3-1.9 0.48-3.9 0.97-6 1.6-4.2 1.4-8.3 2.1-12 2-4-0.028-7.5-0.86-11-2.5-5-2.7-8.6-7.4-11-14-1.2-4-1.7-7.8-1.4-11 0.22-3.3 1.1-6.4 2.6-9.1 1.5-2.6 3.5-5 6.2-6.9 2.6-1.9 5.7-3.5 9.3-4.7l0.13-0.043z"
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
order: 15,
|
|
128
|
+
id: 28,
|
|
129
|
+
name: "Upper Left Third Molar",
|
|
130
|
+
position: "upper",
|
|
131
|
+
side: "left",
|
|
132
|
+
d: "m384 294c2.3-0.74 6.7-1.8 12-2.4 4-0.5 9.7-0.87 14 0.23 0.11 0.03 0.28 0.068 0.48 0.12 1.3 0.3 4.3 1 7.1 2.4 3.5 1.7 5.5 3.9 6 6.4l3e-3 0.015 5e-3 0.015c0.82 2.4 0.36 6.3-0.044 9.8-0.2 1.7-0.4 3.4-0.37 4.5 0.021 0.63 0.58 1.4 1.4 2.4 1.1 1.4 2.6 3.4 3.4 6.2 0.48 1.5 0.72 3.1 0.73 4.7 8e-3 1.9-0.31 4-0.94 6.1-0.91 2.8-2.1 4.9-3.6 6.5-1.3 1.4-2.8 2.4-4.7 3-2.8 0.93-6 0.82-9.1 0.72-3-0.1-5.9-0.2-8.4 0.63l-0.023 7e-3 -0.021 0.011c-2.4 1.3-4.8 2.4-7.2 3.2-7 2.3-14 1.9-19-1-2.9-1.5-5.5-3.8-7.6-6.6s-3.8-6.1-4.8-9.8c-2.2-7.6-1.1-16 3.3-23 4-6.7 10-12 18-14l0.1-0.034z"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
order: 16,
|
|
136
|
+
id: 38,
|
|
137
|
+
name: "Lower Left Third Molar",
|
|
138
|
+
position: "lower",
|
|
139
|
+
side: "left",
|
|
140
|
+
d: "m420 406c1.8 0.6 3.4 1.6 4.7 3 1.5 1.6 2.7 3.7 3.6 6.5 0.63 2.1 0.94 4.2 0.94 6.1a16 16 0 0 1-0.73 4.7c-0.87 2.8-2.3 4.7-3.4 6.2-0.78 1-1.3 1.8-1.4 2.4-0.026 1.2 0.17 2.8 0.37 4.5 0.4 3.4 0.86 7.3 0.044 9.8l-5e-3 0.015-3e-3 0.015c-0.51 2.5-2.5 4.7-6 6.4-2.8 1.4-5.8 2.1-7.1 2.4-0.21 0.049-0.37 0.088-0.48 0.12-4.7 1.1-10 0.73-14 0.23-4.9-0.62-9.3-1.7-12-2.4l-0.1-0.034c-7.1-2.3-14-7.5-18-14-4.3-7.1-5.5-15-3.3-23 1.1-3.7 2.7-7 4.8-9.8s4.7-5 7.6-6.6c5.6-3 12-3.3 19-1 2.4 0.76 4.8 1.8 7.2 3.2l0.021 0.012 0.023 7e-3c2.5 0.82 5.4 0.73 8.4 0.63 3.1-0.1 6.3-0.21 9.1 0.72z"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
order: 17,
|
|
144
|
+
id: 37,
|
|
145
|
+
name: "Lower Left Second Molar",
|
|
146
|
+
position: "lower",
|
|
147
|
+
side: "left",
|
|
148
|
+
d: "m411 471c3 0.96 6.3 2.5 8.5 6.2 1.5 2.9 2.2 10 1.8 21l-6e-3 0.19c-0.026 1.2 0.17 2.8 0.37 4.5 0.4 3.4 0.86 7.3 0.045 9.8-0.4 1.1-1.9 2.4-4.2 3.7-1.8 1-3.9 1.9-4.6 2.1l-6e-3 1e-3 -6e-3 2e-3c-6.5 2.1-24-2.2-29-4a32 32 0 0 1-0.13-0.043c-3.6-1.2-6.7-2.7-9.3-4.7s-4.7-4.3-6.2-6.9c-1.5-2.7-2.4-5.8-2.6-9.1-0.22-3.4 0.26-7.2 1.4-11 1.9-6.6 5.5-11 11-14 3-1.6 6.6-2.4 11-2.5 3.7-0.027 7.8 0.66 12 2l0.24 0.078c2 0.63 3.9 1.1 5.7 1.6 1.7 0.43 3.4 0.83 4.9 1.3z"
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
order: 18,
|
|
152
|
+
id: 36,
|
|
153
|
+
name: "Lower Left First Molar",
|
|
154
|
+
position: "lower",
|
|
155
|
+
side: "left",
|
|
156
|
+
d: "m386 578c-4.7-0.79-9-2.2-13-4.3-3.9-2-7.3-4.6-10-7.5-2.8-3-4.9-6.4-6.3-10a27 27 0 0 1-1.6-12c1.3-16 8.7-23 23-23 0.72 0 1.5 0.018 2.2 0.053 8.3 0.39 16 2.8 21 6.7 3 2.1 5.3 4.7 6.9 7.5 1.7 3.1 2.6 6.6 2.6 10 0 2.7-0.77 5.6-2 7.3-0.41 0.58-1 1.2-1.7 1.9-1.2 1.2-2.6 2.7-3.4 4.4-0.41 0.98-0.45 2.4-0.5 4-0.072 2.5-0.16 5.6-1.8 8.1l-8e-3 0.012c-1.4 2.4-3.6 4.1-6.6 5.1-2.4 0.79-5.4 1.1-9.5 1.1z"
|
|
157
|
+
},
|
|
158
|
+
{
|
|
159
|
+
order: 19,
|
|
160
|
+
id: 35,
|
|
161
|
+
name: "Lower Left Second Premolar",
|
|
162
|
+
position: "lower",
|
|
163
|
+
side: "left",
|
|
164
|
+
d: "m377 582 0.2 0.1c3.9 1.9 7.1 4.1 9.5 6.5 2.3 2.3 3.8 4.7 4.6 7.2 0.59 1.9 0.77 3.8 0.52 5.8-0.24 1.9-0.89 3.8-1.9 5.7-2.2 4.1-6.2 6.9-11 8-2.6 0.56-5.3 0.64-8.1 0.23-3-0.42-6-1.4-9-2.8a37 37 0 0 1-2.1-1.1c-3.2-1.8-6.1-3.9-8.5-6.2-2.4-2.2-4.3-4.5-5.7-6.8s-2.2-4.6-2.5-6.8c-0.29-2.2 0.014-4.3 0.9-6.2 0.62-1.3 1.6-2.5 2.9-3.6 1.3-1 2.9-1.9 4.8-2.5 3.5-1.2 7.6-1.7 12-1.3 4.7 0.38 9.4 1.7 14 3.8z"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
order: 20,
|
|
168
|
+
id: 34,
|
|
169
|
+
name: "Lower Left First Premolar",
|
|
170
|
+
position: "lower",
|
|
171
|
+
side: "left",
|
|
172
|
+
d: "m332 615a6.3 6.3 0 0 1 0.3-0.28c2.4-2.1 6.6-2.8 12-2 5.4 0.85 11 3.3 16 6.8 5.7 4.1 9.3 9.3 9.7 14 0.28 3.4-0.92 6.6-3.5 9.2-0.49 0.49-1 0.96-1.6 1.4-8.7 6.6-22 4.9-29-3.7a26 26 0 0 1-4.2-7 27 27 0 0 1-1.8-7.4c-0.47-4.9 0.57-9.1 2.8-11z"
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
order: 21,
|
|
176
|
+
id: 33,
|
|
177
|
+
name: "Lower Left Canine",
|
|
178
|
+
position: "lower",
|
|
179
|
+
side: "left",
|
|
180
|
+
d: "m307 647c0.09-0.084 0.19-0.17 0.29-0.24 1.2-0.9 2.9-1.5 5.1-1.8 2.2-0.33 4.9-0.3 7.7 0.086 6.4 0.88 13 3.5 19 7.5 2.2 1.6 4 3.4 5.2 5.4a13 13 0 0 1 1.8 5.8c0.18 2.6-0.36 5.4-1.6 8-1.1 2.3-2.6 4.5-4.3 6.1-0.36 0.34-0.73 0.65-1.1 0.92-1.4 1.1-4.4 2.7-7.8 4-2.8 1.1-6.8 2.2-10 1.8h-8e-3c-2.5-0.26-4.4-1.4-5.8-3.6-1.3-2-2.1-4.4-2.9-6.8-0.19-0.58-0.36-1.1-0.55-1.7a301 301 0 0 0-1.7-4.7c-1.6-4.3-3.2-8.8-3.9-12-0.83-4.1-0.48-6.9 1.1-8.3z"
|
|
181
|
+
},
|
|
182
|
+
{
|
|
183
|
+
order: 22,
|
|
184
|
+
id: 32,
|
|
185
|
+
name: "Lower Left Lateral Incisor",
|
|
186
|
+
position: "lower",
|
|
187
|
+
side: "left",
|
|
188
|
+
d: "m283 669c2.9-1.2 6.4-0.91 11 1 3.7 1.7 7.9 4.5 13 8.8 0.54 0.44 1.1 0.86 1.6 1.3 2 1.6 3.8 3 5 4.4 1.3 1.5 1.9 2.7 1.7 4-0.17 1.6-1.4 3.3-3.9 5.3-2.6 2.1-6.8 4.5-13 7.4a105 105 0 0 1-5.9 2.8c-6.4 2.7-10 3.3-13 2-2.5-1.6-2.7-5.7-3-11-0.073-1.5-0.15-3-0.28-4.6-0.61-7.4-0.52-12 0.3-15 0.86-3.2 2.6-5.2 5.8-6.6l0.04-0.017z"
|
|
189
|
+
},
|
|
190
|
+
{
|
|
191
|
+
order: 23,
|
|
192
|
+
id: 31,
|
|
193
|
+
name: "Lower Left Central Incisor",
|
|
194
|
+
position: "lower",
|
|
195
|
+
side: "left",
|
|
196
|
+
d: "m245 677c10-1.1 18 9.3 23 18l0.3 0.5c1.4 2.4 2.7 4.6 3.5 6.7 0.85 2.3 0.88 4.2 0.11 5.9-0.9 2-2.9 3.6-6.2 5.1-3.7 1.6-8.9 3-16 4.2a82 82 0 0 1-5 0.69c-4.3 0.46-7.9 0.39-11-0.2-2.4-0.52-4.2-1.5-5.4-2.8-1.3-1.5-1.9-3.6-1.7-6.3 0.14-2.4 0.79-5 1.4-7.4a96 96 0 0 0 0.92-3.8c0.98-4.3 2.1-9.3 4.2-13 2.4-4.5 5.8-6.9 10-7.6 0.21-0.03 0.42-0.057 0.62-0.079z"
|
|
197
|
+
},
|
|
198
|
+
{
|
|
199
|
+
order: 24,
|
|
200
|
+
id: 41,
|
|
201
|
+
name: "Lower Right Central Incisor",
|
|
202
|
+
position: "lower",
|
|
203
|
+
side: "right",
|
|
204
|
+
d: "m205 718h-1e-3a82 82 0 0 1-5-0.69c-7-1.2-12-2.5-16-4.2-3.3-1.5-5.3-3.1-6.2-5.1-0.77-1.7-0.73-3.5 0.12-5.9 0.77-2.1 2.1-4.4 3.5-6.7l0.3-0.5c5.4-9.2 13-20 23-18 0.21 0.022 0.42 0.048 0.62 0.079 4.5 0.66 7.9 3.2 10 7.6 2.1 3.9 3.2 8.9 4.2 13l0.29 1.3c0.18 0.81 0.4 1.7 0.63 2.5 0.63 2.5 1.3 5 1.4 7.4 0.15 2.7-0.41 4.8-1.7 6.3-1.2 1.3-3 2.3-5.4 2.8-2.7 0.58-6.3 0.65-11 0.19z"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
order: 25,
|
|
208
|
+
id: 42,
|
|
209
|
+
name: "Lower Right Lateral Incisor",
|
|
210
|
+
position: "lower",
|
|
211
|
+
side: "right",
|
|
212
|
+
d: "m158 704h-1e-3a105 105 0 0 1-5.9-2.8c-5.8-2.9-9.9-5.4-13-7.4-2.5-1.9-3.7-3.7-3.9-5.3-0.14-1.3 0.41-2.5 1.7-4 1.2-1.4 3-2.8 5-4.4 0.51-0.41 1-0.83 1.6-1.3 5.3-4.3 9.5-7.1 13-8.8 4.3-1.9 7.8-2.3 11-1l0.04 0.018c3.2 1.4 4.9 3.3 5.8 6.6 0.82 3.1 0.91 7.3 0.3 15-0.13 1.6-0.21 3.1-0.28 4.6-0.26 5.3-0.47 9.4-3 11-2.2 1.4-6.2 0.77-13-2z"
|
|
213
|
+
},
|
|
214
|
+
{
|
|
215
|
+
order: 26,
|
|
216
|
+
id: 43,
|
|
217
|
+
name: "Lower Right Canine",
|
|
218
|
+
position: "lower",
|
|
219
|
+
side: "right",
|
|
220
|
+
d: "m111 677c-1.7-1.6-3.2-3.7-4.3-6.1-1.2-2.7-1.8-5.5-1.6-8a13 13 0 0 1 1.8-5.8c1.2-2 2.9-3.8 5.2-5.4 5.6-3.9 12-6.6 19-7.5 2.8-0.38 5.4-0.41 7.7-0.086 2.2 0.32 3.9 0.96 5.1 1.8 0.1 0.076 0.2 0.16 0.29 0.24 1.6 1.4 1.9 4.2 1.1 8.3-0.75 3.7-2.4 8.2-3.9 12a300 300 0 0 0-1.7 4.7c-0.18 0.54-0.36 1.1-0.55 1.7-0.77 2.4-1.6 4.8-2.9 6.8-1.5 2.2-3.4 3.4-5.8 3.6h-5e-3l-4e-3 1e-3c-3.3 0.45-7.3-0.71-10-1.8-3.4-1.3-6.4-3-7.8-4a13 13 0 0 1-1.1-0.92z"
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
order: 27,
|
|
224
|
+
id: 44,
|
|
225
|
+
name: "Lower Right First Premolar",
|
|
226
|
+
position: "lower",
|
|
227
|
+
side: "right",
|
|
228
|
+
d: "m83 643h-1e-3c-2.6-2.6-3.8-5.7-3.5-9.2 0.42-5 3.9-10 9.7-14 5-3.6 11-6 16-6.8 5.1-0.81 9.4-0.076 12 2 0.1 0.089 0.2 0.18 0.3 0.28 2.2 2.2 3.3 6.5 2.8 11a27 27 0 0 1-1.8 7.4 26 26 0 0 1-4.2 7c-7.4 8.7-21 10-29 3.7a16 16 0 0 1-1.6-1.4z"
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
order: 28,
|
|
232
|
+
id: 45,
|
|
233
|
+
name: "Lower Right Second Premolar",
|
|
234
|
+
position: "lower",
|
|
235
|
+
side: "right",
|
|
236
|
+
d: "m88 613-2e-3 1e-3c-3 1.5-6 2.4-9 2.8-2.8 0.4-5.6 0.32-8.1-0.24-5-1.1-9-3.9-11-8-1-1.9-1.7-3.8-1.9-5.7a13 13 0 0 1 0.52-5.8c0.8-2.5 2.4-5 4.6-7.2 2.4-2.4 5.6-4.6 9.5-6.5l0.2-0.1c4.3-2.1 9.1-3.4 14-3.8 4.3-0.35 8.5 0.11 12 1.3 1.9 0.65 3.5 1.5 4.8 2.5s2.3 2.2 2.9 3.6c0.89 1.9 1.2 4 0.9 6.2-0.28 2.2-1.1 4.5-2.5 6.8s-3.3 4.6-5.7 6.8-5.3 4.3-8.5 6.2c-0.7 0.4-1.4 0.78-2.1 1.1z"
|
|
237
|
+
},
|
|
238
|
+
{
|
|
239
|
+
order: 29,
|
|
240
|
+
id: 46,
|
|
241
|
+
name: "Lower Right First Molar",
|
|
242
|
+
position: "lower",
|
|
243
|
+
side: "right",
|
|
244
|
+
d: "m65 578c-4.1-1e-3 -7.1-0.36-9.5-1.1-3-0.98-5.2-2.6-6.6-5.1l-4e-3 -7e-3 -4e-3 -6e-3c-1.6-2.4-1.7-5.5-1.8-8.1-0.047-1.6-0.087-3-0.5-4-0.76-1.8-2.1-3.2-3.4-4.4-0.65-0.66-1.3-1.3-1.7-1.9-1.2-1.7-2-4.5-2-7.3 0-3.8 0.87-7.2 2.6-10 1.6-2.9 3.9-5.4 6.9-7.5 5.5-3.9 13-6.3 21-6.7 0.76-0.035 1.5-0.053 2.2-0.053 15 0 22 7.3 23 23 0.34 4.1-0.2 8-1.6 12-1.3 3.7-3.5 7-6.3 10s-6.2 5.5-10 7.5c-4 2.1-8.4 3.5-13 4.3z"
|
|
245
|
+
},
|
|
246
|
+
{
|
|
247
|
+
order: 30,
|
|
248
|
+
id: 47,
|
|
249
|
+
name: "Lower Right Second Molar",
|
|
250
|
+
position: "lower",
|
|
251
|
+
side: "right",
|
|
252
|
+
d: "m66 515c-5.5 1.8-23 6.1-29 4l-7e-3 -2e-3 -6e-3 -1e-3c-0.74-0.2-2.7-1-4.6-2.1-2.4-1.3-3.8-2.6-4.2-3.7-0.81-2.4-0.36-6.3 0.045-9.8 0.2-1.7 0.4-3.4 0.37-4.5l-7e-3 -0.2c-0.36-11 0.3-18 1.8-21 2.2-3.8 5.6-5.3 8.5-6.2 1.5-0.5 3.2-0.9 4.9-1.3 1.9-0.48 3.9-0.97 6-1.6 4.2-1.4 8.3-2.1 12-2 4 0.028 7.5 0.86 11 2.5 5 2.7 8.6 7.4 11 14 1.2 4 1.7 7.8 1.4 11-0.22 3.3-1.1 6.4-2.6 9.1-1.5 2.6-3.5 5-6.2 6.9-2.6 1.9-5.7 3.5-9.3 4.7l-0.13 0.043z"
|
|
253
|
+
},
|
|
254
|
+
{
|
|
255
|
+
order: 31,
|
|
256
|
+
id: 48,
|
|
257
|
+
name: "Lower Right Third Molar",
|
|
258
|
+
position: "lower",
|
|
259
|
+
side: "right",
|
|
260
|
+
d: "m66 456c-2.3 0.74-6.7 1.8-12 2.4-4 0.5-9.7 0.87-14-0.23a21 21 0 0 0-0.48-0.12c-1.3-0.3-4.3-1-7.1-2.4-3.5-1.7-5.5-3.9-6-6.4l-3e-3 -0.015-5e-3 -0.015c-0.82-2.4-0.36-6.3 0.044-9.8 0.2-1.7 0.4-3.4 0.37-4.5-0.021-0.63-0.58-1.4-1.4-2.4-1.1-1.4-2.6-3.4-3.4-6.2a16 16 0 0 1-0.73-4.7c-8e-3 -1.9 0.31-4 0.94-6.1 0.91-2.8 2.1-4.9 3.6-6.5 1.3-1.4 2.8-2.4 4.7-3 2.8-0.93 6-0.82 9.1-0.72 3 0.1 5.9 0.2 8.4-0.63l0.023-7e-3 0.021-0.011c2.4-1.3 4.8-2.4 7.2-3.2 7-2.3 14-1.9 19 1 2.9 1.5 5.5 3.8 7.6 6.6s3.8 6.1 4.8 9.8c2.2 7.6 1.1 16-3.3 23-4 6.7-10 12-18 14l-0.1 0.034z"
|
|
261
|
+
}
|
|
262
|
+
];
|
|
263
|
+
var adjacentTeethPairs = [
|
|
264
|
+
[17, 18],
|
|
265
|
+
[16, 17],
|
|
266
|
+
[15, 16],
|
|
267
|
+
[14, 15],
|
|
268
|
+
[13, 14],
|
|
269
|
+
[12, 13],
|
|
270
|
+
[11, 12],
|
|
271
|
+
[11, 21],
|
|
272
|
+
[21, 22],
|
|
273
|
+
[22, 23],
|
|
274
|
+
[23, 24],
|
|
275
|
+
[24, 25],
|
|
276
|
+
[25, 26],
|
|
277
|
+
[26, 27],
|
|
278
|
+
[27, 28],
|
|
279
|
+
[37, 38],
|
|
280
|
+
[36, 37],
|
|
281
|
+
[35, 36],
|
|
282
|
+
[34, 35],
|
|
283
|
+
[33, 34],
|
|
284
|
+
[32, 33],
|
|
285
|
+
[31, 32],
|
|
286
|
+
[31, 41],
|
|
287
|
+
[41, 42],
|
|
288
|
+
[42, 43],
|
|
289
|
+
[43, 44],
|
|
290
|
+
[44, 45],
|
|
291
|
+
[45, 46],
|
|
292
|
+
[46, 47],
|
|
293
|
+
[47, 48]
|
|
294
|
+
];
|
|
295
|
+
function getTeethInRange(startId, endId) {
|
|
296
|
+
const startTooth = teethData.find((t) => t.id === startId);
|
|
297
|
+
const endTooth = teethData.find((t) => t.id === endId);
|
|
298
|
+
if (!startTooth || !endTooth)
|
|
299
|
+
return [];
|
|
300
|
+
const minOrder = Math.min(startTooth.order, endTooth.order);
|
|
301
|
+
const maxOrder = Math.max(startTooth.order, endTooth.order);
|
|
302
|
+
return teethData.filter((t) => t.order >= minOrder && t.order <= maxOrder).map((t) => t.id);
|
|
303
|
+
}
|
|
304
|
+
function sameSide(tooth1, tooth2) {
|
|
305
|
+
const [a, b] = [tooth1.toString(), tooth2.toString()];
|
|
306
|
+
return a[0] === b[0];
|
|
307
|
+
}
|
|
308
|
+
function parseTeethSelection(input) {
|
|
309
|
+
const selectedTeeth = [];
|
|
310
|
+
const bridges = [];
|
|
311
|
+
const regex = /\[(\d+)\s*,\s*(\d+)\]|(\d+)/g;
|
|
312
|
+
let match;
|
|
313
|
+
while ((match = regex.exec(input)) !== null) {
|
|
314
|
+
if (match[1] && match[2]) {
|
|
315
|
+
let start = Number(match[1]);
|
|
316
|
+
let end = Number(match[2]);
|
|
317
|
+
[start, end] = [Math.min(start, end), Math.max(start, end)];
|
|
318
|
+
const range = [];
|
|
319
|
+
if (sameSide(start, end)) {
|
|
320
|
+
for (let i = start;i <= end; i++) {
|
|
321
|
+
range.push(i);
|
|
322
|
+
}
|
|
323
|
+
} else {
|
|
324
|
+
const crossA = Number(`${start.toString()[0]}1`);
|
|
325
|
+
const crossB = Number(`${end.toString()[0]}1`);
|
|
326
|
+
for (let i = start;i >= crossA; i--) {
|
|
327
|
+
range.push(i);
|
|
328
|
+
}
|
|
329
|
+
for (let i = crossB;i <= end; i++) {
|
|
330
|
+
range.push(i);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
selectedTeeth.push(...range);
|
|
334
|
+
for (let i = 0;i < range.length - 1; i++) {
|
|
335
|
+
bridges.push([range[i], range[i + 1]]);
|
|
336
|
+
}
|
|
337
|
+
} else if (match[3]) {
|
|
338
|
+
selectedTeeth.push(Number(match[3]));
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return { selectedTeeth, bridges };
|
|
342
|
+
}
|
|
343
|
+
function formatTeethSelection(selectedTeeth, bridges) {
|
|
344
|
+
if (!selectedTeeth || selectedTeeth.length === 0) {
|
|
345
|
+
return "";
|
|
346
|
+
}
|
|
347
|
+
const bridgeMap = new Map;
|
|
348
|
+
bridges.forEach(([tooth1, tooth2]) => {
|
|
349
|
+
if (!bridgeMap.has(tooth1))
|
|
350
|
+
bridgeMap.set(tooth1, []);
|
|
351
|
+
if (!bridgeMap.has(tooth2))
|
|
352
|
+
bridgeMap.set(tooth2, []);
|
|
353
|
+
bridgeMap.get(tooth1).push(tooth2);
|
|
354
|
+
bridgeMap.get(tooth2).push(tooth1);
|
|
355
|
+
});
|
|
356
|
+
const result = [];
|
|
357
|
+
let currentGroup = [];
|
|
358
|
+
selectedTeeth.forEach((tooth, index) => {
|
|
359
|
+
if (index === 0) {
|
|
360
|
+
currentGroup.push(tooth);
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const prevTooth = selectedTeeth[index - 1];
|
|
364
|
+
const hasBridge = bridgeMap.has(prevTooth) && bridgeMap.get(prevTooth).includes(tooth) && Math.abs(selectedTeeth.indexOf(tooth) - selectedTeeth.indexOf(prevTooth)) === 1;
|
|
365
|
+
if (hasBridge) {
|
|
366
|
+
currentGroup.push(tooth);
|
|
367
|
+
} else {
|
|
368
|
+
if (currentGroup.length > 0) {
|
|
369
|
+
if (currentGroup.length === 1) {
|
|
370
|
+
result.push(`${currentGroup[0]}`);
|
|
371
|
+
} else {
|
|
372
|
+
result.push(`[${currentGroup[0]}, ${currentGroup[currentGroup.length - 1]}]`);
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
currentGroup = [tooth];
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
if (currentGroup.length > 0) {
|
|
379
|
+
if (currentGroup.length === 1) {
|
|
380
|
+
result.push(`${currentGroup[0]}`);
|
|
381
|
+
} else {
|
|
382
|
+
result.push(`[${currentGroup[0]}, ${currentGroup[currentGroup.length - 1]}]`);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
return result.join(", ");
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// src/components/teeth-selector.tsx
|
|
389
|
+
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
390
|
+
"use client";
|
|
391
|
+
var initialState = {
|
|
392
|
+
selectedTeeth: [],
|
|
393
|
+
bridges: []
|
|
394
|
+
};
|
|
395
|
+
function selectionReducer(state, action) {
|
|
396
|
+
switch (action.type) {
|
|
397
|
+
case "toggle-tooth": {
|
|
398
|
+
const exists = state.selectedTeeth.includes(action.toothId);
|
|
399
|
+
const selectedTeeth = exists ? state.selectedTeeth.filter((id) => id !== action.toothId) : [...state.selectedTeeth, action.toothId];
|
|
400
|
+
const bridges = exists ? state.bridges.filter(([a, b]) => a !== action.toothId && b !== action.toothId) : state.bridges;
|
|
401
|
+
return { selectedTeeth, bridges };
|
|
402
|
+
}
|
|
403
|
+
case "select-range": {
|
|
404
|
+
const selectedTeeth = Array.from(new Set([...state.selectedTeeth, ...action.teethIds]));
|
|
405
|
+
const consecutivePairs = [];
|
|
406
|
+
for (let i = 0;i < action.teethIds.length - 1; i++) {
|
|
407
|
+
consecutivePairs.push([action.teethIds[i], action.teethIds[i + 1]]);
|
|
408
|
+
}
|
|
409
|
+
const existing = new Set(state.bridges.map((b) => `${Math.min(...b)}-${Math.max(...b)}`));
|
|
410
|
+
const newBridges = consecutivePairs.filter(([a, b]) => adjacentTeethPairs.some(([x, y]) => x === a && y === b || x === b && y === a)).map((pair) => [Math.min(...pair), Math.max(...pair)]).filter((pair) => {
|
|
411
|
+
const key = `${pair[0]}-${pair[1]}`;
|
|
412
|
+
return !existing.has(key);
|
|
413
|
+
});
|
|
414
|
+
return {
|
|
415
|
+
selectedTeeth,
|
|
416
|
+
bridges: [...state.bridges, ...newBridges]
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
case "select-upper": {
|
|
420
|
+
const upper = teethData.filter((t) => t.position === "upper").map((t) => t.id);
|
|
421
|
+
return selectionReducer(state, { type: "select-range", teethIds: upper });
|
|
422
|
+
}
|
|
423
|
+
case "select-lower": {
|
|
424
|
+
const lower = teethData.filter((t) => t.position === "lower").map((t) => t.id);
|
|
425
|
+
return selectionReducer(state, { type: "select-range", teethIds: lower });
|
|
426
|
+
}
|
|
427
|
+
case "clear-all":
|
|
428
|
+
return initialState;
|
|
429
|
+
case "toggle-bridge": {
|
|
430
|
+
const { fromId, toId } = action;
|
|
431
|
+
if (!state.selectedTeeth.includes(fromId) || !state.selectedTeeth.includes(toId)) {
|
|
432
|
+
return {
|
|
433
|
+
selectedTeeth: [...state.selectedTeeth, fromId, toId],
|
|
434
|
+
bridges: [
|
|
435
|
+
...state.bridges,
|
|
436
|
+
[Math.min(fromId, toId), Math.max(fromId, toId)]
|
|
437
|
+
]
|
|
438
|
+
};
|
|
439
|
+
}
|
|
440
|
+
const key = (a, b) => `${Math.min(a, b)}-${Math.max(a, b)}`;
|
|
441
|
+
const exists = state.bridges.some(([a, b]) => key(a, b) === key(fromId, toId));
|
|
442
|
+
const bridges = exists ? state.bridges.filter(([a, b]) => key(a, b) !== key(fromId, toId)) : [...state.bridges, [Math.min(fromId, toId), Math.max(fromId, toId)]];
|
|
443
|
+
return { ...state, bridges };
|
|
444
|
+
}
|
|
445
|
+
case "set":
|
|
446
|
+
return action.state;
|
|
447
|
+
default:
|
|
448
|
+
return state;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
var TeethSelectorContext = React.createContext(null);
|
|
452
|
+
function useTeethSelectorContext() {
|
|
453
|
+
const context = React.useContext(TeethSelectorContext);
|
|
454
|
+
if (!context) {
|
|
455
|
+
throw new Error("useTeethSelectorContext must be used within a TeethSelector");
|
|
456
|
+
}
|
|
457
|
+
return context;
|
|
458
|
+
}
|
|
459
|
+
var initialDragState = {
|
|
460
|
+
start: null,
|
|
461
|
+
current: null,
|
|
462
|
+
teethInRange: []
|
|
463
|
+
};
|
|
464
|
+
var TeethSelector = React.forwardRef((props, ref) => {
|
|
465
|
+
const {
|
|
466
|
+
defaultSelectedTeeth = [],
|
|
467
|
+
defaultBridges = [],
|
|
468
|
+
selectedTeeth: controlledSelectedTeeth,
|
|
469
|
+
bridges: controlledBridges,
|
|
470
|
+
onSelectionChange,
|
|
471
|
+
onBridgeChange,
|
|
472
|
+
onChange,
|
|
473
|
+
children
|
|
474
|
+
} = props;
|
|
475
|
+
const isControlled = controlledSelectedTeeth !== undefined || controlledBridges !== undefined;
|
|
476
|
+
const [internalState, dispatch] = React.useReducer(selectionReducer, {
|
|
477
|
+
selectedTeeth: defaultSelectedTeeth,
|
|
478
|
+
bridges: defaultBridges
|
|
479
|
+
});
|
|
480
|
+
const [dragState, setDragState] = React.useState(initialDragState);
|
|
481
|
+
const state = isControlled ? {
|
|
482
|
+
selectedTeeth: controlledSelectedTeeth ?? internalState.selectedTeeth,
|
|
483
|
+
bridges: controlledBridges ?? internalState.bridges
|
|
484
|
+
} : internalState;
|
|
485
|
+
const prevStateRef = React.useRef(state);
|
|
486
|
+
React.useEffect(() => {
|
|
487
|
+
if (prevStateRef.current.selectedTeeth !== state.selectedTeeth || prevStateRef.current.bridges !== state.bridges) {
|
|
488
|
+
const sorted = teethData.filter((t) => state.selectedTeeth.includes(t.id)).sort((a, b) => a.order - b.order);
|
|
489
|
+
onSelectionChange?.(sorted);
|
|
490
|
+
onBridgeChange?.(state.bridges);
|
|
491
|
+
onChange?.(sorted, state.bridges);
|
|
492
|
+
prevStateRef.current = state;
|
|
493
|
+
}
|
|
494
|
+
}, [state, onSelectionChange, onBridgeChange, onChange]);
|
|
495
|
+
const toggleTooth = React.useCallback((toothId) => {
|
|
496
|
+
dispatch({ type: "toggle-tooth", toothId });
|
|
497
|
+
}, []);
|
|
498
|
+
const toggleBridge = React.useCallback((fromId, toId) => {
|
|
499
|
+
dispatch({ type: "toggle-bridge", fromId, toId });
|
|
500
|
+
}, []);
|
|
501
|
+
const selectUpper = React.useCallback(() => {
|
|
502
|
+
dispatch({ type: "select-upper" });
|
|
503
|
+
}, []);
|
|
504
|
+
const selectLower = React.useCallback(() => {
|
|
505
|
+
dispatch({ type: "select-lower" });
|
|
506
|
+
}, []);
|
|
507
|
+
const selectRange = React.useCallback((teethIds) => {
|
|
508
|
+
dispatch({ type: "select-range", teethIds });
|
|
509
|
+
}, []);
|
|
510
|
+
const clearAll = React.useCallback(() => {
|
|
511
|
+
dispatch({ type: "clear-all" });
|
|
512
|
+
}, []);
|
|
513
|
+
const isSelected = React.useCallback((toothId) => state.selectedTeeth.includes(toothId), [state.selectedTeeth]);
|
|
514
|
+
const hasBridge = React.useCallback((fromId, toId) => {
|
|
515
|
+
const key = (a, b) => `${Math.min(a, b)}-${Math.max(a, b)}`;
|
|
516
|
+
return state.bridges.some(([a, b]) => key(a, b) === key(fromId, toId));
|
|
517
|
+
}, [state.bridges]);
|
|
518
|
+
const getSelectedTeethData = React.useCallback(() => teethData.filter((t) => state.selectedTeeth.includes(t.id)).sort((a, b) => a.order - b.order), [state.selectedTeeth]);
|
|
519
|
+
const renderProps = {
|
|
520
|
+
...state,
|
|
521
|
+
toggleTooth,
|
|
522
|
+
toggleBridge,
|
|
523
|
+
selectUpper,
|
|
524
|
+
selectLower,
|
|
525
|
+
selectRange,
|
|
526
|
+
clearAll,
|
|
527
|
+
isSelected,
|
|
528
|
+
hasBridge,
|
|
529
|
+
getSelectedTeethData
|
|
530
|
+
};
|
|
531
|
+
return /* @__PURE__ */ jsxDEV(TeethSelectorContext.Provider, {
|
|
532
|
+
value: { state, dispatch, dragState, setDragState },
|
|
533
|
+
children: /* @__PURE__ */ jsxDEV("div", {
|
|
534
|
+
ref,
|
|
535
|
+
children: children(renderProps)
|
|
536
|
+
}, undefined, false, undefined, this)
|
|
537
|
+
}, undefined, false, undefined, this);
|
|
538
|
+
});
|
|
539
|
+
TeethSelector.displayName = "TeethSelector";
|
|
540
|
+
var TeethChart = React.forwardRef((props, ref) => {
|
|
541
|
+
const {
|
|
542
|
+
width = 300,
|
|
543
|
+
height = 500,
|
|
544
|
+
className,
|
|
545
|
+
renderTooth,
|
|
546
|
+
renderBridge,
|
|
547
|
+
enableDragSelection = true
|
|
548
|
+
} = props;
|
|
549
|
+
const { state, dispatch, dragState, setDragState } = useTeethSelectorContext();
|
|
550
|
+
const svgRef = React.useRef(null);
|
|
551
|
+
const toothRefs = React.useRef(new Map);
|
|
552
|
+
const holdRef = React.useRef(null);
|
|
553
|
+
React.useImperativeHandle(ref, () => svgRef.current);
|
|
554
|
+
React.useEffect(() => {
|
|
555
|
+
if (!svgRef.current)
|
|
556
|
+
return;
|
|
557
|
+
const map = new Map;
|
|
558
|
+
teethData.forEach(({ id }) => {
|
|
559
|
+
map.set(id, svgRef.current.querySelector(`#teeth-${id}`));
|
|
560
|
+
});
|
|
561
|
+
toothRefs.current = map;
|
|
562
|
+
}, []);
|
|
563
|
+
const getBridgePos = React.useCallback((a, b) => {
|
|
564
|
+
const from = toothRefs.current.get(a);
|
|
565
|
+
const to = toothRefs.current.get(b);
|
|
566
|
+
if (!from || !to)
|
|
567
|
+
return null;
|
|
568
|
+
const boxA = from.getBBox();
|
|
569
|
+
const boxB = to.getBBox();
|
|
570
|
+
const x1 = boxA.x + boxA.width / 2;
|
|
571
|
+
const y1 = boxA.y + boxA.height / 2;
|
|
572
|
+
const x2 = boxB.x + boxB.width / 2;
|
|
573
|
+
const y2 = boxB.y + boxB.height / 2;
|
|
574
|
+
return { x1, y1, x2, y2, midX: (x1 + x2) / 2, midY: (y1 + y2) / 2 };
|
|
575
|
+
}, []);
|
|
576
|
+
const handleClick = React.useCallback((id) => {
|
|
577
|
+
if (holdRef.current)
|
|
578
|
+
clearTimeout(holdRef.current);
|
|
579
|
+
dispatch({ type: "toggle-tooth", toothId: id });
|
|
580
|
+
}, [dispatch]);
|
|
581
|
+
const handleDown = React.useCallback((id) => {
|
|
582
|
+
if (!enableDragSelection)
|
|
583
|
+
return;
|
|
584
|
+
holdRef.current = setTimeout(() => {
|
|
585
|
+
setDragState({
|
|
586
|
+
start: id,
|
|
587
|
+
current: id,
|
|
588
|
+
teethInRange: [id]
|
|
589
|
+
});
|
|
590
|
+
}, 100);
|
|
591
|
+
}, [enableDragSelection, setDragState]);
|
|
592
|
+
const handleEnter = React.useCallback((id) => {
|
|
593
|
+
if (dragState.start === null)
|
|
594
|
+
return;
|
|
595
|
+
if (holdRef.current)
|
|
596
|
+
clearTimeout(holdRef.current);
|
|
597
|
+
const range = getTeethInRange(dragState.start, id);
|
|
598
|
+
setDragState((prev) => ({
|
|
599
|
+
...prev,
|
|
600
|
+
current: id,
|
|
601
|
+
teethInRange: range
|
|
602
|
+
}));
|
|
603
|
+
}, [dragState.start, setDragState]);
|
|
604
|
+
const handleUp = React.useCallback(() => {
|
|
605
|
+
if (dragState.start === null)
|
|
606
|
+
return;
|
|
607
|
+
if (holdRef.current)
|
|
608
|
+
clearTimeout(holdRef.current);
|
|
609
|
+
if (dragState.teethInRange.length > 1) {
|
|
610
|
+
dispatch({ type: "select-range", teethIds: dragState.teethInRange });
|
|
611
|
+
}
|
|
612
|
+
setDragState(initialDragState);
|
|
613
|
+
}, [dragState, dispatch, setDragState]);
|
|
614
|
+
const handleTouchMove = React.useCallback((e) => {
|
|
615
|
+
if (!enableDragSelection)
|
|
616
|
+
return;
|
|
617
|
+
const touch = e.touches[0];
|
|
618
|
+
const element = document.elementFromPoint(touch.clientX, touch.clientY);
|
|
619
|
+
if (element?.id?.startsWith("teeth-")) {
|
|
620
|
+
const toothId = parseInt(element.id.replace("teeth-", ""), 10);
|
|
621
|
+
if (dragState.start === null) {
|
|
622
|
+
setDragState({
|
|
623
|
+
start: toothId,
|
|
624
|
+
current: toothId,
|
|
625
|
+
teethInRange: [toothId]
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
handleEnter(toothId);
|
|
629
|
+
}
|
|
630
|
+
}, [enableDragSelection, dragState.start, handleEnter, setDragState]);
|
|
631
|
+
return /* @__PURE__ */ jsxDEV("svg", {
|
|
632
|
+
ref: svgRef,
|
|
633
|
+
viewBox: "0 0 450 750",
|
|
634
|
+
width,
|
|
635
|
+
height,
|
|
636
|
+
className,
|
|
637
|
+
style: { touchAction: "none" },
|
|
638
|
+
onMouseUp: handleUp,
|
|
639
|
+
onTouchMove: handleTouchMove,
|
|
640
|
+
onTouchEnd: handleUp,
|
|
641
|
+
children: [
|
|
642
|
+
teethData.map((tooth) => {
|
|
643
|
+
const isSelected = state.selectedTeeth.includes(tooth.id);
|
|
644
|
+
const isInDragRange = dragState.teethInRange.includes(tooth.id);
|
|
645
|
+
const defaultElement = /* @__PURE__ */ jsxDEV("path", {
|
|
646
|
+
id: `teeth-${tooth.id}`,
|
|
647
|
+
d: tooth.d,
|
|
648
|
+
"data-selected": isSelected,
|
|
649
|
+
"data-in-range": isInDragRange,
|
|
650
|
+
onClick: () => handleClick(tooth.id),
|
|
651
|
+
onMouseDown: () => handleDown(tooth.id),
|
|
652
|
+
onMouseEnter: () => handleEnter(tooth.id)
|
|
653
|
+
}, tooth.id, false, undefined, this);
|
|
654
|
+
if (renderTooth) {
|
|
655
|
+
return renderTooth({ tooth, isSelected, isInDragRange }, defaultElement);
|
|
656
|
+
}
|
|
657
|
+
return defaultElement;
|
|
658
|
+
}),
|
|
659
|
+
/* @__PURE__ */ jsxDEV("g", {
|
|
660
|
+
"data-bridges": true,
|
|
661
|
+
children: adjacentTeethPairs.map((pair, i) => {
|
|
662
|
+
const pos = getBridgePos(pair[0], pair[1]);
|
|
663
|
+
if (!pos)
|
|
664
|
+
return null;
|
|
665
|
+
const exists = state.bridges.some(([a, b]) => a === pair[0] && b === pair[1] || a === pair[1] && b === pair[0]);
|
|
666
|
+
const defaultElement = /* @__PURE__ */ jsxDEV("g", {
|
|
667
|
+
children: [
|
|
668
|
+
exists && /* @__PURE__ */ jsxDEV("line", {
|
|
669
|
+
x1: pos.x1,
|
|
670
|
+
y1: pos.y1,
|
|
671
|
+
x2: pos.x2,
|
|
672
|
+
y2: pos.y2,
|
|
673
|
+
"data-bridge-line": true
|
|
674
|
+
}, undefined, false, undefined, this),
|
|
675
|
+
/* @__PURE__ */ jsxDEV("circle", {
|
|
676
|
+
cx: pos.midX,
|
|
677
|
+
cy: pos.midY,
|
|
678
|
+
r: 8,
|
|
679
|
+
"data-bridge-button": true,
|
|
680
|
+
"data-exists": exists,
|
|
681
|
+
onClick: () => dispatch({
|
|
682
|
+
type: "toggle-bridge",
|
|
683
|
+
fromId: pair[0],
|
|
684
|
+
toId: pair[1]
|
|
685
|
+
})
|
|
686
|
+
}, undefined, false, undefined, this)
|
|
687
|
+
]
|
|
688
|
+
}, i, true, undefined, this);
|
|
689
|
+
if (renderBridge) {
|
|
690
|
+
return renderBridge({ fromId: pair[0], toId: pair[1], exists, position: pos }, defaultElement);
|
|
691
|
+
}
|
|
692
|
+
return defaultElement;
|
|
693
|
+
})
|
|
694
|
+
}, undefined, false, undefined, this)
|
|
695
|
+
]
|
|
696
|
+
}, undefined, true, undefined, this);
|
|
697
|
+
});
|
|
698
|
+
TeethChart.displayName = "TeethChart";
|
|
699
|
+
// src/components/teeth-preview.tsx
|
|
700
|
+
import * as React2 from "react";
|
|
701
|
+
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
702
|
+
"use client";
|
|
703
|
+
var TeethPreview = React2.forwardRef((props, ref) => {
|
|
704
|
+
const {
|
|
705
|
+
teeth,
|
|
706
|
+
width = 150,
|
|
707
|
+
height = 250,
|
|
708
|
+
className,
|
|
709
|
+
renderTooth,
|
|
710
|
+
renderBridge
|
|
711
|
+
} = props;
|
|
712
|
+
const [refsReady, setRefsReady] = React2.useState(false);
|
|
713
|
+
const svgRef = React2.useRef(null);
|
|
714
|
+
const toothRefs = React2.useRef(new Map);
|
|
715
|
+
const { selectedTeeth, bridges } = React2.useMemo(() => parseTeethSelection(teeth), [teeth]);
|
|
716
|
+
React2.useImperativeHandle(ref, () => svgRef.current);
|
|
717
|
+
const getBridgePos = React2.useCallback((a, b) => {
|
|
718
|
+
const from = toothRefs.current.get(a);
|
|
719
|
+
const to = toothRefs.current.get(b);
|
|
720
|
+
if (!from || !to)
|
|
721
|
+
return null;
|
|
722
|
+
const boxA = from.getBBox();
|
|
723
|
+
const boxB = to.getBBox();
|
|
724
|
+
const x1 = boxA.x + boxA.width / 2;
|
|
725
|
+
const y1 = boxA.y + boxA.height / 2;
|
|
726
|
+
const x2 = boxB.x + boxB.width / 2;
|
|
727
|
+
const y2 = boxB.y + boxB.height / 2;
|
|
728
|
+
return { x1, y1, x2, y2, midX: (x1 + x2) / 2, midY: (y1 + y2) / 2 };
|
|
729
|
+
}, []);
|
|
730
|
+
React2.useLayoutEffect(() => {
|
|
731
|
+
if (!svgRef.current)
|
|
732
|
+
return;
|
|
733
|
+
const map = new Map;
|
|
734
|
+
teethData.forEach(({ id }) => {
|
|
735
|
+
map.set(id, svgRef.current.querySelector(`#teeth-preview-${id}`));
|
|
736
|
+
});
|
|
737
|
+
toothRefs.current = map;
|
|
738
|
+
setRefsReady(true);
|
|
739
|
+
}, []);
|
|
740
|
+
return /* @__PURE__ */ jsxDEV2("svg", {
|
|
741
|
+
ref: svgRef,
|
|
742
|
+
viewBox: "0 0 450 750",
|
|
743
|
+
width,
|
|
744
|
+
height,
|
|
745
|
+
className,
|
|
746
|
+
children: [
|
|
747
|
+
teethData.map((tooth) => {
|
|
748
|
+
const isSelected = selectedTeeth.includes(tooth.id);
|
|
749
|
+
const defaultElement = /* @__PURE__ */ jsxDEV2("path", {
|
|
750
|
+
id: `teeth-preview-${tooth.id}`,
|
|
751
|
+
d: tooth.d,
|
|
752
|
+
"data-selected": isSelected
|
|
753
|
+
}, tooth.id, false, undefined, this);
|
|
754
|
+
if (renderTooth) {
|
|
755
|
+
return renderTooth({ tooth, isSelected }, defaultElement);
|
|
756
|
+
}
|
|
757
|
+
return defaultElement;
|
|
758
|
+
}),
|
|
759
|
+
/* @__PURE__ */ jsxDEV2("g", {
|
|
760
|
+
"data-bridges": true,
|
|
761
|
+
children: refsReady && bridges.map((pair, i) => {
|
|
762
|
+
const pos = getBridgePos(pair[0], pair[1]);
|
|
763
|
+
if (!pos)
|
|
764
|
+
return null;
|
|
765
|
+
const defaultElement = /* @__PURE__ */ jsxDEV2("g", {
|
|
766
|
+
children: [
|
|
767
|
+
/* @__PURE__ */ jsxDEV2("line", {
|
|
768
|
+
x1: pos.x1,
|
|
769
|
+
y1: pos.y1,
|
|
770
|
+
x2: pos.x2,
|
|
771
|
+
y2: pos.y2,
|
|
772
|
+
"data-bridge-line": true
|
|
773
|
+
}, undefined, false, undefined, this),
|
|
774
|
+
/* @__PURE__ */ jsxDEV2("circle", {
|
|
775
|
+
cx: pos.midX,
|
|
776
|
+
cy: pos.midY,
|
|
777
|
+
r: 8,
|
|
778
|
+
"data-bridge-marker": true
|
|
779
|
+
}, undefined, false, undefined, this)
|
|
780
|
+
]
|
|
781
|
+
}, i, true, undefined, this);
|
|
782
|
+
if (renderBridge) {
|
|
783
|
+
return renderBridge({ fromId: pair[0], toId: pair[1], position: pos }, defaultElement);
|
|
784
|
+
}
|
|
785
|
+
return defaultElement;
|
|
786
|
+
})
|
|
787
|
+
}, undefined, false, undefined, this)
|
|
788
|
+
]
|
|
789
|
+
}, undefined, true, undefined, this);
|
|
790
|
+
});
|
|
791
|
+
TeethPreview.displayName = "TeethPreview";
|
|
792
|
+
export {
|
|
793
|
+
useTeethSelectorContext,
|
|
794
|
+
TeethSelector,
|
|
795
|
+
TeethPreview,
|
|
796
|
+
TeethChart
|
|
797
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salloomd/teeth-selector",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -10,6 +10,16 @@
|
|
|
10
10
|
"types": "./dist/index.d.ts",
|
|
11
11
|
"import": "./dist/index.js",
|
|
12
12
|
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./ui": {
|
|
15
|
+
"types": "./dist/ui.d.ts",
|
|
16
|
+
"import": "./dist/ui.js",
|
|
17
|
+
"default": "./dist/ui.js"
|
|
18
|
+
},
|
|
19
|
+
"./lib": {
|
|
20
|
+
"types": "./dist/lib.d.ts",
|
|
21
|
+
"import": "./dist/lib.js",
|
|
22
|
+
"default": "./dist/lib.js"
|
|
13
23
|
}
|
|
14
24
|
},
|
|
15
25
|
"files": [
|
|
@@ -17,7 +27,7 @@
|
|
|
17
27
|
],
|
|
18
28
|
"sideEffects": false,
|
|
19
29
|
"scripts": {
|
|
20
|
-
"build": "bun build src/index.ts --outdir dist --external react --external react-dom && tsc -p tsconfig.build.json",
|
|
30
|
+
"build": "bun build src/index.ts src/ui.ts src/lib.ts --outdir dist --external react --external react-dom && tsc -p tsconfig.build.json",
|
|
21
31
|
"storybook": "storybook dev -p 6006",
|
|
22
32
|
"build-storybook": "storybook build"
|
|
23
33
|
},
|