julien-c HF staff commited on
Commit
83140f2
1 Parent(s): b083f74

Hardcode static outputs to get rid of API

Browse files
Files changed (4) hide show
  1. .vscode/tasks.json +25 -5
  2. dist/script.js +568 -128
  3. js-src/Coref.ts +478 -8
  4. tsconfig.json +1 -1
.vscode/tasks.json CHANGED
@@ -1,11 +1,31 @@
1
  {
2
  // See https://go.microsoft.com/fwlink/?LinkId=733558
3
  // for the documentation about the tasks.json format
4
- "version": "0.1.0",
5
  "command": "tsc",
6
- "isShellCommand": true,
7
- "args": ["-w", "-p", "."],
8
- "showOutput": "silent",
 
 
9
  "isBackground": true,
10
- "problemMatcher": "$tsc-watch"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  }
 
1
  {
2
  // See https://go.microsoft.com/fwlink/?LinkId=733558
3
  // for the documentation about the tasks.json format
4
+ "version": "2.0.0",
5
  "command": "tsc",
6
+ "args": [
7
+ "-w",
8
+ "-p",
9
+ "."
10
+ ],
11
  "isBackground": true,
12
+ "problemMatcher": "$tsc-watch",
13
+ "tasks": [
14
+ {
15
+ "label": "tsc",
16
+ "type": "shell",
17
+ "command": "tsc",
18
+ "args": [
19
+ "-w",
20
+ "-p",
21
+ "."
22
+ ],
23
+ "isBackground": true,
24
+ "problemMatcher": "$tsc-watch",
25
+ "group": {
26
+ "_id": "build",
27
+ "isDefault": false
28
+ }
29
+ }
30
+ ]
31
  }
dist/script.js CHANGED
@@ -1,7 +1,459 @@
1
- var Coref = (function () {
2
- function Coref(endpoint, opts) {
3
- this.onStart = function () { };
4
- this.onSuccess = function () { };
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  this.endpoint = endpoint;
6
  if (opts.onStart) {
7
  this.onStart = opts.onStart;
@@ -11,63 +463,66 @@ var Coref = (function () {
11
  }
12
  window.addEventListener('resize', this.svgResize);
13
  }
14
- Coref.prototype.svgResize = function () {
15
  if (!this.container || !this.svgContainer) {
16
  return;
17
  }
18
- this.svgContainer.setAttribute('width', "" + this.container.scrollWidth);
19
- this.svgContainer.setAttribute('height', "" + this.container.scrollHeight);
20
- };
21
- Coref.prototype.parse = function (text) {
22
- var _this = this;
23
  this.onStart();
24
- var path = this.endpoint + "?text=" + encodeURIComponent(text);
25
- var request = new XMLHttpRequest();
 
 
 
 
 
 
 
 
26
  request.open('GET', path);
27
- request.onload = function () {
28
  if (request.status >= 200 && request.status < 400) {
29
- _this.onSuccess();
30
- var res = JSON.parse(request.responseText);
31
- _this.render(res);
32
  }
33
  else {
34
  console.error('Error', request);
35
  }
36
  };
37
  request.send();
38
- };
39
- Coref.prototype.render = function (res) {
40
- var _this = this;
41
- var mentions = res.mentions;
42
- for (var _i = 0, mentions_1 = mentions; _i < mentions_1.length; _i++) {
43
- var m = mentions_1[_i];
44
  m.singleScore = res.singleScores[m.index] || undefined;
45
  }
46
- var markup = Displacy.render(res.cleanedText, mentions);
47
  if (!this.container || !this.svgContainer) {
48
  return;
49
  }
50
- this.container.innerHTML = "<div class=\"text\">" + markup + "</div>";
51
  this.svgContainer.textContent = "";
52
  this.svgResize();
53
  window.container = this.container;
54
  window.svgContainer = this.svgContainer;
55
- var endY = document.querySelector('.container .text').getBoundingClientRect().top
56
  - this.container.getBoundingClientRect().top
57
  - 2;
58
  SvgArrow.yArrows = endY;
59
- for (var _a = 0, _b = Object.entries(res.pairScores); _a < _b.length; _a++) {
60
- var _c = _b[_a], __from = _c[0], scores = _c[1];
61
- var from = parseInt(__from, 10);
62
- for (var _d = 0, _e = Object.entries(scores); _d < _e.length; _d++) {
63
- var _f = _e[_d], __to = _f[0], score = _f[1];
64
- var to = parseInt(__to, 10);
65
- var markFrom = document.querySelector("mark[data-index=\"" + from + "\"]");
66
- var markTo = document.querySelector("mark[data-index=\"" + to + "\"]");
67
- var arrow = new SvgArrow(this.container, markFrom, markTo, score);
68
- if (score >= Math.max.apply(Math, Object.values(scores))) {
69
  arrow.classNames.push('score-ok');
70
- var singleScore = res.singleScores[from];
71
  if (singleScore && score >= singleScore) {
72
  arrow.classNames.push('score-best');
73
  }
@@ -75,35 +530,32 @@ var Coref = (function () {
75
  this.svgContainer.appendChild(arrow.generate());
76
  }
77
  }
78
- document.querySelectorAll('.displacy-arrow.score-ok').forEach(function (arw) {
79
- _this.svgContainer.appendChild(arw);
80
  });
81
- };
82
- return Coref;
83
- }());
84
- var Displacy = (function () {
85
- function Displacy() {
86
  }
87
- Displacy.sortSpans = function (spans) {
88
- spans.sort(function (a, b) {
 
 
89
  if (a.start === b.start) {
90
  return b.end - a.end;
91
  }
92
  return a.start - b.start;
93
  });
94
- spans.forEach(function (s, i) {
95
  if (i < spans.length - 1) {
96
- var sNext = spans[i + 1];
97
  if (s.start < sNext.start && s.end > sNext.start) {
98
  console.log("ERROR", "Spans: strict overlapping");
99
  }
100
  }
101
  });
102
- };
103
- Displacy.render = function (text, spans) {
104
  this.sortSpans(spans);
105
- var tags = {};
106
- var __addTag = function (i, s, tag) {
107
  if (Array.isArray(tags[i])) {
108
  tags[i].push({ span: s, tag: tag });
109
  }
@@ -111,93 +563,83 @@ var Displacy = (function () {
111
  tags[i] = [{ span: s, tag: tag }];
112
  }
113
  };
114
- for (var _i = 0, spans_1 = spans; _i < spans_1.length; _i++) {
115
- var s = spans_1[_i];
116
  __addTag(s.start, s, "start");
117
  __addTag(s.end, s, "end");
118
  }
119
- var out = {
120
  __content: "",
121
- append: function (s) {
122
  this.__content += s;
123
  }
124
  };
125
- var offset = 0;
126
- var indexes = Object.keys(tags).map(function (k) { return parseInt(k, 10); }).sort(function (a, b) { return a - b; });
127
- for (var _a = 0, indexes_1 = indexes; _a < indexes_1.length; _a++) {
128
- var i = indexes_1[_a];
129
- var spanTags = tags[i];
130
  if (i > offset) {
131
  out.append(text.slice(offset, i));
132
  }
133
  offset = i;
134
- for (var _b = 0, spanTags_1 = spanTags; _b < spanTags_1.length; _b++) {
135
- var sT = spanTags_1[_b];
136
  if (sT.tag === "start") {
137
- out.append("<mark data-entity=\"" + sT.span.type.toLowerCase() + "\" data-index=\"" + sT.span.index + "\">");
138
- var singleScore = sT.span.singleScore;
139
  if (singleScore) {
140
- out.append("<span class=\"single-score\">" + singleScore.toFixed(3) + "</span>");
141
  }
142
  }
143
  else {
144
- out.append("</mark>");
145
  }
146
  }
147
  }
148
  out.append(text.slice(offset, text.length));
149
  return out.__content;
150
- };
151
- return Displacy;
152
- }());
153
- var SvgArrow = (function () {
154
- function SvgArrow(container, markFrom, markTo, score) {
155
  this.classNames = [];
156
  this.container = container;
157
  this.markFrom = markFrom;
158
  this.markTo = markTo;
159
  this.score = score;
160
  }
161
- SvgArrow.prototype._el = function (tag, options) {
162
- var _a = options.classnames, classnames = _a === void 0 ? [] : _a, _b = options.attributes, attributes = _b === void 0 ? [] : _b, _c = options.style, style = _c === void 0 ? [] : _c, _d = options.children, children = _d === void 0 ? [] : _d, text = options.text, id = options.id, xlink = options.xlink;
163
- var ns = 'http://www.w3.org/2000/svg';
164
- var nsx = 'http://www.w3.org/1999/xlink';
165
- var el = document.createElementNS(ns, tag);
166
- classnames.forEach(function (name) { return el.classList.add(name); });
167
- attributes.forEach(function (_a) {
168
- var attr = _a[0], value = _a[1];
169
- return el.setAttribute(attr, value);
170
- });
171
- style.forEach(function (_a) {
172
- var prop = _a[0], value = _a[1];
173
- return el.style[prop] = value;
174
- });
175
  if (xlink)
176
  el.setAttributeNS(nsx, 'xlink:href', xlink);
177
  if (text)
178
  el.appendChild(document.createTextNode(text));
179
  if (id)
180
  el.id = id;
181
- children.forEach(function (child) { return el.appendChild(child); });
182
  return el;
183
- };
184
- SvgArrow.prototype.generate = function () {
185
- var rand = Math.random().toString(36).substr(2, 8);
186
- var startX = this.markTo.getBoundingClientRect().left
187
  - this.container.getBoundingClientRect().left
188
  + this.markTo.getBoundingClientRect().width / 2;
189
- var endX = this.markFrom.getBoundingClientRect().left
190
  - this.container.getBoundingClientRect().left
191
  + this.markFrom.getBoundingClientRect().width / 2;
192
- var curveY = Math.max(-50, SvgArrow.yArrows - (endX - startX) / 3.2);
193
  return this._el('g', {
194
  classnames: ['displacy-arrow'].concat(this.classNames),
195
  children: [
196
  this._el('path', {
197
- id: "arrow-" + rand,
198
  classnames: ['displacy-arc'],
199
  attributes: [
200
- ['d', "M" + startX + "," + SvgArrow.yArrows + " C" + startX + "," + curveY + " " + endX + "," + curveY + " " + endX + "," + SvgArrow.yArrows],
201
  ['stroke-width', '2px'],
202
  ['fill', 'none'],
203
  ['stroke', 'currentColor'],
@@ -209,7 +651,7 @@ var SvgArrow = (function () {
209
  ],
210
  children: [
211
  this._el('textPath', {
212
- xlink: "#arrow-" + rand,
213
  classnames: ['displacy-label'],
214
  attributes: [
215
  ['startOffset', '50%'],
@@ -222,57 +664,55 @@ var SvgArrow = (function () {
222
  }),
223
  ]
224
  });
225
- };
226
- SvgArrow.yArrows = 0;
227
- return SvgArrow;
228
- }());
229
- var ENDPOINT = "https://coref.huggingface.co/coref";
230
- var DEFAULT_NLP_TEXT = function () {
231
- var items = [
232
- "I love my father and my mother. They work hard. She is always nice but he is sometimes rude.",
233
- "My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.",
234
- "My mother's name is Sasha, she likes dogs."
235
  ];
236
  return items[Math.floor(Math.random() * items.length)];
237
  };
238
- var loading = function () {
239
  document.body.classList.toggle('loading');
240
  };
241
- var toggleDebug = function () {
242
  document.body.classList.toggle('debug');
243
- var icons = document.querySelectorAll('.svg-checkbox');
244
- icons.forEach(function (icon) {
245
  icon.classList.toggle('hide');
246
  });
247
  window.localStorage.setItem('debug', document.body.classList.contains('debug').toString());
248
  };
249
- var coref = new Coref(ENDPOINT, {
250
  onStart: loading,
251
  onSuccess: loading,
252
  });
253
- var getQueryVar = function (key) {
254
- var query = window.location.search.substring(1);
255
- var params = query.split('&').map(function (param) { return param.split('='); });
256
- for (var _i = 0, params_1 = params; _i < params_1.length; _i++) {
257
- var param = params_1[_i];
258
  if (param[0] === key) {
259
  return decodeURIComponent(param[1]);
260
  }
261
  }
262
  return undefined;
263
  };
264
- var updateURL = function (text) {
265
- history.pushState({ text: text }, "", "?text=" + encodeURIComponent(text));
266
  };
267
- document.addEventListener('DOMContentLoaded', function () {
268
- var $input = document.querySelector('input.input-message');
269
- var $form = document.querySelector('form.js-form');
270
- var $checkbox = document.querySelector('.js-checkbox');
271
- var $svgContainer = document.querySelector('.svg-container');
272
  coref.container = document.querySelector('.container');
273
  coref.svgContainer = $svgContainer;
274
  {
275
- var queryText = getQueryVar('text');
276
  if (queryText) {
277
  $input.value = queryText;
278
  coref.parse(queryText);
@@ -281,24 +721,24 @@ document.addEventListener('DOMContentLoaded', function () {
281
  coref.parse(DEFAULT_NLP_TEXT());
282
  }
283
  }
284
- $input.addEventListener('keydown', function (evt) {
285
  if (evt.charCode === 13) {
286
  evt.preventDefault();
287
  $form.submit();
288
  }
289
  });
290
- $form.addEventListener('submit', function (evt) {
291
  evt.preventDefault();
292
- var text = ($input.value.length > 0)
293
  ? $input.value
294
  : DEFAULT_NLP_TEXT();
295
  updateURL(text);
296
  coref.parse(text);
297
  });
298
- $checkbox.addEventListener('click', function () {
299
  toggleDebug();
300
  });
301
  if (window.localStorage.getItem('debug') !== 'false') {
302
  toggleDebug();
303
  }
304
- });
 
1
+ const COREF_HARDCODED_OUTPUTS = new Map([
2
+ [
3
+ `I love my father and my mother. They work hard. She is always nice but he is sometimes rude.`,
4
+ {
5
+ cleanedText: "I love my father and my mother. They work hard. She is always nice but he is sometimes rude.",
6
+ corefResText: "I love my father and my mother. They work hard. my mother is always nice but he is sometimes rude.",
7
+ coreferences: [
8
+ {
9
+ resolved: "my mother",
10
+ original: "She",
11
+ },
12
+ ],
13
+ mentions: [
14
+ {
15
+ index: 0,
16
+ type: "PRONOMINAL",
17
+ end: 1,
18
+ start: 0,
19
+ startToken: 0,
20
+ text: "I",
21
+ utterance: 0,
22
+ endToken: 1,
23
+ },
24
+ {
25
+ index: 1,
26
+ type: "PRONOMINAL",
27
+ end: 9,
28
+ start: 7,
29
+ startToken: 2,
30
+ text: "my",
31
+ utterance: 0,
32
+ endToken: 3,
33
+ },
34
+ {
35
+ index: 2,
36
+ type: "LIST",
37
+ end: 30,
38
+ start: 7,
39
+ startToken: 2,
40
+ text: "my father and my mother",
41
+ utterance: 0,
42
+ endToken: 7,
43
+ },
44
+ {
45
+ index: 3,
46
+ type: "NOMINAL",
47
+ end: 16,
48
+ start: 7,
49
+ startToken: 2,
50
+ text: "my father",
51
+ utterance: 0,
52
+ endToken: 4,
53
+ },
54
+ {
55
+ index: 4,
56
+ type: "PRONOMINAL",
57
+ end: 23,
58
+ start: 21,
59
+ startToken: 5,
60
+ text: "my",
61
+ utterance: 0,
62
+ endToken: 6,
63
+ },
64
+ {
65
+ index: 5,
66
+ type: "NOMINAL",
67
+ end: 30,
68
+ start: 21,
69
+ startToken: 5,
70
+ text: "my mother",
71
+ utterance: 0,
72
+ endToken: 7,
73
+ },
74
+ {
75
+ index: 6,
76
+ type: "PRONOMINAL",
77
+ end: 36,
78
+ start: 32,
79
+ startToken: 8,
80
+ text: "They",
81
+ utterance: 0,
82
+ endToken: 9,
83
+ },
84
+ {
85
+ index: 7,
86
+ type: "PRONOMINAL",
87
+ end: 51,
88
+ start: 48,
89
+ startToken: 12,
90
+ text: "She",
91
+ utterance: 0,
92
+ endToken: 13,
93
+ },
94
+ {
95
+ index: 8,
96
+ type: "PRONOMINAL",
97
+ end: 73,
98
+ start: 71,
99
+ startToken: 17,
100
+ text: "he",
101
+ utterance: 0,
102
+ endToken: 18,
103
+ },
104
+ ],
105
+ singleScores: {
106
+ "0": null,
107
+ "1": -0.5316791573216993,
108
+ "2": 1.5312658152183065,
109
+ "3": 1.555544240226482,
110
+ "4": -1.3024868053674725,
111
+ "5": 1.8934082334098847,
112
+ "6": -0.9070692483062055,
113
+ "7": 0.052800267274213275,
114
+ "8": -0.14679673122527748,
115
+ },
116
+ pairScores: {
117
+ "0": {},
118
+ "1": {
119
+ "0": 15.268471128411697,
120
+ },
121
+ "2": {
122
+ "0": -4.4230603182609896,
123
+ "1": -3.382446088190441,
124
+ },
125
+ "3": {
126
+ "0": -4.2304546215104555,
127
+ "1": -3.5681677896088786,
128
+ "2": -1.9470202037608262,
129
+ },
130
+ "4": {
131
+ "0": 11.654522570777317,
132
+ "1": 13.455601870537567,
133
+ "2": -3.218918301345336,
134
+ "3": -3.882381584104524,
135
+ },
136
+ "5": {
137
+ "0": -3.9280501278811983,
138
+ "1": -4.426880262361277,
139
+ "2": -1.7714693884323367,
140
+ "3": -2.722532370602323,
141
+ "4": -3.290164176455163,
142
+ },
143
+ "6": {
144
+ "0": -4.492101447800931,
145
+ "1": -4.636904674331316,
146
+ "2": 3.1158072056943666,
147
+ "3": -2.7375757747875573,
148
+ "4": -4.689981185699828,
149
+ "5": -2.6728186848475537,
150
+ },
151
+ "7": {
152
+ "0": -3.197215354228037,
153
+ "1": -3.538538702704479,
154
+ "2": -0.02408947507481729,
155
+ "3": 0.3052410603657605,
156
+ "4": -3.519641485034609,
157
+ "5": 1.8101046215415115,
158
+ "6": -3.1353342036917917,
159
+ },
160
+ "8": {
161
+ "0": -0.08532621450323319,
162
+ "1": 5.371002989344198,
163
+ "2": -1.4091179987286686,
164
+ "3": 3.152921411948177,
165
+ "4": 2.268706305216419,
166
+ "5": -2.340743897439996,
167
+ "6": -2.8835496283480597,
168
+ "7": -3.4832126005315334,
169
+ },
170
+ },
171
+ cleanedContext: "",
172
+ isResolved: true,
173
+ },
174
+ ],
175
+ [
176
+ `My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.`,
177
+ {
178
+ cleanedText: "My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.",
179
+ corefResText: "My sister is swimming with my sister classmates. her classmates are not bad, but my sister is better. I love watching my sister swim.",
180
+ coreferences: [
181
+ {
182
+ resolved: "My sister",
183
+ original: "she",
184
+ },
185
+ {
186
+ resolved: "My sister",
187
+ original: "her",
188
+ },
189
+ {
190
+ resolved: "her classmates",
191
+ original: "They",
192
+ },
193
+ {
194
+ resolved: "My sister",
195
+ original: "her",
196
+ },
197
+ ],
198
+ mentions: [
199
+ {
200
+ index: 0,
201
+ type: "PRONOMINAL",
202
+ end: 2,
203
+ start: 0,
204
+ startToken: 0,
205
+ text: "My",
206
+ utterance: 0,
207
+ endToken: 1,
208
+ },
209
+ {
210
+ index: 1,
211
+ type: "NOMINAL",
212
+ end: 9,
213
+ start: 0,
214
+ startToken: 0,
215
+ text: "My sister",
216
+ utterance: 0,
217
+ endToken: 2,
218
+ },
219
+ {
220
+ index: 2,
221
+ type: "PRONOMINAL",
222
+ end: 30,
223
+ start: 27,
224
+ startToken: 5,
225
+ text: "her",
226
+ utterance: 0,
227
+ endToken: 6,
228
+ },
229
+ {
230
+ index: 3,
231
+ type: "NOMINAL",
232
+ end: 41,
233
+ start: 27,
234
+ startToken: 5,
235
+ text: "her classmates",
236
+ utterance: 0,
237
+ endToken: 7,
238
+ },
239
+ {
240
+ index: 4,
241
+ type: "PRONOMINAL",
242
+ end: 47,
243
+ start: 43,
244
+ startToken: 8,
245
+ text: "They",
246
+ utterance: 0,
247
+ endToken: 9,
248
+ },
249
+ {
250
+ index: 5,
251
+ type: "PRONOMINAL",
252
+ end: 68,
253
+ start: 65,
254
+ startToken: 14,
255
+ text: "she",
256
+ utterance: 0,
257
+ endToken: 15,
258
+ },
259
+ {
260
+ index: 6,
261
+ type: "PRONOMINAL",
262
+ end: 81,
263
+ start: 80,
264
+ startToken: 18,
265
+ text: "I",
266
+ utterance: 0,
267
+ endToken: 19,
268
+ },
269
+ {
270
+ index: 7,
271
+ type: "PRONOMINAL",
272
+ end: 99,
273
+ start: 96,
274
+ startToken: 21,
275
+ text: "her",
276
+ utterance: 0,
277
+ endToken: 22,
278
+ },
279
+ ],
280
+ singleScores: {
281
+ "0": null,
282
+ "1": 1.609437735243254,
283
+ "2": -1.1017402175324822,
284
+ "3": 1.4347901008486401,
285
+ "4": -0.02895837171142801,
286
+ "5": -0.4266623545401909,
287
+ "6": 0.009921976322164627,
288
+ "7": -1.8629830475049451,
289
+ },
290
+ pairScores: {
291
+ "0": {},
292
+ "1": {
293
+ "0": -2.2413815226574703,
294
+ },
295
+ "2": {
296
+ "0": -2.409825572927252,
297
+ "1": 5.707592445811339,
298
+ },
299
+ "3": {
300
+ "0": -3.0653216162902854,
301
+ "1": -1.6904548462117184,
302
+ "2": -1.8322836987315447,
303
+ },
304
+ "4": {
305
+ "0": -3.688547511940379,
306
+ "1": -2.0587007889253717,
307
+ "2": -3.370481889890517,
308
+ "3": 2.67729831167075,
309
+ },
310
+ "5": {
311
+ "0": -2.6457134524861243,
312
+ "1": 8.41568336157475,
313
+ "2": 5.457479617210075,
314
+ "3": 0.5541345662624297,
315
+ "4": -2.952959651402653,
316
+ },
317
+ "6": {
318
+ "0": 6.483305186430136,
319
+ "1": -2.5309543937239427,
320
+ "2": -2.4954945953746566,
321
+ "3": -2.812183970273315,
322
+ "4": -2.998588381716906,
323
+ "5": -2.2723718581884205,
324
+ },
325
+ "7": {
326
+ "0": -2.9154581227140457,
327
+ "1": 9.352887851205328,
328
+ "2": 9.844018411095597,
329
+ "3": 1.8138255060465474,
330
+ "4": -3.3396902374034765,
331
+ "5": 10.035481487601054,
332
+ "6": -3.0660799723685312,
333
+ },
334
+ },
335
+ cleanedContext: "",
336
+ isResolved: true,
337
+ },
338
+ ],
339
+ [
340
+ `My mother's name is Sasha, she likes dogs.`,
341
+ {
342
+ cleanedText: "My mother's name is Sasha, she likes dogs.",
343
+ corefResText: "My mother's name is Sasha, my mother likes dogs.",
344
+ coreferences: [
345
+ {
346
+ resolved: "My mother",
347
+ original: "she",
348
+ },
349
+ ],
350
+ mentions: [
351
+ {
352
+ index: 0,
353
+ type: "PRONOMINAL",
354
+ end: 2,
355
+ start: 0,
356
+ startToken: 0,
357
+ text: "My",
358
+ utterance: 0,
359
+ endToken: 1,
360
+ },
361
+ {
362
+ index: 1,
363
+ type: "NOMINAL",
364
+ end: 9,
365
+ start: 0,
366
+ startToken: 0,
367
+ text: "My mother",
368
+ utterance: 0,
369
+ endToken: 2,
370
+ },
371
+ {
372
+ index: 2,
373
+ type: "NOMINAL",
374
+ end: 16,
375
+ start: 0,
376
+ startToken: 0,
377
+ text: "My mother's name",
378
+ utterance: 0,
379
+ endToken: 4,
380
+ },
381
+ {
382
+ index: 3,
383
+ type: "PROPER",
384
+ end: 25,
385
+ start: 20,
386
+ startToken: 5,
387
+ text: "Sasha",
388
+ utterance: 0,
389
+ endToken: 6,
390
+ },
391
+ {
392
+ index: 4,
393
+ type: "PRONOMINAL",
394
+ end: 30,
395
+ start: 27,
396
+ startToken: 7,
397
+ text: "she",
398
+ utterance: 0,
399
+ endToken: 8,
400
+ },
401
+ {
402
+ index: 5,
403
+ type: "NOMINAL",
404
+ end: 41,
405
+ start: 37,
406
+ startToken: 9,
407
+ text: "dogs",
408
+ utterance: 0,
409
+ endToken: 10,
410
+ },
411
+ ],
412
+ singleScores: {
413
+ "0": null,
414
+ "1": 1.9246201814037063,
415
+ "2": 1.3833144431588633,
416
+ "3": 1.8293318485967687,
417
+ "4": 0.11171655922904344,
418
+ "5": 1.8179855402495786,
419
+ },
420
+ pairScores: {
421
+ "0": {},
422
+ "1": {
423
+ "0": -2.021441708531068,
424
+ },
425
+ "2": {
426
+ "0": -2.4538823419832134,
427
+ "1": -1.5272053058795838,
428
+ },
429
+ "3": {
430
+ "0": -2.2864554131219212,
431
+ "1": -1.5158990748985923,
432
+ "2": -1.5676019384720228,
433
+ },
434
+ "4": {
435
+ "0": -1.077294938181586,
436
+ "1": 5.190687831349847,
437
+ "2": 1.3862198517098907,
438
+ "3": 1.5871185522743856,
439
+ },
440
+ "5": {
441
+ "0": -2.957565366582327,
442
+ "1": -1.572206989880445,
443
+ "2": -1.5136893865248766,
444
+ "3": -2.295173505354227,
445
+ "4": -2.2454728131610056,
446
+ },
447
+ },
448
+ cleanedContext: "",
449
+ isResolved: true,
450
+ },
451
+ ],
452
+ ]);
453
+ class Coref {
454
+ constructor(endpoint, opts) {
455
+ this.onStart = () => { };
456
+ this.onSuccess = () => { };
457
  this.endpoint = endpoint;
458
  if (opts.onStart) {
459
  this.onStart = opts.onStart;
 
463
  }
464
  window.addEventListener('resize', this.svgResize);
465
  }
466
+ svgResize() {
467
  if (!this.container || !this.svgContainer) {
468
  return;
469
  }
470
+ this.svgContainer.setAttribute('width', `${this.container.scrollWidth}`);
471
+ this.svgContainer.setAttribute('height', `${this.container.scrollHeight}`);
472
+ }
473
+ parse(text) {
 
474
  this.onStart();
475
+ if (COREF_HARDCODED_OUTPUTS.size) {
476
+ const output = COREF_HARDCODED_OUTPUTS.get(text) ?? [...COREF_HARDCODED_OUTPUTS.values()][0];
477
+ setTimeout(() => {
478
+ this.onSuccess();
479
+ this.render(output);
480
+ }, 300);
481
+ return;
482
+ }
483
+ const path = `${this.endpoint}?text=${encodeURIComponent(text)}`;
484
+ const request = new XMLHttpRequest();
485
  request.open('GET', path);
486
+ request.onload = () => {
487
  if (request.status >= 200 && request.status < 400) {
488
+ this.onSuccess();
489
+ const res = JSON.parse(request.responseText);
490
+ this.render(res);
491
  }
492
  else {
493
  console.error('Error', request);
494
  }
495
  };
496
  request.send();
497
+ }
498
+ render(res) {
499
+ const mentions = res.mentions;
500
+ for (const m of mentions) {
 
 
501
  m.singleScore = res.singleScores[m.index] || undefined;
502
  }
503
+ const markup = Displacy.render(res.cleanedText, mentions);
504
  if (!this.container || !this.svgContainer) {
505
  return;
506
  }
507
+ this.container.innerHTML = `<div class="text">${markup}</div>`;
508
  this.svgContainer.textContent = "";
509
  this.svgResize();
510
  window.container = this.container;
511
  window.svgContainer = this.svgContainer;
512
+ const endY = document.querySelector('.container .text').getBoundingClientRect().top
513
  - this.container.getBoundingClientRect().top
514
  - 2;
515
  SvgArrow.yArrows = endY;
516
+ for (const [__from, scores] of Object.entries(res.pairScores)) {
517
+ const from = parseInt(__from, 10);
518
+ for (const [__to, score] of Object.entries(scores)) {
519
+ const to = parseInt(__to, 10);
520
+ const markFrom = document.querySelector(`mark[data-index="${from}"]`);
521
+ const markTo = document.querySelector(`mark[data-index="${to}"]`);
522
+ const arrow = new SvgArrow(this.container, markFrom, markTo, score);
523
+ if (score >= Math.max(...Object.values(scores))) {
 
 
524
  arrow.classNames.push('score-ok');
525
+ const singleScore = res.singleScores[from];
526
  if (singleScore && score >= singleScore) {
527
  arrow.classNames.push('score-best');
528
  }
 
530
  this.svgContainer.appendChild(arrow.generate());
531
  }
532
  }
533
+ document.querySelectorAll('.displacy-arrow.score-ok').forEach((arw) => {
534
+ this.svgContainer.appendChild(arw);
535
  });
 
 
 
 
 
536
  }
537
+ }
538
+ class Displacy {
539
+ static sortSpans(spans) {
540
+ spans.sort((a, b) => {
541
  if (a.start === b.start) {
542
  return b.end - a.end;
543
  }
544
  return a.start - b.start;
545
  });
546
+ spans.forEach((s, i) => {
547
  if (i < spans.length - 1) {
548
+ const sNext = spans[i + 1];
549
  if (s.start < sNext.start && s.end > sNext.start) {
550
  console.log("ERROR", "Spans: strict overlapping");
551
  }
552
  }
553
  });
554
+ }
555
+ static render(text, spans) {
556
  this.sortSpans(spans);
557
+ const tags = {};
558
+ const __addTag = (i, s, tag) => {
559
  if (Array.isArray(tags[i])) {
560
  tags[i].push({ span: s, tag: tag });
561
  }
 
563
  tags[i] = [{ span: s, tag: tag }];
564
  }
565
  };
566
+ for (const s of spans) {
 
567
  __addTag(s.start, s, "start");
568
  __addTag(s.end, s, "end");
569
  }
570
+ let out = {
571
  __content: "",
572
+ append(s) {
573
  this.__content += s;
574
  }
575
  };
576
+ let offset = 0;
577
+ const indexes = Object.keys(tags).map(k => parseInt(k, 10)).sort((a, b) => a - b);
578
+ for (const i of indexes) {
579
+ const spanTags = tags[i];
 
580
  if (i > offset) {
581
  out.append(text.slice(offset, i));
582
  }
583
  offset = i;
584
+ for (const sT of spanTags) {
 
585
  if (sT.tag === "start") {
586
+ out.append(`<mark data-entity="${sT.span.type.toLowerCase()}" data-index="${sT.span.index}">`);
587
+ const singleScore = sT.span.singleScore;
588
  if (singleScore) {
589
+ out.append(`<span class="single-score">${singleScore.toFixed(3)}</span>`);
590
  }
591
  }
592
  else {
593
+ out.append(`</mark>`);
594
  }
595
  }
596
  }
597
  out.append(text.slice(offset, text.length));
598
  return out.__content;
599
+ }
600
+ }
601
+ class SvgArrow {
602
+ constructor(container, markFrom, markTo, score) {
 
603
  this.classNames = [];
604
  this.container = container;
605
  this.markFrom = markFrom;
606
  this.markTo = markTo;
607
  this.score = score;
608
  }
609
+ _el(tag, options) {
610
+ const { classnames = [], attributes = [], style = [], children = [], text, id, xlink } = options;
611
+ const ns = 'http://www.w3.org/2000/svg';
612
+ const nsx = 'http://www.w3.org/1999/xlink';
613
+ const el = document.createElementNS(ns, tag);
614
+ classnames.forEach(name => el.classList.add(name));
615
+ attributes.forEach(([attr, value]) => el.setAttribute(attr, value));
616
+ style.forEach(([prop, value]) => el.style[prop] = value);
 
 
 
 
 
 
617
  if (xlink)
618
  el.setAttributeNS(nsx, 'xlink:href', xlink);
619
  if (text)
620
  el.appendChild(document.createTextNode(text));
621
  if (id)
622
  el.id = id;
623
+ children.forEach(child => el.appendChild(child));
624
  return el;
625
+ }
626
+ generate() {
627
+ const rand = Math.random().toString(36).substr(2, 8);
628
+ const startX = this.markTo.getBoundingClientRect().left
629
  - this.container.getBoundingClientRect().left
630
  + this.markTo.getBoundingClientRect().width / 2;
631
+ const endX = this.markFrom.getBoundingClientRect().left
632
  - this.container.getBoundingClientRect().left
633
  + this.markFrom.getBoundingClientRect().width / 2;
634
+ const curveY = Math.max(-50, SvgArrow.yArrows - (endX - startX) / 3.2);
635
  return this._el('g', {
636
  classnames: ['displacy-arrow'].concat(this.classNames),
637
  children: [
638
  this._el('path', {
639
+ id: `arrow-${rand}`,
640
  classnames: ['displacy-arc'],
641
  attributes: [
642
+ ['d', `M${startX},${SvgArrow.yArrows} C${startX},${curveY} ${endX},${curveY} ${endX},${SvgArrow.yArrows}`],
643
  ['stroke-width', '2px'],
644
  ['fill', 'none'],
645
  ['stroke', 'currentColor'],
 
651
  ],
652
  children: [
653
  this._el('textPath', {
654
+ xlink: `#arrow-${rand}`,
655
  classnames: ['displacy-label'],
656
  attributes: [
657
  ['startOffset', '50%'],
 
664
  }),
665
  ]
666
  });
667
+ }
668
+ }
669
+ SvgArrow.yArrows = 0;
670
+ const ENDPOINT = "https://coref.huggingface.co/coref";
671
+ const DEFAULT_NLP_TEXT = () => {
672
+ const items = [
673
+ `I love my father and my mother. They work hard. She is always nice but he is sometimes rude.`,
674
+ `My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.`,
675
+ `My mother's name is Sasha, she likes dogs.`
 
676
  ];
677
  return items[Math.floor(Math.random() * items.length)];
678
  };
679
+ const loading = () => {
680
  document.body.classList.toggle('loading');
681
  };
682
+ const toggleDebug = () => {
683
  document.body.classList.toggle('debug');
684
+ const icons = document.querySelectorAll('.svg-checkbox');
685
+ icons.forEach((icon) => {
686
  icon.classList.toggle('hide');
687
  });
688
  window.localStorage.setItem('debug', document.body.classList.contains('debug').toString());
689
  };
690
+ const coref = new Coref(ENDPOINT, {
691
  onStart: loading,
692
  onSuccess: loading,
693
  });
694
+ const getQueryVar = (key) => {
695
+ const query = window.location.search.substring(1);
696
+ const params = query.split('&').map(param => param.split('='));
697
+ for (const param of params) {
 
698
  if (param[0] === key) {
699
  return decodeURIComponent(param[1]);
700
  }
701
  }
702
  return undefined;
703
  };
704
+ const updateURL = (text) => {
705
+ history.pushState({ text: text }, "", `?text=${encodeURIComponent(text)}`);
706
  };
707
+ document.addEventListener('DOMContentLoaded', () => {
708
+ const $input = document.querySelector('input.input-message');
709
+ const $form = document.querySelector('form.js-form');
710
+ const $checkbox = document.querySelector('.js-checkbox');
711
+ const $svgContainer = document.querySelector('.svg-container');
712
  coref.container = document.querySelector('.container');
713
  coref.svgContainer = $svgContainer;
714
  {
715
+ const queryText = getQueryVar('text');
716
  if (queryText) {
717
  $input.value = queryText;
718
  coref.parse(queryText);
 
721
  coref.parse(DEFAULT_NLP_TEXT());
722
  }
723
  }
724
+ $input.addEventListener('keydown', (evt) => {
725
  if (evt.charCode === 13) {
726
  evt.preventDefault();
727
  $form.submit();
728
  }
729
  });
730
+ $form.addEventListener('submit', (evt) => {
731
  evt.preventDefault();
732
+ const text = ($input.value.length > 0)
733
  ? $input.value
734
  : DEFAULT_NLP_TEXT();
735
  updateURL(text);
736
  coref.parse(text);
737
  });
738
+ $checkbox.addEventListener('click', () => {
739
  toggleDebug();
740
  });
741
  if (window.localStorage.getItem('debug') !== 'false') {
742
  toggleDebug();
743
  }
744
+ });
js-src/Coref.ts CHANGED
@@ -4,6 +4,8 @@ declare interface Mention {
4
  index: number;
5
  start: number;
6
  end: number;
 
 
7
  utterance: number;
8
  type: MentionType;
9
  text: string;
@@ -70,7 +72,7 @@ declare interface PairFeatures {
70
  mentionWordsEmbeddings: WordsEmbeddings;
71
  }
72
 
73
- declare interface Response {
74
  cleanedText: string;
75
  corefResText: string;
76
  coreferences: Coreference[];
@@ -80,11 +82,470 @@ declare interface Response {
80
  /// Single scores are to be compared to the set of pairScores (for the same mention).
81
  /// If it's higher than every pair score, it's a single mention.
82
  cleanedContext: string; /// Cleaned version of the context.
83
- singleFeatures: { [id: number]: SingleFeatures | null };
84
- pairFeatures: { [id: number]: { [id: number]: PairFeatures } };
85
  isResolved: boolean;
86
  }
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  class Coref {
89
  endpoint: string;
90
  onStart = () => {};
@@ -92,13 +553,13 @@ class Coref {
92
  container?: HTMLElement;
93
  svgContainer?: SVGSVGElement;
94
 
95
- constructor(endpoint: string, opts: any) {
96
  this.endpoint = endpoint;
97
  if (opts.onStart) {
98
- (<any>this).onStart = opts.onStart;
99
  }
100
  if (opts.onSuccess) {
101
- (<any>this).onSuccess = opts.onSuccess;
102
  }
103
 
104
  window.addEventListener('resize', this.svgResize);
@@ -113,13 +574,22 @@ class Coref {
113
  parse(text: string) {
114
  this.onStart();
115
 
 
 
 
 
 
 
 
 
 
116
  const path = `${this.endpoint}?text=${encodeURIComponent(text)}`;
117
  const request = new XMLHttpRequest();
118
  request.open('GET', path);
119
  request.onload = () => {
120
  if (request.status >= 200 && request.status < 400) {
121
  this.onSuccess();
122
- const res: Response = JSON.parse(request.responseText);
123
  this.render(res);
124
  }
125
  else {
@@ -129,7 +599,7 @@ class Coref {
129
  request.send();
130
  }
131
 
132
- render(res: Response) {
133
  const mentions = (<any>res).mentions; // We will sort them in Displacy
134
  for (const m of mentions) {
135
  // Let's add each mention's singleScore
 
4
  index: number;
5
  start: number;
6
  end: number;
7
+ startToken: number;
8
+ endToken: number;
9
  utterance: number;
10
  type: MentionType;
11
  text: string;
 
72
  mentionWordsEmbeddings: WordsEmbeddings;
73
  }
74
 
75
+ declare interface CorefResponse {
76
  cleanedText: string;
77
  corefResText: string;
78
  coreferences: Coreference[];
 
82
  /// Single scores are to be compared to the set of pairScores (for the same mention).
83
  /// If it's higher than every pair score, it's a single mention.
84
  cleanedContext: string; /// Cleaned version of the context.
85
+ // singleFeatures: { [id: number]: SingleFeatures | null };
86
+ // pairFeatures: { [id: number]: { [id: number]: PairFeatures } };
87
  isResolved: boolean;
88
  }
89
 
90
+
91
+ const COREF_HARDCODED_OUTPUTS = new Map<string, CorefResponse>([
92
+ [
93
+ `I love my father and my mother. They work hard. She is always nice but he is sometimes rude.`,
94
+ {
95
+ cleanedText:
96
+ "I love my father and my mother. They work hard. She is always nice but he is sometimes rude.",
97
+ corefResText:
98
+ "I love my father and my mother. They work hard. my mother is always nice but he is sometimes rude.",
99
+ coreferences: [
100
+ {
101
+ resolved: "my mother",
102
+ original: "She",
103
+ },
104
+ ],
105
+ mentions: [
106
+ {
107
+ index: 0,
108
+ type: "PRONOMINAL",
109
+ end: 1,
110
+ start: 0,
111
+ startToken: 0,
112
+ text: "I",
113
+ utterance: 0,
114
+ endToken: 1,
115
+ },
116
+ {
117
+ index: 1,
118
+ type: "PRONOMINAL",
119
+ end: 9,
120
+ start: 7,
121
+ startToken: 2,
122
+ text: "my",
123
+ utterance: 0,
124
+ endToken: 3,
125
+ },
126
+ {
127
+ index: 2,
128
+ type: "LIST",
129
+ end: 30,
130
+ start: 7,
131
+ startToken: 2,
132
+ text: "my father and my mother",
133
+ utterance: 0,
134
+ endToken: 7,
135
+ },
136
+ {
137
+ index: 3,
138
+ type: "NOMINAL",
139
+ end: 16,
140
+ start: 7,
141
+ startToken: 2,
142
+ text: "my father",
143
+ utterance: 0,
144
+ endToken: 4,
145
+ },
146
+ {
147
+ index: 4,
148
+ type: "PRONOMINAL",
149
+ end: 23,
150
+ start: 21,
151
+ startToken: 5,
152
+ text: "my",
153
+ utterance: 0,
154
+ endToken: 6,
155
+ },
156
+ {
157
+ index: 5,
158
+ type: "NOMINAL",
159
+ end: 30,
160
+ start: 21,
161
+ startToken: 5,
162
+ text: "my mother",
163
+ utterance: 0,
164
+ endToken: 7,
165
+ },
166
+ {
167
+ index: 6,
168
+ type: "PRONOMINAL",
169
+ end: 36,
170
+ start: 32,
171
+ startToken: 8,
172
+ text: "They",
173
+ utterance: 0,
174
+ endToken: 9,
175
+ },
176
+ {
177
+ index: 7,
178
+ type: "PRONOMINAL",
179
+ end: 51,
180
+ start: 48,
181
+ startToken: 12,
182
+ text: "She",
183
+ utterance: 0,
184
+ endToken: 13,
185
+ },
186
+ {
187
+ index: 8,
188
+ type: "PRONOMINAL",
189
+ end: 73,
190
+ start: 71,
191
+ startToken: 17,
192
+ text: "he",
193
+ utterance: 0,
194
+ endToken: 18,
195
+ },
196
+ ],
197
+ singleScores: {
198
+ "0": null,
199
+ "1": -0.5316791573216993,
200
+ "2": 1.5312658152183065,
201
+ "3": 1.555544240226482,
202
+ "4": -1.3024868053674725,
203
+ "5": 1.8934082334098847,
204
+ "6": -0.9070692483062055,
205
+ "7": 0.052800267274213275,
206
+ "8": -0.14679673122527748,
207
+ },
208
+ pairScores: {
209
+ "0": {},
210
+ "1": {
211
+ "0": 15.268471128411697,
212
+ },
213
+ "2": {
214
+ "0": -4.4230603182609896,
215
+ "1": -3.382446088190441,
216
+ },
217
+ "3": {
218
+ "0": -4.2304546215104555,
219
+ "1": -3.5681677896088786,
220
+ "2": -1.9470202037608262,
221
+ },
222
+ "4": {
223
+ "0": 11.654522570777317,
224
+ "1": 13.455601870537567,
225
+ "2": -3.218918301345336,
226
+ "3": -3.882381584104524,
227
+ },
228
+ "5": {
229
+ "0": -3.9280501278811983,
230
+ "1": -4.426880262361277,
231
+ "2": -1.7714693884323367,
232
+ "3": -2.722532370602323,
233
+ "4": -3.290164176455163,
234
+ },
235
+ "6": {
236
+ "0": -4.492101447800931,
237
+ "1": -4.636904674331316,
238
+ "2": 3.1158072056943666,
239
+ "3": -2.7375757747875573,
240
+ "4": -4.689981185699828,
241
+ "5": -2.6728186848475537,
242
+ },
243
+ "7": {
244
+ "0": -3.197215354228037,
245
+ "1": -3.538538702704479,
246
+ "2": -0.02408947507481729,
247
+ "3": 0.3052410603657605,
248
+ "4": -3.519641485034609,
249
+ "5": 1.8101046215415115,
250
+ "6": -3.1353342036917917,
251
+ },
252
+ "8": {
253
+ "0": -0.08532621450323319,
254
+ "1": 5.371002989344198,
255
+ "2": -1.4091179987286686,
256
+ "3": 3.152921411948177,
257
+ "4": 2.268706305216419,
258
+ "5": -2.340743897439996,
259
+ "6": -2.8835496283480597,
260
+ "7": -3.4832126005315334,
261
+ },
262
+ },
263
+ cleanedContext: "",
264
+ isResolved: true,
265
+ },
266
+ ],
267
+ [
268
+ `My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.`,
269
+ {
270
+ cleanedText:
271
+ "My sister is swimming with her classmates. They are not bad, but she is better. I love watching her swim.",
272
+ corefResText:
273
+ "My sister is swimming with my sister classmates. her classmates are not bad, but my sister is better. I love watching my sister swim.",
274
+ coreferences: [
275
+ {
276
+ resolved: "My sister",
277
+ original: "she",
278
+ },
279
+ {
280
+ resolved: "My sister",
281
+ original: "her",
282
+ },
283
+ {
284
+ resolved: "her classmates",
285
+ original: "They",
286
+ },
287
+ {
288
+ resolved: "My sister",
289
+ original: "her",
290
+ },
291
+ ],
292
+ mentions: [
293
+ {
294
+ index: 0,
295
+ type: "PRONOMINAL",
296
+ end: 2,
297
+ start: 0,
298
+ startToken: 0,
299
+ text: "My",
300
+ utterance: 0,
301
+ endToken: 1,
302
+ },
303
+ {
304
+ index: 1,
305
+ type: "NOMINAL",
306
+ end: 9,
307
+ start: 0,
308
+ startToken: 0,
309
+ text: "My sister",
310
+ utterance: 0,
311
+ endToken: 2,
312
+ },
313
+ {
314
+ index: 2,
315
+ type: "PRONOMINAL",
316
+ end: 30,
317
+ start: 27,
318
+ startToken: 5,
319
+ text: "her",
320
+ utterance: 0,
321
+ endToken: 6,
322
+ },
323
+ {
324
+ index: 3,
325
+ type: "NOMINAL",
326
+ end: 41,
327
+ start: 27,
328
+ startToken: 5,
329
+ text: "her classmates",
330
+ utterance: 0,
331
+ endToken: 7,
332
+ },
333
+ {
334
+ index: 4,
335
+ type: "PRONOMINAL",
336
+ end: 47,
337
+ start: 43,
338
+ startToken: 8,
339
+ text: "They",
340
+ utterance: 0,
341
+ endToken: 9,
342
+ },
343
+ {
344
+ index: 5,
345
+ type: "PRONOMINAL",
346
+ end: 68,
347
+ start: 65,
348
+ startToken: 14,
349
+ text: "she",
350
+ utterance: 0,
351
+ endToken: 15,
352
+ },
353
+ {
354
+ index: 6,
355
+ type: "PRONOMINAL",
356
+ end: 81,
357
+ start: 80,
358
+ startToken: 18,
359
+ text: "I",
360
+ utterance: 0,
361
+ endToken: 19,
362
+ },
363
+ {
364
+ index: 7,
365
+ type: "PRONOMINAL",
366
+ end: 99,
367
+ start: 96,
368
+ startToken: 21,
369
+ text: "her",
370
+ utterance: 0,
371
+ endToken: 22,
372
+ },
373
+ ],
374
+ singleScores: {
375
+ "0": null,
376
+ "1": 1.609437735243254,
377
+ "2": -1.1017402175324822,
378
+ "3": 1.4347901008486401,
379
+ "4": -0.02895837171142801,
380
+ "5": -0.4266623545401909,
381
+ "6": 0.009921976322164627,
382
+ "7": -1.8629830475049451,
383
+ },
384
+ pairScores: {
385
+ "0": {},
386
+ "1": {
387
+ "0": -2.2413815226574703,
388
+ },
389
+ "2": {
390
+ "0": -2.409825572927252,
391
+ "1": 5.707592445811339,
392
+ },
393
+ "3": {
394
+ "0": -3.0653216162902854,
395
+ "1": -1.6904548462117184,
396
+ "2": -1.8322836987315447,
397
+ },
398
+ "4": {
399
+ "0": -3.688547511940379,
400
+ "1": -2.0587007889253717,
401
+ "2": -3.370481889890517,
402
+ "3": 2.67729831167075,
403
+ },
404
+ "5": {
405
+ "0": -2.6457134524861243,
406
+ "1": 8.41568336157475,
407
+ "2": 5.457479617210075,
408
+ "3": 0.5541345662624297,
409
+ "4": -2.952959651402653,
410
+ },
411
+ "6": {
412
+ "0": 6.483305186430136,
413
+ "1": -2.5309543937239427,
414
+ "2": -2.4954945953746566,
415
+ "3": -2.812183970273315,
416
+ "4": -2.998588381716906,
417
+ "5": -2.2723718581884205,
418
+ },
419
+ "7": {
420
+ "0": -2.9154581227140457,
421
+ "1": 9.352887851205328,
422
+ "2": 9.844018411095597,
423
+ "3": 1.8138255060465474,
424
+ "4": -3.3396902374034765,
425
+ "5": 10.035481487601054,
426
+ "6": -3.0660799723685312,
427
+ },
428
+ },
429
+ cleanedContext: "",
430
+ isResolved: true,
431
+ },
432
+ ],
433
+ [
434
+ `My mother's name is Sasha, she likes dogs.`,
435
+ {
436
+ cleanedText: "My mother's name is Sasha, she likes dogs.",
437
+ corefResText: "My mother's name is Sasha, my mother likes dogs.",
438
+ coreferences: [
439
+ {
440
+ resolved: "My mother",
441
+ original: "she",
442
+ },
443
+ ],
444
+ mentions: [
445
+ {
446
+ index: 0,
447
+ type: "PRONOMINAL",
448
+ end: 2,
449
+ start: 0,
450
+ startToken: 0,
451
+ text: "My",
452
+ utterance: 0,
453
+ endToken: 1,
454
+ },
455
+ {
456
+ index: 1,
457
+ type: "NOMINAL",
458
+ end: 9,
459
+ start: 0,
460
+ startToken: 0,
461
+ text: "My mother",
462
+ utterance: 0,
463
+ endToken: 2,
464
+ },
465
+ {
466
+ index: 2,
467
+ type: "NOMINAL",
468
+ end: 16,
469
+ start: 0,
470
+ startToken: 0,
471
+ text: "My mother's name",
472
+ utterance: 0,
473
+ endToken: 4,
474
+ },
475
+ {
476
+ index: 3,
477
+ type: "PROPER",
478
+ end: 25,
479
+ start: 20,
480
+ startToken: 5,
481
+ text: "Sasha",
482
+ utterance: 0,
483
+ endToken: 6,
484
+ },
485
+ {
486
+ index: 4,
487
+ type: "PRONOMINAL",
488
+ end: 30,
489
+ start: 27,
490
+ startToken: 7,
491
+ text: "she",
492
+ utterance: 0,
493
+ endToken: 8,
494
+ },
495
+ {
496
+ index: 5,
497
+ type: "NOMINAL",
498
+ end: 41,
499
+ start: 37,
500
+ startToken: 9,
501
+ text: "dogs",
502
+ utterance: 0,
503
+ endToken: 10,
504
+ },
505
+ ],
506
+ singleScores: {
507
+ "0": null,
508
+ "1": 1.9246201814037063,
509
+ "2": 1.3833144431588633,
510
+ "3": 1.8293318485967687,
511
+ "4": 0.11171655922904344,
512
+ "5": 1.8179855402495786,
513
+ },
514
+ pairScores: {
515
+ "0": {},
516
+ "1": {
517
+ "0": -2.021441708531068,
518
+ },
519
+ "2": {
520
+ "0": -2.4538823419832134,
521
+ "1": -1.5272053058795838,
522
+ },
523
+ "3": {
524
+ "0": -2.2864554131219212,
525
+ "1": -1.5158990748985923,
526
+ "2": -1.5676019384720228,
527
+ },
528
+ "4": {
529
+ "0": -1.077294938181586,
530
+ "1": 5.190687831349847,
531
+ "2": 1.3862198517098907,
532
+ "3": 1.5871185522743856,
533
+ },
534
+ "5": {
535
+ "0": -2.957565366582327,
536
+ "1": -1.572206989880445,
537
+ "2": -1.5136893865248766,
538
+ "3": -2.295173505354227,
539
+ "4": -2.2454728131610056,
540
+ },
541
+ },
542
+ cleanedContext: "",
543
+ isResolved: true,
544
+ },
545
+ ],
546
+ ]);
547
+
548
+
549
  class Coref {
550
  endpoint: string;
551
  onStart = () => {};
 
553
  container?: HTMLElement;
554
  svgContainer?: SVGSVGElement;
555
 
556
+ constructor(endpoint: string, opts: { onStart?: () => void, onSuccess?: () => void }) {
557
  this.endpoint = endpoint;
558
  if (opts.onStart) {
559
+ this.onStart = opts.onStart;
560
  }
561
  if (opts.onSuccess) {
562
+ this.onSuccess = opts.onSuccess;
563
  }
564
 
565
  window.addEventListener('resize', this.svgResize);
 
574
  parse(text: string) {
575
  this.onStart();
576
 
577
+ if (COREF_HARDCODED_OUTPUTS.size) {
578
+ const output = COREF_HARDCODED_OUTPUTS.get(text) ?? [...COREF_HARDCODED_OUTPUTS.values()][0];
579
+ setTimeout(() => {
580
+ this.onSuccess();
581
+ this.render(output);
582
+ }, 300);
583
+ return ;
584
+ }
585
+
586
  const path = `${this.endpoint}?text=${encodeURIComponent(text)}`;
587
  const request = new XMLHttpRequest();
588
  request.open('GET', path);
589
  request.onload = () => {
590
  if (request.status >= 200 && request.status < 400) {
591
  this.onSuccess();
592
+ const res: CorefResponse = JSON.parse(request.responseText);
593
  this.render(res);
594
  }
595
  else {
 
599
  request.send();
600
  }
601
 
602
+ render(res: CorefResponse) {
603
  const mentions = (<any>res).mentions; // We will sort them in Displacy
604
  for (const m of mentions) {
605
  // Let's add each mention's singleScore
tsconfig.json CHANGED
@@ -1,6 +1,6 @@
1
  {
2
  "compilerOptions": {
3
- "target": "es5",
4
  "outFile": "dist/script.js",
5
  "sourceMap": false,
6
  "strictNullChecks": true,
 
1
  {
2
  "compilerOptions": {
3
+ "target": "ES2020",
4
  "outFile": "dist/script.js",
5
  "sourceMap": false,
6
  "strictNullChecks": true,