Browse Source

Add OCR tool to media editing modal (#11566)

Eugen Rochko 3 months ago
parent
commit
28636f43e4
No account linked to committer's email address

+ 2
- 1
app/javascript/mastodon/features/compose/components/upload_form.js View File

@@ -4,6 +4,7 @@ import UploadProgressContainer from '../containers/upload_progress_container';
4 4
 import ImmutablePureComponent from 'react-immutable-pure-component';
5 5
 import UploadContainer from '../containers/upload_container';
6 6
 import SensitiveButtonContainer from '../containers/sensitive_button_container';
7
+import { FormattedMessage } from 'react-intl';
7 8
 
8 9
 export default class UploadForm extends ImmutablePureComponent {
9 10
 
@@ -16,7 +17,7 @@ export default class UploadForm extends ImmutablePureComponent {
16 17
 
17 18
     return (
18 19
       <div className='compose-form__upload-wrapper'>
19
-        <UploadProgressContainer />
20
+        <UploadProgressContainer icon='upload' message={<FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />} />
20 21
 
21 22
         <div className='compose-form__uploads-wrapper'>
22 23
           {mediaIds.map(id => (

+ 5
- 4
app/javascript/mastodon/features/compose/components/upload_progress.js View File

@@ -2,7 +2,6 @@ import React from 'react';
2 2
 import PropTypes from 'prop-types';
3 3
 import Motion from '../../ui/util/optional_motion';
4 4
 import spring from 'react-motion/lib/spring';
5
-import { FormattedMessage } from 'react-intl';
6 5
 import Icon from 'mastodon/components/icon';
7 6
 
8 7
 export default class UploadProgress extends React.PureComponent {
@@ -10,10 +9,12 @@ export default class UploadProgress extends React.PureComponent {
10 9
   static propTypes = {
11 10
     active: PropTypes.bool,
12 11
     progress: PropTypes.number,
12
+    icon: PropTypes.string.isRequired,
13
+    message: PropTypes.node.isRequired,
13 14
   };
14 15
 
15 16
   render () {
16
-    const { active, progress } = this.props;
17
+    const { active, progress, icon, message } = this.props;
17 18
 
18 19
     if (!active) {
19 20
       return null;
@@ -22,11 +23,11 @@ export default class UploadProgress extends React.PureComponent {
22 23
     return (
23 24
       <div className='upload-progress'>
24 25
         <div className='upload-progress__icon'>
25
-          <Icon id='upload' />
26
+          <Icon id={icon} />
26 27
         </div>
27 28
 
28 29
         <div className='upload-progress__message'>
29
-          <FormattedMessage id='upload_progress.label' defaultMessage='Uploading...' />
30
+          {message}
30 31
 
31 32
           <div className='upload-progress__backdrop'>
32 33
             <Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}>

+ 51
- 9
app/javascript/mastodon/features/ui/components/focal_point_modal.js View File

@@ -10,6 +10,11 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl';
10 10
 import IconButton from 'mastodon/components/icon_button';
11 11
 import Button from 'mastodon/components/button';
12 12
 import Video from 'mastodon/features/video';
13
+import { TesseractWorker } from 'tesseract.js';
14
+import Textarea from 'react-textarea-autosize';
15
+import UploadProgress from 'mastodon/features/compose/components/upload_progress';
16
+import CharacterCounter from 'mastodon/features/compose/components/character_counter';
17
+import { length } from 'stringz';
13 18
 
14 19
 const messages = defineMessages({
15 20
   close: { id: 'lightbox.close', defaultMessage: 'Close' },
@@ -29,6 +34,12 @@ const mapDispatchToProps = (dispatch, { id }) => ({
29 34
 
30 35
 });
31 36
 
37
+const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******')
38
+  .replace(/\n/g, ' ')
39
+  .replace(/\*\*\*\*\*\*/g, '\n\n');
40
+
41
+const assetHost = process.env.CDN_HOST || '';
42
+
32 43
 export default @connect(mapStateToProps, mapDispatchToProps)
33 44
 @injectIntl
34 45
 class FocalPointModal extends ImmutablePureComponent {
@@ -47,6 +58,7 @@ class FocalPointModal extends ImmutablePureComponent {
47 58
     dragging: false,
48 59
     description: '',
49 60
     dirty: false,
61
+    progress: 0,
50 62
   };
51 63
 
52 64
   componentWillMount () {
@@ -133,9 +145,27 @@ class FocalPointModal extends ImmutablePureComponent {
133 145
     this.node = c;
134 146
   }
135 147
 
148
+  handleTextDetection = () => {
149
+    const { media } = this.props;
150
+
151
+    const worker = new TesseractWorker({
152
+      workerPath: `${assetHost}/packs/ocr/worker.min.js`,
153
+      corePath: `${assetHost}/packs/ocr/tesseract-core.wasm.js`,
154
+      langPath: `${assetHost}/ocr/lang-data`,
155
+    });
156
+
157
+    this.setState({ detecting: true });
158
+
159
+    worker.recognize(media.get('url'))
160
+      .progress(({ progress }) => this.setState({ progress }))
161
+      .finally(() => worker.terminate())
162
+      .then(({ text }) => this.setState({ description: removeExtraLineBreaks(text), dirty: true, detecting: false }))
163
+      .catch(() => this.setState({ detecting: false }));
164
+  }
165
+
136 166
   render () {
137 167
     const { media, intl, onClose } = this.props;
138
-    const { x, y, dragging, description, dirty } = this.state;
168
+    const { x, y, dragging, description, dirty, detecting, progress } = this.state;
139 169
 
140 170
     const width  = media.getIn(['meta', 'original', 'width']) || null;
141 171
     const height = media.getIn(['meta', 'original', 'height']) || null;
@@ -158,15 +188,27 @@ class FocalPointModal extends ImmutablePureComponent {
158 188
 
159 189
             <label className='setting-text-label' htmlFor='upload-modal__description'><FormattedMessage id='upload_form.description' defaultMessage='Describe for the visually impaired' /></label>
160 190
 
161
-            <textarea
162
-              id='upload-modal__description'
163
-              className='setting-text light'
164
-              value={description}
165
-              onChange={this.handleChange}
166
-              autoFocus
167
-            />
191
+            <div className='setting-text__wrapper'>
192
+              <Textarea
193
+                id='upload-modal__description'
194
+                className='setting-text light'
195
+                value={detecting ? '…' : description}
196
+                onChange={this.handleChange}
197
+                disabled={detecting}
198
+                autoFocus
199
+              />
200
+
201
+              <div className='setting-text__modifiers'>
202
+                <UploadProgress progress={progress * 100} active={detecting} icon='file-text-o' message={<FormattedMessage id='upload_modal.analyzing_picture' defaultMessage='Analyzing picture…' />} />
203
+              </div>
204
+            </div>
205
+
206
+            <div className='setting-text__toolbar'>
207
+              <button disabled={detecting || media.get('type') !== 'image'} className='link-button' onClick={this.handleTextDetection}><FormattedMessage id='upload_modal.detect_text' defaultMessage='Detect text from picture' /></button>
208
+              <CharacterCounter max={420} text={detecting ? '' : description} />
209
+            </div>
168 210
 
169
-            <Button disabled={!dirty} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} />
211
+            <Button disabled={!dirty || detecting || length(description) > 420} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} />
170 212
           </div>
171 213
 
172 214
           <div className='report-modal__statuses'>

+ 67
- 14
app/javascript/styles/mastodon/components.scss View File

@@ -3,6 +3,27 @@
3 3
   -ms-overflow-style: -ms-autohiding-scrollbar;
4 4
 }
5 5
 
6
+.link-button {
7
+  display: block;
8
+  font-size: 15px;
9
+  line-height: 20px;
10
+  color: $ui-highlight-color;
11
+  border: 0;
12
+  background: transparent;
13
+  padding: 0;
14
+  cursor: pointer;
15
+
16
+  &:hover,
17
+  &:active {
18
+    text-decoration: underline;
19
+  }
20
+
21
+  &:disabled {
22
+    color: $ui-primary-color;
23
+    cursor: default;
24
+  }
25
+}
26
+
6 27
 .button {
7 28
   background-color: $ui-highlight-color;
8 29
   border: 10px none;
@@ -637,18 +658,6 @@
637 658
     .character-counter__wrapper {
638 659
       align-self: center;
639 660
       margin-right: 4px;
640
-
641
-      .character-counter {
642
-        cursor: default;
643
-        font-family: $font-sans-serif, sans-serif;
644
-        font-size: 14px;
645
-        font-weight: 600;
646
-        color: $lighter-text-color;
647
-
648
-        &.character-counter--over {
649
-          color: $warning-red;
650
-        }
651
-      }
652 661
     }
653 662
   }
654 663
 
@@ -665,6 +674,18 @@
665 674
   }
666 675
 }
667 676
 
677
+.character-counter {
678
+  cursor: default;
679
+  font-family: $font-sans-serif, sans-serif;
680
+  font-size: 14px;
681
+  font-weight: 600;
682
+  color: $lighter-text-color;
683
+
684
+  &.character-counter--over {
685
+    color: $warning-red;
686
+  }
687
+}
688
+
668 689
 .no-reduce-motion .spoiler-input {
669 690
   transition: height 0.4s ease, opacity 0.4s ease;
670 691
 }
@@ -4555,16 +4576,48 @@ a.status-card.compact:hover {
4555 4576
     padding: 10px;
4556 4577
     font-family: inherit;
4557 4578
     font-size: 14px;
4558
-    resize: vertical;
4579
+    resize: none;
4559 4580
     border: 0;
4560 4581
     outline: 0;
4561 4582
     border-radius: 4px;
4562 4583
     border: 1px solid $ui-secondary-color;
4563
-    margin-bottom: 20px;
4584
+    min-height: 100px;
4585
+    max-height: 50vh;
4586
+    margin-bottom: 10px;
4564 4587
 
4565 4588
     &:focus {
4566 4589
       border: 1px solid darken($ui-secondary-color, 8%);
4567 4590
     }
4591
+
4592
+    &__wrapper {
4593
+      background: $white;
4594
+      border: 1px solid $ui-secondary-color;
4595
+      margin-bottom: 10px;
4596
+      border-radius: 4px;
4597
+
4598
+      .setting-text {
4599
+        border: 0;
4600
+        margin-bottom: 0;
4601
+        border-radius: 0;
4602
+
4603
+        &:focus {
4604
+          border: 0;
4605
+        }
4606
+      }
4607
+
4608
+      &__modifiers {
4609
+        color: $inverted-text-color;
4610
+        font-family: inherit;
4611
+        font-size: 14px;
4612
+        background: $white;
4613
+      }
4614
+    }
4615
+
4616
+    &__toolbar {
4617
+      display: flex;
4618
+      justify-content: space-between;
4619
+      margin-bottom: 20px;
4620
+    }
4568 4621
   }
4569 4622
 
4570 4623
   .setting-text-label {

+ 4
- 4
config/initializers/content_security_policy.rb View File

@@ -20,11 +20,11 @@ Rails.application.config.content_security_policy do |p|
20 20
   if Rails.env.development?
21 21
     webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" }
22 22
 
23
-    p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls
24
-    p.script_src  :self, :unsafe_inline, :unsafe_eval, assets_host
23
+    p.connect_src :self, :data, :blob, assets_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls
24
+    p.script_src  :self, :blob, :unsafe_inline, :unsafe_eval, assets_host
25 25
   else
26
-    p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url
27
-    p.script_src  :self, assets_host
26
+    p.connect_src :self, :data, :blob, assets_host, Rails.configuration.x.streaming_api_base_url
27
+    p.script_src  :self, :blob, assets_host
28 28
   end
29 29
 end
30 30
 

+ 1
- 0
config/webpack/development.js View File

@@ -56,5 +56,6 @@ module.exports = merge(sharedConfig, {
56 56
       settings.dev_server.watch_options,
57 57
       watchOptions
58 58
     ),
59
+    writeToDisk: filePath => /ocr/.test(filePath),
59 60
   },
60 61
 });

+ 5
- 0
config/webpack/shared.js View File

@@ -5,6 +5,7 @@ const { basename, dirname, join, relative, resolve } = require('path');
5 5
 const { sync } = require('glob');
6 6
 const MiniCssExtractPlugin = require('mini-css-extract-plugin');
7 7
 const AssetsManifestPlugin = require('webpack-assets-manifest');
8
+const CopyPlugin = require('copy-webpack-plugin');
8 9
 const extname = require('path-complete-extname');
9 10
 const { env, settings, themes, output } = require('./configuration');
10 11
 const rules = require('./rules');
@@ -84,6 +85,10 @@ module.exports = {
84 85
       writeToDisk: true,
85 86
       publicPath: true,
86 87
     }),
88
+    new CopyPlugin([
89
+      { from: 'node_modules/tesseract.js/dist/worker.min.js', to: 'ocr' },
90
+      { from: 'node_modules/tesseract.js-core/tesseract-core.wasm.js', to: 'ocr' },
91
+    ]),
87 92
   ],
88 93
 
89 94
   resolve: {

+ 2
- 0
package.json View File

@@ -84,6 +84,7 @@
84 84
     "blurhash": "^1.0.0",
85 85
     "classnames": "^2.2.5",
86 86
     "compression-webpack-plugin": "^3.0.0",
87
+    "copy-webpack-plugin": "^5.0.4",
87 88
     "cross-env": "^5.1.4",
88 89
     "css-loader": "^3.2.0",
89 90
     "cssnano": "^4.1.10",
@@ -155,6 +156,7 @@
155 156
     "stringz": "^2.0.0",
156 157
     "substring-trie": "^1.0.2",
157 158
     "terser-webpack-plugin": "^1.4.1",
159
+    "tesseract.js": "^2.0.0-alpha.13",
158 160
     "throng": "^4.0.0",
159 161
     "tiny-queue": "^0.2.1",
160 162
     "uuid": "^3.1.0",

BIN
public/ocr/lang-data/eng.traineddata.gz View File


+ 138
- 2
yarn.lock View File

@@ -1727,6 +1727,14 @@ aws4@^1.8.0:
1727 1727
   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f"
1728 1728
   integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==
1729 1729
 
1730
+axios@^0.18.0:
1731
+  version "0.18.1"
1732
+  resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3"
1733
+  integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g==
1734
+  dependencies:
1735
+    follow-redirects "1.5.10"
1736
+    is-buffer "^2.0.2"
1737
+
1730 1738
 axios@^0.19.0:
1731 1739
   version "0.19.0"
1732 1740
   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8"
@@ -1975,6 +1983,11 @@ blurhash@^1.0.0:
1975 1983
   resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.0.0.tgz#9087bc5cc4d482f1305059d7410df4133adcab2e"
1976 1984
   integrity sha512-x6fpZnd6AWde4U9m7xhUB44qIvGV4W6OdTAXGabYm4oZUOOGh5K1HAEoGAQn3iG4gbbPn9RSGce3VfNgGsX/Vw==
1977 1985
 
1986
+bmp-js@^0.1.0:
1987
+  version "0.1.0"
1988
+  resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233"
1989
+  integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM=
1990
+
1978 1991
 bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0:
1979 1992
   version "4.11.8"
1980 1993
   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f"
@@ -2212,6 +2225,26 @@ cacache@^11.2.0:
2212 2225
     unique-filename "^1.1.1"
2213 2226
     y18n "^4.0.0"
2214 2227
 
2228
+cacache@^11.3.3:
2229
+  version "11.3.3"
2230
+  resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc"
2231
+  integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA==
2232
+  dependencies:
2233
+    bluebird "^3.5.5"
2234
+    chownr "^1.1.1"
2235
+    figgy-pudding "^3.5.1"
2236
+    glob "^7.1.4"
2237
+    graceful-fs "^4.1.15"
2238
+    lru-cache "^5.1.1"
2239
+    mississippi "^3.0.0"
2240
+    mkdirp "^0.5.1"
2241
+    move-concurrently "^1.0.1"
2242
+    promise-inflight "^1.0.1"
2243
+    rimraf "^2.6.3"
2244
+    ssri "^6.0.1"
2245
+    unique-filename "^1.1.1"
2246
+    y18n "^4.0.0"
2247
+
2215 2248
 cacache@^12.0.2:
2216 2249
   version "12.0.2"
2217 2250
   resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c"
@@ -2341,7 +2374,7 @@ chardet@^0.7.0:
2341 2374
   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e"
2342 2375
   integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==
2343 2376
 
2344
-check-types@^7.3.0:
2377
+check-types@^7.3.0, check-types@^7.4.0:
2345 2378
   version "7.4.0"
2346 2379
   resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4"
2347 2380
   integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg==
@@ -2691,6 +2724,24 @@ copy-descriptor@^0.1.0:
2691 2724
   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
2692 2725
   integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
2693 2726
 
2727
+copy-webpack-plugin@^5.0.4:
2728
+  version "5.0.4"
2729
+  resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz#c78126f604e24f194c6ec2f43a64e232b5d43655"
2730
+  integrity sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg==
2731
+  dependencies:
2732
+    cacache "^11.3.3"
2733
+    find-cache-dir "^2.1.0"
2734
+    glob-parent "^3.1.0"
2735
+    globby "^7.1.1"
2736
+    is-glob "^4.0.1"
2737
+    loader-utils "^1.2.3"
2738
+    minimatch "^3.0.4"
2739
+    normalize-path "^3.0.0"
2740
+    p-limit "^2.2.0"
2741
+    schema-utils "^1.0.0"
2742
+    serialize-javascript "^1.7.0"
2743
+    webpack-log "^2.0.0"
2744
+
2694 2745
 core-js-compat@^3.1.1:
2695 2746
   version "3.1.3"
2696 2747
   resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.3.tgz#0cc3ba4c7f62928c2837e1cffbe8dc78b4f1ae14"
@@ -3274,6 +3325,13 @@ diffie-hellman@^5.0.0:
3274 3325
     miller-rabin "^4.0.0"
3275 3326
     randombytes "^2.0.0"
3276 3327
 
3328
+dir-glob@^2.0.0:
3329
+  version "2.2.2"
3330
+  resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4"
3331
+  integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==
3332
+  dependencies:
3333
+    path-type "^3.0.0"
3334
+
3277 3335
 discontinuous-range@1.0.0:
3278 3336
   version "1.0.0"
3279 3337
   resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a"
@@ -4222,6 +4280,11 @@ file-loader@^4.1.0:
4222 4280
     loader-utils "^1.2.3"
4223 4281
     schema-utils "^2.0.0"
4224 4282
 
4283
+file-type@^10.5.0:
4284
+  version "10.11.0"
4285
+  resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890"
4286
+  integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==
4287
+
4225 4288
 filesize@^3.6.1:
4226 4289
   version "3.6.1"
4227 4290
   resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317"
@@ -4644,6 +4707,18 @@ globby@^6.1.0:
4644 4707
     pify "^2.0.0"
4645 4708
     pinkie-promise "^2.0.0"
4646 4709
 
4710
+globby@^7.1.1:
4711
+  version "7.1.1"
4712
+  resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680"
4713
+  integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA=
4714
+  dependencies:
4715
+    array-union "^1.0.1"
4716
+    dir-glob "^2.0.0"
4717
+    glob "^7.1.2"
4718
+    ignore "^3.3.5"
4719
+    pify "^3.0.0"
4720
+    slash "^1.0.0"
4721
+
4647 4722
 globule@^1.0.0:
4648 4723
   version "1.2.1"
4649 4724
   resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d"
@@ -4981,6 +5056,11 @@ icss-utils@^4.0.0, icss-utils@^4.1.1:
4981 5056
   dependencies:
4982 5057
     postcss "^7.0.14"
4983 5058
 
5059
+idb-keyval@^3.1.0:
5060
+  version "3.2.0"
5061
+  resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-3.2.0.tgz#cbbf354deb5684b6cdc84376294fc05932845bd6"
5062
+  integrity sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ==
5063
+
4984 5064
 ieee754@^1.1.4:
4985 5065
   version "1.1.12"
4986 5066
   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b"
@@ -4998,7 +5078,7 @@ ignore-walk@^3.0.1:
4998 5078
   dependencies:
4999 5079
     minimatch "^3.0.4"
5000 5080
 
5001
-ignore@^3.1.2:
5081
+ignore@^3.1.2, ignore@^3.3.5:
5002 5082
   version "3.3.10"
5003 5083
   resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043"
5004 5084
   integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==
@@ -5540,6 +5620,16 @@ is-typedarray@~1.0.0:
5540 5620
   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
5541 5621
   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=
5542 5622
 
5623
+is-url@1.2.2:
5624
+  version "1.2.2"
5625
+  resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26"
5626
+  integrity sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=
5627
+
5628
+is-url@^1.2.4:
5629
+  version "1.2.4"
5630
+  resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52"
5631
+  integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==
5632
+
5543 5633
 is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2:
5544 5634
   version "1.0.2"
5545 5635
   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d"
@@ -6818,6 +6908,11 @@ node-fetch@^1.0.1:
6818 6908
     encoding "^0.1.11"
6819 6909
     is-stream "^1.0.1"
6820 6910
 
6911
+node-fetch@^2.3.0:
6912
+  version "2.6.0"
6913
+  resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
6914
+  integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
6915
+
6821 6916
 node-forge@0.7.5:
6822 6917
   version "0.7.5"
6823 6918
   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df"
@@ -7157,6 +7252,11 @@ onetime@^2.0.0:
7157 7252
   dependencies:
7158 7253
     mimic-fn "^1.0.0"
7159 7254
 
7255
+opencollective-postinstall@^2.0.2:
7256
+  version "2.0.2"
7257
+  resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89"
7258
+  integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==
7259
+
7160 7260
 opener@^1.5.1:
7161 7261
   version "1.5.1"
7162 7262
   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed"
@@ -9864,6 +9964,37 @@ terser@^4.1.2:
9864 9964
     source-map "~0.6.1"
9865 9965
     source-map-support "~0.5.12"
9866 9966
 
9967
+tesseract.js-core@^2.0.0-beta.10:
9968
+  version "2.0.0-beta.10"
9969
+  resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-2.0.0-beta.10.tgz#b8f0dd2be4686650c4350f648900adccfaf58d6b"
9970
+  integrity sha512-QmNgMA9m5ES5uMTqpOAPysrUA80vUx/6WKQlfkK3zhOeAgqv8DjwwcDv9tQv2TgRzOQ+LFKrJn94Y2rw5b2IGw==
9971
+
9972
+tesseract.js-utils@^1.0.0-beta.8:
9973
+  version "1.0.0-beta.8"
9974
+  resolved "https://registry.yarnpkg.com/tesseract.js-utils/-/tesseract.js-utils-1.0.0-beta.8.tgz#d1ef25c12609a337c3e0ac12a33f9903f3145a68"
9975
+  integrity sha512-qjHBfWfzo2o1ZY9XI0Wh2hmpp38+mIgCMOk60W5Yyie/pBl421VLBKOZUEwQgpbLnOJ24VU6Q8yXsVgtFFHcFg==
9976
+  dependencies:
9977
+    axios "^0.18.0"
9978
+    bmp-js "^0.1.0"
9979
+    file-type "^10.5.0"
9980
+    idb-keyval "^3.1.0"
9981
+    is-url "^1.2.4"
9982
+    zlibjs "^0.3.1"
9983
+
9984
+tesseract.js@^2.0.0-alpha.13:
9985
+  version "2.0.0-alpha.13"
9986
+  resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-2.0.0-alpha.13.tgz#87bb3d71fe646c0993b073552241d203d9dfef3a"
9987
+  integrity sha512-ZFEdak7jWtN5vIDwZcw8OdAqA7RvG0QRailZKQFS5rtnl/Yy5vC4WcqfJh9+o+cA3bdr2zV5SENoWDtEihlSVA==
9988
+  dependencies:
9989
+    axios "^0.18.0"
9990
+    check-types "^7.4.0"
9991
+    is-url "1.2.2"
9992
+    node-fetch "^2.3.0"
9993
+    opencollective-postinstall "^2.0.2"
9994
+    resolve-url "^0.2.1"
9995
+    tesseract.js-core "^2.0.0-beta.10"
9996
+    tesseract.js-utils "^1.0.0-beta.8"
9997
+
9867 9998
 test-exclude@^5.0.0:
9868 9999
   version "5.1.0"
9869 10000
   resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1"
@@ -10726,3 +10857,8 @@ yargs@^13.3.0:
10726 10857
     which-module "^2.0.0"
10727 10858
     y18n "^4.0.0"
10728 10859
     yargs-parser "^13.1.1"
10860
+
10861
+zlibjs@^0.3.1:
10862
+  version "0.3.1"
10863
+  resolved "https://registry.yarnpkg.com/zlibjs/-/zlibjs-0.3.1.tgz#50197edb28a1c42ca659cc8b4e6a9ddd6d444554"
10864
+  integrity sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ=

Loading…
Cancel
Save