diff --git a/browser/components/CodeEditor.js b/browser/components/CodeEditor.js
index 88fe00b4..92de0540 100644
--- a/browser/components/CodeEditor.js
+++ b/browser/components/CodeEditor.js
@@ -21,6 +21,8 @@ const buildEditorContextMenu = require('browser/lib/contextMenuBuilder')
import { createTurndownService } from '../lib/turndown'
import { languageMaps } from '../lib/CMLanguageList'
import snippetManager from '../lib/SnippetManager'
+import { findStorage } from 'browser/lib/findStorage'
+import { sendWakatimeHeartBeat } from 'browser/lib/wakatime-plugin'
import {
generateInEditor,
tocExistsInEditor
@@ -113,6 +115,16 @@ export default class CodeEditor extends React.Component {
this.editorActivityHandler = () => this.handleEditorActivity()
this.turndownService = createTurndownService()
+
+ // wakatime
+ const { storageKey, noteKey } = this.props
+ const storage = findStorage(storageKey)
+ if (storage)
+ sendWakatimeHeartBeat(storage.path, noteKey, storage.name, {
+ isWrite: false,
+ hasFileChanges: false,
+ isFileChange: true
+ })
}
handleSearch(msg) {
@@ -801,9 +813,23 @@ export default class CodeEditor extends React.Component {
this.updateHighlight(editor, changeObject)
this.value = editor.getValue()
+
+ const { storageKey, noteKey } = this.props
+ const storage = findStorage(storageKey)
if (this.props.onChange) {
this.props.onChange(editor)
}
+
+ const isWrite = !!this.props.onChange
+ const hasFileChanges = isWrite
+
+ if (storage) {
+ sendWakatimeHeartBeat(storage.path, noteKey, storage.name, {
+ isWrite,
+ hasFileChanges,
+ isFileChange: false
+ })
+ }
}
linePossibleContainsHeadline(currentLine) {
@@ -931,6 +957,16 @@ export default class CodeEditor extends React.Component {
this.restartHighlighting()
this.editor.on('change', this.changeHandler)
this.editor.refresh()
+
+ // wakatime
+ const { storageKey, noteKey } = this.props
+ const storage = findStorage(storageKey)
+ if (storage)
+ sendWakatimeHeartBeat(storage.path, noteKey, storage.name, {
+ isWrite: false,
+ hasFileChanges: false,
+ isFileChange: true
+ })
}
setValue(value) {
diff --git a/browser/components/MarkdownPreview.js b/browser/components/MarkdownPreview.js
index 9ddea318..96b7e065 100755
--- a/browser/components/MarkdownPreview.js
+++ b/browser/components/MarkdownPreview.js
@@ -1192,7 +1192,10 @@ class MarkdownPreview extends React.Component {
e.preventDefault()
e.stopPropagation()
- const rawHref = e.target.getAttribute('href')
+ const el = e.target.closest('a[href]')
+ if (!el) return
+
+ const rawHref = el.getAttribute('href')
const { dispatch } = this.props
if (!rawHref) return // not checked href because parser will create file://... string for [empty link]()
diff --git a/browser/components/render/MermaidRender.js b/browser/components/render/MermaidRender.js
index d397d03b..4f0e774a 100644
--- a/browser/components/render/MermaidRender.js
+++ b/browser/components/render/MermaidRender.js
@@ -1,4 +1,4 @@
-import mermaidAPI from 'mermaid'
+import mermaidAPI from 'mermaid/dist/mermaid.min.js'
import uiThemes from 'browser/lib/ui-themes'
// fixes bad styling in the mermaid dark theme
@@ -61,7 +61,6 @@ function render(element, content, theme, enableHTMLLabel) {
el.setAttribute('ratio', ratio)
el.setAttribute('height', el.parentNode.clientWidth / ratio)
- console.log(el)
}
})
} catch (e) {
diff --git a/browser/lib/wakatime-plugin.js b/browser/lib/wakatime-plugin.js
new file mode 100644
index 00000000..9b1233df
--- /dev/null
+++ b/browser/lib/wakatime-plugin.js
@@ -0,0 +1,49 @@
+import config from 'browser/main/lib/ConfigManager'
+const exec = require('child_process').exec
+const path = require('path')
+let lastHeartbeat = 0
+
+function sendWakatimeHeartBeat(
+ storagePath,
+ noteKey,
+ storageName,
+ { isWrite, hasFileChanges, isFileChange }
+) {
+ if (
+ config.get().wakatime.isActive &&
+ !!config.get().wakatime.key &&
+ (new Date().getTime() - lastHeartbeat > 120000 || isFileChange)
+ ) {
+ const notePath = path.join(storagePath, 'notes', noteKey + '.cson')
+
+ if (!isWrite && !hasFileChanges && !isFileChange) {
+ return
+ }
+
+ lastHeartbeat = new Date()
+ const wakatimeKey = config.get().wakatime.key
+ if (wakatimeKey) {
+ exec(
+ `wakatime --file ${notePath} --project '${storageName}' --key ${wakatimeKey} --plugin Boostnote-wakatime`,
+ (error, stdOut, stdErr) => {
+ if (error) {
+ console.log(error)
+ lastHeartbeat = 0
+ } else {
+ console.log(
+ 'wakatime',
+ 'isWrite',
+ isWrite,
+ 'hasChanges',
+ hasFileChanges,
+ 'isFileChange',
+ isFileChange
+ )
+ }
+ }
+ )
+ }
+ }
+}
+
+export { sendWakatimeHeartBeat }
diff --git a/browser/main/Detail/SnippetNoteDetail.js b/browser/main/Detail/SnippetNoteDetail.js
index 612308ba..ca7a8b3e 100644
--- a/browser/main/Detail/SnippetNoteDetail.js
+++ b/browser/main/Detail/SnippetNoteDetail.js
@@ -871,6 +871,8 @@ class SnippetNoteDetail extends React.Component {
hotkey={config.hotkey}
autoDetect={autoDetect}
dateFormatISO8601={config.editor.dateFormatISO8601}
+ storageKey={storageKey}
+ noteKey={note.key}
/>
)}
diff --git a/browser/main/lib/ConfigManager.js b/browser/main/lib/ConfigManager.js
index 84994028..4b6342d2 100644
--- a/browser/main/lib/ConfigManager.js
+++ b/browser/main/lib/ConfigManager.js
@@ -139,7 +139,10 @@ export const DEFAULT_CONFIG = {
username: '',
password: ''
},
- coloredTags: {}
+ coloredTags: {},
+ wakatime: {
+ key: null
+ }
}
function validate(config) {
@@ -255,6 +258,12 @@ function assignConfigValues(originalConfig, rcConfig) {
originalConfig.hotkey,
rcConfig.hotkey
)
+ config.wakatime = Object.assign(
+ {},
+ DEFAULT_CONFIG.wakatime,
+ originalConfig.wakatime,
+ rcConfig.wakatime
+ )
config.blog = Object.assign(
{},
DEFAULT_CONFIG.blog,
diff --git a/browser/main/lib/ThemeManager.js b/browser/main/lib/ThemeManager.js
index a1b090e9..599a61f2 100644
--- a/browser/main/lib/ThemeManager.js
+++ b/browser/main/lib/ThemeManager.js
@@ -1,4 +1,5 @@
import ConfigManager from 'browser/main/lib/ConfigManager'
+import uiThemes from 'browser/lib/ui-themes'
const saveChanges = newConfig => {
ConfigManager.set(newConfig)
@@ -40,14 +41,7 @@ const chooseTheme = config => {
}
const applyTheme = theme => {
- const supportedThemes = [
- 'dark',
- 'white',
- 'solarized-dark',
- 'monokai',
- 'dracula'
- ]
- if (supportedThemes.indexOf(theme) !== -1) {
+ if (uiThemes.some(item => item.name === theme)) {
document.body.setAttribute('data-theme', theme)
if (document.body.querySelector('.MarkdownPreview')) {
document.body
diff --git a/browser/main/modals/PreferencesModal/PluginsTab.js b/browser/main/modals/PreferencesModal/PluginsTab.js
new file mode 100644
index 00000000..ceaa383a
--- /dev/null
+++ b/browser/main/modals/PreferencesModal/PluginsTab.js
@@ -0,0 +1,207 @@
+import PropTypes from 'prop-types'
+import React from 'react'
+import CSSModules from 'browser/lib/CSSModules'
+import styles from './ConfigTab.styl'
+import ConfigManager from 'browser/main/lib/ConfigManager'
+import { store } from 'browser/main/store'
+import _ from 'lodash'
+import i18n from 'browser/lib/i18n'
+import { sync as commandExists } from 'command-exists'
+const electron = require('electron')
+const ipc = electron.ipcRenderer
+const { remote } = electron
+const { dialog } = remote
+class PluginsTab extends React.Component {
+ constructor(props) {
+ super(props)
+
+ this.state = {
+ config: props.config
+ }
+ }
+
+ componentDidMount() {
+ this.handleSettingDone = () => {
+ this.setState({
+ pluginsAlert: {
+ type: 'success',
+ message: i18n.__('Successfully applied!')
+ }
+ })
+ }
+ this.handleSettingError = err => {
+ this.setState({
+ pluginsAlert: {
+ type: 'error',
+ message:
+ err.message != null ? err.message : i18n.__('An error occurred!')
+ }
+ })
+ }
+ this.oldWakatimeConfig = this.state.config.wakatime
+ ipc.addListener('APP_SETTING_DONE', this.handleSettingDone)
+ ipc.addListener('APP_SETTING_ERROR', this.handleSettingError)
+ }
+
+ componentWillUnmount() {
+ ipc.removeListener('APP_SETTING_DONE', this.handleSettingDone)
+ ipc.removeListener('APP_SETTING_ERROR', this.handleSettingError)
+ }
+
+ checkWakatimePluginRequirement() {
+ const { wakatime } = this.state.config
+ if (wakatime.isActive && !commandExists('wakatime')) {
+ this.setState({
+ wakatimePluginAlert: {
+ type: i18n.__('Warning'),
+ message: i18n.__('Missing wakatime cli')
+ }
+ })
+
+ const alertConfig = {
+ type: 'warning',
+ message: i18n.__('Missing Wakatime CLI'),
+ detail: i18n.__(
+ `Please install Wakatime CLI to use Wakatime tracker feature.`
+ ),
+ buttons: [i18n.__('OK')]
+ }
+ dialog.showMessageBox(remote.getCurrentWindow(), alertConfig)
+ } else {
+ this.setState({
+ wakatimePluginAlert: null
+ })
+ }
+ }
+
+ handleSaveButtonClick(e) {
+ const newConfig = {
+ wakatime: {
+ isActive: this.state.config.wakatime.isActive,
+ key: this.state.config.wakatime.key
+ }
+ }
+
+ ConfigManager.set(newConfig)
+
+ store.dispatch({
+ type: 'SET_CONFIG',
+ config: newConfig
+ })
+ this.clearMessage()
+ this.props.haveToSave()
+ this.checkWakatimePluginRequirement()
+ }
+
+ handleIsWakatimePluginActiveChange(e) {
+ const { config } = this.state
+ config.wakatime.isActive = !config.wakatime.isActive
+ this.setState({
+ config
+ })
+ if (_.isEqual(this.oldWakatimeConfig.isActive, config.wakatime.isActive)) {
+ this.props.haveToSave()
+ } else {
+ this.props.haveToSave({
+ tab: 'Plugins',
+ type: 'warning',
+ message: i18n.__('Unsaved Changes!')
+ })
+ }
+ }
+
+ handleWakatimeKeyChange(e) {
+ const { config } = this.state
+ config.wakatime = {
+ isActive: true,
+ key: this.refs.wakatimeKey.value
+ }
+ this.setState({
+ config
+ })
+ if (_.isEqual(this.oldWakatimeConfig.key, config.wakatime.key)) {
+ this.props.haveToSave()
+ } else {
+ this.props.haveToSave({
+ tab: 'Plugins',
+ type: 'warning',
+ message: i18n.__('Unsaved Changes!')
+ })
+ }
+ }
+
+ clearMessage() {
+ _.debounce(() => {
+ this.setState({
+ pluginsAlert: null
+ })
+ }, 2000)()
+ }
+
+ render() {
+ const pluginsAlert = this.state.pluginsAlert
+ const pluginsAlertElement =
+ pluginsAlert != null ? (
+
{pluginsAlert.message}
+ ) : null
+
+ const wakatimeAlert = this.state.wakatimePluginAlert
+ const wakatimePluginAlertElement =
+ wakatimeAlert != null ? (
+ {wakatimeAlert.message}
+ ) : null
+
+ const { config } = this.state
+
+ return (
+
+
+
{i18n.__('Plugins')}
+
{i18n.__('Wakatime')}
+
+
+
+
+
{i18n.__('Wakatime key')}
+
+ this.handleWakatimeKeyChange(e)}
+ disabled={!config.wakatime.isActive}
+ ref='wakatimeKey'
+ value={config.wakatime.key}
+ type='text'
+ />
+ {wakatimePluginAlertElement}
+
+
+
+
+ {pluginsAlertElement}
+
+
+
+ )
+ }
+}
+
+PluginsTab.propTypes = {
+ dispatch: PropTypes.func,
+ haveToSave: PropTypes.func
+}
+
+export default CSSModules(PluginsTab, styles)
diff --git a/browser/main/modals/PreferencesModal/index.js b/browser/main/modals/PreferencesModal/index.js
index 2c14e6c7..36abd734 100644
--- a/browser/main/modals/PreferencesModal/index.js
+++ b/browser/main/modals/PreferencesModal/index.js
@@ -7,6 +7,7 @@ import InfoTab from './InfoTab'
import Crowdfunding from './Crowdfunding'
import StoragesTab from './StoragesTab'
import SnippetTab from './SnippetTab'
+import PluginsTab from './PluginsTab'
import Blog from './Blog'
import ModalEscButton from 'browser/components/ModalEscButton'
import CSSModules from 'browser/lib/CSSModules'
@@ -82,6 +83,14 @@ class Preferences extends React.Component {
)
case 'SNIPPET':
return
+ case 'PLUGINS':
+ return (
+ this.setState({ PluginsAlert: alert })}
+ />
+ )
case 'STORAGES':
default:
return (
@@ -122,7 +131,8 @@ class Preferences extends React.Component {
{ target: 'INFO', label: i18n.__('About') },
{ target: 'CROWDFUNDING', label: i18n.__('Crowdfunding') },
{ target: 'BLOG', label: i18n.__('Blog'), Blog: this.state.BlogAlert },
- { target: 'SNIPPET', label: i18n.__('Snippets') }
+ { target: 'SNIPPET', label: i18n.__('Snippets') },
+ { target: 'PLUGINS', label: i18n.__('Plugins') }
]
const navButtons = tabs.map(tab => {
diff --git a/package.json b/package.json
index 0682c1bb..ae848053 100644
--- a/package.json
+++ b/package.json
@@ -61,6 +61,7 @@
"chart.js": "^2.7.2",
"codemirror": "^5.40.2",
"codemirror-mode-elixir": "^1.1.1",
+ "command-exists": "^1.2.9",
"connected-react-router": "^6.4.0",
"electron-config": "^1.0.0",
"electron-gh-releases": "^2.0.4",
@@ -79,7 +80,7 @@
"js-yaml": "^3.13.1",
"jsonlint-mod": "^1.7.4",
"katex": "^0.10.1",
- "lodash": "^4.17.13",
+ "lodash": "^4.17.19",
"lodash-move": "^1.1.1",
"markdown-it": "^6.0.1",
"markdown-it-abbr": "^1.0.4",
@@ -95,7 +96,7 @@
"markdown-it-sup": "^1.0.0",
"markdown-toc": "^1.2.0",
"mdurl": "^1.0.1",
- "mermaid": "^8.4.2",
+ "mermaid": "^8.5.2",
"moment": "^2.10.3",
"mousetrap": "^1.6.2",
"mousetrap-global-bind": "^1.1.0",
diff --git a/prettier.config b/prettier.config
index 66e7e941..515c6cd5 100644
--- a/prettier.config
+++ b/prettier.config
@@ -1,6 +1,5 @@
{
- "trailingComma": "es5",
- "tabWidth": 2,
+ "singleQuote": true,
"semi": false,
- "singleQuote": true
+ "jsxSingleQuote": true
}
\ No newline at end of file
diff --git a/readme.md b/readme.md
index 63c78f19..dffd9676 100644
--- a/readme.md
+++ b/readme.md
@@ -1,10 +1,10 @@
> [We've launched desktop and mobile app of the new Boost Note now.](https://github.com/BoostIO/BoostNote.next)
-> ### [Boost Note for Teams](https://hub.boostio.co/)
+> ### [Boost Note for Teams](https://boosthub.io/)
>
-> We'll launch the clean and simple wiki specially optimized for developers called "Boost Hub" at June 2020!
+> We've developed a collaborative workspace app called "Boost Hub" for developer teams.
>
-> Boost Hub will aim to be a collaborative wiki tool for teams to centralize and amplify the availability and search ability of both first-party and third-party information.
+> It's customizable and easy to optimize for your team like rego blocks and even lets you edit documents together in real-time!

@@ -53,6 +53,10 @@ Issues on Boostnote can be funded by anyone and the money will be distributed to
- [Blog](https://medium.com/boostnote)
- [Reddit](https://www.reddit.com/r/Boostnote/)
+### Boostnote mobile
+A community project developing a mobile cross-platform version of boostnote for iOS and Android can be found here: [NoteApp](https://github.com/T0M0F/NoteApp)
+
+
#### More Information
- Website: https://boostnote.io
diff --git a/yarn.lock b/yarn.lock
index 27221ff9..df0fdf70 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1966,6 +1966,11 @@ combined-stream@1.0.6, combined-stream@~1.0.5:
dependencies:
delayed-stream "~1.0.0"
+command-exists@^1.2.9:
+ version "1.2.9"
+ resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69"
+ integrity sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==
+
commander@2:
version "2.16.0"
resolved "http://registry.npm.taobao.org/commander/download/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50"
@@ -2583,7 +2588,44 @@ d3-zoom@1:
d3-selection "1"
d3-transition "1"
-d3@^5.12, d3@^5.7.0:
+d3@^5.14:
+ version "5.16.0"
+ resolved "https://registry.yarnpkg.com/d3/-/d3-5.16.0.tgz#9c5e8d3b56403c79d4ed42fbd62f6113f199c877"
+ integrity sha512-4PL5hHaHwX4m7Zr1UapXW23apo6pexCgdetdJ5kTmADpG/7T9Gkxw0M0tf/pjoB63ezCCm0u5UaFYy2aMt0Mcw==
+ dependencies:
+ d3-array "1"
+ d3-axis "1"
+ d3-brush "1"
+ d3-chord "1"
+ d3-collection "1"
+ d3-color "1"
+ d3-contour "1"
+ d3-dispatch "1"
+ d3-drag "1"
+ d3-dsv "1"
+ d3-ease "1"
+ d3-fetch "1"
+ d3-force "1"
+ d3-format "1"
+ d3-geo "1"
+ d3-hierarchy "1"
+ d3-interpolate "1"
+ d3-path "1"
+ d3-polygon "1"
+ d3-quadtree "1"
+ d3-random "1"
+ d3-scale "2"
+ d3-scale-chromatic "1"
+ d3-selection "1"
+ d3-shape "1"
+ d3-time "1"
+ d3-time-format "2"
+ d3-timer "1"
+ d3-transition "1"
+ d3-voronoi "1"
+ d3-zoom "1"
+
+d3@^5.7.0:
version "5.12.0"
resolved "https://registry.yarnpkg.com/d3/-/d3-5.12.0.tgz#0ddeac879c28c882317cd439b495290acd59ab61"
integrity sha512-flYVMoVuhPFHd9zVCe2BxIszUWqBcd5fvQGMNRmSiBrgdnh6Vlruh60RJQTouAK9xPbOB0plxMvBm4MoyODXNg==
@@ -2626,13 +2668,14 @@ d@1:
dependencies:
es5-ext "^0.10.9"
-dagre-d3@dagrejs/dagre-d3:
- version "0.6.4-pre"
- resolved "https://codeload.github.com/dagrejs/dagre-d3/tar.gz/e1a00e5cb518f5d2304a35647e024f31d178e55b"
+dagre-d3@^0.6.4:
+ version "0.6.4"
+ resolved "https://registry.yarnpkg.com/dagre-d3/-/dagre-d3-0.6.4.tgz#0728d5ce7f177ca2337df141ceb60fbe6eeb7b29"
+ integrity sha512-e/6jXeCP7/ptlAM48clmX4xTZc5Ek6T6kagS7Oz2HrYSdqcLZFLqpAfh7ldbZRFfxCZVyh61NEPR08UQRVxJzQ==
dependencies:
- d3 "^5.12"
- dagre "^0.8.4"
- graphlib "^2.1.7"
+ d3 "^5.14"
+ dagre "^0.8.5"
+ graphlib "^2.1.8"
lodash "^4.17.15"
dagre@^0.8.4:
@@ -2643,6 +2686,14 @@ dagre@^0.8.4:
graphlib "^2.1.7"
lodash "^4.17.4"
+dagre@^0.8.5:
+ version "0.8.5"
+ resolved "https://registry.yarnpkg.com/dagre/-/dagre-0.8.5.tgz#ba30b0055dac12b6c1fcc247817442777d06afee"
+ integrity sha512-/aTqmnRta7x7MCCpExk7HQL2O4owCT2h8NT//9I1OQ9vt29Pa0BzSAkR5lwFUcQ7491yVi/3CXU9jQ5o0Mn2Sw==
+ dependencies:
+ graphlib "^2.1.8"
+ lodash "^4.17.15"
+
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
@@ -3130,6 +3181,13 @@ entities@^1.1.1, entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
+entity-decode@^2.0.2:
+ version "2.0.2"
+ resolved "https://registry.yarnpkg.com/entity-decode/-/entity-decode-2.0.2.tgz#e4f807e52c3294246e9347d1f2b02b07fd5f92e7"
+ integrity sha512-5CCY/3ci4MC1m2jlumNjWd7VBFt4VfFnmSqSNmVcXq4gxM3Vmarxtt+SvmBnzwLS669MWdVuXboNVj1qN2esVg==
+ dependencies:
+ he "^1.1.1"
+
env-paths@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-1.0.0.tgz#4168133b42bb05c38a35b1ae4397c8298ab369e0"
@@ -4302,6 +4360,13 @@ graphlib@^2.1.7:
dependencies:
lodash "^4.17.5"
+graphlib@^2.1.8:
+ version "2.1.8"
+ resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da"
+ integrity sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==
+ dependencies:
+ lodash "^4.17.15"
+
gray-matter@^2.1.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/gray-matter/-/gray-matter-2.1.1.tgz#3042d9adec2a1ded6a7707a9ed2380f8a17a430e"
@@ -4490,7 +4555,7 @@ has@^1.0.1:
dependencies:
function-bind "^1.0.2"
-he@^1.2.0:
+he@^1.1.1, he@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@@ -6108,15 +6173,10 @@ lodash.uniq@^4.5.0:
version "4.5.0"
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
-lodash@^4.0.0, lodash@^4.0.1, lodash@^4.12.0, lodash@^4.13.1, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1:
- version "4.17.13"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.13.tgz#0bdc3a6adc873d2f4e0c4bac285df91b64fc7b93"
- integrity sha512-vm3/XWXfWtRua0FkUyEHBZy8kCPjErNBT9fJx8Zvs+U6zjqPbTUOpkaoum3O5uiA8sm+yNMHXfYkTUHFoMxFNA==
-
-lodash@^4.13.0, lodash@^4.17.11, lodash@^4.17.15:
- version "4.17.15"
- resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
- integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
+lodash@^4.0.0, lodash@^4.0.1, lodash@^4.12.0, lodash@^4.13.0, lodash@^4.13.1, lodash@^4.16.6, lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.5.1, lodash@^4.6.1:
+ version "4.17.19"
+ resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b"
+ integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==
lodash@~0.9.2:
version "0.9.2"
@@ -6400,22 +6460,21 @@ merge@^1.1.3:
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==
-mermaid@^8.4.2:
- version "8.4.2"
- resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.4.2.tgz#91d3d8e9541e72eed7a78d0e882db11564fab3bb"
- integrity sha512-vYSCP2u4XkOnjliWz/QIYwvzF/znQAq22vWJJ3YV40SnwV2JQyHblnwwNYXCprkXw7XfwBKDpSNaJ3HP4WfnZw==
+mermaid@^8.5.2:
+ version "8.5.2"
+ resolved "https://registry.yarnpkg.com/mermaid/-/mermaid-8.5.2.tgz#0f1914cda53d4ea5377380e5ce07a38bef2ea7e8"
+ integrity sha512-I+s+8/RzlazF3dGOhDUfU/ERkUV4zfIlTWb3703jNx+2lfACs+4AdY9ULQaw6BPWzW3gB+XlXFOOX/m/vqujIA==
dependencies:
"@braintree/sanitize-url" "^3.1.0"
crypto-random-string "^3.0.1"
d3 "^5.7.0"
dagre "^0.8.4"
- dagre-d3 dagrejs/dagre-d3
+ dagre-d3 "^0.6.4"
+ entity-decode "^2.0.2"
graphlib "^2.1.7"
he "^1.2.0"
- lodash "^4.17.11"
minify "^4.1.1"
moment-mini "^2.22.1"
- prettier "^1.18.2"
scope-css "^1.2.1"
methods@~1.1.2:
@@ -10027,8 +10086,9 @@ websocket-driver@>=0.5.1:
websocket-extensions ">=0.1.1"
websocket-extensions@>=0.1.1:
- version "0.1.3"
- resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
+ version "0.1.4"
+ resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
+ integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
well-known-symbols@^1.0.0:
version "1.0.0"