@datagrok/helm 2.4.6 → 2.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,94 @@
1
+ import * as grok from 'datagrok-api/grok';
2
+ import * as ui from 'datagrok-api/ui';
3
+ import * as DG from 'datagrok-api/dg';
4
+
5
+ import {after, before, category, delay, expect, expectArray, test, testEvent} from '@datagrok-libraries/utils/src/test';
6
+ import {HelmNotSupportedError, IHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
7
+ import {getHelmHelper} from '@datagrok-libraries/bio/src/helm/helm-helper';
8
+
9
+ import {_package} from '../package-test';
10
+
11
+ type TestSrcType = { helm: string };
12
+ type TestTgtType = { helm: string | null, map: [number, number][] };
13
+
14
+ category('HelmHelper: removeGaps', () => {
15
+ let helmHelper: IHelmHelper;
16
+
17
+ before(async () => {
18
+ helmHelper = await getHelmHelper();
19
+ });
20
+
21
+ const tests: { [testName: string]: { src: TestSrcType, tgt: TestTgtType } } = {
22
+ 'single-linear-start': {
23
+ src: {helm: 'PEPTIDE1{*.[meY].A.G.T}$$$$V2.0'},
24
+ tgt: {
25
+ helm: 'PEPTIDE1{[meY].A.G.T}$$$$V2.0',
26
+ map: [[1, 0], [2, 1], [3, 2], [4, 3]],
27
+ }
28
+ },
29
+ 'single-linear-end': {
30
+ src: {helm: 'PEPTIDE1{[meY].A.G.T.*}$$$$V2.0'},
31
+ tgt: {
32
+ helm: 'PEPTIDE1{[meY].A.G.T}$$$$V2.0',
33
+ map: [[0, 0], [1, 1], [2, 2], [3, 3]],
34
+ }
35
+ },
36
+ 'single-linear-middle': {
37
+ src: {helm: 'PEPTIDE1{[meY].A.*.G.T}$$$$V2.0'},
38
+ tgt: {
39
+ helm: 'PEPTIDE1{[meY].A.G.T}$$$$V2.0',
40
+ map: [[0, 0], [1, 1], [3, 2], [4, 3]],
41
+ }
42
+ },
43
+ 'single-cycle-start': {
44
+ src: {helm: 'PEPTIDE1{*.[meY].C.R.N.P.C.T}$PEPTIDE1,PEPTIDE1,3:R3-7:R3$$$V2.0'},
45
+ tgt: {
46
+ helm: 'PEPTIDE1{[meY].C.R.N.P.C.T}$PEPTIDE1,PEPTIDE1,2:R3-6:R3$$$V2.0',
47
+ map: [[1, 0], [2, 1], [3, 2], [4, 3], [5, 4], [6, 5], [7, 6]],
48
+ }
49
+ },
50
+ 'single-cycle-end': {
51
+ src: {helm: 'PEPTIDE1{[meY].C.R.N.P.C.T.*}$PEPTIDE1,PEPTIDE1,2:R3-6:R3$$$V2.0'},
52
+ tgt: {
53
+ helm: 'PEPTIDE1{[meY].C.R.N.P.C.T}$PEPTIDE1,PEPTIDE1,2:R3-6:R3$$$V2.0',
54
+ map: [[0, 0], [1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6]],
55
+ }
56
+ },
57
+ 'single-cycle-middle': {
58
+ src: {helm: 'PEPTIDE1{[meY].C.R.N.*.P.C.T}$PEPTIDE1,PEPTIDE1,2:R3-7:R3$$$V2.0'},
59
+ tgt: {
60
+ helm: 'PEPTIDE1{[meY].C.R.N.P.C.T}$PEPTIDE1,PEPTIDE1,2:R3-6:R3$$$V2.0',
61
+ map: [[0, 0], [1, 1], [2, 2], [3, 3], [5, 4], [6, 5], [7, 6]],
62
+ }
63
+ },
64
+ 'single-cycle-gap-at-connection': {
65
+ src: {helm: 'PEPTIDE1{[meY].*.C.R.N.P.C.T}$PEPTIDE1,PEPTIDE1,2:R3-7:R3$$$V2.0'},
66
+ tgt: {helm: null, map: []}
67
+ }
68
+ };
69
+
70
+ for (const [testName, testData] of Object.entries(tests)) {
71
+ test(`${testName}`, async () => {
72
+ let resErr: any = null;
73
+ try {
74
+ const res = helmHelper.removeGaps(testData.src.helm);
75
+ expect(res.resHelm, testData.tgt.helm);
76
+ expectArray(Array.from(res.monomerMap!.entries()), testData.tgt.map);
77
+ } catch (err: any) {
78
+ resErr = err;
79
+ }
80
+
81
+ if (testData.tgt.helm === null) { // err expected, for debug on GitHub CI
82
+ expect(resErr != null, true, 'Error expected');
83
+ const isErrorInstance = resErr instanceof HelmNotSupportedError;
84
+ const errCtorName = resErr.constructor.name;
85
+ const isErrorCtor = errCtorName === 'HelmNotSupportedError';
86
+ _package.logger.debug(`Check error object. ` +
87
+ `isErrorInstance: ${isErrorInstance}, isErrorCtor: ${isErrorCtor}, errCtorName: ${errCtorName}`);
88
+ }
89
+
90
+ expect((resErr instanceof HelmNotSupportedError) || resErr?.constructor.name === 'HelmNotSupportedError',
91
+ testData.tgt.helm === null, 'HelmNotSupportedError thrown expected');
92
+ }, testData.tgt.helm == null ? {skipReason: 'GitHub CI does not support testing exceptions'} : undefined);
93
+ }
94
+ });
@@ -28,7 +28,7 @@ category('parseHelm', () => {
28
28
  helm: 'PEPTIDE1{[L-hArg(Et,Et)].E.F.G}|PEPTIDE2{C.E}$PEPTIDE1,PEPTIDE2,2:R3-1:R1$$$V2.0'
29
29
  }
30
30
  },
31
- 'PT-cycic': {
31
+ 'PT-cyclic': {
32
32
  src: 'PEPTIDE1{[meI].C.[Aca].[Cys_SEt].T.C.[Thr_PO3H2].[Aca]}$PEPTIDE1,PEPTIDE1,8:R2-1:R1$$$V2.0',
33
33
  tgt: {
34
34
  atomCount: 8, bondCount: 8,
@@ -55,8 +55,7 @@ category('parseHelm', () => {
55
55
 
56
56
  // parseHelm is dependent on monomers RGroups available, test requires default monomer library
57
57
  await setUserLibSettingsForTests();
58
- await timeout(async () => { await libHelper.awaitLoaded(); }, 5000,
59
- 'await monomerLib to be loaded');
58
+ await libHelper.awaitLoaded();
60
59
  await libHelper.loadMonomerLib(true);
61
60
  });
62
61
 
@@ -74,7 +73,7 @@ category('parseHelm', () => {
74
73
  for (const [testName, {src, tgt}] of Object.entries(testData)) {
75
74
  test(`woDOM-${testName}`, async () => {
76
75
  _testParseHelmWithoutDOM(src, tgt);
77
- });
76
+ }, testName == 'RNA' ? {skipReason: 'GROK-16721'} : undefined);
78
77
  }
79
78
  });
80
79
 
@@ -103,7 +102,6 @@ function _testParseHelmWithoutDOM(src: string, tgt: TestTgtType): void {
103
102
  io.parseHelm(plugin, src, origin, undefined);
104
103
 
105
104
  const m: Mol<HelmType> = plugin.jsd.m;
106
- debugger;
107
105
  const resHelm = io.getHelm(m);
108
106
  expect(m.atoms.length, tgt.atomCount);
109
107
  expect(m.bonds.length, tgt.bondCount);
@@ -6,6 +6,9 @@ import {HelmType, PolymerType, Atom, Mol, ISeqMonomer, HelmMol, HelmAtom} from '
6
6
 
7
7
  import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
8
8
 
9
+ import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
10
+ import {GAP_SYMBOL, GapOriginals, NOTATION} from '@datagrok-libraries/bio/src/utils/macromolecule/consts';
11
+
9
12
  import {HelmMonomerPlacer} from '../helm-monomer-placer';
10
13
 
11
14
  export function getHoveredMonomerFromEditorMol(
@@ -77,23 +80,33 @@ export function getHoveredMonomerFallback(
77
80
  }
78
81
  left = (argsX >= sumLengths[left]) ? left : left - 1; // correct left to between sumLengths
79
82
  if (left >= 0)
80
- hoveredSeqMonomer = getSeqMonomerFromHelm(allParts[0], allParts[left]);
83
+ hoveredSeqMonomer = getSeqMonomerFromHelm(left, allParts[left], allParts[0]);
81
84
  return hoveredSeqMonomer;
82
85
  }
83
86
 
84
87
  export function getSeqMonomerFromHelmAtom(atom: HelmAtom): ISeqMonomer {
85
88
  const polymerType = helmTypeToPolymerType(atom.bio!.type);
86
- return {symbol: atom.elem, polymerType: polymerType};
89
+ const canonicalSymbol = atom.elem === GapOriginals[NOTATION.HELM] ? GAP_SYMBOL : atom.elem;
90
+ return {position: parseInt(atom.bio!.continuousId as string) - 1, symbol: atom.elem, biotype: atom.bio!.type};
87
91
  }
88
92
 
89
- function getSeqMonomerFromHelm(
90
- helmPrefix: string, symbol: string
91
- ): ISeqMonomer {
93
+ /** Linear
94
+ * @deprecated
95
+ */
96
+ function getSeqMonomerFromHelm(pos: number, symbol: string, helmPrefix: string): ISeqMonomer {
92
97
  let resSeqMonomer: ISeqMonomer | undefined = undefined;
93
98
  const polymerTypeList: PolymerType[] = ['RNA', 'PEPTIDE', 'CHEM', 'BLOB', 'G'];
94
99
  for (const polymerType of polymerTypeList) {
95
- if (helmPrefix.startsWith(polymerType))
96
- resSeqMonomer = {symbol: symbol, polymerType: polymerType};
100
+ if (helmPrefix.startsWith(polymerType)) {
101
+ let helmType: HelmType = HelmTypes.AA;
102
+ if (polymerType == 'RNA')
103
+ helmType = HelmTypes.NUCLEOTIDE;
104
+ else if (polymerType == 'PEPTIDE')
105
+ helmType = HelmTypes.AA;
106
+ else if (polymerType == 'CHEM')
107
+ helmType = HelmTypes.CHEM;
108
+ resSeqMonomer = {position: pos, symbol: symbol, biotype: helmType};
109
+ }
97
110
  }
98
111
  if (!resSeqMonomer)
99
112
  throw new Error(`Monomer not found for symbol = '${symbol}' and helmPrefix = '${helmPrefix}'.`);
@@ -5,14 +5,7 @@ import * as DG from 'datagrok-api/dg';
5
5
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
6
6
  import {IMonomerLib, Monomer} from '@datagrok-libraries/bio/src/types';
7
7
  import {Atom, HelmType, IWebEditorMonomer, GetMonomerResType} from '@datagrok-libraries/bio/src/helm/types';
8
- import {helmTypeToPolymerType} from '@datagrok-libraries/bio/src/monomer-works/monomer-works';
9
- import {
10
- HELM_REQUIRED_FIELD as REQ
11
- } from '@datagrok-libraries/bio/src/utils/const';
12
- import {HelmTypes} from '@datagrok-libraries/bio/src/helm/consts';
13
8
 
14
- import {AmbiguousWebEditorMonomer, GapWebEditorMonomer, getRS, MissingWebEditorMonomer} from './get-monomer-dummy';
15
- import {LibraryWebEditorMonomer} from './get-monomer-of-library';
16
9
  import {OrgHelmModule, ScilModule} from '../types';
17
10
  import {RGROUP_CAP_GROUP_NAME, RGROUP_LABEL, SMILES} from '../constants';
18
11
 
@@ -21,10 +14,6 @@ import {_package} from '../package';
21
14
  declare const org: OrgHelmModule;
22
15
  declare const scil: ScilModule;
23
16
 
24
- const monomerRe = /[\w()]+/;
25
- //** Do not mess with monomer symbol with parenthesis enclosed in square brackets */
26
- const ambMonomerRe = RegExp(String.raw`\(${monomerRe}(,${monomerRe})+\)`);
27
-
28
17
  type GetMonomerOverridingFunc = (
29
18
  a: Atom<HelmType> | HelmType, name: string | undefined, monomerLib: IMonomerLib,
30
19
  originalGetMonomer: (a: Atom<HelmType> | HelmType, name: string) => GetMonomerResType) => GetMonomerResType;
@@ -52,69 +41,6 @@ export function getMonomerOverrideAndLogAlert(
52
41
  }
53
42
  }
54
43
 
55
- /** Inputs logic */
56
- export function getMonomerHandleArgs(
57
- a: Atom<HelmType> | HelmType, name?: string
58
- ): [/** biotype */ HelmType, /** elem */ string] {
59
- if (!a)
60
- throw new Error(`Argument 'a' of type Atom or HelmType is mandatory.`);
61
- let biotype: HelmType;
62
- let elem: string;
63
- if ((a as Atom<HelmType>).T === 'ATOM') {
64
- biotype = (a as Atom<HelmType>).biotype()!;
65
- elem = (a as Atom<HelmType>).elem;
66
- } else {
67
- biotype = a as HelmType;
68
- elem = org.helm.webeditor.IO.trimBracket(name!);
69
- }
70
- return [biotype, elem];
71
- }
72
-
73
-
74
- /** Substitutes {@link org.helm.webeditor.Monomers.getMonomer()} */
75
- export function getWebEditorMonomer(
76
- monomerLib: IMonomerLib,
77
- a: Atom<HelmType> | HelmType, argName?: string,
78
- ): IWebEditorMonomer | null {
79
- const [biotype, elem] = getMonomerHandleArgs(a, argName);
80
- const pt = helmTypeToPolymerType(biotype);
81
-
82
- /** Get or create {@link Monomer} object (in case it is missing in monomer library current config) */
83
- let m: Monomer | null = monomerLib.getMonomer(pt, elem);
84
- if (m && biotype == HelmTypes.LINKER && m[REQ.RGROUPS].length != 2) {
85
- // Web Editor expects null
86
- return null;
87
- }
88
- if (m && biotype == HelmTypes.SUGAR && m[REQ.RGROUPS].length != 3) {
89
- // Web Editor expects null
90
- return null;
91
- }
92
- if (!m /* && biotype != HelmTypes.LINKER*/)
93
- m = monomerLib.addMissingMonomer(pt, elem);
94
-
95
- /** Get or create {@link org,helm.WebEditorMonomer} */
96
- let resWem: IWebEditorMonomer | null = m.wem ?? null;
97
- if (!resWem) {
98
- if (elem === '*')
99
- resWem = m.wem = new GapWebEditorMonomer(biotype, elem);
100
- else if (
101
- (biotype === 'HELM_NUCLETIDE' && elem === 'N') ||
102
- (biotype === 'HELM_AA' && elem === 'X') ||
103
- (biotype === 'HELM_CHEM' && false) || // TODO: Ambiguous monomer for CHEM
104
- ambMonomerRe.test(elem) // e.g. (A,R,_)
105
- )
106
- resWem = m.wem = new AmbiguousWebEditorMonomer(biotype, elem);
107
- else if (!m.lib)
108
- resWem = m.wem = new MissingWebEditorMonomer(biotype, elem);
109
-
110
-
111
- if (!resWem)
112
- resWem = m.wem = LibraryWebEditorMonomer.fromMonomer(biotype, m);
113
- }
114
-
115
- return resWem;
116
- }
117
-
118
44
  /** Fills org.helm.webeditor.Monomers dictionary for WebEditor */
119
45
  export function rewriteLibraries(monomerLib: IMonomerLib): void {
120
46
  org.helm.webeditor.Monomers.clear();
@@ -145,7 +71,7 @@ export function rewriteLibraries(monomerLib: IMonomerLib): void {
145
71
  } else if (monomer[SMILES] != null) {
146
72
  // @ts-ignore
147
73
  webEditorMonomer.rs = Object.keys(getRS(monomer[SMILES].toString())).length;
148
- webEditorMonomer.at = getRS(monomer[SMILES].toString());
74
+ webEditorMonomer.at = monomerLib.getRS(monomer[SMILES].toString());
149
75
  } else
150
76
  isBroken = true;
151
77
 
@@ -12,8 +12,9 @@ import {HelmAux, HelmProps} from '@datagrok-libraries/bio/src/viewers/helm-servi
12
12
  import {_getHelmService} from '../package-utils';
13
13
  import {errInfo} from '@datagrok-libraries/bio/src/utils/err-info';
14
14
  import {ILogger} from '@datagrok-libraries/bio/src/utils/logger';
15
- import {getGridCellRendererBack} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
15
+ import {getGridCellColTemp} from '@datagrok-libraries/bio/src/utils/cell-renderer-back-base';
16
16
  import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
17
+ import {execMonomerHoverLinks} from '@datagrok-libraries/bio/src/monomer-works/monomer-hover';
17
18
 
18
19
  import {getHoveredMonomerFromEditorMol, getSeqMonomerFromHelmAtom} from './get-hovered';
19
20
 
@@ -129,16 +130,23 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
129
130
  }
130
131
  const hoveredAtom = getHoveredMonomerFromEditorMol(argsX, argsY, editorMol, gridCell.bounds.height);
131
132
 
133
+ let seqMonomer: ISeqMonomer | null = null;
132
134
  if (hoveredAtom) {
133
- const seqMonomer = getSeqMonomerFromHelmAtom(hoveredAtom);
135
+ seqMonomer = getSeqMonomerFromHelmAtom(hoveredAtom);
134
136
  const monomerLib = _package.monomerLib;
135
- const tooltipEl = monomerLib ? monomerLib.getTooltip(seqMonomer.polymerType, seqMonomer.symbol) :
137
+ const tooltipEl = monomerLib ? monomerLib.getTooltip(seqMonomer.biotype, seqMonomer.symbol) :
136
138
  ui.divText('Monomer library is not available');
137
139
  ui.tooltip.show(tooltipEl, e.x + 16, e.y + 16);
138
140
  } else {
139
141
  // Tooltip for missing monomers
140
142
  ui.tooltip.hide();
141
143
  }
144
+
145
+ execMonomerHoverLinks(gridCell, seqMonomer);
146
+ }
147
+
148
+ onMouseLeave(gridCell: DG.GridCell, e: MouseEvent): void {
149
+ execMonomerHoverLinks(gridCell, null);
142
150
  }
143
151
 
144
152
  public override render(g: CanvasRenderingContext2D,
@@ -161,10 +169,10 @@ export class HelmGridCellRendererBack extends CellRendererBackAsyncBase<HelmProp
161
169
 
162
170
  static getOrCreate(gridCell: DG.GridCell): HelmGridCellRendererBack {
163
171
  const [gridCol, tableCol, temp] =
164
- getGridCellRendererBack<string, HelmGridCellRendererBack>(gridCell);
172
+ getGridCellColTemp<string, HelmGridCellRendererBack>(gridCell);
165
173
 
166
- let res: HelmGridCellRendererBack = temp['rendererBack'];
167
- if (!res) res = temp['rendererBack'] = new HelmGridCellRendererBack(gridCol, tableCol);
174
+ let res: HelmGridCellRendererBack = temp.rendererBack;
175
+ if (!res) res = temp.rendererBack = new HelmGridCellRendererBack(gridCol, tableCol);
168
176
  return res;
169
177
  }
170
178
  }
@@ -191,6 +199,19 @@ export class HelmGridCellRenderer extends DG.GridCellRenderer {
191
199
  }
192
200
  }
193
201
 
202
+ override onMouseLeave(gridCell: DG.GridCell, e: MouseEvent) {
203
+ const logPrefix = `Helm: HelmGridCellRenderer.onMouseLeave()`;
204
+ try {
205
+ HelmGridCellRendererBack.getOrCreate(gridCell).onMouseLeave(gridCell, e);
206
+ } catch (err: any) {
207
+ const [errMsg, errStack] = errInfo(err);
208
+ _package.logger.error(errMsg, undefined, errStack);
209
+ } finally {
210
+ e.preventDefault();
211
+ e.stopPropagation();
212
+ }
213
+ }
214
+
194
215
  override render(
195
216
  g: CanvasRenderingContext2D, x: number, y: number, w: number, h: number,
196
217
  gridCell: DG.GridCell, cellStyle: DG.GridCellStyle
@@ -5,7 +5,7 @@ import * as DG from 'datagrok-api/dg';
5
5
  import $ from 'cash-dom';
6
6
  import {fromEvent, Observable, Unsubscribable} from 'rxjs';
7
7
 
8
- import {IMonomerLib} from '@datagrok-libraries/bio/src/types/index';
8
+ import {IMonomerLibBase} from '@datagrok-libraries/bio/src/types/index';
9
9
  import {HelmInputBase, IHelmHelper, IHelmInputInitOptions} from '@datagrok-libraries/bio/src/helm/helm-helper';
10
10
  import {HelmAtom, HelmMol, HelmString, IHelmWebEditor} from '@datagrok-libraries/bio/src/helm/types';
11
11
 
@@ -72,7 +72,7 @@ export class HelmInput extends HelmInputBase {
72
72
 
73
73
  protected constructor(
74
74
  private readonly helmHelper: IHelmHelper,
75
- private readonly monomerLib: IMonomerLib,
75
+ private readonly monomerLib: IMonomerLibBase,
76
76
  name?: string,
77
77
  public readonly options?: IHelmInputInitOptions,
78
78
  private readonly logger = _package.logger,
@@ -135,7 +135,7 @@ export class HelmInput extends HelmInputBase {
135
135
  }
136
136
 
137
137
  /** Inspired by {@link DG.MarkdownInput}, {@link ui._create} */
138
- static create(helmHelper: IHelmHelper, monomerLib: IMonomerLib,
138
+ static create(helmHelper: IHelmHelper, monomerLib: IMonomerLibBase,
139
139
  name?: string, options?: IHelmInputInitOptions
140
140
  ): HelmInput {
141
141
  const input = new HelmInput(helmHelper, monomerLib, name, options);
@@ -183,7 +183,7 @@ export class HelmInput extends HelmInputBase {
183
183
  if (hoveredAtom) {
184
184
  const seqMonomer = getSeqMonomerFromHelmAtom(hoveredAtom);
185
185
  const monomerLib = _package.monomerLib;
186
- const tooltipEl = monomerLib ? monomerLib.getTooltip(seqMonomer.polymerType, seqMonomer.symbol) :
186
+ const tooltipEl = monomerLib ? monomerLib.getTooltip(seqMonomer.biotype, seqMonomer.symbol) :
187
187
  ui.divText('Monomer library is not available');
188
188
  this.showTooltip(tooltipEl, hoveredAtom);
189
189
  event.preventDefault();
@@ -0,0 +1,27 @@
1
+ define("dijit/_base", [
2
+ "./main",
3
+ "./a11y", // used to be in dijit/_base/manager
4
+ "./WidgetSet", // used to be in dijit/_base/manager
5
+ "./_base/focus",
6
+ "./_base/manager",
7
+ "./_base/place",
8
+ "./_base/popup",
9
+ "./_base/scroll",
10
+ "./_base/sniff",
11
+ "./_base/typematic",
12
+ "./_base/wai",
13
+ "./_base/window"
14
+ ], function(dijit){
15
+
16
+ // module:
17
+ // dijit/_base
18
+
19
+ /*=====
20
+ return {
21
+ // summary:
22
+ // Includes all the modules in dijit/_base
23
+ };
24
+ =====*/
25
+
26
+ return dijit._base;
27
+ });
@@ -0,0 +1,253 @@
1
+ //>>built
2
+ define("dojox/gfx/_base",["dojo/_base/kernel","dojo/_base/lang","dojo/_base/Color","dojo/_base/sniff","dojo/_base/window","dojo/_base/array","dojo/dom","dojo/dom-construct","dojo/dom-geometry"],function(_1,_2,_3,_4,_5,_6,_7,_8,_9){
3
+ var g=_2.getObject("dojox.gfx",true),b=g._base={};
4
+ g._hasClass=function(_a,_b){
5
+ var _c=_a.getAttribute("className");
6
+ return _c&&(" "+_c+" ").indexOf(" "+_b+" ")>=0;
7
+ };
8
+ g._addClass=function(_d,_e){
9
+ var _f=_d.getAttribute("className")||"";
10
+ if(!_f||(" "+_f+" ").indexOf(" "+_e+" ")<0){
11
+ _d.setAttribute("className",_f+(_f?" ":"")+_e);
12
+ }
13
+ };
14
+ g._removeClass=function(_10,_11){
15
+ var cls=_10.getAttribute("className");
16
+ if(cls){
17
+ _10.setAttribute("className",cls.replace(new RegExp("(^|\\s+)"+_11+"(\\s+|$)"),"$1$2"));
18
+ }
19
+ };
20
+ b._getFontMeasurements=function(){
21
+ var _12={"1em":0,"1ex":0,"100%":0,"12pt":0,"16px":0,"xx-small":0,"x-small":0,"small":0,"medium":0,"large":0,"x-large":0,"xx-large":0};
22
+ var p,_13;
23
+ if(_4("ie")){
24
+ _13=_5.doc.documentElement.style.fontSize||"";
25
+ if(!_13){
26
+ _5.doc.documentElement.style.fontSize="100%";
27
+ }
28
+ }
29
+ var div=_8.create("div",{style:{position:"absolute",left:"0",top:"-100px",width:"30px",height:"1000em",borderWidth:"0",margin:"0",padding:"0",outline:"none",lineHeight:"1",overflow:"hidden"}},_5.body());
30
+ for(p in _12){
31
+ div.style.fontSize=p;
32
+ _12[p]=Math.round(div.offsetHeight*12/16)*16/12/1000;
33
+ }
34
+ if(_4("ie")){
35
+ _5.doc.documentElement.style.fontSize=_13;
36
+ }
37
+ _5.body().removeChild(div);
38
+ return _12;
39
+ };
40
+ var _14=null;
41
+ b._getCachedFontMeasurements=function(_15){
42
+ if(_15||!_14){
43
+ _14=b._getFontMeasurements();
44
+ }
45
+ return _14;
46
+ };
47
+ var _16=null,_17={};
48
+ b._getTextBox=function(_18,_19,_1a){
49
+ var m,s,al=arguments.length;
50
+ var i,box;
51
+ if(!_16){
52
+ _16=_8.create("div",{style:{position:"absolute",top:"-10000px",left:"0",visibility:"hidden"}},_5.body());
53
+ }
54
+ m=_16;
55
+ m.className="";
56
+ s=m.style;
57
+ s.borderWidth="0";
58
+ s.margin="0";
59
+ s.padding="0";
60
+ s.outline="0";
61
+ if(al>1&&_19){
62
+ for(i in _19){
63
+ if(i in _17){
64
+ continue;
65
+ }
66
+ s[i]=_19[i];
67
+ }
68
+ }
69
+ if(al>2&&_1a){
70
+ m.className=_1a;
71
+ }
72
+ m.innerHTML=_18;
73
+ if(m.getBoundingClientRect){
74
+ var bcr=m.getBoundingClientRect();
75
+ box={l:bcr.left,t:bcr.top,w:bcr.width||(bcr.right-bcr.left),h:bcr.height||(bcr.bottom-bcr.top)};
76
+ }else{
77
+ box=_9.getMarginBox(m);
78
+ }
79
+ m.innerHTML="";
80
+ return box;
81
+ };
82
+ b._computeTextLocation=function(_1b,_1c,_1d,_1e){
83
+ var loc={},_1f=_1b.align;
84
+ switch(_1f){
85
+ case "end":
86
+ loc.x=_1b.x-_1c;
87
+ break;
88
+ case "middle":
89
+ loc.x=_1b.x-_1c/2;
90
+ break;
91
+ default:
92
+ loc.x=_1b.x;
93
+ break;
94
+ }
95
+ var c=_1e?0.75:1;
96
+ loc.y=_1b.y-_1d*c;
97
+ return loc;
98
+ };
99
+ b._computeTextBoundingBox=function(s){
100
+ if(!g._base._isRendered(s)){
101
+ return {x:0,y:0,width:0,height:0};
102
+ }
103
+ var loc,_20=s.getShape(),_21=s.getFont()||g.defaultFont,w=s.getTextWidth(),h=g.normalizedLength(_21.size);
104
+ loc=b._computeTextLocation(_20,w,h,true);
105
+ return {x:loc.x,y:loc.y,width:w,height:h};
106
+ };
107
+ b._isRendered=function(s){
108
+ var p=s.parent;
109
+ while(p&&p.getParent){
110
+ p=p.parent;
111
+ }
112
+ return p!==null;
113
+ };
114
+ var _22=0;
115
+ b._getUniqueId=function(){
116
+ var id;
117
+ do{
118
+ id=_1._scopeName+"xUnique"+(++_22);
119
+ }while(_7.byId(id));
120
+ return id;
121
+ };
122
+ var _23=_4("pointer-events")?"touchAction":_4("MSPointer")?"msTouchAction":null;
123
+ b._fixMsTouchAction=_23?function(_24){
124
+ _24.rawNode.style[_23]="none";
125
+ }:function(){
126
+ };
127
+ _2.mixin(g,{defaultPath:{type:"path",path:""},defaultPolyline:{type:"polyline",points:[]},defaultRect:{type:"rect",x:0,y:0,width:100,height:100,r:0},defaultEllipse:{type:"ellipse",cx:0,cy:0,rx:200,ry:100},defaultCircle:{type:"circle",cx:0,cy:0,r:100},defaultLine:{type:"line",x1:0,y1:0,x2:100,y2:100},defaultImage:{type:"image",x:0,y:0,width:0,height:0,src:""},defaultText:{type:"text",x:0,y:0,text:"",align:"start",decoration:"none",rotated:false,kerning:true},defaultTextPath:{type:"textpath",text:"",align:"start",decoration:"none",rotated:false,kerning:true},defaultStroke:{type:"stroke",color:"black",style:"solid",width:1,cap:"butt",join:4},defaultLinearGradient:{type:"linear",x1:0,y1:0,x2:100,y2:100,colors:[{offset:0,color:"black"},{offset:1,color:"white"}]},defaultRadialGradient:{type:"radial",cx:0,cy:0,r:100,colors:[{offset:0,color:"black"},{offset:1,color:"white"}]},defaultPattern:{type:"pattern",x:0,y:0,width:0,height:0,src:""},defaultFont:{type:"font",style:"normal",variant:"normal",weight:"normal",size:"10pt",family:"serif"},getDefault:(function(){
128
+ var _25={};
129
+ return function(_26){
130
+ var t=_25[_26];
131
+ if(t){
132
+ return new t();
133
+ }
134
+ t=_25[_26]=new Function();
135
+ t.prototype=g["default"+_26];
136
+ return new t();
137
+ };
138
+ })(),normalizeColor:function(_27){
139
+ return (_27 instanceof _3)?_27:new _3(_27);
140
+ },normalizeParameters:function(_28,_29){
141
+ var x;
142
+ if(_29){
143
+ var _2a={};
144
+ for(x in _28){
145
+ if(x in _29&&!(x in _2a)){
146
+ _28[x]=_29[x];
147
+ }
148
+ }
149
+ }
150
+ return _28;
151
+ },makeParameters:function(_2b,_2c){
152
+ var i=null;
153
+ if(!_2c){
154
+ return _2.delegate(_2b);
155
+ }
156
+ var _2d={};
157
+ for(i in _2b){
158
+ if(!(i in _2d)){
159
+ _2d[i]=_2.clone((i in _2c)?_2c[i]:_2b[i]);
160
+ }
161
+ }
162
+ return _2d;
163
+ },formatNumber:function(x,_2e){
164
+ var val=x.toString();
165
+ if(val.indexOf("e")>=0){
166
+ val=x.toFixed(4);
167
+ }else{
168
+ var _2f=val.indexOf(".");
169
+ if(_2f>=0&&val.length-_2f>5){
170
+ val=x.toFixed(4);
171
+ }
172
+ }
173
+ if(x<0){
174
+ return val;
175
+ }
176
+ return _2e?" "+val:val;
177
+ },makeFontString:function(_30){
178
+ return _30.style+" "+_30.variant+" "+_30.weight+" "+_30.size+" "+_30.family;
179
+ },splitFontString:function(str){
180
+ var _31=g.getDefault("Font");
181
+ var t=str.split(/\s+/);
182
+ do{
183
+ if(t.length<5){
184
+ break;
185
+ }
186
+ _31.style=t[0];
187
+ _31.variant=t[1];
188
+ _31.weight=t[2];
189
+ var i=t[3].indexOf("/");
190
+ _31.size=i<0?t[3]:t[3].substring(0,i);
191
+ var j=4;
192
+ if(i<0){
193
+ if(t[4]=="/"){
194
+ j=6;
195
+ }else{
196
+ if(t[4].charAt(0)=="/"){
197
+ j=5;
198
+ }
199
+ }
200
+ }
201
+ if(j<t.length){
202
+ _31.family=t.slice(j).join(" ");
203
+ }
204
+ }while(false);
205
+ return _31;
206
+ },cm_in_pt:72/2.54,mm_in_pt:7.2/2.54,px_in_pt:function(){
207
+ return g._base._getCachedFontMeasurements()["12pt"]/12;
208
+ },pt2px:function(len){
209
+ return len*g.px_in_pt();
210
+ },px2pt:function(len){
211
+ return len/g.px_in_pt();
212
+ },normalizedLength:function(len){
213
+ if(len.length===0){
214
+ return 0;
215
+ }
216
+ if(len.length>2){
217
+ var _32=g.px_in_pt();
218
+ var val=parseFloat(len);
219
+ switch(len.slice(-2)){
220
+ case "px":
221
+ return val;
222
+ case "pt":
223
+ return val*_32;
224
+ case "in":
225
+ return val*72*_32;
226
+ case "pc":
227
+ return val*12*_32;
228
+ case "mm":
229
+ return val*g.mm_in_pt*_32;
230
+ case "cm":
231
+ return val*g.cm_in_pt*_32;
232
+ }
233
+ }
234
+ return parseFloat(len);
235
+ },pathVmlRegExp:/([A-Za-z]+)|(\d+(\.\d+)?)|(\.\d+)|(-\d+(\.\d+)?)|(-\.\d+)/g,pathSvgRegExp:/([A-DF-Za-df-z])|([-+]?\d*[.]?\d+(?:[eE][-+]?\d+)?)/g,equalSources:function(a,b){
236
+ return a&&b&&a===b;
237
+ },switchTo:function(_33){
238
+ var ns=typeof _33=="string"?g[_33]:_33;
239
+ if(ns){
240
+ _6.forEach(["Group","Rect","Ellipse","Circle","Line","Polyline","Image","Text","Path","TextPath","Surface","createSurface","fixTarget"],function(_34){
241
+ g[_34]=ns[_34];
242
+ });
243
+ if(typeof _33=="string"){
244
+ g.renderer=_33;
245
+ }else{
246
+ _6.some(["svg","vml","canvas","canvasWithEvents","silverlight"],function(r){
247
+ return (g.renderer=g[r]&&g[r].Surface===g.Surface?r:null);
248
+ });
249
+ }
250
+ }
251
+ }});
252
+ return g;
253
+ });