chore: Merged in cleaned up lily branch
This commit is contained in:
commit
13a390e707
30 changed files with 1931 additions and 134 deletions
|
@ -85,6 +85,10 @@ jaeger:
|
||||||
'@freesewing/brian': *freesewing
|
'@freesewing/brian': *freesewing
|
||||||
'@freesewing/bent': *freesewing
|
'@freesewing/bent': *freesewing
|
||||||
'@freesewing/plugin-bust': *freesewing
|
'@freesewing/plugin-bust': *freesewing
|
||||||
|
lily:
|
||||||
|
peer:
|
||||||
|
'@freesewing/titan': *freesewing
|
||||||
|
'@freesewing/paco': *freesewing
|
||||||
new-design:
|
new-design:
|
||||||
_:
|
_:
|
||||||
'axios': &axios '1.6.8'
|
'axios': &axios '1.6.8'
|
||||||
|
|
|
@ -34,6 +34,8 @@ packageJson:
|
||||||
private: true
|
private: true
|
||||||
lab:
|
lab:
|
||||||
private: true
|
private: true
|
||||||
|
lily:
|
||||||
|
author: Anna Puk (https://github.com/anna-puk)
|
||||||
lucy:
|
lucy:
|
||||||
author: SeaZeeZee (https://github.com/SeaZeeZee)
|
author: SeaZeeZee (https://github.com/SeaZeeZee)
|
||||||
lunetius: &starf
|
lunetius: &starf
|
||||||
|
|
|
@ -554,14 +554,25 @@
|
||||||
"techniques": []
|
"techniques": []
|
||||||
},
|
},
|
||||||
"naomiwu": {
|
"naomiwu": {
|
||||||
"description": "A FreeSewing pattern for Naomi Wu's signature cargo skirt",
|
|
||||||
"code": "Joost De Cock",
|
"code": "Joost De Cock",
|
||||||
"design": ["Naomi Wu", "Joost De Cock"],
|
"description": "A FreeSewing pattern for Naomi Wu's signature cargo skirt",
|
||||||
|
"design": [
|
||||||
|
"Naomi Wu",
|
||||||
|
"Joost De Cock"
|
||||||
|
],
|
||||||
"difficulty": 3,
|
"difficulty": 3,
|
||||||
"lab": false,
|
"lab": false,
|
||||||
"org": false,
|
"org": false,
|
||||||
"tags": ["bottoms", "skirts"],
|
"tags": [
|
||||||
"techniques": ["button", "hem", "pocket", "lining"]
|
"bottoms",
|
||||||
|
"skirts"
|
||||||
|
],
|
||||||
|
"techniques": [
|
||||||
|
"button",
|
||||||
|
"hem",
|
||||||
|
"pocket",
|
||||||
|
"lining"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"noble": {
|
"noble": {
|
||||||
"code": "Wouter Van Wageningen",
|
"code": "Wouter Van Wageningen",
|
||||||
|
@ -976,5 +987,21 @@
|
||||||
"hem",
|
"hem",
|
||||||
"button"
|
"button"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"lily": {
|
||||||
|
"code": "Anna Puk, Joost De Cock",
|
||||||
|
"description": "A FreeSewing pattern for basic leggings",
|
||||||
|
"design": "Anna Puk",
|
||||||
|
"difficulty": 2,
|
||||||
|
"lab": true,
|
||||||
|
"org": true,
|
||||||
|
"tags": [
|
||||||
|
"bottoms"
|
||||||
|
],
|
||||||
|
"techniques": [
|
||||||
|
"elastic",
|
||||||
|
"curvedSeam",
|
||||||
|
"hem"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
17
designs/lily/CHANGELOG.md
Normal file
17
designs/lily/CHANGELOG.md
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
# Change log for: @freesewing/lily
|
||||||
|
|
||||||
|
|
||||||
|
## 3.0.0 (2023-09-30)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- All FreeSewing packages are now ESM only.
|
||||||
|
- All FreeSewing packages now use named exports.
|
||||||
|
- Dropped support for NodeJS 14. NodeJS 18 (LTS/hydrogen) or more recent is now required.
|
||||||
|
|
||||||
|
|
||||||
|
This is the **initial release**, and the start of this change log.
|
||||||
|
|
||||||
|
> Prior to version 2, FreeSewing was not a JavaScript project.
|
||||||
|
> As such, that history is out of scope for this change log.
|
||||||
|
|
162
designs/lily/README.md
Normal file
162
designs/lily/README.md
Normal file
|
@ -0,0 +1,162 @@
|
||||||
|
<p align='center'><a
|
||||||
|
href="https://www.npmjs.com/package/@freesewing/lily"
|
||||||
|
title="@freesewing/lily on NPM"
|
||||||
|
><img src="https://img.shields.io/npm/v/@freesewing/lily.svg"
|
||||||
|
alt="@freesewing/lily on NPM"/>
|
||||||
|
</a><a
|
||||||
|
href="https://opensource.org/licenses/MIT"
|
||||||
|
title="License: MIT"
|
||||||
|
><img src="https://img.shields.io/npm/l/@freesewing/lily.svg?label=License"
|
||||||
|
alt="License: MIT"/>
|
||||||
|
</a><a
|
||||||
|
href="https://deepscan.io/dashboard#view=project&tid=2114&pid=2993&bid=23256"
|
||||||
|
title="Code quality on DeepScan"
|
||||||
|
><img src="https://deepscan.io/api/teams/2114/projects/2993/branches/23256/badge/grade.svg"
|
||||||
|
alt="Code quality on DeepScan"/>
|
||||||
|
</a><a
|
||||||
|
href="https://github.com/freesewing/freesewing/issues?q=is%3Aissue+is%3Aopen+label%3Apkg%3Alily"
|
||||||
|
title="Open issues tagged pkg:lily"
|
||||||
|
><img src="https://img.shields.io/github/issues/freesewing/freesewing/pkg:lily.svg?label=Issues"
|
||||||
|
alt="Open issues tagged pkg:lily"/>
|
||||||
|
</a><a
|
||||||
|
href="#contributors-"
|
||||||
|
title="All Contributors"
|
||||||
|
><img src="https://img.shields.io/badge/all_contributors-126-pink.svg"
|
||||||
|
alt="All Contributors"/>
|
||||||
|
</a></p><p align='center'><a
|
||||||
|
href="https://twitter.com/freesewing_org"
|
||||||
|
title="Follow @freesewing_org on Twitter"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-blue.svg?logo=twitter&logoColor=white&logoWidth=15"
|
||||||
|
alt="Follow @freesewing_org on Twitter"/>
|
||||||
|
</a><a
|
||||||
|
href="https://chat.freesewing.org"
|
||||||
|
title="Chat with us on Discord"
|
||||||
|
><img src="https://img.shields.io/discord/698854858052075530?label=Chat%20on%20Discord"
|
||||||
|
alt="Chat with us on Discord"/>
|
||||||
|
</a><a
|
||||||
|
href="https://freesewing.org/patrons/join"
|
||||||
|
title="Become a FreeSewing Patron"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Support%20us-blueviolet.svg?logo=cash-app&logoColor=white&logoWidth=15"
|
||||||
|
alt="Become a FreeSewing Patron"/>
|
||||||
|
</a><a
|
||||||
|
href="https://instagram.com/freesewing_org"
|
||||||
|
title="Follow @freesewing_org on Twitter"
|
||||||
|
><img src="https://img.shields.io/badge/%F3%A0%80%A0-Follow%20us-E4405F.svg?logo=instagram&logoColor=white&logoWidth=15"
|
||||||
|
alt="Follow @freesewing_org on Twitter"/>
|
||||||
|
</a></p>
|
||||||
|
|
||||||
|
# @freesewing/lily
|
||||||
|
|
||||||
|
A FreeSewing pattern for basic leggings
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# FreeSewing
|
||||||
|
|
||||||
|
> [!TIP]
|
||||||
|
>#### Support FreeSewing: Become a patron, or make a one-time donation 🥰
|
||||||
|
>
|
||||||
|
> FreeSewing is an open source project maintained by Joost De Cock and financially supported by the FreeSewing patrons.
|
||||||
|
>
|
||||||
|
> If you feel FreeSewing is worthwhile, and you can spend a few coins without
|
||||||
|
hardship, then you should [join us and become a patron](https://freesewing.org/community/join).
|
||||||
|
|
||||||
|
## What am I looking at? 🤔
|
||||||
|
|
||||||
|
This repository is the FreeSewing *monorepo* holding all FreeSewing's websites, documentation, designs, plugins, and other NPM packages.
|
||||||
|
|
||||||
|
This folder holds: @freesewing/lily
|
||||||
|
|
||||||
|
If you're not entirely sure what to do or how to start, type this command:
|
||||||
|
|
||||||
|
```
|
||||||
|
npm run tips
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> If you don't want to set up a dev environment, you can run it in your browser:
|
||||||
|
>
|
||||||
|
> [](https://gitpod.io/#https://github.com/freesewing/freesewing)
|
||||||
|
>
|
||||||
|
> We recommend that you fork our repository and then
|
||||||
|
> put `gitpod.io/#<entire-url-of-your-fork` into a browser
|
||||||
|
> to start up a browser-based dev environment of your own.
|
||||||
|
|
||||||
|
## About FreeSewing 💀
|
||||||
|
|
||||||
|
Where the world of makers and developers collide, that's where you'll find FreeSewing.
|
||||||
|
|
||||||
|
If you're a maker, checkout [freesewing.org](https://freesewing.org/) where you can generate
|
||||||
|
sewing patterns adapted to your measurements.
|
||||||
|
|
||||||
|
If you're a developer, the FreeSewing documentation lives at [freesewing.dev](https://freesewing.dev/).
|
||||||
|
The FreeSewing [core library](https://freesewing.dev/reference/api/) is a *batteries-included* toolbox
|
||||||
|
for parametric design of sewing patterns. But FreeSewing also provides a range
|
||||||
|
of [plugins](https://freesewing.dev/reference/plugins/) that further extend the
|
||||||
|
functionality of the platform.
|
||||||
|
|
||||||
|
If you have NodeJS installed, you can try it right now by running:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @freesewing/new-design
|
||||||
|
```
|
||||||
|
|
||||||
|
Getting started guides are available for:
|
||||||
|
- [Linux](https://freesewing.dev/tutorials/getting-started-linux/)
|
||||||
|
- [MacOS](https://freesewing.dev/tutorials/getting-started-mac/)
|
||||||
|
- [Windows](https://freesewing.dev/tutorials/getting-started-windows/)
|
||||||
|
|
||||||
|
The [pattern design tutorial](https://freesewing.dev/tutorials/pattern-design/) will
|
||||||
|
show you how to create your first parametric design.
|
||||||
|
|
||||||
|
## Getting started ⚡
|
||||||
|
|
||||||
|
To get started with FreeSewing, you can spin up our development environment with:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
npx @freesewing/new-design
|
||||||
|
```
|
||||||
|
|
||||||
|
To work with FreeSewing's monorepo, you'll need [NodeJS v18](https://nodejs.org), [lerna](https://lerna.js.org/) and [yarn](https://yarnpkg.com/) on your system.
|
||||||
|
Once you have those, clone (or fork) this repo and run `yarn kickstart`:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git clone git@github.com:freesewing/freesewing.git
|
||||||
|
cd freesewing
|
||||||
|
yarn kickstart
|
||||||
|
```
|
||||||
|
|
||||||
|
## Links 👩💻
|
||||||
|
|
||||||
|
**Official channels**
|
||||||
|
|
||||||
|
- 💻 Makers website: [FreeSewing.org](https://freesewing.org)
|
||||||
|
- 💻 Developers website: [FreeSewing.dev](https://freesewing.dev)
|
||||||
|
- ✅ [Support](https://github.com/freesewing/freesewing/issues/new/choose),
|
||||||
|
[Issues](https://github.com/freesewing/freesewing/issues) &
|
||||||
|
[Discussions](https://github.com/freesewing/freesewing/discussions) on
|
||||||
|
[GitHub](https://github.com/freesewing/freesewing)
|
||||||
|
|
||||||
|
**Social media**
|
||||||
|
|
||||||
|
- 🐦 Twitter: [@freesewing_org](https://twitter.com/freesewing_org)
|
||||||
|
- 📷 Instagram: [@freesewing_org](https://instagram.com/freesewing_org)
|
||||||
|
|
||||||
|
**Places the FreeSewing community hangs out**
|
||||||
|
|
||||||
|
- 💬 [Discord](https://discord.freesewing.org/)
|
||||||
|
- 💬 [Facebook](https://www.facebook.com/groups/627769821272714/)
|
||||||
|
- 💬 [Reddit](https://www.reddit.com/r/freesewing/)
|
||||||
|
|
||||||
|
## License: MIT 🤓
|
||||||
|
|
||||||
|
© [Joost De Cock](https://github.com/joostdecock).
|
||||||
|
See [the license file](https://github.com/freesewing/freesewing/blob/develop/LICENSE) for details.
|
||||||
|
|
||||||
|
## Where to get help 🤯
|
||||||
|
|
||||||
|
For [Support](https://github.com/freesewing/freesewing/issues/new/choose),
|
||||||
|
please use the [Issues](https://github.com/freesewing/freesewing/issues) &
|
||||||
|
[Discussions](https://github.com/freesewing/freesewing/discussions) on
|
||||||
|
[GitHub](https://github.com/freesewing/freesewing).
|
||||||
|
|
35
designs/lily/build.mjs
Normal file
35
designs/lily/build.mjs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
/* This script will build the package with esbuild */
|
||||||
|
import esbuild from 'esbuild'
|
||||||
|
import pkg from './package.json' assert { type: 'json' }
|
||||||
|
|
||||||
|
// Create banner based on package info
|
||||||
|
const banner = `/**
|
||||||
|
* ${pkg.name} | v${pkg.version}
|
||||||
|
* ${pkg.description}
|
||||||
|
* (c) ${new Date().getFullYear()} ${pkg.author}
|
||||||
|
* @license ${pkg.license}
|
||||||
|
*/`
|
||||||
|
|
||||||
|
// Shared esbuild options
|
||||||
|
const options = {
|
||||||
|
banner: { js: banner },
|
||||||
|
bundle: true,
|
||||||
|
entryPoints: ['src/index.mjs'],
|
||||||
|
format: 'esm',
|
||||||
|
outfile: 'dist/index.mjs',
|
||||||
|
external: ['@freesewing'],
|
||||||
|
metafile: process.env.VERBOSE ? true : false,
|
||||||
|
minify: process.env.NO_MINIFY ? false : true,
|
||||||
|
sourcemap: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Let esbuild generate the build
|
||||||
|
const build = async () => {
|
||||||
|
const result = await esbuild.build(options).catch(() => process.exit(1))
|
||||||
|
|
||||||
|
if (process.env.VERBOSE) {
|
||||||
|
const info = await esbuild.analyzeMetafile(result.metafile)
|
||||||
|
console.log(info)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
build()
|
4
designs/lily/data.mjs
Normal file
4
designs/lily/data.mjs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
// This file is auto-generated | All changes you make will be overwritten.
|
||||||
|
export const name = '@freesewing/lily'
|
||||||
|
export const version = '3.2.0'
|
||||||
|
export const data = { name, version }
|
7
designs/lily/i18n/de.json
Normal file
7
designs/lily/i18n/de.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern that needs a description",
|
||||||
|
"p": { },
|
||||||
|
"s": { },
|
||||||
|
"o": { }
|
||||||
|
}
|
24
designs/lily/i18n/en.json
Normal file
24
designs/lily/i18n/en.json
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern for basic leggings",
|
||||||
|
"p": {
|
||||||
|
"back": "Back",
|
||||||
|
"front": "Front",
|
||||||
|
"waistband": "Waistband"
|
||||||
|
},
|
||||||
|
"s": {
|
||||||
|
"adjustEase.t": "Adjust ease settings to match fabric stretch",
|
||||||
|
"adjustEase.d": "Knee, seat and waist ease should be set to fabric stretch * -1/10; click the button to adjust all three.",
|
||||||
|
"adjustEase": "adjust ease"
|
||||||
|
},
|
||||||
|
"o": {
|
||||||
|
"lengthReduction": {
|
||||||
|
"t": "Length reduction",
|
||||||
|
"d": "Controls how much the leggings are shortened with respect to ankle length"
|
||||||
|
},
|
||||||
|
"fabricStretch": {
|
||||||
|
"t": "Fabric stretch",
|
||||||
|
"d": "How much the fabric can stretch horizontally; this is used to calculate ease"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
designs/lily/i18n/es.json
Normal file
7
designs/lily/i18n/es.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern that needs a description",
|
||||||
|
"p": { },
|
||||||
|
"s": { },
|
||||||
|
"o": { }
|
||||||
|
}
|
7
designs/lily/i18n/fr.json
Normal file
7
designs/lily/i18n/fr.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern that needs a description",
|
||||||
|
"p": { },
|
||||||
|
"s": { },
|
||||||
|
"o": { }
|
||||||
|
}
|
8
designs/lily/i18n/index.mjs
Normal file
8
designs/lily/i18n/index.mjs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import en from './en.json' assert { type: 'json' }
|
||||||
|
import de from './de.json' assert { type: 'json' }
|
||||||
|
import es from './es.json' assert { type: 'json' }
|
||||||
|
import fr from './fr.json' assert { type: 'json' }
|
||||||
|
import nl from './nl.json' assert { type: 'json' }
|
||||||
|
import uk from './uk.json' assert { type: 'json' }
|
||||||
|
|
||||||
|
export const i18n = { en, de, es, fr, nl, uk }
|
7
designs/lily/i18n/nl.json
Normal file
7
designs/lily/i18n/nl.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern that needs a description",
|
||||||
|
"p": { },
|
||||||
|
"s": { },
|
||||||
|
"o": { }
|
||||||
|
}
|
7
designs/lily/i18n/uk.json
Normal file
7
designs/lily/i18n/uk.json
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
{
|
||||||
|
"t": "Lily",
|
||||||
|
"d": "A FreeSewing pattern that needs a description",
|
||||||
|
"p": { },
|
||||||
|
"s": { },
|
||||||
|
"o": { }
|
||||||
|
}
|
74
designs/lily/package.json
Normal file
74
designs/lily/package.json
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
{
|
||||||
|
"name": "@freesewing/lily",
|
||||||
|
"version": "3.2.0",
|
||||||
|
"description": "A FreeSewing pattern for basic leggings",
|
||||||
|
"author": "Anna Puk (https://github.com/anna-puk)",
|
||||||
|
"homepage": "https://freesewing.org/",
|
||||||
|
"repository": "github:freesewing/freesewing",
|
||||||
|
"license": "MIT",
|
||||||
|
"bugs": {
|
||||||
|
"url": "https://github.com/freesewing/freesewing/issues"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://freesewing.org/patrons/join"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"freesewing",
|
||||||
|
"design",
|
||||||
|
"diy",
|
||||||
|
"fashion",
|
||||||
|
"made to measure",
|
||||||
|
"parametric design",
|
||||||
|
"pattern",
|
||||||
|
"sewing",
|
||||||
|
"sewing pattern"
|
||||||
|
],
|
||||||
|
"type": "module",
|
||||||
|
"module": "dist/index.mjs",
|
||||||
|
"exports": {
|
||||||
|
".": {
|
||||||
|
"internal": "./src/index.mjs",
|
||||||
|
"default": "./dist/index.mjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"build": "node build.mjs",
|
||||||
|
"build:all": "yarn build",
|
||||||
|
"clean": "rimraf dist",
|
||||||
|
"mbuild": "NO_MINIFY=1 node build.mjs",
|
||||||
|
"symlink": "mkdir -p ./node_modules/@freesewing && cd ./node_modules/@freesewing && ln -s -f ../../../* . && cd -",
|
||||||
|
"test": "npx mocha tests/*.test.mjs",
|
||||||
|
"vbuild": "VERBOSE=1 node build.mjs",
|
||||||
|
"lab": "cd ../../sites/lab && yarn start",
|
||||||
|
"tips": "node ../../scripts/help.mjs",
|
||||||
|
"lint": "npx eslint 'src/**' 'tests/*.mjs'",
|
||||||
|
"prettier": "npx prettier --write 'src/*.mjs' 'tests/*.mjs'",
|
||||||
|
"testci": "NODE_OPTIONS=\"--conditions=internal\" npx mocha tests/*.test.mjs --reporter ../../tests/reporters/terse.js",
|
||||||
|
"wbuild": "node build.mjs",
|
||||||
|
"wbuild:all": "yarn wbuild"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@freesewing/core": "3.2.0",
|
||||||
|
"@freesewing/titan": "3.2.0",
|
||||||
|
"@freesewing/paco": "3.2.0"
|
||||||
|
},
|
||||||
|
"dependencies": {},
|
||||||
|
"devDependencies": {
|
||||||
|
"mocha": "10.3.0",
|
||||||
|
"chai": "5.1.0",
|
||||||
|
"@freesewing/models": "3.2.0",
|
||||||
|
"@freesewing/plugin-timing": "3.2.0"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"dist/*",
|
||||||
|
"README.md"
|
||||||
|
],
|
||||||
|
"publishConfig": {
|
||||||
|
"access": "public",
|
||||||
|
"tag": "latest"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 18.17.0 <22"
|
||||||
|
}
|
||||||
|
}
|
590
designs/lily/src/back.mjs
Normal file
590
designs/lily/src/back.mjs
Normal file
|
@ -0,0 +1,590 @@
|
||||||
|
import { back as titanBack } from '@freesewing/titan'
|
||||||
|
|
||||||
|
function draftLilyBack({
|
||||||
|
points,
|
||||||
|
Point,
|
||||||
|
paths,
|
||||||
|
Path,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
complete,
|
||||||
|
paperless,
|
||||||
|
store,
|
||||||
|
macro,
|
||||||
|
utils,
|
||||||
|
snippets,
|
||||||
|
Snippet,
|
||||||
|
sa,
|
||||||
|
absoluteOptions,
|
||||||
|
part,
|
||||||
|
log,
|
||||||
|
units,
|
||||||
|
}) {
|
||||||
|
//TODO: implement stretch setting to replace ease
|
||||||
|
// work-around: flag it
|
||||||
|
const stretchAsEase = -options.fabricStretch / 10
|
||||||
|
const easeTol = 0.005
|
||||||
|
if (
|
||||||
|
Math.abs(options.waistEase - stretchAsEase) > easeTol ||
|
||||||
|
Math.abs(options.seatEase - stretchAsEase) > easeTol ||
|
||||||
|
Math.abs(options.kneeEase - stretchAsEase) > easeTol
|
||||||
|
) {
|
||||||
|
store.flag.note({
|
||||||
|
msg: `lily:adjustEase`,
|
||||||
|
replace: {
|
||||||
|
stretch: units(options.fabricStretch),
|
||||||
|
ease: stretchAsEase,
|
||||||
|
},
|
||||||
|
suggest: {
|
||||||
|
text: 'adjustEase',
|
||||||
|
icon: 'options',
|
||||||
|
update: {
|
||||||
|
settings: [
|
||||||
|
'options',
|
||||||
|
{
|
||||||
|
...options,
|
||||||
|
waistEase: stretchAsEase,
|
||||||
|
seatEase: stretchAsEase,
|
||||||
|
kneeEase: stretchAsEase,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Helper method to draw the inseam path
|
||||||
|
*/
|
||||||
|
const drawInseam = () =>
|
||||||
|
new Path()
|
||||||
|
.move(points.fork)
|
||||||
|
.curve(points.forkCp2, points.kneeInCp1, points.kneeIn)
|
||||||
|
.curve(points.kneeInCp2, points.floorInCp2, points.floorIn)
|
||||||
|
/*
|
||||||
|
* Helper method to draw the outseam path
|
||||||
|
*/
|
||||||
|
const drawOutseam = () => {
|
||||||
|
const waistOut = points.styleWaistOutLily || points.waistOut
|
||||||
|
if (points.waistOut.x > points.seatOut.x)
|
||||||
|
return new Path()
|
||||||
|
.move(points.floorOut)
|
||||||
|
.curve(points.floorOutCp2, points.kneeOutCp1, points.kneeOut)
|
||||||
|
.curve(points.kneeOutCp2, points.seatOut, waistOut)
|
||||||
|
else
|
||||||
|
return new Path()
|
||||||
|
.move(points.floorOut)
|
||||||
|
.curve(points.floorOutCp2, points.kneeOutCp1, points.kneeOut)
|
||||||
|
.curve(points.kneeOutCp2, points.seatOutCp1, points.seatOut)
|
||||||
|
.curve_(points.seatOutCp2, waistOut)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to draw the outline path
|
||||||
|
*/
|
||||||
|
const drawPath = () => {
|
||||||
|
const waistIn = points.styleWaistInLily || points.waistIn
|
||||||
|
return drawInseam()
|
||||||
|
.line(points.floorOut)
|
||||||
|
.join(drawOutseam())
|
||||||
|
.line(waistIn)
|
||||||
|
.line(points.crossSeamCurveStart)
|
||||||
|
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to calculate the length of the cross seam
|
||||||
|
*/
|
||||||
|
const crossSeamDelta = () =>
|
||||||
|
new Path()
|
||||||
|
.move(points.waistIn)
|
||||||
|
.line(points.crossSeamCurveStart)
|
||||||
|
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
|
||||||
|
.length() - measurements.crossSeamBack
|
||||||
|
/*
|
||||||
|
* Helper method to (re)draw the cross seam
|
||||||
|
*/
|
||||||
|
const drawCrossSeam = () => {
|
||||||
|
points.crossSeamCurveStart = points.waistIn.shiftFractionTowards(
|
||||||
|
points.cbSeat,
|
||||||
|
options.crossSeamCurveStart
|
||||||
|
)
|
||||||
|
points.crossSeamCurveMax = utils.beamsIntersect(
|
||||||
|
points.waistIn,
|
||||||
|
points.cbSeat,
|
||||||
|
points.fork,
|
||||||
|
points.fork.shift(0, 1) // beams have infinite length anyway
|
||||||
|
)
|
||||||
|
points.crossSeamCurveCp1 = points.crossSeamCurveStart.shiftFractionTowards(
|
||||||
|
points.crossSeamCurveMax,
|
||||||
|
options.crossSeamCurveBend
|
||||||
|
)
|
||||||
|
points.crossSeamCurveCp2 = points.fork
|
||||||
|
.shiftFractionTowards(points.crossSeamCurveMax, options.crossSeamCurveBend)
|
||||||
|
.rotate(options.crossSeamCurveAngle, points.fork)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: majority of points re-used from titan
|
||||||
|
|
||||||
|
// shape at the ankle (unlike titan)
|
||||||
|
const halfAnkle =
|
||||||
|
measurements.ankle * (1 + options.fabricStretch) > measurements.heel
|
||||||
|
? (1 - options.fabricStretch / 10) * (measurements.ankle / 4)
|
||||||
|
: measurements.heel / 4 / (1 + options.fabricStretch)
|
||||||
|
// NOTE: for shortened leggings, this may not have been necessary...
|
||||||
|
|
||||||
|
points.floorOut = points.floor.shift(0, halfAnkle)
|
||||||
|
points.floorIn = points.floorOut.flipX(points.floor)
|
||||||
|
|
||||||
|
store.set('halfAnkle', halfAnkle)
|
||||||
|
|
||||||
|
points.floorInCp2 = points.floorIn.shift(90, points.knee.dy(points.floor) / 3)
|
||||||
|
points.kneeInCp2 = points.kneeIn.shift(90, -points.knee.dy(points.floor) / 3)
|
||||||
|
points.floorOutCp2 = points.floorOut.shift(90, points.knee.dy(points.floor) / 3)
|
||||||
|
points.kneeOutCp1 = points.kneeOut.shift(90, -points.knee.dy(points.floor) / 3)
|
||||||
|
|
||||||
|
// other control points have already been calculated in titan:
|
||||||
|
// Control points to shape the legs towards the seat
|
||||||
|
// Balance the waist
|
||||||
|
|
||||||
|
// Cross seam
|
||||||
|
drawCrossSeam()
|
||||||
|
|
||||||
|
//Uncomment the line below to see the seam prior to fitting the cross seam
|
||||||
|
// paths.seam1 = drawPath().attr('class', 'dashed lining')
|
||||||
|
|
||||||
|
// Should we fit the cross seam?
|
||||||
|
if (options.fitCrossSeam && options.fitCrossSeamBack) {
|
||||||
|
let delta = crossSeamDelta()
|
||||||
|
let run = 0
|
||||||
|
do {
|
||||||
|
run++
|
||||||
|
// Remedy A: Slash and spread
|
||||||
|
for (const i of ['waistIn', 'waistOut'])
|
||||||
|
points[i] = points[i].rotate(delta / 15, points.seatOut)
|
||||||
|
// Remedy B: Nudge the fork inwards/outwards
|
||||||
|
points.fork = points.fork.shift(0, delta / 5)
|
||||||
|
points.forkCp2 = points.crossSeamCurveCp2.rotate(-90, points.fork)
|
||||||
|
drawCrossSeam()
|
||||||
|
delta = crossSeamDelta()
|
||||||
|
// Uncomment the line beloe this to see all iterations
|
||||||
|
// paths[`try${run}`] = drawPath().attr('class', 'dotted')
|
||||||
|
} while (Math.abs(delta) > 1 && run < 15)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store inseam & outseam length
|
||||||
|
store.set('inseamBack', drawInseam().length())
|
||||||
|
store.set('outseamBack', drawOutseam().length())
|
||||||
|
|
||||||
|
// Only now style the waist lower if requested
|
||||||
|
// Note: redo this for lily even though it was already done for titan;
|
||||||
|
// calculation for titan happened using its own seam lengths
|
||||||
|
store.set('waistbandWidth', absoluteOptions.waistbandWidth) // used in lilyWaistband
|
||||||
|
if (options.waistHeight < 1 || absoluteOptions.waistbandWidth > 0) {
|
||||||
|
points.styleWaistOutLily = drawOutseam()
|
||||||
|
.reverse()
|
||||||
|
.shiftAlong(
|
||||||
|
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth
|
||||||
|
)
|
||||||
|
points.styleWaistInLily = utils.beamsIntersect(
|
||||||
|
points.styleWaistOutLily,
|
||||||
|
points.styleWaistOutLily.shift(points.waistOut.angle(points.waistIn), 10),
|
||||||
|
points.waistIn,
|
||||||
|
points.crossSeamCurveStart
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
points.styleWaistInLily = points.waistIn.clone()
|
||||||
|
points.styleWaistOutLily = points.waistOut.clone()
|
||||||
|
}
|
||||||
|
// Adapt the vertical placement of the seat control point to the lowered waist
|
||||||
|
points.seatOutCp2.y = points.seatOut.y - points.styleWaistOutLily.dy(points.seatOut) / 2
|
||||||
|
let test = points.styleWaistInLily.dist(points.styleWaistOutLily)
|
||||||
|
console.log('back waist length', test)
|
||||||
|
store.set('backWaist', points.styleWaistInLily.dist(points.styleWaistOutLily))
|
||||||
|
|
||||||
|
// Paths
|
||||||
|
paths.seam = drawPath().attr('class', 'fabric')
|
||||||
|
|
||||||
|
// adjust the length (at the bottom)
|
||||||
|
let extendBeyondKnee = 1
|
||||||
|
if (options.lengthReduction > 0) {
|
||||||
|
let requestedLength = (1 - options.lengthReduction) * measurements.waistToFloor
|
||||||
|
// leggings must reach to fork at least, so define a minimum
|
||||||
|
const waistToFork = points.waistX.dy(points.fork)
|
||||||
|
if (waistToFork >= 0.999 * requestedLength) {
|
||||||
|
log.warn('length reduction capped; cutting off at fork')
|
||||||
|
// add one percent to waistToFork to ensure that path length is nonzero
|
||||||
|
requestedLength = waistToFork * 1.01
|
||||||
|
}
|
||||||
|
|
||||||
|
// work-around to avoid splitting exactly at the knee
|
||||||
|
// (due to a bug, splitting a path at a node is not possible)
|
||||||
|
if (
|
||||||
|
0.999 < requestedLength / measurements.waistToKnee &&
|
||||||
|
requestedLength / measurements.waistToKnee < 1.001
|
||||||
|
) {
|
||||||
|
requestedLength = 1.001 * measurements.waistToKnee
|
||||||
|
}
|
||||||
|
points.bottom = points.waistX.shift(270, requestedLength)
|
||||||
|
let upperPoint, upperCp
|
||||||
|
if (requestedLength < measurements.waistToKnee) {
|
||||||
|
extendBeyondKnee = 0
|
||||||
|
|
||||||
|
// 'cut' between fork and knee
|
||||||
|
if (points.waistOut.x > points.seatOut.x) {
|
||||||
|
upperPoint = points.styleWaistOutLily
|
||||||
|
upperCp = points.seatOut
|
||||||
|
} else {
|
||||||
|
upperPoint = points.seatOut
|
||||||
|
upperCp = points.seatOutCp1
|
||||||
|
}
|
||||||
|
points.bottomOut = utils.beamIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp2,
|
||||||
|
upperCp,
|
||||||
|
upperPoint
|
||||||
|
)
|
||||||
|
|
||||||
|
points.bottomIn = utils.beamIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeIn,
|
||||||
|
points.kneeInCp1,
|
||||||
|
points.forkCp2,
|
||||||
|
points.fork
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// 'cut' between knee and 'floor'
|
||||||
|
points.bottomOut = utils.beamIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp1,
|
||||||
|
points.floorOutCp2,
|
||||||
|
points.floorOut
|
||||||
|
)
|
||||||
|
|
||||||
|
points.bottomIn = utils.beamIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeIn,
|
||||||
|
points.kneeInCp2,
|
||||||
|
points.floorInCp2,
|
||||||
|
points.floorIn
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the three parts of the path, then combine
|
||||||
|
paths.bottom = new Path().move(points.bottomIn).line(points.bottomOut)
|
||||||
|
|
||||||
|
const halves = paths.seam.split(points.bottomIn)
|
||||||
|
paths.upperInseam = halves[0]
|
||||||
|
const halves2 = halves[1].split(points.bottomOut)
|
||||||
|
paths.upperOutseam = halves2[1]
|
||||||
|
|
||||||
|
paths.seam = paths.upperInseam.join(paths.bottom).join(paths.upperOutseam)
|
||||||
|
|
||||||
|
// store requestedLength for use in front part
|
||||||
|
store.set('requestedLength', requestedLength)
|
||||||
|
} else {
|
||||||
|
// define the same three parts of the path as when length reduction is enabled, then combine
|
||||||
|
|
||||||
|
// first define the points (also used for paperless)
|
||||||
|
points.bottom = points.floor
|
||||||
|
points.bottomIn = points.floorIn
|
||||||
|
points.bottomOut = points.floorOut
|
||||||
|
|
||||||
|
paths.bottom = new Path().move(points.bottomIn).line(points.bottomOut)
|
||||||
|
|
||||||
|
// note: upperOutseam contains waist and cross seam as well
|
||||||
|
paths.upperInseam = drawInseam()
|
||||||
|
paths.upperOutseam = drawOutseam().join(
|
||||||
|
new Path()
|
||||||
|
.move(points.styleWaistOutLily)
|
||||||
|
.line(points.styleWaistInLily)
|
||||||
|
.line(points.crossSeamCurveStart)
|
||||||
|
.curve(points.crossSeamCurveCp1, points.crossSeamCurveCp2, points.fork)
|
||||||
|
)
|
||||||
|
paths.bottom.hide()
|
||||||
|
paths.upperInseam.hide()
|
||||||
|
paths.upperOutseam.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
points.grainlineTop.y = points.styleWaistOutLily.y
|
||||||
|
points.grainlineBottom.y = points.bottom.y
|
||||||
|
macro('grainline', {
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.grainlineBottom,
|
||||||
|
})
|
||||||
|
points.logoAnchor = new Point(points.crossSeamCurveStart.x / 2, points.fork.y)
|
||||||
|
snippets.logo = new Snippet('logo', points.logoAnchor)
|
||||||
|
points.scalebox = points.logoAnchor.shiftFractionTowards(
|
||||||
|
points.styleWaistOutLily.shiftFractionTowards(points.styleWaistInLily, 0.5),
|
||||||
|
0.5
|
||||||
|
)
|
||||||
|
macro('scalebox', { at: points.scalebox })
|
||||||
|
points.titleAnchor = points.logoAnchor.shift(-90, 60)
|
||||||
|
macro('title', {
|
||||||
|
nr: 1,
|
||||||
|
title: 'back',
|
||||||
|
at: points.titleAnchor,
|
||||||
|
})
|
||||||
|
|
||||||
|
//notches
|
||||||
|
if (options.fitGuides) {
|
||||||
|
points.waistMid = points.waistOut.shiftFractionTowards(points.waistIn, 0.5)
|
||||||
|
// shift + rotate (below) is equivalent to shifting measurements.waistToSeat perpendicular to the waistIn-waistMid line
|
||||||
|
points.seatMid = points.waistMid
|
||||||
|
.shiftTowards(points.waistIn, measurements.waistToSeat)
|
||||||
|
.rotate(90, points.waistMid)
|
||||||
|
points.seatInTarget = points.seatOut.shiftOutwards(points.seatMid, measurements.seat / 4)
|
||||||
|
points.seatOutTarget = points.seatMid.shiftTowards(points.seatOut, measurements.seat / 4)
|
||||||
|
// shift + rotate (below) is equivalent to shifting measurements.waistToHips perpendicular to the waistIn-waistOut line
|
||||||
|
points.hipsInTarget = points.waistIn
|
||||||
|
.shiftTowards(points.waistOut, measurements.waistToHips)
|
||||||
|
.rotate(-90, points.waistIn)
|
||||||
|
points.hipsOutTarget = points.waistOut
|
||||||
|
.shiftTowards(points.waistIn, measurements.waistToHips)
|
||||||
|
.rotate(90, points.waistOut)
|
||||||
|
points.hipsIn = utils.beamsIntersect(
|
||||||
|
points.hipsOutTarget,
|
||||||
|
points.hipsInTarget,
|
||||||
|
points.waistIn,
|
||||||
|
points.crossSeamCurveStart
|
||||||
|
)
|
||||||
|
points.crossSeamCurveStartMid = utils.beamsIntersect(
|
||||||
|
points.crossSeamCurveStart,
|
||||||
|
points.crossSeamCurveStart.shift(points.waistIn.angle(points.waistOut), 1),
|
||||||
|
points.waistMid,
|
||||||
|
points.seatMid
|
||||||
|
)
|
||||||
|
if (points.seatMid.y > points.crossSeamCurveStartMid.y) {
|
||||||
|
points.seatIn = utils.lineIntersectsCurve(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatInTarget,
|
||||||
|
points.crossSeamCurveStart,
|
||||||
|
points.crossSeamCurveCp1,
|
||||||
|
points.crossSeamCurveCp2,
|
||||||
|
points.fork
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
points.seatIn = utils.beamsIntersect(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatInTarget,
|
||||||
|
points.waistIn,
|
||||||
|
points.crossSeamCurveStart
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (points.waistOut.x > points.seatOut.x) {
|
||||||
|
points.hipsOut = utils.lineIntersectsCurve(
|
||||||
|
points.hipsIn,
|
||||||
|
points.hipsIn.rotate(180, points.hipsOutTarget),
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp2,
|
||||||
|
points.seatOut,
|
||||||
|
points.waistOut
|
||||||
|
)
|
||||||
|
points.seatOutNotch = utils.lineIntersectsCurve(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatOutTarget,
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp2,
|
||||||
|
points.seatOut,
|
||||||
|
points.waistOut
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
points.hipsOut = utils.lineIntersectsCurve(
|
||||||
|
points.hipsIn,
|
||||||
|
points.hipsIn.rotate(180, points.hipsOutTarget),
|
||||||
|
points.seatOut,
|
||||||
|
points.seatOutCp2,
|
||||||
|
points.waistOut,
|
||||||
|
points.waistOut
|
||||||
|
)
|
||||||
|
points.seatOutNotch = points.seatOut
|
||||||
|
}
|
||||||
|
points.kneeOutNotch = points.kneeOut
|
||||||
|
points.kneeInNotch = points.kneeIn
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'notch',
|
||||||
|
on: ['seatOutNotch'],
|
||||||
|
})
|
||||||
|
if (extendBeyondKnee) {
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'notch',
|
||||||
|
on: ['kneeInNotch', 'kneeOutNotch'],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'bnotch',
|
||||||
|
on: ['crossSeamCurveStart', 'seatIn'],
|
||||||
|
})
|
||||||
|
|
||||||
|
if (complete) {
|
||||||
|
paths.seatline = new Path()
|
||||||
|
.move(points.seatIn)
|
||||||
|
.line(points.seatOutNotch)
|
||||||
|
.addClass('fabric help')
|
||||||
|
.addText('Seat Line', 'center')
|
||||||
|
if (
|
||||||
|
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth <
|
||||||
|
measurements.waistToHips
|
||||||
|
) {
|
||||||
|
snippets.hipsIn = new Snippet('bnotch', points.hipsIn)
|
||||||
|
snippets.hipsOut = new Snippet('notch', points.hipsOut)
|
||||||
|
paths.hipline = new Path()
|
||||||
|
.move(points.hipsIn)
|
||||||
|
.line(points.hipsOut)
|
||||||
|
.addClass('fabric help')
|
||||||
|
.addText('Hip Line', 'center')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa) {
|
||||||
|
paths.saBase = paths.upperOutseam.join(paths.upperInseam).hide()
|
||||||
|
paths.hemBase = paths.bottom.hide()
|
||||||
|
paths.sa = paths.hemBase
|
||||||
|
.offset(sa * 3)
|
||||||
|
.join(paths.saBase.offset(sa))
|
||||||
|
.close()
|
||||||
|
.addClass('fabric sa')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (paperless) {
|
||||||
|
// Help construct cross seam
|
||||||
|
paths.hint = new Path()
|
||||||
|
.move(points.crossSeamCurveStart)
|
||||||
|
.line(points.crossSeamCurveMax)
|
||||||
|
.line(points.fork)
|
||||||
|
.addClass('note lashed')
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHem',
|
||||||
|
from: points.bottomIn,
|
||||||
|
to: points.bottomOut,
|
||||||
|
y: points.bottomIn.y - 30,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHemLeft',
|
||||||
|
from: points.bottomIn,
|
||||||
|
to: points.bottom,
|
||||||
|
y: points.bottomIn.y - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHemRight',
|
||||||
|
from: points.bottom,
|
||||||
|
to: points.bottomOut,
|
||||||
|
y: points.bottomIn.y - 15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hHemToSideWaist',
|
||||||
|
from: points.bottomOut,
|
||||||
|
to: points.styleWaistOutLily,
|
||||||
|
x:
|
||||||
|
(points.seatOut.x > points.styleWaistOutLily.x
|
||||||
|
? points.seatOut.x
|
||||||
|
: points.styleWaistOutLily.x) +
|
||||||
|
sa +
|
||||||
|
15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hHemToFork',
|
||||||
|
from: points.bottomIn,
|
||||||
|
to: points.fork,
|
||||||
|
x: points.fork.x - sa - 15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hForkToCbWaist',
|
||||||
|
from: points.fork,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
x: points.fork.x - sa - 15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hFull',
|
||||||
|
from: points.bottomIn,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
x: points.fork.x - sa - 30,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hStartCrotchCurveToCbWaist',
|
||||||
|
from: points.crossSeamCurveStart,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
x: points.crossSeamCurveStart.x - sa - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wCbWaistToPleat',
|
||||||
|
from: points.styleWaistInLily,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wStartCrotchCurveToPleat',
|
||||||
|
from: points.crossSeamCurveStart,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 30,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wForkProjectionToPleat',
|
||||||
|
from: points.crossSeamCurveMax,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 45,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wForkToPleat',
|
||||||
|
from: points.fork,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 60,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToSideWaist',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.styleWaistOutLily,
|
||||||
|
y: points.styleWaistInLily.y - sa - 15,
|
||||||
|
})
|
||||||
|
if (points.seatOut.x > points.styleWaistOutLily.x) {
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToSideWaistAlt',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.seatOut,
|
||||||
|
y: points.styleWaistInLily.y - sa - 30,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
|
||||||
|
export const back = {
|
||||||
|
name: 'lily.back',
|
||||||
|
from: titanBack,
|
||||||
|
//after: titanFront,
|
||||||
|
measurements: [
|
||||||
|
'ankle',
|
||||||
|
'heel', // secondary measurement, used instead of ankle
|
||||||
|
],
|
||||||
|
options: {
|
||||||
|
fitGuides: { bool: false, menu: 'advanced' },
|
||||||
|
fitKnee: { bool: true, hide: true },
|
||||||
|
legBalance: 0.5, // between back and front parts
|
||||||
|
waistBalance: 0.5,
|
||||||
|
crotchDrop: { pct: 0, min: 0, max: 15, menu: 'advanced' }, // 'downgrade' to advanced menu
|
||||||
|
waistHeight: { ...titanBack.options.waistHeight, pct: 50 }, // halfway between waist and hips
|
||||||
|
fabricStretch: { pct: 40, min: 0, max: 50, menu: 'fit' },
|
||||||
|
waistEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
|
||||||
|
seatEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
|
||||||
|
kneeEase: { pct: -4, min: -20, max: 0, menu: 'fit' }, // -fabricStretch/10,
|
||||||
|
//test: {pct: back.options.fabricStretch/2, min: 0, max: 50, menu: 'fit'},
|
||||||
|
lengthBonus: 0,
|
||||||
|
lengthReduction: {
|
||||||
|
pct: 0,
|
||||||
|
min: 0,
|
||||||
|
max: 100,
|
||||||
|
toAbs: (pct, { measurements }) => measurements.waistToFloor * pct,
|
||||||
|
menu: 'style',
|
||||||
|
},
|
||||||
|
waistbandWidth: { ...titanBack.options.waistbandWidth, menu: 'style' },
|
||||||
|
},
|
||||||
|
hide: 'HIDE_TREE',
|
||||||
|
draft: draftLilyBack,
|
||||||
|
}
|
602
designs/lily/src/front.mjs
Normal file
602
designs/lily/src/front.mjs
Normal file
|
@ -0,0 +1,602 @@
|
||||||
|
import { front as titanFront } from '@freesewing/titan'
|
||||||
|
import { back } from './back.mjs'
|
||||||
|
|
||||||
|
function draftLilyFront({
|
||||||
|
points,
|
||||||
|
Point,
|
||||||
|
paths,
|
||||||
|
Path,
|
||||||
|
measurements,
|
||||||
|
options,
|
||||||
|
complete,
|
||||||
|
paperless,
|
||||||
|
store,
|
||||||
|
macro,
|
||||||
|
utils,
|
||||||
|
snippets,
|
||||||
|
Snippet,
|
||||||
|
sa,
|
||||||
|
absoluteOptions,
|
||||||
|
log,
|
||||||
|
part,
|
||||||
|
}) {
|
||||||
|
/*
|
||||||
|
* Helper method to draw the inseam path
|
||||||
|
*/
|
||||||
|
const drawInseam = () =>
|
||||||
|
new Path()
|
||||||
|
.move(points.floorIn)
|
||||||
|
.curve(points.floorInCp2, points.kneeInCp1, points.kneeIn)
|
||||||
|
.curve(points.kneeInCp2, points.forkCp1, points.fork)
|
||||||
|
/*
|
||||||
|
* Helper method to draw the outseam path
|
||||||
|
*/
|
||||||
|
const drawOutseam = () => {
|
||||||
|
const waistOut = points.styleWaistOutLily || points.waistOut
|
||||||
|
return points.waistOut.x < points.seatOut.x
|
||||||
|
? new Path()
|
||||||
|
.move(waistOut)
|
||||||
|
.curve(points.seatOut, points.kneeOutCp1, points.kneeOut)
|
||||||
|
.curve(points.kneeOutCp2, points.floorOutCp2, points.floorOut)
|
||||||
|
: new Path()
|
||||||
|
.move(waistOut)
|
||||||
|
._curve(points.seatOutCp1, points.seatOut)
|
||||||
|
.curve(points.seatOutCp2, points.kneeOutCp1, points.kneeOut)
|
||||||
|
.curve(points.kneeOutCp2, points.floorOutCp2, points.floorOut)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to draw the outline path
|
||||||
|
*/
|
||||||
|
const drawPath = () => {
|
||||||
|
const waistIn = points.styleWaistInLily || points.waistIn
|
||||||
|
const waistOut = points.styleWaistOutLily || points.waistOut
|
||||||
|
return drawOutseam()
|
||||||
|
.line(points.floorIn)
|
||||||
|
.join(drawInseam())
|
||||||
|
.curve(points.crotchSeamCurveCp1, points.crotchSeamCurveCp2, points.crotchSeamCurveStart)
|
||||||
|
.line(waistIn)
|
||||||
|
.line(waistOut)
|
||||||
|
.close()
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to calculate the length of the crotch seam
|
||||||
|
*/
|
||||||
|
const crotchSeamDelta = () =>
|
||||||
|
new Path()
|
||||||
|
.move(points.waistIn)
|
||||||
|
.line(points.crotchSeamCurveStart)
|
||||||
|
.curve(points.crotchSeamCurveCp2, points.crotchSeamCurveCp1, points.fork)
|
||||||
|
.length() - measurements.crossSeamFront
|
||||||
|
/*
|
||||||
|
* Helper method to (re)draw the crotch seam
|
||||||
|
*/
|
||||||
|
const drawCrotchSeam = () => {
|
||||||
|
points.crotchSeamCurveStart = points.waistIn.shiftFractionTowards(
|
||||||
|
points.cfSeat,
|
||||||
|
options.crotchSeamCurveStart
|
||||||
|
)
|
||||||
|
points.crotchSeamCurveMax = utils.beamsIntersect(
|
||||||
|
points.waistIn,
|
||||||
|
points.cfSeat,
|
||||||
|
points.fork,
|
||||||
|
points.fork.shift(0, 666)
|
||||||
|
)
|
||||||
|
points.crotchSeamCurveCp1 = points.fork
|
||||||
|
.shiftFractionTowards(points.crotchSeamCurveMax, options.crotchSeamCurveBend)
|
||||||
|
.rotate(options.crotchSeamCurveAngle * -1, points.fork)
|
||||||
|
points.crotchSeamCurveCp2 = points.crotchSeamCurveStart.shiftFractionTowards(
|
||||||
|
points.crotchSeamCurveMax,
|
||||||
|
options.crotchSeamCurveBend
|
||||||
|
)
|
||||||
|
points.forkCp1 = points.crotchSeamCurveCp1.rotate(90, points.fork)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to calculate the inseam delta
|
||||||
|
*/
|
||||||
|
const inseamDelta = () => drawInseam().length() - store.get('inseamBack')
|
||||||
|
/*
|
||||||
|
* Helper method to calculate the outseam delta
|
||||||
|
*/
|
||||||
|
const outseamDelta = () => drawOutseam().length() - store.get('outseamBack')
|
||||||
|
/*
|
||||||
|
* Helper method to lengthen/shorten both inseam and outseam
|
||||||
|
*/
|
||||||
|
const adaptInseamAndOutseam = () => {
|
||||||
|
const shift = [
|
||||||
|
'kneeInCp1',
|
||||||
|
'kneeInCp2',
|
||||||
|
'kneeOutCp1',
|
||||||
|
'kneeOutCp2',
|
||||||
|
'kneeIn',
|
||||||
|
'kneeOut',
|
||||||
|
'knee',
|
||||||
|
'floorInCp2',
|
||||||
|
'floorIn',
|
||||||
|
'floorOutCp2',
|
||||||
|
'floorOut',
|
||||||
|
'floor',
|
||||||
|
'grainlineBottom',
|
||||||
|
]
|
||||||
|
let delta = seamDelta()
|
||||||
|
let run = 0
|
||||||
|
do {
|
||||||
|
run++
|
||||||
|
for (const i of shift) points[i] = points[i].shift(90, delta)
|
||||||
|
delta = seamDelta()
|
||||||
|
} while (Math.abs(delta) > 1 && run < 10)
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method to determine the delta common when both inseam and outseam
|
||||||
|
* are either too long or too short
|
||||||
|
*/
|
||||||
|
const seamDelta = () => {
|
||||||
|
const inseam = inseamDelta()
|
||||||
|
const outseam = outseamDelta()
|
||||||
|
return Math.abs(inseam) > Math.abs(outseam) ? outseam : inseam
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Helper method that can fit either inseam or outseam
|
||||||
|
*/
|
||||||
|
const adaptSeam = (side) => {
|
||||||
|
const out = side === 'out' ? true : false
|
||||||
|
const rotate = [
|
||||||
|
'cfSeat',
|
||||||
|
'crotchSeamCurveCp1',
|
||||||
|
'crotchSeamCurveCp2',
|
||||||
|
'crotchSeamCurveStart',
|
||||||
|
'waistIn',
|
||||||
|
'cfWaist',
|
||||||
|
'waistOut',
|
||||||
|
]
|
||||||
|
rotate.push(out ? 'seatOut' : 'fork')
|
||||||
|
const deltaMethod = out ? outseamDelta : inseamDelta
|
||||||
|
let run = 0
|
||||||
|
let delta = deltaMethod()
|
||||||
|
do {
|
||||||
|
for (const i of rotate)
|
||||||
|
points[i] = points[i].rotate(
|
||||||
|
(delta / 10) * (out ? 1 : -1),
|
||||||
|
points[out ? 'fork' : 'seatOut']
|
||||||
|
)
|
||||||
|
run++
|
||||||
|
delta = deltaMethod()
|
||||||
|
} while (Math.abs(delta) > 1 && run < 20)
|
||||||
|
}
|
||||||
|
const adaptOutseam = () => adaptSeam('out')
|
||||||
|
const adaptInseam = () => adaptSeam('in')
|
||||||
|
|
||||||
|
// NOTE: majority of points re-used from titan
|
||||||
|
|
||||||
|
// shape at the ankle (unlike titan)
|
||||||
|
points.floorOut = points.floor.shift(180, store.get('halfAnkle'))
|
||||||
|
points.floorIn = points.floorOut.flipX(points.floor)
|
||||||
|
|
||||||
|
// Control points between knee and ankle
|
||||||
|
points.floorInCp2 = points.floorIn.shift(90, points.knee.dy(points.floor) / 3)
|
||||||
|
points.kneeInCp1 = points.kneeIn.shift(90, -points.knee.dy(points.floor) / 3)
|
||||||
|
points.floorOutCp2 = points.floorOut.shift(90, points.knee.dy(points.floor) / 3)
|
||||||
|
points.kneeOutCp2 = points.kneeOut.shift(90, -points.knee.dy(points.floor) / 3)
|
||||||
|
|
||||||
|
// other control points have already been calculated in titan
|
||||||
|
// Control points to shape the legs towards the seat
|
||||||
|
// Balance the waist
|
||||||
|
|
||||||
|
// Draw initial crotch seam
|
||||||
|
drawCrotchSeam()
|
||||||
|
|
||||||
|
// Uncomment this to see the outline prior to fitting the crotch seam
|
||||||
|
//paths.seam1 = drawPath().attr('class', 'dashed lining')
|
||||||
|
|
||||||
|
if (options.fitCrossSeam && options.fitCrossSeamFront) {
|
||||||
|
let delta = crotchSeamDelta()
|
||||||
|
let run = 0
|
||||||
|
do {
|
||||||
|
run++
|
||||||
|
// Remedy A: Slash and spread
|
||||||
|
for (const i of ['waistIn', 'waistOut', 'cfWaist'])
|
||||||
|
points[i] = points[i].rotate(delta / -15, points.seatOut)
|
||||||
|
// Remedy B: Nudge the fork inwards/outwards
|
||||||
|
points.fork = points.fork.shift(180, delta / 5)
|
||||||
|
drawCrotchSeam()
|
||||||
|
delta = crotchSeamDelta()
|
||||||
|
// Uncomment the line below this to see all iterations
|
||||||
|
//paths[`try${run}`] = drawPath().attr('class', 'dotted')
|
||||||
|
} while (Math.abs(delta) > 1 && run < 15)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Uncomment this to see the outline prior to fitting the inseam & outseam
|
||||||
|
//paths.seam2 = drawPath().attr('class', 'dotted interfacing')
|
||||||
|
|
||||||
|
/*
|
||||||
|
* With the cross seams matched back and front,
|
||||||
|
* all that's left is to match the inseam and outseam
|
||||||
|
*/
|
||||||
|
|
||||||
|
// When both are too short/long, adapt the leg length
|
||||||
|
if ((inseamDelta() < 0 && outseamDelta() < 0) || (inseamDelta() > 0 && outseamDelta() > 0))
|
||||||
|
adaptInseamAndOutseam()
|
||||||
|
|
||||||
|
// Now one is ok, the other will be adapted
|
||||||
|
adaptOutseam()
|
||||||
|
adaptInseam()
|
||||||
|
|
||||||
|
// Changing one will ever so slightly impact the other, so let's run both again to be sure
|
||||||
|
adaptOutseam()
|
||||||
|
adaptInseam()
|
||||||
|
|
||||||
|
// Only now style the waist lower if requested
|
||||||
|
// Note: redo this for lily even though it was already done for titan;
|
||||||
|
// calculation for titan happened using its own seam lengths
|
||||||
|
if (options.waistHeight < 1 || absoluteOptions.waistbandWidth > 0) {
|
||||||
|
points.styleWaistOutLily = drawOutseam().shiftAlong(
|
||||||
|
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth
|
||||||
|
)
|
||||||
|
points.styleWaistInLily = utils.beamsIntersect(
|
||||||
|
points.styleWaistOutLily,
|
||||||
|
points.styleWaistOutLily.shift(points.waistOut.angle(points.waistIn), 10),
|
||||||
|
points.waistIn,
|
||||||
|
points.crotchSeamCurveStart
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
points.styleWaistInLily = points.waistIn.clone()
|
||||||
|
points.styleWaistOutLily = points.waistOut.clone()
|
||||||
|
}
|
||||||
|
store.set('frontWaist', points.styleWaistInLily.dist(points.styleWaistOutLily))
|
||||||
|
|
||||||
|
// Now that the top of the garment has been lowered, adjust the
|
||||||
|
// crotchSeamCurveStart so it doesn't start above the top of the garment.
|
||||||
|
if (points.crotchSeamCurveStart.y < points.styleWaistInLily.y) {
|
||||||
|
points.crotchSeamCurveStart = points.styleWaistInLily.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Seamline
|
||||||
|
paths.seam = drawPath().attr('class', 'fabric')
|
||||||
|
|
||||||
|
// adjust the length (at the bottom)
|
||||||
|
let extendBeyondKnee = 1
|
||||||
|
if (options.lengthReduction > 0) {
|
||||||
|
let requestedLength = store.get('requestedLength')
|
||||||
|
// leggings must reach to fork at least, so define a minimum
|
||||||
|
let waistToFork = points.waistX.dy(points.fork)
|
||||||
|
let waistToKnee = points.waistX.dy(points.knee) // adapting the seams may have shifted the knee up or down
|
||||||
|
if (waistToFork > requestedLength) {
|
||||||
|
//log.warning('length reduction capped; cutting off at fork') // log only for back part
|
||||||
|
// add one percent to waistToFork to ensure that path length is nonzero
|
||||||
|
requestedLength = waistToFork * 1.01
|
||||||
|
}
|
||||||
|
|
||||||
|
// work-around to avoid splitting exactly at the knee
|
||||||
|
// (due to a bug, splitting a path at a node is not possible)
|
||||||
|
if (0.999 < requestedLength / waistToKnee && requestedLength / waistToKnee < 1.001) {
|
||||||
|
requestedLength = 1.001 * waistToKnee
|
||||||
|
}
|
||||||
|
points.bottom = points.waistX.shift(270, requestedLength)
|
||||||
|
let upperPoint, upperCp
|
||||||
|
if (requestedLength < waistToKnee) {
|
||||||
|
extendBeyondKnee = 0
|
||||||
|
|
||||||
|
// 'cut' between fork and knee
|
||||||
|
if (points.waistOut.x < points.seatOut.x) {
|
||||||
|
upperPoint = points.styleWaistOutLily
|
||||||
|
upperCp = points.seatOut
|
||||||
|
} else {
|
||||||
|
upperPoint = points.seatOut
|
||||||
|
upperCp = points.seatOutCp2
|
||||||
|
}
|
||||||
|
points.bottomOut = utils.lineIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp1,
|
||||||
|
upperCp,
|
||||||
|
upperPoint
|
||||||
|
)
|
||||||
|
|
||||||
|
points.bottomIn = utils.lineIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeIn,
|
||||||
|
points.kneeInCp2,
|
||||||
|
points.forkCp1,
|
||||||
|
points.fork
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// 'cut' between knee and 'floor'
|
||||||
|
points.bottomOut = utils.lineIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeOut,
|
||||||
|
points.kneeOutCp2,
|
||||||
|
points.floorOutCp2,
|
||||||
|
points.floorOut
|
||||||
|
)
|
||||||
|
|
||||||
|
points.bottomIn = utils.lineIntersectsCurve(
|
||||||
|
points.bottom.shift(0, 999),
|
||||||
|
points.bottom.shift(180, 999),
|
||||||
|
points.kneeIn,
|
||||||
|
points.kneeInCp1,
|
||||||
|
points.floorInCp2,
|
||||||
|
points.floorIn
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the three parts of the path, then combine
|
||||||
|
paths.bottom = new Path().move(points.bottomOut).line(points.bottomIn)
|
||||||
|
|
||||||
|
const halves = paths.seam.split(points.bottomOut)
|
||||||
|
paths.upperOutseam = halves[0]
|
||||||
|
const halves2 = halves[1].split(points.bottomIn)
|
||||||
|
paths.upperInseam = halves2[1]
|
||||||
|
|
||||||
|
paths.seam = paths.upperOutseam.join(paths.bottom).join(paths.upperInseam)
|
||||||
|
} else {
|
||||||
|
// define the same three parts of the path as when length reduction is enabled, then combine
|
||||||
|
|
||||||
|
// first define the points (also used for paperless)
|
||||||
|
points.bottom = points.floor
|
||||||
|
points.bottomIn = points.floorIn
|
||||||
|
points.bottomOut = points.floorOut
|
||||||
|
|
||||||
|
paths.bottom = new Path().move(points.bottomOut).line(points.bottomIn)
|
||||||
|
|
||||||
|
// note: upperInseam contains waist and cross seam as well
|
||||||
|
paths.upperInseam = drawInseam()
|
||||||
|
.curve(points.crotchSeamCurveCp1, points.crotchSeamCurveCp2, points.crotchSeamCurveStart)
|
||||||
|
.line(points.styleWaistInLily)
|
||||||
|
.line(points.styleWaistOutLily)
|
||||||
|
paths.upperOutseam = drawOutseam()
|
||||||
|
paths.bottom.hide()
|
||||||
|
paths.upperInseam.hide()
|
||||||
|
paths.upperOutseam.hide()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (complete) {
|
||||||
|
points.grainlineTop.y = points.styleWaistInLily.y
|
||||||
|
points.grainlineBottom.y = points.bottom.y
|
||||||
|
macro('grainline', {
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.grainlineBottom,
|
||||||
|
})
|
||||||
|
points.logoAnchor = new Point(points.crotchSeamCurveStart.x / 2, points.fork.y)
|
||||||
|
snippets.logo = new Snippet('logo', points.logoAnchor)
|
||||||
|
points.titleAnchor = points.logoAnchor.shift(-90, 60)
|
||||||
|
macro('title', {
|
||||||
|
nr: 2,
|
||||||
|
title: 'front',
|
||||||
|
at: points.titleAnchor,
|
||||||
|
})
|
||||||
|
|
||||||
|
//notches
|
||||||
|
if (options.fitGuides) {
|
||||||
|
points.waistMid = points.waistOut.shiftFractionTowards(points.waistIn, 0.5)
|
||||||
|
points.seatMid = points.waistMid
|
||||||
|
.shiftTowards(points.waistOut, measurements.waistToSeat)
|
||||||
|
.rotate(90, points.waistMid)
|
||||||
|
points.seatInTarget = points.seatOut.shiftOutwards(points.seatMid, measurements.seat / 4)
|
||||||
|
points.seatOutTarget = points.seatMid.shiftTowards(points.seatOut, measurements.seat / 4)
|
||||||
|
points.hipsInTarget = points.waistIn
|
||||||
|
.shiftTowards(points.waistOut, measurements.waistToHips)
|
||||||
|
.rotate(90, points.waistIn)
|
||||||
|
points.hipsOutTarget = points.waistOut
|
||||||
|
.shiftTowards(points.waistIn, measurements.waistToHips)
|
||||||
|
.rotate(-90, points.waistOut)
|
||||||
|
points.hipsIn = utils.beamsIntersect(
|
||||||
|
points.hipsOutTarget,
|
||||||
|
points.hipsInTarget,
|
||||||
|
points.waistIn,
|
||||||
|
points.crotchSeamCurveStart
|
||||||
|
)
|
||||||
|
// intersection between the vertical line from waistMid to seatMid and a line parallel to waistIn-waistOut that goes through crotchSeamCurveStart
|
||||||
|
points.crotchSeamCurveStartMid = utils.beamsIntersect(
|
||||||
|
points.crotchSeamCurveStart,
|
||||||
|
points.crotchSeamCurveStart.shift(points.waistIn.angle(points.waistOut), 1),
|
||||||
|
points.waistMid,
|
||||||
|
points.seatMid
|
||||||
|
)
|
||||||
|
// check whether intersection occurs above or below crotch seam curve start
|
||||||
|
points.seatInTemp = utils.beamsIntersect(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatInTarget,
|
||||||
|
points.crotchSeamCurveStart,
|
||||||
|
points.waistIn
|
||||||
|
) // NOTE: guaranteed to return a Point since the lines cannot be parallel
|
||||||
|
if (points.seatInTemp.y <= points.crotchSeamCurveStartMid.y) {
|
||||||
|
// intersection is above the crotch seam curve start, so on the line segment
|
||||||
|
points.seatIn = points.seatInTemp.clone()
|
||||||
|
} else if (points.seatInTemp.y > points.fork.y) {
|
||||||
|
// seat appears to be below crotch
|
||||||
|
log.warn('seat estimated to be below crotch; this is probably not accurate')
|
||||||
|
points.seatIn = points.fork.clone()
|
||||||
|
} else {
|
||||||
|
points.seatIn = utils.beamIntersectsCurve(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatInTarget,
|
||||||
|
points.crotchSeamCurveStart,
|
||||||
|
points.crotchSeamCurveCp2,
|
||||||
|
points.crotchSeamCurveCp1,
|
||||||
|
points.fork
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (points.waistOut.x < points.seatOut.x) {
|
||||||
|
//log.info('waist to the left of seat')
|
||||||
|
points.hipsOut = utils.lineIntersectsCurve(
|
||||||
|
points.hipsIn,
|
||||||
|
points.hipsIn.rotate(180, points.hipsOutTarget),
|
||||||
|
points.waistOut,
|
||||||
|
points.seatOut,
|
||||||
|
points.kneeOutCp1,
|
||||||
|
points.kneeOut
|
||||||
|
)
|
||||||
|
points.seatOutNotch = utils.lineIntersectsCurve(
|
||||||
|
points.seatMid,
|
||||||
|
points.seatOutTarget,
|
||||||
|
points.waistOut,
|
||||||
|
points.seatOut,
|
||||||
|
points.kneeOutCp1,
|
||||||
|
points.kneeOut
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
//log.info('waist to the right of seat')
|
||||||
|
points.hipsOut = utils.lineIntersectsCurve(
|
||||||
|
points.hipsIn,
|
||||||
|
points.hipsIn.rotate(180, points.hipsOutTarget),
|
||||||
|
points.waistOut,
|
||||||
|
points.waistOut,
|
||||||
|
points.seatOutCp1,
|
||||||
|
points.seatOut
|
||||||
|
)
|
||||||
|
points.seatOutNotch = points.seatOut
|
||||||
|
}
|
||||||
|
points.kneeOutNotch = points.kneeOut
|
||||||
|
points.kneeInNotch = points.kneeIn
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'notch',
|
||||||
|
on: ['crotchSeamCurveStart', 'seatIn', 'seatOutNotch'],
|
||||||
|
})
|
||||||
|
if (extendBeyondKnee) {
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'notch',
|
||||||
|
on: ['kneeInNotch', 'kneeOutNotch'],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
paths.seatline = new Path()
|
||||||
|
.move(points.seatOutNotch)
|
||||||
|
.line(points.seatIn)
|
||||||
|
.addClass('fabric help')
|
||||||
|
.addText('Seat Line', 'center')
|
||||||
|
if (
|
||||||
|
measurements.waistToHips * (1 - options.waistHeight) + absoluteOptions.waistbandWidth <
|
||||||
|
measurements.waistToHips
|
||||||
|
) {
|
||||||
|
macro('sprinkle', {
|
||||||
|
snippet: 'notch',
|
||||||
|
on: ['hipsIn', 'hipsOut'],
|
||||||
|
})
|
||||||
|
paths.hipline = new Path()
|
||||||
|
.move(points.hipsOut)
|
||||||
|
.line(points.hipsIn)
|
||||||
|
.addClass('fabric help')
|
||||||
|
.addText('Hip Line', 'center')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sa) {
|
||||||
|
paths.saBase = paths.upperInseam.join(paths.upperOutseam).hide()
|
||||||
|
paths.hemBase = paths.bottom.hide()
|
||||||
|
paths.sa = paths.hemBase
|
||||||
|
.offset(sa * 3)
|
||||||
|
.join(paths.saBase.offset(sa))
|
||||||
|
.close()
|
||||||
|
.addClass('fabric sa')
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete Titan's old hint path (which could start above the top
|
||||||
|
// of the garment)
|
||||||
|
// delete paths.hint
|
||||||
|
|
||||||
|
if (paperless) {
|
||||||
|
// Help construct crotch seam
|
||||||
|
paths.hint = new Path()
|
||||||
|
.move(points.crotchSeamCurveStart)
|
||||||
|
.line(points.crotchSeamCurveMax)
|
||||||
|
.line(points.fork)
|
||||||
|
.addClass('note lashed')
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHemLeftToPleat',
|
||||||
|
from: points.bottomOut,
|
||||||
|
to: points.bottom,
|
||||||
|
y: points.bottomIn.y - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHemRightToPleat',
|
||||||
|
from: points.bottom,
|
||||||
|
to: points.bottomIn,
|
||||||
|
y: points.bottomIn.y - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wHem',
|
||||||
|
from: points.bottomOut,
|
||||||
|
to: points.bottomIn,
|
||||||
|
y: points.bottomIn.y - 30,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hHemToFork',
|
||||||
|
from: points.bottomOut,
|
||||||
|
to: points.fork,
|
||||||
|
x: points.fork.x + sa + 15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hForkToCfWaist',
|
||||||
|
from: points.fork,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
x: points.fork.x + sa + 15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hHemToSideWaist',
|
||||||
|
from: points.bottomIn,
|
||||||
|
to: points.styleWaistOutLily,
|
||||||
|
x:
|
||||||
|
(points.seatOut.x < points.styleWaistOutLily.x
|
||||||
|
? points.seatOut.x
|
||||||
|
: points.styleWaistOutLily.x) -
|
||||||
|
sa -
|
||||||
|
15,
|
||||||
|
})
|
||||||
|
macro('vd', {
|
||||||
|
id: 'hStartCrotchCurveToCfWaist',
|
||||||
|
from: points.crotchSeamCurveStart,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
x: points.crotchSeamCurveStart.x + sa + 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wSideWaistToPleat',
|
||||||
|
from: points.seatOut,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 15,
|
||||||
|
})
|
||||||
|
if (points.styleWaistOutLily.x < points.seatOut.x) {
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wSideWaistToPleatAlt',
|
||||||
|
from: points.styleWaistOutLily,
|
||||||
|
to: points.grainlineTop,
|
||||||
|
y: points.styleWaistInLily.y - sa - 30,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToCfWaist',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.styleWaistInLily,
|
||||||
|
y: points.styleWaistInLily.y - sa - 15,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToStartCrotchCurve',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.crotchSeamCurveStart,
|
||||||
|
y: points.styleWaistInLily.y - sa - 30,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToCrotchProjection',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.crotchSeamCurveMax,
|
||||||
|
y: points.styleWaistInLily.y - sa - 45,
|
||||||
|
})
|
||||||
|
macro('hd', {
|
||||||
|
id: 'wPleatToFork',
|
||||||
|
from: points.grainlineTop,
|
||||||
|
to: points.fork,
|
||||||
|
y: points.styleWaistInLily.y - sa - 60,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return part
|
||||||
|
}
|
||||||
|
|
||||||
|
export const front = {
|
||||||
|
name: 'lily.front',
|
||||||
|
from: titanFront,
|
||||||
|
after: back,
|
||||||
|
hide: 'HIDE_TREE',
|
||||||
|
draft: draftLilyFront,
|
||||||
|
}
|
16
designs/lily/src/index.mjs
Normal file
16
designs/lily/src/index.mjs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { Design } from '@freesewing/core'
|
||||||
|
import { i18n } from '../i18n/index.mjs'
|
||||||
|
import { data } from '../data.mjs'
|
||||||
|
// Parts
|
||||||
|
import { front } from './front.mjs'
|
||||||
|
import { back } from './back.mjs'
|
||||||
|
import { waistband } from './waistband.mjs'
|
||||||
|
|
||||||
|
// Create new design
|
||||||
|
const Lily = new Design({
|
||||||
|
data,
|
||||||
|
parts: [front, back, waistband],
|
||||||
|
})
|
||||||
|
|
||||||
|
// Named exports
|
||||||
|
export { front, back, waistband, i18n, Lily }
|
18
designs/lily/src/waistband.mjs
Normal file
18
designs/lily/src/waistband.mjs
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
import { back } from './back.mjs'
|
||||||
|
import { front } from './front.mjs'
|
||||||
|
import { waistband as pacoWaistband } from '@freesewing/paco'
|
||||||
|
|
||||||
|
export const waistband = {
|
||||||
|
name: 'lily.waistband',
|
||||||
|
after: [back, front],
|
||||||
|
hide: 'HIDE_TREE',
|
||||||
|
draft: (sh) => {
|
||||||
|
const { snippets, part } = sh
|
||||||
|
//draft
|
||||||
|
pacoWaistband.draft(sh)
|
||||||
|
//delete eyelets
|
||||||
|
for (let s in snippets) delete snippets[s]
|
||||||
|
|
||||||
|
return part
|
||||||
|
},
|
||||||
|
}
|
20
designs/lily/tests/shared.test.mjs
Normal file
20
designs/lily/tests/shared.test.mjs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
// This file is auto-generated | Any changes you make will be overwritten.
|
||||||
|
import { Lily, i18n } from '../src/index.mjs'
|
||||||
|
|
||||||
|
// Shared tests
|
||||||
|
import { testPatternConfig } from '../../../tests/designs/config.mjs'
|
||||||
|
import { testPatternI18n } from '../../../tests/designs/i18n.mjs'
|
||||||
|
import { testPatternDrafting } from '../../../tests/designs/drafting.mjs'
|
||||||
|
import { testPatternSampling } from '../../../tests/designs/sampling.mjs'
|
||||||
|
|
||||||
|
// Test config
|
||||||
|
testPatternConfig(Lily)
|
||||||
|
|
||||||
|
// Test translation
|
||||||
|
testPatternI18n(Lily, i18n)
|
||||||
|
|
||||||
|
// Test drafting - Change the second parameter to `true` to log errors
|
||||||
|
testPatternDrafting(Lily, false)
|
||||||
|
|
||||||
|
// Test sampling - Change the second parameter to `true` to log errors
|
||||||
|
testPatternSampling(Lily, false)
|
|
@ -10,7 +10,6 @@ export const downloads = {
|
||||||
'sde/site.config.mjs',
|
'sde/site.config.mjs',
|
||||||
'sde/tailwind.config.mjs',
|
'sde/tailwind.config.mjs',
|
||||||
'sde/hooks/use-design.mjs',
|
'sde/hooks/use-design.mjs',
|
||||||
'sde/pkgs/.gitkeep',
|
|
||||||
'sde/mock/designs.mjs',
|
'sde/mock/designs.mjs',
|
||||||
'sde/mock/docs-helpers.mjs',
|
'sde/mock/docs-helpers.mjs',
|
||||||
'sde/mock/highlight.mjs',
|
'sde/mock/highlight.mjs',
|
||||||
|
@ -21,6 +20,7 @@ export const downloads = {
|
||||||
'sde/mock/read-more.mjs',
|
'sde/mock/read-more.mjs',
|
||||||
'sde/mock/tabbed-example.mjs',
|
'sde/mock/tabbed-example.mjs',
|
||||||
'sde/mock/youtube.mjs',
|
'sde/mock/youtube.mjs',
|
||||||
|
'sde/pkgs/.gitkeep',
|
||||||
'sde/prebuild/.gitkeep',
|
'sde/prebuild/.gitkeep',
|
||||||
'sde/prebuild/sitenav.de.mjs',
|
'sde/prebuild/sitenav.de.mjs',
|
||||||
'sde/prebuild/sitenav.en.mjs',
|
'sde/prebuild/sitenav.en.mjs',
|
||||||
|
@ -36,23 +36,11 @@ export const downloads = {
|
||||||
'sde/components/search.mjs',
|
'sde/components/search.mjs',
|
||||||
'sde/components/header/design-picker.mjs',
|
'sde/components/header/design-picker.mjs',
|
||||||
'sde/components/header/index.mjs',
|
'sde/components/header/index.mjs',
|
||||||
'sde/components/navigation/modal-menu.mjs',
|
|
||||||
'sde/components/layouts/bare.mjs',
|
'sde/components/layouts/bare.mjs',
|
||||||
'sde/components/layouts/default.mjs',
|
'sde/components/layouts/default.mjs',
|
||||||
'sde/components/layouts/workbench.mjs',
|
'sde/components/layouts/workbench.mjs',
|
||||||
|
'sde/components/navigation/modal-menu.mjs',
|
||||||
'sde/components/wrappers/page.mjs',
|
'sde/components/wrappers/page.mjs',
|
||||||
'sde/design/from-bent/src/back.mjs',
|
|
||||||
'sde/design/from-bent/src/front.mjs',
|
|
||||||
'sde/design/from-bent/src/index.mjs',
|
|
||||||
'sde/design/from-bent/src/top-sleeve.mjs',
|
|
||||||
'sde/design/from-bent/src/under-sleeve.mjs',
|
|
||||||
'sde/design/from-bent/i18n/de.json',
|
|
||||||
'sde/design/from-bent/i18n/en.json',
|
|
||||||
'sde/design/from-bent/i18n/es.json',
|
|
||||||
'sde/design/from-bent/i18n/fr.json',
|
|
||||||
'sde/design/from-bent/i18n/index.mjs',
|
|
||||||
'sde/design/from-bent/i18n/nl.json',
|
|
||||||
'sde/design/from-bent/i18n/uk.json',
|
|
||||||
'sde/design/from-bella/en.json',
|
'sde/design/from-bella/en.json',
|
||||||
'sde/design/from-bella/i18n/de.json',
|
'sde/design/from-bella/i18n/de.json',
|
||||||
'sde/design/from-bella/i18n/en.json',
|
'sde/design/from-bella/i18n/en.json',
|
||||||
|
@ -64,6 +52,18 @@ export const downloads = {
|
||||||
'sde/design/from-bella/src/back.mjs',
|
'sde/design/from-bella/src/back.mjs',
|
||||||
'sde/design/from-bella/src/front.mjs',
|
'sde/design/from-bella/src/front.mjs',
|
||||||
'sde/design/from-bella/src/index.mjs',
|
'sde/design/from-bella/src/index.mjs',
|
||||||
|
'sde/design/from-bent/i18n/de.json',
|
||||||
|
'sde/design/from-bent/i18n/en.json',
|
||||||
|
'sde/design/from-bent/i18n/es.json',
|
||||||
|
'sde/design/from-bent/i18n/fr.json',
|
||||||
|
'sde/design/from-bent/i18n/index.mjs',
|
||||||
|
'sde/design/from-bent/i18n/nl.json',
|
||||||
|
'sde/design/from-bent/i18n/uk.json',
|
||||||
|
'sde/design/from-bent/src/back.mjs',
|
||||||
|
'sde/design/from-bent/src/front.mjs',
|
||||||
|
'sde/design/from-bent/src/index.mjs',
|
||||||
|
'sde/design/from-bent/src/top-sleeve.mjs',
|
||||||
|
'sde/design/from-bent/src/under-sleeve.mjs',
|
||||||
'sde/design/from-breanna/i18n/de.json',
|
'sde/design/from-breanna/i18n/de.json',
|
||||||
'sde/design/from-breanna/i18n/en.json',
|
'sde/design/from-breanna/i18n/en.json',
|
||||||
'sde/design/from-breanna/i18n/es.json',
|
'sde/design/from-breanna/i18n/es.json',
|
||||||
|
@ -75,6 +75,10 @@ export const downloads = {
|
||||||
'sde/design/from-breanna/src/front.mjs',
|
'sde/design/from-breanna/src/front.mjs',
|
||||||
'sde/design/from-breanna/src/index.mjs',
|
'sde/design/from-breanna/src/index.mjs',
|
||||||
'sde/design/from-breanna/src/sleeve.mjs',
|
'sde/design/from-breanna/src/sleeve.mjs',
|
||||||
|
'sde/design/from-brian/src/back.mjs',
|
||||||
|
'sde/design/from-brian/src/front.mjs',
|
||||||
|
'sde/design/from-brian/src/index.mjs',
|
||||||
|
'sde/design/from-brian/src/sleeve.mjs',
|
||||||
'sde/design/from-brian/i18n/de.json',
|
'sde/design/from-brian/i18n/de.json',
|
||||||
'sde/design/from-brian/i18n/en.json',
|
'sde/design/from-brian/i18n/en.json',
|
||||||
'sde/design/from-brian/i18n/es.json',
|
'sde/design/from-brian/i18n/es.json',
|
||||||
|
@ -82,10 +86,6 @@ export const downloads = {
|
||||||
'sde/design/from-brian/i18n/index.mjs',
|
'sde/design/from-brian/i18n/index.mjs',
|
||||||
'sde/design/from-brian/i18n/nl.json',
|
'sde/design/from-brian/i18n/nl.json',
|
||||||
'sde/design/from-brian/i18n/uk.json',
|
'sde/design/from-brian/i18n/uk.json',
|
||||||
'sde/design/from-brian/src/back.mjs',
|
|
||||||
'sde/design/from-brian/src/front.mjs',
|
|
||||||
'sde/design/from-brian/src/index.mjs',
|
|
||||||
'sde/design/from-brian/src/sleeve.mjs',
|
|
||||||
'sde/design/from-scratch/i18n/de.json',
|
'sde/design/from-scratch/i18n/de.json',
|
||||||
'sde/design/from-scratch/i18n/en.json',
|
'sde/design/from-scratch/i18n/en.json',
|
||||||
'sde/design/from-scratch/i18n/es.json',
|
'sde/design/from-scratch/i18n/es.json',
|
||||||
|
@ -189,6 +189,60 @@ export const downloads = {
|
||||||
'sde/public/locales/de/tutorial.json',
|
'sde/public/locales/de/tutorial.json',
|
||||||
'sde/public/locales/de/ui-settings.json',
|
'sde/public/locales/de/ui-settings.json',
|
||||||
'sde/public/locales/de/workbench.json',
|
'sde/public/locales/de/workbench.json',
|
||||||
|
'sde/public/locales/es/account.json',
|
||||||
|
'sde/public/locales/es/auth.json',
|
||||||
|
'sde/public/locales/es/bella.json',
|
||||||
|
'sde/public/locales/es/bent.json',
|
||||||
|
'sde/public/locales/es/breanna.json',
|
||||||
|
'sde/public/locales/es/brian.json',
|
||||||
|
'sde/public/locales/es/common.json',
|
||||||
|
'sde/public/locales/es/core-settings.json',
|
||||||
|
'sde/public/locales/es/curate.json',
|
||||||
|
'sde/public/locales/es/cut.json',
|
||||||
|
'sde/public/locales/es/design-options.json',
|
||||||
|
'sde/public/locales/es/designs.json',
|
||||||
|
'sde/public/locales/es/docs.json',
|
||||||
|
'sde/public/locales/es/errors.json',
|
||||||
|
'sde/public/locales/es/flag.json',
|
||||||
|
'sde/public/locales/es/footer.json',
|
||||||
|
'sde/public/locales/es/frombella.json',
|
||||||
|
'sde/public/locales/es/frombent.json',
|
||||||
|
'sde/public/locales/es/frombreanna.json',
|
||||||
|
'sde/public/locales/es/frombrian.json',
|
||||||
|
'sde/public/locales/es/fromscratch.json',
|
||||||
|
'sde/public/locales/es/fromtitan.json',
|
||||||
|
'sde/public/locales/es/gdpr.json',
|
||||||
|
'sde/public/locales/es/header.json',
|
||||||
|
'sde/public/locales/es/hodl.json',
|
||||||
|
'sde/public/locales/es/homepage.json',
|
||||||
|
'sde/public/locales/es/lab.json',
|
||||||
|
'sde/public/locales/es/locales.json',
|
||||||
|
'sde/public/locales/es/logs.json',
|
||||||
|
'sde/public/locales/es/measurements.json',
|
||||||
|
'sde/public/locales/es/modal.json',
|
||||||
|
'sde/public/locales/es/newsletter.json',
|
||||||
|
'sde/public/locales/es/patrons.json',
|
||||||
|
'sde/public/locales/es/plugin-annotations.json',
|
||||||
|
'sde/public/locales/es/plugins.json',
|
||||||
|
'sde/public/locales/es/popout.json',
|
||||||
|
'sde/public/locales/es/print.json',
|
||||||
|
'sde/public/locales/es/roles.json',
|
||||||
|
'sde/public/locales/es/sde.json',
|
||||||
|
'sde/public/locales/es/sections.json',
|
||||||
|
'sde/public/locales/es/sets.json',
|
||||||
|
'sde/public/locales/es/sponsors.json',
|
||||||
|
'sde/public/locales/es/status.json',
|
||||||
|
'sde/public/locales/es/submissions.json',
|
||||||
|
'sde/public/locales/es/support.json',
|
||||||
|
'sde/public/locales/es/susi.json',
|
||||||
|
'sde/public/locales/es/tags.json',
|
||||||
|
'sde/public/locales/es/techniques.json',
|
||||||
|
'sde/public/locales/es/themes.json',
|
||||||
|
'sde/public/locales/es/timeago.json',
|
||||||
|
'sde/public/locales/es/titan.json',
|
||||||
|
'sde/public/locales/es/tutorial.json',
|
||||||
|
'sde/public/locales/es/ui-settings.json',
|
||||||
|
'sde/public/locales/es/workbench.json',
|
||||||
'sde/public/locales/en/account.json',
|
'sde/public/locales/en/account.json',
|
||||||
'sde/public/locales/en/auth.json',
|
'sde/public/locales/en/auth.json',
|
||||||
'sde/public/locales/en/bella.json',
|
'sde/public/locales/en/bella.json',
|
||||||
|
@ -297,114 +351,6 @@ export const downloads = {
|
||||||
'sde/public/locales/fr/tutorial.json',
|
'sde/public/locales/fr/tutorial.json',
|
||||||
'sde/public/locales/fr/ui-settings.json',
|
'sde/public/locales/fr/ui-settings.json',
|
||||||
'sde/public/locales/fr/workbench.json',
|
'sde/public/locales/fr/workbench.json',
|
||||||
'sde/public/locales/nl/account.json',
|
|
||||||
'sde/public/locales/nl/auth.json',
|
|
||||||
'sde/public/locales/nl/bella.json',
|
|
||||||
'sde/public/locales/nl/bent.json',
|
|
||||||
'sde/public/locales/nl/breanna.json',
|
|
||||||
'sde/public/locales/nl/brian.json',
|
|
||||||
'sde/public/locales/nl/common.json',
|
|
||||||
'sde/public/locales/nl/core-settings.json',
|
|
||||||
'sde/public/locales/nl/curate.json',
|
|
||||||
'sde/public/locales/nl/cut.json',
|
|
||||||
'sde/public/locales/nl/design-options.json',
|
|
||||||
'sde/public/locales/nl/designs.json',
|
|
||||||
'sde/public/locales/nl/docs.json',
|
|
||||||
'sde/public/locales/nl/errors.json',
|
|
||||||
'sde/public/locales/nl/flag.json',
|
|
||||||
'sde/public/locales/nl/footer.json',
|
|
||||||
'sde/public/locales/nl/frombella.json',
|
|
||||||
'sde/public/locales/nl/frombent.json',
|
|
||||||
'sde/public/locales/nl/frombreanna.json',
|
|
||||||
'sde/public/locales/nl/frombrian.json',
|
|
||||||
'sde/public/locales/nl/fromscratch.json',
|
|
||||||
'sde/public/locales/nl/fromtitan.json',
|
|
||||||
'sde/public/locales/nl/gdpr.json',
|
|
||||||
'sde/public/locales/nl/header.json',
|
|
||||||
'sde/public/locales/nl/hodl.json',
|
|
||||||
'sde/public/locales/nl/homepage.json',
|
|
||||||
'sde/public/locales/nl/lab.json',
|
|
||||||
'sde/public/locales/nl/locales.json',
|
|
||||||
'sde/public/locales/nl/logs.json',
|
|
||||||
'sde/public/locales/nl/measurements.json',
|
|
||||||
'sde/public/locales/nl/modal.json',
|
|
||||||
'sde/public/locales/nl/newsletter.json',
|
|
||||||
'sde/public/locales/nl/patrons.json',
|
|
||||||
'sde/public/locales/nl/plugin-annotations.json',
|
|
||||||
'sde/public/locales/nl/plugins.json',
|
|
||||||
'sde/public/locales/nl/popout.json',
|
|
||||||
'sde/public/locales/nl/print.json',
|
|
||||||
'sde/public/locales/nl/roles.json',
|
|
||||||
'sde/public/locales/nl/sde.json',
|
|
||||||
'sde/public/locales/nl/sections.json',
|
|
||||||
'sde/public/locales/nl/sets.json',
|
|
||||||
'sde/public/locales/nl/sponsors.json',
|
|
||||||
'sde/public/locales/nl/status.json',
|
|
||||||
'sde/public/locales/nl/submissions.json',
|
|
||||||
'sde/public/locales/nl/support.json',
|
|
||||||
'sde/public/locales/nl/susi.json',
|
|
||||||
'sde/public/locales/nl/tags.json',
|
|
||||||
'sde/public/locales/nl/techniques.json',
|
|
||||||
'sde/public/locales/nl/themes.json',
|
|
||||||
'sde/public/locales/nl/timeago.json',
|
|
||||||
'sde/public/locales/nl/titan.json',
|
|
||||||
'sde/public/locales/nl/tutorial.json',
|
|
||||||
'sde/public/locales/nl/ui-settings.json',
|
|
||||||
'sde/public/locales/nl/workbench.json',
|
|
||||||
'sde/public/locales/es/account.json',
|
|
||||||
'sde/public/locales/es/auth.json',
|
|
||||||
'sde/public/locales/es/bella.json',
|
|
||||||
'sde/public/locales/es/bent.json',
|
|
||||||
'sde/public/locales/es/breanna.json',
|
|
||||||
'sde/public/locales/es/brian.json',
|
|
||||||
'sde/public/locales/es/common.json',
|
|
||||||
'sde/public/locales/es/core-settings.json',
|
|
||||||
'sde/public/locales/es/curate.json',
|
|
||||||
'sde/public/locales/es/cut.json',
|
|
||||||
'sde/public/locales/es/design-options.json',
|
|
||||||
'sde/public/locales/es/designs.json',
|
|
||||||
'sde/public/locales/es/docs.json',
|
|
||||||
'sde/public/locales/es/errors.json',
|
|
||||||
'sde/public/locales/es/flag.json',
|
|
||||||
'sde/public/locales/es/footer.json',
|
|
||||||
'sde/public/locales/es/frombella.json',
|
|
||||||
'sde/public/locales/es/frombent.json',
|
|
||||||
'sde/public/locales/es/frombreanna.json',
|
|
||||||
'sde/public/locales/es/frombrian.json',
|
|
||||||
'sde/public/locales/es/fromscratch.json',
|
|
||||||
'sde/public/locales/es/fromtitan.json',
|
|
||||||
'sde/public/locales/es/gdpr.json',
|
|
||||||
'sde/public/locales/es/header.json',
|
|
||||||
'sde/public/locales/es/hodl.json',
|
|
||||||
'sde/public/locales/es/homepage.json',
|
|
||||||
'sde/public/locales/es/lab.json',
|
|
||||||
'sde/public/locales/es/locales.json',
|
|
||||||
'sde/public/locales/es/logs.json',
|
|
||||||
'sde/public/locales/es/measurements.json',
|
|
||||||
'sde/public/locales/es/modal.json',
|
|
||||||
'sde/public/locales/es/newsletter.json',
|
|
||||||
'sde/public/locales/es/patrons.json',
|
|
||||||
'sde/public/locales/es/plugin-annotations.json',
|
|
||||||
'sde/public/locales/es/plugins.json',
|
|
||||||
'sde/public/locales/es/popout.json',
|
|
||||||
'sde/public/locales/es/print.json',
|
|
||||||
'sde/public/locales/es/roles.json',
|
|
||||||
'sde/public/locales/es/sde.json',
|
|
||||||
'sde/public/locales/es/sections.json',
|
|
||||||
'sde/public/locales/es/sets.json',
|
|
||||||
'sde/public/locales/es/sponsors.json',
|
|
||||||
'sde/public/locales/es/status.json',
|
|
||||||
'sde/public/locales/es/submissions.json',
|
|
||||||
'sde/public/locales/es/support.json',
|
|
||||||
'sde/public/locales/es/susi.json',
|
|
||||||
'sde/public/locales/es/tags.json',
|
|
||||||
'sde/public/locales/es/techniques.json',
|
|
||||||
'sde/public/locales/es/themes.json',
|
|
||||||
'sde/public/locales/es/timeago.json',
|
|
||||||
'sde/public/locales/es/titan.json',
|
|
||||||
'sde/public/locales/es/tutorial.json',
|
|
||||||
'sde/public/locales/es/ui-settings.json',
|
|
||||||
'sde/public/locales/es/workbench.json',
|
|
||||||
'sde/public/locales/uk/account.json',
|
'sde/public/locales/uk/account.json',
|
||||||
'sde/public/locales/uk/auth.json',
|
'sde/public/locales/uk/auth.json',
|
||||||
'sde/public/locales/uk/bella.json',
|
'sde/public/locales/uk/bella.json',
|
||||||
|
@ -459,6 +405,60 @@ export const downloads = {
|
||||||
'sde/public/locales/uk/tutorial.json',
|
'sde/public/locales/uk/tutorial.json',
|
||||||
'sde/public/locales/uk/ui-settings.json',
|
'sde/public/locales/uk/ui-settings.json',
|
||||||
'sde/public/locales/uk/workbench.json',
|
'sde/public/locales/uk/workbench.json',
|
||||||
|
'sde/public/locales/nl/account.json',
|
||||||
|
'sde/public/locales/nl/auth.json',
|
||||||
|
'sde/public/locales/nl/bella.json',
|
||||||
|
'sde/public/locales/nl/bent.json',
|
||||||
|
'sde/public/locales/nl/breanna.json',
|
||||||
|
'sde/public/locales/nl/brian.json',
|
||||||
|
'sde/public/locales/nl/common.json',
|
||||||
|
'sde/public/locales/nl/core-settings.json',
|
||||||
|
'sde/public/locales/nl/curate.json',
|
||||||
|
'sde/public/locales/nl/cut.json',
|
||||||
|
'sde/public/locales/nl/design-options.json',
|
||||||
|
'sde/public/locales/nl/designs.json',
|
||||||
|
'sde/public/locales/nl/docs.json',
|
||||||
|
'sde/public/locales/nl/errors.json',
|
||||||
|
'sde/public/locales/nl/flag.json',
|
||||||
|
'sde/public/locales/nl/footer.json',
|
||||||
|
'sde/public/locales/nl/frombella.json',
|
||||||
|
'sde/public/locales/nl/frombent.json',
|
||||||
|
'sde/public/locales/nl/frombreanna.json',
|
||||||
|
'sde/public/locales/nl/frombrian.json',
|
||||||
|
'sde/public/locales/nl/fromscratch.json',
|
||||||
|
'sde/public/locales/nl/fromtitan.json',
|
||||||
|
'sde/public/locales/nl/gdpr.json',
|
||||||
|
'sde/public/locales/nl/header.json',
|
||||||
|
'sde/public/locales/nl/hodl.json',
|
||||||
|
'sde/public/locales/nl/homepage.json',
|
||||||
|
'sde/public/locales/nl/lab.json',
|
||||||
|
'sde/public/locales/nl/locales.json',
|
||||||
|
'sde/public/locales/nl/logs.json',
|
||||||
|
'sde/public/locales/nl/measurements.json',
|
||||||
|
'sde/public/locales/nl/modal.json',
|
||||||
|
'sde/public/locales/nl/newsletter.json',
|
||||||
|
'sde/public/locales/nl/patrons.json',
|
||||||
|
'sde/public/locales/nl/plugin-annotations.json',
|
||||||
|
'sde/public/locales/nl/plugins.json',
|
||||||
|
'sde/public/locales/nl/popout.json',
|
||||||
|
'sde/public/locales/nl/print.json',
|
||||||
|
'sde/public/locales/nl/roles.json',
|
||||||
|
'sde/public/locales/nl/sde.json',
|
||||||
|
'sde/public/locales/nl/sections.json',
|
||||||
|
'sde/public/locales/nl/sets.json',
|
||||||
|
'sde/public/locales/nl/sponsors.json',
|
||||||
|
'sde/public/locales/nl/status.json',
|
||||||
|
'sde/public/locales/nl/submissions.json',
|
||||||
|
'sde/public/locales/nl/support.json',
|
||||||
|
'sde/public/locales/nl/susi.json',
|
||||||
|
'sde/public/locales/nl/tags.json',
|
||||||
|
'sde/public/locales/nl/techniques.json',
|
||||||
|
'sde/public/locales/nl/themes.json',
|
||||||
|
'sde/public/locales/nl/timeago.json',
|
||||||
|
'sde/public/locales/nl/titan.json',
|
||||||
|
'sde/public/locales/nl/tutorial.json',
|
||||||
|
'sde/public/locales/nl/ui-settings.json',
|
||||||
|
'sde/public/locales/nl/workbench.json',
|
||||||
'shared/utils.mjs',
|
'shared/utils.mjs',
|
||||||
'shared/components/mdx/dynamic.mjs',
|
'shared/components/mdx/dynamic.mjs',
|
||||||
'shared/components/mdx/design-measurements.mjs',
|
'shared/components/mdx/design-measurements.mjs',
|
||||||
|
|
|
@ -58,6 +58,7 @@ import { Wahid as wahid } from '@freesewing/wahid'
|
||||||
import { Walburga as walburga } from '@freesewing/walburga'
|
import { Walburga as walburga } from '@freesewing/walburga'
|
||||||
import { Waralee as waralee } from '@freesewing/waralee'
|
import { Waralee as waralee } from '@freesewing/waralee'
|
||||||
import { Yuri as yuri } from '@freesewing/yuri'
|
import { Yuri as yuri } from '@freesewing/yuri'
|
||||||
|
import { Lily as lily } from '@freesewing/lily'
|
||||||
|
|
||||||
const designs = {
|
const designs = {
|
||||||
aaron,
|
aaron,
|
||||||
|
@ -116,6 +117,7 @@ const designs = {
|
||||||
walburga,
|
walburga,
|
||||||
waralee,
|
waralee,
|
||||||
yuri,
|
yuri,
|
||||||
|
lily,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDesign = (design) => (designs[design] ? designs[design] : false)
|
export const useDesign = (design) => (designs[design] ? designs[design] : false)
|
||||||
|
|
|
@ -55,6 +55,7 @@ import { Wahid as wahid } from '@freesewing/wahid'
|
||||||
import { Walburga as walburga } from '@freesewing/walburga'
|
import { Walburga as walburga } from '@freesewing/walburga'
|
||||||
import { Waralee as waralee } from '@freesewing/waralee'
|
import { Waralee as waralee } from '@freesewing/waralee'
|
||||||
import { Yuri as yuri } from '@freesewing/yuri'
|
import { Yuri as yuri } from '@freesewing/yuri'
|
||||||
|
import { Lily as lily } from '@freesewing/lily'
|
||||||
|
|
||||||
const designs = {
|
const designs = {
|
||||||
aaron,
|
aaron,
|
||||||
|
@ -110,6 +111,7 @@ const designs = {
|
||||||
walburga,
|
walburga,
|
||||||
waralee,
|
waralee,
|
||||||
yuri,
|
yuri,
|
||||||
|
lily,
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useDesign = (design) => (designs[design] ? designs[design] : false)
|
export const useDesign = (design) => (designs[design] ? designs[design] : false)
|
||||||
|
|
86
sites/org/pages/account/patterns/lily/edit.mjs
Normal file
86
sites/org/pages/account/patterns/lily/edit.mjs
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
/*
|
||||||
|
* This page is auto-generated. Do not edit it by hand.
|
||||||
|
*/
|
||||||
|
import { Lily } from 'designs/lily/src/index.mjs'
|
||||||
|
// Dependencies
|
||||||
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
|
import { nsMerge, getSearchParam } from 'shared/utils.mjs'
|
||||||
|
// Hooks
|
||||||
|
import { useState, useEffect, useContext } from 'react'
|
||||||
|
import { useTranslation } from 'next-i18next'
|
||||||
|
import { useBackend } from 'shared/hooks/use-backend.mjs'
|
||||||
|
// Context
|
||||||
|
import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs'
|
||||||
|
// Components
|
||||||
|
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||||
|
import { Workbench, ns as wbNs } from 'shared/components/workbench/new.mjs'
|
||||||
|
import { WorkbenchLayout } from 'site/components/layouts/workbench.mjs'
|
||||||
|
import { Loading } from 'shared/components/spinner.mjs'
|
||||||
|
|
||||||
|
// Translation namespaces used on this page
|
||||||
|
const ns = nsMerge('lily', wbNs, pageNs)
|
||||||
|
|
||||||
|
const EditDesignComponent = ({ id, design, Design, settings }) => (
|
||||||
|
<Workbench preload={{ settings }} saveAs={{ pattern: id }} {...{ design, Design }} />
|
||||||
|
)
|
||||||
|
|
||||||
|
const EditLilyPage = ({ page }) => {
|
||||||
|
const { setLoadingStatus } = useContext(LoadingStatusContext)
|
||||||
|
const backend = useBackend()
|
||||||
|
const { t } = useTranslation(ns)
|
||||||
|
|
||||||
|
const [pattern, setPattern] = useState(false)
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const getPattern = async () => {
|
||||||
|
setLoadingStatus([true, t('backendLoadingStarted')])
|
||||||
|
let result
|
||||||
|
try {
|
||||||
|
result = await backend.getPattern(id)
|
||||||
|
if (result.success) {
|
||||||
|
setPattern(result.data.pattern)
|
||||||
|
setLoadingStatus([true, 'backendLoadingCompleted', true, true])
|
||||||
|
} else setLoadingStatus([true, 'backendError', true, false])
|
||||||
|
} catch (err) {
|
||||||
|
console.log(err)
|
||||||
|
setLoadingStatus([true, 'backendError', true, false])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const id = getSearchParam('id')
|
||||||
|
if (id) getPattern()
|
||||||
|
}, [backend, setLoadingStatus, t])
|
||||||
|
|
||||||
|
return (
|
||||||
|
// prettier-ignore
|
||||||
|
<PageWrapper {...page} title="Lily" layout={pattern ? WorkbenchLayout : false} header={null}>
|
||||||
|
{pattern ? (
|
||||||
|
<EditDesignComponent
|
||||||
|
id={pattern.id}
|
||||||
|
settings={pattern.settings}
|
||||||
|
design="lily"
|
||||||
|
Design={Lily}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<div>
|
||||||
|
<h1>{t('account:oneMomentPLease')}</h1>
|
||||||
|
<Loading />
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</PageWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditLilyPage
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale }) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
...(await serverSideTranslations(locale, ns)),
|
||||||
|
page: {
|
||||||
|
locale,
|
||||||
|
path: ['account', 'patterns', 'lily'],
|
||||||
|
title: 'Lily',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
41
sites/org/pages/new/lily.mjs
Normal file
41
sites/org/pages/new/lily.mjs
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* This page is auto-generated. Do not edit it by hand.
|
||||||
|
*/
|
||||||
|
import { Lily } from 'designs/lily/src/index.mjs'
|
||||||
|
// Dependencies
|
||||||
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
|
import { nsMerge } from 'shared/utils.mjs'
|
||||||
|
// Components
|
||||||
|
import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs'
|
||||||
|
import { Workbench, ns as wbNs } from 'shared/components/workbench/new.mjs'
|
||||||
|
import { WorkbenchLayout } from 'site/components/layouts/workbench.mjs'
|
||||||
|
|
||||||
|
// Translation namespaces used on this page
|
||||||
|
const ns = nsMerge('lily', wbNs, pageNs)
|
||||||
|
|
||||||
|
const NewLilyPage = ({ page, docs }) => (
|
||||||
|
<PageWrapper {...page} title="Lily" layout={WorkbenchLayout} header={null}>
|
||||||
|
<Workbench
|
||||||
|
{...{
|
||||||
|
design: 'lily',
|
||||||
|
Design: Lily,
|
||||||
|
docs,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</PageWrapper>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default NewLilyPage
|
||||||
|
|
||||||
|
export async function getStaticProps({ locale }) {
|
||||||
|
return {
|
||||||
|
props: {
|
||||||
|
...(await serverSideTranslations(locale, ns)),
|
||||||
|
page: {
|
||||||
|
locale,
|
||||||
|
path: ['new', 'lily'],
|
||||||
|
title: 'Lily',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
|
@ -61,6 +61,7 @@ import { i18n as wahid } from '@freesewing/wahid'
|
||||||
import { i18n as walburga } from '@freesewing/walburga'
|
import { i18n as walburga } from '@freesewing/walburga'
|
||||||
import { i18n as waralee } from '@freesewing/waralee'
|
import { i18n as waralee } from '@freesewing/waralee'
|
||||||
import { i18n as yuri } from '@freesewing/yuri'
|
import { i18n as yuri } from '@freesewing/yuri'
|
||||||
|
import { i18n as lily } from '@freesewing/lily'
|
||||||
|
|
||||||
export const designs = {
|
export const designs = {
|
||||||
aaron,
|
aaron,
|
||||||
|
@ -122,4 +123,5 @@ export const designs = {
|
||||||
walburga,
|
walburga,
|
||||||
waralee,
|
waralee,
|
||||||
yuri,
|
yuri,
|
||||||
|
lily,
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,3 +1,3 @@
|
||||||
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
// __SDEFILE__ - This file is a dependency for the stand-alone environment
|
||||||
// This file is auto-generated by the prebuild script | Any changes will be overwritten
|
// This file is auto-generated by the prebuild script | Any changes will be overwritten
|
||||||
export const designs = ["aaron","albert","bee","bella","benjamin","bent","bob","breanna","brian","bruce","carlita","carlton","cathrin","charlie","cornelius","diana","examples","florence","florent","gozer","hi","holmes","hortensia","huey","hugo","jaeger","legend","lucy","lumina","lumira","lunetius","magde","naomiwu","noble","octoplushy","onyx","otis","paco","penelope","plugintest","rendertest","sandy","shelly","shin","simon","simone","skully","sven","tamiko","teagan","tiberius","titan","trayvon","tristan","uma","wahid","walburga","waralee","yuri"]
|
export const designs = ["aaron","albert","bee","bella","benjamin","bent","bob","breanna","brian","bruce","carlita","carlton","cathrin","charlie","cornelius","diana","examples","florence","florent","gozer","hi","holmes","hortensia","huey","hugo","jaeger","legend","lucy","lumina","lumira","lunetius","magde","naomiwu","noble","octoplushy","onyx","otis","paco","penelope","plugintest","rendertest","sandy","shelly","shin","simon","simone","skully","sven","tamiko","teagan","tiberius","titan","trayvon","tristan","uma","wahid","walburga","waralee","yuri","lily"]
|
||||||
|
|
26
yarn.lock
26
yarn.lock
|
@ -10024,6 +10024,32 @@ mocha-steps@1.3.0:
|
||||||
resolved "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz"
|
resolved "https://registry.npmjs.org/mocha-steps/-/mocha-steps-1.3.0.tgz"
|
||||||
integrity sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==
|
integrity sha512-KZvpMJTqzLZw3mOb+EEuYi4YZS41C9iTnb7skVFRxHjUd1OYbl64tCMSmpdIRM9LnwIrSOaRfPtNpF5msgv6Eg==
|
||||||
|
|
||||||
|
mocha@10.3.0:
|
||||||
|
version "10.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.3.0.tgz#0e185c49e6dccf582035c05fa91084a4ff6e3fe9"
|
||||||
|
integrity sha512-uF2XJs+7xSLsrmIvn37i/wnc91nw7XjOQB8ccyx5aEgdnohr7n+rEiZP23WkCYHjilR6+EboEnbq/ZQDz4LSbg==
|
||||||
|
dependencies:
|
||||||
|
ansi-colors "4.1.1"
|
||||||
|
browser-stdout "1.3.1"
|
||||||
|
chokidar "3.5.3"
|
||||||
|
debug "4.3.4"
|
||||||
|
diff "5.0.0"
|
||||||
|
escape-string-regexp "4.0.0"
|
||||||
|
find-up "5.0.0"
|
||||||
|
glob "8.1.0"
|
||||||
|
he "1.2.0"
|
||||||
|
js-yaml "4.1.0"
|
||||||
|
log-symbols "4.1.0"
|
||||||
|
minimatch "5.0.1"
|
||||||
|
ms "2.1.3"
|
||||||
|
serialize-javascript "6.0.0"
|
||||||
|
strip-json-comments "3.1.1"
|
||||||
|
supports-color "8.1.1"
|
||||||
|
workerpool "6.2.1"
|
||||||
|
yargs "16.2.0"
|
||||||
|
yargs-parser "20.2.4"
|
||||||
|
yargs-unparser "2.0.0"
|
||||||
|
|
||||||
mocha@10.4.0, mocha@^10.0.0:
|
mocha@10.4.0, mocha@^10.0.0:
|
||||||
version "10.4.0"
|
version "10.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261"
|
resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.4.0.tgz#ed03db96ee9cfc6d20c56f8e2af07b961dbae261"
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue