diff --git "a/src/backend/gradio_cofoldinginput/templates/component/index.js" "b/src/backend/gradio_cofoldinginput/templates/component/index.js"
new file mode 100644--- /dev/null
+++ "b/src/backend/gradio_cofoldinginput/templates/component/index.js"
@@ -0,0 +1,29316 @@
+const Block_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$f,
+ assign: assign$1,
+ create_slot: create_slot$3,
+ detach: detach$f,
+ element: element$c,
+ get_all_dirty_from_scope: get_all_dirty_from_scope$3,
+ get_slot_changes: get_slot_changes$3,
+ get_spread_update: get_spread_update$1,
+ init: init$f,
+ insert: insert$f,
+ safe_not_equal: safe_not_equal$g,
+ set_dynamic_element_data,
+ set_style: set_style$3,
+ toggle_class: toggle_class$7,
+ transition_in: transition_in$7,
+ transition_out: transition_out$7,
+ update_slot_base: update_slot_base$3
+} = window.__gradio__svelte__internal;
+function create_dynamic_element(y) {
+ let s, e, l;
+ const g = (
+ /*#slots*/
+ y[18].default
+ ), _ = create_slot$3(
+ g,
+ y,
+ /*$$scope*/
+ y[17],
+ null
+ );
+ let x = [
+ { "data-testid": (
+ /*test_id*/
+ y[7]
+ ) },
+ { id: (
+ /*elem_id*/
+ y[2]
+ ) },
+ {
+ class: e = "block " + /*elem_classes*/
+ y[3].join(" ") + " svelte-1t38q2d"
+ }
+ ], o = {};
+ for (let p = 0; p < x.length; p += 1)
+ o = assign$1(o, x[p]);
+ return {
+ c() {
+ s = element$c(
+ /*tag*/
+ y[14]
+ ), _ && _.c(), set_dynamic_element_data(
+ /*tag*/
+ y[14]
+ )(s, o), toggle_class$7(
+ s,
+ "hidden",
+ /*visible*/
+ y[10] === !1
+ ), toggle_class$7(
+ s,
+ "padded",
+ /*padding*/
+ y[6]
+ ), toggle_class$7(
+ s,
+ "border_focus",
+ /*border_mode*/
+ y[5] === "focus"
+ ), toggle_class$7(s, "hide-container", !/*explicit_call*/
+ y[8] && !/*container*/
+ y[9]), set_style$3(
+ s,
+ "height",
+ /*get_dimension*/
+ y[15](
+ /*height*/
+ y[0]
+ )
+ ), set_style$3(s, "width", typeof /*width*/
+ y[1] == "number" ? `calc(min(${/*width*/
+ y[1]}px, 100%))` : (
+ /*get_dimension*/
+ y[15](
+ /*width*/
+ y[1]
+ )
+ )), set_style$3(
+ s,
+ "border-style",
+ /*variant*/
+ y[4]
+ ), set_style$3(
+ s,
+ "overflow",
+ /*allow_overflow*/
+ y[11] ? "visible" : "hidden"
+ ), set_style$3(
+ s,
+ "flex-grow",
+ /*scale*/
+ y[12]
+ ), set_style$3(s, "min-width", `calc(min(${/*min_width*/
+ y[13]}px, 100%))`), set_style$3(s, "border-width", "var(--block-border-width)");
+ },
+ m(p, E) {
+ insert$f(p, s, E), _ && _.m(s, null), l = !0;
+ },
+ p(p, E) {
+ _ && _.p && (!l || E & /*$$scope*/
+ 131072) && update_slot_base$3(
+ _,
+ g,
+ p,
+ /*$$scope*/
+ p[17],
+ l ? get_slot_changes$3(
+ g,
+ /*$$scope*/
+ p[17],
+ E,
+ null
+ ) : get_all_dirty_from_scope$3(
+ /*$$scope*/
+ p[17]
+ ),
+ null
+ ), set_dynamic_element_data(
+ /*tag*/
+ p[14]
+ )(s, o = get_spread_update$1(x, [
+ (!l || E & /*test_id*/
+ 128) && { "data-testid": (
+ /*test_id*/
+ p[7]
+ ) },
+ (!l || E & /*elem_id*/
+ 4) && { id: (
+ /*elem_id*/
+ p[2]
+ ) },
+ (!l || E & /*elem_classes*/
+ 8 && e !== (e = "block " + /*elem_classes*/
+ p[3].join(" ") + " svelte-1t38q2d")) && { class: e }
+ ])), toggle_class$7(
+ s,
+ "hidden",
+ /*visible*/
+ p[10] === !1
+ ), toggle_class$7(
+ s,
+ "padded",
+ /*padding*/
+ p[6]
+ ), toggle_class$7(
+ s,
+ "border_focus",
+ /*border_mode*/
+ p[5] === "focus"
+ ), toggle_class$7(s, "hide-container", !/*explicit_call*/
+ p[8] && !/*container*/
+ p[9]), E & /*height*/
+ 1 && set_style$3(
+ s,
+ "height",
+ /*get_dimension*/
+ p[15](
+ /*height*/
+ p[0]
+ )
+ ), E & /*width*/
+ 2 && set_style$3(s, "width", typeof /*width*/
+ p[1] == "number" ? `calc(min(${/*width*/
+ p[1]}px, 100%))` : (
+ /*get_dimension*/
+ p[15](
+ /*width*/
+ p[1]
+ )
+ )), E & /*variant*/
+ 16 && set_style$3(
+ s,
+ "border-style",
+ /*variant*/
+ p[4]
+ ), E & /*allow_overflow*/
+ 2048 && set_style$3(
+ s,
+ "overflow",
+ /*allow_overflow*/
+ p[11] ? "visible" : "hidden"
+ ), E & /*scale*/
+ 4096 && set_style$3(
+ s,
+ "flex-grow",
+ /*scale*/
+ p[12]
+ ), E & /*min_width*/
+ 8192 && set_style$3(s, "min-width", `calc(min(${/*min_width*/
+ p[13]}px, 100%))`);
+ },
+ i(p) {
+ l || (transition_in$7(_, p), l = !0);
+ },
+ o(p) {
+ transition_out$7(_, p), l = !1;
+ },
+ d(p) {
+ p && detach$f(s), _ && _.d(p);
+ }
+ };
+}
+function create_fragment$f(y) {
+ let s, e = (
+ /*tag*/
+ y[14] && create_dynamic_element(y)
+ );
+ return {
+ c() {
+ e && e.c();
+ },
+ m(l, g) {
+ e && e.m(l, g), s = !0;
+ },
+ p(l, [g]) {
+ /*tag*/
+ l[14] && e.p(l, g);
+ },
+ i(l) {
+ s || (transition_in$7(e, l), s = !0);
+ },
+ o(l) {
+ transition_out$7(e, l), s = !1;
+ },
+ d(l) {
+ e && e.d(l);
+ }
+ };
+}
+function instance$d(y, s, e) {
+ let { $$slots: l = {}, $$scope: g } = s, { height: _ = void 0 } = s, { width: x = void 0 } = s, { elem_id: o = "" } = s, { elem_classes: p = [] } = s, { variant: E = "solid" } = s, { border_mode: u = "base" } = s, { padding: A = !0 } = s, { type: C = "normal" } = s, { test_id: L = void 0 } = s, { explicit_call: D = !1 } = s, { container: r = !0 } = s, { visible: n = !0 } = s, { allow_overflow: b = !0 } = s, { scale: f = null } = s, { min_width: c = 0 } = s, t = C === "fieldset" ? "fieldset" : "div";
+ const a = (h) => {
+ if (h !== void 0) {
+ if (typeof h == "number")
+ return h + "px";
+ if (typeof h == "string")
+ return h;
+ }
+ };
+ return y.$$set = (h) => {
+ "height" in h && e(0, _ = h.height), "width" in h && e(1, x = h.width), "elem_id" in h && e(2, o = h.elem_id), "elem_classes" in h && e(3, p = h.elem_classes), "variant" in h && e(4, E = h.variant), "border_mode" in h && e(5, u = h.border_mode), "padding" in h && e(6, A = h.padding), "type" in h && e(16, C = h.type), "test_id" in h && e(7, L = h.test_id), "explicit_call" in h && e(8, D = h.explicit_call), "container" in h && e(9, r = h.container), "visible" in h && e(10, n = h.visible), "allow_overflow" in h && e(11, b = h.allow_overflow), "scale" in h && e(12, f = h.scale), "min_width" in h && e(13, c = h.min_width), "$$scope" in h && e(17, g = h.$$scope);
+ }, [
+ _,
+ x,
+ o,
+ p,
+ E,
+ u,
+ A,
+ L,
+ D,
+ r,
+ n,
+ b,
+ f,
+ c,
+ t,
+ a,
+ C,
+ g,
+ l
+ ];
+}
+class Block extends SvelteComponent$f {
+ constructor(s) {
+ super(), init$f(this, s, instance$d, create_fragment$f, safe_not_equal$g, {
+ height: 0,
+ width: 1,
+ elem_id: 2,
+ elem_classes: 3,
+ variant: 4,
+ border_mode: 5,
+ padding: 6,
+ type: 16,
+ test_id: 7,
+ explicit_call: 8,
+ container: 9,
+ visible: 10,
+ allow_overflow: 11,
+ scale: 12,
+ min_width: 13
+ });
+ }
+}
+const Info_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$e,
+ attr: attr$d,
+ create_slot: create_slot$2,
+ detach: detach$e,
+ element: element$b,
+ get_all_dirty_from_scope: get_all_dirty_from_scope$2,
+ get_slot_changes: get_slot_changes$2,
+ init: init$e,
+ insert: insert$e,
+ safe_not_equal: safe_not_equal$f,
+ transition_in: transition_in$6,
+ transition_out: transition_out$6,
+ update_slot_base: update_slot_base$2
+} = window.__gradio__svelte__internal;
+function create_fragment$e(y) {
+ let s, e;
+ const l = (
+ /*#slots*/
+ y[1].default
+ ), g = create_slot$2(
+ l,
+ y,
+ /*$$scope*/
+ y[0],
+ null
+ );
+ return {
+ c() {
+ s = element$b("div"), g && g.c(), attr$d(s, "class", "svelte-1hnfib2");
+ },
+ m(_, x) {
+ insert$e(_, s, x), g && g.m(s, null), e = !0;
+ },
+ p(_, [x]) {
+ g && g.p && (!e || x & /*$$scope*/
+ 1) && update_slot_base$2(
+ g,
+ l,
+ _,
+ /*$$scope*/
+ _[0],
+ e ? get_slot_changes$2(
+ l,
+ /*$$scope*/
+ _[0],
+ x,
+ null
+ ) : get_all_dirty_from_scope$2(
+ /*$$scope*/
+ _[0]
+ ),
+ null
+ );
+ },
+ i(_) {
+ e || (transition_in$6(g, _), e = !0);
+ },
+ o(_) {
+ transition_out$6(g, _), e = !1;
+ },
+ d(_) {
+ _ && detach$e(s), g && g.d(_);
+ }
+ };
+}
+function instance$c(y, s, e) {
+ let { $$slots: l = {}, $$scope: g } = s;
+ return y.$$set = (_) => {
+ "$$scope" in _ && e(0, g = _.$$scope);
+ }, [g, l];
+}
+class Info extends SvelteComponent$e {
+ constructor(s) {
+ super(), init$e(this, s, instance$c, create_fragment$e, safe_not_equal$f, {});
+ }
+}
+const BlockTitle_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$d,
+ attr: attr$c,
+ check_outros: check_outros$5,
+ create_component: create_component$5,
+ create_slot: create_slot$1,
+ destroy_component: destroy_component$5,
+ detach: detach$d,
+ element: element$a,
+ empty: empty$4,
+ get_all_dirty_from_scope: get_all_dirty_from_scope$1,
+ get_slot_changes: get_slot_changes$1,
+ group_outros: group_outros$5,
+ init: init$d,
+ insert: insert$d,
+ mount_component: mount_component$5,
+ safe_not_equal: safe_not_equal$e,
+ set_data: set_data$6,
+ space: space$9,
+ text: text$8,
+ toggle_class: toggle_class$6,
+ transition_in: transition_in$5,
+ transition_out: transition_out$5,
+ update_slot_base: update_slot_base$1
+} = window.__gradio__svelte__internal;
+function create_if_block$7(y) {
+ let s, e;
+ return s = new Info({
+ props: {
+ $$slots: { default: [create_default_slot$2] },
+ $$scope: { ctx: y }
+ }
+ }), {
+ c() {
+ create_component$5(s.$$.fragment);
+ },
+ m(l, g) {
+ mount_component$5(s, l, g), e = !0;
+ },
+ p(l, g) {
+ const _ = {};
+ g & /*$$scope, info*/
+ 10 && (_.$$scope = { dirty: g, ctx: l }), s.$set(_);
+ },
+ i(l) {
+ e || (transition_in$5(s.$$.fragment, l), e = !0);
+ },
+ o(l) {
+ transition_out$5(s.$$.fragment, l), e = !1;
+ },
+ d(l) {
+ destroy_component$5(s, l);
+ }
+ };
+}
+function create_default_slot$2(y) {
+ let s;
+ return {
+ c() {
+ s = text$8(
+ /*info*/
+ y[1]
+ );
+ },
+ m(e, l) {
+ insert$d(e, s, l);
+ },
+ p(e, l) {
+ l & /*info*/
+ 2 && set_data$6(
+ s,
+ /*info*/
+ e[1]
+ );
+ },
+ d(e) {
+ e && detach$d(s);
+ }
+ };
+}
+function create_fragment$d(y) {
+ let s, e, l, g;
+ const _ = (
+ /*#slots*/
+ y[2].default
+ ), x = create_slot$1(
+ _,
+ y,
+ /*$$scope*/
+ y[3],
+ null
+ );
+ let o = (
+ /*info*/
+ y[1] && create_if_block$7(y)
+ );
+ return {
+ c() {
+ s = element$a("span"), x && x.c(), e = space$9(), o && o.c(), l = empty$4(), attr$c(s, "data-testid", "block-info"), attr$c(s, "class", "svelte-22c38v"), toggle_class$6(s, "sr-only", !/*show_label*/
+ y[0]), toggle_class$6(s, "hide", !/*show_label*/
+ y[0]), toggle_class$6(
+ s,
+ "has-info",
+ /*info*/
+ y[1] != null
+ );
+ },
+ m(p, E) {
+ insert$d(p, s, E), x && x.m(s, null), insert$d(p, e, E), o && o.m(p, E), insert$d(p, l, E), g = !0;
+ },
+ p(p, [E]) {
+ x && x.p && (!g || E & /*$$scope*/
+ 8) && update_slot_base$1(
+ x,
+ _,
+ p,
+ /*$$scope*/
+ p[3],
+ g ? get_slot_changes$1(
+ _,
+ /*$$scope*/
+ p[3],
+ E,
+ null
+ ) : get_all_dirty_from_scope$1(
+ /*$$scope*/
+ p[3]
+ ),
+ null
+ ), (!g || E & /*show_label*/
+ 1) && toggle_class$6(s, "sr-only", !/*show_label*/
+ p[0]), (!g || E & /*show_label*/
+ 1) && toggle_class$6(s, "hide", !/*show_label*/
+ p[0]), (!g || E & /*info*/
+ 2) && toggle_class$6(
+ s,
+ "has-info",
+ /*info*/
+ p[1] != null
+ ), /*info*/
+ p[1] ? o ? (o.p(p, E), E & /*info*/
+ 2 && transition_in$5(o, 1)) : (o = create_if_block$7(p), o.c(), transition_in$5(o, 1), o.m(l.parentNode, l)) : o && (group_outros$5(), transition_out$5(o, 1, 1, () => {
+ o = null;
+ }), check_outros$5());
+ },
+ i(p) {
+ g || (transition_in$5(x, p), transition_in$5(o), g = !0);
+ },
+ o(p) {
+ transition_out$5(x, p), transition_out$5(o), g = !1;
+ },
+ d(p) {
+ p && (detach$d(s), detach$d(e), detach$d(l)), x && x.d(p), o && o.d(p);
+ }
+ };
+}
+function instance$b(y, s, e) {
+ let { $$slots: l = {}, $$scope: g } = s, { show_label: _ = !0 } = s, { info: x = void 0 } = s;
+ return y.$$set = (o) => {
+ "show_label" in o && e(0, _ = o.show_label), "info" in o && e(1, x = o.info), "$$scope" in o && e(3, g = o.$$scope);
+ }, [_, x, l, g];
+}
+class BlockTitle extends SvelteComponent$d {
+ constructor(s) {
+ super(), init$d(this, s, instance$b, create_fragment$d, safe_not_equal$e, { show_label: 0, info: 1 });
+ }
+}
+const BlockLabel_svelte_svelte_type_style_lang = "", IconButton_svelte_svelte_type_style_lang = "", Empty_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$c,
+ append: append$a,
+ attr: attr$b,
+ detach: detach$c,
+ init: init$c,
+ insert: insert$c,
+ noop: noop$c,
+ safe_not_equal: safe_not_equal$d,
+ svg_element: svg_element$3
+} = window.__gradio__svelte__internal;
+function create_fragment$c(y) {
+ let s, e;
+ return {
+ c() {
+ s = svg_element$3("svg"), e = svg_element$3("polyline"), attr$b(e, "points", "20 6 9 17 4 12"), attr$b(s, "xmlns", "http://www.w3.org/2000/svg"), attr$b(s, "viewBox", "2 0 20 20"), attr$b(s, "fill", "none"), attr$b(s, "stroke", "currentColor"), attr$b(s, "stroke-width", "3"), attr$b(s, "stroke-linecap", "round"), attr$b(s, "stroke-linejoin", "round");
+ },
+ m(l, g) {
+ insert$c(l, s, g), append$a(s, e);
+ },
+ p: noop$c,
+ i: noop$c,
+ o: noop$c,
+ d(l) {
+ l && detach$c(s);
+ }
+ };
+}
+class Check extends SvelteComponent$c {
+ constructor(s) {
+ super(), init$c(this, s, null, create_fragment$c, safe_not_equal$d, {});
+ }
+}
+const {
+ SvelteComponent: SvelteComponent$b,
+ append: append$9,
+ attr: attr$a,
+ detach: detach$b,
+ init: init$b,
+ insert: insert$b,
+ noop: noop$b,
+ safe_not_equal: safe_not_equal$c,
+ svg_element: svg_element$2
+} = window.__gradio__svelte__internal;
+function create_fragment$b(y) {
+ let s, e, l;
+ return {
+ c() {
+ s = svg_element$2("svg"), e = svg_element$2("path"), l = svg_element$2("path"), attr$a(e, "fill", "currentColor"), attr$a(e, "d", "M28 10v18H10V10h18m0-2H10a2 2 0 0 0-2 2v18a2 2 0 0 0 2 2h18a2 2 0 0 0 2-2V10a2 2 0 0 0-2-2Z"), attr$a(l, "fill", "currentColor"), attr$a(l, "d", "M4 18H2V4a2 2 0 0 1 2-2h14v2H4Z"), attr$a(s, "xmlns", "http://www.w3.org/2000/svg"), attr$a(s, "viewBox", "0 0 33 33"), attr$a(s, "color", "currentColor");
+ },
+ m(g, _) {
+ insert$b(g, s, _), append$9(s, e), append$9(s, l);
+ },
+ p: noop$b,
+ i: noop$b,
+ o: noop$b,
+ d(g) {
+ g && detach$b(s);
+ }
+ };
+}
+class Copy extends SvelteComponent$b {
+ constructor(s) {
+ super(), init$b(this, s, null, create_fragment$b, safe_not_equal$c, {});
+ }
+}
+const DropdownArrow_svelte_svelte_type_style_lang = "", color_values = [
+ { color: "red", primary: 600, secondary: 100 },
+ { color: "green", primary: 600, secondary: 100 },
+ { color: "blue", primary: 600, secondary: 100 },
+ { color: "yellow", primary: 500, secondary: 100 },
+ { color: "purple", primary: 600, secondary: 100 },
+ { color: "teal", primary: 600, secondary: 100 },
+ { color: "orange", primary: 600, secondary: 100 },
+ { color: "cyan", primary: 600, secondary: 100 },
+ { color: "lime", primary: 500, secondary: 100 },
+ { color: "pink", primary: 600, secondary: 100 }
+], tw_colors = {
+ inherit: "inherit",
+ current: "currentColor",
+ transparent: "transparent",
+ black: "#000",
+ white: "#fff",
+ slate: {
+ 50: "#f8fafc",
+ 100: "#f1f5f9",
+ 200: "#e2e8f0",
+ 300: "#cbd5e1",
+ 400: "#94a3b8",
+ 500: "#64748b",
+ 600: "#475569",
+ 700: "#334155",
+ 800: "#1e293b",
+ 900: "#0f172a",
+ 950: "#020617"
+ },
+ gray: {
+ 50: "#f9fafb",
+ 100: "#f3f4f6",
+ 200: "#e5e7eb",
+ 300: "#d1d5db",
+ 400: "#9ca3af",
+ 500: "#6b7280",
+ 600: "#4b5563",
+ 700: "#374151",
+ 800: "#1f2937",
+ 900: "#111827",
+ 950: "#030712"
+ },
+ zinc: {
+ 50: "#fafafa",
+ 100: "#f4f4f5",
+ 200: "#e4e4e7",
+ 300: "#d4d4d8",
+ 400: "#a1a1aa",
+ 500: "#71717a",
+ 600: "#52525b",
+ 700: "#3f3f46",
+ 800: "#27272a",
+ 900: "#18181b",
+ 950: "#09090b"
+ },
+ neutral: {
+ 50: "#fafafa",
+ 100: "#f5f5f5",
+ 200: "#e5e5e5",
+ 300: "#d4d4d4",
+ 400: "#a3a3a3",
+ 500: "#737373",
+ 600: "#525252",
+ 700: "#404040",
+ 800: "#262626",
+ 900: "#171717",
+ 950: "#0a0a0a"
+ },
+ stone: {
+ 50: "#fafaf9",
+ 100: "#f5f5f4",
+ 200: "#e7e5e4",
+ 300: "#d6d3d1",
+ 400: "#a8a29e",
+ 500: "#78716c",
+ 600: "#57534e",
+ 700: "#44403c",
+ 800: "#292524",
+ 900: "#1c1917",
+ 950: "#0c0a09"
+ },
+ red: {
+ 50: "#fef2f2",
+ 100: "#fee2e2",
+ 200: "#fecaca",
+ 300: "#fca5a5",
+ 400: "#f87171",
+ 500: "#ef4444",
+ 600: "#dc2626",
+ 700: "#b91c1c",
+ 800: "#991b1b",
+ 900: "#7f1d1d",
+ 950: "#450a0a"
+ },
+ orange: {
+ 50: "#fff7ed",
+ 100: "#ffedd5",
+ 200: "#fed7aa",
+ 300: "#fdba74",
+ 400: "#fb923c",
+ 500: "#f97316",
+ 600: "#ea580c",
+ 700: "#c2410c",
+ 800: "#9a3412",
+ 900: "#7c2d12",
+ 950: "#431407"
+ },
+ amber: {
+ 50: "#fffbeb",
+ 100: "#fef3c7",
+ 200: "#fde68a",
+ 300: "#fcd34d",
+ 400: "#fbbf24",
+ 500: "#f59e0b",
+ 600: "#d97706",
+ 700: "#b45309",
+ 800: "#92400e",
+ 900: "#78350f",
+ 950: "#451a03"
+ },
+ yellow: {
+ 50: "#fefce8",
+ 100: "#fef9c3",
+ 200: "#fef08a",
+ 300: "#fde047",
+ 400: "#facc15",
+ 500: "#eab308",
+ 600: "#ca8a04",
+ 700: "#a16207",
+ 800: "#854d0e",
+ 900: "#713f12",
+ 950: "#422006"
+ },
+ lime: {
+ 50: "#f7fee7",
+ 100: "#ecfccb",
+ 200: "#d9f99d",
+ 300: "#bef264",
+ 400: "#a3e635",
+ 500: "#84cc16",
+ 600: "#65a30d",
+ 700: "#4d7c0f",
+ 800: "#3f6212",
+ 900: "#365314",
+ 950: "#1a2e05"
+ },
+ green: {
+ 50: "#f0fdf4",
+ 100: "#dcfce7",
+ 200: "#bbf7d0",
+ 300: "#86efac",
+ 400: "#4ade80",
+ 500: "#22c55e",
+ 600: "#16a34a",
+ 700: "#15803d",
+ 800: "#166534",
+ 900: "#14532d",
+ 950: "#052e16"
+ },
+ emerald: {
+ 50: "#ecfdf5",
+ 100: "#d1fae5",
+ 200: "#a7f3d0",
+ 300: "#6ee7b7",
+ 400: "#34d399",
+ 500: "#10b981",
+ 600: "#059669",
+ 700: "#047857",
+ 800: "#065f46",
+ 900: "#064e3b",
+ 950: "#022c22"
+ },
+ teal: {
+ 50: "#f0fdfa",
+ 100: "#ccfbf1",
+ 200: "#99f6e4",
+ 300: "#5eead4",
+ 400: "#2dd4bf",
+ 500: "#14b8a6",
+ 600: "#0d9488",
+ 700: "#0f766e",
+ 800: "#115e59",
+ 900: "#134e4a",
+ 950: "#042f2e"
+ },
+ cyan: {
+ 50: "#ecfeff",
+ 100: "#cffafe",
+ 200: "#a5f3fc",
+ 300: "#67e8f9",
+ 400: "#22d3ee",
+ 500: "#06b6d4",
+ 600: "#0891b2",
+ 700: "#0e7490",
+ 800: "#155e75",
+ 900: "#164e63",
+ 950: "#083344"
+ },
+ sky: {
+ 50: "#f0f9ff",
+ 100: "#e0f2fe",
+ 200: "#bae6fd",
+ 300: "#7dd3fc",
+ 400: "#38bdf8",
+ 500: "#0ea5e9",
+ 600: "#0284c7",
+ 700: "#0369a1",
+ 800: "#075985",
+ 900: "#0c4a6e",
+ 950: "#082f49"
+ },
+ blue: {
+ 50: "#eff6ff",
+ 100: "#dbeafe",
+ 200: "#bfdbfe",
+ 300: "#93c5fd",
+ 400: "#60a5fa",
+ 500: "#3b82f6",
+ 600: "#2563eb",
+ 700: "#1d4ed8",
+ 800: "#1e40af",
+ 900: "#1e3a8a",
+ 950: "#172554"
+ },
+ indigo: {
+ 50: "#eef2ff",
+ 100: "#e0e7ff",
+ 200: "#c7d2fe",
+ 300: "#a5b4fc",
+ 400: "#818cf8",
+ 500: "#6366f1",
+ 600: "#4f46e5",
+ 700: "#4338ca",
+ 800: "#3730a3",
+ 900: "#312e81",
+ 950: "#1e1b4b"
+ },
+ violet: {
+ 50: "#f5f3ff",
+ 100: "#ede9fe",
+ 200: "#ddd6fe",
+ 300: "#c4b5fd",
+ 400: "#a78bfa",
+ 500: "#8b5cf6",
+ 600: "#7c3aed",
+ 700: "#6d28d9",
+ 800: "#5b21b6",
+ 900: "#4c1d95",
+ 950: "#2e1065"
+ },
+ purple: {
+ 50: "#faf5ff",
+ 100: "#f3e8ff",
+ 200: "#e9d5ff",
+ 300: "#d8b4fe",
+ 400: "#c084fc",
+ 500: "#a855f7",
+ 600: "#9333ea",
+ 700: "#7e22ce",
+ 800: "#6b21a8",
+ 900: "#581c87",
+ 950: "#3b0764"
+ },
+ fuchsia: {
+ 50: "#fdf4ff",
+ 100: "#fae8ff",
+ 200: "#f5d0fe",
+ 300: "#f0abfc",
+ 400: "#e879f9",
+ 500: "#d946ef",
+ 600: "#c026d3",
+ 700: "#a21caf",
+ 800: "#86198f",
+ 900: "#701a75",
+ 950: "#4a044e"
+ },
+ pink: {
+ 50: "#fdf2f8",
+ 100: "#fce7f3",
+ 200: "#fbcfe8",
+ 300: "#f9a8d4",
+ 400: "#f472b6",
+ 500: "#ec4899",
+ 600: "#db2777",
+ 700: "#be185d",
+ 800: "#9d174d",
+ 900: "#831843",
+ 950: "#500724"
+ },
+ rose: {
+ 50: "#fff1f2",
+ 100: "#ffe4e6",
+ 200: "#fecdd3",
+ 300: "#fda4af",
+ 400: "#fb7185",
+ 500: "#f43f5e",
+ 600: "#e11d48",
+ 700: "#be123c",
+ 800: "#9f1239",
+ 900: "#881337",
+ 950: "#4c0519"
+ }
+};
+color_values.reduce(
+ (y, { color: s, primary: e, secondary: l }) => ({
+ ...y,
+ [s]: {
+ primary: tw_colors[s][e],
+ secondary: tw_colors[s][l]
+ }
+ }),
+ {}
+);
+const UploadText_svelte_svelte_type_style_lang = "", Toolbar_svelte_svelte_type_style_lang = "", SelectSource_svelte_svelte_type_style_lang = "", Button_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$a,
+ append: append$8,
+ attr: attr$9,
+ detach: detach$a,
+ element: element$9,
+ init: init$a,
+ insert: insert$a,
+ listen: listen$4,
+ noop: noop$a,
+ run_all: run_all$4,
+ safe_not_equal: safe_not_equal$b,
+ space: space$8
+} = window.__gradio__svelte__internal, { createEventDispatcher: createEventDispatcher$5 } = window.__gradio__svelte__internal;
+function create_if_block$6(y) {
+ let s, e, l;
+ return {
+ c() {
+ s = element$9("button"), s.innerHTML = ' Covalent modifcation', attr$9(s, "class", "flex items-center space-x-2 block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white svelte-8wrmgx");
+ },
+ m(g, _) {
+ insert$a(g, s, _), e || (l = listen$4(
+ s,
+ "click",
+ /*click_handler_3*/
+ y[7]
+ ), e = !0);
+ },
+ p: noop$a,
+ d(g) {
+ g && detach$a(s), e = !1, l();
+ }
+ };
+}
+function create_fragment$a(y) {
+ let s, e, l, g, _, x, o, p, E, u, A = (
+ /*displayCovMod*/
+ y[0] && create_if_block$6(y)
+ );
+ return {
+ c() {
+ s = element$9("div"), e = element$9("div"), l = element$9("button"), l.innerHTML = ' Protein', g = space$8(), _ = element$9("button"), _.innerHTML = ' Nucleic acid', x = space$8(), o = element$9("button"), o.innerHTML = ' Small molecule', p = space$8(), A && A.c(), attr$9(l, "class", "flex items-center space-x-2 block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white svelte-8wrmgx"), attr$9(_, "class", "flex items-center space-x-2 block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white svelte-8wrmgx"), attr$9(o, "class", "flex items-center space-x-2 block px-4 py-2 hover:bg-gray-100 dark:hover:bg-gray-600 dark:hover:text-white svelte-8wrmgx"), attr$9(e, "class", "flex justify-center mt-2 svelte-8wrmgx"), attr$9(s, "class", "svelte-8wrmgx");
+ },
+ m(C, L) {
+ insert$a(C, s, L), append$8(s, e), append$8(e, l), append$8(e, g), append$8(e, _), append$8(e, x), append$8(e, o), append$8(e, p), A && A.m(e, null), E || (u = [
+ listen$4(
+ l,
+ "click",
+ /*click_handler*/
+ y[4]
+ ),
+ listen$4(
+ _,
+ "click",
+ /*click_handler_1*/
+ y[5]
+ ),
+ listen$4(
+ o,
+ "click",
+ /*click_handler_2*/
+ y[6]
+ )
+ ], E = !0);
+ },
+ p(C, [L]) {
+ /*displayCovMod*/
+ C[0] ? A ? A.p(C, L) : (A = create_if_block$6(C), A.c(), A.m(e, null)) : A && (A.d(1), A = null);
+ },
+ i: noop$a,
+ o: noop$a,
+ d(C) {
+ C && detach$a(s), A && A.d(), E = !1, run_all$4(u);
+ }
+ };
+}
+function instance$a(y, s, e) {
+ const l = createEventDispatcher$5();
+ let { vals: g = [] } = s;
+ function _(C) {
+ l("addNewChain", { type: C });
+ }
+ function x() {
+ l("addCovalentModification");
+ }
+ let o = !1;
+ const p = () => {
+ _("protein");
+ }, E = () => {
+ _("DNA");
+ }, u = () => {
+ _("ligand");
+ }, A = () => {
+ x();
+ };
+ return y.$$set = (C) => {
+ "vals" in C && e(3, g = C.vals);
+ }, y.$$.update = () => {
+ y.$$.dirty & /*vals*/
+ 8 && e(0, o = g.filter((C) => C.class === "protein" && C.sequence.length > 0).length > 0 && g.filter((C) => C.class === "ligand" && C.sdf != "").length > 0);
+ }, [
+ o,
+ _,
+ x,
+ g,
+ p,
+ E,
+ u,
+ A
+ ];
+}
+class Button extends SvelteComponent$a {
+ constructor(s) {
+ super(), init$a(this, s, instance$a, create_fragment$a, safe_not_equal$b, { vals: 3 });
+ }
+}
+const SearchInput_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$9,
+ append: append$7,
+ attr: attr$8,
+ detach: detach$9,
+ element: element$8,
+ init: init$9,
+ insert: insert$9,
+ listen: listen$3,
+ noop: noop$9,
+ prevent_default,
+ run_all: run_all$3,
+ safe_not_equal: safe_not_equal$a,
+ space: space$7,
+ text: text$7
+} = window.__gradio__svelte__internal, { createEventDispatcher: createEventDispatcher$4 } = window.__gradio__svelte__internal;
+function create_fragment$9(y) {
+ let s, e, l, g, _, x = (
+ /*databases*/
+ y[1][
+ /*currentSel*/
+ y[3]
+ ] + ""
+ ), o, p, E, u, A, C, L, D, r, n;
+ return {
+ c() {
+ s = element$8("form"), e = element$8("div"), l = element$8("label"), l.textContent = "Search", g = space$7(), _ = element$8("button"), o = text$7(x), p = space$7(), E = element$8("div"), E.innerHTML = '
', u = space$7(), A = element$8("div"), C = element$8("input"), L = space$7(), D = element$8("button"), D.innerHTML = ' Search', attr$8(l, "for", "search-dropdown"), attr$8(l, "class", "mb-2 text-sm font-medium text-gray-900 sr-only dark:text-white svelte-8wrmgx"), attr$8(_, "id", "dropdown-button"), attr$8(_, "data-dropdown-toggle", "dropdown"), attr$8(_, "class", "flex-shrink-0 z-10 inline-flex items-center py-2.5 px-4 text-sm font-medium text-center text-gray-900 bg-gray-100 border border-gray-300 rounded-s-lg hover:bg-gray-200 focus:ring-4 focus:outline-none focus:ring-gray-100 dark:bg-gray-700 dark:hover:bg-gray-600 dark:focus:ring-gray-700 dark:text-white dark:border-gray-600 svelte-8wrmgx"), attr$8(_, "type", "button"), attr$8(E, "id", "dropdown"), attr$8(E, "class", "z-10 hidden bg-white divide-y divide-gray-100 rounded-lg shadow w-44 dark:bg-gray-700 svelte-8wrmgx"), attr$8(C, "type", "search"), attr$8(C, "id", "search-dropdown"), attr$8(C, "class", "block p-2.5 w-full z-20 text-sm text-gray-900 bg-gray-50 rounded-e-lg border-s-gray-50 border-s-2 border border-gray-300 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:border-s-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:border-blue-500 svelte-8wrmgx"), attr$8(
+ C,
+ "placeholder",
+ /*placeholder*/
+ y[2][
+ /*currentSel*/
+ y[3]
+ ]
+ ), attr$8(D, "type", "submit"), attr$8(D, "class", "absolute top-0 end-0 p-2.5 text-sm font-medium h-full text-white bg-blue-700 rounded-e-lg border border-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800 svelte-8wrmgx"), attr$8(A, "class", "relative w-full svelte-8wrmgx"), attr$8(e, "class", "flex svelte-8wrmgx"), attr$8(s, "class", "max-w-lg mx-auto mb-2 my-2 svelte-8wrmgx");
+ },
+ m(b, f) {
+ insert$9(b, s, f), append$7(s, e), append$7(e, l), append$7(e, g), append$7(e, _), append$7(_, o), append$7(e, p), append$7(e, E), append$7(e, u), append$7(e, A), append$7(A, C), append$7(A, L), append$7(A, D), r || (n = [
+ listen$3(
+ C,
+ "input",
+ /*input_handler*/
+ y[7]
+ ),
+ listen$3(D, "click", prevent_default(
+ /*triggerFetch*/
+ y[4]
+ ))
+ ], r = !0);
+ },
+ p: noop$9,
+ i: noop$9,
+ o: noop$9,
+ d(b) {
+ b && detach$9(s), r = !1, run_all$3(n);
+ }
+ };
+}
+function instance$9(y, s, e) {
+ const l = createEventDispatcher$4();
+ let { database: g = "rcsb-bioass" } = s, { index: _ = 0 } = s, x = {
+ "rcsb-3ligand": "RCSB 3-Letter Codes",
+ pubchem: "Pubchem",
+ "rcsb-bioass": "RCSB BioAssembly"
+ }, o = {
+ "rcsb-3ligand": "e.g HEM, ZN, K, GOL ...",
+ pubchem: "molecule name",
+ "rcsb-bioass": "4 Letter PDB Code"
+ }, p = g, E = "";
+ function u() {
+ l("triggerFetch", {
+ text: E,
+ database: p,
+ index: _
+ });
+ }
+ const A = (C) => e(0, E = C.target.value);
+ return y.$$set = (C) => {
+ "database" in C && e(5, g = C.database), "index" in C && e(6, _ = C.index);
+ }, [
+ E,
+ x,
+ o,
+ p,
+ u,
+ g,
+ _,
+ A
+ ];
+}
+class SearchInput extends SvelteComponent$9 {
+ constructor(s) {
+ super(), init$9(this, s, instance$9, create_fragment$9, safe_not_equal$a, { database: 5, index: 6 });
+ }
+}
+const Sequence_svelte_svelte_type_style_lang = "", {
+ SvelteComponent: SvelteComponent$8,
+ append: append$6,
+ attr: attr$7,
+ destroy_each: destroy_each$2,
+ detach: detach$8,
+ element: element$7,
+ ensure_array_like: ensure_array_like$2,
+ init: init$8,
+ insert: insert$8,
+ noop: noop$8,
+ safe_not_equal: safe_not_equal$9,
+ set_style: set_style$2,
+ space: space$6,
+ text: text$6
+} = window.__gradio__svelte__internal;
+function get_each_context$2(y, s, e) {
+ const l = y.slice();
+ return l[3] = s[e], l[5] = e, l;
+}
+function get_each_context_1$2(y, s, e) {
+ const l = y.slice();
+ return l[6] = s[e], l[8] = e, l;
+}
+function create_each_block_1$2(y) {
+ let s, e, l = (
+ /*letter*/
+ y[6] + ""
+ ), g;
+ return {
+ c() {
+ s = element$7("span"), e = element$7("div"), g = text$6(l), attr$7(e, "class", "inline-block p-0.5 svelte-hhspdt"), attr$7(e, "title", "residue " + /*chunk_ids*/
+ y[1][
+ /*i*/
+ y[5]
+ ][
+ /*j*/
+ y[8]
+ ]), attr$7(s, "class", "p-0.1 text-center w-full inline hover:font-bold cursor-pointer item-selectable ds-selectable svelte-hhspdt"), set_style$2(s, "font-family", "monospace");
+ },
+ m(_, x) {
+ insert$8(_, s, x), append$6(s, e), append$6(e, g);
+ },
+ p: noop$8,
+ d(_) {
+ _ && detach$8(s);
+ }
+ };
+}
+function create_each_block$2(y) {
+ let s, e, l = ensure_array_like$2(
+ /*chunk*/
+ y[3]
+ ), g = [];
+ for (let _ = 0; _ < l.length; _ += 1)
+ g[_] = create_each_block_1$2(get_each_context_1$2(y, l, _));
+ return {
+ c() {
+ s = element$7("div");
+ for (let _ = 0; _ < g.length; _ += 1)
+ g[_].c();
+ e = space$6(), attr$7(s, "class", "sequence__chunk svelte-hhspdt");
+ },
+ m(_, x) {
+ insert$8(_, s, x);
+ for (let o = 0; o < g.length; o += 1)
+ g[o] && g[o].m(s, null);
+ append$6(s, e);
+ },
+ p(_, x) {
+ if (x & /*chunk_ids, chunked_seq*/
+ 3) {
+ l = ensure_array_like$2(
+ /*chunk*/
+ _[3]
+ );
+ let o;
+ for (o = 0; o < l.length; o += 1) {
+ const p = get_each_context_1$2(_, l, o);
+ g[o] ? g[o].p(p, x) : (g[o] = create_each_block_1$2(p), g[o].c(), g[o].m(s, e));
+ }
+ for (; o < g.length; o += 1)
+ g[o].d(1);
+ g.length = l.length;
+ }
+ },
+ d(_) {
+ _ && detach$8(s), destroy_each$2(g, _);
+ }
+ };
+}
+function create_fragment$8(y) {
+ let s, e = ensure_array_like$2(
+ /*chunked_seq*/
+ y[0]
+ ), l = [];
+ for (let g = 0; g < e.length; g += 1)
+ l[g] = create_each_block$2(get_each_context$2(y, e, g));
+ return {
+ c() {
+ s = element$7("div");
+ for (let g = 0; g < l.length; g += 1)
+ l[g].c();
+ attr$7(s, "class", "sequence_container text-xs svelte-hhspdt");
+ },
+ m(g, _) {
+ insert$8(g, s, _);
+ for (let x = 0; x < l.length; x += 1)
+ l[x] && l[x].m(s, null);
+ },
+ p(g, [_]) {
+ if (_ & /*chunked_seq, chunk_ids*/
+ 3) {
+ e = ensure_array_like$2(
+ /*chunked_seq*/
+ g[0]
+ );
+ let x;
+ for (x = 0; x < e.length; x += 1) {
+ const o = get_each_context$2(g, e, x);
+ l[x] ? l[x].p(o, _) : (l[x] = create_each_block$2(o), l[x].c(), l[x].m(s, null));
+ }
+ for (; x < l.length; x += 1)
+ l[x].d(1);
+ l.length = e.length;
+ }
+ },
+ i: noop$8,
+ o: noop$8,
+ d(g) {
+ g && detach$8(s), destroy_each$2(l, g);
+ }
+ };
+}
+function instance$8(y, s, e) {
+ let { seq: l = "" } = s, g = l.match(/.{1,10}/g), _ = g.map((x, o) => x.split("").map((p, E) => o * 10 + E + 1));
+ return y.$$set = (x) => {
+ "seq" in x && e(2, l = x.seq);
+ }, [g, _, l];
+}
+class Sequence extends SvelteComponent$8 {
+ constructor(s) {
+ super(), init$8(this, s, instance$8, create_fragment$8, safe_not_equal$9, { seq: 2 });
+ }
+}
+var commonjsGlobal = typeof globalThis < "u" ? globalThis : typeof window < "u" ? window : typeof global < "u" ? global : typeof self < "u" ? self : {};
+function getDefaultExportFromCjs(y) {
+ return y && y.__esModule && Object.prototype.hasOwnProperty.call(y, "default") ? y.default : y;
+}
+var _3Dmol = { exports: {} };
+/*!
+ * 3dmol v2.1.0
+ * JavaScript/TypeScript molecular visualization library
+ * Author: David Koes and contributors
+ */
+(function(module, exports) {
+ (function(s, e) {
+ module.exports = e();
+ })(commonjsGlobal, () => (
+ /******/
+ (() => {
+ var __webpack_modules__ = {
+ /***/
+ "./node_modules/iobuffer/lib-esm/IOBuffer.js": (
+ /*!***************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/IOBuffer.js ***!
+ \***************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ IOBuffer: () => (
+ /* binding */
+ o
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./text */
+ "./node_modules/iobuffer/lib-esm/text.browser.js"
+ );
+ const g = 1024 * 8, _ = (() => {
+ const p = new Uint8Array(4), E = new Uint32Array(p.buffer);
+ return !((E[0] = 1) & p[0]);
+ })(), x = {
+ int8: globalThis.Int8Array,
+ uint8: globalThis.Uint8Array,
+ int16: globalThis.Int16Array,
+ uint16: globalThis.Uint16Array,
+ int32: globalThis.Int32Array,
+ uint32: globalThis.Uint32Array,
+ uint64: globalThis.BigUint64Array,
+ int64: globalThis.BigInt64Array,
+ float32: globalThis.Float32Array,
+ float64: globalThis.Float64Array
+ };
+ class o {
+ /**
+ * @param data - The data to construct the IOBuffer with.
+ * If data is a number, it will be the new buffer's length
+ * If data is `undefined`, the buffer will be initialized with a default length of 8Kb
+ * If data is an ArrayBuffer, SharedArrayBuffer, an ArrayBufferView (Typed Array), an IOBuffer instance,
+ * or a Node.js Buffer, a view will be created over the underlying ArrayBuffer.
+ * @param options
+ */
+ constructor(E = g, u = {}) {
+ let A = !1;
+ typeof E == "number" ? E = new ArrayBuffer(E) : (A = !0, this.lastWrittenByte = E.byteLength);
+ const C = u.offset ? u.offset >>> 0 : 0, L = E.byteLength - C;
+ let D = C;
+ (ArrayBuffer.isView(E) || E instanceof o) && (E.byteLength !== E.buffer.byteLength && (D = E.byteOffset + C), E = E.buffer), A ? this.lastWrittenByte = L : this.lastWrittenByte = 0, this.buffer = E, this.length = L, this.byteLength = L, this.byteOffset = D, this.offset = 0, this.littleEndian = !0, this._data = new DataView(this.buffer, D, L), this._mark = 0, this._marks = [];
+ }
+ /**
+ * Checks if the memory allocated to the buffer is sufficient to store more
+ * bytes after the offset.
+ * @param byteLength - The needed memory in bytes.
+ * @returns `true` if there is sufficient space and `false` otherwise.
+ */
+ available(E = 1) {
+ return this.offset + E <= this.length;
+ }
+ /**
+ * Check if little-endian mode is used for reading and writing multi-byte
+ * values.
+ * @returns `true` if little-endian mode is used, `false` otherwise.
+ */
+ isLittleEndian() {
+ return this.littleEndian;
+ }
+ /**
+ * Set little-endian mode for reading and writing multi-byte values.
+ */
+ setLittleEndian() {
+ return this.littleEndian = !0, this;
+ }
+ /**
+ * Check if big-endian mode is used for reading and writing multi-byte values.
+ * @returns `true` if big-endian mode is used, `false` otherwise.
+ */
+ isBigEndian() {
+ return !this.littleEndian;
+ }
+ /**
+ * Switches to big-endian mode for reading and writing multi-byte values.
+ */
+ setBigEndian() {
+ return this.littleEndian = !1, this;
+ }
+ /**
+ * Move the pointer n bytes forward.
+ * @param n - Number of bytes to skip.
+ */
+ skip(E = 1) {
+ return this.offset += E, this;
+ }
+ /**
+ * Move the pointer n bytes backward.
+ * @param n - Number of bytes to move back.
+ */
+ back(E = 1) {
+ return this.offset -= E, this;
+ }
+ /**
+ * Move the pointer to the given offset.
+ * @param offset
+ */
+ seek(E) {
+ return this.offset = E, this;
+ }
+ /**
+ * Store the current pointer offset.
+ * @see {@link IOBuffer#reset}
+ */
+ mark() {
+ return this._mark = this.offset, this;
+ }
+ /**
+ * Move the pointer back to the last pointer offset set by mark.
+ * @see {@link IOBuffer#mark}
+ */
+ reset() {
+ return this.offset = this._mark, this;
+ }
+ /**
+ * Push the current pointer offset to the mark stack.
+ * @see {@link IOBuffer#popMark}
+ */
+ pushMark() {
+ return this._marks.push(this.offset), this;
+ }
+ /**
+ * Pop the last pointer offset from the mark stack, and set the current
+ * pointer offset to the popped value.
+ * @see {@link IOBuffer#pushMark}
+ */
+ popMark() {
+ const E = this._marks.pop();
+ if (E === void 0)
+ throw new Error("Mark stack empty");
+ return this.seek(E), this;
+ }
+ /**
+ * Move the pointer offset back to 0.
+ */
+ rewind() {
+ return this.offset = 0, this;
+ }
+ /**
+ * Make sure the buffer has sufficient memory to write a given byteLength at
+ * the current pointer offset.
+ * If the buffer's memory is insufficient, this method will create a new
+ * buffer (a copy) with a length that is twice (byteLength + current offset).
+ * @param byteLength
+ */
+ ensureAvailable(E = 1) {
+ if (!this.available(E)) {
+ const A = (this.offset + E) * 2, C = new Uint8Array(A);
+ C.set(new Uint8Array(this.buffer)), this.buffer = C.buffer, this.length = this.byteLength = A, this._data = new DataView(this.buffer);
+ }
+ return this;
+ }
+ /**
+ * Read a byte and return false if the byte's value is 0, or true otherwise.
+ * Moves pointer forward by one byte.
+ */
+ readBoolean() {
+ return this.readUint8() !== 0;
+ }
+ /**
+ * Read a signed 8-bit integer and move pointer forward by 1 byte.
+ */
+ readInt8() {
+ return this._data.getInt8(this.offset++);
+ }
+ /**
+ * Read an unsigned 8-bit integer and move pointer forward by 1 byte.
+ */
+ readUint8() {
+ return this._data.getUint8(this.offset++);
+ }
+ /**
+ * Alias for {@link IOBuffer#readUint8}.
+ */
+ readByte() {
+ return this.readUint8();
+ }
+ /**
+ * Read `n` bytes and move pointer forward by `n` bytes.
+ */
+ readBytes(E = 1) {
+ return this.readArray(E, "uint8");
+ }
+ /**
+ * Creates an array of corresponding to the type `type` and size `size`.
+ * For example type `uint8` will create a `Uint8Array`.
+ * @param size - size of the resulting array
+ * @param type - number type of elements to read
+ */
+ readArray(E, u) {
+ const A = x[u].BYTES_PER_ELEMENT * E, C = this.byteOffset + this.offset, L = this.buffer.slice(C, C + A);
+ if (this.littleEndian === _ && u !== "uint8" && u !== "int8") {
+ const r = new Uint8Array(this.buffer.slice(C, C + A));
+ r.reverse();
+ const n = new x[u](r.buffer);
+ return this.offset += A, n.reverse(), n;
+ }
+ const D = new x[u](L);
+ return this.offset += A, D;
+ }
+ /**
+ * Read a 16-bit signed integer and move pointer forward by 2 bytes.
+ */
+ readInt16() {
+ const E = this._data.getInt16(this.offset, this.littleEndian);
+ return this.offset += 2, E;
+ }
+ /**
+ * Read a 16-bit unsigned integer and move pointer forward by 2 bytes.
+ */
+ readUint16() {
+ const E = this._data.getUint16(this.offset, this.littleEndian);
+ return this.offset += 2, E;
+ }
+ /**
+ * Read a 32-bit signed integer and move pointer forward by 4 bytes.
+ */
+ readInt32() {
+ const E = this._data.getInt32(this.offset, this.littleEndian);
+ return this.offset += 4, E;
+ }
+ /**
+ * Read a 32-bit unsigned integer and move pointer forward by 4 bytes.
+ */
+ readUint32() {
+ const E = this._data.getUint32(this.offset, this.littleEndian);
+ return this.offset += 4, E;
+ }
+ /**
+ * Read a 32-bit floating number and move pointer forward by 4 bytes.
+ */
+ readFloat32() {
+ const E = this._data.getFloat32(this.offset, this.littleEndian);
+ return this.offset += 4, E;
+ }
+ /**
+ * Read a 64-bit floating number and move pointer forward by 8 bytes.
+ */
+ readFloat64() {
+ const E = this._data.getFloat64(this.offset, this.littleEndian);
+ return this.offset += 8, E;
+ }
+ /**
+ * Read a 64-bit signed integer number and move pointer forward by 8 bytes.
+ */
+ readBigInt64() {
+ const E = this._data.getBigInt64(this.offset, this.littleEndian);
+ return this.offset += 8, E;
+ }
+ /**
+ * Read a 64-bit unsigned integer number and move pointer forward by 8 bytes.
+ */
+ readBigUint64() {
+ const E = this._data.getBigUint64(this.offset, this.littleEndian);
+ return this.offset += 8, E;
+ }
+ /**
+ * Read a 1-byte ASCII character and move pointer forward by 1 byte.
+ */
+ readChar() {
+ return String.fromCharCode(this.readInt8());
+ }
+ /**
+ * Read `n` 1-byte ASCII characters and move pointer forward by `n` bytes.
+ */
+ readChars(E = 1) {
+ let u = "";
+ for (let A = 0; A < E; A++)
+ u += this.readChar();
+ return u;
+ }
+ /**
+ * Read the next `n` bytes, return a UTF-8 decoded string and move pointer
+ * forward by `n` bytes.
+ */
+ readUtf8(E = 1) {
+ return (0, l.decode)(this.readBytes(E));
+ }
+ /**
+ * Read the next `n` bytes, return a string decoded with `encoding` and move pointer
+ * forward by `n` bytes.
+ * If no encoding is passed, the function is equivalent to @see {@link IOBuffer#readUtf8}
+ */
+ decodeText(E = 1, u = "utf-8") {
+ return (0, l.decode)(this.readBytes(E), u);
+ }
+ /**
+ * Write 0xff if the passed value is truthy, 0x00 otherwise and move pointer
+ * forward by 1 byte.
+ */
+ writeBoolean(E) {
+ return this.writeUint8(E ? 255 : 0), this;
+ }
+ /**
+ * Write `value` as an 8-bit signed integer and move pointer forward by 1 byte.
+ */
+ writeInt8(E) {
+ return this.ensureAvailable(1), this._data.setInt8(this.offset++, E), this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as an 8-bit unsigned integer and move pointer forward by 1
+ * byte.
+ */
+ writeUint8(E) {
+ return this.ensureAvailable(1), this._data.setUint8(this.offset++, E), this._updateLastWrittenByte(), this;
+ }
+ /**
+ * An alias for {@link IOBuffer#writeUint8}.
+ */
+ writeByte(E) {
+ return this.writeUint8(E);
+ }
+ /**
+ * Write all elements of `bytes` as uint8 values and move pointer forward by
+ * `bytes.length` bytes.
+ */
+ writeBytes(E) {
+ this.ensureAvailable(E.length);
+ for (let u = 0; u < E.length; u++)
+ this._data.setUint8(this.offset++, E[u]);
+ return this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 16-bit signed integer and move pointer forward by 2
+ * bytes.
+ */
+ writeInt16(E) {
+ return this.ensureAvailable(2), this._data.setInt16(this.offset, E, this.littleEndian), this.offset += 2, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 16-bit unsigned integer and move pointer forward by 2
+ * bytes.
+ */
+ writeUint16(E) {
+ return this.ensureAvailable(2), this._data.setUint16(this.offset, E, this.littleEndian), this.offset += 2, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit signed integer and move pointer forward by 4
+ * bytes.
+ */
+ writeInt32(E) {
+ return this.ensureAvailable(4), this._data.setInt32(this.offset, E, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit unsigned integer and move pointer forward by 4
+ * bytes.
+ */
+ writeUint32(E) {
+ return this.ensureAvailable(4), this._data.setUint32(this.offset, E, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 32-bit floating number and move pointer forward by 4
+ * bytes.
+ */
+ writeFloat32(E) {
+ return this.ensureAvailable(4), this._data.setFloat32(this.offset, E, this.littleEndian), this.offset += 4, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit floating number and move pointer forward by 8
+ * bytes.
+ */
+ writeFloat64(E) {
+ return this.ensureAvailable(8), this._data.setFloat64(this.offset, E, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit signed bigint and move pointer forward by 8
+ * bytes.
+ */
+ writeBigInt64(E) {
+ return this.ensureAvailable(8), this._data.setBigInt64(this.offset, E, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write `value` as a 64-bit unsigned bigint and move pointer forward by 8
+ * bytes.
+ */
+ writeBigUint64(E) {
+ return this.ensureAvailable(8), this._data.setBigUint64(this.offset, E, this.littleEndian), this.offset += 8, this._updateLastWrittenByte(), this;
+ }
+ /**
+ * Write the charCode of `str`'s first character as an 8-bit unsigned integer
+ * and move pointer forward by 1 byte.
+ */
+ writeChar(E) {
+ return this.writeUint8(E.charCodeAt(0));
+ }
+ /**
+ * Write the charCodes of all `str`'s characters as 8-bit unsigned integers
+ * and move pointer forward by `str.length` bytes.
+ */
+ writeChars(E) {
+ for (let u = 0; u < E.length; u++)
+ this.writeUint8(E.charCodeAt(u));
+ return this;
+ }
+ /**
+ * UTF-8 encode and write `str` to the current pointer offset and move pointer
+ * forward according to the encoded length.
+ */
+ writeUtf8(E) {
+ return this.writeBytes((0, l.encode)(E));
+ }
+ /**
+ * Export a Uint8Array view of the internal buffer.
+ * The view starts at the byte offset and its length
+ * is calculated to stop at the last written byte or the original length.
+ */
+ toArray() {
+ return new Uint8Array(this.buffer, this.byteOffset, this.lastWrittenByte);
+ }
+ /**
+ * Update the last written byte offset
+ * @private
+ */
+ _updateLastWrittenByte() {
+ this.offset > this.lastWrittenByte && (this.lastWrittenByte = this.offset);
+ }
+ }
+ }
+ ),
+ /***/
+ "./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js": (
+ /*!*****************************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js ***!
+ \*****************************************************************/
+ /***/
+ function() {
+ (function(y) {
+ if (y.TextEncoder && y.TextDecoder)
+ return !1;
+ function s(l = "utf-8") {
+ if (l !== "utf-8")
+ throw new RangeError(`Failed to construct 'TextEncoder': The encoding label provided ('${l}') is invalid.`);
+ }
+ Object.defineProperty(s.prototype, "encoding", {
+ value: "utf-8"
+ }), s.prototype.encode = function(l, g = { stream: !1 }) {
+ if (g.stream)
+ throw new Error("Failed to encode: the 'stream' option is unsupported.");
+ let _ = 0;
+ const x = l.length;
+ let o = 0, p = Math.max(32, x + (x >> 1) + 7), E = new Uint8Array(p >> 3 << 3);
+ for (; _ < x; ) {
+ let u = l.charCodeAt(_++);
+ if (u >= 55296 && u <= 56319) {
+ if (_ < x) {
+ const A = l.charCodeAt(_);
+ (A & 64512) === 56320 && (++_, u = ((u & 1023) << 10) + (A & 1023) + 65536);
+ }
+ if (u >= 55296 && u <= 56319)
+ continue;
+ }
+ if (o + 4 > E.length) {
+ p += 8, p *= 1 + _ / l.length * 2, p = p >> 3 << 3;
+ const A = new Uint8Array(p);
+ A.set(E), E = A;
+ }
+ if (u & 4294967168)
+ if (!(u & 4294965248))
+ E[o++] = u >> 6 & 31 | 192;
+ else if (!(u & 4294901760))
+ E[o++] = u >> 12 & 15 | 224, E[o++] = u >> 6 & 63 | 128;
+ else if (!(u & 4292870144))
+ E[o++] = u >> 18 & 7 | 240, E[o++] = u >> 12 & 63 | 128, E[o++] = u >> 6 & 63 | 128;
+ else
+ continue;
+ else {
+ E[o++] = u;
+ continue;
+ }
+ E[o++] = u & 63 | 128;
+ }
+ return E.slice(0, o);
+ };
+ function e(l = "utf-8", g = { fatal: !1 }) {
+ if (l !== "utf-8")
+ throw new RangeError(`Failed to construct 'TextDecoder': The encoding label provided ('${l}') is invalid.`);
+ if (g.fatal)
+ throw new Error("Failed to construct 'TextDecoder': the 'fatal' option is unsupported.");
+ }
+ Object.defineProperty(e.prototype, "encoding", {
+ value: "utf-8"
+ }), Object.defineProperty(e.prototype, "fatal", { value: !1 }), Object.defineProperty(e.prototype, "ignoreBOM", {
+ value: !1
+ }), e.prototype.decode = function(l, g = { stream: !1 }) {
+ if (g.stream)
+ throw new Error("Failed to decode: the 'stream' option is unsupported.");
+ const _ = new Uint8Array(l);
+ let x = 0;
+ const o = _.length, p = [];
+ for (; x < o; ) {
+ const E = _[x++];
+ if (E === 0)
+ break;
+ if (!(E & 128))
+ p.push(E);
+ else if ((E & 224) === 192) {
+ const u = _[x++] & 63;
+ p.push((E & 31) << 6 | u);
+ } else if ((E & 240) === 224) {
+ const u = _[x++] & 63, A = _[x++] & 63;
+ p.push((E & 31) << 12 | u << 6 | A);
+ } else if ((E & 248) === 240) {
+ const u = _[x++] & 63, A = _[x++] & 63, C = _[x++] & 63;
+ let L = (E & 7) << 18 | u << 12 | A << 6 | C;
+ L > 65535 && (L -= 65536, p.push(L >>> 10 & 1023 | 55296), L = 56320 | L & 1023), p.push(L);
+ }
+ }
+ return String.fromCharCode.apply(null, p);
+ }, y.TextEncoder = s, y.TextDecoder = e;
+ })(typeof window < "u" ? window : typeof self < "u" ? self : this);
+ }
+ ),
+ /***/
+ "./node_modules/iobuffer/lib-esm/text.browser.js": (
+ /*!*******************************************************!*\
+ !*** ./node_modules/iobuffer/lib-esm/text.browser.js ***!
+ \*******************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ decode: () => (
+ /* binding */
+ l
+ ),
+ /* harmony export */
+ encode: () => (
+ /* binding */
+ _
+ )
+ /* harmony export */
+ }), e(
+ /*! ./text-encoding-polyfill */
+ "./node_modules/iobuffer/lib-esm/text-encoding-polyfill.js"
+ );
+ function l(x, o = "utf8") {
+ return new TextDecoder(o).decode(x);
+ }
+ const g = new TextEncoder();
+ function _(x) {
+ return g.encode(x);
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/data.js": (
+ /*!***********************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/data.js ***!
+ \***********************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ nonRecord: () => (
+ /* binding */
+ g
+ ),
+ /* harmony export */
+ record: () => (
+ /* binding */
+ _
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./types */
+ "./node_modules/netcdfjs/lib-esm/types.js"
+ );
+ function g(x, o) {
+ const p = (0, l.str2num)(o.type), E = o.size / (0, l.num2bytes)(p), u = new Array(E);
+ for (let A = 0; A < E; A++)
+ u[A] = (0, l.readType)(x, p, 1);
+ return u;
+ }
+ function _(x, o, p) {
+ const E = (0, l.str2num)(o.type), u = o.size ? o.size / (0, l.num2bytes)(E) : 1, A = p.length, C = new Array(A), L = p.recordStep;
+ if (L)
+ for (let D = 0; D < A; D++) {
+ const r = x.offset;
+ C[D] = (0, l.readType)(x, E, u), x.seek(r + L);
+ }
+ else
+ throw new Error("recordDimension.recordStep is undefined");
+ return C;
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/header.js": (
+ /*!*************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/header.js ***!
+ \*************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ header: () => (
+ /* binding */
+ u
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./types */
+ "./node_modules/netcdfjs/lib-esm/types.js"
+ ), g = e(
+ /*! ./utils */
+ "./node_modules/netcdfjs/lib-esm/utils.js"
+ );
+ const _ = 0, x = 10, o = 11, p = 12, E = 0;
+ function u(D, r) {
+ const n = { version: r }, b = {
+ length: D.readUint32()
+ }, f = A(D);
+ Array.isArray(f) || (b.id = f.recordId, b.name = f.recordName, n.dimensions = f.dimensions), n.globalAttributes = C(D);
+ const c = L(D, b == null ? void 0 : b.id, r);
+ return Array.isArray(c) || (n.variables = c.variables, b.recordStep = c.recordStep), n.recordDimension = b, n;
+ }
+ function A(D) {
+ const r = {};
+ let n, b;
+ const f = D.readUint32();
+ let c;
+ if (f === _)
+ return (0, g.notNetcdf)(D.readUint32() !== _, "wrong empty tag for list of dimensions"), [];
+ {
+ (0, g.notNetcdf)(f !== x, "wrong tag for list of dimensions");
+ const t = D.readUint32();
+ c = new Array(t);
+ for (let a = 0; a < t; a++) {
+ const h = (0, g.readName)(D), M = D.readUint32();
+ M === E && (n = a, b = h), c[a] = {
+ name: h,
+ size: M
+ };
+ }
+ }
+ return n !== void 0 && (r.recordId = n), b !== void 0 && (r.recordName = b), r.dimensions = c, r;
+ }
+ function C(D) {
+ const r = D.readUint32();
+ let n;
+ if (r === _)
+ return (0, g.notNetcdf)(D.readUint32() !== _, "wrong empty tag for list of attributes"), [];
+ {
+ (0, g.notNetcdf)(r !== p, "wrong tag for list of attributes");
+ const b = D.readUint32();
+ n = new Array(b);
+ for (let f = 0; f < b; f++) {
+ const c = (0, g.readName)(D), t = D.readUint32();
+ (0, g.notNetcdf)(t < 1 || t > 6, `non valid type ${t}`);
+ const a = D.readUint32(), h = (0, l.readType)(D, t, a);
+ (0, g.padding)(D), n[f] = {
+ name: c,
+ type: (0, l.num2str)(t),
+ value: h
+ };
+ }
+ }
+ return n;
+ }
+ function L(D, r, n) {
+ const b = D.readUint32();
+ let f = 0, c;
+ if (b === _)
+ return (0, g.notNetcdf)(D.readUint32() !== _, "wrong empty tag for list of variables"), [];
+ {
+ (0, g.notNetcdf)(b !== o, "wrong tag for list of variables");
+ const t = D.readUint32();
+ c = new Array(t);
+ for (let a = 0; a < t; a++) {
+ const h = (0, g.readName)(D), M = D.readUint32(), w = new Array(M);
+ for (let B = 0; B < M; B++)
+ w[B] = D.readUint32();
+ const S = C(D), T = D.readUint32();
+ (0, g.notNetcdf)(T < 1 && T > 6, `non valid type ${T}`);
+ const R = D.readUint32();
+ let z = D.readUint32();
+ n === 2 && ((0, g.notNetcdf)(z > 0, "offsets larger than 4GB not supported"), z = D.readUint32());
+ let P = !1;
+ typeof r < "u" && w[0] === r && (f += R, P = !0), c[a] = {
+ name: h,
+ dimensions: w,
+ attributes: S,
+ type: (0, l.num2str)(T),
+ size: R,
+ offset: z,
+ record: P
+ };
+ }
+ }
+ return {
+ variables: c,
+ recordStep: f
+ };
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/index.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/index.js ***!
+ \************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ NetCDFReader: () => (
+ /* reexport safe */
+ l.NetCDFReader
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./parser */
+ "./node_modules/netcdfjs/lib-esm/parser.js"
+ );
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/parser.js": (
+ /*!*************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/parser.js ***!
+ \*************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ NetCDFReader: () => (
+ /* binding */
+ p
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! iobuffer */
+ "./node_modules/iobuffer/lib-esm/IOBuffer.js"
+ ), g = e(
+ /*! ./data */
+ "./node_modules/netcdfjs/lib-esm/data.js"
+ ), _ = e(
+ /*! ./header */
+ "./node_modules/netcdfjs/lib-esm/header.js"
+ ), x = e(
+ /*! ./toString */
+ "./node_modules/netcdfjs/lib-esm/toString.js"
+ ), o = e(
+ /*! ./utils */
+ "./node_modules/netcdfjs/lib-esm/utils.js"
+ );
+ class p {
+ constructor(u) {
+ this.toString = x.toString;
+ const A = new l.IOBuffer(u);
+ A.setBigEndian(), (0, o.notNetcdf)(A.readChars(3) !== "CDF", "should start with CDF");
+ const C = A.readByte();
+ (0, o.notNetcdf)(C > 2, "unknown version"), this.header = (0, _.header)(A, C), this.buffer = A;
+ }
+ /**
+ * @return - Version for the NetCDF format
+ */
+ get version() {
+ return this.header.version === 1 ? "classic format" : "64-bit offset format";
+ }
+ /**
+ * @return {object} - Metadata for the record dimension
+ * * `length`: Number of elements in the record dimension
+ * * `id`: Id number in the list of dimensions for the record dimension
+ * * `name`: String with the name of the record dimension
+ * * `recordStep`: Number with the record variables step size
+ */
+ get recordDimension() {
+ return this.header.recordDimension;
+ }
+ /**
+ * @return - Array - List of dimensions with:
+ * * `name`: String with the name of the dimension
+ * * `size`: Number with the size of the dimension
+ */
+ get dimensions() {
+ return this.header.dimensions;
+ }
+ /**
+ * @return - Array - List of global attributes with:
+ * * `name`: String with the name of the attribute
+ * * `type`: String with the type of the attribute
+ * * `value`: A number or string with the value of the attribute
+ */
+ get globalAttributes() {
+ return this.header.globalAttributes;
+ }
+ /**
+ * Returns the value of an attribute
+ * @param - AttributeName
+ * @return - Value of the attributeName or null
+ */
+ getAttribute(u) {
+ const A = this.globalAttributes.find((C) => C.name === u);
+ return A ? A.value : null;
+ }
+ /**
+ * Returns the value of a variable as a string
+ * @param - variableName
+ * @return - Value of the variable as a string or null
+ */
+ getDataVariableAsString(u) {
+ const A = this.getDataVariable(u);
+ return A ? A.join("") : null;
+ }
+ get variables() {
+ return this.header.variables;
+ }
+ /**
+ * Retrieves the data for a given variable
+ * @param variableName - Name of the variable to search or variable object
+ * @return The variable values
+ */
+ getDataVariable(u) {
+ let A;
+ if (typeof u == "string" ? A = this.header.variables.find((C) => C.name === u) : A = u, A === void 0)
+ throw new Error("Not a valid NetCDF v3.x file: variable not found");
+ return this.buffer.seek(A.offset), A.record ? (0, g.record)(this.buffer, A, this.header.recordDimension) : (0, g.nonRecord)(this.buffer, A);
+ }
+ /**
+ * Check if a dataVariable exists
+ * @param variableName - Name of the variable to find
+ * @return boolean
+ */
+ dataVariableExists(u) {
+ return this.header.variables.find((C) => C.name === u) !== void 0;
+ }
+ /**
+ * Check if an attribute exists
+ * @param attributeName - Name of the attribute to find
+ * @return boolean
+ */
+ attributeExists(u) {
+ return this.globalAttributes.find((C) => C.name === u) !== void 0;
+ }
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/toString.js": (
+ /*!***************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/toString.js ***!
+ \***************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ toString: () => (
+ /* binding */
+ l
+ )
+ /* harmony export */
+ });
+ function l() {
+ const g = [];
+ g.push("DIMENSIONS");
+ for (const x of this.dimensions)
+ g.push(` ${x.name.padEnd(30)} = size: ${x.size}`);
+ g.push(""), g.push("GLOBAL ATTRIBUTES");
+ for (const x of this.globalAttributes)
+ g.push(` ${x.name.padEnd(30)} = ${x.value}`);
+ const _ = JSON.parse(JSON.stringify(this.variables));
+ g.push(""), g.push("VARIABLES:");
+ for (const x of _) {
+ x.value = this.getDataVariable(x);
+ let o = JSON.stringify(x.value);
+ o.length > 50 && (o = o.substring(0, 50)), isNaN(x.value.length) || (o += ` (length: ${x.value.length})`), g.push(` ${x.name.padEnd(30)} = ${o}`);
+ }
+ return g.join(`
+`);
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/types.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/types.js ***!
+ \************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ num2bytes: () => (
+ /* binding */
+ _
+ ),
+ /* harmony export */
+ num2str: () => (
+ /* binding */
+ g
+ ),
+ /* harmony export */
+ readType: () => (
+ /* binding */
+ p
+ ),
+ /* harmony export */
+ str2num: () => (
+ /* binding */
+ x
+ )
+ /* harmony export */
+ });
+ const l = {
+ BYTE: 1,
+ CHAR: 2,
+ SHORT: 3,
+ INT: 4,
+ FLOAT: 5,
+ DOUBLE: 6
+ };
+ function g(u) {
+ switch (Number(u)) {
+ case l.BYTE:
+ return "byte";
+ case l.CHAR:
+ return "char";
+ case l.SHORT:
+ return "short";
+ case l.INT:
+ return "int";
+ case l.FLOAT:
+ return "float";
+ case l.DOUBLE:
+ return "double";
+ default:
+ return "undefined";
+ }
+ }
+ function _(u) {
+ switch (Number(u)) {
+ case l.BYTE:
+ return 1;
+ case l.CHAR:
+ return 1;
+ case l.SHORT:
+ return 2;
+ case l.INT:
+ return 4;
+ case l.FLOAT:
+ return 4;
+ case l.DOUBLE:
+ return 8;
+ default:
+ return -1;
+ }
+ }
+ function x(u) {
+ switch (String(u)) {
+ case "byte":
+ return l.BYTE;
+ case "char":
+ return l.CHAR;
+ case "short":
+ return l.SHORT;
+ case "int":
+ return l.INT;
+ case "float":
+ return l.FLOAT;
+ case "double":
+ return l.DOUBLE;
+ default:
+ return -1;
+ }
+ }
+ function o(u, A) {
+ if (u !== 1) {
+ const C = new Array(u);
+ for (let L = 0; L < u; L++)
+ C[L] = A();
+ return C;
+ } else
+ return A();
+ }
+ function p(u, A, C) {
+ switch (A) {
+ case l.BYTE:
+ return Array.from(u.readBytes(C));
+ case l.CHAR:
+ return E(u.readChars(C));
+ case l.SHORT:
+ return o(C, u.readInt16.bind(u));
+ case l.INT:
+ return o(C, u.readInt32.bind(u));
+ case l.FLOAT:
+ return o(C, u.readFloat32.bind(u));
+ case l.DOUBLE:
+ return o(C, u.readFloat64.bind(u));
+ default:
+ throw new Error(`non valid type ${A}`);
+ }
+ }
+ function E(u) {
+ return u.charCodeAt(u.length - 1) === 0 ? u.substring(0, u.length - 1) : u;
+ }
+ }
+ ),
+ /***/
+ "./node_modules/netcdfjs/lib-esm/utils.js": (
+ /*!************************************************!*\
+ !*** ./node_modules/netcdfjs/lib-esm/utils.js ***!
+ \************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ notNetcdf: () => (
+ /* binding */
+ l
+ ),
+ /* harmony export */
+ padding: () => (
+ /* binding */
+ g
+ ),
+ /* harmony export */
+ readName: () => (
+ /* binding */
+ _
+ )
+ /* harmony export */
+ });
+ function l(x, o) {
+ if (x)
+ throw new TypeError(`Not a valid NetCDF v3.x file: ${o}`);
+ }
+ function g(x) {
+ x.offset % 4 !== 0 && x.skip(4 - x.offset % 4);
+ }
+ function _(x) {
+ const o = x.readUint32(), p = x.readChars(o);
+ return g(x), p;
+ }
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/basic/basic.frag": (
+ /*!************************************************!*\
+ !*** ./src/WebGL/shaders/lib/basic/basic.frag ***!
+ \************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 viewMatrix;
+uniform float opacity;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+void main() {
+ gl_FragColor = vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/basic/basic.vert": (
+ /*!************************************************!*\
+ !*** ./src/WebGL/shaders/lib/basic/basic.vert ***!
+ \************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+
+attribute vec3 position;
+attribute vec3 color;
+
+varying vec3 vColor;
+
+void main() {
+
+ vColor = color;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ gl_Position = projectionMatrix * mvPosition;
+
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/instanced/instanced.frag": (
+ /*!********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/instanced/instanced.frag ***!
+ \********************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ gl_FragColor.xyz *= vLightFront;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/instanced/instanced.vert": (
+ /*!********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/instanced/instanced.vert ***!
+ \********************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 offset;
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position * radius + offset, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+
+ gl_Position = projectionMatrix * mvPosition;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambert/lambert.frag": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambert/lambert.frag ***!
+ \****************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ gl_FragColor.xyz *= vLightFront;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambert/lambert.vert": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambert/lambert.vert ***!
+ \****************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+
+ gl_Position = projectionMatrix * mvPosition;
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambertdouble/lambertdouble.frag": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambertdouble/lambertdouble.frag ***!
+ \****************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 viewMatrix;
+uniform float opacity;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLightFront;
+varying vec3 vLightBack;
+
+varying vec3 vColor;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ gl_FragColor = vec4( vec3 ( 1.0 ), opacity );
+
+ #ifndef WIREFRAME
+ if ( gl_FrontFacing )
+ gl_FragColor.xyz *= vLightFront;
+ else
+ gl_FragColor.xyz *= vLightBack;
+ #endif
+
+ gl_FragColor = gl_FragColor * vec4( vColor, opacity );
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/lambertdouble/lambertdouble.vert": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/lambertdouble/lambertdouble.vert ***!
+ \****************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec3 vColor;
+varying vec3 vLightFront;
+varying vec3 vLightBack;
+
+void main() {
+
+ vColor = color;
+
+ vec3 objectNormal = normal;
+ vec3 transformedNormal = normalMatrix * objectNormal;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+
+ vLightFront = vec3( 0.0 );
+ vLightBack = vec3( 0.0 );
+
+ transformedNormal = normalize( transformedNormal );
+
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vec3 dirVector = normalize( lDirection.xyz );
+ float dotProduct = dot( transformedNormal, dirVector );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+ vec3 directionalLightWeightingBack = vec3( max( -dotProduct, 0.0 ) );
+
+ vLightFront += directionalLightColor[ 0 ] * directionalLightWeighting;
+ vLightBack += directionalLightColor[ 0 ] * directionalLightWeightingBack;
+
+ gl_Position = projectionMatrix * mvPosition;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/outline/outline.frag": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/outline/outline.frag ***!
+ \****************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform float opacity;
+uniform vec3 outlineColor;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+//DEFINEFRAGCOLOR
+
+void main() {
+ gl_FragColor = vec4( outlineColor, 1 );
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/outline/outline.vert": (
+ /*!****************************************************!*\
+ !*** ./src/WebGL/shaders/lib/outline/outline.vert ***!
+ \****************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+void main() {
+
+ vec4 norm = modelViewMatrix*vec4(normalize(normal),0.0);
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ mvPosition.xy += norm.xy*outlineWidth;
+ gl_Position = projectionMatrix * mvPosition;
+ mvPosition.z -= outlinePushback; //go backwards in model space
+ vec4 pushpos = projectionMatrix*mvPosition; //project to get z in projection space, I'm probably missing some simple math to do the same thing..
+ gl_Position.z = gl_Position.w*pushpos.z/pushpos.w;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screen/screen.frag": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screen/screen.frag ***!
+ \**************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform sampler2D colormap;
+varying highp vec2 vTexCoords;
+uniform vec2 dimensions;
+//DEFINEFRAGCOLOR
+void main (void) {
+ gl_FragColor = texture2D(colormap, vTexCoords);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screen/screen.vert": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screen/screen.vert ***!
+ \**************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `attribute vec2 vertexPosition;
+varying highp vec2 vTexCoords;
+const vec2 scale = vec2(0.5, 0.5);
+
+void main() {
+ vTexCoords = vertexPosition * scale + scale; // scale vertex attribute to [0,1] range
+ gl_Position = vec4(vertexPosition, 0.0, 1.0);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screenaa/screenaa.frag": (
+ /*!******************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screenaa/screenaa.frag ***!
+ \******************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform sampler2D colormap;
+varying highp vec2 vTexCoords;
+uniform vec2 dimensions;
+
+// Basic FXAA implementation based on the code on geeks3d.com
+#define FXAA_REDUCE_MIN (1.0/ 128.0)
+#define FXAA_REDUCE_MUL (1.0 / 8.0)
+#define FXAA_SPAN_MAX 8.0
+
+vec4 applyFXAA(vec2 fragCoord, sampler2D tex)
+{
+ vec4 color;
+ vec2 inverseVP = vec2(1.0 / dimensions.x, 1.0 / dimensions.y);
+ vec3 rgbNW = texture2D(tex, fragCoord + vec2(-1.0, -1.0) * inverseVP).xyz;
+ vec3 rgbNE = texture2D(tex, fragCoord + vec2(1.0, -1.0) * inverseVP).xyz;
+ vec3 rgbSW = texture2D(tex, fragCoord + vec2(-1.0, 1.0) * inverseVP).xyz;
+ vec3 rgbSE = texture2D(tex, fragCoord + vec2(1.0, 1.0) * inverseVP).xyz;
+ vec3 rgbM = texture2D(tex, fragCoord * inverseVP).xyz;
+ vec3 luma = vec3(0.299, 0.587, 0.114);
+ float lumaNW = dot(rgbNW, luma);
+ float lumaNE = dot(rgbNE, luma);
+ float lumaSW = dot(rgbSW, luma);
+ float lumaSE = dot(rgbSE, luma);
+ float lumaM = dot(rgbM, luma);
+ float lumaMin = min(lumaM, min(min(lumaNW, lumaNE), min(lumaSW, lumaSE)));
+ float lumaMax = max(lumaM, max(max(lumaNW, lumaNE), max(lumaSW, lumaSE)));
+
+ vec2 dir;
+ dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));
+ dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));
+
+ float dirReduce = max((lumaNW + lumaNE + lumaSW + lumaSE) *
+ (0.25 * FXAA_REDUCE_MUL), FXAA_REDUCE_MIN);
+
+ float rcpDirMin = 1.0 / (min(abs(dir.x), abs(dir.y)) + dirReduce);
+ dir = min(vec2(FXAA_SPAN_MAX, FXAA_SPAN_MAX),
+ max(vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),
+ dir * rcpDirMin)) * inverseVP;
+
+ vec3 rgbA = 0.5 * (
+ texture2D(tex, fragCoord + dir * (1.0 / 3.0 - 0.5)).xyz +
+ texture2D(tex, fragCoord + dir * (2.0 / 3.0 - 0.5)).xyz);
+ vec3 rgbB = rgbA * 0.5 + 0.25 * (
+ texture2D(tex, fragCoord + dir * -0.5).xyz +
+ texture2D(tex, fragCoord + dir * 0.5).xyz);
+
+ float lumaB = dot(rgbB, luma);
+ if ((lumaB < lumaMin) || (lumaB > lumaMax))
+ color = vec4(rgbA, 1.0);
+ else
+ color = vec4(rgbB, 1.0);
+ return color;
+}
+//DEFINEFRAGCOLOR
+void main (void) {
+ gl_FragColor = applyFXAA(vTexCoords, colormap);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/screenaa/screenaa.vert": (
+ /*!******************************************************!*\
+ !*** ./src/WebGL/shaders/lib/screenaa/screenaa.vert ***!
+ \******************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `attribute vec2 vertexPosition;
+varying highp vec2 vTexCoords;
+const vec2 scale = vec2(0.5, 0.5);
+
+void main() {
+ vTexCoords = vertexPosition * scale + scale; // scale vertex attribute to [0,1] range
+ gl_Position = vec4(vertexPosition, 0.0, 1.0);
+}
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposter/sphereimposter.frag": (
+ /*!******************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposter/sphereimposter.frag ***!
+ \******************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+uniform mat4 viewMatrix;
+uniform float opacity;
+uniform mat4 projectionMatrix;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+uniform float uDepth;
+uniform vec3 directionalLightColor[ 1 ];
+
+varying vec3 vColor;
+varying vec2 mapping;
+varying float rval;
+varying vec3 vLight;
+varying vec3 center;
+
+//DEFINEFRAGCOLOR
+
+void main() {
+ float lensqr = dot(mapping,mapping);
+ float rsqr = rval*rval;
+ if(lensqr > rsqr)
+ discard;
+ float z = sqrt(rsqr-lensqr);
+ vec3 cameraPos = center+ vec3(mapping.x,mapping.y,z);
+ vec4 clipPos = projectionMatrix * vec4(cameraPos, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ gl_FragDepthEXT = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ vec3 norm = normalize(vec3(mapping.x,mapping.y,z));
+ float dotProduct = dot( norm, vLight );
+ vec3 directionalLightWeighting = vec3( max( dotProduct, 0.0 ) );
+ vec3 vLight = directionalLightColor[ 0 ] * directionalLightWeighting;
+ gl_FragColor = vec4(vLight*vColor, opacity*opacity );
+ float fogFactor = smoothstep( fogNear, fogFar, gl_FragDepthEXT/gl_FragCoord.w );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+
+
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposter/sphereimposter.vert": (
+ /*!******************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposter/sphereimposter.vert ***!
+ \******************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec2 mapping;
+varying vec3 vColor;
+varying float rval;
+varying vec3 vLight;
+varying vec3 center;
+
+void main() {
+
+ vColor = color;
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ center = mvPosition.xyz;
+ vec4 projPosition = projectionMatrix * mvPosition;
+ vec4 adjust = projectionMatrix* vec4(normal,0.0); adjust.z = 0.0; adjust.w = 0.0;
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vLight = normalize( lDirection.xyz );
+ mapping = normal.xy;
+ rval = abs(normal.x);
+ gl_Position = projPosition+adjust;
+
+}
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.frag": (
+ /*!********************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.frag ***!
+ \********************************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform float opacity;
+uniform vec3 outlineColor;
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+uniform mat4 projectionMatrix;
+varying vec2 mapping;
+varying float rval;
+varying vec3 center;
+
+uniform float outlinePushback;
+
+//DEFINEFRAGCOLOR
+
+void main() {
+ float lensqr = dot(mapping,mapping);
+ float rsqr = rval*rval;
+ if(lensqr > rsqr)
+ discard;
+ float z = sqrt(rsqr-lensqr);
+ vec3 cameraPos = center+ vec3(mapping.x,mapping.y,z-outlinePushback);
+ vec4 clipPos = projectionMatrix * vec4(cameraPos, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ gl_FragDepthEXT = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ gl_FragColor = vec4(outlineColor, 1 );
+}
+
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.vert": (
+ /*!********************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sphereimposteroutline/sphereimposteroutline.vert ***!
+ \********************************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+
+varying vec2 mapping;
+varying float rval;
+varying vec3 center;
+
+void main() {
+
+ vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ center = mvPosition.xyz;
+ vec4 projPosition = projectionMatrix * mvPosition;
+ vec2 norm = normal.xy + vec2(sign(normal.x)*outlineWidth,sign(normal.y)*outlineWidth);
+ vec4 adjust = projectionMatrix* vec4(norm,normal.z,0.0); adjust.z = 0.0; adjust.w = 0.0;
+ mapping = norm.xy;
+ rval = abs(norm.x);
+ gl_Position = projPosition+adjust;
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sprite/sprite.frag": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sprite/sprite.frag ***!
+ \**************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform vec3 color;
+uniform sampler2D map;
+uniform float opacity;
+
+uniform int fogType;
+uniform vec3 fogColor;
+uniform float fogDensity;
+uniform float fogNear;
+uniform float fogFar;
+uniform float alphaTest;
+
+varying vec2 vUV;
+//DEFINEFRAGCOLOR
+
+void main() {
+
+ vec4 texture = texture2D(map, vUV);
+
+ if (texture.a < alphaTest) discard;
+
+ gl_FragColor = vec4(color * texture.xyz, texture.a * opacity);
+
+ if (fogType > 0) {
+
+ float depth = gl_FragCoord.z / gl_FragCoord.w;
+ float fogFactor = 0.0;
+
+ if (fogType == 1) {
+ fogFactor = smoothstep(fogNear, fogFar, depth);
+ }
+
+ else {
+ const float LOG2 = 1.442695;
+ float fogFactor = exp2(- fogDensity * fogDensity * depth * depth * LOG2);
+ fogFactor = 1.0 - clamp(fogFactor, 0.0, 1.0);
+ }
+
+ gl_FragColor = mix(gl_FragColor, vec4(fogColor, gl_FragColor.w), fogFactor);
+
+ }
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/sprite/sprite.vert": (
+ /*!**************************************************!*\
+ !*** ./src/WebGL/shaders/lib/sprite/sprite.vert ***!
+ \**************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform int useScreenCoordinates;
+uniform vec3 screenPosition;
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform float rotation;
+uniform vec2 scale;
+uniform vec2 alignment;
+uniform vec2 uvOffset;
+uniform vec2 uvScale;
+
+attribute vec2 position;
+attribute vec2 uv;
+
+varying vec2 vUV;
+
+void main() {
+
+ vUV = uvOffset + uv * uvScale;
+
+ vec2 alignedPosition = position + alignment;
+
+ vec2 rotatedPosition;
+ rotatedPosition.x = ( cos(rotation) * alignedPosition.x - sin(rotation) * alignedPosition.y ) * scale.x;
+ rotatedPosition.y = ( sin(rotation) * alignedPosition.x + cos(rotation) * alignedPosition.y ) * scale.y;
+
+ vec4 finalPosition;
+
+ if(useScreenCoordinates != 0) {
+ finalPosition = vec4(screenPosition.xy + rotatedPosition, screenPosition.z, 1.0);
+ }
+
+ else {
+ finalPosition = projectionMatrix * modelViewMatrix * vec4(0.0, 0.0, 0.0, 1.0); finalPosition /= finalPosition.w;
+ finalPosition.xy += rotatedPosition;
+ }
+
+ gl_Position = finalPosition;
+
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposter/stickimposter.partial.frag": (
+ /*!************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposter/stickimposter.partial.frag ***!
+ \************************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = ` float dotProduct = dot( norm, vLight );
+ vec3 light = vec3( max( dotProduct, 0.0 ) );
+ gl_FragColor = vec4(light*color, opacity*opacity );
+ float fogFactor = smoothstep( fogNear, fogFar, depth );
+ gl_FragColor = mix( gl_FragColor, vec4( fogColor, gl_FragColor.w ), fogFactor );
+}`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposter/stickimposter.vert": (
+ /*!****************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposter/stickimposter.vert ***!
+ \****************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLight;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+void main() {
+
+ vColor = color; vColor.z = abs(vColor.z); //z indicates which vertex and so would vary
+ r = abs(radius);
+ vec4 to = modelViewMatrix*vec4(normal, 1.0); //normal is other point of cylinder
+ vec4 pt = modelViewMatrix*vec4(position, 1.0);
+ vec4 mvPosition = pt;
+ p1 = pt.xyz; p2 = to.xyz;
+ vec3 norm = to.xyz-pt.xyz;
+ float mult = 1.1; //slop to account for perspective of sphere
+ if(length(p1) > length(p2)) { //billboard at level of closest point
+ mvPosition = to;
+ }
+ vec3 n = normalize(mvPosition.xyz);
+//intersect with the plane defined by the camera looking at the billboard point
+ if(color.z >= 0.0) { //p1
+ if(projectionMatrix[3][3] == 0.0) { //perspective
+ vec3 pnorm = normalize(p1);
+ float t = dot(mvPosition.xyz-p1,n)/dot(pnorm,n);
+ mvPosition.xyz = p1+t*pnorm;
+ } else { //orthographic
+ mvPosition.xyz = p1;
+ }
+ } else {
+ if(projectionMatrix[3][3] == 0.0) { //perspective
+ vec3 pnorm = normalize(p2);
+ float t = dot(mvPosition.xyz-p2,n)/dot(pnorm,n);
+ mvPosition.xyz = p2+t*pnorm;
+ } else { //orthographic
+ mvPosition.xyz = p2;
+ }
+ mult *= -1.0;
+ }
+ vec3 cr = normalize(cross(mvPosition.xyz,norm))*radius;
+ vec3 doublecr = normalize(cross(mvPosition.xyz,cr))*radius;
+ mvPosition.xyz += mult*(cr + doublecr).xyz;
+ cposition = mvPosition.xyz;
+ gl_Position = projectionMatrix * mvPosition;
+ vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );
+ vLight = normalize( lDirection.xyz )*directionalLightColor[0]; //not really sure this is right, but color is always white so..
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/stickimposteroutline/stickimposteroutline.vert": (
+ /*!******************************************************************************!*\
+ !*** ./src/WebGL/shaders/lib/stickimposteroutline/stickimposteroutline.vert ***!
+ \******************************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+
+uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+uniform mat3 normalMatrix;
+uniform vec3 directionalLightColor[ 1 ];
+uniform vec3 directionalLightDirection[ 1 ];
+uniform vec3 outlineColor;
+uniform float outlineWidth;
+uniform float outlinePushback;
+
+
+attribute vec3 position;
+attribute vec3 normal;
+attribute vec3 color;
+attribute float radius;
+
+varying vec3 vColor;
+varying vec3 vLight;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+void main() {
+
+ vColor = outlineColor;
+ float rad = radius+sign(radius)*outlineWidth;
+ r = abs(rad);
+ vec4 to = modelViewMatrix*vec4(normal, 1.0); //normal is other point of cylinder
+ vec4 pt = modelViewMatrix*vec4(position, 1.0);
+//pushback
+ to.xyz += normalize(to.xyz)*outlinePushback;
+ pt.xyz += normalize(pt.xyz)*outlinePushback;
+
+ vec4 mvPosition = pt;
+ p1 = pt.xyz; p2 = to.xyz;
+ vec3 norm = to.xyz-pt.xyz;
+ float mult = 1.1; //slop to account for perspective of sphere
+ if(length(p1) > length(p2)) { //billboard at level of closest point
+ mvPosition = to;
+ }
+ vec3 n = normalize(mvPosition.xyz);
+//intersect with the plane defined by the camera looking at the billboard point
+ if(color.z >= 0.0) { //p1
+ vec3 pnorm = normalize(p1);
+ float t = dot(mvPosition.xyz-p1,n)/dot(pnorm,n);
+ mvPosition.xyz = p1+t*pnorm;
+ } else {
+ vec3 pnorm = normalize(p2);
+ float t = dot(mvPosition.xyz-p2,n)/dot(pnorm,n);
+ mvPosition.xyz = p2+t*pnorm;
+ mult *= -1.0;
+ }
+ vec3 cr = normalize(cross(mvPosition.xyz,norm))*rad;
+ vec3 doublecr = normalize(cross(mvPosition.xyz,cr))*rad;
+ mvPosition.xy += mult*(cr + doublecr).xy;
+ cposition = mvPosition.xyz;
+ gl_Position = projectionMatrix * mvPosition;
+ vLight = vec3(1.0,1.0,1.0);
+}
+
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/volumetric/volumetric.frag": (
+ /*!**********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/volumetric/volumetric.frag ***!
+ \**********************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `
+uniform highp sampler3D data;
+uniform highp sampler2D colormap;
+uniform highp sampler2D depthmap;
+
+
+uniform mat4 textmat;
+uniform mat4 projinv;
+uniform mat4 projectionMatrix;
+
+uniform float step;
+uniform float subsamples;
+uniform float maxdepth;
+uniform float transfermin;
+uniform float transfermax;
+in vec4 mvPosition;
+out vec4 color;
+void main(void) {
+
+ vec4 pos = mvPosition;
+ bool seengood = false;
+ float i = 0.0;
+ color = vec4(1,1,1,0);
+ float increment = 1.0/subsamples;
+ float maxsteps = (maxdepth*subsamples/step);
+//there's probably a better way to do this..
+//calculate farthest possible point in model coordinates
+ vec4 maxpos = vec4(pos.x,pos.y,pos.z-maxdepth,1.0);
+// convert to projection
+ maxpos = projectionMatrix*maxpos;
+ vec4 startp = projectionMatrix*pos;
+// homogonize
+ maxpos /= maxpos.w;
+ startp /= startp.w;
+//take x,y from start and z from max
+ maxpos = vec4(startp.x,startp.y,maxpos.z,1.0);
+//convert back to model space
+ maxpos = projinv*maxpos;
+ maxpos /= maxpos.w;
+ float incr = step/subsamples;
+//get depth from depthmap
+//startp is apparently [-1,1]
+ vec2 tpos = startp.xy/2.0+0.5;
+ float depth = texture(depthmap, tpos).r;
+//compute vector between start and end
+ vec4 direction = maxpos-pos;
+ for( i = 0.0; i <= maxsteps; i++) {
+ vec4 pt = (pos+(i/maxsteps)*direction);
+ vec4 ppt = projectionMatrix*pt;
+ float ptdepth = ppt.z/ppt.w;
+ ptdepth = ((gl_DepthRange.diff * ptdepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ if(ptdepth > depth) break;
+ pt = textmat*pt;
+// pt /= pt.w;
+ if(pt.x >= -0.01 && pt.y >= -0.01 && pt.z >= -0.01 && pt.x <= 1.01 && pt.y <= 1.01 && pt.z <= 1.01) {
+ seengood = true;
+ } else if(seengood) {
+ break;
+ }
+ if( pt.x < -0.01 || pt.x > 1.01 || pt.y < -0.01 || pt.y > 1.01 || pt.z < -0.01 || pt.z > 1.01 ){
+ color.a = 0.0;
+ continue;
+ }
+ else {
+ float val = texture(data, pt.zyx).r;
+ if(isinf(val)) continue; //masked out
+ float cval = (val-transfermin)/(transfermax-transfermin); //scale to texture 0-1 range
+ vec4 val_color = texture(colormap, vec2(cval,0.5));
+ color.rgb = color.rgb*color.a + (1.0-color.a)*val_color.a*val_color.rgb;
+ color.a += (1.0 - color.a) * val_color.a;
+ if(color.a > 0.0) color.rgb /= color.a;
+// color = vec4(pt.x, pt.y, pt.z, 1.0);
+ }
+// color = vec4(pt.x, pt.y, pt.z, 0.0)
+ }
+}
+
+ `;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/lib/volumetric/volumetric.vert": (
+ /*!**********************************************************!*\
+ !*** ./src/WebGL/shaders/lib/volumetric/volumetric.vert ***!
+ \**********************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform mat4 modelViewMatrix;
+uniform mat4 projectionMatrix;
+uniform mat4 viewMatrix;
+
+in vec3 position;
+out vec4 mvPosition;
+void main() {
+
+ mvPosition = modelViewMatrix * vec4( position, 1.0 );
+ gl_Position = projectionMatrix*mvPosition;
+}
+`;
+ }
+ ),
+ /***/
+ "./src/WebGL/shaders/utils/stickimposterFragmentShader.partial.frag": (
+ /*!**************************************************************************!*\
+ !*** ./src/WebGL/shaders/utils/stickimposterFragmentShader.partial.frag ***!
+ \**************************************************************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ default: () => l
+ /* harmony export */
+ });
+ const l = `uniform float opacity;
+uniform mat4 projectionMatrix;
+
+uniform vec3 fogColor;
+uniform float fogNear;
+uniform float fogFar;
+
+varying vec3 vLight;
+varying vec3 vColor;
+varying vec3 cposition;
+varying vec3 p1;
+varying vec3 p2;
+varying float r;
+
+//DEFINEFRAGCOLOR
+
+//cylinder-ray intersection testing taken from http://mrl.nyu.edu/~dzorin/cg05/lecture12.pdf
+//also useful: http://stackoverflow.com/questions/9595300/cylinder-impostor-in-glsl
+//with a bit more care (caps) this could be a general cylinder imposter (see also outline)
+void main() {
+ vec3 color = abs(vColor);
+ vec3 pos = cposition;
+ vec3 p = pos; //ray point
+ vec3 v = vec3(0.0,0.0,-1.0); //ray normal - orthographic
+ if(projectionMatrix[3][3] == 0.0) v = normalize(pos); //ray normal - perspective
+ vec3 pa = p1; //cyl start
+ vec3 va = normalize(p2-p1); //cyl norm
+ vec3 tmp1 = v-(dot(v,va)*va);
+ vec3 deltap = p-pa;
+ float A = dot(tmp1,tmp1);
+ if(A == 0.0) discard;
+ vec3 tmp2 = deltap-(dot(deltap,va)*va);
+ float B = 2.0*dot(tmp1, tmp2);
+ float C = dot(tmp2,tmp2)-r*r;
+//quadratic equation!
+ float det = (B*B) - (4.0*A*C);
+ if(det < 0.0) discard;
+ float sqrtDet = sqrt(det);
+ float posT = (-B+sqrtDet)/(2.0*A);
+ float negT = (-B-sqrtDet)/(2.0*A);
+ float intersectionT = min(posT,negT);
+ vec3 qi = p+v*intersectionT;
+ float dotp1 = dot(va,qi-p1);
+ float dotp2 = dot(va,qi-p2);
+ vec3 norm;
+ if( dotp1 < 0.0 || dotp2 > 0.0) { //(p-c)^2 + 2(p-c)vt +v^2+t^2 - r^2 = 0
+ vec3 cp;
+ if( dotp1 < 0.0) {
+// if(vColor.x < 0.0 ) discard; //color sign bit indicates if we should cap or not
+ cp = p1;
+ } else {
+// if(vColor.y < 0.0 ) discard;
+ cp = p2;
+ }
+ vec3 diff = p-cp;
+ A = dot(v,v);
+ B = dot(diff,v)*2.0;
+ C = dot(diff,diff)-r*r;
+ det = (B*B) - (4.0*C);
+ if(det < 0.0) discard;
+ sqrtDet = sqrt(det);
+ posT = (-B+sqrtDet)/(2.0);
+ negT = (-B-sqrtDet)/(2.0);
+ float t = min(posT,negT);
+ qi = p+v*t;
+ norm = normalize(qi-cp);
+ } else {
+ norm = normalize(qi-(dotp1*va + p1));
+ }
+ vec4 clipPos = projectionMatrix * vec4(qi, 1.0);
+ float ndcDepth = clipPos.z / clipPos.w;
+ float depth = ((gl_DepthRange.diff * ndcDepth) + gl_DepthRange.near + gl_DepthRange.far) / 2.0;
+ gl_FragDepthEXT = depth;`;
+ }
+ ),
+ /***/
+ "./src/GLDraw.ts": (
+ /*!***********************!*\
+ !*** ./src/GLDraw.ts ***!
+ \***********************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ CAP: () => (
+ /* binding */
+ g
+ ),
+ /* harmony export */
+ GLDraw: () => (
+ /* binding */
+ _
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), g;
+ (function(x) {
+ x[x.NONE = 0] = "NONE", x[x.FLAT = 1] = "FLAT", x[x.ROUND = 2] = "ROUND";
+ })(g || (g = {}));
+ var _;
+ (function(x) {
+ function o(r, n, b) {
+ var f = Math.hypot(r, n), c, t, a, h, M;
+ f < 1e-4 ? (t = 0, a = 1) : (t = -r / f, a = n / f), n = -t * r + a * n, c = Math.hypot(n, b), c < 1e-4 ? (h = 0, M = 1) : (h = b / c, M = n / c);
+ var w = new Float32Array(9);
+ return w[0] = a, w[1] = t, w[2] = 0, w[3] = -t * M, w[4] = a * M, w[5] = h, w[6] = t * h, w[7] = -a * h, w[8] = M, w;
+ }
+ class p {
+ constructor() {
+ this.cache = {};
+ let n = [], b = 4, f = Math.pow(2, b), c = 2, t = Math.pow(2, c), a = f / t, h;
+ for (n[0] = new l.Vector3(-1, 0, 0), n[a] = new l.Vector3(0, 0, 1), n[a * 2] = new l.Vector3(1, 0, 0), n[a * 3] = new l.Vector3(0, 0, -1), c = 3; c <= b; c++) {
+ for (t = Math.pow(2, c - 1), a = f / t, h = 0; h < t - 1; h++)
+ n[a / 2 + h * a] = n[h * a].clone().add(n[(h + 1) * a]).normalize();
+ h = t - 1, n[a / 2 + h * a] = n[h * a].clone().add(n[0]).normalize();
+ }
+ this.basisVectors = n;
+ }
+ getVerticesForRadius(n, b, f) {
+ if (typeof this.cache < "u" && this.cache[n] !== void 0 && this.cache[n][b + f] !== void 0)
+ return this.cache[n][b + f];
+ for (var c = this.basisVectors.length, t = [], a = [], h, M = 0; M < c; M++)
+ t.push(this.basisVectors[M].clone().multiplyScalar(n)), t.push(this.basisVectors[M].clone().multiplyScalar(n)), h = this.basisVectors[M].clone().normalize(), a.push(h), a.push(h);
+ var w = [], S = 10, T = c, R = 0, z = Math.PI * 2, P = 0, B = Math.PI, U, F, $ = !1, W = !1;
+ for (F = 0; F <= S; F++) {
+ $ = F === 0 || F === S, W = F === S / 2;
+ var N = [], G = [];
+ for (U = 0; U <= T; U++) {
+ if (W) {
+ var k = U < T ? 2 * U : 0;
+ G.push(k + 1), N.push(k);
+ continue;
+ }
+ var j = U / T, Q = F / S;
+ if (!$ || U === 0)
+ if (U < T) {
+ var ie = new l.Vector3();
+ ie.x = -n * Math.cos(R + j * z) * Math.sin(P + Q * B), b == 1 ? ie.y = 0 : ie.y = n * Math.cos(P + Q * B), ie.z = n * Math.sin(R + j * z) * Math.sin(P + Q * B), Math.abs(ie.x) < 1e-5 && (ie.x = 0), Math.abs(ie.y) < 1e-5 && (ie.y = 0), Math.abs(ie.z) < 1e-5 && (ie.z = 0), b == g.FLAT ? (h = new l.Vector3(0, Math.cos(P + Q * B), 0), h.normalize()) : (h = new l.Vector3(ie.x, ie.y, ie.z), h.normalize()), t.push(ie), a.push(h), N.push(t.length - 1);
+ } else
+ N.push(t.length - T);
+ else
+ $ && N.push(t.length - 1);
+ }
+ W && w.push(G), w.push(N);
+ }
+ var pe = {
+ vertices: t,
+ normals: a,
+ verticesRows: w,
+ w: T,
+ h: S
+ };
+ return n in this.cache || (this.cache[n] = {}), this.cache[n][b + f] = pe, pe;
+ }
+ }
+ var E = new p();
+ function u(r, n, b, f, c, t = 0, a = 0) {
+ if (!n || !b)
+ return;
+ let h = function(Ee) {
+ if (typeof Ee == "string") {
+ let He = Ee;
+ return He.toLowerCase() == "flat" ? g.FLAT : He.toLowerCase() == "round" ? g.ROUND : g.NONE;
+ } else
+ return Ee;
+ };
+ t = h(t), a = h(a);
+ var M = a || t;
+ c = c || { r: 0, g: 0, b: 0 };
+ var w = o(b.x - n.x, b.y - n.y, b.z - n.z), S = E.getVerticesForRadius(f, a, "to"), T = S.w, R = S.h, z = M ? R * T + 2 : 2 * T, P = r.updateGeoGroup(z), B = S.vertices, U = S.normals, F = S.verticesRows, $ = F[R / 2], W = F[R / 2 + 1], N = P.vertices, G, k, j, Q, ie, pe, he = P.vertexArray, ue = P.normalArray, se = P.colorArray, ae = P.faceArray;
+ for (j = 0; j < T; ++j) {
+ var we = 2 * j;
+ Q = w[0] * B[we].x + w[3] * B[we].y + w[6] * B[we].z, ie = w[1] * B[we].x + w[4] * B[we].y + w[7] * B[we].z, pe = w[5] * B[we].y + w[8] * B[we].z, G = 3 * (N + we), k = P.faceidx, he[G] = Q + n.x, he[G + 1] = ie + n.y, he[G + 2] = pe + n.z, he[G + 3] = Q + b.x, he[G + 4] = ie + b.y, he[G + 5] = pe + b.z, ue[G] = Q, ue[G + 3] = Q, ue[G + 1] = ie, ue[G + 4] = ie, ue[G + 2] = pe, ue[G + 5] = pe, se[G] = c.r, se[G + 3] = c.r, se[G + 1] = c.g, se[G + 4] = c.g, se[G + 2] = c.b, se[G + 5] = c.b, ae[k] = W[j] + N, ae[k + 1] = W[j + 1] + N, ae[k + 2] = $[j] + N, ae[k + 3] = $[j] + N, ae[k + 4] = W[j + 1] + N, ae[k + 5] = $[j + 1] + N, P.faceidx += 6;
+ }
+ if (M) {
+ var xe = a ? 0 : R / 2, Ie = t ? R + 1 : R / 2 + 1, oe, ve, re, Se, ze, Ge, $e, Re, Be, ke, We, Te, je, Fe, X, Z, q, fe, _e, Me, Ae, H, ce, ye, Pe, le, De, K, Oe, Ne, I, me;
+ for (ie = xe; ie < Ie; ie++)
+ if (ie !== R / 2) {
+ var ge = ie <= R / 2 ? b : n, Y = E.getVerticesForRadius(f, a, "to"), ne = E.getVerticesForRadius(f, t, "from");
+ for (ge === b ? (B = Y.vertices, U = Y.normals, F = Y.verticesRows) : ge == n && (B = ne.vertices, U = ne.normals, F = ne.verticesRows), Q = 0; Q < T; Q++)
+ k = P.faceidx, oe = F[ie][Q + 1], Oe = (oe + N) * 3, ve = F[ie][Q], Ne = (ve + N) * 3, re = F[ie + 1][Q], I = (re + N) * 3, Se = F[ie + 1][Q + 1], me = (Se + N) * 3, ze = w[0] * B[oe].x + w[3] * B[oe].y + w[6] * B[oe].z, Ge = w[0] * B[ve].x + w[3] * B[ve].y + w[6] * B[ve].z, $e = w[0] * B[re].x + w[3] * B[re].y + w[6] * B[re].z, Re = w[0] * B[Se].x + w[3] * B[Se].y + w[6] * B[Se].z, Be = w[1] * B[oe].x + w[4] * B[oe].y + w[7] * B[oe].z, ke = w[1] * B[ve].x + w[4] * B[ve].y + w[7] * B[ve].z, We = w[1] * B[re].x + w[4] * B[re].y + w[7] * B[re].z, Te = w[1] * B[Se].x + w[4] * B[Se].y + w[7] * B[Se].z, je = w[5] * B[oe].y + w[8] * B[oe].z, Fe = w[5] * B[ve].y + w[8] * B[ve].z, X = w[5] * B[re].y + w[8] * B[re].z, Z = w[5] * B[Se].y + w[8] * B[Se].z, he[Oe] = ze + ge.x, he[Ne] = Ge + ge.x, he[I] = $e + ge.x, he[me] = Re + ge.x, he[Oe + 1] = Be + ge.y, he[Ne + 1] = ke + ge.y, he[I + 1] = We + ge.y, he[me + 1] = Te + ge.y, he[Oe + 2] = je + ge.z, he[Ne + 2] = Fe + ge.z, he[I + 2] = X + ge.z, he[me + 2] = Z + ge.z, se[Oe] = c.r, se[Ne] = c.r, se[I] = c.r, se[me] = c.r, se[Oe + 1] = c.g, se[Ne + 1] = c.g, se[I + 1] = c.g, se[me + 1] = c.g, se[Oe + 2] = c.b, se[Ne + 2] = c.b, se[I + 2] = c.b, se[me + 2] = c.b, q = w[0] * U[oe].x + w[3] * U[oe].y + w[6] * U[oe].z, fe = w[0] * U[ve].x + w[3] * U[ve].y + w[6] * U[ve].z, _e = w[0] * U[re].x + w[3] * U[re].y + w[6] * U[re].z, Me = w[0] * U[Se].x + w[3] * U[Se].y + w[6] * U[Se].z, Ae = w[1] * U[oe].x + w[4] * U[oe].y + w[7] * U[oe].z, H = w[1] * U[ve].x + w[4] * U[ve].y + w[7] * U[ve].z, ce = w[1] * U[re].x + w[4] * U[re].y + w[7] * U[re].z, ye = w[1] * U[Se].x + w[4] * U[Se].y + w[7] * U[Se].z, Pe = w[5] * U[oe].y + w[8] * U[oe].z, le = w[5] * U[ve].y + w[8] * U[ve].z, De = w[5] * U[re].y + w[8] * U[re].z, K = w[5] * U[Se].y + w[8] * U[Se].z, ie === 0 ? (ue[Oe] = q, ue[I] = _e, ue[me] = Me, ue[Oe + 1] = Ae, ue[I + 1] = ce, ue[me + 1] = ye, ue[Oe + 2] = Pe, ue[I + 2] = De, ue[me + 2] = K, ae[k] = oe + N, ae[k + 1] = re + N, ae[k + 2] = Se + N, P.faceidx += 3) : ie === Ie - 1 ? (ue[Oe] = q, ue[Ne] = fe, ue[I] = _e, ue[Oe + 1] = Ae, ue[Ne + 1] = H, ue[I + 1] = ce, ue[Oe + 2] = Pe, ue[Ne + 2] = le, ue[I + 2] = De, ae[k] = oe + N, ae[k + 1] = ve + N, ae[k + 2] = re + N, P.faceidx += 3) : (ue[Oe] = q, ue[Ne] = fe, ue[me] = Me, ue[Oe + 1] = Ae, ue[Ne + 1] = H, ue[me + 1] = ye, ue[Oe + 2] = Pe, ue[Ne + 2] = le, ue[me + 2] = K, ue[Ne] = fe, ue[I] = _e, ue[me] = Me, ue[Ne + 1] = H, ue[I + 1] = ce, ue[me + 1] = ye, ue[Ne + 2] = le, ue[I + 2] = De, ue[me + 2] = K, ae[k] = oe + N, ae[k + 1] = ve + N, ae[k + 2] = Se + N, ae[k + 3] = ve + N, ae[k + 4] = re + N, ae[k + 5] = Se + N, P.faceidx += 6);
+ }
+ }
+ P.vertices += z;
+ }
+ x.drawCylinder = u;
+ function A(r, n, b, f, c) {
+ if (!n || !b)
+ return;
+ c = c || { r: 0, g: 0, b: 0 };
+ let t = new l.Vector3(b.x - n.x, b.y - n.y, b.z - n.z);
+ var a = o(t.x, t.y, t.z);
+ t = t.normalize();
+ var h = E.basisVectors.length, M = E.basisVectors, w = h + 2, S = r.updateGeoGroup(w), T = S.vertices, R, z, P, B, U, F, $ = S.vertexArray, W = S.normalArray, N = S.colorArray, G = S.faceArray;
+ for (R = T * 3, $[R] = n.x, $[R + 1] = n.y, $[R + 2] = n.z, W[R] = -t.x, W[R + 1] = -t.y, W[R + 2] = -t.z, N[R] = c.r, N[R + 1] = c.g, N[R + 2] = c.b, $[R + 3] = b.x, $[R + 4] = b.y, $[R + 5] = b.z, W[R + 3] = t.x, W[R + 4] = t.y, W[R + 5] = t.z, N[R + 3] = c.r, N[R + 4] = c.g, N[R + 5] = c.b, R += 6, P = 0; P < h; ++P) {
+ var k = M[P].clone();
+ k.multiplyScalar(f), B = a[0] * k.x + a[3] * k.y + a[6] * k.z, U = a[1] * k.x + a[4] * k.y + a[7] * k.z, F = a[5] * k.y + a[8] * k.z, $[R] = B + n.x, $[R + 1] = U + n.y, $[R + 2] = F + n.z, W[R] = B, W[R + 1] = U, W[R + 2] = F, N[R] = c.r, N[R + 1] = c.g, N[R + 2] = c.b, R += 3;
+ }
+ for (S.vertices += h + 2, z = S.faceidx, P = 0; P < h; P++) {
+ var j = T + 2 + P, Q = T + 2 + (P + 1) % h;
+ G[z] = j, G[z + 1] = Q, G[z + 2] = T, z += 3, G[z] = j, G[z + 1] = Q, G[z + 2] = T + 1, z += 3;
+ }
+ S.faceidx += 6 * h;
+ }
+ x.drawCone = A;
+ class C {
+ constructor() {
+ this.cache = /* @__PURE__ */ new Map();
+ }
+ getVerticesForRadius(n, b) {
+ b = b || 2, this.cache.has(b) || this.cache.set(b, /* @__PURE__ */ new Map());
+ let f = this.cache.get(b);
+ if (f.has(n))
+ return f.get(n);
+ var c = {
+ vertices: [],
+ verticesRows: [],
+ normals: []
+ }, t = 16 * b, a = 10 * b;
+ n < 1 && (t = 10 * b, a = 8 * b);
+ var h = 0, M = Math.PI * 2, w = 0, S = Math.PI, T, R;
+ for (R = 0; R <= a; R++) {
+ let P = [];
+ for (T = 0; T <= t; T++) {
+ let B = T / t, U = R / a, F = -n * Math.cos(h + B * M) * Math.sin(w + U * S), $ = n * Math.cos(w + U * S), W = n * Math.sin(h + B * M) * Math.sin(w + U * S);
+ var z = new l.Vector3(F, $, W);
+ z.normalize(), c.vertices.push({ x: F, y: $, z: W }), c.normals.push(z), P.push(c.vertices.length - 1);
+ }
+ c.verticesRows.push(P);
+ }
+ return f.set(n, c), c;
+ }
+ }
+ var L = new C();
+ function D(r, n, b, f, c) {
+ var t = L.getVerticesForRadius(b, c), a = t.vertices, h = t.normals, M = r.updateGeoGroup(a.length), w = M.vertices, S = M.vertexArray, T = M.colorArray, R = M.faceArray, z = M.lineArray, P = M.normalArray;
+ for (let F = 0, $ = a.length; F < $; ++F) {
+ let W = 3 * (w + F), N = a[F];
+ S[W] = N.x + n.x, S[W + 1] = N.y + n.y, S[W + 2] = N.z + n.z, T[W] = f.r, T[W + 1] = f.g, T[W + 2] = f.b;
+ }
+ M.vertices += a.length;
+ let B = t.verticesRows, U = B.length - 1;
+ for (let F = 0; F < U; F++) {
+ let $ = B[F].length - 1;
+ for (let W = 0; W < $; W++) {
+ let N = M.faceidx, G = M.lineidx, k = B[F][W + 1] + w, j = k * 3, Q = B[F][W] + w, ie = Q * 3, pe = B[F + 1][W] + w, he = pe * 3, ue = B[F + 1][W + 1] + w, se = ue * 3, ae = h[k - w], we = h[Q - w], xe = h[pe - w], Ie = h[ue - w];
+ Math.abs(a[k - w].y) === b ? (P[j] = ae.x, P[he] = xe.x, P[se] = Ie.x, P[j + 1] = ae.y, P[he + 1] = xe.y, P[se + 1] = Ie.y, P[j + 2] = ae.z, P[he + 2] = xe.z, P[se + 2] = Ie.z, R[N] = k, R[N + 1] = pe, R[N + 2] = ue, z[G] = k, z[G + 1] = pe, z[G + 2] = k, z[G + 3] = ue, z[G + 4] = pe, z[G + 5] = ue, M.faceidx += 3, M.lineidx += 6) : Math.abs(a[pe - w].y) === b ? (P[j] = ae.x, P[ie] = we.x, P[he] = xe.x, P[j + 1] = ae.y, P[ie + 1] = we.y, P[he + 1] = xe.y, P[j + 2] = ae.z, P[ie + 2] = we.z, P[he + 2] = xe.z, R[N] = k, R[N + 1] = Q, R[N + 2] = pe, z[G] = k, z[G + 1] = Q, z[G + 2] = k, z[G + 3] = pe, z[G + 4] = Q, z[G + 5] = pe, M.faceidx += 3, M.lineidx += 6) : (P[j] = ae.x, P[ie] = we.x, P[se] = Ie.x, P[j + 1] = ae.y, P[ie + 1] = we.y, P[se + 1] = Ie.y, P[j + 2] = ae.z, P[ie + 2] = we.z, P[se + 2] = Ie.z, P[ie] = we.x, P[he] = xe.x, P[se] = Ie.x, P[ie + 1] = we.y, P[he + 1] = xe.y, P[se + 1] = Ie.y, P[ie + 2] = we.z, P[he + 2] = xe.z, P[se + 2] = Ie.z, R[N] = k, R[N + 1] = Q, R[N + 2] = ue, R[N + 3] = Q, R[N + 4] = pe, R[N + 5] = ue, z[G] = k, z[G + 1] = Q, z[G + 2] = k, z[G + 3] = ue, z[G + 4] = Q, z[G + 5] = pe, z[G + 6] = pe, z[G + 7] = ue, M.faceidx += 6, M.lineidx += 8);
+ }
+ }
+ }
+ x.drawSphere = D;
+ })(_ || (_ = {}));
+ }
+ ),
+ /***/
+ "./src/GLModel.ts": (
+ /*!************************!*\
+ !*** ./src/GLModel.ts ***!
+ \************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ GLModel: () => (
+ /* binding */
+ n
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), g = e(
+ /*! ./WebGL/shapes */
+ "./src/WebGL/shapes/index.ts"
+ ), _ = e(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), x = e(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), o = e(
+ /*! ./GLDraw */
+ "./src/GLDraw.ts"
+ ), p = e(
+ /*! ./glcartoon */
+ "./src/glcartoon.ts"
+ ), E = e(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ ), u = e(
+ /*! ./Gradient */
+ "./src/Gradient.ts"
+ ), A = e(
+ /*! ./parsers */
+ "./src/parsers/index.ts"
+ ), C = e(
+ /*! netcdfjs */
+ "./node_modules/netcdfjs/lib-esm/index.js"
+ ), L = e(
+ /*! pako */
+ "./node_modules/pako/dist/pako.esm.mjs"
+ ), D = e(
+ /*! ./parsers/utils/assignBonds */
+ "./src/parsers/utils/assignBonds.ts"
+ );
+ function r(b) {
+ let f;
+ return typeof b == "string" ? f = new TextEncoder().encode(b) : f = new Uint8Array(b), (0, L.inflate)(f, {
+ to: "string"
+ });
+ }
+ class n {
+ // class functions
+ // return true if a and b represent the same style
+ static sameObj(f, c) {
+ return f && c ? JSON.stringify(f) == JSON.stringify(c) : f == c;
+ }
+ constructor(f, c) {
+ this.atoms = [], this.frames = [], this.box = null, this.atomdfs = null, this.id = 0, this.hidden = !1, this.molObj = null, this.renderedMolObj = null, this.lastColors = null, this.modelData = {}, this.modelDatas = null, this.idMatrix = new _.Matrix4(), this.dontDuplicateAtoms = !0, this.defaultColor = x.elementColors.defaultColor, this.defaultStickRadius = 0.25, this.options = c || {}, this.ElementColors = this.options.defaultcolors ? this.options.defaultcolors : x.elementColors.defaultColors, this.defaultSphereRadius = this.options.defaultSphereRadius ? this.options.defaultSphereRadius : 1.5, this.defaultCartoonQuality = this.options.cartoonQuality ? this.options.cartoonQuality : 10, this.id = f;
+ }
+ // return proper radius for atom given style
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {atomstyle} style
+ * @return {number}
+ *
+ */
+ getRadiusFromStyle(f, c) {
+ var t = this.defaultSphereRadius;
+ if (typeof c.radius < "u")
+ t = c.radius;
+ else if (n.vdwRadii[f.elem])
+ t = n.vdwRadii[f.elem];
+ else if (f.elem.length > 1) {
+ let a = f.elem;
+ a = a[0].toUpperCase() + a[1].toLowerCase(), n.vdwRadii[a] && (t = n.vdwRadii[a]);
+ }
+ return typeof c.scale < "u" && (t *= c.scale), t;
+ }
+ // cross drawing
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {Record} geos
+ */
+ drawAtomCross(f, c) {
+ if (f.style.cross) {
+ var t = f.style.cross;
+ if (!t.hidden) {
+ var a = t.linewidth || n.defaultlineWidth;
+ c[a] || (c[a] = new l.Geometry());
+ var h = c[a].updateGeoGroup(6), M = this.getRadiusFromStyle(f, t), w = [
+ [M, 0, 0],
+ [-M, 0, 0],
+ [0, M, 0],
+ [0, -M, 0],
+ [0, 0, M],
+ [0, 0, -M]
+ ], S = f.clickable || f.hoverable;
+ S && f.intersectionShape === void 0 && (f.intersectionShape = { sphere: [], cylinder: [], line: [] });
+ for (var T = (0, E.getColorFromStyle)(f, t), R = h.vertexArray, z = h.colorArray, P = 0; P < 6; P++) {
+ var B = h.vertices * 3;
+ if (h.vertices++, R[B] = f.x + w[P][0], R[B + 1] = f.y + w[P][1], R[B + 2] = f.z + w[P][2], z[B] = T.r, z[B + 1] = T.g, z[B + 2] = T.b, S) {
+ var U = new _.Vector3(w[P][0], w[P][1], w[P][2]);
+ U.multiplyScalar(0.1), U.set(U.x + f.x, U.y + f.y, U.z + f.z), f.intersectionShape.line.push(U);
+ }
+ }
+ }
+ }
+ }
+ getGoodCross(f, c, t, a) {
+ for (var h = null, M = -1, w = 0, S = f.bonds.length; w < S; w++)
+ if (f.bonds[w] != c.index) {
+ let R = f.bonds[w], z = this.atoms[R], B = new _.Vector3(z.x, z.y, z.z).clone();
+ B.sub(t);
+ let U = B.clone();
+ U.cross(a);
+ var T = U.lengthSq();
+ if (T > M && (M = T, h = U, M > 0.1))
+ return h;
+ }
+ return h;
+ }
+ //from atom, return a normalized vector v that is orthogonal and along which
+ //it is appropraite to draw multiple bonds
+ getSideBondV(f, c, t) {
+ var a, h, M, w, S, T = new _.Vector3(f.x, f.y, f.z), R = new _.Vector3(c.x, c.y, c.z), z = R.clone(), P = null;
+ if (z.sub(T), f.bonds.length === 1)
+ c.bonds.length === 1 ? (P = z.clone(), Math.abs(P.x) > 1e-4 ? P.y += 1 : P.x += 1) : (a = (t + 1) % c.bonds.length, h = c.bonds[a], M = this.atoms[h], M.index == f.index && (a = (a + 1) % c.bonds.length, h = c.bonds[a], M = this.atoms[h]), w = new _.Vector3(M.x, M.y, M.z), S = w.clone(), S.sub(T), P = S.clone(), P.cross(z));
+ else if (P = this.getGoodCross(f, c, T, z), P.lengthSq() < 0.01) {
+ var B = this.getGoodCross(c, f, T, z);
+ B != null && (P = B);
+ }
+ return P.lengthSq() < 0.01 && (P = z.clone(), Math.abs(P.x) > 1e-4 ? P.y += 1 : P.x += 1), P.cross(z), P.normalize(), P;
+ }
+ addLine(f, c, t, a, h, M) {
+ f[t] = a.x, f[t + 1] = a.y, f[t + 2] = a.z, c[t] = M.r, c[t + 1] = M.g, c[t + 2] = M.b, f[t + 3] = h.x, f[t + 4] = h.y, f[t + 5] = h.z, c[t + 3] = M.r, c[t + 4] = M.g, c[t + 5] = M.b;
+ }
+ // bonds - both atoms must match bond style
+ // standardize on only drawing for lowest to highest
+ /**
+ *
+ * @param {AtomSpec}
+ * atom
+ * @param {AtomSpec[]} atoms
+ * @param {Record} geos
+ */
+ drawBondLines(f, c, t) {
+ if (f.style.line) {
+ var a = f.style.line;
+ if (!a.hidden) {
+ var h, M, w, S, T = a.linewidth || n.defaultlineWidth;
+ t[T] || (t[T] = new l.Geometry());
+ for (var R = t[T].updateGeoGroup(6 * f.bonds.length), z = R.vertexArray, P = R.colorArray, B = 0; B < f.bonds.length; B++) {
+ var U = f.bonds[B], F = c[U];
+ if (F.style.line && !(f.index >= F.index)) {
+ var $ = new _.Vector3(f.x, f.y, f.z), W = new _.Vector3(F.x, F.y, F.z), N = $.clone().add(W).multiplyScalar(0.5), G = !1, k = f.clickable || f.hoverable, j = F.clickable || F.hoverable;
+ (k || j) && (k && (f.intersectionShape === void 0 && (f.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), f.intersectionShape.line.push($), f.intersectionShape.line.push(N)), j && (F.intersectionShape === void 0 && (F.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), F.intersectionShape.line.push(N), F.intersectionShape.line.push(W)));
+ var Q = (0, E.getColorFromStyle)(f, f.style.line), ie = (0, E.getColorFromStyle)(F, F.style.line);
+ if (f.bondStyles && f.bondStyles[B]) {
+ var pe = f.bondStyles[B];
+ if (!pe.iswire)
+ continue;
+ pe.singleBond && (G = !0), typeof pe.color1 < "u" && (Q = x.CC.color(pe.color1)), typeof pe.color2 < "u" && (ie = x.CC.color(pe.color2));
+ }
+ var he = R.vertices * 3, ue, se;
+ if (f.bondOrder[B] > 1 && f.bondOrder[B] < 4 && !G) {
+ var ae = this.getSideBondV(f, F, B), we = W.clone();
+ we.sub($), f.bondOrder[B] == 2 ? (ae.multiplyScalar(0.1), h = $.clone(), h.add(ae), M = $.clone(), M.sub(ae), w = h.clone(), w.add(we), S = M.clone(), S.add(we), Q == ie ? (R.vertices += 4, this.addLine(z, P, he, h, w, Q), this.addLine(z, P, he + 6, M, S, Q)) : (R.vertices += 8, we.multiplyScalar(0.5), ue = h.clone(), ue.add(we), se = M.clone(), se.add(we), this.addLine(z, P, he, h, ue, Q), this.addLine(z, P, he + 6, ue, w, ie), this.addLine(z, P, he + 12, M, se, Q), this.addLine(z, P, he + 18, se, S, ie))) : f.bondOrder[B] == 3 && (ae.multiplyScalar(0.1), h = $.clone(), h.add(ae), M = $.clone(), M.sub(ae), w = h.clone(), w.add(we), S = M.clone(), S.add(we), Q == ie ? (R.vertices += 6, this.addLine(z, P, he, $, W, Q), this.addLine(z, P, he + 6, h, w, Q), this.addLine(z, P, he + 12, M, S, Q)) : (R.vertices += 12, we.multiplyScalar(0.5), ue = h.clone(), ue.add(we), se = M.clone(), se.add(we), this.addLine(z, P, he, $, N, Q), this.addLine(z, P, he + 6, N, W, ie), this.addLine(z, P, he + 12, h, ue, Q), this.addLine(z, P, he + 18, ue, w, ie), this.addLine(z, P, he + 24, M, se, Q), this.addLine(z, P, he + 30, se, S, ie)));
+ } else
+ Q == ie ? (R.vertices += 2, this.addLine(z, P, he, $, W, Q)) : (R.vertices += 4, this.addLine(z, P, he, $, N, Q), this.addLine(z, P, he + 6, N, W, ie));
+ }
+ }
+ }
+ }
+ }
+ //sphere drawing
+ //See also: drawCylinder
+ /**
+ *
+ * @param {AtomSpec} atom
+ * @param {Geometry} geo
+ */
+ drawAtomSphere(f, c) {
+ if (f.style.sphere) {
+ var t = f.style.sphere;
+ if (!t.hidden) {
+ var a = (0, E.getColorFromStyle)(f, t), h = this.getRadiusFromStyle(f, t);
+ if ((f.clickable === !0 || f.hoverable) && f.intersectionShape !== void 0) {
+ var M = new _.Vector3(f.x, f.y, f.z);
+ f.intersectionShape.sphere.push(new g.Sphere(M, h));
+ }
+ o.GLDraw.drawSphere(c, f, h, a);
+ }
+ }
+ }
+ /** Register atom shaped click handlers */
+ drawAtomClickSphere(f) {
+ if (f.style.clicksphere) {
+ var c = f.style.clicksphere;
+ if (!c.hidden) {
+ var t = this.getRadiusFromStyle(f, c);
+ if ((f.clickable === !0 || f.hoverable) && f.intersectionShape !== void 0) {
+ var a = new _.Vector3(f.x, f.y, f.z);
+ f.intersectionShape.sphere.push(new g.Sphere(a, t));
+ }
+ }
+ }
+ }
+ drawAtomInstanced(f, c) {
+ if (f.style.sphere) {
+ var t = f.style.sphere;
+ if (!t.hidden) {
+ var a = this.getRadiusFromStyle(f, t), h = (0, E.getColorFromStyle)(f, t), M = c.updateGeoGroup(1), w = M.vertices, S = w * 3, T = M.vertexArray, R = M.colorArray, z = M.radiusArray;
+ if (T[S] = f.x, T[S + 1] = f.y, T[S + 2] = f.z, R[S] = h.r, R[S + 1] = h.g, R[S + 2] = h.b, z[w] = a, (f.clickable === !0 || f.hoverable) && f.intersectionShape !== void 0) {
+ var P = new _.Vector3(f.x, f.y, f.z);
+ f.intersectionShape.sphere.push(new g.Sphere(P, a));
+ }
+ M.vertices += 1;
+ }
+ }
+ }
+ drawSphereImposter(f, c, t, a) {
+ var h = f.updateGeoGroup(4), M, w = h.vertices, S = w * 3, T = h.vertexArray, R = h.colorArray;
+ for (M = 0; M < 4; M++)
+ T[S + 3 * M] = c.x, T[S + 3 * M + 1] = c.y, T[S + 3 * M + 2] = c.z;
+ var z = h.normalArray;
+ for (M = 0; M < 4; M++)
+ R[S + 3 * M] = a.r, R[S + 3 * M + 1] = a.g, R[S + 3 * M + 2] = a.b;
+ z[S + 0] = -t, z[S + 1] = t, z[S + 2] = 0, z[S + 3] = -t, z[S + 4] = -t, z[S + 5] = 0, z[S + 6] = t, z[S + 7] = -t, z[S + 8] = 0, z[S + 9] = t, z[S + 10] = t, z[S + 11] = 0, h.vertices += 4;
+ var P = h.faceArray, B = h.faceidx;
+ P[B + 0] = w, P[B + 1] = w + 1, P[B + 2] = w + 2, P[B + 3] = w + 2, P[B + 4] = w + 3, P[B + 5] = w, h.faceidx += 6;
+ }
+ //dkoes - code for sphere imposters
+ drawAtomImposter(f, c) {
+ if (f.style.sphere) {
+ var t = f.style.sphere;
+ if (!t.hidden) {
+ var a = this.getRadiusFromStyle(f, t), h = (0, E.getColorFromStyle)(f, t);
+ if ((f.clickable === !0 || f.hoverable) && f.intersectionShape !== void 0) {
+ var M = new _.Vector3(f.x, f.y, f.z);
+ f.intersectionShape.sphere.push(new g.Sphere(M, a));
+ }
+ this.drawSphereImposter(c, f, a, h);
+ }
+ }
+ }
+ calculateDashes(f, c, t, a, h) {
+ var M = Math.sqrt(Math.pow(f.x - c.x, 2) + Math.pow(f.y - c.y, 2) + Math.pow(f.z - c.z, 2));
+ t = Math.max(t, 0), h = Math.max(h, 0) + 2 * t, a = Math.max(a, 1e-3), a + h > M && (a = M, h = 0);
+ var w = Math.floor((M - a) / (a + h)) + 1, S = w * a;
+ h = (M - S) / w;
+ for (var T, R = new _.Vector3(f.x, f.y, f.z), z = new _.Vector3((c.x - f.x) / (M / h), (c.y - f.y) / (M / h), (c.z - f.z) / (M / h)), P = new _.Vector3((c.x - f.x) / (M / a), (c.y - f.y) / (M / a), (c.z - f.z) / (M / a)), B = [], U = 0; U < w; U++)
+ T = new _.Vector3(R.x + P.x, R.y + P.y, R.z + P.z), B.push({ from: R, to: T }), R = new _.Vector3(T.x + z.x, T.y + z.y, T.z + z.z);
+ return B;
+ }
+ static drawStickImposter(f, c, t, a, h, M = 0, w = 0) {
+ for (var S = f.updateGeoGroup(4), T = S.vertices, R = T * 3, z = S.vertexArray, P = S.colorArray, B = S.radiusArray, U = S.normalArray, F = h.r, $ = h.g, W = h.b, N = function(ie) {
+ var pe = -ie;
+ return pe == 0 && (pe = -1e-4), pe;
+ }, G = R, k = 0; k < 4; k++)
+ z[G] = c.x, U[G] = t.x, P[G] = F, G++, z[G] = c.y, U[G] = t.y, P[G] = $, G++, z[G] = c.z, U[G] = t.z, k < 2 ? P[G] = W : P[G] = N(W), G++;
+ S.vertices += 4, B[T] = -a, B[T + 1] = a, B[T + 2] = -a, B[T + 3] = a;
+ var j = S.faceArray, Q = S.faceidx;
+ j[Q + 0] = T, j[Q + 1] = T + 1, j[Q + 2] = T + 2, j[Q + 3] = T + 2, j[Q + 4] = T + 3, j[Q + 5] = T, S.faceidx += 6;
+ }
+ // draws cylinders and small spheres (at bond radius)
+ drawBondSticks(f, c, t) {
+ var a, h;
+ if (f.style.stick) {
+ var M = f.style.stick;
+ if (!M.hidden) {
+ var w = M.radius || this.defaultStickRadius, S = M.doubleBondScaling || 0.4, T = M.tripleBondScaling || 0.25, R = ((a = M.dashedBondConfig) === null || a === void 0 ? void 0 : a.dashLength) || 0.1, z = ((h = M.dashedBondConfig) === null || h === void 0 ? void 0 : h.gapLength) || 0.25, P = w, B = M.singleBonds || !1, U = M.dashedBonds || !1, F = 0, $ = 0, W, N, G, k, j, Q, ie, pe, he, ue, se, ae = (0, E.getColorFromStyle)(f, M), we, xe, Ie;
+ !f.capDrawn && f.bonds.length < 4 && (F = 2);
+ var oe = (Pe) => {
+ var le = t.imposter ? n.drawStickImposter : o.GLDraw.drawCylinder;
+ return !U && Pe >= 1 ? le : (De, K, Oe, Ne, I, me = 0, ge = 0, Y = 0.1, ne = 0.25) => {
+ var Ee = this.calculateDashes(K, Oe, Ne, Y, ne);
+ Ee.forEach((He) => {
+ le(De, He.from, He.to, Ne, I, me, ge);
+ });
+ };
+ };
+ for (G = 0; G < f.bonds.length; G++) {
+ var ve = oe(f.bondOrder[G]), re = f.bonds[G], Se = c[re];
+ if (we = xe = Ie = null, f.index < Se.index) {
+ var ze = Se.style;
+ if (!ze.stick || ze.stick.hidden)
+ continue;
+ var Ge = (0, E.getColorFromStyle)(Se, ze.stick);
+ if (P = w, k = B, f.bondStyles && f.bondStyles[G]) {
+ if (j = f.bondStyles[G], j.iswire)
+ continue;
+ j.radius && (P = j.radius), j.singleBond && (k = !0), typeof j.color1 < "u" && (ae = x.CC.color(j.color1)), typeof j.color2 < "u" && (Ge = x.CC.color(j.color2));
+ }
+ var $e = new _.Vector3(f.x, f.y, f.z), Re = new _.Vector3(Se.x, Se.y, Se.z);
+ if (f.bondOrder[G] <= 1 || k || f.bondOrder[G] > 3) {
+ if (f.bondOrder[G] < 1 && (P *= f.bondOrder[G]), !Se.capDrawn && Se.bonds.length < 4 && ($ = 2), ae != Ge ? (we = new _.Vector3().addVectors($e, Re).multiplyScalar(0.5), ve(t, $e, we, P, ae, F, 0, R, z), ve(t, we, Re, P, Ge, 0, $, R, z)) : ve(t, $e, Re, P, ae, F, $, R, z), W = f.clickable || f.hoverable, N = Se.clickable || Se.hoverable, W || N) {
+ if (we || (we = new _.Vector3().addVectors($e, Re).multiplyScalar(0.5)), W) {
+ var Be = new g.Cylinder($e, we, P), ke = new g.Sphere($e, P);
+ f.intersectionShape.cylinder.push(Be), f.intersectionShape.sphere.push(ke);
+ }
+ if (N) {
+ var We = new g.Cylinder(Re, we, P), Te = new g.Sphere(Re, P);
+ Se.intersectionShape.cylinder.push(We), Se.intersectionShape.sphere.push(Te);
+ }
+ }
+ } else if (f.bondOrder[G] > 1) {
+ var je = 0, Fe = 0;
+ P != w && (je = 2, Fe = 2);
+ var X = Re.clone(), Z = null;
+ X.sub($e);
+ var q, fe, _e, Me, Ae;
+ Z = this.getSideBondV(f, Se, G), f.bondOrder[G] == 2 ? (q = P * S, Z.multiplyScalar(q * 1.5), fe = $e.clone(), fe.add(Z), _e = $e.clone(), _e.sub(Z), Me = fe.clone(), Me.add(X), Ae = _e.clone(), Ae.add(X), ae != Ge ? (we = new _.Vector3().addVectors(fe, Me).multiplyScalar(0.5), xe = new _.Vector3().addVectors(_e, Ae).multiplyScalar(0.5), ve(t, fe, we, q, ae, je, 0), ve(t, we, Me, q, Ge, 0, Fe), ve(t, _e, xe, q, ae, je, 0), ve(t, xe, Ae, q, Ge, 0, Fe)) : (ve(t, fe, Me, q, ae, je, Fe), ve(t, _e, Ae, q, ae, je, Fe)), W = f.clickable || f.hoverable, N = Se.clickable || Se.hoverable, (W || N) && (we || (we = new _.Vector3().addVectors(fe, Me).multiplyScalar(0.5)), xe || (xe = new _.Vector3().addVectors(_e, Ae).multiplyScalar(0.5)), W && (Q = new g.Cylinder(fe, we, q), ie = new g.Cylinder(_e, xe, q), f.intersectionShape.cylinder.push(Q), f.intersectionShape.cylinder.push(ie)), N && (he = new g.Cylinder(Me, we, q), ue = new g.Cylinder(Ae, xe, q), Se.intersectionShape.cylinder.push(he), Se.intersectionShape.cylinder.push(ue)))) : f.bondOrder[G] == 3 && (q = P * T, Z.cross(X), Z.normalize(), Z.multiplyScalar(q * 3), fe = $e.clone(), fe.add(Z), _e = $e.clone(), _e.sub(Z), Me = fe.clone(), Me.add(X), Ae = _e.clone(), Ae.add(X), ae != Ge ? (we = new _.Vector3().addVectors(fe, Me).multiplyScalar(0.5), xe = new _.Vector3().addVectors(_e, Ae).multiplyScalar(0.5), Ie = new _.Vector3().addVectors($e, Re).multiplyScalar(0.5), ve(t, fe, we, q, ae, je, 0), ve(t, we, Me, q, Ge, 0, Fe), ve(t, $e, Ie, q, ae, F, 0), ve(t, Ie, Re, q, Ge, 0, $), ve(t, _e, xe, q, ae, je, 0), ve(t, xe, Ae, q, Ge, 0, Fe)) : (ve(t, fe, Me, q, ae, je, Fe), ve(t, $e, Re, q, ae, F, $), ve(t, _e, Ae, q, ae, je, Fe)), W = f.clickable || f.hoverable, N = Se.clickable || Se.hoverable, (W || N) && (we || (we = new _.Vector3().addVectors(fe, Me).multiplyScalar(0.5)), xe || (xe = new _.Vector3().addVectors(_e, Ae).multiplyScalar(0.5)), Ie || (Ie = new _.Vector3().addVectors($e, Re).multiplyScalar(0.5)), W && (Q = new g.Cylinder(fe.clone(), we.clone(), q), ie = new g.Cylinder(_e.clone(), xe.clone(), q), pe = new g.Cylinder($e.clone(), Ie.clone(), q), f.intersectionShape.cylinder.push(Q), f.intersectionShape.cylinder.push(ie), f.intersectionShape.cylinder.push(pe)), N && (he = new g.Cylinder(Me.clone(), we.clone(), q), ue = new g.Cylinder(Ae.clone(), xe.clone(), q), se = new g.Cylinder(Re.clone(), Ie.clone(), q), Se.intersectionShape.cylinder.push(he), Se.intersectionShape.cylinder.push(ue), Se.intersectionShape.cylinder.push(se))));
+ }
+ }
+ }
+ var H = !1, ce = 0, ye = !1;
+ for (G = 0; G < f.bonds.length; G++)
+ k = B, f.bondStyles && f.bondStyles[G] && (j = f.bondStyles[G], j.singleBond && (k = !0), j.radius && j.radius != w && (ye = !0)), (k || f.bondOrder[G] == 1) && ce++;
+ ye ? ce > 0 && (H = !0) : ce == 0 && (f.bonds.length > 0 || M.showNonBonded) && (H = !0), H && (P = w, t.imposter ? this.drawSphereImposter(t.sphereGeometry, f, P, ae) : o.GLDraw.drawSphere(t, f, P, ae));
+ }
+ }
+ }
+ // go through all the atoms and regenerate their geometries
+ // we try to have one geometry for each style since this is much much
+ // faster
+ // at some point we should optimize this to avoid unnecessary
+ // recalculation
+ /** param {AtomSpec[]} atoms */
+ createMolObj(f, c) {
+ c = c || {};
+ var t = new l.Object3D(), a = [], h = {}, M = {}, w = this.drawAtomSphere, S = null, T = null;
+ c.supportsImposters ? (w = this.drawAtomImposter, S = new l.Geometry(!0), S.imposter = !0, T = new l.Geometry(!0, !0), T.imposter = !0, T.sphereGeometry = new l.Geometry(!0), T.sphereGeometry.imposter = !0, T.drawnCaps = {}) : c.supportsAIA ? (w = this.drawAtomInstanced, S = new l.Geometry(!1, !0, !0), S.instanced = !0, T = new l.Geometry(!0)) : (S = new l.Geometry(!0), T = new l.Geometry(!0));
+ var R, z, P, B, U = {}, F = [Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY];
+ for (R = 0, P = f.length; R < P; R++) {
+ var $ = f[R];
+ if ($ && $.style) {
+ ($.clickable || $.hoverable) && $.intersectionShape === void 0 && ($.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), B = { line: void 0, cross: void 0, stick: void 0, sphere: void 0 };
+ for (z in B)
+ $.style[z] ? $.style[z].opacity ? B[z] = parseFloat($.style[z].opacity) : B[z] = 1 : B[z] = void 0, U[z] ? B[z] != null && U[z] != B[z] && (console.log("Warning: " + z + " opacity is ambiguous"), U[z] = 1) : U[z] = B[z];
+ w.call(this, $, S), this.drawAtomClickSphere($), this.drawAtomCross($, M), this.drawBondLines($, f, h), this.drawBondSticks($, f, T), typeof $.style.cartoon < "u" && !$.style.cartoon.hidden && ($.style.cartoon.color === "spectrum" && typeof $.resi == "number" && !$.hetflag && ($.resi < F[0] && (F[0] = $.resi), $.resi > F[1] && (F[1] = $.resi)), a.push($));
+ }
+ }
+ if (a.length > 0 && (0, p.drawCartoon)(t, a, F, this.defaultCartoonQuality), S && S.vertices > 0) {
+ S.initTypedArrays();
+ var W = null, N = null;
+ S.imposter ? W = new l.SphereImposterMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }) : S.instanced ? (N = new l.Geometry(!0), o.GLDraw.drawSphere(N, { x: 0, y: 0, z: 0 }, 1, new x.Color(0.5, 0.5, 0.5)), N.initTypedArrays(), W = new l.InstancedMaterial({
+ sphereMaterial: new l.MeshLambertMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }),
+ sphere: N
+ })) : W = new l.MeshLambertMaterial({
+ ambient: 0,
+ vertexColors: !0,
+ reflectivity: 0
+ }), U.sphere < 1 && U.sphere >= 0 && (W.transparent = !0, W.opacity = U.sphere), N = new l.Mesh(S, W), t.add(N);
+ }
+ if (T.vertices > 0) {
+ var G = null, k = null, j = T.sphereGeometry;
+ (!j || typeof j.vertices > "u" || j.vertices == 0) && (j = null), T.initTypedArrays(), j && j.initTypedArrays();
+ var Q = { ambient: 0, vertexColors: !0, reflectivity: 0 };
+ T.imposter ? (G = new l.StickImposterMaterial(Q), k = new l.SphereImposterMaterial(Q)) : (G = new l.MeshLambertMaterial(Q), k = new l.MeshLambertMaterial(Q), G.wireframe && (T.setUpWireframe(), j && j.setUpWireframe())), U.stick < 1 && U.stick >= 0 && (G.transparent = !0, G.opacity = U.stick, k.transparent = !0, k.opacity = U.stick);
+ var ie = new l.Mesh(T, G);
+ if (t.add(ie), j) {
+ var pe = new l.Mesh(j, k);
+ t.add(pe);
+ }
+ }
+ var he;
+ for (R in h)
+ if (h.hasOwnProperty(R)) {
+ he = R;
+ var ue = new l.LineBasicMaterial({
+ linewidth: he,
+ vertexColors: !0
+ });
+ U.line < 1 && U.line >= 0 && (ue.transparent = !0, ue.opacity = U.line), h[R].initTypedArrays();
+ var se = new l.Line(h[R], ue, l.LineStyle.LinePieces);
+ t.add(se);
+ }
+ for (R in M)
+ if (M.hasOwnProperty(R)) {
+ he = R;
+ var ae = new l.LineBasicMaterial({
+ linewidth: he,
+ vertexColors: !0
+ });
+ U.cross < 1 && U.cross >= 0 && (ae.transparent = !0, ae.opacity = U.cross), M[R].initTypedArrays();
+ var we = new l.Line(M[R], ae, l.LineStyle.LinePieces);
+ t.add(we);
+ }
+ if (this.dontDuplicateAtoms && this.modelData.symmetries && this.modelData.symmetries.length > 0) {
+ var xe = new l.Object3D(), Ie;
+ for (Ie = 0; Ie < this.modelData.symmetries.length; Ie++) {
+ var oe = new l.Object3D();
+ oe = t.clone(), oe.matrix.copy(this.modelData.symmetries[Ie]), oe.matrixAutoUpdate = !1, xe.add(oe);
+ }
+ return xe;
+ }
+ return t;
+ }
+ /**
+ * Return object representing internal state of
+ * the model appropriate for passing to setInternalState
+ *
+ */
+ getInternalState() {
+ return {
+ atoms: this.atoms,
+ frames: this.frames
+ };
+ }
+ /**
+ * Overwrite the internal model state with the passed state.
+ *
+ */
+ setInternalState(f) {
+ this.atoms = f.atoms, this.frames = f.frames, this.molObj = null;
+ }
+ /**
+ * Returns crystallographic information if present.
+ *
+ *
+ */
+ getCrystData() {
+ if (this.modelData.cryst) {
+ if (!this.modelData.cryst.matrix) {
+ const f = this.modelData.cryst;
+ this.modelData.cryst.matrix = (0, _.conversionMatrix3)(f.a, f.b, f.c, f.alpha, f.beta, f.gamma);
+ }
+ return this.modelData.cryst;
+ } else
+ return null;
+ }
+ /**
+ * Set crystallographic information using three angles and three lengths
+ *
+ * @param {number} a - length of unit cell side
+ * @param {number} b - length of unit cell side
+ * @param {number} c - length of unit cell side
+ * @param {number} alpha - unit cell angle in degrees (default 90)
+ * @param {number} beta - unit cell angle in degrees (default 90)
+ * @param {number} gamma - unit cell angle in degrees (default 90)
+
+ */
+ setCrystData(f, c, t, a, h, M) {
+ f = f || 1, c = c || 1, t = t || 1, a = a || 90, h = h || 90, M = M || 90;
+ const w = (0, _.conversionMatrix3)(f, c, t, a, h, M);
+ this.modelData.cryst = {
+ a: f,
+ b: c,
+ c: t,
+ alpha: a,
+ beta: h,
+ gamma: M,
+ matrix: w
+ };
+ }
+ /**
+ * Set the crystallographic matrix to the given matrix.
+ *
+ * This function removes `a`, `b`, `c`, `alpha`, `beta`, `gamma` from
+ * the crystal data.
+ *
+ * @param {Matrix3} matrix - unit cell matrix
+ */
+ setCrystMatrix(f) {
+ f = f || new _.Matrix3(1, 0, 0, 0, 1, 0, 0, 0, 1), this.modelData.cryst = {
+ matrix: f
+ };
+ }
+ /**
+ * Returns list of rotational/translational matrices if there is BIOMT data
+ * Otherwise returns a list of just the ID matrix
+ *
+ * @return {Array}
+ *
+ */
+ getSymmetries() {
+ return typeof this.modelData.symmetries > "u" && (this.modelData.symmetries = [this.idMatrix]), this.modelData.symmetries;
+ }
+ /**
+ * Sets symmetries based on specified matrices in list
+ *
+ * @param {Array} list
+ *
+ */
+ setSymmetries(f) {
+ typeof f > "u" ? this.modelData.symmetries = [this.idMatrix] : this.modelData.symmetries = f;
+ }
+ /**
+ * Returns model id number
+ *
+ * @return {number} Model ID
+ */
+ getID() {
+ return this.id;
+ }
+ /**
+ * Returns model's frames property, a list of atom lists
+ *
+ * @return {number}
+ */
+ getNumFrames() {
+ return this.frames.numFrames != null ? this.frames.numFrames : this.frames.length;
+ }
+ adjustCoord(f, c, t, a) {
+ var h = c - f;
+ return h < -t ? c + a : h > t ? c - a : c;
+ }
+ //go over current atoms in depth first order and ensure that connected
+ //attoms aren't split across the box
+ adjustCoordinatesToBox() {
+ if (this.box && this.atomdfs)
+ for (var f = this.box[0], c = this.box[1], t = this.box[2], a = f * 0.9, h = c * 0.9, M = t * 0.9, w = 0; w < this.atomdfs.length; w++)
+ for (var S = this.atomdfs[w], T = 1; T < S.length; T++) {
+ var R = this.atoms[S[T][0]], z = this.atoms[S[T][1]];
+ R.x = this.adjustCoord(z.x, R.x, a, f), R.y = this.adjustCoord(z.y, R.y, h, c), R.z = this.adjustCoord(z.z, R.z, M, t);
+ }
+ }
+ /**
+ * Sets model's atomlist to specified frame
+ * Sets to last frame if framenum out of range
+ *
+ * @param {number} framenum - model's atoms are set to this index in frames list
+ * @return {Promise}
+ */
+ setFrame(f, c) {
+ var t = this.getNumFrames();
+ let a = this;
+ return new Promise(function(h, M) {
+ if (t == 0 && h(), (f < 0 || f >= t) && (f = t - 1), a.frames.url != null) {
+ var w = a.frames.url;
+ (0, E.getbin)(w + "/traj/frame/" + f + "/" + a.frames.path, void 0, "POST", void 0).then(function(S) {
+ for (var T = new Float32Array(S, 44), R = 0, z = 0; z < a.atoms.length; z++)
+ a.atoms[z].x = T[R++], a.atoms[z].y = T[R++], a.atoms[z].z = T[R++];
+ a.box && a.atomdfs && a.adjustCoordinatesToBox(), h();
+ }).catch(M);
+ } else
+ a.atoms = a.frames[f], h();
+ a.molObj = null, a.modelDatas && f < a.modelDatas.length && (a.modelData = a.modelDatas[f], a.unitCellObjects && c && (c.removeUnitCell(a), c.addUnitCell(a)));
+ });
+ }
+ /**
+ * Add atoms as frames of model
+ *
+ * @param {AtomSpec[]} atoms - atoms to be added
+ */
+ addFrame(f) {
+ this.frames.push(f);
+ }
+ /**
+ * If model atoms have dx, dy, dz properties (in some xyz files), vibrate populates the model's frame property based on parameters.
+ * Model can then be animated
+ *
+ * @param {number} numFrames - number of frames to be created, default to 10
+ * @param {number} amplitude - amplitude of distortion, default to 1 (full)
+ * @param {boolean} bothWays - if true, extend both in positive and negative directions by numFrames
+ * @param {GLViewer} viewer - required if arrowSpec is provided
+ * @param {ArrowSpec} arrowSpec - specification for drawing animated arrows. If color isn't specified, atom color (sphere, stick, line preference) is used.
+ *@example
+
+ $3Dmol.download("pdb:4UAA",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.vibrate(10, 1);
+ viewer.animate({loop: "forward",reps: 1});
+
+ viewer.zoomTo();
+ viewer.render();
+ });
+ */
+ vibrate(f = 10, c = 1, t = !1, a, h) {
+ var M = 0, w = f;
+ t && (M = -f, w = f), this.frames !== void 0 && this.frames.origIndex !== void 0 ? this.setFrame(this.frames.origIndex) : this.setFrame(0), M < w && (this.frames = []), t && (this.frames.origIndex = f);
+ for (var S = M; S < w; S++) {
+ var T = [], R = this.frames.length;
+ if (S == 0 && !h) {
+ this.frames.push(this.atoms);
+ continue;
+ }
+ for (var z = 0; z < this.atoms.length; z++) {
+ var P = (0, E.getAtomProperty)(this.atoms[z], "dx"), B = (0, E.getAtomProperty)(this.atoms[z], "dy"), U = (0, E.getAtomProperty)(this.atoms[z], "dz"), F = new _.Vector3(P, B, U), $ = new _.Vector3(this.atoms[z].x, this.atoms[z].y, this.atoms[z].z), W = S * c / f;
+ F.multiplyScalar(W), $.add(F);
+ var N = {};
+ for (var G in this.atoms[z])
+ N[G] = this.atoms[z][G];
+ if (N.x = $.x, N.y = $.y, N.z = $.z, T.push(N), a && h) {
+ var k = (0, E.extend)({}, h), j = new _.Vector3(P, B, U);
+ if (j.multiplyScalar(c), j.add($), k.start = $, k.end = j, k.frame = R, !k.color) {
+ var Q = N.style.sphere;
+ Q || (Q = N.style.stick), Q || (Q = N.style.line), k.color = (0, E.getColorFromStyle)(N, Q);
+ }
+ a.addArrow(k);
+ }
+ }
+ this.frames.push(T);
+ }
+ }
+ // set default style and colors for atoms
+ setAtomDefaults(f) {
+ for (let c = 0; c < f.length; c++) {
+ let t = f[c];
+ t && (t.style = t.style || (0, E.deepCopy)(n.defaultAtomStyle), t.color = t.color || this.ElementColors[t.elem] || this.defaultColor, t.model = this.id, (t.clickable || t.hoverable) && (t.intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }));
+ }
+ }
+ /** add atoms to this model from molecular data string
+ *
+ * @param {string|ArrayBuffer} data - atom structure file input data string, for gzipped input use ArrayBuffer
+ * @param {string} format - input file string format (e.g 'pdb', 'sdf', 'sdf.gz', etc.)
+ * @param {ParserOptionsSpec} options - format dependent options. Attributes depend on the input format
+ */
+ addMolData(f, c, t = {}) {
+ var a = n.parseMolData(f, c, t);
+ this.dontDuplicateAtoms = !t.duplicateAssemblyAtoms;
+ var h = a.modelData;
+ if (h && (Array.isArray(h) ? (this.modelData = h[0], t.frames && (this.modelDatas = h)) : this.modelData = h), a.box ? this.box = a.box : this.box = null, this.frames.length == 0) {
+ for (let w = 0; w < a.length; w++)
+ a[w].length != 0 && this.frames.push(a[w]);
+ this.frames[0] && (this.atoms = this.frames[0]);
+ } else if (t.frames)
+ for (let w = 0; w < a.length; w++)
+ this.frames.push(a[w]);
+ else
+ for (var M = 0; M < a.length; M++)
+ this.addAtoms(a[M]);
+ for (let w = 0; w < this.frames.length; w++)
+ this.setAtomDefaults(this.frames[w]);
+ t.vibrate && t.vibrate.frames && t.vibrate.amplitude && this.vibrate(t.vibrate.frames, t.vibrate.amplitude), t.style && this.setStyle({}, t.style);
+ }
+ setDontDuplicateAtoms(f) {
+ this.dontDuplicateAtoms = f;
+ }
+ setModelData(f) {
+ this.modelData = f;
+ }
+ //return true if atom value matches property val
+ propertyMatches(f, c) {
+ if (f == c)
+ return !0;
+ if (typeof c == "string" && typeof f == "number") {
+ var t = c.match(/(-?\d+)\s*-\s*(-?\d+)/);
+ if (t) {
+ var a = parseInt(t[1]), h = parseInt(t[2]);
+ if (t && f >= a && f <= h)
+ return !0;
+ }
+ }
+ return !1;
+ }
+ // make a deep copy of a selection object and create caches of expensive
+ // selections. We create a copy so caches are not attached to user
+ // supplied objects where the user might change them invalidating the cache.
+ // This does not support arbitrary
+ // javascript objects, but support enough for eveything that is
+ // used in selections: number, string, boolean, functions; as well
+ // as arrays and nested objects with values of the aformentioned
+ // types.
+ static deepCopyAndCache(f, c) {
+ if (typeof f != "object" || f == null || f.__cache_created)
+ return f;
+ const t = {};
+ for (const a in f) {
+ const h = f[a];
+ if (Array.isArray(h)) {
+ t[a] = [];
+ for (let M = 0; M < h.length; M++)
+ t[a].push(n.deepCopyAndCache(h[M], c));
+ } else
+ typeof h == "object" && a != "properties" && a != "model" ? t[a] = n.deepCopyAndCache(h, c) : t[a] = h;
+ if (a == "and" || a == "or") {
+ const M = [];
+ for (const w of t[a]) {
+ const S = /* @__PURE__ */ new Set();
+ for (const T of c.selectedAtoms(w))
+ S.add(T.index);
+ M.push(S);
+ }
+ if (a == "and") {
+ const w = function(T, R) {
+ const z = /* @__PURE__ */ new Set();
+ for (const P of R)
+ T.has(P) && z.add(P);
+ return z;
+ };
+ let S = new Set(M[0]);
+ for (const T of M.splice(1))
+ S = w(S, T);
+ t[a].__cached_results = S;
+ } else if (a == "or") {
+ const w = /* @__PURE__ */ new Set();
+ for (const S of M)
+ for (const T of S)
+ w.add(T);
+ t[a].__cached_results = w;
+ }
+ }
+ }
+ return t.__cache_created = !0, t;
+ }
+ /** given a selection specification, return true if atom is selected.
+ * Does not support context-aware selectors like expand/within/byres.
+ *
+ * @param {AtomSpec} atom
+ * @param {AtomSelectionSpec} sel
+ * @return {boolean}
+ */
+ atomIsSelected(f, c) {
+ if (typeof c > "u")
+ return !0;
+ var t = !!c.invert, a = !0;
+ for (var h in c)
+ if (h == "and" || h == "or" || h == "not") {
+ if (h == "not") {
+ if (this.atomIsSelected(f, c[h])) {
+ a = !1;
+ break;
+ }
+ } else if (c[h].__cached_results === void 0 && (c = n.deepCopyAndCache(c, this)), a = c[h].__cached_results.has(f.index), !a)
+ break;
+ } else if (h === "predicate") {
+ if (!c.predicate(f)) {
+ a = !1;
+ break;
+ }
+ } else if (h == "properties" && f[h]) {
+ for (var M in c.properties)
+ if (!M.startsWith("__cache")) {
+ if (typeof f.properties[M] > "u") {
+ a = !1;
+ break;
+ }
+ if (f.properties[M] != c.properties[M]) {
+ a = !1;
+ break;
+ }
+ }
+ } else if (c.hasOwnProperty(h) && !n.ignoredKeys.has(h) && !h.startsWith("__cache")) {
+ if (typeof f[h] > "u") {
+ a = !1;
+ break;
+ }
+ var w = !1;
+ if (h === "bonds") {
+ var S = c[h];
+ if (S != f.bonds.length) {
+ a = !1;
+ break;
+ }
+ } else if (Array.isArray(c[h])) {
+ var T = c[h], R = f[h];
+ for (let z = 0; z < T.length; z++)
+ if (this.propertyMatches(R, T[z])) {
+ w = !0;
+ break;
+ }
+ if (!w) {
+ a = !1;
+ break;
+ }
+ } else {
+ let z = c[h];
+ if (!this.propertyMatches(f[h], z)) {
+ a = !1;
+ break;
+ }
+ }
+ }
+ return t ? !a : a;
+ }
+ static squaredDistance(f, c) {
+ var t = c.x - f.x, a = c.y - f.y, h = c.z - f.z;
+ return t * t + a * a + h * h;
+ }
+ /** returns a list of atoms in the expanded bounding box, but not in the current one
+ *
+ * Bounding box:
+ *
+ * [ [ xmin, ymin, zmin ],
+ * [ xmax, ymax, zmax ],
+ * [ xctr, yctr, zctr ] ]
+ *
+ **/
+ expandAtomList(f, c) {
+ if (c <= 0)
+ return f;
+ for (var t = (0, E.getExtent)(f, void 0), a = [[], [], []], h = 0; h < 3; h++)
+ a[0][h] = t[0][h] - c, a[1][h] = t[1][h] + c, a[2][h] = t[2][h];
+ var M = [];
+ for (let R = 0; R < this.atoms.length; R++) {
+ var w = this.atoms[R].x, S = this.atoms[R].y, T = this.atoms[R].z;
+ w >= a[0][0] && w <= a[1][0] && S >= a[0][1] && S <= a[1][1] && T >= a[0][2] && T <= a[1][2] && (w >= t[0][0] && w <= t[1][0] && S >= t[0][1] && S <= t[1][1] && T >= t[0][2] && T <= t[1][2] || M.push(this.atoms[R]));
+ }
+ return M;
+ }
+ static getFloat(f) {
+ return typeof f == "number" ? f : parseFloat(f);
+ }
+ /** return list of atoms selected by sel, this is specific to glmodel
+ *
+ * @param {AtomSelectionSpec} sel
+ * @return {Object[]}
+ * @example
+ $3Dmol.download("pdb:4wwy",viewer,{},function(){
+ var atoms = viewer.selectedAtoms({chain:'A'});
+ for(var i = 0, n = atoms.length; i < n; i++) {
+ atoms[i].b = 0.0;
+ }
+ viewer.setStyle({cartoon:{colorscheme:{prop:'b',gradient: 'roygb',min:0,max:30}}});
+ viewer.render();
+ });
+ */
+ selectedAtoms(f, c) {
+ var t = [];
+ f = n.deepCopyAndCache(f || {}, this), c || (c = this.atoms);
+ for (var a = c.length, h = 0; h < a; h++) {
+ var M = c[h];
+ M && this.atomIsSelected(M, f) && t.push(M);
+ }
+ if (f.hasOwnProperty("expand")) {
+ const N = n.getFloat(f.expand);
+ let G = this.expandAtomList(t, N), k = t.length;
+ const j = N * N;
+ for (let Q = 0; Q < G.length; Q++)
+ for (let ie = 0; ie < k; ie++) {
+ var w = n.squaredDistance(G[Q], t[ie]);
+ w < j && w > 0 && t.push(G[Q]);
+ }
+ }
+ if (f.hasOwnProperty("within") && f.within.hasOwnProperty("sel") && f.within.hasOwnProperty("distance")) {
+ var S = this.selectedAtoms(f.within.sel, this.atoms), T = {};
+ const N = n.getFloat(f.within.distance), G = N * N;
+ for (let k = 0; k < S.length; k++)
+ for (let j = 0; j < t.length; j++) {
+ let Q = n.squaredDistance(S[k], t[j]);
+ Q < G && Q > 0 && (T[j] = 1);
+ }
+ var R = [];
+ if (f.within.invert)
+ for (let k = 0; k < t.length; k++)
+ T[k] || R.push(t[k]);
+ else
+ for (let k in T)
+ R.push(t[k]);
+ t = R;
+ }
+ if (f.hasOwnProperty("byres")) {
+ var z = {}, P = [], B = [];
+ for (let N = 0; N < t.length; N++) {
+ let G = t[N];
+ var U = G.chain, F = G.resi;
+ if (z[U] === void 0 && (z[U] = {}), G.hasOwnProperty("resi") && z[U][F] === void 0) {
+ for (z[U][F] = !0, B.push(G); B.length > 0; )
+ if (G = B.pop(), U = G.chain, F = G.resi, P[G.index] === void 0) {
+ P[G.index] = !0;
+ for (var $ = 0; $ < G.bonds.length; $++) {
+ var W = this.atoms[G.bonds[$]];
+ P[W.index] === void 0 && W.hasOwnProperty("resi") && W.chain == U && W.resi == F && (B.push(W), t.push(W));
+ }
+ }
+ }
+ }
+ }
+ return t;
+ }
+ /** Add list of new atoms to model. Adjusts bonds appropriately.
+ *
+ * @param {AtomSpec[]} newatoms
+ * @example
+ * var atoms = [{elem: 'C', x: 0, y: 0, z: 0, bonds: [1,2], bondOrder: [1,2]}, {elem: 'O', x: -1.5, y: 0, z: 0, bonds: [0]},{elem: 'O', x: 1.5, y: 0, z: 0, bonds: [0], bondOrder: [2]}];
+
+ viewer.setBackgroundColor(0xffffffff);
+ var m = viewer.addModel();
+ m.addAtoms(atoms);
+ m.setStyle({},{stick:{}});
+ viewer.zoomTo();
+ viewer.render();
+ */
+ addAtoms(f) {
+ this.molObj = null;
+ var c = this.atoms.length, t = [], a;
+ for (a = 0; a < f.length; a++)
+ typeof f[a].index > "u" && (f[a].index = a), typeof f[a].serial > "u" && (f[a].serial = a), t[f[a].index] = c + a;
+ for (a = 0; a < f.length; a++) {
+ var h = f[a], M = t[h.index], w = (0, E.extend)({}, h);
+ w.index = M, w.bonds = [], w.bondOrder = [], w.model = this.id, w.style = w.style || (0, E.deepCopy)(n.defaultAtomStyle), typeof w.color > "u" && (w.color = this.ElementColors[w.elem] || this.defaultColor);
+ for (var S = h.bonds ? h.bonds.length : 0, T = 0; T < S; T++) {
+ var R = t[h.bonds[T]];
+ typeof R < "u" && (w.bonds.push(R), w.bondOrder.push(h.bondOrder ? h.bondOrder[T] : 1));
+ }
+ this.atoms.push(w);
+ }
+ }
+ /** Assign bonds based on atomic coordinates.
+ * This currently uses a primitive distance-based algorithm that does not
+ * consider valence constraints and will only create single bonds.
+ */
+ assignBonds() {
+ (0, D.assignBonds)(this.atoms, { assignBonds: !0 });
+ }
+ /** Remove specified atoms from model
+ *
+ * @param {AtomSpec[]} badatoms - list of atoms
+ */
+ removeAtoms(f) {
+ this.molObj = null;
+ var c = [], t;
+ for (t = 0; t < f.length; t++)
+ c[f[t].index] = !0;
+ var a = [];
+ for (t = 0; t < this.atoms.length; t++) {
+ var h = this.atoms[t];
+ c[h.index] || a.push(h);
+ }
+ this.atoms = [], this.addAtoms(a);
+ }
+ /** Set atom style of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {AtomStyleSpec} style
+ * @param {boolean} add - if true, add to current style, don't replace
+ @example
+ $3Dmol.download("pdb:4UB9",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+
+ viewer.setStyle({chain:'A'},{line:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'B'},{line:{colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'C'},{cross:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.Sinebow($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'D'},{cross:{colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'E'},{cross:{radius:2.0,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'F'},{stick:{hidden:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.RWB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'G'},{stick:{radius:0.8,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.ROYGB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.setStyle({chain:'H'},{stick:{singleBonds:true,colorscheme:{prop:'b',gradient: new $3Dmol.Gradient.ROYGB($3Dmol.getPropertyRange(viewer.selectedAtoms(),'b'))}}});
+ viewer.render();
+ });
+ */
+ setStyle(f, c, t) {
+ typeof c > "u" && typeof t > "u" && (c = f, f = {}), f = f, typeof c == "string" && (c = (0, E.specStringToObject)(c));
+ var a = !1, h = this, M = function(S) {
+ var T = h.selectedAtoms(f, S);
+ for (let R = 0; R < S.length; R++)
+ S[R] && (S[R].capDrawn = !1);
+ for (let R = 0; R < T.length; R++) {
+ a = !0, (T[R].clickable || T[R].hoverable) && (T[R].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }), t || (T[R].style = {});
+ for (let z in c)
+ c.hasOwnProperty(z) && (T[R].style[z] = T[R].style[z] || {}, Object.assign(T[R].style[z], c[z]));
+ }
+ };
+ if (f.frame !== void 0 && f.frame < this.frames.length) {
+ let S = f.frame;
+ S < 0 && (S = this.frames.length + S), M(this.frames[S]);
+ } else {
+ M(this.atoms);
+ for (var w = 0; w < this.frames.length; w++)
+ this.frames[w] !== this.atoms && M(this.frames[w]);
+ }
+ a && (this.molObj = null);
+ }
+ /** Set clickable and callback of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply clickable settings to
+ * @param {boolean} clickable - whether click-handling is enabled for the selection
+ * @param {function} callback - function called when an atom in the selection is clicked
+
+ */
+ setClickable(f, c, t) {
+ if (c = !!c, t = (0, E.makeFunction)(t), t === null) {
+ console.log("Callback is not a function");
+ return;
+ }
+ var a = this.selectedAtoms(f, this.atoms), h = a.length;
+ for (let M = 0; M < h; M++)
+ a[M].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, a[M].clickable = c, t && (a[M].callback = t);
+ h > 0 && (this.molObj = null);
+ }
+ /** Set hoverable and callback of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply hoverable settings to
+ * @param {boolean} hoverable - whether hover-handling is enabled for the selection
+ * @param {function} hover_callback - function called when an atom in the selection is hovered over
+ * @param {function} unhover_callback - function called when the mouse moves out of the hover area
+ */
+ setHoverable(f, c, t, a) {
+ if (c = !!c, t = (0, E.makeFunction)(t), a = (0, E.makeFunction)(a), t === null) {
+ console.log("Hover_callback is not a function");
+ return;
+ }
+ if (a === null) {
+ console.log("Unhover_callback is not a function");
+ return;
+ }
+ var h = this.selectedAtoms(f, this.atoms), M = h.length;
+ for (let w = 0; w < M; w++)
+ h[w].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, h[w].hoverable = c, t && (h[w].hover_callback = t), a && (h[w].unhover_callback = a);
+ M > 0 && (this.molObj = null);
+ }
+ /** enable context menu of selected atoms
+ *
+ * @param {AtomSelectionSpec} sel - atom selection to apply hoverable settings to
+ * @param {boolean} contextMenuEnabled - whether contextMenu-handling is enabled for the selection
+ */
+ enableContextMenu(f, c) {
+ c = !!c;
+ var t, a = this.selectedAtoms(f, this.atoms), h = a.length;
+ for (t = 0; t < h; t++)
+ a[t].intersectionShape = { sphere: [], cylinder: [], line: [], triangle: [] }, a[t].contextMenuEnabled = c;
+ h > 0 && (this.molObj = null);
+ }
+ /** given a mapping from element to color, set atom colors
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {object} colors
+ */
+ setColorByElement(f, c) {
+ if (!(this.molObj !== null && n.sameObj(c, this.lastColors))) {
+ this.lastColors = c;
+ var t = this.selectedAtoms(f, t);
+ t.length > 0 && (this.molObj = null);
+ for (var a = 0; a < t.length; a++) {
+ var h = t[a];
+ typeof c[h.elem] < "u" && (h.color = c[h.elem]);
+ }
+ }
+ }
+ /**
+ * @param {AtomSelectionSpec} sel
+ * @param {string} prop
+ * @param {Gradient|string} scheme
+ */
+ setColorByProperty(f, c, t, a) {
+ var h, M, w = this.selectedAtoms(f, w);
+ for (this.lastColors = null, w.length > 0 && (this.molObj = null), typeof t == "string" && typeof u.Gradient.builtinGradients[t] < "u" && (t = new u.Gradient.builtinGradients[t]()), t = t, a || (a = t.range()), a || (a = (0, E.getPropertyRange)(w, c)), h = 0; h < w.length; h++) {
+ M = w[h];
+ var S = (0, E.getAtomProperty)(M, c);
+ S != null && (M.color = t.valueToHex(parseFloat(M.properties[c]), a));
+ }
+ }
+ /**
+ * @deprecated use setStyle and colorfunc attribute
+ * @param {AtomSelectionSpec} sel - selection object
+ * @param {function} func - function to be used to set the color
+ @example
+ $3Dmol.download("pdb:4UAA",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+ var colorAsSnake = function(atom) {
+ return atom.resi % 2 ? 'white': 'green'
+ };
+
+ viewer.setStyle( {}, { cartoon: {colorfunc: colorAsSnake }});
+
+ viewer.render();
+ });
+
+ */
+ setColorByFunction(f, c) {
+ var t = this.selectedAtoms(f, t);
+ if (typeof c == "function") {
+ this.lastColors = null, t.length > 0 && (this.molObj = null);
+ for (let a = 0; a < t.length; a++) {
+ let h = t[a];
+ h.color = c(h);
+ }
+ }
+ }
+ /** Convert the model into an object in the format of a ChemDoodle JSON model.
+ *
+ * @param {boolean} whether or not to include style information. Defaults to false.
+ * @return {Object}
+ */
+ toCDObject(f = !1) {
+ var c = { a: [], b: [] };
+ f && (c.s = []);
+ for (let a = 0; a < this.atoms.length; a++) {
+ let h = {}, M = this.atoms[a];
+ if (h.x = M.x, h.y = M.y, h.z = M.z, M.elem != "C" && (h.l = M.elem), f) {
+ for (var t = 0; t < c.s.length && JSON.stringify(M.style) !== JSON.stringify(c.s[t]); )
+ t++;
+ t === c.s.length && c.s.push(M.style), t !== 0 && (h.s = t);
+ }
+ c.a.push(h);
+ for (let w = 0; w < M.bonds.length; w++) {
+ let S = a, T = M.bonds[w];
+ if (S >= T)
+ continue;
+ let R = {
+ b: S,
+ e: T
+ }, z = M.bondOrder[w];
+ z != 1 && (R.o = z), c.b.push(R);
+ }
+ }
+ return c;
+ }
+ /** manage the globj for this model in the possed modelGroup - if it has to be regenerated, remove and add
+ *
+ * @param {Object3D} group
+ * @param Object options
+ */
+ globj(f, c) {
+ (this.molObj === null || c.regen) && (this.molObj = this.createMolObj(this.atoms, c), this.renderedMolObj && (f.remove(this.renderedMolObj), this.renderedMolObj = null), this.renderedMolObj = this.molObj.clone(), this.hidden && (this.renderedMolObj.setVisible(!1), this.molObj.setVisible(!1)), f.add(this.renderedMolObj));
+ }
+ /** return a VRML string representation of the model. Does not include VRML header information
+ * @return VRML
+ */
+ exportVRML() {
+ var f = this.createMolObj(this.atoms, { supportsImposters: !1, supportsAIA: !1 });
+ return f.vrml();
+ }
+ /** Remove any renderable mol object from scene
+ *
+ * @param {Object3D} group
+ */
+ removegl(f) {
+ this.renderedMolObj && (this.renderedMolObj.geometry !== void 0 && this.renderedMolObj.geometry.dispose(), this.renderedMolObj.material !== void 0 && this.renderedMolObj.material.dispose(), f.remove(this.renderedMolObj), this.renderedMolObj = null), this.molObj = null;
+ }
+ /**
+ * Don't show this model in future renderings. Keep all styles and state
+ * so it can be efficiencly shown again.
+ *
+ * * @see GLModel#show
+
+ * @example
+ $3Dmol.download("pdb:3ucr",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.getModel().hide();
+ viewer.render();
+ });
+ */
+ hide() {
+ this.hidden = !0, this.renderedMolObj && this.renderedMolObj.setVisible(!1), this.molObj && this.molObj.setVisible(!1);
+ }
+ /**
+ * Unhide a hidden model
+ * @see GLModel#hide
+ * @example
+ $3Dmol.download("pdb:3ucr",viewer,{},function(){
+ viewer.setStyle({},{stick:{}});
+ viewer.getModel().hide();
+ viewer.render( )
+ viewer.getModel().show()
+ viewer.render();
+ });
+ */
+ show() {
+ this.hidden = !1, this.renderedMolObj && this.renderedMolObj.setVisible(!0), this.molObj && this.molObj.setVisible(!0);
+ }
+ /** Create labels for atoms that show the value of the passed property.
+ *
+ * @param {String} prop - property name
+ * @param {AtomSelectionSpec} sel
+ * @param {GLViewer} viewer
+ * @param {LabelSpec} options
+ */
+ addPropertyLabels(f, c, t, a) {
+ for (var h = this.selectedAtoms(c, h), M = (0, E.deepCopy)(a), w = 0; w < h.length; w++) {
+ var S = h[w], T = null;
+ typeof S[f] < "u" ? T = String(S[f]) : typeof S.properties[f] < "u" && (T = String(S.properties[f])), T != null && (M.position = S, t.addLabel(T, M));
+ }
+ }
+ /** Create labels for residues of selected atoms.
+ * Will create a single label at the center of mass of all atoms
+ * with the same chain,resn, and resi.
+ *
+ * @param {AtomSelectionSpec} sel
+ * @param {GLViewer} viewer
+ * @param {LabelSpec} options
+ * @param {boolean} byframe - if true, create labels for every individual frame, not just current; frames must be loaded already
+ */
+ addResLabels(f, c, t, a = !1) {
+ var h = [], M = function(S, T) {
+ for (var R = S.selectedAtoms(f, R), z = {}, P = 0; P < R.length; P++) {
+ var B = R[P], U = B.chain, F = B.resn, $ = B.resi, W = F + "" + $;
+ z[U] || (z[U] = {}), z[U][W] || (z[U][W] = []), z[U][W].push(B);
+ }
+ var N = (0, E.deepCopy)(t);
+ for (let k in z)
+ if (z.hasOwnProperty(k)) {
+ var G = z[k];
+ for (let j in G)
+ if (G.hasOwnProperty(j)) {
+ let Q = G[j], ie = new _.Vector3(0, 0, 0);
+ for (let he = 0; he < Q.length; he++) {
+ let ue = Q[he];
+ ie.x += ue.x, ie.y += ue.y, ie.z += ue.z;
+ }
+ ie.divideScalar(Q.length), N.position = ie, N.frame = T;
+ let pe = c.addLabel(j, N, void 0, !0);
+ h.push(pe);
+ }
+ }
+ };
+ if (a) {
+ var w = this.getNumFrames();
+ let S = this.atoms;
+ for (let T = 0; T < w; T++)
+ this.frames[T] && (this.atoms = this.frames[T], M(this, T));
+ this.atoms = S;
+ } else
+ M(this);
+ return h;
+ }
+ //recurse over the current atoms to establish a depth first order
+ setupDFS() {
+ this.atomdfs = [];
+ var f = this, c = new Int8Array(this.atoms.length);
+ c.fill(0);
+ for (var t = function(w, S, T) {
+ T.push([w, S]);
+ var R = f.atoms[w];
+ c[w] = 1;
+ for (var z = 0; z < R.bonds.length; z++) {
+ var P = R.bonds[z];
+ f.atoms[P] && !c[P] && t(P, w, T);
+ }
+ }, a = 0; a < this.atoms.length; a++) {
+ var h = this.atoms[a];
+ if (h && !c[a]) {
+ var M = [];
+ t(a, -1, M), this.atomdfs.push(M);
+ }
+ }
+ }
+ /**
+ * Set coordinates from remote trajectory file.
+ * @param {string} url - contains the url where mdsrv has been hosted
+ * @param {string} path - contains the path of the file (/filename)
+ * @return {Promise}
+ */
+ setCoordinatesFromURL(f, c) {
+ this.frames = [];
+ var t = this;
+ return this.box && this.setupDFS(), f.startsWith("http") || (f = "http://" + f), (0, E.get)(f + "/traj/numframes/" + c, function(a) {
+ if (!isNaN(parseInt(a)))
+ return t.frames.push(t.atoms), t.frames.numFrames = a, t.frames.url = f, t.frames.path = c, t.setFrame(0);
+ });
+ }
+ /**
+ * Set coordinates for the atoms from provided trajectory file.
+ * @param {string|ArrayBuffer} str - contains the data of the file
+ * @param {string} format - contains the format of the file (mdcrd, inpcrd, pdb, netcdf, or array). Arrays should be TxNx3 where T is the number of timesteps and N the number of atoms.
+ @example
+ let m = viewer.addModel() //create an empty model
+ m.addAtoms([{x:0,y:0,z:0,elem:'C'},{x:2,y:0,z:0,elem:'C'}]) //provide a list of dictionaries representing the atoms
+ viewer.setStyle({'sphere':{}})
+ m.setCoordinates([[[0.0, 0.0, 0.0], [2.0, 0.0, 0.0]], [[0.0, 0.0, 0.0], [2.8888888359069824, 0.0, 0.0]], [[0.0, 0.0, 0.0], [3.777777671813965, 0.0, 0.0]], [[0.0, 0.0, 0.0], [4.666666507720947, 0.0, 0.0]], [[0.0, 0.0, 0.0], [5.55555534362793, 0.0, 0.0]], [[0.0, 0.0, 0.0], [6.44444465637207, 0.0, 0.0]], [[0.0, 0.0, 0.0], [7.333333492279053, 0.0, 0.0]], [[0.0, 0.0, 0.0], [8.222222328186035, 0.0, 0.0]], [[0.0, 0.0, 0.0], [9.11111068725586, 0.0, 0.0]], [[0.0, 0.0, 0.0], [10.0, 0.0, 0.0]]],'array');
+ viewer.animate({loop: "forward",reps: 1});
+ viewer.zoomTo();
+ viewer.zoom(0.5);
+ viewer.render();
+ */
+ setCoordinates(f, c) {
+ if (c = c || "", !f)
+ return [];
+ if (/\.gz$/.test(c)) {
+ c = c.replace(/\.gz$/, "");
+ try {
+ f = r(f);
+ } catch (z) {
+ console.log(z);
+ }
+ }
+ var t = { mdcrd: "", inpcrd: "", pdb: "", netcdf: "", array: "" };
+ if (t.hasOwnProperty(c)) {
+ this.frames = [];
+ for (var a = this.atoms.length, h = n.parseCrd(f, c), M = 0; M < h.length; ) {
+ for (var w = [], S = 0; S < a; S++) {
+ var T = {};
+ for (var R in this.atoms[S])
+ T[R] = this.atoms[S][R];
+ w[S] = T, w[S].x = h[M++], w[S].y = h[M++], w[S].z = h[M++];
+ }
+ this.frames.push(w);
+ }
+ return this.atoms = this.frames[0], this.frames;
+ }
+ return [];
+ }
+ /**
+ * add atomSpecs to validAtomSelectionSpecs
+ * @deprecated
+ * @param {Array} customAtomSpecs - array of strings that can be used as atomSelectionSpecs
+ * this is to prevent the 'Unknown Selector x' message on the console for the strings passed.
+ * These messages are no longer generated as, in theory, typescript will catch problems at compile time.
+ * In practice, there may still be issues at run-time but we don't check for them...
+ *
+ * What we should do is use something like https://github.com/woutervh-/typescript-is to do runtime
+ * type checking, but it currently doesn't work with our types...
+ */
+ addAtomSpecs(f) {
+ }
+ static parseCrd(f, c) {
+ var t = [], a = 0;
+ if (c == "pdb")
+ for (var h = f.indexOf(`
+ATOM`); h != -1; ) {
+ for (; f.slice(h, h + 5) == `
+ATOM` || f.slice(h, h + 7) == `
+HETATM`; )
+ t[a++] = parseFloat(f.slice(h + 31, h + 39)), t[a++] = parseFloat(f.slice(h + 39, h + 47)), t[a++] = parseFloat(f.slice(h + 47, h + 55)), h = f.indexOf(`
+`, h + 54), f.slice(h, h + 4) == `
+TER` && (h = f.indexOf(`
+`, h + 5));
+ h = f.indexOf(`
+ATOM`, h);
+ }
+ else if (c == "netcdf") {
+ var M = new C.NetCDFReader(f);
+ t = [].concat.apply([], M.getDataVariable("coordinates"));
+ } else {
+ if (c == "array" || Array.isArray(f))
+ return f.flat(2);
+ {
+ let w = f.indexOf(`
+`);
+ c == "inpcrd" && (w = f.indexOf(`
+`, w + 1)), f = f.slice(w + 1), t = f.match(/\S+/g).map(parseFloat);
+ }
+ }
+ return t;
+ }
+ static parseMolData(f, c = "", t) {
+ if (!f)
+ return [];
+ if (/\.gz$/.test(c)) {
+ c = c.replace(/\.gz$/, "");
+ try {
+ f = r(f);
+ } catch (M) {
+ console.log(M);
+ }
+ }
+ typeof A.Parsers[c] > "u" && (c = c.split(".").pop(), typeof A.Parsers[c] > "u" && (console.log("Unknown format: " + c), f instanceof Uint8Array ? c = "mmtf" : f.match(/^@MOLECULE/gm) ? c = "mol2" : f.match(/^data_/gm) && f.match(/^loop_/gm) ? c = "cif" : f.match(/^HETATM/gm) || f.match(/^ATOM/gm) ? c = "pdb" : f.match(/ITEM: TIMESTEP/gm) ? c = "lammpstrj" : f.match(/^.*\n.*\n.\s*(\d+)\s+(\d+)/gm) ? c = "sdf" : f.match(/^%VERSION\s+VERSION_STAMP/gm) ? c = "prmtop" : c = "xyz", console.log("Best guess: " + c)));
+ var a = A.Parsers[c], h = a(f, t);
+ return h;
+ }
+ }
+ n.defaultAtomStyle = {
+ line: {}
+ }, n.defaultlineWidth = 1, n.vdwRadii = {
+ H: 1.2,
+ He: 1.4,
+ Li: 1.82,
+ Be: 1.53,
+ B: 1.92,
+ C: 1.7,
+ N: 1.55,
+ O: 1.52,
+ F: 1.47,
+ Ne: 1.54,
+ Na: 2.27,
+ Mg: 1.73,
+ Al: 1.84,
+ Si: 2.1,
+ P: 1.8,
+ S: 1.8,
+ Cl: 1.75,
+ Ar: 1.88,
+ K: 2.75,
+ Ca: 2.31,
+ Ni: 1.63,
+ Cu: 1.4,
+ Zn: 1.39,
+ Ga: 1.87,
+ Ge: 2.11,
+ As: 1.85,
+ Se: 1.9,
+ Br: 1.85,
+ Kr: 2.02,
+ Rb: 3.03,
+ Sr: 2.49,
+ Pd: 1.63,
+ Ag: 1.72,
+ Cd: 1.58,
+ In: 1.93,
+ Sn: 2.17,
+ Sb: 2.06,
+ Te: 2.06,
+ I: 1.98,
+ Xe: 2.16,
+ Cs: 3.43,
+ Ba: 2.68,
+ Pt: 1.75,
+ Au: 1.66,
+ Hg: 1.55,
+ Tl: 1.96,
+ Pb: 2.02,
+ Bi: 2.07,
+ Po: 1.97,
+ At: 2.02,
+ Rn: 2.2,
+ Fr: 3.48,
+ Ra: 2.83,
+ U: 1.86
+ }, n.ignoredKeys = /* @__PURE__ */ new Set(["props", "invert", "model", "frame", "byres", "expand", "within", "and", "or", "not"]);
+ }
+ ),
+ /***/
+ "./src/GLShape.ts": (
+ /*!************************!*\
+ !*** ./src/GLShape.ts ***!
+ \************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ GLShape: () => (
+ /* binding */
+ C
+ ),
+ /* harmony export */
+ splitMesh: () => (
+ /* binding */
+ L
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), g = e(
+ /*! ./WebGL/shapes */
+ "./src/WebGL/shapes/index.ts"
+ ), _ = e(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), x = e(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), o = e(
+ /*! ./ProteinSurface4 */
+ "./src/ProteinSurface4.ts"
+ ), p = e(
+ /*! ./VolumeData */
+ "./src/VolumeData.ts"
+ ), E = e(
+ /*! ./GLDraw */
+ "./src/GLDraw.ts"
+ ), u = e(
+ /*! ./glcartoon */
+ "./src/glcartoon.ts"
+ ), A = e(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ );
+ class C {
+ static finalizeGeo(r) {
+ var n = r.updateGeoGroup(0);
+ n.vertices > 0 && n.truncateArrayBuffers(!0, !0);
+ }
+ /*
+ *
+ * @param {Geometry}
+ * geo
+ * @param {Color | colorlike} color
+ */
+ static updateColor(r, n) {
+ n = n || x.CC.color(n), r.colorsNeedUpdate = !0;
+ var b, f, c;
+ n.constructor !== Array && (b = n.r, f = n.g, c = n.b);
+ for (let t in r.geometryGroups) {
+ let a = r.geometryGroups[t], h = a.colorArray;
+ for (let M = 0, w = a.vertices; M < w; ++M) {
+ if (n.constructor === Array) {
+ let S = n[M];
+ b = S.r, f = S.g, c = S.b;
+ }
+ h[M * 3] = b, h[M * 3 + 1] = f, h[M * 3 + 2] = c;
+ }
+ }
+ }
+ /*
+ * @param {GLShape}
+ * shape
+ * @param {geometryGroup}
+ * geoGroup
+ * @param {ArrowSpec}
+ * spec
+ */
+ static drawArrow(r, n, b) {
+ var f = b.start, c = b.end, t = b.radius, a = b.radiusRatio, h = b.mid, M = b.midpos;
+ if (!(f && c))
+ return;
+ var w = n.updateGeoGroup(51), S = new _.Vector3(c.x, c.y, c.z).sub(f);
+ if (M) {
+ let le = S.length();
+ M > 0 ? h = M / le : h = (le + M) / le;
+ }
+ S.multiplyScalar(h);
+ var T = new _.Vector3(f.x, f.y, f.z).add(S), R = S.clone().negate();
+ let z = new _.Vector3(f.x, f.y, f.z);
+ r.intersectionShape.cylinder.push(new g.Cylinder(z, T.clone(), t)), r.intersectionShape.sphere.push(new g.Sphere(z, t));
+ var P = [];
+ P[0] = S.clone(), Math.abs(P[0].x) > 1e-4 ? P[0].y += 1 : P[0].x += 1, P[0].cross(S), P[0].normalize(), P[4] = P[0].clone(), P[4].crossVectors(P[0], S), P[4].normalize(), P[8] = P[0].clone().negate(), P[12] = P[4].clone().negate(), P[2] = P[0].clone().add(P[4]).normalize(), P[6] = P[4].clone().add(P[8]).normalize(), P[10] = P[8].clone().add(P[12]).normalize(), P[14] = P[12].clone().add(P[0]).normalize(), P[1] = P[0].clone().add(P[2]).normalize(), P[3] = P[2].clone().add(P[4]).normalize(), P[5] = P[4].clone().add(P[6]).normalize(), P[7] = P[6].clone().add(P[8]).normalize(), P[9] = P[8].clone().add(P[10]).normalize(), P[11] = P[10].clone().add(P[12]).normalize(), P[13] = P[12].clone().add(P[14]).normalize(), P[15] = P[14].clone().add(P[0]).normalize();
+ var B = w.vertices, U = w.vertexArray, F = w.faceArray, $ = w.normalArray, W = w.lineArray, N, G, k;
+ for (G = 0, k = P.length; G < k; ++G) {
+ N = 3 * (B + 3 * G);
+ var j = P[G].clone().multiplyScalar(t).add(f), Q = P[G].clone().multiplyScalar(t).add(T), ie = P[G].clone().multiplyScalar(t * a).add(T);
+ if (U[N] = j.x, U[N + 1] = j.y, U[N + 2] = j.z, U[N + 3] = Q.x, U[N + 4] = Q.y, U[N + 5] = Q.z, U[N + 6] = ie.x, U[N + 7] = ie.y, U[N + 8] = ie.z, G > 0) {
+ var pe = U[N - 3], he = U[N - 2], ue = U[N - 1], se = new _.Vector3(pe, he, ue), ae = new _.Vector3(c.x, c.y, c.z), we = T.clone(), xe = new _.Vector3(ie.x, ie.y, ie.z);
+ r.intersectionShape.triangle.push(new g.Triangle(xe, ae, se)), r.intersectionShape.triangle.push(new g.Triangle(se.clone(), we, xe.clone()));
+ }
+ }
+ w.vertices += 48, N = w.vertices * 3, U[N] = f.x, U[N + 1] = f.y, U[N + 2] = f.z, U[N + 3] = T.x, U[N + 4] = T.y, U[N + 5] = T.z, U[N + 6] = c.x, U[N + 7] = c.y, U[N + 8] = c.z, w.vertices += 3;
+ var Ie, oe, ve, re, Se, ze, Ge, $e, Re, Be, ke, We, Te, je, Fe, X, Z, q, fe, _e = w.vertices - 3, Me = w.vertices - 2, Ae = w.vertices - 1, H = _e * 3, ce = Me * 3, ye = Ae * 3;
+ for (G = 0, k = P.length - 1; G < k; ++G) {
+ var Pe = B + 3 * G;
+ N = Pe * 3, oe = w.faceidx, ve = w.lineidx, re = Pe, Be = re * 3, Se = Pe + 1, ke = Se * 3, ze = Pe + 2, We = ze * 3, Ge = Pe + 4, Te = Ge * 3, $e = Pe + 5, je = $e * 3, Re = Pe + 3, Fe = Re * 3, X = Z = P[G], q = fe = P[G + 1], $[Be] = X.x, $[ke] = Z.x, $[Fe] = fe.x, $[Be + 1] = X.y, $[ke + 1] = Z.y, $[Fe + 1] = fe.y, $[Be + 2] = X.z, $[ke + 2] = Z.z, $[Fe + 2] = fe.z, $[ke] = Z.x, $[Te] = q.x, $[Fe] = fe.x, $[ke + 1] = Z.y, $[Te + 1] = q.y, $[Fe + 1] = fe.y, $[ke + 2] = Z.z, $[Te + 2] = q.z, $[Fe + 2] = fe.z, $[We] = Z.x, $[je] = q.x, $[We + 1] = Z.y, $[je + 1] = q.y, $[We + 2] = Z.z, $[je + 2] = q.z, F[oe] = re, F[oe + 1] = Se, F[oe + 2] = Re, F[oe + 3] = Se, F[oe + 4] = Ge, F[oe + 5] = Re, F[oe + 6] = re, F[oe + 7] = Re, F[oe + 8] = _e, F[oe + 9] = ze, F[oe + 10] = Me, F[oe + 11] = $e, F[oe + 12] = ze, F[oe + 13] = Ae, F[oe + 14] = $e, W[ve] = re, W[ve + 1] = Se, W[ve + 2] = re, W[ve + 3] = Re, W[ve + 4] = Ge, W[ve + 5] = Re, W[ve + 6] = re, W[ve + 7] = Re, W[ve + 8] = ze, W[ve + 9] = Se, W[ve + 10] = ze, W[ve + 11] = $e, W[ve + 12] = Ge, W[ve + 13] = $e, W[ve + 14] = ze, W[ve + 15] = Ae, W[ve + 16] = ze, W[ve + 17] = $e, W[ve + 18] = Ae, W[ve + 19] = $e, w.faceidx += 15, w.lineidx += 20;
+ }
+ Ie = [
+ B + 45,
+ B + 46,
+ B + 1,
+ B,
+ B + 47,
+ B + 2
+ ], oe = w.faceidx, ve = w.lineidx, re = Ie[0], Be = re * 3, Se = Ie[1], ke = Se * 3, ze = Ie[4], We = ze * 3, Ge = Ie[2], Te = Ge * 3, $e = Ie[5], je = $e * 3, Re = Ie[3], Fe = Re * 3, X = Z = P[15], q = fe = P[0], $[Be] = X.x, $[ke] = Z.x, $[Fe] = fe.x, $[Be + 1] = X.y, $[ke + 1] = Z.y, $[Fe + 1] = fe.y, $[Be + 2] = X.z, $[ke + 2] = Z.z, $[Fe + 2] = fe.z, $[ke] = Z.x, $[Te] = q.x, $[Fe] = fe.x, $[ke + 1] = Z.y, $[Te + 1] = q.y, $[Fe + 1] = fe.y, $[ke + 2] = Z.z, $[Te + 2] = q.z, $[Fe + 2] = fe.z, $[We] = Z.x, $[je] = q.x, $[We + 1] = Z.y, $[je + 1] = q.y, $[We + 2] = Z.z, $[je + 2] = q.z, S.normalize(), R.normalize(), $[H] = R.x, $[ce] = $[ye] = S.x, $[H + 1] = R.y, $[ce + 1] = $[ye + 1] = S.y, $[H + 2] = R.z, $[ce + 2] = $[ye + 2] = S.z, F[oe] = re, F[oe + 1] = Se, F[oe + 2] = Re, F[oe + 3] = Se, F[oe + 4] = Ge, F[oe + 5] = Re, F[oe + 6] = re, F[oe + 7] = Re, F[oe + 8] = _e, F[oe + 9] = ze, F[oe + 10] = Me, F[oe + 11] = $e, F[oe + 12] = ze, F[oe + 13] = Ae, F[oe + 14] = $e, W[ve] = re, W[ve + 1] = Se, W[ve + 2] = re, W[ve + 3] = Re, W[ve + 4] = Ge, W[ve + 5] = Re, W[ve + 6] = re, W[ve + 7] = Re, W[ve + 8] = ze, W[ve + 9] = Se, W[ve + 10] = ze, W[ve + 11] = $e, W[ve + 12] = Ge, W[ve + 13] = $e, W[ve + 14] = ze, W[ve + 15] = Ae, W[ve + 16] = ze, W[ve + 17] = $e, W[ve + 18] = Ae, W[ve + 19] = $e, w.faceidx += 15, w.lineidx += 20;
+ }
+ // Update a bounding sphere's position and radius
+ // from list of centroids and new points
+ /*
+ * @param {Sphere}
+ * sphere
+ * @param {Object}
+ * components, centroid of all objects in shape
+ * @param {Array}
+ * points, flat array of all points in shape
+ * @param {int} numPoints, number of valid poitns in points
+ */
+ static updateBoundingFromPoints(r, n, b, f) {
+ r.center.set(0, 0, 0);
+ let c = 1 / 0, t = 1 / 0, a = 1 / 0, h = -1 / 0, M = -1 / 0, w = -1 / 0;
+ r.box && (c = r.box.min.x, h = r.box.max.x, t = r.box.min.y, M = r.box.max.y, a = r.box.min.z, w = r.box.max.z);
+ for (let z = 0, P = f; z < P; z++) {
+ var S = b[z * 3], T = b[z * 3 + 1], R = b[z * 3 + 2];
+ S < c && (c = S), T < t && (t = T), R < a && (a = R), S > h && (h = S), T > M && (M = T), R > w && (w = R);
+ }
+ r.center.set((h + c) / 2, (M + t) / 2, (w + a) / 2), r.radius = r.center.distanceTo({ x: h, y: M, z: w }), r.box = { min: { x: c, y: t, z: a }, max: { x: h, y: M, z: w } };
+ }
+ //helper function for adding an appropriately sized mesh
+ static addCustomGeo(r, n, b, f, c) {
+ var t = n.addGeoGroup(), a = b.vertexArr, h = b.normalArr, M = b.faceArr;
+ t.vertices = a.length, t.faceidx = M.length;
+ var w, S, T, R, z, P, B, U, F, $ = t.vertexArray, W = t.colorArray;
+ for (f.constructor !== Array && (U = f.r, F = f.g, R = f.b), P = 0, B = t.vertices; P < B; ++P)
+ w = P * 3, S = a[P], $[w] = S.x, $[w + 1] = S.y, $[w + 2] = S.z, f.constructor === Array && (z = f[P], U = z.r, F = z.g, R = z.b), W[w] = U, W[w + 1] = F, W[w + 2] = R;
+ if (c)
+ for (P = 0, B = t.faceidx / 3; P < B; ++P) {
+ w = P * 3, T = M[w], R = M[w + 1], z = M[w + 2];
+ var N = new _.Vector3(), G = new _.Vector3(), k = new _.Vector3();
+ r.intersectionShape.triangle.push(new g.Triangle(N.copy(a[T]), G.copy(a[R]), k.copy(a[z])));
+ }
+ if (c) {
+ var j = new _.Vector3(0, 0, 0), Q = 0;
+ for (let he = 0; he < n.geometryGroups.length; he++)
+ j.add(n.geometryGroups[he].getCentroid()), Q++;
+ j.divideScalar(Q), C.updateBoundingFromPoints(r.boundingSphere, { centroid: j }, $, t.vertices);
+ }
+ if (t.faceArray = new Uint16Array(M), t.truncateArrayBuffers(!0, !0), h.length < t.vertices)
+ t.setNormals();
+ else {
+ var ie = t.normalArray = new Float32Array(t.vertices * 3), pe;
+ for (P = 0, B = t.vertices; P < B; ++P)
+ w = P * 3, pe = h[P], ie[w] = pe.x, ie[w + 1] = pe.y, ie[w + 2] = pe.z;
+ }
+ t.setLineIndices(), t.lineidx = t.lineArray.length;
+ }
+ /*
+ *
+ * @param {$3Dmol.GLShape}
+ * shape
+ * @param {ShapeSpec}
+ * stylespec
+ * @returns {undefined}
+ */
+ static updateFromStyle(r, n) {
+ typeof n.color < "u" ? (r.color = n.color || new x.Color(), n.color instanceof x.Color || (r.color = x.CC.color(n.color))) : r.color = x.CC.color(0), r.wireframe = !!n.wireframe, r.opacity = n.alpha ? (0, _.clamp)(n.alpha, 0, 1) : 1, typeof n.opacity < "u" && (r.opacity = (0, _.clamp)(n.opacity, 0, 1)), r.side = n.side !== void 0 ? n.side : l.DoubleSide, r.linewidth = typeof n.linewidth > "u" ? 1 : n.linewidth, r.clickable = !!n.clickable, r.callback = (0, A.makeFunction)(n.callback), r.hoverable = !!n.hoverable, r.hover_callback = (0, A.makeFunction)(n.hover_callback), r.unhover_callback = (0, A.makeFunction)(n.unhover_callback), r.hidden = n.hidden, r.frame = n.frame;
+ }
+ /**
+ * Custom renderable shape
+ *
+ * @constructor
+ *
+ * @param {ShapeSpec} stylespec
+ */
+ constructor(r) {
+ this.color = 16777215, this.hidden = !1, this.wireframe = !1, this.opacity = 1, this.linewidth = 1, this.clickable = !1, this.hoverable = !1, this.side = l.DoubleSide, this.stylespec = r || {}, this.boundingSphere = new g.Sphere(), this.intersectionShape = {
+ sphere: [],
+ cylinder: [],
+ line: [],
+ triangle: []
+ }, C.updateFromStyle(this, this.stylespec), this.components = [], this.shapeObj = null, this.renderedShapeObj = null, this.geo = new l.Geometry(!0), this.linegeo = new l.Geometry(!0);
+ }
+ /** Update shape with new style specification
+ * @param {ShapeSpec} newspec
+ @example
+ let sphere = viewer.addSphere({center:{x:0,y:0,z:0},radius:10.0,color:'red'});
+ sphere.updateStyle({color:'yellow',opacity:0.5});
+ viewer.render();
+ */
+ updateStyle(r) {
+ for (var n in r)
+ this.stylespec[n] = r[n];
+ if (C.updateFromStyle(this, this.stylespec), r.voldata && r.volscheme) {
+ (0, A.adjustVolumeStyle)(r);
+ const b = r.volscheme, f = r.voldata, c = x.CC, t = b.range() || [-1, 1];
+ this.geo.setColors(function(a, h, M) {
+ let w = f.getVal(a, h, M);
+ return c.color(b.valueToHex(w, t));
+ }), delete this.color;
+ }
+ }
+ /**
+ * Creates a custom shape from supplied vertex and face arrays
+ * @param {CustomShapeSpec} customSpec
+ */
+ addCustom(r) {
+ r.vertexArr = r.vertexArr || [], r.faceArr = r.faceArr || [], r.normalArr = r.normalArr || [], C.drawCustom(this, this.geo, r);
+ }
+ /**
+ * Creates a sphere shape
+ * @param {SphereSpec} sphereSpec
+ @example
+ viewer.addSphere({center:{x:0,y:0,z:0},radius:10.0,color:'red'});
+
+ viewer.render();
+ */
+ addSphere(r) {
+ r.center || (r.center = new _.Vector3(0, 0, 0)), r.radius = r.radius ? (0, _.clamp)(r.radius, 0, 1 / 0) : 1.5, r.color = x.CC.color(r.color), this.intersectionShape.sphere.push(new g.Sphere(r.center, r.radius)), E.GLDraw.drawSphere(this.geo, r.center, r.radius, r.color, r.quality), this.components.push({
+ centroid: new _.Vector3(r.center.x, r.center.y, r.center.z)
+ });
+ var n = this.geo.updateGeoGroup(0);
+ C.updateBoundingFromPoints(this.boundingSphere, this.components, n.vertexArray, n.vertices);
+ }
+ /**
+ * Creates a box
+ * @param {BoxSpec} boxSpec
+ @example
+ var shape = viewer.addShape({color:'red'});
+ shape.addBox({corner: {x:1,y:2,z:0}, dimensions: {w: 4, h: 2, d: 6}});
+ shape.addBox({corner: {x:-5,y:-3,z:0},
+ dimensions: { w: {x:1,y:1,z:0},
+ h: {x:-1,y:1,z:0},
+ d: {x:0,y:0,z:1} }});
+ viewer.zoomTo();
+ viewer.rotate(30);
+ viewer.render();
+ */
+ addBox(r) {
+ var n = r.dimensions || { w: 1, h: 1, d: 1 }, b;
+ typeof n.w == "number" ? b = { x: n.w, y: 0, z: 0 } : b = n.w;
+ var f;
+ typeof n.h == "number" ? f = { x: 0, y: n.h, z: 0 } : f = n.h;
+ var c;
+ typeof n.d == "number" ? c = { x: 0, y: 0, z: n.d } : c = n.d;
+ var t = r.corner;
+ t == null && (r.center !== void 0 ? t = {
+ x: r.center.x - 0.5 * (b.x + f.x + c.x),
+ y: r.center.y - 0.5 * (b.y + f.y + c.y),
+ z: r.center.z - 0.5 * (b.z + f.z + c.z)
+ } : t = { x: 0, y: 0, z: 0 });
+ var a = [
+ { x: t.x, y: t.y, z: t.z },
+ { x: t.x + b.x, y: t.y + b.y, z: t.z + b.z },
+ { x: t.x + f.x, y: t.y + f.y, z: t.z + f.z },
+ { x: t.x + b.x + f.x, y: t.y + b.y + f.y, z: t.z + b.z + f.z },
+ { x: t.x + c.x, y: t.y + c.y, z: t.z + c.z },
+ { x: t.x + b.x + c.x, y: t.y + b.y + c.y, z: t.z + b.z + c.z },
+ { x: t.x + f.x + c.x, y: t.y + f.y + c.y, z: t.z + f.z + c.z },
+ { x: t.x + b.x + f.x + c.x, y: t.y + b.y + f.y + c.y, z: t.z + b.z + f.z + c.z }
+ ], h = [], M = [];
+ h.splice(h.length, 0, a[0], a[1], a[2], a[3]), M.splice(M.length, 0, 0, 2, 1, 1, 2, 3);
+ var w = 4;
+ h.splice(h.length, 0, a[2], a[3], a[6], a[7]), M.splice(M.length, 0, w + 0, w + 2, w + 1, w + 1, w + 2, w + 3), w += 4, h.splice(h.length, 0, a[4], a[5], a[0], a[1]), M.splice(M.length, 0, w + 0, w + 2, w + 1, w + 1, w + 2, w + 3), w += 4, h.splice(h.length, 0, a[6], a[7], a[4], a[5]), M.splice(M.length, 0, w + 0, w + 2, w + 1, w + 1, w + 2, w + 3), w += 4, h.splice(h.length, 0, a[3], a[1], a[7], a[5]), M.splice(M.length, 0, w + 0, w + 2, w + 1, w + 1, w + 2, w + 3), w += 4, h.splice(h.length, 0, a[2], a[6], a[0], a[4]), M.splice(M.length, 0, w + 0, w + 2, w + 1, w + 1, w + 2, w + 3), w += 4;
+ var S = (0, A.extend)({}, r);
+ S.vertexArr = h, S.faceArr = M, S.normalArr = [], C.drawCustom(this, this.geo, S);
+ var T = new _.Vector3();
+ this.components.push({
+ centroid: T.addVectors(a[0], a[7]).multiplyScalar(0.5)
+ });
+ var R = this.geo.updateGeoGroup(0);
+ C.updateBoundingFromPoints(this.boundingSphere, this.components, R.vertexArray, R.vertices);
+ }
+ /**
+ * Creates a cylinder shape
+ * @param {CylinderSpec} cylinderSpec
+ @example
+ viewer.addCylinder({start:{x:0.0,y:0.0,z:0.0},
+ end:{x:10.0,y:0.0,z:0.0},
+ radius:1.0,
+ fromCap:1,
+ toCap:2,
+ color:'red',
+ hoverable:true,
+ clickable:true,
+ callback:function(){ this.color.setHex(0x00FFFF00);viewer.render( );},
+ hover_callback: function(){ viewer.render( );},
+ unhover_callback: function(){ this.color.setHex(0xFF000000);viewer.render( );}
+ });
+ viewer.addCylinder({start:{x:0.0,y:2.0,z:0.0},
+ end:{x:0.0,y:10.0,z:0.0},
+ radius:0.5,
+ fromCap:false,
+ toCap:true,
+ color:'teal'});
+ viewer.addCylinder({start:{x:15.0,y:0.0,z:0.0},
+ end:{x:20.0,y:0.0,z:0.0},
+ radius:1.0,
+ color:'black',
+ fromCap:false,
+ toCap:false});
+ viewer.render();
+ */
+ addCylinder(r) {
+ var n, b;
+ r.start ? n = new _.Vector3(r.start.x || 0, r.start.y || 0, r.start.z || 0) : n = new _.Vector3(0, 0, 0), r.end ? (b = new _.Vector3(r.end.x, r.end.y || 0, r.end.z || 0), typeof b.x > "u" && (b.x = 3)) : b = new _.Vector3(0, 0, 0);
+ var f = r.radius || 0.1, c = x.CC.color(r.color);
+ this.intersectionShape.cylinder.push(new g.Cylinder(n, b, f)), E.GLDraw.drawCylinder(this.geo, n, b, f, c, r.fromCap, r.toCap);
+ var t = new _.Vector3();
+ this.components.push({
+ centroid: t.addVectors(n, b).multiplyScalar(0.5)
+ });
+ var a = this.geo.updateGeoGroup(0);
+ C.updateBoundingFromPoints(this.boundingSphere, this.components, a.vertexArray, a.vertices);
+ }
+ /**
+ * Creates a dashed cylinder shape
+ * @param {CylinderSpec} cylinderSpec
+ */
+ addDashedCylinder(r) {
+ r.dashLength = r.dashLength || 0.25, r.gapLength = r.gapLength || 0.25;
+ var n;
+ r.start ? n = new _.Vector3(r.start.x || 0, r.start.y || 0, r.start.z || 0) : n = new _.Vector3(0, 0, 0);
+ var b;
+ r.end ? (b = new _.Vector3(r.end.x, r.end.y || 0, r.end.z || 0), typeof b.x > "u" && (b.x = 3)) : b = new _.Vector3(3, 0, 0);
+ for (var f = r.radius || 0.1, c = x.CC.color(r.color), t = Math.sqrt(Math.pow(n.x - b.x, 2) + Math.pow(n.y - b.y, 2) + Math.pow(n.z - b.z, 2)), a = t / (r.gapLength + r.dashLength), h = new _.Vector3(r.start.x || 0, r.start.y || 0, r.start.z || 0), M = new _.Vector3(r.end.x, r.end.y || 0, r.end.z || 0), w = new _.Vector3((b.x - n.x) / (t / r.gapLength), (b.y - n.y) / (t / r.gapLength), (b.z - n.z) / (t / r.gapLength)), S = new _.Vector3((b.x - n.x) / (t / r.dashLength), (b.y - n.y) / (t / r.dashLength), (b.z - n.z) / (t / r.dashLength)), T = 0; T < a; T++)
+ M = new _.Vector3(h.x + S.x, h.y + S.y, h.z + S.z), this.intersectionShape.cylinder.push(new g.Cylinder(h, M, f)), E.GLDraw.drawCylinder(this.geo, h, M, f, c, r.fromCap, r.toCap), h = new _.Vector3(M.x + w.x, M.y + w.y, M.z + w.z);
+ var R = new _.Vector3();
+ this.components.push({
+ centroid: R.addVectors(n, b).multiplyScalar(0.5)
+ });
+ var z = this.geo.updateGeoGroup(0);
+ C.updateBoundingFromPoints(this.boundingSphere, this.components, z.vertexArray, z.vertices);
+ }
+ /**
+ * Creates a curved shape
+ * @param {CurveSpec} curveSpec
+ */
+ addCurve(r) {
+ r.points = r.points || [], r.smooth = r.smooth || 10, typeof r.fromCap > "u" && (r.fromCap = 2), typeof r.toCap > "u" && (r.toCap = 2);
+ var n = (0, u.subdivide_spline)(r.points, r.smooth);
+ if (n.length < 3) {
+ console.log("Too few points in addCurve");
+ return;
+ }
+ var b = r.radius || 0.1, f = x.CC.color(r.color), c = 0, t = n.length - 1, a = n[0].distanceTo(n[1]), h = Math.ceil(2 * b / a);
+ if (r.toArrow) {
+ t -= h;
+ let T = {
+ start: n[t],
+ end: n[n.length - 1],
+ radius: b,
+ color: f,
+ mid: 1e-4
+ };
+ this.addArrow(T);
+ }
+ if (r.fromArrow) {
+ c += h;
+ let T = {
+ start: n[c],
+ end: n[0],
+ radius: b,
+ color: f,
+ mid: 1e-4
+ };
+ this.addArrow(T);
+ }
+ for (var M = Math.ceil(n.length / 2), w = { radius: b, color: f, fromCap: 2, toCap: 2 }, S = c; S < t; S++)
+ w.start = n[S], w.end = n[S + 1], w.fromCap = 2, w.toCap = 2, S < M ? (w.fromCap = 2, w.toCap = 0) : S > M ? (w.fromCap = 0, w.toCap = 2) : (w.fromCap = 2, w.toCap = 2), this.addCylinder(w);
+ }
+ /**
+ * Creates a line shape
+ * @param {LineSpec} lineSpec
+ @example
+ $3Dmol.download("pdb:2ABJ",viewer,{},function(){
+ viewer.addLine({dashed:true,start:{x:0,y:0,z:0},end:{x:100,y:100,z:100}});
+ viewer.render(callback);
+ });
+
+ */
+ addLine(r) {
+ var n, b;
+ r.start ? n = new _.Vector3(r.start.x || 0, r.start.y || 0, r.start.z || 0) : n = new _.Vector3(0, 0, 0), r.end ? (b = new _.Vector3(r.end.x, r.end.y || 0, r.end.z || 0), typeof b.x > "u" && (b.x = 3)) : b = new _.Vector3(3, 0, 0);
+ var f = this.geo.updateGeoGroup(2), c = f.vertices, t = c * 3, a = f.vertexArray;
+ a[t] = n.x, a[t + 1] = n.y, a[t + 2] = n.z, a[t + 3] = b.x, a[t + 4] = b.y, a[t + 5] = b.z, f.vertices += 2;
+ var h = f.lineArray, M = f.lineidx;
+ h[M] = c, h[M + 1] = c + 1, f.lineidx += 2;
+ var w = new _.Vector3();
+ this.components.push({
+ centroid: w.addVectors(n, b).multiplyScalar(0.5)
+ }), f = this.geo.updateGeoGroup(0), C.updateBoundingFromPoints(this.boundingSphere, this.components, f.vertexArray, f.vertices);
+ }
+ /**
+ * Creates an arrow shape
+ * @param {ArrowSpec} arrowSpec
+ @example
+ $3Dmol.download("pdb:4DM7",viewer,{},function(){
+ viewer.setBackgroundColor(0xffffffff);
+ viewer.addArrow({
+ start: {x:-10.0, y:0.0, z:0.0},
+ end: {x:0.0, y:-10.0, z:0.0},
+ radius: 1.0,
+ radiusRadio:1.0,
+ mid:1.0,
+ clickable:true,
+ callback:function(){
+ this.color.setHex(0xFF0000FF);
+ viewer.render( );
+ }
+ });
+ viewer.render();
+ });
+ */
+ addArrow(r) {
+ if (r.start ? r.start = new _.Vector3(r.start.x || 0, r.start.y || 0, r.start.z || 0) : r.start = new _.Vector3(0, 0, 0), r.dir instanceof _.Vector3 && typeof r.length == "number") {
+ var n = r.dir.clone().multiplyScalar(r.length).add(r.start);
+ r.end = n;
+ } else
+ r.end ? (r.end = new _.Vector3(r.end.x, r.end.y || 0, r.end.z || 0), typeof r.end.x > "u" && (r.end.x = 3)) : r.end = new _.Vector3(3, 0, 0);
+ r.radius = r.radius || 0.1, r.radiusRatio = r.radiusRatio || 1.618034, r.mid = 0 < r.mid && r.mid < 1 ? r.mid : 0.618034, C.drawArrow(this, this.geo, r);
+ var b = new _.Vector3();
+ this.components.push({
+ centroid: b.addVectors(r.start, r.end).multiplyScalar(0.5)
+ });
+ var f = this.geo.updateGeoGroup(0);
+ C.updateBoundingFromPoints(this.boundingSphere, this.components, f.vertexArray, f.vertices);
+ }
+ static distance_from(r, n) {
+ return Math.sqrt(Math.pow(r.x - n.x, 2) + Math.pow(r.y - n.y, 2) + Math.pow(r.z - n.z, 2));
+ }
+ static inSelectedRegion(r, n, b) {
+ for (var f = 0; f < n.length; f++)
+ if (C.distance_from(n[f], r) <= b)
+ return !0;
+ return !1;
+ }
+ /**
+ * Create isosurface from voluemetric data.
+ * @param {VolumeData} data - volumetric input data
+ * @param {IsoSurfaceSpec} isoSpec - volumetric data shape specification
+ * @example //the user can specify a selected region for the isosurface
+ $.get('../test_structs/benzene-homo.cube', function(data){
+ var voldata = new $3Dmol.VolumeData(data, "cube");
+ viewer.addIsosurface(voldata, {isoval: 0.01,
+ color: "blue",
+ alpha: 0.5,
+ smoothness: 10});
+ viewer.addIsosurface(voldata, {isoval: -0.01,
+ color: "red",
+ smoothness: 5,
+ opacity:0.5,
+ wireframe:true,
+ clickable:true,
+ callback:
+ function() {
+ this.opacity = 0.0;
+ viewer.render( );
+ }});
+ viewer.setStyle({}, {stick:{}});
+ viewer.zoomTo();
+ viewer.render();
+ });
+ */
+ addIsosurface(r, n, b) {
+ var f = n.isoval !== void 0 && typeof n.isoval == "number" ? n.isoval : 0, c = !!n.voxel, t = n.smoothness === void 0 ? 1 : n.smoothness, a = r.size.x, h = r.size.y, M = r.size.z, w = new Int16Array(a * h * M), S = r.data, T, R;
+ for (T = 0, R = w.length; T < R; ++T)
+ w[T] = -1;
+ var z = new Uint8Array(a * h * M);
+ for (T = 0, R = S.length; T < R; ++T) {
+ var P = f >= 0 ? S[T] - f : f - S[T];
+ P > 0 && (z[T] |= C.ISDONE);
+ }
+ var B = [], U = [];
+ o.MarchingCube.march(z, B, U, {
+ fulltable: !0,
+ voxel: c,
+ unitCube: r.unit,
+ origin: r.origin,
+ matrix: r.matrix,
+ nX: a,
+ nY: h,
+ nZ: M
+ }), !c && t > 0 && o.MarchingCube.laplacianSmooth(t, B, U);
+ var F = [], $ = [], W = [];
+ if (n.selectedRegion && n.coords === void 0 && (n.coords = n.selectedRegion), n.coords !== void 0) {
+ var N = n.coords[0].x, G = n.coords[0].y, k = n.coords[0].z, j = n.coords[0].x, Q = n.coords[0].y, ie = n.coords[0].z;
+ for (let oe = 0; oe < n.coords.length; oe++)
+ n.coords[oe].x > N ? N = n.coords[oe].x : n.coords[oe].x < j && (j = n.coords[oe].x), n.coords[oe].y > G ? G = n.coords[oe].y : n.coords[oe].y < Q && (Q = n.coords[oe].y), n.coords[oe].z > k ? k = n.coords[oe].z : n.coords[oe].z < ie && (ie = n.coords[oe].z);
+ var pe = 2;
+ n.radius !== void 0 && (pe = n.radius), n.selectedOffset !== void 0 && (pe = n.selectedOffset), n.seldist !== void 0 && (pe = n.seldist), j -= pe, N += pe, Q -= pe, G += pe, ie -= pe, k += pe;
+ for (let oe = 0; oe < B.length; oe++)
+ B[oe].x > j && B[oe].x < N && B[oe].y > Q && B[oe].y < G && B[oe].z > ie && B[oe].z < k && C.inSelectedRegion(B[oe], n.coords, pe) ? (F.push($.length), $.push(B[oe])) : F.push(-1);
+ for (let oe = 0; oe + 2 < U.length; oe += 3)
+ F[U[oe]] !== -1 && F[U[oe + 1]] !== -1 && F[U[oe + 2]] !== -1 && (W.push(U[oe] - (U[oe] - F[U[oe]])), W.push(U[oe + 1] - (U[oe + 1] - F[U[oe + 1]])), W.push(U[oe + 2] - (U[oe + 2] - F[U[oe + 2]])));
+ B = $, U = W;
+ }
+ C.drawCustom(this, this.geo, {
+ vertexArr: B,
+ faceArr: U,
+ normalArr: [],
+ clickable: n.clickable,
+ hoverable: n.hoverable
+ }), this.updateStyle(n);
+ var he = new _.Vector3(r.origin.x, r.origin.y, r.origin.z), ue = new _.Vector3(r.size.x * r.unit.x, r.size.y * r.unit.y, r.size.z * r.unit.z), se = new _.Vector3(0, 0, 0), ae = he.clone(), we = he.clone().add(ue);
+ for (let oe = 0; oe < B.length; oe++)
+ se.add(B[oe]), ae.max(B[oe]), we.min(B[oe]);
+ se.divideScalar(B.length);
+ var xe = se.distanceTo(we), Ie = se.distanceTo(ae);
+ this.boundingSphere.center = se, this.boundingSphere.radius = Math.max(xe, Ie), typeof b == "function" && b();
+ }
+ /**
+ * @deprecated Use addIsosurface instead
+ * Creates custom shape from volumetric data
+ * @param {string} data - Volumetric input data
+ * @param {string} fmt - Input data format (e.g. 'cube' for cube file format)
+ * @param {IsoSurfaceSpec} isoSpec - Volumetric data shape specification
+ */
+ addVolumetricData(r, n, b) {
+ r = new p.VolumeData(r, n), this.addIsosurface(r, b);
+ }
+ //for internal use, truncate buffers to save memory
+ finalize() {
+ return C.finalizeGeo(this.geo), this.geo.initTypedArrays(), this.geo;
+ }
+ /*
+ * Initialize webgl objects for rendering
+ * @param {$3Dmol.Object3D} group
+ *
+ */
+ globj(r) {
+ if (this.renderedShapeObj && (r.remove(this.renderedShapeObj), this.renderedShapeObj = null), !this.hidden) {
+ C.finalizeGeo(this.geo), this.geo.initTypedArrays(), this.wireframe && this.geo.setUpWireframe(), typeof this.color < "u" && C.updateColor(this.geo, this.color), this.shapeObj = new l.Object3D();
+ var n = null;
+ this.side == l.DoubleSide ? n = new l.MeshDoubleLambertMaterial({
+ wireframe: this.wireframe,
+ side: this.side,
+ transparent: this.opacity < 1,
+ opacity: this.opacity,
+ wireframeLinewidth: this.linewidth,
+ vertexColors: l.Coloring.VertexColors
+ }) : n = new l.MeshLambertMaterial({
+ wireframe: this.wireframe,
+ side: this.side,
+ transparent: this.opacity < 1,
+ opacity: this.opacity,
+ wireframeLinewidth: this.linewidth,
+ vertexColors: l.Coloring.VertexColors
+ });
+ var b = new l.Mesh(this.geo, n);
+ this.shapeObj.add(b);
+ var f = new l.LineBasicMaterial({
+ linewidth: this.linewidth,
+ color: this.color
+ }), c = new l.Line(this.linegeo, f, l.LineStyle.LinePieces);
+ this.shapeObj.add(c), this.renderedShapeObj = this.shapeObj.clone(), r.add(this.renderedShapeObj);
+ }
+ }
+ removegl(r) {
+ this.renderedShapeObj && (this.renderedShapeObj.geometry !== void 0 && this.renderedShapeObj.geometry.dispose(), this.renderedShapeObj.material !== void 0 && this.renderedShapeObj.material.dispose(), r.remove(this.renderedShapeObj), this.renderedShapeObj = null), this.shapeObj = null;
+ }
+ get position() {
+ return this.boundingSphere.center;
+ }
+ get x() {
+ return this.boundingSphere.center.x;
+ }
+ get y() {
+ return this.boundingSphere.center.y;
+ }
+ get z() {
+ return this.boundingSphere.center.z;
+ }
+ }
+ C.ISDONE = 2, C.drawCustom = function(D, r, n) {
+ var b = n, f = b.vertexArr, c = b.faceArr;
+ (f.length === 0 || c.length === 0) && console.warn("Error adding custom shape component: No vertices and/or face indices supplied!");
+ var t = n.color;
+ typeof t > "u" && (t = D.color), t = x.CC.color(t);
+ for (var a = L(b), h = 0, M = a.length; h < M; h++)
+ C.addCustomGeo(D, r, a[h], a[h].colorArr ? a[h].colorArr : t, n.clickable);
+ };
+ function L(D) {
+ var r = 64e3;
+ if (D.vertexArr.length < r)
+ return [D];
+ var n = [{ vertexArr: [], normalArr: [], faceArr: [] }];
+ D.colorArr && (n.colorArr = []);
+ var b = [], f = [], c = 0, t = D.faceArr;
+ for (let h = 0, M = t.length; h < M; h += 3) {
+ let w = n[c];
+ for (let S = 0; S < 3; S++) {
+ var a = t[h + S];
+ b[a] !== c && (b[a] = c, f[a] = w.vertexArr.length, w.vertexArr.push(D.vertexArr[a]), D.normalArr && D.normalArr[a] && w.normalArr.push(D.normalArr[a]), D.colorArr && D.colorArr[a] && w.colorArr.push(D.colorArr[a])), w.faceArr.push(f[a]);
+ }
+ w.vertexArr.length >= r && (n.push({ vertexArr: [], normalArr: [], faceArr: [] }), D.colorArr && (n.colorArr = []), c++);
+ }
+ return n;
+ }
+ }
+ ),
+ /***/
+ "./src/GLViewer.ts": (
+ /*!*************************!*\
+ !*** ./src/GLViewer.ts ***!
+ \*************************/
+ /***/
+ (y, s, e) => {
+ e.r(s), e.d(s, {
+ /* harmony export */
+ GLViewer: () => (
+ /* binding */
+ r
+ ),
+ /* harmony export */
+ createStereoViewer: () => (
+ /* binding */
+ f
+ ),
+ /* harmony export */
+ createViewer: () => (
+ /* binding */
+ n
+ ),
+ /* harmony export */
+ createViewerGrid: () => (
+ /* binding */
+ b
+ )
+ /* harmony export */
+ });
+ var l = e(
+ /*! ./WebGL */
+ "./src/WebGL/index.ts"
+ ), g = e(
+ /*! ./WebGL/math */
+ "./src/WebGL/math/index.ts"
+ ), _ = e(
+ /*! ./colors */
+ "./src/colors.ts"
+ ), x = e(
+ /*! ./utilities */
+ "./src/utilities.ts"
+ ), o = e(
+ /*! ./Gradient */
+ "./src/Gradient.ts"
+ ), p = e(
+ /*! ./GLModel */
+ "./src/GLModel.ts"
+ ), E = e(
+ /*! ./Label */
+ "./src/Label.ts"
+ ), u = e(
+ /*! ./GLShape */
+ "./src/GLShape.ts"
+ ), A = e(
+ /*! ./VolumeData */
+ "./src/VolumeData.ts"
+ ), C = e(
+ /*! ./ProteinSurface4 */
+ "./src/ProteinSurface4.ts"
+ ), L = e(
+ /*! ./VolumetricRender */
+ "./src/VolumetricRender.ts"
+ ), D = e(
+ /*! upng-js */
+ "./node_modules/upng-js/UPNG.js"
+ );
+ class r {
+ //reimplement jquery getwidth/height
+ getRect() {
+ let t = this.container, a = t.getBoundingClientRect();
+ if (a.width == 0 && a.height == 0 && t.style.display === "none") {
+ let h = t.style.position, M = t.style.visibility;
+ t.style.display = "block", t.style.visibility = "hidden", t.style.position = "absolute", a = t.getBoundingClientRect(), t.style.display = "none", t.style.visibility = M, t.style.position = h;
+ }
+ return a;
+ }
+ getWidth() {
+ return this.getRect().width;
+ }
+ getHeight() {
+ return this.getRect().height;
+ }
+ setupRenderer() {
+ this.renderer = new l.Renderer({
+ antialias: this.config.antialias,
+ preserveDrawingBuffer: !0,
+ premultipliedAlpha: !1,
+ id: this.config.id,
+ row: this.config.row,
+ col: this.config.col,
+ rows: this.config.rows,
+ cols: this.config.cols,
+ canvas: this.config.canvas,
+ //cannot initialize with zero size
+ containerWidth: this.WIDTH || 1,
+ containerHeight: this.HEIGHT || 1
+ }), this.renderer.domElement.style.width = "100%", this.renderer.domElement.style.height = "100%", this.renderer.domElement.style.padding = "0", this.renderer.domElement.style.position = "absolute", this.renderer.domElement.style.top = "0px", this.renderer.domElement.style.left = "0px", this.renderer.domElement.style.zIndex = "0";
+ }
+ initializeScene() {
+ this.scene = new l.Scene(), this.scene.fog = new l.Fog(this.bgColor, 100, 200), this.modelGroup = new l.Object3D(), this.rotationGroup = new l.Object3D(), this.rotationGroup.useQuaternion = !0, this.rotationGroup.quaternion = new g.Quaternion(0, 0, 0, 1), this.rotationGroup.add(this.modelGroup), this.scene.add(this.rotationGroup);
+ var t = new l.Light(16777215);
+ t.position = new g.Vector3(0.2, 0.2, 1).normalize(), t.intensity = 1, this.scene.add(t);
+ }
+ initContainer(t) {
+ this.container = t, this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight(), this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.renderer.setSize(this.WIDTH, this.HEIGHT), this.container.append(this.renderer.domElement), this.glDOM = this.renderer.domElement, this.nomouse || (this.glDOM.addEventListener("mousedown", this._handleMouseDown.bind(this), { passive: !1 }), this.glDOM.addEventListener("touchstart", this._handleMouseDown.bind(this), { passive: !1 }), this.glDOM.addEventListener("wheel", this._handleMouseScroll.bind(this), { passive: !1 }), this.glDOM.addEventListener("mousemove", this._handleMouseMove.bind(this), { passive: !1 }), this.glDOM.addEventListener("touchmove", this._handleMouseMove.bind(this), { passive: !1 }), this.glDOM.addEventListener("contextmenu", this._handleContextMenu.bind(this), { passive: !1 }));
+ }
+ decAnim() {
+ this.animated--, this.animated < 0 && (this.animated = 0);
+ }
+ incAnim() {
+ this.animated++;
+ }
+ nextSurfID() {
+ var t = 0;
+ for (let h in this.surfaces)
+ if (this.surfaces.hasOwnProperty(h)) {
+ var a = parseInt(h);
+ isNaN(a) || a > t && (t = a);
+ }
+ return t + 1;
+ }
+ setSlabAndFog() {
+ let t = this.camera.position.z - this.rotationGroup.position.z;
+ t < 1 && (t = 1), this.camera.near = t + this.slabNear, this.camera.near < 1 && (this.camera.near = 1), this.camera.far = t + this.slabFar, this.camera.near + 1 > this.camera.far && (this.camera.far = this.camera.near + 1), this.camera.fov = this.fov, this.camera.right = t * Math.tan(Math.PI / 180 * this.fov), this.camera.left = -this.camera.right, this.camera.top = this.camera.right / this.ASPECT, this.camera.bottom = -this.camera.top, this.camera.updateProjectionMatrix(), this.scene.fog.near = this.camera.near + this.fogStart * (this.camera.far - this.camera.near), this.scene.fog.far = this.camera.far, this.config.disableFog && (this.scene.fog.near = this.scene.fog.far);
+ }
+ // display scene
+ //if nolink is set/true, don't propagate changes to linked viewers
+ show(t) {
+ if (this.renderer.setViewport(), !!this.scene && (this.setSlabAndFog(), this.renderer.render(this.scene, this.camera), this.viewChangeCallback && this.viewChangeCallback(this._viewer.getView()), !t && this.linkedViewers.length > 0))
+ for (var a = this._viewer.getView(), h = 0; h < this.linkedViewers.length; h++) {
+ var M = this.linkedViewers[h];
+ M.setView(a, !0);
+ }
+ }
+ //regenerate the list of clickables
+ //also updates hoverables
+ updateClickables() {
+ this.clickables.splice(0, this.clickables.length), this.hoverables.splice(0, this.hoverables.length), this.contextMenuEnabledAtoms.splice(0, this.contextMenuEnabledAtoms.length);
+ for (let t = 0, a = this.models.length; t < a; t++) {
+ let h = this.models[t];
+ if (h) {
+ let M = h.selectedAtoms({
+ clickable: !0
+ }), w = h.selectedAtoms({
+ hoverable: !0
+ }), S = h.selectedAtoms({ contextMenuEnabled: !0 });
+ for (let T = 0; T < w.length; T++)
+ this.hoverables.push(w[T]);
+ for (let T = 0; T < M.length; T++)
+ this.clickables.push(M[T]);
+ for (let T = 0; T < S.length; T++)
+ this.contextMenuEnabledAtoms.push(S[T]);
+ }
+ }
+ for (let t = 0, a = this.shapes.length; t < a; t++) {
+ let h = this.shapes[t];
+ h && h.clickable && this.clickables.push(h), h && h.hoverable && this.hoverables.push(h);
+ }
+ }
+ // Checks for selection intersects on mousedown
+ handleClickSelection(t, a, h) {
+ let M = this.targetedObjects(t, a, this.clickables);
+ if (M.length) {
+ var w = M[0].clickable;
+ w.callback !== void 0 && (typeof w.callback != "function" && (w.callback = (0, x.makeFunction)(w.callback)), typeof w.callback == "function" && w.callback(w, this._viewer, h, this.container, M));
+ }
+ }
+ //return offset of container
+ canvasOffset() {
+ let t = this.glDOM, a = t.getBoundingClientRect(), h = t.ownerDocument, M = h.documentElement, w = h.defaultView;
+ return {
+ top: a.top + w.pageYOffset - M.clientTop,
+ left: a.left + w.pageXOffset - M.clientLeft
+ };
+ }
+ //set current_hover to sel (which can be null), calling appropraite callbacks
+ setHover(t, a, h) {
+ this.current_hover != t && (this.current_hover && (typeof this.current_hover.unhover_callback != "function" && (this.current_hover.unhover_callback = (0, x.makeFunction)(this.current_hover.unhover_callback)), this.current_hover.unhover_callback(this.current_hover, this._viewer, a, this.container, h)), this.current_hover = t, t && t.hover_callback !== void 0 && (typeof t.hover_callback != "function" && (t.hover_callback = (0, x.makeFunction)(t.hover_callback)), typeof t.hover_callback == "function" && t.hover_callback(t, this._viewer, a, this.container, h)));
+ }
+ //checks for selection intersects on hover
+ handleHoverSelection(t, a, h) {
+ if (this.hoverables.length == 0)
+ return;
+ let M = this.targetedObjects(t, a, this.hoverables);
+ if (M.length) {
+ var w = M[0].clickable;
+ this.setHover(w, h, M), this.current_hover = w;
+ } else
+ this.setHover(null);
+ }
+ //sees if the mouse is still on the object that invoked a hover event and if not then the unhover callback is called
+ handleHoverContinue(t, a) {
+ let h = this.targetedObjects(t, a, this.hoverables);
+ (h.length == 0 || h[0] === void 0) && this.setHover(null), h[0] !== void 0 && h[0].clickable !== this.current_hover && this.setHover(null);
+ }
+ /**
+ * Determine if a positioned event is "close enough" to mouseStart to be considered a click.
+ * With a mouse, the position should be exact, but allow a slight delta for a touch interface.
+ * @param {Event} event
+ * @param {{ allowTolerance, tolerance: number }} options
+ */
+ closeEnoughForClick(t, { allowTolerance: a = t.targetTouches, tolerance: h = 5 } = {}) {
+ const M = this.getX(t), w = this.getY(t);
+ if (a) {
+ const S = Math.abs(M - this.mouseStartX), T = Math.abs(w - this.mouseStartY);
+ return S <= h && T <= h;
+ } else
+ return M === this.mouseStartX && w === this.mouseStartY;
+ }
+ calcTouchDistance(t) {
+ var a = t.targetTouches[0].pageX - t.targetTouches[1].pageX, h = t.targetTouches[0].pageY - t.targetTouches[1].pageY;
+ return Math.hypot(a, h);
+ }
+ //check targetTouches as well
+ getX(t) {
+ var a = t.pageX;
+ return a == null && (a = t.pageX), t.targetTouches && t.targetTouches[0] ? a = t.targetTouches[0].pageX : t.changedTouches && t.changedTouches[0] && (a = t.changedTouches[0].pageX), a;
+ }
+ getY(t) {
+ var a = t.pageY;
+ return a == null && (a = t.pageY), t.targetTouches && t.targetTouches[0] ? a = t.targetTouches[0].pageY : t.changedTouches && t.changedTouches[0] && (a = t.changedTouches[0].pageY), a;
+ }
+ //for grid viewers, return true if point is in this viewer
+ isInViewer(t, a) {
+ if (this.viewers != null) {
+ var h = this.WIDTH / this.cols, M = this.HEIGHT / this.rows, w = this.canvasOffset(), S = t - w.left, T = a - w.top, R = this.rows - Math.floor(T / M) - 1, z = Math.floor(S / h);
+ if (R != this.row || z != this.col)
+ return !1;
+ }
+ return !0;
+ }
+ //if the user has specify zoom limits, readjust to fit within them
+ //also, make sure we don't go past CAMERA_Z
+ adjustZoomToLimits(t) {
+ if (this.config.lowerZoomLimit && this.config.lowerZoomLimit > 0) {
+ let a = this.CAMERA_Z - this.config.lowerZoomLimit;
+ t > a && (t = a);
+ }
+ if (this.config.upperZoomLimit && this.config.upperZoomLimit > 0) {
+ let a = this.CAMERA_Z - this.config.upperZoomLimit;
+ t < a && (t = a);
+ }
+ return t > this.CAMERA_Z - 1 && (t = this.CAMERA_Z - 1), t;
+ }
+ //interpolate between two normalized quaternions (t between 0 and 1)
+ //https://en.wikipedia.org/wiki/Slerp
+ static slerp(t, a, h) {
+ if (h == 1)
+ return a.clone();
+ if (h == 0)
+ return t.clone();
+ let M = t.x * a.x + t.y * a.y + t.z * a.z + t.w * a.w;
+ if (M > 0.9995) {
+ let B = new g.Quaternion(t.x + h * (a.x - t.x), t.y + h * (a.y - t.y), t.z + h * (a.z - t.z), t.w + h * (a.w - t.w));
+ return B.normalize(), B;
+ }
+ M < 0 && (a = a.clone().multiplyScalar(-1), M = -M), M > 1 ? M = 1 : M < -1 && (M = -1);
+ var w = Math.acos(M), S = w * h, T = a.clone();
+ T.sub(t.clone().multiplyScalar(M)), T.normalize();
+ var R = Math.cos(S), z = Math.sin(S), P = new g.Quaternion(t.x * R + T.x * z, t.y * R + T.y * z, t.z * R + T.z * z, t.w * R + T.w * z);
+ return P.normalize(), P;
+ }
+ /* @param {Object} element HTML element within which to create viewer
+ * @param {ViewerSpec} config Object containing optional configuration for the viewer
+ */
+ constructor(t, a = {}) {
+ this.nomouse = !1, this.glDOM = null, this.models = [], this.surfaces = {}, this.shapes = [], this.labels = [], this.clickables = [], this.hoverables = [], this.contextMenuEnabledAtoms = [], this.current_hover = null, this.hoverDuration = 500, this.viewer_frame = 0, this.viewChangeCallback = null, this.stateChangeCallback = null, this.NEAR = 1, this.FAR = 800, this.CAMERA_Z = 150, this.fov = 20, this.linkedViewers = [], this.renderer = null, this.control_all = !1, this.scene = null, this.rotationGroup = null, this.modelGroup = null, this.fogStart = 0.4, this.slabNear = -50, this.slabFar = 50, this.cq = new g.Quaternion(0, 0, 0, 1), this.dq = new g.Quaternion(0, 0, 0, 1), this.animated = 0, this.animationTimers = /* @__PURE__ */ new Set(), this.isDragging = !1, this.mouseStartX = 0, this.mouseStartY = 0, this.touchDistanceStart = 0, this.touchHold = !1, this.currentModelPos = 0, this.cz = 0, this.cslabNear = 0, this.cslabFar = 0, this.userContextMenuHandler = null, this.config = a, this.callback = this.config.callback, this.defaultcolors = this.config.defaultcolors, this.defaultcolors || (this.defaultcolors = _.elementColors.defaultColors), this.nomouse = this.config.nomouse, this.bgColor = 0, this.config.backgroundColor = this.config.backgroundColor || "#ffffff", typeof this.config.backgroundColor < "u" && (this.bgColor = _.CC.color(this.config.backgroundColor).getHex()), this.config.backgroundAlpha = this.config.backgroundAlpha == null ? 1 : this.config.backgroundAlpha, this.camerax = 0, typeof this.config.camerax < "u" && (this.camerax = parseFloat(this.config.camerax)), this._viewer = this, this.container = t, this.config.hoverDuration != null && (this.hoverDuration = this.config.hoverDuration), this.config.antialias === void 0 && (this.config.antialias = !0), this.config.cartoonQuality === void 0 && (this.config.cartoonQuality = 10), this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight(), this.setupRenderer(), this.row = this.config.row == null ? 0 : this.config.row, this.col = this.config.col == null ? 0 : this.config.col, this.cols = this.config.cols, this.rows = this.config.rows, this.viewers = this.config.viewers, this.control_all = this.config.control_all, this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.camera = new l.Camera(this.fov, this.ASPECT, this.NEAR, this.FAR, this.config.orthographic), this.camera.position = new g.Vector3(this.camerax, 0, this.CAMERA_Z), this.lookingAt = new g.Vector3(), this.camera.lookAt(this.lookingAt), this.raycaster = new l.Raycaster(new g.Vector3(0, 0, 0), new g.Vector3(0, 0, 0)), this.projector = new l.Projector(), this.initializeScene(), this.renderer.setClearColorHex(this.bgColor, this.config.backgroundAlpha), this.scene.fog.color = _.CC.color(this.bgColor), document.body.addEventListener("mouseup", this._handleMouseUp.bind(this)), document.body.addEventListener("touchend", this._handleMouseUp.bind(this)), this.initContainer(this.container), this.config.style && this.setViewStyle(this.config), window.addEventListener("resize", this.resize.bind(this)), typeof window.ResizeObserver < "u" && (this.divwatcher = new window.ResizeObserver(this.resize.bind(this)), this.divwatcher.observe(this.container));
+ try {
+ typeof this.callback == "function" && this.callback(this);
+ } catch (h) {
+ console.log("error with glviewer callback: " + h);
+ }
+ }
+ /**
+ * Return a list of objects that intersect that at the specified viewer position.
+ *
+ * @param x - x position in screen coordinates
+ * @param y - y position in screen coordinates
+ * @param {Object[]} - list of objects or selection object specifying what object to check for targeting
+ */
+ targetedObjects(t, a, h) {
+ var M = {
+ x: t,
+ y: a,
+ z: -1
+ };
+ return Array.isArray(h) || (h = this.selectedAtoms(h)), h.length == 0 ? [] : (this.raycaster.setFromCamera(M, this.camera), this.raycaster.intersectObjects(this.modelGroup, h));
+ }
+ /** Convert model coordinates to screen coordinates.
+ * @param {object | list} - an object or list of objects with x,y,z attributes (e.g. an atom)
+ * @return {object | list} - and object or list of {x: screenX, y: screenY}
+ */
+ modelToScreen(t) {
+ let a = !1;
+ Array.isArray(t) || (t = [t], a = !0);
+ let h = this.renderer.getXRatio(), M = this.renderer.getYRatio(), w = this.col, S = this.row, T = w * (this.WIDTH / h), R = (M - S - 1) * (this.HEIGHT / M), z = [], P = this.canvasOffset();
+ return t.forEach((B) => {
+ let U = new g.Vector3(B.x, B.y, B.z);
+ U.applyMatrix4(this.modelGroup.matrixWorld), this.projector.projectVector(U, this.camera);
+ let F = this.WIDTH / h * (U.x + 1) / 2 + P.left + T, $ = -(this.HEIGHT / M) * (U.y - 1) / 2 + P.top + R;
+ z.push({ x: F, y: $ });
+ }), a && (z = z[0]), z;
+ }
+ /**
+ * For a given screen (x,y) displacement return model displacement
+ * @param{x} x displacement in screen coordinates
+ * @param{y} y displacement in screen corodinates
+ * @param{modelz} z coordinate in model coordinates to compute offset for, default is model axis
+ */
+ screenOffsetToModel(t, a, h) {
+ var M = t / this.WIDTH, w = a / this.HEIGHT, S = h === void 0 ? this.rotationGroup.position.z : h, T = this.rotationGroup.quaternion, R = new g.Vector3(0, 0, S);
+ return this.projector.projectVector(R, this.camera), R.x += M * 2, R.y -= w * 2, this.projector.unprojectVector(R, this.camera), R.z = 0, R.applyQuaternion(T), R;
+ }
+ /**
+ * Distance from screen coordinate to model coordinate assuming screen point
+ * is projected to the same depth as model coordinate
+ * @param{screen} xy screen coordinate
+ * @param{model} xyz model coordinate
+ */
+ screenToModelDistance(t, a) {
+ let h = this.canvasOffset(), M = new g.Vector3(a.x, a.y, a.z);
+ M.applyMatrix4(this.modelGroup.matrixWorld);
+ let w = M.clone();
+ this.projector.projectVector(M, this.camera);
+ let S = new g.Vector3((t.x - h.left) * 2 / this.WIDTH - 1, (t.y - h.top) * 2 / -this.HEIGHT + 1, M.z);
+ return this.projector.unprojectVector(S, this.camera), S.distanceTo(w);
+ }
+ /**
+ * Set a callback to call when the view has potentially changed.
+ *
+ */
+ setViewChangeCallback(t) {
+ (typeof t == "function" || t == null) && (this.viewChangeCallback = t);
+ }
+ /**
+ * Set a callback to call when the view has potentially changed.
+ *
+ */
+ setStateChangeCallback(t) {
+ (typeof t == "function" || t == null) && (this.stateChangeCallback = t);
+ }
+ /**
+ * Return configuration of viewer
+ */
+ getConfig() {
+ return this.config;
+ }
+ /**
+ * Set the configuration object. Note that some setting may only
+ * have an effect at viewer creation time.
+ */
+ setConfig(t) {
+ this.config = t;
+ }
+ /**
+ * Return object representing internal state of
+ * the viewer appropriate for passing to setInternalState
+ *
+ */
+ getInternalState() {
+ var t = { models: [], surfaces: [], shapes: [], labels: [] };
+ for (let a = 0; a < this.models.length; a++)
+ this.models[a] && (t.models[a] = this.models[a].getInternalState());
+ return t;
+ }
+ /**
+ * Overwrite internal state of the viewer with passed object
+ * which should come from getInternalState.
+ *
+ */
+ setInternalState(t) {
+ this.clear();
+ var a = t.models;
+ for (let h = 0; h < a.length; h++)
+ a[h] && (this.models[h] = new p.GLModel(h), this.models[h].setInternalState(a[h]));
+ this.render();
+ }
+ /**
+ * Set lower and upper limit stops for zoom.
+ *
+ * @param {lower} - limit on zoom in (positive number). Default 0.
+ * @param {upper} - limit on zoom out (positive number). Default infinite.
+ * @example
+ $3Dmol.get("data/set1_122_complex.mol2", function(moldata) {
+ var m = viewer.addModel(moldata);
+ viewer.setStyle({stick:{colorscheme:"Jmol"}});
+ viewer.setZoomLimits(100,200);
+ viewer.zoomTo();
+ viewer.zoom(10); //will not zoom all the way
+ viewer.render();
+ });
+ */
+ setZoomLimits(t, a) {
+ typeof t < "u" && (this.config.lowerZoomLimit = t), a && (this.config.upperZoomLimit = a), this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z), this.show();
+ }
+ /**
+ * Set camera parameters (distance to the origin and field of view)
+ *
+ * @param {parameters} - new camera parameters, with possible fields
+ * being fov for the field of view, z for the
+ * distance to the origin, and orthographic (boolean)
+ * for kind of projection (default false).
+ * @example
+ $3Dmol.get("data/set1_122_complex.mol2", function(data) {
+ var m = viewer.addModel(data);
+ viewer.setStyle({stick:{}});
+ viewer.zoomTo();
+ viewer.setCameraParameters({ fov: 10 , z: 300 });
+ viewer.render();
+ });
+ */
+ setCameraParameters(t) {
+ t.fov !== void 0 && (this.fov = t.fov, this.camera.fov = this.fov), t.z !== void 0 && (this.CAMERA_Z = t.z, this.camera.z = this.CAMERA_Z), t.orthographic !== void 0 && (this.camera.ortho = t.orthographic);
+ }
+ _handleMouseDown(t) {
+ if (t.preventDefault(), !this.scene)
+ return;
+ var a = this.getX(t), h = this.getY(t);
+ if (a === void 0)
+ return;
+ this.isDragging = !0, this.mouseButton = t.which, this.mouseStartX = a, this.mouseStartY = h, this.touchHold = !0, this.touchDistanceStart = 0, t.targetTouches && t.targetTouches.length == 2 && (this.touchDistanceStart = this.calcTouchDistance(t)), this.cq = this.rotationGroup.quaternion.clone(), this.cz = this.rotationGroup.position.z, this.currentModelPos = this.modelGroup.position.clone(), this.cslabNear = this.slabNear, this.cslabFar = this.slabFar;
+ let M = this;
+ setTimeout(function() {
+ t.targetTouches && M.touchHold == !0 && (M.glDOM = M.renderer.domElement, M.glDOM.dispatchEvent(new Event("contextmenu")));
+ }, 1e3);
+ }
+ _handleMouseUp(t) {
+ if (this.touchHold = !1, this.isDragging && this.scene) {
+ var a = this.getX(t), h = this.getY(t);
+ if (this.closeEnoughForClick(t) && this.isInViewer(a, h)) {
+ let M = this.mouseXY(a, h);
+ this.handleClickSelection(M.x, M.y, t);
+ }
+ }
+ this.isDragging = !1;
+ }
+ _handleMouseScroll(t) {
+ if (t.preventDefault(), !!this.scene) {
+ var a = this.getX(t), h = this.getY(t);
+ if (a !== void 0 && !(!this.control_all && !this.isInViewer(a, h))) {
+ var M = (this.CAMERA_Z - this.rotationGroup.position.z) * 0.85, w = 1;
+ if (t.ctrlKey && (w = -1), t.detail)
+ this.rotationGroup.position.z += w * M * t.detail / 10;
+ else if (t.wheelDelta) {
+ let S = t.wheelDelta * 600 / (t.wheelDelta + 600);
+ this.rotationGroup.position.z -= w * M * S / 400;
+ }
+ this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z), this.show();
+ }
+ }
+ }
+ /**
+ * Return image URI of viewer contents (base64 encoded). *
+ */
+ pngURI() {
+ return this.getCanvas().toDataURL("image/png");
+ }
+ /**
+ * Return a promise that resolves to an animated PNG image URI of
+ viewer contents (base64 encoded) for nframes of viewer changes.
+ * @return {Promise}
+ */
+ apngURI(t) {
+ let a = this;
+ return t = t || 1, new Promise(function(h) {
+ let M = 0, w = a.viewChangeCallback, S = [], T = [], R = Date.now();
+ a.viewChangeCallback = function() {
+ T.push(Date.now() - R), R = Date.now(), S.push(new Promise((z) => {
+ a.getCanvas().toBlob(function(P) {
+ P.arrayBuffer().then(z);
+ }, "image/png");
+ })), M += 1, M == t && (a.viewChangeCallback = w, Promise.all(S).then((z) => {
+ let P = [];
+ for (let N = 0; N < z.length; N++) {
+ let G = (0, D.decode)(z[N]);
+ P.push((0, D.toRGBA8)(G)[0]);
+ }
+ let B = a.getCanvas().width, U = a.getCanvas().height, F = (0, D.encode)(P, B, U, 0, T), $ = new Blob([F], { type: "image/png" }), W = new FileReader();
+ W.onload = function(N) {
+ h(N.target.result);
+ }, W.readAsDataURL($);
+ }));
+ };
+ });
+ }
+ /**
+ * Return underlying canvas element.
+ */
+ getCanvas() {
+ return this.glDOM;
+ }
+ /**
+ * Return renderer element.
+ */
+ getRenderer() {
+ return this.renderer;
+ }
+ /**
+ * Set the duration of the hover delay
+ *
+ * @param {number}
+ * [hoverDuration] - an optional parameter that denotes
+ * the duration of the hover delay (in milliseconds) before the hover action is called
+ *
+ */
+ setHoverDuration(t) {
+ this.hoverDuration = t;
+ }
+ mouseXY(t, a) {
+ let h = this.canvasOffset(), M = this.renderer.getXRatio(), w = this.renderer.getYRatio(), S = this.col, T = this.row, R = S * (this.WIDTH / M), z = (w - T - 1) * (this.HEIGHT / w), P = (t - h.left - R) / (this.WIDTH / M) * 2 - 1, B = -((a - h.top - z) / (this.HEIGHT / w)) * 2 + 1;
+ return { x: P, y: B };
+ }
+ _handleMouseMove(t) {
+ clearTimeout(this.hoverTimeout), t.preventDefault();
+ let a = this.getX(t), h = this.getY(t);
+ if (a === void 0)
+ return;
+ let M = this.renderer.getXRatio(), w = this.renderer.getYRatio(), S = this.mouseXY(a, h), T = this;
+ this.current_hover !== null && this.handleHoverContinue(S.x, S.y);
+ var R = 0;
+ if (!(!this.control_all && !this.isInViewer(a, h)) && this.scene && (this.hoverables.length > 0 && (this.hoverTimeout = setTimeout(function() {
+ T.handleHoverSelection(S.x, S.y, t);
+ }, this.hoverDuration)), !!this.isDragging)) {
+ var z = (a - this.mouseStartX) / this.WIDTH, P = (h - this.mouseStartY) / this.HEIGHT;
+ if (this.touchDistanceStart != 0 && t.targetTouches && t.targetTouches.length == 2) {
+ var B = this.calcTouchDistance(t);
+ R = 2, P = (B - this.touchDistanceStart) * 2 / (this.WIDTH + this.HEIGHT);
+ } else
+ t.targetTouches && t.targetTouches.length == 3 && (R = 1);
+ z *= M, P *= w;
+ var U = Math.hypot(z, P), F;
+ if (R == 3 || this.mouseButton == 3 && t.ctrlKey)
+ this.slabNear = this.cslabNear + z * 100, this.slabFar = this.cslabFar - P * 100;
+ else if (R == 2 || this.mouseButton == 3 || t.shiftKey)
+ F = (this.CAMERA_Z - this.rotationGroup.position.z) * 0.85, F < 80 && (F = 80), this.rotationGroup.position.z = this.cz + P * F, this.rotationGroup.position.z = this.adjustZoomToLimits(this.rotationGroup.position.z);
+ else if (R == 1 || this.mouseButton == 2 || t.ctrlKey) {
+ var $ = this.screenOffsetToModel(M * (a - this.mouseStartX), w * (h - this.mouseStartY));
+ this.modelGroup.position.addVectors(this.currentModelPos, $);
+ } else if ((R === 0 || this.mouseButton == 1) && U !== 0) {
+ var W = Math.sin(U * Math.PI) / U;
+ this.dq.x = Math.cos(U * Math.PI), this.dq.y = 0, this.dq.z = W * z, this.dq.w = -W * P, this.rotationGroup.quaternion.set(1, 0, 0, 0), this.rotationGroup.quaternion.multiply(this.dq), this.rotationGroup.quaternion.multiply(this.cq);
+ }
+ this.show();
+ }
+ }
+ _handleContextMenu(t) {
+ t.preventDefault();
+ var a = this.getX(t), h = this.getY(t);
+ if (!(a != this.mouseStartX || h != this.mouseStartY)) {
+ var S = this.mouseStartX, T = this.mouseStartY, w = this.canvasOffset();
+ let R = this.mouseXY(S, T), z = R.x, P = R.y, B = this.targetedObjects(z, P, this.contextMenuEnabledAtoms);
+ var M = null;
+ B.length && (M = B[0].clickable);
+ var w = this.canvasOffset(), S = this.mouseStartX - w.left, T = this.mouseStartY - w.top;
+ this.userContextMenuHandler && this.userContextMenuHandler(M, S, T, B);
+ }
+ }
+ /**
+ * Change the viewer's container element
+ * Also useful if the original container element was removed from the DOM.
+ *
+ * @param {Object | string} element
+ * Either HTML element or string identifier. Defaults to the element used to initialize the viewer.
+
+ */
+ setContainer(t) {
+ let a = (0, x.getElement)(t) || this.container;
+ return this.initContainer(a), this;
+ }
+ /**
+ * Set the background color (default white)
+ *
+ * @param {number}
+ * hex Hexcode specified background color, or standard color spec
+ * @param {number}
+ * a Alpha level (default 1.0)
+ *
+ * @example
+ *
+ * viewer.setBackgroundColor(0x000000);
+
+
+ *
+ */
+ setBackgroundColor(t, a) {
+ (typeof a > "u" || a < 0 || a > 1) && (a = 1);
+ var h = _.CC.color(t);
+ return this.scene.fog.color = h, this.bgColor = h.getHex(), this.renderer.setClearColorHex(h.getHex(), a), this.show(), this;
+ }
+ /**
+ * Set view projection scheme. Either orthographic or perspective.
+ * Default is perspective. Orthographic can also be enabled on viewer creation
+ * by setting orthographic to true in the config object.
+ *
+ *
+ * @example
+ viewer.setViewStyle({style:"outline"});
+ $3Dmol.get('data/1fas.pqr', function(data){
+ viewer.addModel(data, "pqr");
+ $3Dmol.get("data/1fas.cube",function(volumedata){
+ viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity:0.85,voldata: new $3Dmol.VolumeData(volumedata, "cube"), volscheme: new $3Dmol.Gradient.RWB(-10,10)},{});
+ });
+ viewer.zoomTo();
+
+ viewer.setProjection("orthographic");
+ viewer.render(callback);
+ });
+ *
+ */
+ setProjection(t) {
+ this.camera.ortho = t === "orthographic", this.setSlabAndFog();
+ }
+ /**
+ * Set global view styles.
+ *
+ * @example
+ * viewer.setViewStyle({style:"outline"});
+ $3Dmol.get('data/1fas.pqr', function(data){
+ viewer.addModel(data, "pqr");
+ $3Dmol.get("data/1fas.cube",function(volumedata){
+ viewer.addSurface($3Dmol.SurfaceType.VDW, {opacity:0.85,voldata: new $3Dmol.VolumeData(volumedata, "cube"), volscheme: new $3Dmol.Gradient.RWB(-10,10)},{});
+ });
+ viewer.zoomTo();
+ viewer.render(callback);
+ });
+ *
+ */
+ setViewStyle(t) {
+ if (t.style === "outline") {
+ var a = {};
+ t.color && (a.color = _.CC.color(t.color)), t.width && (a.width = t.width), this.renderer.enableOutline(a);
+ } else
+ this.renderer.disableOutline();
+ return this;
+ }
+ updateSize() {
+ this.renderer.setSize(this.WIDTH, this.HEIGHT), this.ASPECT = this.renderer.getAspect(this.WIDTH, this.HEIGHT), this.renderer.setSize(this.WIDTH, this.HEIGHT), this.camera.aspect = this.ASPECT, this.camera.updateProjectionMatrix();
+ }
+ /**
+ * Set viewer width independently of the HTML container. This is probably not what you want.
+ *
+ * @param {number} w Width in pixels
+ */
+ setWidth(t) {
+ return this.WIDTH = t || this.WIDTH, this.updateSize(), this;
+ }
+ /**
+ * Set viewer height independently of the HTML container. This is probably not what you want.
+ *
+ * @param {number} h Height in pixels
+ */
+ setHeight(t) {
+ return this.HEIGHT = t || this.HEIGHT, this.updateSize(), this;
+ }
+ /**
+ * Resize viewer according to containing HTML element's dimensions
+ *
+ */
+ resize() {
+ this.WIDTH = this.getWidth(), this.HEIGHT = this.getHeight();
+ let t = !1;
+ if (this.renderer.isLost() && this.WIDTH > 0 && this.HEIGHT > 0) {
+ let a = !1, h = this.container.querySelector("canvas");
+ h && h != this.renderer.getCanvas() ? this.config.canvas = h : (h.remove(), this.config && this.config.canvas != null && (delete this.config.canvas, a = !0)), this.setupRenderer(), this.initContainer(this.container), t = !0, a && (this.config.canvas = this.renderer.getCanvas());
+ }
+ if (this.WIDTH == 0 || this.HEIGHT == 0 ? this.animated && this._viewer.pauseAnimate() : this.animated && this._viewer.resumeAnimate(), this.updateSize(), t) {
+ let a = this.renderer.supportedExtensions();
+ if (a.regen = !0, this.viewers)
+ for (let h = 0, M = this.viewers.length; h < M; h++)
+ for (let w = 0, S = this.viewers[h].length; w < S; w++)
+ this.viewers[h][w].render(null, a);
+ this._viewer.render(null, a);
+ } else
+ this.show();
+ return this;
+ }
+ /**
+ * Return specified model
+ *
+ * @param {number}
+ * [id=last model id] - Retrieve model with specified id
+ * @default Returns last model added to viewer or null if there are no models
+ * @return {GLModel}
+ *
+ * @example // Retrieve reference to first GLModel added var m =
+ * $3Dmol.download("pdb:1UBQ",viewer,{},function(m1){
+ $3Dmol.download("pdb:1UBI", viewer,{}, function(m2) {
+ viewer.zoomTo();
+ m1.setStyle({cartoon: {color:'green'}});
+ //could use m2 here as well
+ viewer.getModel().setStyle({cartoon: {color:'blue'}});
+ viewer.render();
+ })
+ });
+ */
+ getModel(t) {
+ return t === void 0 ? this.models.length == 0 ? null : this.models[this.models.length - 1] : t instanceof p.GLModel ? t : t in this.models ? this.models[t] : this.models.length == 0 ? null : this.models[this.models.length - 1];
+ }
+ /**
+ * Continuously rotate a scene around the specified axis.
+ *
+ * Call `spin(false)` to stop spinning.
+ *
+ * @param {string|boolean|Array} axis
+ * [axis] - Axis ("x", "y", "z", "vx", "vy", or "vz") to rotate around.
+ * Default "y". View relative (rather than model relative) axes are prefixed with v.
+ * @param {number} speed
+ * [speed] - Speed multiplier for spinning the viewer. 1 is default and a negative
+ * value reverses the direction of the spin.
+ *
+ */
+ spin(t, a = 1) {
+ if (clearInterval(this.spinInterval), typeof t > "u" && (t = "y"), typeof t == "boolean")
+ if (t)
+ t = "y";
+ else
+ return;
+ Array.isArray(t) && (t = { x: t[0], y: t[1], z: t[2] });
+ var h = this;
+ this.spinInterval = setInterval(function() {
+ !h.getCanvas().isConnected && h.renderer.isLost() && clearInterval(h.spinInterval), h.rotate(1 * a, t);
+ }, 25);
+ }
+ //animate motion between current position and passed position
+ // can set some parameters to null
+ //if fixed is true will enforce the request animation, otherwise
+ //does relative updates
+ //positions objects have modelggroup position, rotation group position.z,
+ //and rotationgroup quaternion
+ //return array includes final position, but not current
+ //the returned array includes an animate method
+ animateMotion(t, a, h, M, w, S) {
+ var T = 20, R = Math.ceil(t / T);
+ R < 1 && (R = 1), this.incAnim();
+ var z = {
+ mpos: this.modelGroup.position.clone(),
+ rz: this.rotationGroup.position.z,
+ rot: this.rotationGroup.quaternion.clone(),
+ cam: this.lookingAt.clone()
+ };
+ if (a) {
+ let U = new Array(R);
+ for (let N = 0; N < R; N++) {
+ let G = (N + 1) / R, k = { mpos: z.mpos, rz: z.rz, rot: z.rot };
+ k.mpos = h.clone().sub(z.mpos).multiplyScalar(G).add(z.mpos), k.rz = z.rz + G * (M - z.rz), k.rot = r.slerp(z.rot, w, G), k.cam = S.clone().sub(z.cam).multiplyScalar(G).add(z.cam), U[N] = k;
+ }
+ let F = 0, $ = this, W = function() {
+ var N = U[F];
+ F += 1, $.modelGroup.position = N.mpos, $.rotationGroup.position.z = N.rz, $.rotationGroup.quaternion = N.rot, $.camera.lookAt(N.cam), F < U.length ? setTimeout(W, T) : $.decAnim(), $.show();
+ };
+ setTimeout(W, T);
+ } else {
+ var P = {};
+ let U = 1 / R;
+ if (h && (P.mpos = h.clone().sub(z.mpos).multiplyScalar(U)), typeof M < "u" && M != null && (P.rz = U * (M - z.rz)), w) {
+ var B = r.slerp(z.rot, w, U);
+ P.rot = z.rot.clone().inverse().multiply(B);
+ }
+ S && (P.cam = S.clone().sub(z.cam).multiplyScalar(U));
+ let F = 0, $ = this, W = function() {
+ F += 1, P.mpos && $.modelGroup.position.add(P.mpos), P.rz && ($.rotationGroup.position.z += P.rz), P.rot && $.rotationGroup.quaternion.multiply(P.rot), P.cam && ($.lookingAt.add(P.cam), $.camera.lookAt($.lookingAt)), F < R ? setTimeout(W, T) : $.decAnim(), $.show();
+ };
+ setTimeout(W, T);
+ }
+ }
+ /**
+ * Rotate scene by angle degrees around axis
+ *
+ * @param {number}
+ * [angle] - Angle, in degrees, to rotate by.
+ * @param {string}
+ * [axis] - Axis ("x", "y", "z", "vx", "vy", or "vz") to rotate around.
+ * Default "y". View relative (rather than model relative) axes are prefixed with v.
+ * Axis can also be specified as a vector.
+ * @param {number}
+ * [animationDuration] - an optional parameter that denotes
+ * the duration of the rotation animation. Default 0 (no animation)
+ * @param {boolean} [fixedPath] - if true animation is constrained to
+ * requested motion, overriding updates that happen during the animation *
+ * @example $3Dmol.download('cid:4000', viewer, {}, function() {
+ viewer.setStyle({stick:{}});
+ viewer.zoomTo();
+ viewer.rotate(90,'y',1);
+ viewer.render(callback);
+ });
+
+ *
+ */
+ rotate(t, a = "y", h = 0, M = !1) {
+ if (a == "x" ? a = { x: 1, y: 0, z: 0 } : a == "y" ? a = { x: 0, y: 1, z: 0 } : a == "z" && (a = { x: 0, y: 0, z: 1 }), a == "vx" ? a = { vx: 1, vy: 0, vz: 0 } : a == "vy" ? a = { vx: 0, vy: 1, vz: 0 } : a == "vz" && (a = { vx: 0, vy: 0, vz: 1 }), typeof a.vx < "u") {
+ var w = new g.Vector3(a.vx, a.vy, a.vz);
+ w.applyQuaternion(this.rotationGroup.quaternion), a = { x: w.x, y: w.y, z: w.z };
+ }
+ var S = function(P) {
+ var B = Math.sin(P / 2), U = Math.cos(P / 2), F = 0, $ = 0, W = 0;
+ return F = a.x * B, $ = a.y * B, W = a.z * B, new g.Quaternion(F, $, W, U).normalize();
+ }, T = Math.PI * t / 180, R = S(T);
+ if (h) {
+ var z = new g.Quaternion().copy(this.rotationGroup.quaternion).multiply(R);
+ this.animateMotion(h, M, this.modelGroup.position, this.rotationGroup.position.z, z, this.lookingAt);
+ } else
+ this.rotationGroup.quaternion.multiply(R), this.show();
+ return this;
+ }
+ surfacesFinished() {
+ for (var t in this.surfaces)
+ if (!this.surfaces[t][0].done)
+ return !1;
+ return !0;
+ }
+ /** Returns an array representing the current viewpoint.
+ * Translation, zoom, and rotation quaternion.
+ * @returns {Array.} [ pos.x, pos.y, pos.z, rotationGroup.position.z, q.x, q.y, q.z, q.w ]
+ * */
+ getView() {
+ if (!this.modelGroup)
+ return [0, 0, 0, 0, 0, 0, 0, 1];
+ var t = this.modelGroup.position, a = this.rotationGroup.quaternion;
+ return [
+ t.x,
+ t.y,
+ t.z,
+ this.rotationGroup.position.z,
+ a.x,
+ a.y,
+ a.z,
+ a.w
+ ];
+ }
+ /** Sets the view to the specified translation, zoom, and rotation.
+ *
+ * @param {Array.} arg Array formatted identically to the return value of getView */
+ setView(t, a) {
+ return t === void 0 || !(t instanceof Array || t.length !== 8) ? this : !this.modelGroup || !this.rotationGroup ? this : (this.modelGroup.position.x = t[0], this.modelGroup.position.y = t[1], this.modelGroup.position.z = t[2], this.rotationGroup.position.z = t[3], this.rotationGroup.quaternion.x = t[4], this.rotationGroup.quaternion.y = t[5], this.rotationGroup.quaternion.z = t[6], this.rotationGroup.quaternion.w = t[7], typeof t[8] < "u" && (this.rotationGroup.position.x = t[8], this.rotationGroup.position.y = t[9]), this.show(a), this);
+ }
+ // apply styles, models, etc in viewer
+ /**
+ * Render current state of viewer, after
+ * adding/removing models, applying styles, etc.
+ *
+ */
+ render(t, a) {
+ this.renderer.setViewport(), this.updateClickables();
+ var h = this.getView();
+ this.stateChangeCallback && this.stateChangeCallback(this.getInternalState());
+ var M, w;
+ for (a || (a = this.renderer.supportedExtensions()), M = 0; M < this.models.length; M++)
+ this.models[M] && this.models[M].globj(this.modelGroup, a);
+ for (M = 0; M < this.shapes.length; M++)
+ this.shapes[M] && (typeof this.shapes[M].frame > "u" || this.viewer_frame < 0 || this.shapes[M].frame < 0 || this.shapes[M].frame == this.viewer_frame ? this.shapes[M].globj(this.modelGroup, a) : this.shapes[M].removegl(this.modelGroup));
+ for (M = 0; M < this.labels.length; M++)
+ a.regen && (this.labels[M].dispose(), this.modelGroup.remove(this.labels[M].sprite), this.labels[M].setContext(), this.modelGroup.add(this.labels[M].sprite)), this.labels[M] && typeof this.labels[M].frame < "u" && this.labels[M].frame >= 0 && (this.modelGroup.remove(this.labels[M].sprite), (this.viewer_frame < 0 || this.labels[M].frame == this.viewer_frame) && this.modelGroup.add(this.labels[M].sprite));
+ for (M in this.surfaces)
+ if (this.surfaces.hasOwnProperty(M)) {
+ var S = this.surfaces[M];
+ for (w = 0; w < S.length; w++)
+ if (S.hasOwnProperty(w)) {
+ var T = S[w].geo;
+ if (!S[w].finished || a.regen) {
+ T.verticesNeedUpdate = !0, T.elementsNeedUpdate = !0, T.normalsNeedUpdate = !0, T.colorsNeedUpdate = !0, T.buffersNeedUpdate = !0, T.boundingSphere = null, S[w].mat.needsUpdate = !0, S[w].done && (S[w].finished = !0), S[w].lastGL && this.modelGroup.remove(S[w].lastGL);
+ var R = null;
+ if (S[w].mat instanceof l.LineBasicMaterial ? R = new l.Line(T, S[w].mat) : R = new l.Mesh(T, S[w].mat), S[w].mat.transparent && S[w].mat.opacity == 0 ? R.visible = !1 : R.visible = !0, S[w].symmetries.length > 1 || S[w].symmetries.length == 1 && !S[w].symmetries[w].isIdentity()) {
+ var z, P = new l.Object3D();
+ for (z = 0; z < S[w].symmetries.length; z++) {
+ var B = R.clone();
+ B.matrix = S[w].symmetries[z], B.matrixAutoUpdate = !1, P.add(B);
+ }
+ S[w].lastGL = P, this.modelGroup.add(P);
+ } else
+ S[w].lastGL = R, this.modelGroup.add(R);
+ }
+ }
+ }
+ return this.setView(h), typeof t == "function" && t(this), this;
+ }
+ /* @param {AtomSelectionSpec|any} sel
+ * @return list of models specified by sel
+ */
+ getModelList(t) {
+ let a = [];
+ if (typeof t > "u" || typeof t.model > "u")
+ for (let M = 0; M < this.models.length; M++)
+ this.models[M] && a.push(this.models[M]);
+ else {
+ let M = t.model;
+ Array.isArray(M) || (M = [M]);
+ for (let w = 0; w < M.length; w++)
+ if (typeof M[w] == "number") {
+ var h = M[w];
+ h < 0 && (h += this.models.length), a.push(this.models[h]);
+ } else
+ a.push(M[w]);
+ }
+ return a;
+ }
+ /**
+ *
+ * @param {AtomSelectionSpec}
+ * sel
+ * @return {AtomSpec[]}
+ */
+ getAtomsFromSel(t) {
+ var a = [];
+ typeof t > "u" && (t = {});
+ var h = this.getModelList(t);
+ for (let M = 0; M < h.length; M++)
+ a = a.concat(h[M].selectedAtoms(t));
+ return a;
+ }
+ /**
+ *
+ * @param {AtomSpec}
+ * atom
+ * @param {AtomSelectionSpec}
+ * sel
+ * @return {boolean}
+ */
+ atomIsSelected(t, a) {
+ typeof a > "u" && (a = {});
+ for (var h = this.getModelList(a), M = 0; M < h.length; M++)
+ if (h[M].atomIsSelected(t, a))
+ return !0;
+ return !1;
+ }
+ /** return list of atoms selected by sel
+ *
+ * @param {AtomSelectionSpec} sel
+ * @return {AtomSpec[]}
+ */
+ selectedAtoms(t) {
+ return this.getAtomsFromSel(t);
+ }
+ /**
+ * Returns valid values for the specified attribute in the given selection
+ * @param {string} attribute
+ * @param {AtomSelectionSpec} sel
+ * @return {Array.