Add OCR tool to media editing modal (#11566)
This commit is contained in:
		
					parent
					
						
							
								f178a01c11
							
						
					
				
			
			
				commit
				
					
						28636f43e4
					
				
			
		
					 10 changed files with 275 additions and 34 deletions
				
			
		|  | @ -4,6 +4,7 @@ import UploadProgressContainer from '../containers/upload_progress_container'; | ||||||
| import ImmutablePureComponent from 'react-immutable-pure-component'; | import ImmutablePureComponent from 'react-immutable-pure-component'; | ||||||
| import UploadContainer from '../containers/upload_container'; | import UploadContainer from '../containers/upload_container'; | ||||||
| import SensitiveButtonContainer from '../containers/sensitive_button_container'; | import SensitiveButtonContainer from '../containers/sensitive_button_container'; | ||||||
|  | import { FormattedMessage } from 'react-intl'; | ||||||
| 
 | 
 | ||||||
| export default class UploadForm extends ImmutablePureComponent { | export default class UploadForm extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|  | @ -16,7 +17,7 @@ export default class UploadForm extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <div className='compose-form__upload-wrapper'> |       <div className='compose-form__upload-wrapper'> | ||||||
|         <UploadProgressContainer /> |         <UploadProgressContainer icon='upload' message={<FormattedMessage id='upload_progress.label' defaultMessage='Uploading…' />} /> | ||||||
| 
 | 
 | ||||||
|         <div className='compose-form__uploads-wrapper'> |         <div className='compose-form__uploads-wrapper'> | ||||||
|           {mediaIds.map(id => ( |           {mediaIds.map(id => ( | ||||||
|  |  | ||||||
|  | @ -2,7 +2,6 @@ import React from 'react'; | ||||||
| import PropTypes from 'prop-types'; | import PropTypes from 'prop-types'; | ||||||
| import Motion from '../../ui/util/optional_motion'; | import Motion from '../../ui/util/optional_motion'; | ||||||
| import spring from 'react-motion/lib/spring'; | import spring from 'react-motion/lib/spring'; | ||||||
| import { FormattedMessage } from 'react-intl'; |  | ||||||
| import Icon from 'mastodon/components/icon'; | import Icon from 'mastodon/components/icon'; | ||||||
| 
 | 
 | ||||||
| export default class UploadProgress extends React.PureComponent { | export default class UploadProgress extends React.PureComponent { | ||||||
|  | @ -10,10 +9,12 @@ export default class UploadProgress extends React.PureComponent { | ||||||
|   static propTypes = { |   static propTypes = { | ||||||
|     active: PropTypes.bool, |     active: PropTypes.bool, | ||||||
|     progress: PropTypes.number, |     progress: PropTypes.number, | ||||||
|  |     icon: PropTypes.string.isRequired, | ||||||
|  |     message: PropTypes.node.isRequired, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { active, progress } = this.props; |     const { active, progress, icon, message } = this.props; | ||||||
| 
 | 
 | ||||||
|     if (!active) { |     if (!active) { | ||||||
|       return null; |       return null; | ||||||
|  | @ -22,11 +23,11 @@ export default class UploadProgress extends React.PureComponent { | ||||||
|     return ( |     return ( | ||||||
|       <div className='upload-progress'> |       <div className='upload-progress'> | ||||||
|         <div className='upload-progress__icon'> |         <div className='upload-progress__icon'> | ||||||
|           <Icon id='upload' /> |           <Icon id={icon} /> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
|         <div className='upload-progress__message'> |         <div className='upload-progress__message'> | ||||||
|           <FormattedMessage id='upload_progress.label' defaultMessage='Uploading...' /> |           {message} | ||||||
| 
 | 
 | ||||||
|           <div className='upload-progress__backdrop'> |           <div className='upload-progress__backdrop'> | ||||||
|             <Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}> |             <Motion defaultStyle={{ width: 0 }} style={{ width: spring(progress) }}> | ||||||
|  |  | ||||||
|  | @ -10,6 +10,11 @@ import { FormattedMessage, defineMessages, injectIntl } from 'react-intl'; | ||||||
| import IconButton from 'mastodon/components/icon_button'; | import IconButton from 'mastodon/components/icon_button'; | ||||||
| import Button from 'mastodon/components/button'; | import Button from 'mastodon/components/button'; | ||||||
| import Video from 'mastodon/features/video'; | import Video from 'mastodon/features/video'; | ||||||
|  | import { TesseractWorker } from 'tesseract.js'; | ||||||
|  | import Textarea from 'react-textarea-autosize'; | ||||||
|  | import UploadProgress from 'mastodon/features/compose/components/upload_progress'; | ||||||
|  | import CharacterCounter from 'mastodon/features/compose/components/character_counter'; | ||||||
|  | import { length } from 'stringz'; | ||||||
| 
 | 
 | ||||||
| const messages = defineMessages({ | const messages = defineMessages({ | ||||||
|   close: { id: 'lightbox.close', defaultMessage: 'Close' }, |   close: { id: 'lightbox.close', defaultMessage: 'Close' }, | ||||||
|  | @ -29,6 +34,12 @@ const mapDispatchToProps = (dispatch, { id }) => ({ | ||||||
| 
 | 
 | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
|  | const removeExtraLineBreaks = str => str.replace(/\n\n/g, '******') | ||||||
|  |   .replace(/\n/g, ' ') | ||||||
|  |   .replace(/\*\*\*\*\*\*/g, '\n\n'); | ||||||
|  | 
 | ||||||
|  | const assetHost = process.env.CDN_HOST || ''; | ||||||
|  | 
 | ||||||
| export default @connect(mapStateToProps, mapDispatchToProps) | export default @connect(mapStateToProps, mapDispatchToProps) | ||||||
| @injectIntl | @injectIntl | ||||||
| class FocalPointModal extends ImmutablePureComponent { | class FocalPointModal extends ImmutablePureComponent { | ||||||
|  | @ -47,6 +58,7 @@ class FocalPointModal extends ImmutablePureComponent { | ||||||
|     dragging: false, |     dragging: false, | ||||||
|     description: '', |     description: '', | ||||||
|     dirty: false, |     dirty: false, | ||||||
|  |     progress: 0, | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   componentWillMount () { |   componentWillMount () { | ||||||
|  | @ -133,9 +145,27 @@ class FocalPointModal extends ImmutablePureComponent { | ||||||
|     this.node = c; |     this.node = c; | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  |   handleTextDetection = () => { | ||||||
|  |     const { media } = this.props; | ||||||
|  | 
 | ||||||
|  |     const worker = new TesseractWorker({ | ||||||
|  |       workerPath: `${assetHost}/packs/ocr/worker.min.js`, | ||||||
|  |       corePath: `${assetHost}/packs/ocr/tesseract-core.wasm.js`, | ||||||
|  |       langPath: `${assetHost}/ocr/lang-data`, | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     this.setState({ detecting: true }); | ||||||
|  | 
 | ||||||
|  |     worker.recognize(media.get('url')) | ||||||
|  |       .progress(({ progress }) => this.setState({ progress })) | ||||||
|  |       .finally(() => worker.terminate()) | ||||||
|  |       .then(({ text }) => this.setState({ description: removeExtraLineBreaks(text), dirty: true, detecting: false })) | ||||||
|  |       .catch(() => this.setState({ detecting: false })); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|   render () { |   render () { | ||||||
|     const { media, intl, onClose } = this.props; |     const { media, intl, onClose } = this.props; | ||||||
|     const { x, y, dragging, description, dirty } = this.state; |     const { x, y, dragging, description, dirty, detecting, progress } = this.state; | ||||||
| 
 | 
 | ||||||
|     const width  = media.getIn(['meta', 'original', 'width']) || null; |     const width  = media.getIn(['meta', 'original', 'width']) || null; | ||||||
|     const height = media.getIn(['meta', 'original', 'height']) || null; |     const height = media.getIn(['meta', 'original', 'height']) || null; | ||||||
|  | @ -158,15 +188,27 @@ class FocalPointModal extends ImmutablePureComponent { | ||||||
| 
 | 
 | ||||||
|             <label className='setting-text-label' htmlFor='upload-modal__description'><FormattedMessage id='upload_form.description' defaultMessage='Describe for the visually impaired' /></label> |             <label className='setting-text-label' htmlFor='upload-modal__description'><FormattedMessage id='upload_form.description' defaultMessage='Describe for the visually impaired' /></label> | ||||||
| 
 | 
 | ||||||
|             <textarea |             <div className='setting-text__wrapper'> | ||||||
|  |               <Textarea | ||||||
|                 id='upload-modal__description' |                 id='upload-modal__description' | ||||||
|                 className='setting-text light' |                 className='setting-text light' | ||||||
|               value={description} |                 value={detecting ? '…' : description} | ||||||
|                 onChange={this.handleChange} |                 onChange={this.handleChange} | ||||||
|  |                 disabled={detecting} | ||||||
|                 autoFocus |                 autoFocus | ||||||
|               /> |               /> | ||||||
| 
 | 
 | ||||||
|             <Button disabled={!dirty} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> |               <div className='setting-text__modifiers'> | ||||||
|  |                 <UploadProgress progress={progress * 100} active={detecting} icon='file-text-o' message={<FormattedMessage id='upload_modal.analyzing_picture' defaultMessage='Analyzing picture…' />} /> | ||||||
|  |               </div> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <div className='setting-text__toolbar'> | ||||||
|  |               <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> | ||||||
|  |               <CharacterCounter max={420} text={detecting ? '' : description} /> | ||||||
|  |             </div> | ||||||
|  | 
 | ||||||
|  |             <Button disabled={!dirty || detecting || length(description) > 420} text={intl.formatMessage(messages.apply)} onClick={this.handleSubmit} /> | ||||||
|           </div> |           </div> | ||||||
| 
 | 
 | ||||||
|           <div className='report-modal__statuses'> |           <div className='report-modal__statuses'> | ||||||
|  |  | ||||||
|  | @ -3,6 +3,27 @@ | ||||||
|   -ms-overflow-style: -ms-autohiding-scrollbar; |   -ms-overflow-style: -ms-autohiding-scrollbar; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .link-button { | ||||||
|  |   display: block; | ||||||
|  |   font-size: 15px; | ||||||
|  |   line-height: 20px; | ||||||
|  |   color: $ui-highlight-color; | ||||||
|  |   border: 0; | ||||||
|  |   background: transparent; | ||||||
|  |   padding: 0; | ||||||
|  |   cursor: pointer; | ||||||
|  | 
 | ||||||
|  |   &:hover, | ||||||
|  |   &:active { | ||||||
|  |     text-decoration: underline; | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   &:disabled { | ||||||
|  |     color: $ui-primary-color; | ||||||
|  |     cursor: default; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .button { | .button { | ||||||
|   background-color: $ui-highlight-color; |   background-color: $ui-highlight-color; | ||||||
|   border: 10px none; |   border: 10px none; | ||||||
|  | @ -637,18 +658,6 @@ | ||||||
|     .character-counter__wrapper { |     .character-counter__wrapper { | ||||||
|       align-self: center; |       align-self: center; | ||||||
|       margin-right: 4px; |       margin-right: 4px; | ||||||
| 
 |  | ||||||
|       .character-counter { |  | ||||||
|         cursor: default; |  | ||||||
|         font-family: $font-sans-serif, sans-serif; |  | ||||||
|         font-size: 14px; |  | ||||||
|         font-weight: 600; |  | ||||||
|         color: $lighter-text-color; |  | ||||||
| 
 |  | ||||||
|         &.character-counter--over { |  | ||||||
|           color: $warning-red; |  | ||||||
|         } |  | ||||||
|       } |  | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|  | @ -665,6 +674,18 @@ | ||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | .character-counter { | ||||||
|  |   cursor: default; | ||||||
|  |   font-family: $font-sans-serif, sans-serif; | ||||||
|  |   font-size: 14px; | ||||||
|  |   font-weight: 600; | ||||||
|  |   color: $lighter-text-color; | ||||||
|  | 
 | ||||||
|  |   &.character-counter--over { | ||||||
|  |     color: $warning-red; | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
| .no-reduce-motion .spoiler-input { | .no-reduce-motion .spoiler-input { | ||||||
|   transition: height 0.4s ease, opacity 0.4s ease; |   transition: height 0.4s ease, opacity 0.4s ease; | ||||||
| } | } | ||||||
|  | @ -4555,16 +4576,48 @@ a.status-card.compact:hover { | ||||||
|     padding: 10px; |     padding: 10px; | ||||||
|     font-family: inherit; |     font-family: inherit; | ||||||
|     font-size: 14px; |     font-size: 14px; | ||||||
|     resize: vertical; |     resize: none; | ||||||
|     border: 0; |     border: 0; | ||||||
|     outline: 0; |     outline: 0; | ||||||
|     border-radius: 4px; |     border-radius: 4px; | ||||||
|     border: 1px solid $ui-secondary-color; |     border: 1px solid $ui-secondary-color; | ||||||
|     margin-bottom: 20px; |     min-height: 100px; | ||||||
|  |     max-height: 50vh; | ||||||
|  |     margin-bottom: 10px; | ||||||
| 
 | 
 | ||||||
|     &:focus { |     &:focus { | ||||||
|       border: 1px solid darken($ui-secondary-color, 8%); |       border: 1px solid darken($ui-secondary-color, 8%); | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     &__wrapper { | ||||||
|  |       background: $white; | ||||||
|  |       border: 1px solid $ui-secondary-color; | ||||||
|  |       margin-bottom: 10px; | ||||||
|  |       border-radius: 4px; | ||||||
|  | 
 | ||||||
|  |       .setting-text { | ||||||
|  |         border: 0; | ||||||
|  |         margin-bottom: 0; | ||||||
|  |         border-radius: 0; | ||||||
|  | 
 | ||||||
|  |         &:focus { | ||||||
|  |           border: 0; | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       &__modifiers { | ||||||
|  |         color: $inverted-text-color; | ||||||
|  |         font-family: inherit; | ||||||
|  |         font-size: 14px; | ||||||
|  |         background: $white; | ||||||
|  |       } | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     &__toolbar { | ||||||
|  |       display: flex; | ||||||
|  |       justify-content: space-between; | ||||||
|  |       margin-bottom: 20px; | ||||||
|  |     } | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   .setting-text-label { |   .setting-text-label { | ||||||
|  |  | ||||||
|  | @ -20,11 +20,11 @@ Rails.application.config.content_security_policy do |p| | ||||||
|   if Rails.env.development? |   if Rails.env.development? | ||||||
|     webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" } |     webpacker_urls = %w(ws http).map { |protocol| "#{protocol}#{Webpacker.dev_server.https? ? 's' : ''}://#{Webpacker.dev_server.host_with_port}" } | ||||||
| 
 | 
 | ||||||
|     p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls |     p.connect_src :self, :data, :blob, assets_host, Rails.configuration.x.streaming_api_base_url, *webpacker_urls | ||||||
|     p.script_src  :self, :unsafe_inline, :unsafe_eval, assets_host |     p.script_src  :self, :blob, :unsafe_inline, :unsafe_eval, assets_host | ||||||
|   else |   else | ||||||
|     p.connect_src :self, :blob, assets_host, Rails.configuration.x.streaming_api_base_url |     p.connect_src :self, :data, :blob, assets_host, Rails.configuration.x.streaming_api_base_url | ||||||
|     p.script_src  :self, assets_host |     p.script_src  :self, :blob, assets_host | ||||||
|   end |   end | ||||||
| end | end | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -56,5 +56,6 @@ module.exports = merge(sharedConfig, { | ||||||
|       settings.dev_server.watch_options, |       settings.dev_server.watch_options, | ||||||
|       watchOptions |       watchOptions | ||||||
|     ), |     ), | ||||||
|  |     writeToDisk: filePath => /ocr/.test(filePath), | ||||||
|   }, |   }, | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ const { basename, dirname, join, relative, resolve } = require('path'); | ||||||
| const { sync } = require('glob'); | const { sync } = require('glob'); | ||||||
| const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | const MiniCssExtractPlugin = require('mini-css-extract-plugin'); | ||||||
| const AssetsManifestPlugin = require('webpack-assets-manifest'); | const AssetsManifestPlugin = require('webpack-assets-manifest'); | ||||||
|  | const CopyPlugin = require('copy-webpack-plugin'); | ||||||
| const extname = require('path-complete-extname'); | const extname = require('path-complete-extname'); | ||||||
| const { env, settings, themes, output } = require('./configuration'); | const { env, settings, themes, output } = require('./configuration'); | ||||||
| const rules = require('./rules'); | const rules = require('./rules'); | ||||||
|  | @ -84,6 +85,10 @@ module.exports = { | ||||||
|       writeToDisk: true, |       writeToDisk: true, | ||||||
|       publicPath: true, |       publicPath: true, | ||||||
|     }), |     }), | ||||||
|  |     new CopyPlugin([ | ||||||
|  |       { from: 'node_modules/tesseract.js/dist/worker.min.js', to: 'ocr' }, | ||||||
|  |       { from: 'node_modules/tesseract.js-core/tesseract-core.wasm.js', to: 'ocr' }, | ||||||
|  |     ]), | ||||||
|   ], |   ], | ||||||
| 
 | 
 | ||||||
|   resolve: { |   resolve: { | ||||||
|  |  | ||||||
|  | @ -84,6 +84,7 @@ | ||||||
|     "blurhash": "^1.0.0", |     "blurhash": "^1.0.0", | ||||||
|     "classnames": "^2.2.5", |     "classnames": "^2.2.5", | ||||||
|     "compression-webpack-plugin": "^3.0.0", |     "compression-webpack-plugin": "^3.0.0", | ||||||
|  |     "copy-webpack-plugin": "^5.0.4", | ||||||
|     "cross-env": "^5.1.4", |     "cross-env": "^5.1.4", | ||||||
|     "css-loader": "^3.2.0", |     "css-loader": "^3.2.0", | ||||||
|     "cssnano": "^4.1.10", |     "cssnano": "^4.1.10", | ||||||
|  | @ -155,6 +156,7 @@ | ||||||
|     "stringz": "^2.0.0", |     "stringz": "^2.0.0", | ||||||
|     "substring-trie": "^1.0.2", |     "substring-trie": "^1.0.2", | ||||||
|     "terser-webpack-plugin": "^1.4.1", |     "terser-webpack-plugin": "^1.4.1", | ||||||
|  |     "tesseract.js": "^2.0.0-alpha.13", | ||||||
|     "throng": "^4.0.0", |     "throng": "^4.0.0", | ||||||
|     "tiny-queue": "^0.2.1", |     "tiny-queue": "^0.2.1", | ||||||
|     "uuid": "^3.1.0", |     "uuid": "^3.1.0", | ||||||
|  |  | ||||||
							
								
								
									
										
											BIN
										
									
								
								public/ocr/lang-data/eng.traineddata.gz
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/ocr/lang-data/eng.traineddata.gz
									
										
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										140
									
								
								yarn.lock
									
										
									
									
									
								
							
							
						
						
									
										140
									
								
								yarn.lock
									
										
									
									
									
								
							|  | @ -1727,6 +1727,14 @@ aws4@^1.8.0: | ||||||
|   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" |   resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" | ||||||
|   integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== |   integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== | ||||||
| 
 | 
 | ||||||
|  | axios@^0.18.0: | ||||||
|  |   version "0.18.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/axios/-/axios-0.18.1.tgz#ff3f0de2e7b5d180e757ad98000f1081b87bcea3" | ||||||
|  |   integrity sha512-0BfJq4NSfQXd+SkFdrvFbG7addhYSBA2mQwISr46pD6E5iqkWg02RAs8vyTT/j0RTnoYmeXauBuSv1qKwR179g== | ||||||
|  |   dependencies: | ||||||
|  |     follow-redirects "1.5.10" | ||||||
|  |     is-buffer "^2.0.2" | ||||||
|  | 
 | ||||||
| axios@^0.19.0: | axios@^0.19.0: | ||||||
|   version "0.19.0" |   version "0.19.0" | ||||||
|   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" |   resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" | ||||||
|  | @ -1975,6 +1983,11 @@ blurhash@^1.0.0: | ||||||
|   resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.0.0.tgz#9087bc5cc4d482f1305059d7410df4133adcab2e" |   resolved "https://registry.yarnpkg.com/blurhash/-/blurhash-1.0.0.tgz#9087bc5cc4d482f1305059d7410df4133adcab2e" | ||||||
|   integrity sha512-x6fpZnd6AWde4U9m7xhUB44qIvGV4W6OdTAXGabYm4oZUOOGh5K1HAEoGAQn3iG4gbbPn9RSGce3VfNgGsX/Vw== |   integrity sha512-x6fpZnd6AWde4U9m7xhUB44qIvGV4W6OdTAXGabYm4oZUOOGh5K1HAEoGAQn3iG4gbbPn9RSGce3VfNgGsX/Vw== | ||||||
| 
 | 
 | ||||||
|  | bmp-js@^0.1.0: | ||||||
|  |   version "0.1.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/bmp-js/-/bmp-js-0.1.0.tgz#e05a63f796a6c1ff25f4771ec7adadc148c07233" | ||||||
|  |   integrity sha1-4Fpj95amwf8l9Hcex62twUjAcjM= | ||||||
|  | 
 | ||||||
| bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: | bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: | ||||||
|   version "4.11.8" |   version "4.11.8" | ||||||
|   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" |   resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" | ||||||
|  | @ -2212,6 +2225,26 @@ cacache@^11.2.0: | ||||||
|     unique-filename "^1.1.1" |     unique-filename "^1.1.1" | ||||||
|     y18n "^4.0.0" |     y18n "^4.0.0" | ||||||
| 
 | 
 | ||||||
|  | cacache@^11.3.3: | ||||||
|  |   version "11.3.3" | ||||||
|  |   resolved "https://registry.yarnpkg.com/cacache/-/cacache-11.3.3.tgz#8bd29df8c6a718a6ebd2d010da4d7972ae3bbadc" | ||||||
|  |   integrity sha512-p8WcneCytvzPxhDvYp31PD039vi77I12W+/KfR9S8AZbaiARFBCpsPJS+9uhWfeBfeAtW7o/4vt3MUqLkbY6nA== | ||||||
|  |   dependencies: | ||||||
|  |     bluebird "^3.5.5" | ||||||
|  |     chownr "^1.1.1" | ||||||
|  |     figgy-pudding "^3.5.1" | ||||||
|  |     glob "^7.1.4" | ||||||
|  |     graceful-fs "^4.1.15" | ||||||
|  |     lru-cache "^5.1.1" | ||||||
|  |     mississippi "^3.0.0" | ||||||
|  |     mkdirp "^0.5.1" | ||||||
|  |     move-concurrently "^1.0.1" | ||||||
|  |     promise-inflight "^1.0.1" | ||||||
|  |     rimraf "^2.6.3" | ||||||
|  |     ssri "^6.0.1" | ||||||
|  |     unique-filename "^1.1.1" | ||||||
|  |     y18n "^4.0.0" | ||||||
|  | 
 | ||||||
| cacache@^12.0.2: | cacache@^12.0.2: | ||||||
|   version "12.0.2" |   version "12.0.2" | ||||||
|   resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c" |   resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.2.tgz#8db03205e36089a3df6954c66ce92541441ac46c" | ||||||
|  | @ -2341,7 +2374,7 @@ chardet@^0.7.0: | ||||||
|   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" |   resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" | ||||||
|   integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== |   integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== | ||||||
| 
 | 
 | ||||||
| check-types@^7.3.0: | check-types@^7.3.0, check-types@^7.4.0: | ||||||
|   version "7.4.0" |   version "7.4.0" | ||||||
|   resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" |   resolved "https://registry.yarnpkg.com/check-types/-/check-types-7.4.0.tgz#0378ec1b9616ec71f774931a3c6516fad8c152f4" | ||||||
|   integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg== |   integrity sha512-YbulWHdfP99UfZ73NcUDlNJhEIDgm9Doq9GhpyXbF+7Aegi3CVV7qqMCKTTqJxlvEvnQBp9IA+dxsGN6xK/nSg== | ||||||
|  | @ -2691,6 +2724,24 @@ copy-descriptor@^0.1.0: | ||||||
|   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" |   resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" | ||||||
|   integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= |   integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= | ||||||
| 
 | 
 | ||||||
|  | copy-webpack-plugin@^5.0.4: | ||||||
|  |   version "5.0.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-5.0.4.tgz#c78126f604e24f194c6ec2f43a64e232b5d43655" | ||||||
|  |   integrity sha512-YBuYGpSzoCHSSDGyHy6VJ7SHojKp6WHT4D7ItcQFNAYx2hrwkMe56e97xfVR0/ovDuMTrMffXUiltvQljtAGeg== | ||||||
|  |   dependencies: | ||||||
|  |     cacache "^11.3.3" | ||||||
|  |     find-cache-dir "^2.1.0" | ||||||
|  |     glob-parent "^3.1.0" | ||||||
|  |     globby "^7.1.1" | ||||||
|  |     is-glob "^4.0.1" | ||||||
|  |     loader-utils "^1.2.3" | ||||||
|  |     minimatch "^3.0.4" | ||||||
|  |     normalize-path "^3.0.0" | ||||||
|  |     p-limit "^2.2.0" | ||||||
|  |     schema-utils "^1.0.0" | ||||||
|  |     serialize-javascript "^1.7.0" | ||||||
|  |     webpack-log "^2.0.0" | ||||||
|  | 
 | ||||||
| core-js-compat@^3.1.1: | core-js-compat@^3.1.1: | ||||||
|   version "3.1.3" |   version "3.1.3" | ||||||
|   resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.3.tgz#0cc3ba4c7f62928c2837e1cffbe8dc78b4f1ae14" |   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: | ||||||
|     miller-rabin "^4.0.0" |     miller-rabin "^4.0.0" | ||||||
|     randombytes "^2.0.0" |     randombytes "^2.0.0" | ||||||
| 
 | 
 | ||||||
|  | dir-glob@^2.0.0: | ||||||
|  |   version "2.2.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" | ||||||
|  |   integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== | ||||||
|  |   dependencies: | ||||||
|  |     path-type "^3.0.0" | ||||||
|  | 
 | ||||||
| discontinuous-range@1.0.0: | discontinuous-range@1.0.0: | ||||||
|   version "1.0.0" |   version "1.0.0" | ||||||
|   resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" |   resolved "https://registry.yarnpkg.com/discontinuous-range/-/discontinuous-range-1.0.0.tgz#e38331f0844bba49b9a9cb71c771585aab1bc65a" | ||||||
|  | @ -4222,6 +4280,11 @@ file-loader@^4.1.0: | ||||||
|     loader-utils "^1.2.3" |     loader-utils "^1.2.3" | ||||||
|     schema-utils "^2.0.0" |     schema-utils "^2.0.0" | ||||||
| 
 | 
 | ||||||
|  | file-type@^10.5.0: | ||||||
|  |   version "10.11.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.11.0.tgz#2961d09e4675b9fb9a3ee6b69e9cd23f43fd1890" | ||||||
|  |   integrity sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw== | ||||||
|  | 
 | ||||||
| filesize@^3.6.1: | filesize@^3.6.1: | ||||||
|   version "3.6.1" |   version "3.6.1" | ||||||
|   resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" |   resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.6.1.tgz#090bb3ee01b6f801a8a8be99d31710b3422bb317" | ||||||
|  | @ -4644,6 +4707,18 @@ globby@^6.1.0: | ||||||
|     pify "^2.0.0" |     pify "^2.0.0" | ||||||
|     pinkie-promise "^2.0.0" |     pinkie-promise "^2.0.0" | ||||||
| 
 | 
 | ||||||
|  | globby@^7.1.1: | ||||||
|  |   version "7.1.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" | ||||||
|  |   integrity sha1-+yzP+UAfhgCUXfral0QMypcrhoA= | ||||||
|  |   dependencies: | ||||||
|  |     array-union "^1.0.1" | ||||||
|  |     dir-glob "^2.0.0" | ||||||
|  |     glob "^7.1.2" | ||||||
|  |     ignore "^3.3.5" | ||||||
|  |     pify "^3.0.0" | ||||||
|  |     slash "^1.0.0" | ||||||
|  | 
 | ||||||
| globule@^1.0.0: | globule@^1.0.0: | ||||||
|   version "1.2.1" |   version "1.2.1" | ||||||
|   resolved "https://registry.yarnpkg.com/globule/-/globule-1.2.1.tgz#5dffb1b191f22d20797a9369b49eab4e9839696d" |   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: | ||||||
|   dependencies: |   dependencies: | ||||||
|     postcss "^7.0.14" |     postcss "^7.0.14" | ||||||
| 
 | 
 | ||||||
|  | idb-keyval@^3.1.0: | ||||||
|  |   version "3.2.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-3.2.0.tgz#cbbf354deb5684b6cdc84376294fc05932845bd6" | ||||||
|  |   integrity sha512-slx8Q6oywCCSfKgPgL0sEsXtPVnSbTLWpyiDcu6msHOyKOLari1TD1qocXVCft80umnkk3/Qqh3lwoFt8T/BPQ== | ||||||
|  | 
 | ||||||
| ieee754@^1.1.4: | ieee754@^1.1.4: | ||||||
|   version "1.1.12" |   version "1.1.12" | ||||||
|   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" |   resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" | ||||||
|  | @ -4998,7 +5078,7 @@ ignore-walk@^3.0.1: | ||||||
|   dependencies: |   dependencies: | ||||||
|     minimatch "^3.0.4" |     minimatch "^3.0.4" | ||||||
| 
 | 
 | ||||||
| ignore@^3.1.2: | ignore@^3.1.2, ignore@^3.3.5: | ||||||
|   version "3.3.10" |   version "3.3.10" | ||||||
|   resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" |   resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" | ||||||
|   integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== |   integrity sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug== | ||||||
|  | @ -5540,6 +5620,16 @@ is-typedarray@~1.0.0: | ||||||
|   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" |   resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" | ||||||
|   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= |   integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= | ||||||
| 
 | 
 | ||||||
|  | is-url@1.2.2: | ||||||
|  |   version "1.2.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.2.tgz#498905a593bf47cc2d9e7f738372bbf7696c7f26" | ||||||
|  |   integrity sha1-SYkFpZO/R8wtnn9zg3K792lsfyY= | ||||||
|  | 
 | ||||||
|  | is-url@^1.2.4: | ||||||
|  |   version "1.2.4" | ||||||
|  |   resolved "https://registry.yarnpkg.com/is-url/-/is-url-1.2.4.tgz#04a4df46d28c4cff3d73d01ff06abeb318a1aa52" | ||||||
|  |   integrity sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww== | ||||||
|  | 
 | ||||||
| is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: | is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: | ||||||
|   version "1.0.2" |   version "1.0.2" | ||||||
|   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" |   resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" | ||||||
|  | @ -6818,6 +6908,11 @@ node-fetch@^1.0.1: | ||||||
|     encoding "^0.1.11" |     encoding "^0.1.11" | ||||||
|     is-stream "^1.0.1" |     is-stream "^1.0.1" | ||||||
| 
 | 
 | ||||||
|  | node-fetch@^2.3.0: | ||||||
|  |   version "2.6.0" | ||||||
|  |   resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" | ||||||
|  |   integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== | ||||||
|  | 
 | ||||||
| node-forge@0.7.5: | node-forge@0.7.5: | ||||||
|   version "0.7.5" |   version "0.7.5" | ||||||
|   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" |   resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.7.5.tgz#6c152c345ce11c52f465c2abd957e8639cd674df" | ||||||
|  | @ -7157,6 +7252,11 @@ onetime@^2.0.0: | ||||||
|   dependencies: |   dependencies: | ||||||
|     mimic-fn "^1.0.0" |     mimic-fn "^1.0.0" | ||||||
| 
 | 
 | ||||||
|  | opencollective-postinstall@^2.0.2: | ||||||
|  |   version "2.0.2" | ||||||
|  |   resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz#5657f1bede69b6e33a45939b061eb53d3c6c3a89" | ||||||
|  |   integrity sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw== | ||||||
|  | 
 | ||||||
| opener@^1.5.1: | opener@^1.5.1: | ||||||
|   version "1.5.1" |   version "1.5.1" | ||||||
|   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" |   resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.1.tgz#6d2f0e77f1a0af0032aca716c2c1fbb8e7e8abed" | ||||||
|  | @ -9864,6 +9964,37 @@ terser@^4.1.2: | ||||||
|     source-map "~0.6.1" |     source-map "~0.6.1" | ||||||
|     source-map-support "~0.5.12" |     source-map-support "~0.5.12" | ||||||
| 
 | 
 | ||||||
|  | tesseract.js-core@^2.0.0-beta.10: | ||||||
|  |   version "2.0.0-beta.10" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tesseract.js-core/-/tesseract.js-core-2.0.0-beta.10.tgz#b8f0dd2be4686650c4350f648900adccfaf58d6b" | ||||||
|  |   integrity sha512-QmNgMA9m5ES5uMTqpOAPysrUA80vUx/6WKQlfkK3zhOeAgqv8DjwwcDv9tQv2TgRzOQ+LFKrJn94Y2rw5b2IGw== | ||||||
|  | 
 | ||||||
|  | tesseract.js-utils@^1.0.0-beta.8: | ||||||
|  |   version "1.0.0-beta.8" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tesseract.js-utils/-/tesseract.js-utils-1.0.0-beta.8.tgz#d1ef25c12609a337c3e0ac12a33f9903f3145a68" | ||||||
|  |   integrity sha512-qjHBfWfzo2o1ZY9XI0Wh2hmpp38+mIgCMOk60W5Yyie/pBl421VLBKOZUEwQgpbLnOJ24VU6Q8yXsVgtFFHcFg== | ||||||
|  |   dependencies: | ||||||
|  |     axios "^0.18.0" | ||||||
|  |     bmp-js "^0.1.0" | ||||||
|  |     file-type "^10.5.0" | ||||||
|  |     idb-keyval "^3.1.0" | ||||||
|  |     is-url "^1.2.4" | ||||||
|  |     zlibjs "^0.3.1" | ||||||
|  | 
 | ||||||
|  | tesseract.js@^2.0.0-alpha.13: | ||||||
|  |   version "2.0.0-alpha.13" | ||||||
|  |   resolved "https://registry.yarnpkg.com/tesseract.js/-/tesseract.js-2.0.0-alpha.13.tgz#87bb3d71fe646c0993b073552241d203d9dfef3a" | ||||||
|  |   integrity sha512-ZFEdak7jWtN5vIDwZcw8OdAqA7RvG0QRailZKQFS5rtnl/Yy5vC4WcqfJh9+o+cA3bdr2zV5SENoWDtEihlSVA== | ||||||
|  |   dependencies: | ||||||
|  |     axios "^0.18.0" | ||||||
|  |     check-types "^7.4.0" | ||||||
|  |     is-url "1.2.2" | ||||||
|  |     node-fetch "^2.3.0" | ||||||
|  |     opencollective-postinstall "^2.0.2" | ||||||
|  |     resolve-url "^0.2.1" | ||||||
|  |     tesseract.js-core "^2.0.0-beta.10" | ||||||
|  |     tesseract.js-utils "^1.0.0-beta.8" | ||||||
|  | 
 | ||||||
| test-exclude@^5.0.0: | test-exclude@^5.0.0: | ||||||
|   version "5.1.0" |   version "5.1.0" | ||||||
|   resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" |   resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-5.1.0.tgz#6ba6b25179d2d38724824661323b73e03c0c1de1" | ||||||
|  | @ -10726,3 +10857,8 @@ yargs@^13.3.0: | ||||||
|     which-module "^2.0.0" |     which-module "^2.0.0" | ||||||
|     y18n "^4.0.0" |     y18n "^4.0.0" | ||||||
|     yargs-parser "^13.1.1" |     yargs-parser "^13.1.1" | ||||||
|  | 
 | ||||||
|  | zlibjs@^0.3.1: | ||||||
|  |   version "0.3.1" | ||||||
|  |   resolved "https://registry.yarnpkg.com/zlibjs/-/zlibjs-0.3.1.tgz#50197edb28a1c42ca659cc8b4e6a9ddd6d444554" | ||||||
|  |   integrity sha1-UBl+2yihxCymWcyLTmqd3W1ERVQ= | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue