cifkao commited on
Commit
8443315
1 Parent(s): 7f8c345

Add app files

Browse files
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ node_modules
app.py ADDED
@@ -0,0 +1,79 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pathlib import Path
2
+
3
+ import streamlit as st
4
+ import streamlit.components.v1 as components
5
+ import torch
6
+ import torch.nn.functional as F
7
+ from transformers import AutoModelForCausalLM, AutoTokenizer, BatchEncoding
8
+
9
+ root_dir = Path(__file__).resolve().parent
10
+ _highlighted_text_fn = components.declare_component(
11
+ "highlighted_text", path=root_dir / "highlighted_text" / "build"
12
+ )
13
+
14
+ def highlighted_text(tokens, scores, key=None):
15
+ return _highlighted_text_fn(tokens=tokens, scores=scores, key=key, default=0)
16
+
17
+ def get_windows_batched(examples: BatchEncoding, window_len: int, stride: int = 1, pad_id: int = 0) -> BatchEncoding:
18
+ return BatchEncoding({
19
+ k: [
20
+ t[i][j : j + window_len] + [
21
+ pad_id if k == "input_ids" else 0
22
+ ] * (j + window_len - len(t[i]))
23
+ for i in range(len(examples["input_ids"]))
24
+ for j in range(0, len(examples["input_ids"][i]) - 1, stride)
25
+ ]
26
+ for k, t in examples.items()
27
+ })
28
+
29
+ BAD_CHAR = chr(0xfffd)
30
+
31
+ def ids_to_readable_tokens(tokenizer, ids, strip_whitespace=False):
32
+ cur_ids = []
33
+ result = []
34
+ for idx in ids:
35
+ cur_ids.append(idx)
36
+ decoded = tokenizer.decode(cur_ids)
37
+ if BAD_CHAR not in decoded:
38
+ if strip_whitespace:
39
+ decoded = decoded.strip()
40
+ result.append(decoded)
41
+ del cur_ids[:]
42
+ else:
43
+ result.append("")
44
+ return result
45
+
46
+ model_name = st.selectbox("Model", ["distilgpt2"])
47
+
48
+ tokenizer = AutoTokenizer.from_pretrained(model_name)
49
+ model = AutoModelForCausalLM.from_pretrained(model_name)
50
+
51
+ window_len = st.select_slider("Window size", options=[8, 16, 32, 64, 128, 256, 512, 1024], value=512)
52
+ text = st.text_area("Input text", "The complex houses married and single soldiers and their families.")
53
+
54
+ inputs = tokenizer([text])
55
+ [input_ids] = inputs["input_ids"]
56
+ window_len = min(window_len, len(input_ids))
57
+ tokens = ids_to_readable_tokens(tokenizer, input_ids)
58
+
59
+ inputs_sliding = get_windows_batched(
60
+ inputs,
61
+ window_len=window_len,
62
+ pad_id=tokenizer.eos_token_id
63
+ )
64
+ with torch.inference_mode():
65
+ logits = model(**inputs_sliding.convert_to_tensors("pt")).logits.to(torch.float16)
66
+ logits = F.pad(logits, (0, 0, 0, window_len - 1, 0, 0), value=torch.nan)
67
+ logits = logits.view(-1, logits.shape[-1])[:(window_len - 1) * (len(input_ids) + window_len - 2)]
68
+ logits = logits.view(window_len - 1, len(input_ids) + window_len - 2, logits.shape[-1])
69
+
70
+ scores = logits.to(torch.float32).softmax(dim=-1)
71
+ scores = scores[:, torch.arange(len(input_ids[1:])), input_ids[1:]]
72
+ scores = scores.diff(dim=0).transpose(0, 1)
73
+ scores = scores.nan_to_num()
74
+ scores /= scores.abs().max(dim=1, keepdim=True).values + 1e-9
75
+ scores = scores.to(torch.float16)
76
+ print(scores)
77
+ st.markdown("---")
78
+ highlighted_text(tokens=tokens, scores=scores.tolist())
79
+
highlighted_text/.env ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # Run the component's dev server on :3001
2
+ # (The Streamlit dev server already runs on :3000)
3
+ PORT=3001
4
+
5
+ # Don't automatically open the web browser on `npm run start`.
6
+ BROWSER=none
highlighted_text/.prettierrc ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ {
2
+ "endOfLine": "lf",
3
+ "semi": false,
4
+ "trailingComma": "es5"
5
+ }
highlighted_text/build/asset-manifest.json ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "files": {
3
+ "main.js": "./static/js/main.243f5634.chunk.js",
4
+ "main.js.map": "./static/js/main.243f5634.chunk.js.map",
5
+ "runtime-main.js": "./static/js/runtime-main.e6b0ae4c.js",
6
+ "runtime-main.js.map": "./static/js/runtime-main.e6b0ae4c.js.map",
7
+ "static/js/2.ce130e37.chunk.js": "./static/js/2.ce130e37.chunk.js",
8
+ "static/js/2.ce130e37.chunk.js.map": "./static/js/2.ce130e37.chunk.js.map",
9
+ "index.html": "./index.html",
10
+ "static/js/2.ce130e37.chunk.js.LICENSE.txt": "./static/js/2.ce130e37.chunk.js.LICENSE.txt"
11
+ },
12
+ "entrypoints": [
13
+ "static/js/runtime-main.e6b0ae4c.js",
14
+ "static/js/2.ce130e37.chunk.js",
15
+ "static/js/main.243f5634.chunk.js"
16
+ ]
17
+ }
highlighted_text/build/index.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ padding: 0;
3
+ margin: 0;
4
+ font-family: "Source Sans Pro", sans-serif;
5
+ font-size: 1rem;
6
+ line-height: 1.4;
7
+ }
8
+
9
+ .status-bar {
10
+ display: none;
11
+ }
12
+
13
+ .highlighted-text {
14
+ border: 1px solid #d2d2d2;
15
+ border-radius: 5px 5px 5px 5px;
16
+ padding: 2px;
17
+ cursor: pointer;
18
+
19
+ .token.active {
20
+ outline: 1px solid #444;
21
+ }
22
+
23
+ &.frozen {
24
+ .token {
25
+ opacity: 0.75;
26
+
27
+ &.context, &.active {
28
+ opacity: 1;
29
+ }
30
+
31
+ &.context {
32
+ text-decoration: #999 underline;
33
+ }
34
+ }
35
+ }
36
+ }
highlighted_text/build/index.html ADDED
@@ -0,0 +1 @@
 
 
1
+ <!doctype html><html lang="en"><head><title>Highlighted text component</title><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#fff"/><meta name="description" content="Highlighted text"/><link rel="stylesheet" href="index.css"/></head><body><div id="root"></div><script>!function(e){function t(t){for(var n,l,a=t[0],p=t[1],i=t[2],c=0,s=[];c<a.length;c++)l=a[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in p)Object.prototype.hasOwnProperty.call(p,n)&&(e[n]=p[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var p=r[a];0!==o[p]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="./";var a=this.webpackJsonpstreamlit_component_template=this.webpackJsonpstreamlit_component_template||[],p=a.push.bind(a);a.push=t,a=a.slice();for(var i=0;i<a.length;i++)t(a[i]);var f=p;r()}([])</script><script src="./static/js/2.ce130e37.chunk.js"></script><script src="./static/js/main.243f5634.chunk.js"></script></body></html>
highlighted_text/build/static/js/2.ce130e37.chunk.js ADDED
The diff for this file is too large to render. See raw diff
 
highlighted_text/build/static/js/2.ce130e37.chunk.js.LICENSE.txt ADDED
@@ -0,0 +1,69 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*
2
+ object-assign
3
+ (c) Sindre Sorhus
4
+ @license MIT
5
+ */
6
+
7
+ /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
8
+
9
+ /**
10
+ * @license
11
+ * Copyright 2018-2021 Streamlit Inc.
12
+ *
13
+ * Licensed under the Apache License, Version 2.0 (the "License");
14
+ * you may not use this file except in compliance with the License.
15
+ * You may obtain a copy of the License at
16
+ *
17
+ * http://www.apache.org/licenses/LICENSE-2.0
18
+ *
19
+ * Unless required by applicable law or agreed to in writing, software
20
+ * distributed under the License is distributed on an "AS IS" BASIS,
21
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22
+ * See the License for the specific language governing permissions and
23
+ * limitations under the License.
24
+ */
25
+
26
+ /** @license React v0.19.1
27
+ * scheduler.production.min.js
28
+ *
29
+ * Copyright (c) Facebook, Inc. and its affiliates.
30
+ *
31
+ * This source code is licensed under the MIT license found in the
32
+ * LICENSE file in the root directory of this source tree.
33
+ */
34
+
35
+ /** @license React v16.13.1
36
+ * react-is.production.min.js
37
+ *
38
+ * Copyright (c) Facebook, Inc. and its affiliates.
39
+ *
40
+ * This source code is licensed under the MIT license found in the
41
+ * LICENSE file in the root directory of this source tree.
42
+ */
43
+
44
+ /** @license React v16.14.0
45
+ * react-dom.production.min.js
46
+ *
47
+ * Copyright (c) Facebook, Inc. and its affiliates.
48
+ *
49
+ * This source code is licensed under the MIT license found in the
50
+ * LICENSE file in the root directory of this source tree.
51
+ */
52
+
53
+ /** @license React v16.14.0
54
+ * react-jsx-runtime.production.min.js
55
+ *
56
+ * Copyright (c) Facebook, Inc. and its affiliates.
57
+ *
58
+ * This source code is licensed under the MIT license found in the
59
+ * LICENSE file in the root directory of this source tree.
60
+ */
61
+
62
+ /** @license React v16.14.0
63
+ * react.production.min.js
64
+ *
65
+ * Copyright (c) Facebook, Inc. and its affiliates.
66
+ *
67
+ * This source code is licensed under the MIT license found in the
68
+ * LICENSE file in the root directory of this source tree.
69
+ */
highlighted_text/build/static/js/2.ce130e37.chunk.js.map ADDED
The diff for this file is too large to render. See raw diff
 
highlighted_text/build/static/js/main.243f5634.chunk.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ (this.webpackJsonpstreamlit_component_template=this.webpackJsonpstreamlit_component_template||[]).push([[0],{27:function(t,e,a){"use strict";a.r(e);var n=a(7),s=a.n(n),r=a(18),c=a.n(r),i=a(4),o=a(0),l=a(1),h=a(2),j=a(3),u=a(16),v=a(6),b=function(t){Object(h.a)(a,t);var e=Object(j.a)(a);function a(){var t;Object(o.a)(this,a);for(var n=arguments.length,s=new Array(n),r=0;r<n;r++)s[r]=arguments[r];return(t=e.call.apply(e,[this].concat(s))).state={activeIndex:null,hoverIndex:null,isFrozen:!1},t}return Object(l.a)(a,[{key:"render",value:function(){var t=this,e=this.props.args.tokens,a=this.getScores();console.log(a);var n="highlighted-text";this.state.isFrozen&&(n+=" frozen");var s=function(){t.setState({isFrozen:!1})};return Object(v.jsxs)(v.Fragment,{children:[Object(v.jsxs)("div",{className:"status-bar",children:[Object(v.jsxs)("span",{className:this.state.isFrozen?"":" d-none",children:[Object(v.jsx)("i",{className:"fa fa-lock"})," "]},"lock-icon"),Object(v.jsx)("strong",{children:"target:"},"target-label"),null!=this.state.activeIndex?Object(v.jsx)("span",{className:"token",children:e[this.state.activeIndex]},"target"):Object(v.jsx)(v.Fragment,{})]},"status-bar"),Object(v.jsx)("div",{className:n,onClick:s,children:e.map((function(e,n){var r="token";t.state&&t.state.activeIndex==n&&(r+=" active");var c={backgroundColor:a[n]>0?"rgba(255, 32, 32, ".concat(a[n],")"):"rgba(32, 255, 32, ".concat(-a[n],")")};return Object(v.jsx)("span",{className:r,style:c,onMouseOver:function(){t.state.isFrozen||t.setState({activeIndex:n}),t.setState({hoverIndex:n})},onClick:s,children:e},n)}))},"text")]})}},{key:"getScores",value:function(){var t=this.props.args.tokens;if(!this.state||null==this.state.activeIndex||this.state.activeIndex<1)return t.map((function(){return 0}));var e=this.props.args.scores,a=this.state.activeIndex-1,n=Math.min(Math.max(0,a),e[a].length),s=e[a].slice(0,n);s.reverse();var r=[].concat(Object(i.a)(Array(Math.max(0,a-1-s.length)).fill(0)),Object(i.a)(s.map((function(t){return void 0==t||isNaN(t)?0:t}))));return r=[].concat(Object(i.a)(r),Object(i.a)(Array(t.length-r.length).fill(0)))}}]),a}(u.a),d=Object(u.b)(b);c.a.render(Object(v.jsx)(s.a.StrictMode,{children:Object(v.jsx)(d,{})}),document.getElementById("root"))}},[[27,1,2]]]);
2
+ //# sourceMappingURL=main.243f5634.chunk.js.map
highlighted_text/build/static/js/main.243f5634.chunk.js.map ADDED
@@ -0,0 +1 @@
 
 
1
+ {"version":3,"sources":["HighlightedText.tsx","index.tsx"],"names":["HighlightedText","_StreamlitComponentBa","_inherits","_super","_createSuper","_this","_classCallCheck","_len","arguments","length","args","Array","_key","call","apply","concat","state","activeIndex","hoverIndex","isFrozen","_createClass","key","value","_this2","tokens","this","props","scores","getScores","console","log","className","onClick","setState","_jsxs","_Fragment","children","_jsx","map","t","i","style","backgroundColor","onMouseOver","allScores","hi","Math","min","max","row","slice","reverse","result","_toConsumableArray","fill","x","undefined","isNaN","StreamlitComponentBase","withStreamlitConnection","ReactDOM","render","React","StrictMode","document","getElementById"],"mappings":"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","file":"static/js/main.243f5634.chunk.js","sourcesContent":["import {\n Streamlit,\n StreamlitComponentBase,\n withStreamlitConnection,\n} from \"streamlit-component-lib\";\nimport React, { ReactNode } from \"react\";\n\ntype HighlightedTextState = {\n activeIndex: number | null,\n hoverIndex: number | null,\n isFrozen: boolean\n};\n\n/**\n * This is a React-based component template. The `render()` function is called\n * automatically when your component should be re-rendered.\n */\nclass HighlightedText extends StreamlitComponentBase<HighlightedTextState> {\n public state = {activeIndex: null, hoverIndex: null, isFrozen: false};\n\n render() {\n const tokens: string[] = this.props.args[\"tokens\"];\n const scores: number[] = this.getScores();\n console.log(scores);\n\n let className = \"highlighted-text\";\n if (this.state.isFrozen) {\n className += \" frozen\";\n }\n\n const onClick = () => {\n this.setState({ isFrozen: false });\n };\n\n return <>\n <div className=\"status-bar\" key=\"status-bar\">\n <span className={this.state.isFrozen ? \"\" : \" d-none\"} key=\"lock-icon\"><i className=\"fa fa-lock\"></i> </span>\n <strong key=\"target-label\">target:</strong>\n {\n this.state.activeIndex != null\n ? <span className=\"token\" key=\"target\">{tokens[this.state.activeIndex]}</span>\n : <></>\n }\n </div>\n <div className={className} onClick={onClick} key=\"text\">\n {\n tokens.map((t: string, i: number) => {\n let className = \"token\";\n if (this.state) {\n if (this.state.activeIndex == i) {\n className += \" active\";\n }\n }\n const style = {\n backgroundColor:\n scores[i] > 0\n ? `rgba(255, 32, 32, ${scores[i]})`\n : `rgba(32, 255, 32, ${-scores[i]})`\n };\n\n const onMouseOver = () => {\n if (!this.state.isFrozen) {\n this.setState({ activeIndex: i });\n }\n this.setState({ hoverIndex: i });\n };\n return <span key={i} className={className} style={style}\n onMouseOver={onMouseOver} onClick={onClick}>{t}</span>;\n })\n }\n </div>\n </>;\n }\n\n private getScores() {\n const tokens = this.props.args[\"tokens\"];\n if (!this.state || this.state.activeIndex == null || this.state.activeIndex < 1) {\n return tokens.map(() => 0);\n }\n const allScores: number[][] = this.props.args[\"scores\"];\n\n const i = this.state.activeIndex - 1;\n const hi = Math.min(Math.max(0, i), allScores[i].length);\n const row = allScores[i].slice(0, hi);\n row.reverse();\n let result = [\n ...Array(Math.max(0, i - 1 - row.length)).fill(0), \n ...row.map((x) => x == undefined || isNaN(x) ? 0 : x)\n ];\n result = [...result, ...Array(tokens.length - result.length).fill(0)];\n return result;\n }\n}\n\nexport default withStreamlitConnection(HighlightedText);\n","import React from \"react\";\nimport ReactDOM from \"react-dom\";\nimport HighlightedText from \"./HighlightedText\";\n\nReactDOM.render(\n <React.StrictMode>\n <HighlightedText />\n </React.StrictMode>,\n document.getElementById(\"root\")\n)\n"],"sourceRoot":""}
highlighted_text/build/static/js/runtime-main.e6b0ae4c.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ !function(e){function t(t){for(var n,l,a=t[0],p=t[1],i=t[2],c=0,s=[];c<a.length;c++)l=a[c],Object.prototype.hasOwnProperty.call(o,l)&&o[l]&&s.push(o[l][0]),o[l]=0;for(n in p)Object.prototype.hasOwnProperty.call(p,n)&&(e[n]=p[n]);for(f&&f(t);s.length;)s.shift()();return u.push.apply(u,i||[]),r()}function r(){for(var e,t=0;t<u.length;t++){for(var r=u[t],n=!0,a=1;a<r.length;a++){var p=r[a];0!==o[p]&&(n=!1)}n&&(u.splice(t--,1),e=l(l.s=r[0]))}return e}var n={},o={1:0},u=[];function l(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,l),r.l=!0,r.exports}l.m=e,l.c=n,l.d=function(e,t,r){l.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:r})},l.r=function(e){"undefined"!==typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},l.t=function(e,t){if(1&t&&(e=l(e)),8&t)return e;if(4&t&&"object"===typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(l.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var n in e)l.d(r,n,function(t){return e[t]}.bind(null,n));return r},l.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return l.d(t,"a",t),t},l.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},l.p="./";var a=this.webpackJsonpstreamlit_component_template=this.webpackJsonpstreamlit_component_template||[],p=a.push.bind(a);a.push=t,a=a.slice();for(var i=0;i<a.length;i++)t(a[i]);var f=p;r()}([]);
2
+ //# sourceMappingURL=runtime-main.e6b0ae4c.js.map
highlighted_text/build/static/js/runtime-main.e6b0ae4c.js.map ADDED
@@ -0,0 +1 @@
 
 
1
+ {"version":3,"sources":["../webpack/bootstrap"],"names":["webpackJsonpCallback","data","moduleId","chunkId","chunkIds","moreModules","executeModules","i","resolves","length","Object","prototype","hasOwnProperty","call","installedChunks","push","modules","parentJsonpFunction","shift","deferredModules","apply","checkDeferredModules","result","deferredModule","fulfilled","j","depId","splice","__webpack_require__","s","installedModules","exports","module","l","m","c","d","name","getter","o","defineProperty","enumerable","get","r","Symbol","toStringTag","value","t","mode","__esModule","ns","create","key","bind","n","object","property","p","jsonpArray","this","oldJsonpFunction","slice"],"mappings":"aACE,SAASA,EAAqBC,GAQ7B,IAPA,IAMIC,EAAUC,EANVC,EAAWH,EAAK,GAChBI,EAAcJ,EAAK,GACnBK,EAAiBL,EAAK,GAIHM,EAAI,EAAGC,EAAW,GACpCD,EAAIH,EAASK,OAAQF,IACzBJ,EAAUC,EAASG,GAChBG,OAAOC,UAAUC,eAAeC,KAAKC,EAAiBX,IAAYW,EAAgBX,IACpFK,EAASO,KAAKD,EAAgBX,GAAS,IAExCW,EAAgBX,GAAW,EAE5B,IAAID,KAAYG,EACZK,OAAOC,UAAUC,eAAeC,KAAKR,EAAaH,KACpDc,EAAQd,GAAYG,EAAYH,IAKlC,IAFGe,GAAqBA,EAAoBhB,GAEtCO,EAASC,QACdD,EAASU,OAATV,GAOD,OAHAW,EAAgBJ,KAAKK,MAAMD,EAAiBb,GAAkB,IAGvDe,GACR,CACA,SAASA,IAER,IADA,IAAIC,EACIf,EAAI,EAAGA,EAAIY,EAAgBV,OAAQF,IAAK,CAG/C,IAFA,IAAIgB,EAAiBJ,EAAgBZ,GACjCiB,GAAY,EACRC,EAAI,EAAGA,EAAIF,EAAed,OAAQgB,IAAK,CAC9C,IAAIC,EAAQH,EAAeE,GACG,IAA3BX,EAAgBY,KAAcF,GAAY,EAC9C,CACGA,IACFL,EAAgBQ,OAAOpB,IAAK,GAC5Be,EAASM,EAAoBA,EAAoBC,EAAIN,EAAe,IAEtE,CAEA,OAAOD,CACR,CAGA,IAAIQ,EAAmB,CAAC,EAKpBhB,EAAkB,CACrB,EAAG,GAGAK,EAAkB,GAGtB,SAASS,EAAoB1B,GAG5B,GAAG4B,EAAiB5B,GACnB,OAAO4B,EAAiB5B,GAAU6B,QAGnC,IAAIC,EAASF,EAAiB5B,GAAY,CACzCK,EAAGL,EACH+B,GAAG,EACHF,QAAS,CAAC,GAUX,OANAf,EAAQd,GAAUW,KAAKmB,EAAOD,QAASC,EAAQA,EAAOD,QAASH,GAG/DI,EAAOC,GAAI,EAGJD,EAAOD,OACf,CAIAH,EAAoBM,EAAIlB,EAGxBY,EAAoBO,EAAIL,EAGxBF,EAAoBQ,EAAI,SAASL,EAASM,EAAMC,GAC3CV,EAAoBW,EAAER,EAASM,IAClC3B,OAAO8B,eAAeT,EAASM,EAAM,CAAEI,YAAY,EAAMC,IAAKJ,GAEhE,EAGAV,EAAoBe,EAAI,SAASZ,GACX,qBAAXa,QAA0BA,OAAOC,aAC1CnC,OAAO8B,eAAeT,EAASa,OAAOC,YAAa,CAAEC,MAAO,WAE7DpC,OAAO8B,eAAeT,EAAS,aAAc,CAAEe,OAAO,GACvD,EAOAlB,EAAoBmB,EAAI,SAASD,EAAOE,GAEvC,GADU,EAAPA,IAAUF,EAAQlB,EAAoBkB,IAC/B,EAAPE,EAAU,OAAOF,EACpB,GAAW,EAAPE,GAA8B,kBAAVF,GAAsBA,GAASA,EAAMG,WAAY,OAAOH,EAChF,IAAII,EAAKxC,OAAOyC,OAAO,MAGvB,GAFAvB,EAAoBe,EAAEO,GACtBxC,OAAO8B,eAAeU,EAAI,UAAW,CAAET,YAAY,EAAMK,MAAOA,IACtD,EAAPE,GAA4B,iBAATF,EAAmB,IAAI,IAAIM,KAAON,EAAOlB,EAAoBQ,EAAEc,EAAIE,EAAK,SAASA,GAAO,OAAON,EAAMM,EAAM,EAAEC,KAAK,KAAMD,IAC9I,OAAOF,CACR,EAGAtB,EAAoB0B,EAAI,SAAStB,GAChC,IAAIM,EAASN,GAAUA,EAAOiB,WAC7B,WAAwB,OAAOjB,EAAgB,OAAG,EAClD,WAA8B,OAAOA,CAAQ,EAE9C,OADAJ,EAAoBQ,EAAEE,EAAQ,IAAKA,GAC5BA,CACR,EAGAV,EAAoBW,EAAI,SAASgB,EAAQC,GAAY,OAAO9C,OAAOC,UAAUC,eAAeC,KAAK0C,EAAQC,EAAW,EAGpH5B,EAAoB6B,EAAI,KAExB,IAAIC,EAAaC,KAA+C,yCAAIA,KAA+C,0CAAK,GACpHC,EAAmBF,EAAW3C,KAAKsC,KAAKK,GAC5CA,EAAW3C,KAAOf,EAClB0D,EAAaA,EAAWG,QACxB,IAAI,IAAItD,EAAI,EAAGA,EAAImD,EAAWjD,OAAQF,IAAKP,EAAqB0D,EAAWnD,IAC3E,IAAIU,EAAsB2C,EAI1BvC,G","file":"static/js/runtime-main.e6b0ae4c.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tfunction webpackJsonpCallback(data) {\n \t\tvar chunkIds = data[0];\n \t\tvar moreModules = data[1];\n \t\tvar executeModules = data[2];\n\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [];\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(Object.prototype.hasOwnProperty.call(installedChunks, chunkId) && installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(data);\n\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n\n \t\t// add entry modules from loaded chunk to deferred list\n \t\tdeferredModules.push.apply(deferredModules, executeModules || []);\n\n \t\t// run deferred modules when all chunks ready\n \t\treturn checkDeferredModules();\n \t};\n \tfunction checkDeferredModules() {\n \t\tvar result;\n \t\tfor(var i = 0; i < deferredModules.length; i++) {\n \t\t\tvar deferredModule = deferredModules[i];\n \t\t\tvar fulfilled = true;\n \t\t\tfor(var j = 1; j < deferredModule.length; j++) {\n \t\t\t\tvar depId = deferredModule[j];\n \t\t\t\tif(installedChunks[depId] !== 0) fulfilled = false;\n \t\t\t}\n \t\t\tif(fulfilled) {\n \t\t\t\tdeferredModules.splice(i--, 1);\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = deferredModule[0]);\n \t\t\t}\n \t\t}\n\n \t\treturn result;\n \t}\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// object to store loaded and loading chunks\n \t// undefined = chunk not loaded, null = chunk preloaded/prefetched\n \t// Promise = chunk loading, 0 = chunk loaded\n \tvar installedChunks = {\n \t\t1: 0\n \t};\n\n \tvar deferredModules = [];\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, { enumerable: true, get: getter });\n \t\t}\n \t};\n\n \t// define __esModule on exports\n \t__webpack_require__.r = function(exports) {\n \t\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n \t\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n \t\t}\n \t\tObject.defineProperty(exports, '__esModule', { value: true });\n \t};\n\n \t// create a fake namespace object\n \t// mode & 1: value is a module id, require it\n \t// mode & 2: merge all properties of value into the ns\n \t// mode & 4: return value when already ns object\n \t// mode & 8|1: behave like require\n \t__webpack_require__.t = function(value, mode) {\n \t\tif(mode & 1) value = __webpack_require__(value);\n \t\tif(mode & 8) return value;\n \t\tif((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;\n \t\tvar ns = Object.create(null);\n \t\t__webpack_require__.r(ns);\n \t\tObject.defineProperty(ns, 'default', { enumerable: true, value: value });\n \t\tif(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));\n \t\treturn ns;\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"./\";\n\n \tvar jsonpArray = this[\"webpackJsonpstreamlit_component_template\"] = this[\"webpackJsonpstreamlit_component_template\"] || [];\n \tvar oldJsonpFunction = jsonpArray.push.bind(jsonpArray);\n \tjsonpArray.push = webpackJsonpCallback;\n \tjsonpArray = jsonpArray.slice();\n \tfor(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);\n \tvar parentJsonpFunction = oldJsonpFunction;\n\n\n \t// run deferred modules from other chunks\n \tcheckDeferredModules();\n"],"sourceRoot":""}
highlighted_text/package-lock.json ADDED
The diff for this file is too large to render. See raw diff
 
highlighted_text/package.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "streamlit_component_template",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "dependencies": {
6
+ "react": "^16.13.1",
7
+ "react-dom": "^16.13.1",
8
+ "streamlit-component-lib": "^1.3.0"
9
+ },
10
+ "scripts": {
11
+ "start": "react-scripts start",
12
+ "build": "react-scripts build",
13
+ "test": "react-scripts test",
14
+ "eject": "react-scripts eject"
15
+ },
16
+ "eslintConfig": {
17
+ "extends": "react-app"
18
+ },
19
+ "browserslist": {
20
+ "production": [
21
+ ">0.2%",
22
+ "not dead",
23
+ "not op_mini all"
24
+ ],
25
+ "development": [
26
+ "last 1 chrome version",
27
+ "last 1 firefox version",
28
+ "last 1 safari version"
29
+ ]
30
+ },
31
+ "homepage": ".",
32
+ "devDependencies": {
33
+ "@types/node": "^12.0.0",
34
+ "@types/react": "^16.9.0",
35
+ "@types/react-dom": "^16.9.0",
36
+ "react-scripts": "4.0.3",
37
+ "typescript": "^4.2.0"
38
+ }
39
+ }
highlighted_text/public/index.css ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ body {
2
+ padding: 0;
3
+ margin: 0;
4
+ font-family: "Source Sans Pro", sans-serif;
5
+ font-size: 1rem;
6
+ line-height: 1.4;
7
+ }
8
+
9
+ .status-bar {
10
+ display: none;
11
+ }
12
+
13
+ .highlighted-text {
14
+ border: 1px solid #d2d2d2;
15
+ border-radius: 5px 5px 5px 5px;
16
+ padding: 2px;
17
+ cursor: pointer;
18
+
19
+ .token.active {
20
+ outline: 1px solid #444;
21
+ }
22
+
23
+ &.frozen {
24
+ .token {
25
+ opacity: 0.75;
26
+
27
+ &.context, &.active {
28
+ opacity: 1;
29
+ }
30
+
31
+ &.context {
32
+ text-decoration: #999 underline;
33
+ }
34
+ }
35
+ }
36
+ }
highlighted_text/public/index.html ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Highlighted text component</title>
5
+ <meta charset="UTF-8" />
6
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
7
+ <meta name="theme-color" content="#fff" />
8
+ <meta name="description" content="Highlighted text" />
9
+ <link rel="stylesheet" href="index.css" />
10
+ </head>
11
+ <body>
12
+ <div id="root"></div>
13
+ </body>
14
+ </html>
highlighted_text/src/HighlightedText.tsx ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import {
2
+ StreamlitComponentBase,
3
+ withStreamlitConnection,
4
+ } from "streamlit-component-lib";
5
+
6
+ type HighlightedTextState = {
7
+ activeIndex: number | null,
8
+ hoverIndex: number | null,
9
+ isFrozen: boolean
10
+ };
11
+
12
+ /**
13
+ * This is a React-based component template. The `render()` function is called
14
+ * automatically when your component should be re-rendered.
15
+ */
16
+ class HighlightedText extends StreamlitComponentBase<HighlightedTextState> {
17
+ public state = {activeIndex: null, hoverIndex: null, isFrozen: false};
18
+
19
+ render() {
20
+ const tokens: string[] = this.props.args["tokens"];
21
+ const scores: number[] = this.getScores();
22
+ console.log(scores);
23
+
24
+ let className = "highlighted-text";
25
+ if (this.state.isFrozen) {
26
+ className += " frozen";
27
+ }
28
+
29
+ const onClick = () => {
30
+ this.setState({ isFrozen: false });
31
+ };
32
+
33
+ return <>
34
+ <div className="status-bar" key="status-bar">
35
+ <span className={this.state.isFrozen ? "" : " d-none"} key="lock-icon"><i className="fa fa-lock"></i> </span>
36
+ <strong key="target-label">target:</strong>
37
+ {
38
+ this.state.activeIndex != null
39
+ ? <span className="token" key="target">{tokens[this.state.activeIndex]}</span>
40
+ : <></>
41
+ }
42
+ </div>
43
+ <div className={className} onClick={onClick} key="text">
44
+ {
45
+ tokens.map((t: string, i: number) => {
46
+ let className = "token";
47
+ if (this.state) {
48
+ if (this.state.activeIndex == i) {
49
+ className += " active";
50
+ }
51
+ }
52
+ const style = {
53
+ backgroundColor:
54
+ scores[i] > 0
55
+ ? `rgba(255, 32, 32, ${scores[i]})`
56
+ : `rgba(32, 255, 32, ${-scores[i]})`
57
+ };
58
+
59
+ const onMouseOver = () => {
60
+ if (!this.state.isFrozen) {
61
+ this.setState({ activeIndex: i });
62
+ }
63
+ this.setState({ hoverIndex: i });
64
+ };
65
+ return <span key={i} className={className} style={style}
66
+ onMouseOver={onMouseOver} onClick={onClick}>{t}</span>;
67
+ })
68
+ }
69
+ </div>
70
+ </>;
71
+ }
72
+
73
+ private getScores() {
74
+ const tokens = this.props.args["tokens"];
75
+ if (!this.state || this.state.activeIndex == null || this.state.activeIndex < 1) {
76
+ return tokens.map(() => 0);
77
+ }
78
+ const allScores: number[][] = this.props.args["scores"];
79
+
80
+ const i = this.state.activeIndex - 1;
81
+ const hi = Math.min(Math.max(0, i), allScores[i].length);
82
+ const row = allScores[i].slice(0, hi);
83
+ row.reverse();
84
+ let result = [
85
+ ...Array(Math.max(0, i - 1 - row.length)).fill(0),
86
+ ...row.map((x) => x == undefined || isNaN(x) ? 0 : x)
87
+ ];
88
+ result = [...result, ...Array(tokens.length - result.length).fill(0)];
89
+ return result;
90
+ }
91
+ }
92
+
93
+ export default withStreamlitConnection(HighlightedText);
highlighted_text/src/index.tsx ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import React from "react";
2
+ import ReactDOM from "react-dom";
3
+ import HighlightedText from "./HighlightedText";
4
+
5
+ ReactDOM.render(
6
+ <React.StrictMode>
7
+ <HighlightedText />
8
+ </React.StrictMode>,
9
+ document.getElementById("root")
10
+ )
highlighted_text/src/react-app-env.d.ts ADDED
@@ -0,0 +1 @@
 
 
1
+ /// <reference types="react-scripts" />
highlighted_text/tsconfig.json ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "compilerOptions": {
3
+ "target": "es5",
4
+ "lib": [
5
+ "dom",
6
+ "dom.iterable",
7
+ "esnext"
8
+ ],
9
+ "allowJs": true,
10
+ "skipLibCheck": true,
11
+ "esModuleInterop": true,
12
+ "allowSyntheticDefaultImports": true,
13
+ "strict": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "module": "esnext",
16
+ "moduleResolution": "node",
17
+ "resolveJsonModule": true,
18
+ "isolatedModules": true,
19
+ "noEmit": true,
20
+ "jsx": "react-jsx",
21
+ "noFallthroughCasesInSwitch": true
22
+ },
23
+ "include": [
24
+ "src"
25
+ ]
26
+ }
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ streamlit==1.17.0
2
+ torch
3
+ transformers