1
0
Fork 0

feat(core): Added new debug event type and debug system

This commit is contained in:
Joost De Cock 2020-07-18 16:48:29 +02:00
parent b360359cf6
commit 03da84b824
52 changed files with 860 additions and 398 deletions

View file

@ -1,5 +1,13 @@
Unreleased: Unreleased:
date: date:
Added:
core:
- Added new debug functionality through the use of the `raise.debug`
- Added a new `debug` setting
components:
- Workbench now includes events debug output and enables debug by default
css-theme:
- Added themeing for events
2.7.0: 2.7.0:
date: 2020-07-12 date: 2020-07-12

View file

@ -89,6 +89,7 @@ components:
'@material-ui/icons': '^4.0.1' '@material-ui/icons': '^4.0.1'
'@material-ui/lab': '^v4.0.0-alpha.14' '@material-ui/lab': '^v4.0.0-alpha.14'
'prismjs': '1.16.0' 'prismjs': '1.16.0'
'react-markdown': '4.3.1'
'file-saver': '^2.0.2' 'file-saver': '^2.0.2'
core: core:
_: _:

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -44,6 +44,7 @@
"@material-ui/icons": "^4.0.1", "@material-ui/icons": "^4.0.1",
"@material-ui/lab": "^v4.0.0-alpha.14", "@material-ui/lab": "^v4.0.0-alpha.14",
"prismjs": "1.16.0", "prismjs": "1.16.0",
"react-markdown": "4.3.1",
"file-saver": "^2.0.2" "file-saver": "^2.0.2"
}, },
"dependencies": {}, "dependencies": {},

View file

@ -33,7 +33,7 @@ const createConfig = (component, module) => {
const config = [] const config = []
// When developing, you can use this to only rebuild the components you're working on // When developing, you can use this to only rebuild the components you're working on
let dev = false let dev = true
let only = ['Workbench'] let only = ['Workbench']
for (let component of components) { for (let component of components) {
if (!dev || only.indexOf(component) !== -1) config.push(createConfig(component, false)) if (!dev || only.indexOf(component) !== -1) config.push(createConfig(component, false))

View file

@ -18,7 +18,6 @@ const Text = (props) => {
text.push(<tspan key={'tspan-' + key}>{lines.shift()}</tspan>) text.push(<tspan key={'tspan-' + key}>{lines.shift()}</tspan>)
for (let line of lines) { for (let line of lines) {
key++ key++
console.log('multi', line, typeof line)
text.push( text.push(
<tspan <tspan
key={'tspan-' + key} key={'tspan-' + key}

View file

@ -0,0 +1,20 @@
import React from 'react'
import DebugIcon from '@material-ui/icons/PlayCircleOutline'
import InfoIcon from '@material-ui/icons/Info'
import WarningIcon from '@material-ui/icons/ErrorOutline'
import ErrorIcon from '@material-ui/icons/HighlightOff'
import Markdown from 'react-markdown'
const Event = ({ type, event }) => (
<div className={`draft-event ${type}`}>
<div className={`icon ${type}`}>
{type === 'debug' && <DebugIcon fontSize="small" />}
{type === 'info' && <InfoIcon fontSize="small" />}
{type === 'warning' && <WarningIcon fontSize="small" />}
{type === 'error' && <ErrorIcon fontSize="small" />}
</div>
<Markdown source={event} />
</div>
)
export default Event

View file

@ -0,0 +1,16 @@
import React from 'react'
import Event from './event'
const DraftEvents = ({ events, app }) => (
<div className="draft-events">
{['error', 'warning', 'info', 'debug'].map((type) => (
<div className={`events-${type}`}>
{events[type].map((event, index) => (
<Event event={event} app={app} type={type} key={index} />
))}
</div>
))}
</div>
)
export default DraftEvents

View file

@ -16,6 +16,7 @@ import PaperlessIcon from '@material-ui/icons/Nature'
import CompleteIcon from '@material-ui/icons/Style' import CompleteIcon from '@material-ui/icons/Style'
import UnhideIcon from '@material-ui/icons/ChevronLeft' import UnhideIcon from '@material-ui/icons/ChevronLeft'
import HideIcon from '@material-ui/icons/ChevronRight' import HideIcon from '@material-ui/icons/ChevronRight'
import Events from './Events'
const DraftPattern = (props) => { const DraftPattern = (props) => {
const [design, setDesign] = useState(true) const [design, setDesign] = useState(true)
@ -123,6 +124,7 @@ const DraftPattern = (props) => {
viewBox={viewBox} viewBox={viewBox}
className="freesewing draft shadow" className="freesewing draft shadow"
/> />
<Events events={patternProps.events} />
{hideAside && ( {hideAside && (
<div style={styles.unhide}> <div style={styles.unhide}>
<IconButton <IconButton

View file

@ -36,6 +36,9 @@ const Workbench = ({
const [measurements, setMeasurements] = useState(null) const [measurements, setMeasurements] = useState(null)
const [svgExport, setSvgExport] = useState(false) const [svgExport, setSvgExport] = useState(false)
// Enable debug in Workbench
defaultGist.settings.debug = true
useEffect(() => { useEffect(() => {
let m = getMeasurements() let m = getMeasurements()
setMeasurements(m) setMeasurements(m)
@ -220,7 +223,11 @@ const Workbench = ({
return ( return (
<MuiThemeProvider theme={createMuiTheme(themes[theme])}> <MuiThemeProvider theme={createMuiTheme(themes[theme])}>
<div className={theme === 'light' ? 'theme-wrapper light' : 'theme-wrapper dark'}> <div
className={
theme === 'light' ? 'workbench theme-wrapper light' : 'workbench theme-wrapper dark'
}
>
{display !== 'welcome' ? <Navbar navs={navs} home={() => saveDisplay('welcome')} /> : null} {display !== 'welcome' ? <Navbar navs={navs} home={() => saveDisplay('welcome')} /> : null}
{main} {main}
{display !== 'welcome' ? <Footer language={language} /> : null} {display !== 'welcome' ? <Footer language={language} /> : null}

View file

@ -18,7 +18,6 @@ function Part() {
this.render = true this.render = true
this.utils = utils this.utils = utils
// Constructors so macros can create objects
this.Point = Point this.Point = Point
this.Path = Path this.Path = Path
this.Snippet = Snippet this.Snippet = Snippet
@ -59,6 +58,10 @@ Part.prototype.getId = function () {
Part.prototype.unitsClosure = function (value) { Part.prototype.unitsClosure = function (value) {
let self = this let self = this
let method = function (value) { let method = function (value) {
if (self.context.settings.debug && typeof value !== 'number')
self.context.raise.debug(
`Calling \`units(value)\` but \`value\` is not a number (\`${typeof value}\`)`
)
return utils.units(value, self.context.settings.units) return utils.units(value, self.context.settings.units)
} }
@ -169,25 +172,144 @@ Part.prototype.shorthand = function () {
let complete = this.context.settings.complete ? true : false let complete = this.context.settings.complete ? true : false
let paperless = this.context.settings.paperless === true ? true : false let paperless = this.context.settings.paperless === true ? true : false
let sa = this.context.settings.complete ? this.context.settings.sa || 0 : 0 let sa = this.context.settings.complete ? this.context.settings.sa || 0 : 0
return { const shorthand = {
sa, sa,
measurements: this.context.settings.measurements || {},
options: this.context.settings.options || {},
store: this.context.store, store: this.context.store,
points: this.points || {},
paths: this.paths || {},
snippets: this.snippets || {},
macro: this.macroClosure(), macro: this.macroClosure(),
units: this.unitsClosure(), units: this.unitsClosure(),
utils: utils, utils: utils,
Point: this.Point,
Path: this.Path,
Snippet: this.Snippet,
complete, complete,
paperless, paperless,
events: this.context.events, events: this.context.events,
raise: this.context.events.raise raise: this.context.raise
} }
if (this.context.settings.debug) {
// We'll need this
let self = this
// Wrap the Point constructor so objects can raise events
shorthand.Point = function (x, y) {
Point.apply(this, [x, y, self.context.raise])
this.raise = self.context.raise
}
shorthand.Point.prototype = Object.create(Point.prototype)
// Wrap the Path constructor so objects can raise events
shorthand.Path = function () {
Path.apply(this, [self.context.raise])
this.raise = self.context.raise
}
shorthand.Path.prototype = Object.create(Path.prototype)
// Wrap the Snippet constructor so objects can raise events
shorthand.Snippet = function (def, anchor) {
Snippet.apply(this, [def, anchor, self.context.raise])
Snippet.apply(this, arguments)
shorthand.raise = self.context.raise
}
shorthand.Snippet.prototype = Object.create(Snippet.prototype)
// Proxy the points object
const pointsProxy = {
get: function () {
return Reflect.get(...arguments)
},
set: (points, name, value) => {
// Constructor checks
if (value instanceof Point !== true)
self.context.raise.warning(
`\`points.${name}\` was set with a value that is not a \`Point\` object`
)
if (!utils.isCoord(value.x))
self.context.raise.warning(
`\`points.${name}\` was set with a \`x\` parameter that is not a \`number\``
)
if (!utils.isCoord(value.y))
self.context.raise.warning(
`\`points.${name}\` was set with a \`y\` parameter that is not a \`number\``
)
value.name = name
return (self.points[name] = value)
}
}
shorthand.points = new Proxy(this.points || {}, pointsProxy)
// Proxy the paths object
const pathsProxy = {
get: function () {
return Reflect.get(...arguments)
},
set: (paths, name, value) => {
// Constructor checks
if (value instanceof Path !== true)
self.context.raise.warning(
`\`paths.${name}\` was set with a value that is not a \`Path\` object`
)
value.name = name
return (self.paths[name] = value)
}
}
shorthand.paths = new Proxy(this.paths || {}, pathsProxy)
// Proxy the snippets object
const snippetsProxy = {
get: function (target, prop, receiver) {
return Reflect.get(...arguments)
},
set: (snippets, name, value) => {
// Constructor checks
if (value instanceof Snippet !== true)
self.context.raise.warning(
`\`snippets.${name}\` was set with a value that is not a \`Snippet\` object`
)
if (typeof value.def !== 'string')
self.context.raise.warning(
`\`snippets.${name}\` was set with a \`def\` parameter that is not a \`string\``
)
if (value.anchor instanceof Point !== true)
self.context.raise.warning(
`\`snippets.${name}\` was set with an \`anchor\` parameter that is not a \`Point\``
)
value.name = name
return (self.snippets[name] = value)
}
}
shorthand.snippets = new Proxy(this.snippets || {}, snippetsProxy)
// Proxy the measurements object
const measurementsProxy = {
get: function (measurements, name) {
if (typeof measurements[name] === 'undefined')
self.context.raise.warning(
`Tried to access \`measurements.${name}\` but it is \`undefined\``
)
return Reflect.get(...arguments)
},
set: (measurements, name, value) => {
return (self.measurements[name] = value)
}
}
shorthand.measurements = new Proxy(this.context.settings.measurements || {}, measurementsProxy)
// Proxy the options object
const optionsProxy = {
get: function (options, name) {
if (typeof options[name] === 'undefined')
self.context.raise.warning(`Tried to access \`options.${name}\` but it is \`undefined\``)
return Reflect.get(...arguments)
},
set: (options, name, value) => {
return (self.options[name] = value)
}
}
shorthand.options = new Proxy(this.context.settings.options || {}, optionsProxy)
} else {
shorthand.Point = Point
shorthand.Path = Path
shorthand.Snippet = Snippet
shorthand.points = this.points || {}
shorthand.paths = this.paths || {}
shorthand.snippets = this.snippets || {}
shorthand.measurements = this.context.settings.measurements || {}
shorthand.options = this.context.settings.options || {}
}
return shorthand
} }
export default Part export default Part

View file

@ -11,7 +11,8 @@ import {
round round
} from './utils' } from './utils'
function Path() { function Path(raise = false) {
this.debug = raise ? true : false
this.render = true this.render = true
this.topLeft = false this.topLeft = false
this.bottomRight = false this.bottomRight = false
@ -20,36 +21,55 @@ function Path() {
} }
/** Chainable way to set the render property */ /** Chainable way to set the render property */
Path.prototype.setRender = function(render = true) { Path.prototype.setRender = function (render = true) {
if (render) this.render = true if (render) this.render = true
else this.render = false else this.render = false
if (this.debug) this.raise('Setting `Path.render` to ' + render ? '`true`' : '`false`')
return this return this
} }
/** Adds a move operation to Point to */ /** Adds a move operation to Point to */
Path.prototype.move = function(to) { Path.prototype.move = function (to) {
if (this.debug && to instanceof Point !== true)
this.raise.warning('Called `Path.rotate(to)` but `to` is not a `Point` object')
this.ops.push({ type: 'move', to }) this.ops.push({ type: 'move', to })
return this return this
} }
/** Adds a line operation to Point to */ /** Adds a line operation to Point to */
Path.prototype.line = function(to) { Path.prototype.line = function (to) {
if (this.debug && to instanceof Point !== true)
this.raise.warning('Called `Path.line(to)` but `to` is not a `Point` object')
this.ops.push({ type: 'line', to }) this.ops.push({ type: 'line', to })
return this return this
} }
/** Adds a curve operation via cp1 & cp2 to Point to */ /** Adds a curve operation via cp1 & cp2 to Point to */
Path.prototype.curve = function(cp1, cp2, to) { Path.prototype.curve = function (cp1, cp2, to) {
if (this.debug) {
if (to instanceof Point !== true)
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `to` is not a `Point` object')
if (cp1 instanceof Point !== true)
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `cp1` is not a `Point` object')
if (cp2 instanceof Point !== true)
this.raise.warning('Called `Path.curve(cp1, cp2, to)` but `cp2` is not a `Point` object')
}
this.ops.push({ type: 'curve', cp1, cp2, to }) this.ops.push({ type: 'curve', cp1, cp2, to })
return this return this
} }
/** Adds a curve operation without cp1 via cp2 to Point to */ /** Adds a curve operation without cp1 via cp2 to Point to */
Path.prototype._curve = function(cp2, to) { Path.prototype._curve = function (cp2, to) {
if (this.debug) {
if (to instanceof Point !== true)
this.raise.warning('Called `Path._curve(cp2, to)` but `to` is not a `Point` object')
if (cp2 instanceof Point !== true)
this.raise.warning('Called `Path._curve(cp2, to)` but `cp2` is not a `Point` object')
}
let cp1 = this.ops.slice(-1).pop().to let cp1 = this.ops.slice(-1).pop().to
this.ops.push({ type: 'curve', cp1, cp2, to }) this.ops.push({ type: 'curve', cp1, cp2, to })
@ -57,7 +77,13 @@ Path.prototype._curve = function(cp2, to) {
} }
/** Adds a curve operation via cp1 with no cp2 to Point to */ /** Adds a curve operation via cp1 with no cp2 to Point to */
Path.prototype.curve_ = function(cp1, to) { Path.prototype.curve_ = function (cp1, to) {
if (this.debug) {
if (to instanceof Point !== true)
this.raise.warning('Called `Path.curve_(cp1, to)` but `to` is not a `Point` object')
if (cp1 instanceof Point !== true)
this.raise.warning('Called `Path.curve_(cp1, to)` but `cp2` is not a `Point` object')
}
let cp2 = to.copy() let cp2 = to.copy()
this.ops.push({ type: 'curve', cp1, cp2, to }) this.ops.push({ type: 'curve', cp1, cp2, to })
@ -65,21 +91,27 @@ Path.prototype.curve_ = function(cp1, to) {
} }
/** Adds a close operation */ /** Adds a close operation */
Path.prototype.close = function() { Path.prototype.close = function () {
this.ops.push({ type: 'close' }) this.ops.push({ type: 'close' })
return this return this
} }
/** Adds a noop operation */ /** Adds a noop operation */
Path.prototype.noop = function(id = false) { Path.prototype.noop = function (id = false) {
this.ops.push({ type: 'noop', id }) this.ops.push({ type: 'noop', id })
return this return this
} }
/** Replace a noop operation with the ops from path */ /** Replace a noop operation with the ops from path */
Path.prototype.insop = function(noopId, path) { Path.prototype.insop = function (noopId, path) {
if (this.debug) {
if (!noopId)
this.raise.warning('Called `Path.insop(noopId, path)` but `noopId` is undefined or false')
if (path instanceof Path !== true)
this.raise.warning('Called `Path.insop(noopId, path) but `path` is not a `Path` object')
}
let newPath = this.clone() let newPath = this.clone()
for (let i in newPath.ops) { for (let i in newPath.ops) {
if (newPath.ops[i].type === 'noop' && newPath.ops[i].id === noopId) { if (newPath.ops[i].type === 'noop' && newPath.ops[i].id === noopId) {
@ -94,7 +126,21 @@ Path.prototype.insop = function(noopId, path) {
} }
/** Adds an attribute. This is here to make this call chainable in assignment */ /** Adds an attribute. This is here to make this call chainable in assignment */
Path.prototype.attr = function(name, value, overwrite = false) { Path.prototype.attr = function (name, value, overwrite = false) {
if (this.debug) {
if (!name)
this.raise.warning(
'Called `Path.attr(name, value, overwrite=false)` but `name` is undefined or false'
)
if (typeof value === 'undefined')
this.raise.warning(
'Called `Path.attr(name, value, overwrite=false)` but `value` is undefined'
)
if (overwrite)
this.raise.debug(
`Overwriting \`Path.attribute.${name}\` with ${value} (was: ${this.attributes.get(name)})`
)
}
if (overwrite) this.attributes.set(name, value) if (overwrite) this.attributes.set(name, value)
else this.attributes.add(name, value) else this.attributes.add(name, value)
@ -102,7 +148,7 @@ Path.prototype.attr = function(name, value, overwrite = false) {
} }
/** Returns SVG pathstring for this path */ /** Returns SVG pathstring for this path */
Path.prototype.asPathstring = function() { Path.prototype.asPathstring = function () {
let d = '' let d = ''
for (let op of this.ops) { for (let op of this.ops) {
switch (op.type) { switch (op.type) {
@ -125,12 +171,14 @@ Path.prototype.asPathstring = function() {
} }
/** Returns offset of this path as a new path */ /** Returns offset of this path as a new path */
Path.prototype.offset = function(distance) { Path.prototype.offset = function (distance) {
if (typeof distance !== 'number')
this.raise.error('Called `Path.offset(distance)` but `distance` is not a number')
return pathOffset(this, distance) return pathOffset(this, distance)
} }
/** Returns the length of this path */ /** Returns the length of this path */
Path.prototype.length = function() { Path.prototype.length = function () {
let current, start let current, start
let length = 0 let length = 0
for (let i in this.ops) { for (let i in this.ops) {
@ -156,12 +204,16 @@ Path.prototype.length = function() {
} }
/** Returns the startpoint of the path */ /** Returns the startpoint of the path */
Path.prototype.start = function() { Path.prototype.start = function () {
if (this.ops.length < 1 || typeof this.ops[0].to === 'undefined')
this.raise.error('Called `Path.start()` but this path has no drawing operations')
return this.ops[0].to return this.ops[0].to
} }
/** Returns the endpoint of the path */ /** Returns the endpoint of the path */
Path.prototype.end = function() { Path.prototype.end = function () {
if (this.ops.length < 1)
this.raise.error('Called `Path.end()` but this path has no drawing operations')
let op = this.ops[this.ops.length - 1] let op = this.ops[this.ops.length - 1]
if (op.type === 'close') return this.start() if (op.type === 'close') return this.start()
@ -169,7 +221,7 @@ Path.prototype.end = function() {
} }
/** Finds the bounding box of a path */ /** Finds the bounding box of a path */
Path.prototype.boundary = function() { Path.prototype.boundary = function () {
if (this.topLeft) return this // Cached if (this.topLeft) return this // Cached
let current let current
@ -235,7 +287,7 @@ Path.prototype.boundary = function() {
} }
/** Returns a deep copy of this */ /** Returns a deep copy of this */
Path.prototype.clone = function() { Path.prototype.clone = function () {
let clone = new Path() let clone = new Path()
clone.render = this.render clone.render = this.render
if (this.topLeft) clone.topLeft = this.topLeft.clone() if (this.topLeft) clone.topLeft = this.topLeft.clone()
@ -262,7 +314,9 @@ Path.prototype.clone = function() {
} }
/** Joins this with that path, closes them if wanted */ /** Joins this with that path, closes them if wanted */
Path.prototype.join = function(that, closed = false) { Path.prototype.join = function (that, closed = false) {
if (that instanceof Path !== true)
this.raise.error('Called `Path.join(that)` but `that` is not a `Path` object')
return joinPaths([this, that], closed) return joinPaths([this, that], closed)
} }
@ -282,16 +336,10 @@ function pathOffset(path, distance) {
// because that will break the offset in bezier-js // because that will break the offset in bezier-js
let cp1, cp2 let cp1, cp2
if (current.sitsRoughlyOn(op.cp1)) { if (current.sitsRoughlyOn(op.cp1)) {
cp1 = new Path() cp1 = new Path().move(current).curve(op.cp1, op.cp2, op.to).shiftAlong(2)
.move(current)
.curve(op.cp1, op.cp2, op.to)
.shiftAlong(2)
} else cp1 = op.cp1 } else cp1 = op.cp1
if (op.cp2.sitsRoughlyOn(op.to)) { if (op.cp2.sitsRoughlyOn(op.to)) {
cp2 = new Path() cp2 = new Path().move(op.to).curve(op.cp2, op.cp1, current).shiftAlong(2)
.move(op.to)
.curve(op.cp2, op.cp1, current)
.shiftAlong(2)
} else cp2 = op.cp2 } else cp2 = op.cp2
let b = new Bezier( let b = new Bezier(
{ x: current.x, y: current.y }, { x: current.x, y: current.y },
@ -350,7 +398,9 @@ function joinPaths(paths, closed = false) {
} }
/** Returns a point that lies at distance along this */ /** Returns a point that lies at distance along this */
Path.prototype.shiftAlong = function(distance) { Path.prototype.shiftAlong = function (distance) {
if (typeof distance !== 'number')
this.raise.error('Called `Path.shiftAlong(distance)` but `distance` is not a number')
let len = 0 let len = 0
let current let current
for (let i in this.ops) { for (let i in this.ops) {
@ -372,13 +422,15 @@ Path.prototype.shiftAlong = function(distance) {
} }
current = op.to current = op.to
} }
throw new Error( this.raise.error(
`Error in Path.shiftAlong(): Ran out of path to shift along. Distance requested was ${distance}, path length is${this.length()}.` `Called \`Path.shiftAlong(distance)\` with a \`distance\` of \`${distance}\` but \`Path.length()\` is only \`${this.length()}\``
) )
} }
/** Returns a point that lies at fraction along this */ /** Returns a point that lies at fraction along this */
Path.prototype.shiftFractionAlong = function(fraction) { Path.prototype.shiftFractionAlong = function (fraction) {
if (typeof fraction !== 'number')
this.raise.error('Called `Path.shiftFractionAlong(fraction)` but `fraction` is not a number')
return this.shiftAlong(this.length() * fraction) return this.shiftAlong(this.length() * fraction)
} }
@ -401,7 +453,7 @@ function shiftAlongBezier(distance, bezier) {
} }
/** Returns a point at the top edge of a bounding box of this */ /** Returns a point at the top edge of a bounding box of this */
Path.prototype.bbox = function() { Path.prototype.bbox = function () {
let bbs = [] let bbs = []
let current let current
for (let i in this.ops) { for (let i in this.ops) {
@ -481,7 +533,7 @@ function bbbbox(boxes) {
} }
/** Returns a reversed version of this */ /** Returns a reversed version of this */
Path.prototype.reverse = function() { Path.prototype.reverse = function () {
let sections = [] let sections = []
let current let current
let closed = false let closed = false
@ -504,7 +556,7 @@ Path.prototype.reverse = function() {
} }
/** Returns the point at an edge of this path */ /** Returns the point at an edge of this path */
Path.prototype.edge = function(side) { Path.prototype.edge = function (side) {
this.boundary() this.boundary()
if (side === 'topLeft') return this.topLeft if (side === 'topLeft') return this.topLeft
else if (side === 'bottomRight') return this.bottomRight else if (side === 'bottomRight') return this.bottomRight
@ -532,6 +584,7 @@ Path.prototype.edge = function(side) {
return curveEdge(curve, side) return curveEdge(curve, side)
} }
} }
this.raise.error(`Unable to find \`Path.edge(side)\` for side ${side}`)
} }
function edgeCurveAsBezier(op) { function edgeCurveAsBezier(op) {
@ -544,7 +597,7 @@ function edgeCurveAsBezier(op) {
} }
/** Divides a path into atomic paths */ /** Divides a path into atomic paths */
Path.prototype.divide = function() { Path.prototype.divide = function () {
let paths = [] let paths = []
let current, start let current, start
for (let i in this.ops) { for (let i in this.ops) {
@ -565,18 +618,21 @@ Path.prototype.divide = function() {
} }
/** Finds intersections between this path and an X value */ /** Finds intersections between this path and an X value */
Path.prototype.intersectsX = function(x) { Path.prototype.intersectsX = function (x) {
if (typeof x !== 'number')
this.raise.error('Called `Path.intersectsX(x)` but `x` is not a number')
return this.intersectsAxis(x, 'x') return this.intersectsAxis(x, 'x')
} }
/** Finds intersections between this path and an Y value */ /** Finds intersections between this path and an Y value */
Path.prototype.intersectsY = function(y) { Path.prototype.intersectsY = function (y) {
if (typeof y !== 'number')
this.raise.error('Called `Path.intersectsX(y)` but `y` is not a number')
return this.intersectsAxis(y, 'y') return this.intersectsAxis(y, 'y')
} }
/** Finds intersections between this path and a X or Y value */ /** Finds intersections between this path and a X or Y value */
Path.prototype.intersectsAxis = function(val = false, mode) { Path.prototype.intersectsAxis = function (val = false, mode) {
if (val === false) throw new Error('Path.intersects[X-Y] requires an value as parameter')
let intersections = [] let intersections = []
let lineStart = mode === 'x' ? new Point(val, -100000) : new Point(-10000, val) let lineStart = mode === 'x' ? new Point(val, -100000) : new Point(-10000, val)
let lineEnd = mode === 'x' ? new Point(val, 100000) : new Point(100000, val) let lineEnd = mode === 'x' ? new Point(val, 100000) : new Point(100000, val)
@ -605,9 +661,9 @@ Path.prototype.intersectsAxis = function(val = false, mode) {
} }
/** Finds intersections between this path and another path */ /** Finds intersections between this path and another path */
Path.prototype.intersects = function(path) { Path.prototype.intersects = function (path) {
if (this === path) if (this === path)
throw new Error('Calculating intersections between two identical paths is bad idea') this.raise.error('You called Path.intersects(path)` but `path` and `this` are the same object')
let intersections = [] let intersections = []
for (let pathA of this.divide()) { for (let pathA of this.divide()) {
for (let pathB of path.divide()) { for (let pathB of path.divide()) {
@ -676,7 +732,9 @@ function addIntersectionsToArray(candidates, intersections) {
} }
/** Splits path on point, and retuns both halves */ /** Splits path on point, and retuns both halves */
Path.prototype.split = function(point) { Path.prototype.split = function (point) {
if (point instanceof Point !== true)
this.raise.error('Called `Path.split(point)` but `point` is not a `Point` object')
let divided = this.divide() let divided = this.divide()
let firstHalf = false let firstHalf = false
let secondHalf = false let secondHalf = false
@ -731,7 +789,7 @@ Path.prototype.split = function(point) {
} }
/** Removes self-intersections (overlap) from the path */ /** Removes self-intersections (overlap) from the path */
Path.prototype.trim = function() { Path.prototype.trim = function () {
let chunks = this.divide() let chunks = this.divide()
for (let i = 0; i < chunks.length; i++) { for (let i = 0; i < chunks.length; i++) {
let firstCandidate = parseInt(i) + 2 let firstCandidate = parseInt(i) + 2
@ -783,7 +841,13 @@ Path.prototype.trim = function() {
} }
/** Applies a path translate transform */ /** Applies a path translate transform */
Path.prototype.translate = function(x, y) { Path.prototype.translate = function (x, y) {
if (this.debug) {
if (typeof x !== 'number')
this.raise.warning('Called `Path.translate(x, y)` but `x` is not a number')
if (typeof y !== 'number')
this.raise.warning('Called `Path.translate(x, y)` but `y` is not a number')
}
let clone = this.clone() let clone = this.clone()
for (let op of clone.ops) { for (let op of clone.ops) {
if (op.type !== 'close') { if (op.type !== 'close') {

View file

@ -8,14 +8,43 @@ import pack from 'bin-pack'
import Store from './store' import Store from './store'
import Hooks from './hooks' import Hooks from './hooks'
import Attributes from './attributes' import Attributes from './attributes'
import { version } from '../package.json'
export default function Pattern(config = { options: {} }) { export default function Pattern(config = { options: {} }) {
// Events store and raise methods
this.events = {
info: [],
warning: [],
error: [],
debug: []
}
const events = this.events
this.raise = {
event: function (data) {
events.info.push(data)
},
warning: function (data) {
events.warning.push(data)
},
error: function (data) {
events.error.push(data)
},
debug: function (data) {
events.debug.push(data)
console.log(data)
}
}
this.raise.debug(
`New \`@freesewing/${config.name}:${config.version}\` pattern using \`@freesewing/core:${version}\``
)
this.config = config // Pattern configuration this.config = config // Pattern configuration
this.width = 0 // Will be set after render this.width = 0 // Will be set after render
this.height = 0 // Will be set after render this.height = 0 // Will be set after render
this.is = '' // Will be set when drafting/sampling this.is = '' // Will be set when drafting/sampling
this.debug = true // Will be set when applying settings
this.store = new Store() // Store for sharing data across parts this.store = new Store(this.raise) // Store for sharing data across parts
this.parts = {} // Parts container this.parts = {} // Parts container
this.hooks = new Hooks() // Hooks container this.hooks = new Hooks() // Hooks container
this.Point = Point // Point constructor this.Point = Point // Point constructor
@ -31,7 +60,7 @@ export default function Pattern(config = { options: {} }) {
units: 'metric', units: 'metric',
margin: 2, margin: 2,
layout: true, layout: true,
debug: false, debug: true,
options: {} options: {}
} }
@ -57,31 +86,6 @@ export default function Pattern(config = { options: {} }) {
} }
} }
// Store events
this.events = {
info: [],
warning: [],
error: [],
debug: []
}
const events = this.events
this.events.raise = {
event: function (data) {
events.info.push(data)
},
warning: function (data) {
events.warning.push(data)
},
error: function (data) {
events.error.push(data)
},
debug: function (data) {
if (this.settings.debug) events.debug.push(data)
}
}
// Debug helper
this.debug = this.events.raise.debug
// Macros // Macros
this.macros = {} this.macros = {}
@ -92,7 +96,8 @@ export default function Pattern(config = { options: {} }) {
settings: this.settings, settings: this.settings,
store: this.store, store: this.store,
macros: this.macros, macros: this.macros,
events: this.events events: this.events,
raise: this.raise
} }
// Part closure // Part closure
@ -108,7 +113,10 @@ export default function Pattern(config = { options: {} }) {
// Merges settings object with this.settings // Merges settings object with this.settings
Pattern.prototype.apply = function (settings) { Pattern.prototype.apply = function (settings) {
if (typeof settings !== 'object') return this if (typeof settings !== 'object') {
this.raise.warning('Pattern initialized without any settings')
return this
}
for (let key of Object.keys(settings)) { for (let key of Object.keys(settings)) {
if (Array.isArray(settings[key])) { if (Array.isArray(settings[key])) {
if (Array.isArray(this.settings[key])) { if (Array.isArray(this.settings[key])) {
@ -121,7 +129,11 @@ Pattern.prototype.apply = function (settings) {
} }
} else this.settings[key] = settings[key] } else this.settings[key] = settings[key]
} }
if (this.settings.debug) this.debug('Debug enabled') if (this.settings.debug) this.raise.debug('Debug enabled')
else {
this.raise.debug('Debug disabled')
this.debug = false
}
return this return this
} }
@ -130,6 +142,7 @@ Pattern.prototype.runHooks = function (hookName, data = false) {
if (data === false) data = this if (data === false) data = this
let hooks = this.hooks[hookName] let hooks = this.hooks[hookName]
if (hooks.length > 0) { if (hooks.length > 0) {
if (this.debug) this.raise.debug(`Running \`${hookName}\` hooks`)
for (let hook of hooks) { for (let hook of hooks) {
hook.method(data, hook.data) hook.method(data, hook.data)
} }
@ -140,25 +153,43 @@ Pattern.prototype.runHooks = function (hookName, data = false) {
* The default draft method with pre- and postDraft hooks * The default draft method with pre- and postDraft hooks
*/ */
Pattern.prototype.draft = function () { Pattern.prototype.draft = function () {
if (this.is !== 'sample') this.is = 'draft' if (this.is !== 'sample') {
this.is = 'draft'
if (this.debug) this.raise.debug(`Drafting pattern`)
}
this.runHooks('preDraft') this.runHooks('preDraft')
for (let partName of this.config.draftOrder) { for (let partName of this.config.draftOrder) {
if (this.debug) this.raise.debug(`Creating part \`${partName}\``)
this.parts[partName] = new this.Part() this.parts[partName] = new this.Part()
if (typeof this.config.inject[partName] === 'string') { if (typeof this.config.inject[partName] === 'string') {
if (this.debug)
this.raise.debug(
`Injecting part \`${this.config.inject[partName]}\` into part \`${partName}\``
)
this.parts[partName].inject(this.parts[this.config.inject[partName]]) this.parts[partName].inject(this.parts[this.config.inject[partName]])
} }
if (this.needs(partName)) { if (this.needs(partName)) {
let method = 'draft' + capitalize(partName) let method = 'draft' + capitalize(partName)
if (typeof this[method] !== 'function') if (typeof this[method] !== 'function') {
this.raise.error(`Method \`pattern.${method}\` is callable`)
throw new Error('Method "' + method + '" on pattern object is not callable') throw new Error('Method "' + method + '" on pattern object is not callable')
}
this.parts[partName] = this[method](this.parts[partName]) this.parts[partName] = this[method](this.parts[partName])
if (typeof this.parts[partName] === 'undefined') if (typeof this.parts[partName] === 'undefined') {
this.raise.error(
`Result of \`pattern.${method}\` was \`undefined\`. Did you forget to return the \`Part\` object?`
)
throw new Error( throw new Error(
'Result of ' + method + '() was undefined. Did you forget to return the Part object?' 'Result of ' + method + '() was undefined. Did you forget to return the Part object?'
) )
}
this.parts[partName].render = this.parts[partName].render =
this.parts[partName].render === false ? false : this.wants(partName) this.parts[partName].render === false ? false : this.wants(partName)
} else { } else {
if (this.debug)
this.raise.debug(
`Part \`${partName}\` is not needed. Skipping draft and setting render to \`false\``
)
this.parts[partName].render = false this.parts[partName].render = false
} }
} }
@ -236,6 +267,7 @@ Pattern.prototype.sampleRun = function (parts, anchors, run, runs, extraClass =
*/ */
Pattern.prototype.sampleOption = function (optionName) { Pattern.prototype.sampleOption = function (optionName) {
this.is = 'sample' this.is = 'sample'
if (this.debug) this.raise.debug(`Sampling option \`${optionName}\``)
this.runHooks('preSample') this.runHooks('preSample')
let step, val let step, val
let factor = 1 let factor = 1
@ -285,6 +317,7 @@ Pattern.prototype.sampleListOption = function (optionName) {
*/ */
Pattern.prototype.sampleMeasurement = function (measurementName) { Pattern.prototype.sampleMeasurement = function (measurementName) {
this.is = 'sample' this.is = 'sample'
if (this.debug) this.raise.debug(`Sampling measurement \`${measurement}\``)
this.runHooks('preSample') this.runHooks('preSample')
let anchors = {} let anchors = {}
let parts = this.sampleParts() let parts = this.sampleParts()
@ -309,6 +342,7 @@ Pattern.prototype.sampleMeasurement = function (measurementName) {
*/ */
Pattern.prototype.sampleModels = function (models, focus = false) { Pattern.prototype.sampleModels = function (models, focus = false) {
this.is = 'sample' this.is = 'sample'
if (this.debug) this.raise.debug(`Sampling models`)
this.runHooks('preSample') this.runHooks('preSample')
let anchors = {} let anchors = {}
let parts = this.sampleParts() let parts = this.sampleParts()
@ -343,6 +377,7 @@ Pattern.prototype.on = function (hook, method, data) {
} }
Pattern.prototype.use = function (plugin, data) { Pattern.prototype.use = function (plugin, data) {
if (this.debug) this.raise.debug(`Loaded plugin \`${plugin.name}:${plugin.version}\``)
if (plugin.hooks) this.loadPluginHooks(plugin, data) if (plugin.hooks) this.loadPluginHooks(plugin, data)
if (plugin.macros) this.loadPluginMacros(plugin) if (plugin.macros) this.loadPluginMacros(plugin)

View file

@ -1,24 +1,38 @@
import Attributes from './attributes' import Attributes from './attributes'
import { round } from './utils' import { round } from './utils'
function Point(x, y) { function Point(x, y, raise = false) {
this.debug = raise ? true : false
if (this.debug) {
if (typeof x !== 'number') raise.warning('Called `new Point(x,y)` but `x` is not a number')
if (typeof y !== 'number') raise.warning('Called `new Point(x,y)` but `y` is not a number')
}
this.x = round(x) this.x = round(x)
this.y = round(y) this.y = round(y)
this.attributes = new Attributes() this.attributes = new Attributes()
} }
/** Debug method to validate point data **/
Point.prototype.check = function () {
if (this.debug) {
if (typeof this.x !== 'number') this.raise.warning('X value of `Point` is not a number')
if (typeof this.y !== 'number') this.raise.warning('Y value of `Point` is not a number')
}
}
/** Radians to degrees */ /** Radians to degrees */
Point.prototype.rad2deg = function(radians) { Point.prototype.rad2deg = function (radians) {
return radians * 57.29577951308232 return radians * 57.29577951308232
} }
/** Degrees to radians */ /** Degrees to radians */
Point.prototype.deg2rad = function(degrees) { Point.prototype.deg2rad = function (degrees) {
return degrees / 57.29577951308232 return degrees / 57.29577951308232
} }
/** Adds an attribute. This is here to make this call chainable in assignment */ /** Adds an attribute. This is here to make this call chainable in assignment */
Point.prototype.attr = function(name, value, overwrite = false) { Point.prototype.attr = function (name, value, overwrite = false) {
if (this.debug) this.check()
if (overwrite) this.attributes.set(name, value) if (overwrite) this.attributes.set(name, value)
else this.attributes.add(name, value) else this.attributes.add(name, value)
@ -26,7 +40,11 @@ Point.prototype.attr = function(name, value, overwrite = false) {
} }
/** Returns the distance between this point and that point */ /** Returns the distance between this point and that point */
Point.prototype.dist = function(that) { Point.prototype.dist = function (that) {
if (this.debug) {
this.check()
that.check()
}
let dx = this.x - that.x let dx = this.x - that.x
let dy = this.y - that.y let dy = this.y - that.y
@ -34,22 +52,38 @@ Point.prototype.dist = function(that) {
} }
/** Returns slope of a line made by this point and that point */ /** Returns slope of a line made by this point and that point */
Point.prototype.slope = function(that) { Point.prototype.slope = function (that) {
if (this.debug) {
this.check()
that.check()
}
return (that.y - this.y) / (that.x - this.x) return (that.y - this.y) / (that.x - this.x)
} }
/** Returns the x-delta between this point and that point */ /** Returns the x-delta between this point and that point */
Point.prototype.dx = function(that) { Point.prototype.dx = function (that) {
if (this.debug) {
this.check()
that.check()
}
return that.x - this.x return that.x - this.x
} }
/** Returns the y-delta between this point and that point */ /** Returns the y-delta between this point and that point */
Point.prototype.dy = function(that) { Point.prototype.dy = function (that) {
if (this.debug) {
this.check()
that.check()
}
return that.y - this.y return that.y - this.y
} }
/** Returns the angle between this point and that point */ /** Returns the angle between this point and that point */
Point.prototype.angle = function(that) { Point.prototype.angle = function (that) {
if (this.debug) {
this.check()
that.check()
}
let rad = Math.atan2(-1 * this.dy(that), this.dx(that)) let rad = Math.atan2(-1 * this.dy(that), this.dx(that))
while (rad < 0) rad += 2 * Math.PI while (rad < 0) rad += 2 * Math.PI
@ -57,7 +91,15 @@ Point.prototype.angle = function(that) {
} }
/** Rotate this point deg around that point */ /** Rotate this point deg around that point */
Point.prototype.rotate = function(deg, that) { Point.prototype.rotate = function (deg, that) {
if (this.debug) {
this.check()
that.check()
if (typeof deg !== 'number')
this.raise.warning('Called `Point.rotate(deg,that)` but `deg` is not a number')
if (that instanceof Point !== true)
this.raise.warning('Called `Point.rotate(deg,that)` but `that` is not a `Point` object')
}
let radius = this.dist(that) let radius = this.dist(that)
let angle = this.angle(that) let angle = this.angle(that)
let x = that.x + radius * Math.cos(this.deg2rad(angle + deg)) * -1 let x = that.x + radius * Math.cos(this.deg2rad(angle + deg)) * -1
@ -67,24 +109,46 @@ Point.prototype.rotate = function(deg, that) {
} }
/** returns an identical copy of this point */ /** returns an identical copy of this point */
Point.prototype.copy = function() { Point.prototype.copy = function () {
if (this.debug) this.check()
return new Point(this.x, this.y) return new Point(this.x, this.y)
} }
/** Mirrors this point around X value of that point */ /** Mirrors this point around X value of that point */
Point.prototype.flipX = function(that = false) { Point.prototype.flipX = function (that = false) {
if (this.debug) {
this.check()
if (that) {
if (that instanceof Point !== true)
this.raise.warning('Called `Point.rotate(deg,that)` but `that` is not a `Point` object')
that.check()
}
}
if (that === false || that.x === 0) return new Point(this.x * -1, this.y) if (that === false || that.x === 0) return new Point(this.x * -1, this.y)
else return new Point(that.x + this.dx(that), this.y) else return new Point(that.x + this.dx(that), this.y)
} }
/** Mirrors this point around Y value of that point */ /** Mirrors this point around Y value of that point */
Point.prototype.flipY = function(that = false) { Point.prototype.flipY = function (that = false) {
if (this.debug) {
this.check()
if (that) {
if (that instanceof Point !== true)
this.raise.warning('Called `Point.flipY(that)` but `that` is not a `Point` object')
that.check()
}
}
if (that === false || that.y === 0) return new Point(this.x, this.y * -1) if (that === false || that.y === 0) return new Point(this.x, this.y * -1)
else return new Point(this.x, that.y + this.dy(that)) else return new Point(this.x, that.y + this.dy(that))
} }
/** Shifts this point distance in the deg direction */ /** Shifts this point distance in the deg direction */
Point.prototype.shift = function(deg, distance) { Point.prototype.shift = function (deg, distance) {
if (this.debug) {
this.check()
if (typeof distance !== 'number')
this.raise.warning('Called `Point.shift` but `distance` is not a number')
}
let p = this.copy() let p = this.copy()
p.x += distance p.x += distance
@ -92,35 +156,81 @@ Point.prototype.shift = function(deg, distance) {
} }
/** Shifts this point distance in the direction of that point */ /** Shifts this point distance in the direction of that point */
Point.prototype.shiftTowards = function(that, distance) { Point.prototype.shiftTowards = function (that, distance) {
if (this.debug) {
if (typeof distance !== 'number')
this.raise.warning('Called `Point.shiftTowards` but `distance` is not a number')
if (that instanceof Point !== true)
this.raise.warning(
'Called `Point.shiftTowards(that, distance)` but `that` is not a `Point` object'
)
this.check()
that.check()
}
if (this.debug) this.check()
return this.shift(this.angle(that), distance) return this.shift(this.angle(that), distance)
} }
/** Checks whether this has the same coordinates as that */ /** Checks whether this has the same coordinates as that */
Point.prototype.sitsOn = function(that) { Point.prototype.sitsOn = function (that) {
if (this.debug) {
if (that instanceof Point !== true)
this.raise.warning('Called `Point.sitsOn(that)` but `that` is not a `Point` object')
this.check()
that.check()
}
if (this.x === that.x && this.y === that.y) return true if (this.x === that.x && this.y === that.y) return true
else return false else return false
} }
/** Checks whether this has roughly the same coordinates as that */ /** Checks whether this has roughly the same coordinates as that */
Point.prototype.sitsRoughlyOn = function(that) { Point.prototype.sitsRoughlyOn = function (that) {
if (this.debug) {
if (that instanceof Point !== true)
this.raise.warning('Called `Point.sitsRoughlyOn(that)` but `that` is not a `Point` object')
this.check()
that.check()
}
if (Math.round(this.x) === Math.round(that.x) && Math.round(this.y) === Math.round(that.y)) if (Math.round(this.x) === Math.round(that.x) && Math.round(this.y) === Math.round(that.y))
return true return true
else return false else return false
} }
/** Shifts this point fraction of the distance towards that point */ /** Shifts this point fraction of the distance towards that point */
Point.prototype.shiftFractionTowards = function(that, fraction) { Point.prototype.shiftFractionTowards = function (that, fraction) {
if (this.debug) {
if (that instanceof Point !== true)
this.raise.warning(
'Called `Point.shiftFractionTowards(that, fraction)` but `that` is not a `Point` object'
)
if (typeof fraction !== 'number')
this.raise.warning('Called `Point.shiftFractionTowards` but `fraction` is not a number')
this.check()
that.check()
}
return this.shiftTowards(that, this.dist(that) * fraction) return this.shiftTowards(that, this.dist(that) * fraction)
} }
/** Shifts this point distance beyond that point */ /** Shifts this point distance beyond that point */
Point.prototype.shiftOutwards = function(that, distance) { Point.prototype.shiftOutwards = function (that, distance) {
if (this.debug) {
if (that instanceof Point !== true)
this.raise.warning(
'Called `Point.shiftOutwards(that, distance)` but `that` is not a `Point` object'
)
if (typeof distance !== 'number')
this.raise.warning(
'Called `Point.shiftOutwards(that, distance)` but `distance` is not a number'
)
this.check()
that.check()
}
return this.shiftTowards(that, this.dist(that) + distance) return this.shiftTowards(that, this.dist(that) + distance)
} }
/** Returns a deep copy of this */ /** Returns a deep copy of this */
Point.prototype.clone = function() { Point.prototype.clone = function () {
if (this.debug) this.check()
let clone = new Point(this.x, this.y) let clone = new Point(this.x, this.y)
clone.attributes = this.attributes.clone() clone.attributes = this.attributes.clone()
@ -128,7 +238,14 @@ Point.prototype.clone = function() {
} }
/** Applies a translate transform */ /** Applies a translate transform */
Point.prototype.translate = function(x, y) { Point.prototype.translate = function (x, y) {
if (this.debug) {
this.check()
if (typeof x !== 'number')
this.raise.warning('Called `Point.translate(x,y)` but `x` is not a number')
if (typeof y !== 'number')
this.raise.warning('Called `Point.translate(x,y)` but `y` is not a number')
}
let p = this.copy() let p = this.copy()
p.x += x p.x += x
p.y += y p.y += y

View file

@ -1,6 +1,14 @@
import Attributes from './attributes' import Attributes from './attributes'
import Point from './point'
function Snippet(def, anchor) { function Snippet(def, anchor, raise = false) {
this.debug = raise ? true : false
if (this.debug) {
if (typeof def !== 'string')
raise.warning('Called `new Snippet(def, anchor)` but `def` is not a string')
if (anchor instanceof Point !== true)
raise.warning('Called `new Snippet(dev, anchor)` but `anchor` is not a `Point` object')
}
this.def = def this.def = def
this.anchor = anchor this.anchor = anchor
this.attributes = new Attributes() this.attributes = new Attributes()
@ -9,7 +17,7 @@ function Snippet(def, anchor) {
} }
/** Adds an attribute. This is here to make this call chainable in assignment */ /** Adds an attribute. This is here to make this call chainable in assignment */
Snippet.prototype.attr = function(name, value, overwrite = false) { Snippet.prototype.attr = function (name, value, overwrite = false) {
if (overwrite) this.attributes.set(name, value) if (overwrite) this.attributes.set(name, value)
else this.attributes.add(name, value) else this.attributes.add(name, value)
@ -17,7 +25,7 @@ Snippet.prototype.attr = function(name, value, overwrite = false) {
} }
/** Returns a deep copy of this */ /** Returns a deep copy of this */
Snippet.prototype.clone = function() { Snippet.prototype.clone = function () {
let clone = new Snippet(this.def, this.anchor.clone()) let clone = new Snippet(this.def, this.anchor.clone())
clone.attributes = this.attributes.clone() clone.attributes = this.attributes.clone()

View file

@ -1,19 +1,22 @@
function Store() { function Store(raise) {
this.data = new Map() this.data = new Map()
this.raise = raise
} }
/** Sets a value under index key */ /** Sets a value under index key */
Store.prototype.set = function(key, value) { Store.prototype.set = function (key, value) {
this.data.set(key, value) this.data.set(key, value)
} }
/** Sets a value under index key */ /** Sets a value under index key */
Store.prototype.setIfUnset = function(key, value) { Store.prototype.setIfUnset = function (key, value) {
if (!this.data.has(key)) this.data.set(key, value) if (!this.data.has(key)) this.data.set(key, value)
} }
/** Gets a value under index key */ /** Gets a value under index key */
Store.prototype.get = function(key) { Store.prototype.get = function (key) {
if (!this.data.has(key))
this.raise.warning(`Tried to access \`${key}\` in the \`store\` but it is not set`)
return this.data.get(key) return this.data.get(key)
} }

View file

@ -6,6 +6,13 @@ export function capitalize(string) {
return string.charAt(0).toUpperCase() + string.slice(1) return string.charAt(0).toUpperCase() + string.slice(1)
} }
/** Checks for a valid coordinate value **/
export function isCoord(value) {
return value === value // NaN does not equal itself
? typeof value === 'number'
: false
}
/** Returns internal hook name for a macro */ /** Returns internal hook name for a macro */
export function macroName(name) { export function macroName(name) {
return `_macro_${name}` return `_macro_${name}`

View file

@ -25,6 +25,7 @@
"react-dom": "^16.13", "react-dom": "^16.13",
"react-scripts": "^3.4.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"react-markdown": "4.3.1",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
"scripts": { "scripts": {

View file

@ -5,6 +5,7 @@
@import 'components/draft-design'; @import 'components/draft-design';
@import 'components/topicstoc'; @import 'components/topicstoc';
@import 'components/breadcrumbs'; @import 'components/breadcrumbs';
@import 'components/event';
@import 'components/example'; @import 'components/example';
@import 'components/fab'; @import 'components/fab';
@import 'components/spinner'; @import 'components/spinner';

View file

@ -0,0 +1,58 @@
div.draft-events {
margin: 2rem auto;
max-width: 900px;
div.draft-event {
margin: 0.5rem auto;
line-height: 1.1;
font-size: 85%;
padding: 0.5rem;
border: 1px dotted black;
border-radius: 3px;
position: relative;
padding-left: 36px;
div.icon {
position: absolute;
top: 0;
left: 6px;
padding: 2px;
border-bottom-left-radius: 12px;
border-bottom-right-radius: 12px;
color: white;
line-height: 0.4;
display: inline-block;
}
div.icon svg {
font-size: 20px;
}
div.icon.debug {
background: $oc-grape-5;
}
div.icon.info {
background: $oc-blue-6;
}
div.icon.warning {
background: $oc-orange-6;
}
div.icon.error {
background: $oc-red-6;
}
p:first-of-type {
margin-top: 0;
}
p:last-of-type {
margin-bottom: 0;
}
}
div.draft-event.debug {
border-color: $oc-grape-5;
}
div.draft-event.info {
border-color: $oc-blue-6;
}
div.draft-event.warning {
border-color: $oc-orange-6;
}
div.draft-event.error {
border-color: $oc-red-6;
}
}

View file

@ -1,14 +1,16 @@
code[class*="language-"], code[class*='language-'],
pre[class*="language-"] { pre[class*='language-'] {
text-shadow: none; text-shadow: none;
} }
.theme-wrapper.light :not(pre) > code[class*="language-"] { .workbench.theme-wrapper.light code,
.theme-wrapper.light :not(pre) > code[class*='language-'] {
padding: 0.1rem 0.25rem; padding: 0.1rem 0.25rem;
background: $oc-yellow-0; background: $oc-yellow-0;
border: 1px $oc-yellow-2 solid; border: 1px $oc-yellow-2 solid;
color: $oc-gray-9; color: $oc-gray-9;
} }
.theme-wrapper.dark :not(pre) > code[class*="language-"] { .workbench.theme-wrapper.dark code,
.theme-wrapper.dark :not(pre) > code[class*='language-'] {
padding: 0.125rem 0.5rem; padding: 0.125rem 0.5rem;
background: $oc-gray-9; background: $oc-gray-9;
border: 1px $oc-gray-7 solid; border: 1px $oc-gray-7 solid;
@ -42,46 +44,46 @@ pre.language-bash:before {
text-shadow: none; text-shadow: none;
} }
pre.language-yaml:before { pre.language-yaml:before {
content: "yaml"; content: 'yaml';
background: rgba(255, 255, 0, 0.9); background: rgba(255, 255, 0, 0.9);
} }
pre.language-js:before { pre.language-js:before {
content: "js"; content: 'js';
background: rgba(255, 255, 0, 0.9); background: rgba(255, 255, 0, 0.9);
} }
pre.language-jsx:before { pre.language-jsx:before {
content: "jsx"; content: 'jsx';
background: rgba(255, 255, 0, 0.9); background: rgba(255, 255, 0, 0.9);
} }
pre.language-mdx:before { pre.language-mdx:before {
content: "mdx"; content: 'mdx';
background: rgba(130, 201, 30, 0.9); background: rgba(130, 201, 30, 0.9);
} }
pre.language-json:before { pre.language-json:before {
content: "json"; content: 'json';
background: rgba(255, 255, 0, 0.9); background: rgba(255, 255, 0, 0.9);
} }
pre.language-bash:before { pre.language-bash:before {
content: "bash"; content: 'bash';
background: rgba(29, 227, 0, 0.9); background: rgba(29, 227, 0, 0.9);
} }
pre.language-svg:before { pre.language-svg:before {
content: "svg"; content: 'svg';
background: rgba(129, 197, 255, 0.9); background: rgba(129, 197, 255, 0.9);
} }
pre code[class*="language-"], pre code[class*='language-'],
pre[class*="language-"] { pre[class*='language-'] {
white-space: pre-wrap; white-space: pre-wrap;
border-radius: 6px; border-radius: 6px;
margin: 2rem 0; margin: 2rem 0;
padding: 1.5rem 0; padding: 1.5rem 0;
} }
.theme-wrapper.dark pre[class*="language-"] { .theme-wrapper.dark pre[class*='language-'] {
border: 1px solid $oc-gray-8; border: 1px solid $oc-gray-8;
} }
@include xs-screen { @include xs-screen {
pre code[class*="language-"], pre code[class*='language-'],
pre[class*="language-"] { pre[class*='language-'] {
margin: 2rem -1.5rem; margin: 2rem -1.5rem;
padding: 1.5rem; padding: 1.5rem;
border-radius: 0; border-radius: 0;
@ -97,5 +99,3 @@ pre[class*="language-"] {
right: calc(20px - 1.5rem); right: calc(20px - 1.5rem);
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,15 +16,16 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"react-markdown": "4.3.1",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
"scripts": { "scripts": {
@ -43,6 +44,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -1,4 +1,4 @@
export default part => { export default (part) => {
let { let {
measurements, measurements,
Point, Point,
@ -299,10 +299,7 @@ export default part => {
// //
// Now recreate the paths and let Simon take it from here // Now recreate the paths and let Simon take it from here
// //
paths.dart = new Path() paths.dart = new Path().move(points.dartBottom).line(points.bustDartTip).line(points.dartTop)
.move(points.dartBottom)
.line(points.bustDartTip)
.line(points.dartTop)
paths.saBaseFromHips = new Path() paths.saBaseFromHips = new Path()
.move(points.hips) .move(points.hips)
.curve(points.hipsCp2, points.waistCp1, points.waist) .curve(points.hipsCp2, points.waistCp1, points.waist)
@ -327,10 +324,7 @@ export default part => {
points.bballEnd = points.hem.shiftFractionTowards(points.hips, options.hemCurve) points.bballEnd = points.hem.shiftFractionTowards(points.hips, options.hemCurve)
points.bballCp1 = points.bballStart.shiftFractionTowards(points.hem, 0.5) points.bballCp1 = points.bballStart.shiftFractionTowards(points.hem, 0.5)
points.bballCp2 = new Point(points.bballCp1.x, points.bballEnd.y) points.bballCp2 = new Point(points.bballCp1.x, points.bballEnd.y)
paths.saBase = new Path() paths.saBase = new Path().move(points.bballEnd).line(points.hips).join(paths.saBaseFromHips)
.move(points.bballEnd)
.line(points.hips)
.join(paths.saBaseFromHips)
paths.hemBase = new Path() paths.hemBase = new Path()
.move(points.cfHem) .move(points.cfHem)
.line(points.bballStart) .line(points.bballStart)
@ -351,10 +345,7 @@ export default part => {
.curve(points.slashCp2, points.slashCp1, points.slashStart) .curve(points.slashCp2, points.slashCp1, points.slashStart)
break break
default: default:
paths.saBase = new Path() paths.saBase = new Path().move(points.hem).line(points.hips).join(paths.saBaseFromHips)
.move(points.hem)
.line(points.hips)
.join(paths.saBaseFromHips)
paths.hemBase = new Path().move(points.cfHem).line(points.hem) paths.hemBase = new Path().move(points.cfHem).line(points.hem)
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }

View file

@ -16,14 +16,14 @@
"@freesewing/plugin-i18n": "latest", "@freesewing/plugin-i18n": "latest",
"@freesewing/plugin-svgattr": "latest", "@freesewing/plugin-svgattr": "latest",
"@freesewing/utils": "latest", "@freesewing/utils": "latest",
"@material-ui/core": "^4.4.0", "@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.2.1", "@material-ui/icons": "^4.9.1",
"@material-ui/lab": "^v4.0.0-alpha.25", "@material-ui/lab": "^v4.0.0-alpha.56",
"pattern": "link:..", "pattern": "link:..",
"prismjs": "1.17.1", "prismjs": "1.20.0",
"react": "^16.9", "react": "^16.13",
"react-dom": "^16.9", "react-dom": "^16.13",
"react-scripts": "^3.1.1", "react-scripts": "^3.4.1",
"file-saver": "^2.0.2", "file-saver": "^2.0.2",
"typeface-roboto-condensed": "latest" "typeface-roboto-condensed": "latest"
}, },
@ -43,6 +43,6 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"babel-plugin-prismjs": "1.1.1" "babel-plugin-prismjs": "2.0.1"
} }
} }