diff --git a/.gitignore b/.gitignore index 5537c2f8f3f..a77a2b2d193 100644 --- a/.gitignore +++ b/.gitignore @@ -105,7 +105,6 @@ sites/*/out sites/*/public/mdx sites/*/prebuild !sites/shared/prebuild -sites/shared/prebuild/data sites/dev/public/og # misc diff --git a/packages/new-design/lib/config.mjs b/packages/new-design/lib/config.mjs index ed982293206..297efc82b29 100644 --- a/packages/new-design/lib/config.mjs +++ b/packages/new-design/lib/config.mjs @@ -57,6 +57,10 @@ yarn-error.log* `, fetch: { + // account: + // sets + // shared + // control config: [ { from: 'measurements.mjs', @@ -73,7 +77,15 @@ yarn-error.log* ], sites: [ // Mock MDX components - ...['highlight', 'youtube', 'read-more', 'tabbed-example'].map((file) => ({ + ...[ + 'highlight', + 'youtube', + 'read-more', + 'tabbed-example', + 'http', + 'legend', + 'docs-helpers', + ].map((file) => ({ from: `sde/mock/${file}.mjs`, to: `shared/components/mdx/${file}.mjs`, })), diff --git a/sites/sde/components/header/index.mjs b/sites/sde/components/header/index.mjs index 56e1e9caff5..e22178d0a4f 100644 --- a/sites/sde/components/header/index.mjs +++ b/sites/sde/components/header/index.mjs @@ -10,7 +10,7 @@ import { DesignIcon, DocsIcon, MenuIcon, - UserIcon, + LockIcon, ThemeIcon, I18nIcon, MeasieIcon, @@ -49,34 +49,34 @@ const NavIcons = ({ setModal }) => { > - + - - - - - + setModal()} label={t('header:theme')} - color={spectrum[7]} + color={spectrum[6]} > setModal()} label={t('header:language')} - color={spectrum[8]} + color={spectrum[7]} > + + + + > ) } diff --git a/sites/sde/mock/docs-helpers.mjs b/sites/sde/mock/docs-helpers.mjs new file mode 100644 index 00000000000..cd7d61dd497 --- /dev/null +++ b/sites/sde/mock/docs-helpers.mjs @@ -0,0 +1,2 @@ +export const DocsTitle = () => null +export const DocsLink = () => null diff --git a/sites/sde/mock/http.mjs b/sites/sde/mock/http.mjs new file mode 100644 index 00000000000..5a1a29460ff --- /dev/null +++ b/sites/sde/mock/http.mjs @@ -0,0 +1,2 @@ +export const HttpMethod = () => null +export const HttpStatusCode = () => null diff --git a/sites/sde/mock/legend.mjs b/sites/sde/mock/legend.mjs new file mode 100644 index 00000000000..3223c81bce6 --- /dev/null +++ b/sites/sde/mock/legend.mjs @@ -0,0 +1 @@ +export const Legend = () => null diff --git a/sites/sde/next.config.mjs b/sites/sde/next.config.mjs index bda30c6d7c2..85f59cb0934 100644 --- a/sites/sde/next.config.mjs +++ b/sites/sde/next.config.mjs @@ -1,7 +1,7 @@ import path from 'path' import i18nConfig from './next-i18next.config.js' // Remark plugins -//import remarkFrontmatter from 'remark-frontmatter' +import remarkFrontmatter from 'remark-frontmatter' import remarkMdxFrontmatter from 'remark-mdx-frontmatter' import remarkGfm from 'remark-gfm' import smartypants from 'remark-smartypants' @@ -33,12 +33,7 @@ const config = { options: { providerImportSource: '@mdx-js/react', format: 'mdx', - remarkPlugins: [ - //remarkFrontmatter, - remarkMdxFrontmatter, - remarkGfm, - smartypants, - ], + remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter, remarkGfm, smartypants], }, }, ], @@ -56,6 +51,7 @@ const config = { // Aliases config.resolve.alias.shared = path.resolve('./shared/') config.resolve.alias.config = path.resolve('./shared/config/') + config.resolve.alias.pkgs = path.resolve('./pkgs/') config.resolve.alias.site = path.resolve(`./`) return config diff --git a/sites/sde/pages/account.mjs b/sites/sde/pages/account.mjs new file mode 100644 index 00000000000..b3cb5bd79f1 --- /dev/null +++ b/sites/sde/pages/account.mjs @@ -0,0 +1,52 @@ +// Dependencies +import { serverSideTranslations } from 'next-i18next/serverSideTranslations' +import { nsMerge } from 'shared/utils.mjs' +// Hooks +import { useTranslation } from 'next-i18next' +// Components +import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' +import { Popout, ns as popoutNs } from 'shared/components/popout/index.mjs' +import { PageLink, WebLink } from 'shared/components/link.mjs' +import { FreeSewingIcon } from 'shared/components/icons.mjs' +import { collection } from 'site/hooks/use-design.mjs' + +const ns = nsMerge('sde', 'account', pageNs, popoutNs) +/* + * Each page MUST be wrapped in the PageWrapper component. + * You also MUST spread props.page into this wrapper component + * when path and locale come from static props (as here) + * or set them manually. + */ +const AccountPage = ({ page }) => { + const { t } = useTranslation(ns) + + return ( + + + {t('header:account')} + To manage your FreeSewing account, please go to FreeSewing.org + + You can use the data in your account, but this development environment does not come with + account management features. + + + FreeSewing.org + + + + ) +} + +export default AccountPage + +export async function getStaticProps({ locale }) { + return { + props: { + ...(await serverSideTranslations(locale, ns)), + page: { + locale, + path: [], + }, + }, + } +} diff --git a/sites/sde/pages/account/[platform].mjs b/sites/sde/pages/account/[platform].mjs deleted file mode 100644 index a47580ec167..00000000000 --- a/sites/sde/pages/account/[platform].mjs +++ /dev/null @@ -1,84 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge, capitalize } from 'shared/utils.mjs' -import { freeSewingConfig } from 'shared/config/freesewing.config.mjs' -import { siteConfig } from 'site/site.config.mjs' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as platformNs } from 'shared/components/account/platform.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(platformNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicPlatform = dynamic( - () => import('shared/components/account/platform.mjs').then((mod) => mod.PlatformSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPage = ({ page, platform }) => ( - - - - - -) - -export default AccountPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - platform: params.platform, - page: { - locale, - path: ['account', params.platform], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * - * On this page, it is returning a truncated list of routes (think URLs) for all - * the mdx blog (markdown) content. - * That list comes from prebuild/blog-paths.mjs, which is built in the prebuild step - * and contains paths, titles, imageUrls, and intro for all blog posts. - * - * the fallback: 'blocking' property means that - * any pages that haven't been pre-generated - * will generate and cache the first time someone visits them - * - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => { - const paths = [] - for (const platform of Object.keys(freeSewingConfig.account.fields.identities).filter( - (key) => key !== 'github' - )) { - for (const locale of siteConfig.languages) { - paths.push({ params: { platform }, locale }) - } - } - - return { paths, fallback: true } -} diff --git a/sites/sde/pages/account/apikeys/[id].mjs b/sites/sde/pages/account/apikeys/[id].mjs deleted file mode 100644 index 5f49b0173eb..00000000000 --- a/sites/sde/pages/account/apikeys/[id].mjs +++ /dev/null @@ -1,84 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Context -import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -import { useState, useEffect, useContext } from 'react' -import { useBackend } from 'shared/hooks/use-backend.mjs' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as apikeysNs } from 'shared/components/account/apikeys.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(apikeysNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicApikey = dynamic( - () => import('shared/components/account/apikeys.mjs').then((mod) => mod.Apikey), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const ApikeyPage = ({ page, id }) => { - const { t } = useTranslation(ns) - const backend = useBackend() - const { setLoadingStatus } = useContext(LoadingStatusContext) - - const [apikey, setApikey] = useState() - - useEffect(() => { - const getApikey = async () => { - const result = await backend.getApikey(id) - if (result.success) setApikey(result.data.apikey) - else setLoadingStatus([false]) - } - getApikey() - }, [id]) - - return ( - - - - - - ) -} - -export default ApikeyPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'apikeys', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: true }) diff --git a/sites/sde/pages/account/apikeys/index.mjs b/sites/sde/pages/account/apikeys/index.mjs deleted file mode 100644 index f1c346f8e10..00000000000 --- a/sites/sde/pages/account/apikeys/index.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as apikeysNs } from 'shared/components/account/apikeys.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(apikeysNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicApikeys = dynamic( - () => import('shared/components/account/apikeys.mjs').then((mod) => mod.Apikeys), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountApikeysPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountApikeysPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'apikeys'], - }, - }, - } -} diff --git a/sites/sde/pages/account/bio.mjs b/sites/sde/pages/account/bio.mjs deleted file mode 100644 index de1459d45d2..00000000000 --- a/sites/sde/pages/account/bio.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as bioNs } from 'shared/components/account/bio.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(bioNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicBio = dynamic( - () => import('shared/components/account/bio.mjs').then((mod) => mod.BioSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountBioPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountBioPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'bio'], - }, - }, - } -} diff --git a/sites/sde/pages/account/bookmarks/[id].mjs b/sites/sde/pages/account/bookmarks/[id].mjs deleted file mode 100644 index 1b36edc05af..00000000000 --- a/sites/sde/pages/account/bookmarks/[id].mjs +++ /dev/null @@ -1,84 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Context -import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -import { useState, useEffect, useContext } from 'react' -import { useBackend } from 'shared/hooks/use-backend.mjs' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as bookmarksNs } from 'shared/components/account/bookmarks.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(bookmarksNs, authNs, pageNs, 'status') - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicBookmark = dynamic( - () => import('shared/components/account/bookmarks.mjs').then((mod) => mod.Bookmark), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const BookmarkPage = ({ page, id }) => { - const { t } = useTranslation(ns) - const backend = useBackend() - const { setLoadingStatus } = useContext(LoadingStatusContext) - - const [bookmark, setBookmark] = useState() - - useEffect(() => { - const getBookmark = async () => { - const result = await backend.getBookmark(id) - if (result.success) setBookmark(result.data.bookmark) - else setLoadingStatus([false]) - } - getBookmark() - }, [id]) - - return ( - - - - - - ) -} - -export default BookmarkPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'bookmarks', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: true }) diff --git a/sites/sde/pages/account/bookmarks/index.mjs b/sites/sde/pages/account/bookmarks/index.mjs deleted file mode 100644 index 73cd278a9a8..00000000000 --- a/sites/sde/pages/account/bookmarks/index.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as bookmarksNs } from 'shared/components/account/bookmarks.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(bookmarksNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicBookmarks = dynamic( - () => import('shared/components/account/bookmarks.mjs').then((mod) => mod.Bookmarks), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountBookmarksPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountBookmarksPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'bookmarks'], - }, - }, - } -} diff --git a/sites/sde/pages/account/compare.mjs b/sites/sde/pages/account/compare.mjs deleted file mode 100644 index 4f7d08d4de4..00000000000 --- a/sites/sde/pages/account/compare.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as compareNs } from 'shared/components/account/compare.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(compareNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicCompare = dynamic( - () => import('shared/components/account/compare.mjs').then((mod) => mod.CompareSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountComparePage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountComparePage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'compare'], - }, - }, - } -} diff --git a/sites/sde/pages/account/consent.mjs b/sites/sde/pages/account/consent.mjs deleted file mode 100644 index 23e7c00415c..00000000000 --- a/sites/sde/pages/account/consent.mjs +++ /dev/null @@ -1,52 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as consentNs } from 'shared/components/account/consent.mjs' - -// Translation namespaces used on this page -const namespaces = [...new Set([...consentNs, ...authNs, ...pageNs])] - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicConsent = dynamic( - () => import('shared/components/account/consent.mjs').then((mod) => mod.ConsentSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountConsentPage = ({ page }) => ( - - - - - -) - -export default AccountConsentPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, namespaces)), - page: { - locale, - path: ['account', 'consent'], - }, - }, - } -} diff --git a/sites/sde/pages/account/control.mjs b/sites/sde/pages/account/control.mjs deleted file mode 100644 index a3e598f5bdf..00000000000 --- a/sites/sde/pages/account/control.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as controlNs } from 'shared/components/account/control.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(controlNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicControl = dynamic( - () => import('shared/components/account/control.mjs').then((mod) => mod.ControlSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'control'], - }, - }, - } -} diff --git a/sites/sde/pages/account/email.mjs b/sites/sde/pages/account/email.mjs deleted file mode 100644 index 38443b2e029..00000000000 --- a/sites/sde/pages/account/email.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as emailNs } from 'shared/components/account/email.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(emailNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicEmail = dynamic( - () => import('shared/components/account/email.mjs').then((mod) => mod.EmailSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountEmailPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountEmailPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'email'], - }, - }, - } -} diff --git a/sites/sde/pages/account/export.mjs b/sites/sde/pages/account/export.mjs deleted file mode 100644 index af4eeea480d..00000000000 --- a/sites/sde/pages/account/export.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as reloadNs } from 'shared/components/account/reload.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(reloadNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicExport = dynamic( - () => import('shared/components/account/export.mjs').then((mod) => mod.ExportAccount), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountExportPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountExportPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'export'], - }, - }, - } -} diff --git a/sites/sde/pages/account/github.mjs b/sites/sde/pages/account/github.mjs deleted file mode 100644 index 5976fc41c7c..00000000000 --- a/sites/sde/pages/account/github.mjs +++ /dev/null @@ -1,53 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -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 { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as githubNs } from 'shared/components/account/github.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(githubNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicGithub = dynamic( - () => import('shared/components/account/github.mjs').then((mod) => mod.GithubSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPage = ({ page }) => ( - - - - - -) - -export default AccountPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'github'], - }, - }, - } -} diff --git a/sites/sde/pages/account/img.mjs b/sites/sde/pages/account/img.mjs deleted file mode 100644 index 971fad057e3..00000000000 --- a/sites/sde/pages/account/img.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as imgNs } from 'shared/components/account/img.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(imgNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicImg = dynamic( - () => import('shared/components/account/img.mjs').then((mod) => mod.ImgSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'img'], - }, - }, - } -} diff --git a/sites/sde/pages/account/index.mjs b/sites/sde/pages/account/index.mjs deleted file mode 100644 index d3bb8cac2c0..00000000000 --- a/sites/sde/pages/account/index.mjs +++ /dev/null @@ -1,52 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' - -// Translation namespaces used on this page -const ns = nsMerge('account', 'status', pageNs, authNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicAccountOverview = dynamic( - () => import('shared/components/account/overview.mjs').then((mod) => mod.AccountOverview), - { ssr: false } -) - -const AccountIndexPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountIndexPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account'], - }, - }, - } -} diff --git a/sites/sde/pages/account/language.mjs b/sites/sde/pages/account/language.mjs deleted file mode 100644 index 136ea77c763..00000000000 --- a/sites/sde/pages/account/language.mjs +++ /dev/null @@ -1,66 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -import { siteConfig } from 'site/site.config.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as languageNs } from 'shared/components/account/language.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(languageNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicLanguage = dynamic( - () => import('shared/components/account/language.mjs').then((mod) => mod.LanguageSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountLanguagePage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountLanguagePage - -export async function getStaticProps({ locale }) { - return { - props: { - // We are loading all languages here so we can show each language in its own language - ...(await serverSideTranslations( - locale, - ns, - null, - siteConfig.languages.filter((lang) => lang !== locale) - )), - page: { - locale, - path: ['account', 'language'], - }, - }, - } -} diff --git a/sites/sde/pages/account/mfa.mjs b/sites/sde/pages/account/mfa.mjs deleted file mode 100644 index bcebe204970..00000000000 --- a/sites/sde/pages/account/mfa.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as mfaNs } from 'shared/components/account/mfa.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(mfaNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicMfa = dynamic( - () => import('shared/components/account/mfa.mjs').then((mod) => mod.MfaSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountMfaPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountMfaPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'mfa'], - }, - }, - } -} diff --git a/sites/sde/pages/account/newsletter.mjs b/sites/sde/pages/account/newsletter.mjs deleted file mode 100644 index cc0b5c65566..00000000000 --- a/sites/sde/pages/account/newsletter.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as newsletterNs } from 'shared/components/account/newsletter.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(newsletterNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicNewsletter = dynamic( - () => import('shared/components/account/newsletter.mjs').then((mod) => mod.NewsletterSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountNewsletterPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountNewsletterPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'newsletter'], - }, - }, - } -} diff --git a/sites/sde/pages/account/password.mjs b/sites/sde/pages/account/password.mjs deleted file mode 100644 index d9cb5e98f36..00000000000 --- a/sites/sde/pages/account/password.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as passwordNs } from 'shared/components/account/password.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(passwordNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicPassword = dynamic( - () => import('shared/components/account/password.mjs').then((mod) => mod.PasswordSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPasswordPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountPasswordPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'password'], - }, - }, - } -} diff --git a/sites/sde/pages/account/patterns/[id]/edit.mjs b/sites/sde/pages/account/patterns/[id]/edit.mjs deleted file mode 100644 index 6e6de73de7b..00000000000 --- a/sites/sde/pages/account/patterns/[id]/edit.mjs +++ /dev/null @@ -1,99 +0,0 @@ -// Dependencies -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useState, useEffect, useContext } from 'react' -import { useTranslation } from 'next-i18next' -import { useDesign } from 'site/hooks/use-design.mjs' -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 { DynamicOrgDocs as DynamicDocs } from 'site/components/dynamic-org-docs.mjs' -import { Loading } from 'shared/components/spinner.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(wbNs, pageNs) - -const EditDesignComponent = ({ design, id, settings }) => { - const Design = useDesign(design) - - return ( - - ) -} - -const EditDesignPage = ({ page, design, id }) => { - 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]) - } - } - if (id) getPattern() - }, [id]) - - return ( - - {pattern ? ( - - ) : ( - - {t('account:oneMomentPLease')} - - Give it a moment - - )} - {JSON.stringify(pattern, null, 2)} - - ) -} - -export default EditDesignPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'patterns', params.id, 'edit'], - title: '', - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - */ -export async function getStaticPaths() { - return { - paths: [], - fallback: 'blocking', - } -} diff --git a/sites/sde/pages/account/patterns/[id]/index.mjs b/sites/sde/pages/account/patterns/[id]/index.mjs deleted file mode 100644 index c518cea8800..00000000000 --- a/sites/sde/pages/account/patterns/[id]/index.mjs +++ /dev/null @@ -1,67 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as patternsNs } from 'shared/components/account/patterns.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(patternsNs, authNs, pageNs, 'status') - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicPattern = dynamic( - () => import('shared/components/account/patterns.mjs').then((mod) => mod.Pattern), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const PatternPage = ({ page, id }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default PatternPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'patterns', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: true }) diff --git a/sites/sde/pages/account/patterns/index.mjs b/sites/sde/pages/account/patterns/index.mjs deleted file mode 100644 index 4665d61ee04..00000000000 --- a/sites/sde/pages/account/patterns/index.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as setsNs } from 'shared/components/account/sets.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(setsNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicPatterns = dynamic( - () => import('shared/components/account/patterns.mjs').then((mod) => mod.Patterns), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountSetsPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountSetsPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'patterns'], - }, - }, - } -} diff --git a/sites/sde/pages/account/privacy.mjs b/sites/sde/pages/account/privacy.mjs deleted file mode 100644 index fa7e4059823..00000000000 --- a/sites/sde/pages/account/privacy.mjs +++ /dev/null @@ -1,7 +0,0 @@ -/* - * This `/account/privacy` page is merely an alias for the `/account/consent` page - */ -import Page, { getStaticProps as gsp } from './consent.mjs' - -export const getStaticProps = gsp -export default Page diff --git a/sites/sde/pages/account/reload.mjs b/sites/sde/pages/account/reload.mjs deleted file mode 100644 index f96685d5336..00000000000 --- a/sites/sde/pages/account/reload.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as reloadNs } from 'shared/components/account/reload.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(reloadNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicReload = dynamic( - () => import('shared/components/account/reload.mjs').then((mod) => mod.ReloadAccount), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountReloadPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountReloadPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'reload'], - }, - }, - } -} diff --git a/sites/sde/pages/account/remove.mjs b/sites/sde/pages/account/remove.mjs deleted file mode 100644 index 173b27257ae..00000000000 --- a/sites/sde/pages/account/remove.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as reloadNs } from 'shared/components/account/reload.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(reloadNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicRemove = dynamic( - () => import('shared/components/account/remove.mjs').then((mod) => mod.RemoveAccount), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountRemovePage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountRemovePage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'remove'], - }, - }, - } -} diff --git a/sites/sde/pages/account/restrict.mjs b/sites/sde/pages/account/restrict.mjs deleted file mode 100644 index 84f3cb3cd90..00000000000 --- a/sites/sde/pages/account/restrict.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as reloadNs } from 'shared/components/account/reload.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(reloadNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicRestrict = dynamic( - () => import('shared/components/account/restrict.mjs').then((mod) => mod.RestrictAccount), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountRestrictPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountRestrictPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'restrict'], - }, - }, - } -} diff --git a/sites/sde/pages/account/sets/[id].mjs b/sites/sde/pages/account/sets/[id].mjs deleted file mode 100644 index bf9302391af..00000000000 --- a/sites/sde/pages/account/sets/[id].mjs +++ /dev/null @@ -1,67 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as setsNs } from 'shared/components/account/sets.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(setsNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicSet = dynamic( - () => import('shared/components/account/sets.mjs').then((mod) => mod.Mset), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const SetPage = ({ page, id }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default SetPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'sets', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: true }) diff --git a/sites/sde/pages/account/sets/index.mjs b/sites/sde/pages/account/sets/index.mjs deleted file mode 100644 index 5c79ea23be9..00000000000 --- a/sites/sde/pages/account/sets/index.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as setsNs } from 'shared/components/account/bookmarks.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(setsNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicSets = dynamic( - () => import('shared/components/account/sets.mjs').then((mod) => mod.Sets), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountSetsPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountSetsPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'bookmarks'], - }, - }, - } -} diff --git a/sites/sde/pages/account/units.mjs b/sites/sde/pages/account/units.mjs deleted file mode 100644 index 6cc5d2f7b53..00000000000 --- a/sites/sde/pages/account/units.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as unitsNs } from 'shared/components/account/imperial.mjs' - -// Translation namespaces used on this page -const namespaces = nsMerge(unitsNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicImperial = dynamic( - () => import('shared/components/account/imperial.mjs').then((mod) => mod.ImperialSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountUnitsPage = ({ page }) => { - const { t } = useTranslation(namespaces) - - return ( - - - - - - ) -} - -export default AccountUnitsPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, namespaces)), - page: { - locale, - path: ['account', 'units'], - }, - }, - } -} diff --git a/sites/sde/pages/account/username.mjs b/sites/sde/pages/account/username.mjs deleted file mode 100644 index aeadc56e3c4..00000000000 --- a/sites/sde/pages/account/username.mjs +++ /dev/null @@ -1,59 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as usernameNs } from 'shared/components/account/username.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(usernameNs, authNs, pageNs) - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicUsername = dynamic( - () => import('shared/components/account/username.mjs').then((mod) => mod.UsernameSettings), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const AccountPage = ({ page }) => { - const { t } = useTranslation(ns) - - return ( - - - - - - ) -} - -export default AccountPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - page: { - locale, - path: ['account', 'username'], - }, - }, - } -} diff --git a/sites/sde/pages/code/index.mjs b/sites/sde/pages/code/index.mjs index 7aa0b781fb3..d2b9ea23ed9 100644 --- a/sites/sde/pages/code/index.mjs +++ b/sites/sde/pages/code/index.mjs @@ -13,7 +13,7 @@ import nl, { frontmatter as nlFrontmatter } from './nl.mdx' import fr, { frontmatter as frFrontmatter } from './fr.mdx' import uk, { frontmatter as ukFrontmatter } from './uk.mdx' -const ns = [pageNs, 'sde'] +const ns = [pageNs, 'sde', 'account'] const mdx = { en, de, es, nl, fr, uk } const frontmatter = { diff --git a/sites/sde/pages/docs/index.mjs b/sites/sde/pages/docs/index.mjs index 7aa0b781fb3..d2b9ea23ed9 100644 --- a/sites/sde/pages/docs/index.mjs +++ b/sites/sde/pages/docs/index.mjs @@ -13,7 +13,7 @@ import nl, { frontmatter as nlFrontmatter } from './nl.mdx' import fr, { frontmatter as frFrontmatter } from './fr.mdx' import uk, { frontmatter as ukFrontmatter } from './uk.mdx' -const ns = [pageNs, 'sde'] +const ns = [pageNs, 'sde', 'account'] const mdx = { en, de, es, nl, fr, uk } const frontmatter = { diff --git a/sites/sde/pages/patterns/[id]/edit.mjs b/sites/sde/pages/patterns/[id]/edit.mjs deleted file mode 100644 index 85c5582cdb2..00000000000 --- a/sites/sde/pages/patterns/[id]/edit.mjs +++ /dev/null @@ -1,75 +0,0 @@ -// Hooks -import { useEffect, useState } from 'react' -import { useBackend } from 'shared/hooks/use-backend.mjs' -import { useDesign } from 'site/hooks/use-design.mjs' -// Dependencies -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -// 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 { Null } from 'shared/components/null.mjs' -import { DynamicOrgDocs as DynamicDocs } from 'site/components/dynamic-org-docs.mjs' - -// Translation namespaces used on this page -const namespaces = [...new Set(['aaron', ...wbNs, ...pageNs])] - -const EditPatternPage = ({ page, id }) => { - // State - const [pattern, setPattern] = useState(false) - - // Hooks - const backend = useBackend() - const Design = useDesign(pattern?.design) - - // Effect - useEffect(() => { - const getPattern = async () => { - const result = await backend.getPattern(id) - if (result.success) setPattern(result.data.pattern) - } - // Guard against loops as the backend object is recreated on each render - if (pattern === false) getPattern() - else if (pattern.id && pattern.id !== id) getPattern() - }, [id, pattern, backend]) - - const baseSettings = pattern - ? { - ...pattern.settings, - measurements: pattern.set ? pattern.set.measies : pattern.cset.measies, - } - : null - - return ( - - - - ) -} - -export default EditPatternPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, namespaces)), - id: Number(params.id), - page: { - locale, - path: ['new', 'pattern', 'aaron', 'set', params.id], - title: '', - }, - }, - } -} - -export async function getStaticPaths() { - return { - paths: [], - fallback: true, - } -} diff --git a/sites/sde/pages/patterns/[id]/index.mjs b/sites/sde/pages/patterns/[id]/index.mjs deleted file mode 100644 index 4c2b08b98d8..00000000000 --- a/sites/sde/pages/patterns/[id]/index.mjs +++ /dev/null @@ -1,60 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as patternsNs } from 'shared/components/account/patterns.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(patternsNs, authNs, pageNs, 'status') - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicPattern = dynamic( - () => import('shared/components/account/patterns.mjs').then((mod) => mod.ShowPattern), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const PatternPage = ({ page, id }) => { - const { t } = useTranslation(ns) - - return ( - - - - ) -} - -export default PatternPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['account', 'patterns', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: true }) diff --git a/sites/sde/pages/patterns/index.mjs b/sites/sde/pages/patterns/index.mjs deleted file mode 100644 index b74a5880e31..00000000000 --- a/sites/sde/pages/patterns/index.mjs +++ /dev/null @@ -1,53 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' - -import { ns as authNs } from 'shared/components/wrappers/auth/index.mjs' -import { ns as setsNs } from 'shared/components/account/sets.mjs' - -// Translation namespaces used on this page -const namespaces = [...new Set([...setsNs, ...authNs, ...pageNs])] - -/* - * Some things should never generated as SSR - * So for these, we run a dynamic import and disable SSR rendering - */ -const DynamicAuthWrapper = dynamic( - () => import('shared/components/wrappers/auth/index.mjs').then((mod) => mod.AuthWrapper), - { ssr: false } -) - -const DynamicPatterns = dynamic( - () => import('shared/components/account/patterns.mjs').then((mod) => mod.Patterns), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const PatternsIndexPage = ({ page }) => ( - - - - - -) - -export default PatternsIndexPage - -export async function getStaticProps({ locale }) { - return { - props: { - ...(await serverSideTranslations(locale, namespaces)), - page: { - locale, - path: ['patterns'], - }, - }, - } -} diff --git a/sites/sde/pages/sde/en.yaml b/sites/sde/pages/sde/en.yaml index 411b99b9638..53bd7b6d21f 100644 --- a/sites/sde/pages/sde/en.yaml +++ b/sites/sde/pages/sde/en.yaml @@ -15,6 +15,7 @@ tutorial.d: Follow along with our design tutorial design: Design support: Support code: Code +docs: Documentation chooseATemplate: Choose a template pageLeftBlank: Blank page pageLeftBlankMsg: This page was intentionally left blank. diff --git a/sites/sde/pages/sets/[id].mjs b/sites/sde/pages/sets/[id].mjs deleted file mode 100644 index 79b0643bfb0..00000000000 --- a/sites/sde/pages/sets/[id].mjs +++ /dev/null @@ -1,55 +0,0 @@ -// Dependencies -import dynamic from 'next/dynamic' -import { serverSideTranslations } from 'next-i18next/serverSideTranslations' -import { nsMerge } from 'shared/utils.mjs' -// Hooks -import { useTranslation } from 'next-i18next' -// Components -import { PageWrapper, ns as pageNs } from 'shared/components/wrappers/page.mjs' -import { ns as setsNs } from 'shared/components/account/sets.mjs' - -// Translation namespaces used on this page -const ns = nsMerge(setsNs, pageNs) - -const DynamicSet = dynamic( - () => import('shared/components/account/sets.mjs').then((mod) => mod.Mset), - { ssr: false } -) - -/* - * Each page MUST be wrapped in the PageWrapper component. - * You also MUST spread props.page into this wrapper component - * when path and locale come from static props (as here) - * or set them manually. - */ -const SetPage = ({ page, id }) => { - const { t } = useTranslation(ns) - - return ( - - - - ) -} - -export default SetPage - -export async function getStaticProps({ locale, params }) { - return { - props: { - ...(await serverSideTranslations(locale, ns)), - id: params.id, - page: { - locale, - path: ['sets', params.id], - }, - }, - } -} - -/* - * getStaticPaths() is used to specify for which routes (think URLs) - * this page should be used to generate the result. - * To learn more, see: https://nextjs.org/docs/basic-features/data-fetching - */ -export const getStaticPaths = async () => ({ paths: [], fallback: false }) diff --git a/sites/sde/pkgs/.gitkeep b/sites/sde/pkgs/.gitkeep new file mode 100644 index 00000000000..e69de29bb2d diff --git a/sites/sde/prebuild.mjs b/sites/sde/prebuild.mjs index e9cc45a903c..1e0dd9a0e4f 100644 --- a/sites/sde/prebuild.mjs +++ b/sites/sde/prebuild.mjs @@ -12,8 +12,8 @@ prebuildRunner({ // Always prebuild i18n: true, navigation: true, + designs: true, // Never prebuild - designs: false, favicon: false, ogImages: false, docs: false, diff --git a/sites/sde/public/img/lineup-backdrop.svg b/sites/sde/public/img/lineup-backdrop.svg new file mode 100644 index 00000000000..ad288284046 --- /dev/null +++ b/sites/sde/public/img/lineup-backdrop.svg @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + 0.60m + 0.80m + 1.00m + 1.20m + 1.40m + 1.60m + 1.80m + 2.00m + + + + + + + + + + + + + + + + + 2f + 3f + 4f + 5f + 6f + 7f + + + + diff --git a/sites/sde/public/locales/de/sde.json b/sites/sde/public/locales/de/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/de/sde.json +++ b/sites/sde/public/locales/de/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/sde/public/locales/en/sde.json b/sites/sde/public/locales/en/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/en/sde.json +++ b/sites/sde/public/locales/en/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/sde/public/locales/es/sde.json b/sites/sde/public/locales/es/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/es/sde.json +++ b/sites/sde/public/locales/es/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/sde/public/locales/fr/sde.json b/sites/sde/public/locales/fr/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/fr/sde.json +++ b/sites/sde/public/locales/fr/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/sde/public/locales/nl/sde.json b/sites/sde/public/locales/nl/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/nl/sde.json +++ b/sites/sde/public/locales/nl/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/sde/public/locales/uk/sde.json b/sites/sde/public/locales/uk/sde.json index fb9f1e6865a..7d7fe5aa7e0 100644 --- a/sites/sde/public/locales/uk/sde.json +++ b/sites/sde/public/locales/uk/sde.json @@ -16,6 +16,7 @@ "design": "Design", "support": "Support", "code": "Code", + "docs": "Documentation", "chooseATemplate": "Choose a template", "pageLeftBlank": "Blank page", "pageLeftBlankMsg": "This page was intentionally left blank.", diff --git a/sites/shared/components/account/apikeys.mjs b/sites/shared/components/account/apikeys.mjs index 6d8d554da70..2bca4946618 100644 --- a/sites/shared/components/account/apikeys.mjs +++ b/sites/shared/components/account/apikeys.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useEffect, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/bio.mjs b/sites/shared/components/account/bio.mjs index 7a70d5982a3..47e25849141 100644 --- a/sites/shared/components/account/bio.mjs +++ b/sites/shared/components/account/bio.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/compare.mjs b/sites/shared/components/account/compare.mjs index ad438129037..279395851b1 100644 --- a/sites/shared/components/account/compare.mjs +++ b/sites/shared/components/account/compare.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/consent.mjs b/sites/shared/components/account/consent.mjs index 5fbc7cb72e2..a21b2b15c38 100644 --- a/sites/shared/components/account/consent.mjs +++ b/sites/shared/components/account/consent.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/email.mjs b/sites/shared/components/account/email.mjs index d3d39a7eacc..11a332d8adf 100644 --- a/sites/shared/components/account/email.mjs +++ b/sites/shared/components/account/email.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/export.mjs b/sites/shared/components/account/export.mjs index d7c4f09f22e..97ff787c52a 100644 --- a/sites/shared/components/account/export.mjs +++ b/sites/shared/components/account/export.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/force-account-check.mjs b/sites/shared/components/account/force-account-check.mjs index a57434c3bba..4e5c0bd45d6 100644 --- a/sites/shared/components/account/force-account-check.mjs +++ b/sites/shared/components/account/force-account-check.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useEffect } from 'react' // Hooks diff --git a/sites/shared/components/account/github.mjs b/sites/shared/components/account/github.mjs index bfbfff1ad49..8f07f251ed2 100644 --- a/sites/shared/components/account/github.mjs +++ b/sites/shared/components/account/github.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/imperial.mjs b/sites/shared/components/account/imperial.mjs index b00c16ec807..b68729e2357 100644 --- a/sites/shared/components/account/imperial.mjs +++ b/sites/shared/components/account/imperial.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/language.mjs b/sites/shared/components/account/language.mjs index 55b1c98ece1..209a693ecdc 100644 --- a/sites/shared/components/account/language.mjs +++ b/sites/shared/components/account/language.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/links.mjs b/sites/shared/components/account/links.mjs index 8fd11e6215e..101e8379919 100644 --- a/sites/shared/components/account/links.mjs +++ b/sites/shared/components/account/links.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment import { useState, useEffect } from 'react' import { useAccount } from 'shared/hooks/use-account.mjs' import { useBackend } from 'shared/hooks/use-backend.mjs' diff --git a/sites/shared/components/account/mfa.mjs b/sites/shared/components/account/mfa.mjs index 40072614aa6..b7781b1eed7 100644 --- a/sites/shared/components/account/mfa.mjs +++ b/sites/shared/components/account/mfa.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/newsletter.mjs b/sites/shared/components/account/newsletter.mjs index def56fe189c..e20f30799e5 100644 --- a/sites/shared/components/account/newsletter.mjs +++ b/sites/shared/components/account/newsletter.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/overview.mjs b/sites/shared/components/account/overview.mjs index 2c5e6bbb710..045fd7ebe5c 100644 --- a/sites/shared/components/account/overview.mjs +++ b/sites/shared/components/account/overview.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment import { AccountLinks } from './links.mjs' export const AccountOverview = ({ app }) => diff --git a/sites/shared/components/account/password.mjs b/sites/shared/components/account/password.mjs index 2c4e7e0ddba..2b007c602fa 100644 --- a/sites/shared/components/account/password.mjs +++ b/sites/shared/components/account/password.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/patterns.mjs b/sites/shared/components/account/patterns.mjs index 848e945f306..80745bbb3b5 100644 --- a/sites/shared/components/account/patterns.mjs +++ b/sites/shared/components/account/patterns.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { useState, useEffect, useContext } from 'react' import { useTranslation } from 'next-i18next' diff --git a/sites/shared/components/account/platform.mjs b/sites/shared/components/account/platform.mjs index 4b3ce242c30..43fb764c89a 100644 --- a/sites/shared/components/account/platform.mjs +++ b/sites/shared/components/account/platform.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/profile.mjs b/sites/shared/components/account/profile.mjs index 59a1a871738..e3b0147005a 100644 --- a/sites/shared/components/account/profile.mjs +++ b/sites/shared/components/account/profile.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Hooks import { useAccount } from 'shared/hooks/use-account.mjs' // Components diff --git a/sites/shared/components/account/reload.mjs b/sites/shared/components/account/reload.mjs index 32d7273436f..d82b43e7188 100644 --- a/sites/shared/components/account/reload.mjs +++ b/sites/shared/components/account/reload.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/remove.mjs b/sites/shared/components/account/remove.mjs index 2c925edcd9c..b22536c21db 100644 --- a/sites/shared/components/account/remove.mjs +++ b/sites/shared/components/account/remove.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/restrict.mjs b/sites/shared/components/account/restrict.mjs index 34d33860a8e..255b5d64aee 100644 --- a/sites/shared/components/account/restrict.mjs +++ b/sites/shared/components/account/restrict.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/account/role.mjs b/sites/shared/components/account/role.mjs index b784695658d..e0391325c08 100644 --- a/sites/shared/components/account/role.mjs +++ b/sites/shared/components/account/role.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment export const ns = ['roles'] const colors = { diff --git a/sites/shared/components/account/sets.mjs b/sites/shared/components/account/sets.mjs index a0013bec217..46207688191 100644 --- a/sites/shared/components/account/sets.mjs +++ b/sites/shared/components/account/sets.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Dependencies import { measurements } from 'config/measurements.mjs' import { measurements as designMeasurements } from 'shared/prebuild/data/design-measurements.mjs' diff --git a/sites/shared/components/account/status.mjs b/sites/shared/components/account/status.mjs index 3edb744fceb..cfc9d623d16 100644 --- a/sites/shared/components/account/status.mjs +++ b/sites/shared/components/account/status.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment import { freeSewingConfig } from 'shared/config/freesewing.config.mjs' export const ns = ['status'] diff --git a/sites/shared/components/account/username.mjs b/sites/shared/components/account/username.mjs index 128340b3cd1..bdad167fa4b 100644 --- a/sites/shared/components/account/username.mjs +++ b/sites/shared/components/account/username.mjs @@ -1,4 +1,3 @@ -// __SDEFILE__ - This file is a dependency for the stand-alone environment // Context import { LoadingStatusContext } from 'shared/context/loading-status-context.mjs' // Hooks diff --git a/sites/shared/components/workbench/pattern/movable/stack.mjs b/sites/shared/components/workbench/pattern/movable/stack.mjs index d9c3194869e..f11aa01ac8d 100644 --- a/sites/shared/components/workbench/pattern/movable/stack.mjs +++ b/sites/shared/components/workbench/pattern/movable/stack.mjs @@ -44,7 +44,7 @@ */ import { useRef, useState, useEffect, useCallback } from 'react' import { generateStackTransform, getTransformedBounds } from '@freesewing/core' -import { getProps } from 'pkgs/react-components/src/index.mjs' +import { getProps } from 'pkgs/react-components/src/pattern/utils.mjs' import { angle } from '../utils.mjs' import { drag } from 'd3-drag' import { select } from 'd3-selection' diff --git a/sites/shared/prebuild/data/design-measurements.mjs b/sites/shared/prebuild/data/design-measurements.mjs new file mode 100644 index 00000000000..8b6879146eb --- /dev/null +++ b/sites/shared/prebuild/data/design-measurements.mjs @@ -0,0 +1,401 @@ +// __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 +export const measurements = { + aaron: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + ], + albert: ['chest', 'hpsToWaistBack', 'waist', 'waistToKnee', 'hips'], + bee: [ + 'highBust', + 'chest', + 'underbust', + 'waist', + 'waistBack', + 'bustSpan', + 'neck', + 'hpsToBust', + 'hpsToWaistFront', + 'hpsToWaistBack', + 'shoulderToShoulder', + 'shoulderSlope', + 'bustPointToUnderbust', + ], + bella: [ + 'highBust', + 'chest', + 'underbust', + 'waist', + 'waistBack', + 'bustSpan', + 'neck', + 'hpsToBust', + 'hpsToWaistFront', + 'hpsToWaistBack', + 'shoulderToShoulder', + 'shoulderSlope', + ], + benjamin: ['neck'], + bent: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'shoulderToElbow', + 'shoulderToWrist', + 'wrist', + ], + bob: [], + breanna: [ + 'biceps', + 'bustFront', + 'bustSpan', + 'highBust', + 'highBustFront', + 'hpsToBust', + 'hpsToWaistBack', + 'hpsToWaistFront', + 'waist', + 'waistToHips', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'shoulderToWrist', + 'wrist', + ], + brian: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'shoulderToWrist', + 'wrist', + ], + bruce: ['hips', 'upperLeg', 'waistToHips', 'waistToUpperLeg'], + carlita: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'waist', + 'waistToFloor', + 'waistToSeat', + 'seat', + 'highBust', + 'bustSpan', + 'shoulderToElbow', + 'shoulderToWrist', + 'wrist', + ], + carlton: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'waist', + 'waistToFloor', + 'waistToSeat', + 'seat', + 'shoulderToElbow', + 'shoulderToWrist', + 'wrist', + ], + cathrin: ['underbust', 'waist', 'hips', 'waistToUnderbust', 'waistToHips'], + charlie: [ + 'crossSeam', + 'crossSeamFront', + 'knee', + 'seat', + 'seatBack', + 'waist', + 'waistBack', + 'waistToFloor', + 'waistToKnee', + 'waistToHips', + 'waistToSeat', + 'waistToUpperLeg', + ], + cornelius: [ + 'waist', + 'hips', + 'inseam', + 'seat', + 'waistToKnee', + 'waistToHips', + 'waistToFloor', + 'knee', + ], + diana: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'waist', + 'shoulderToWrist', + 'wrist', + ], + examples: ['head'], + florence: ['head'], + florent: ['head'], + hi: [], + holmes: ['head'], + hortensia: [], + huey: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'shoulderToWrist', + 'wrist', + 'head', + ], + hugo: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'shoulderToWrist', + 'wrist', + 'head', + ], + jaeger: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'waist', + 'shoulderToElbow', + 'shoulderToWrist', + 'wrist', + ], + legend: [], + lucy: [], + lunetius: [ + 'waistToKnee', + 'waistToUpperLeg', + 'waistToFloor', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderToElbow', + 'waistToHips', + ], + magde: [], + noble: [ + 'highBust', + 'chest', + 'underbust', + 'waist', + 'waistBack', + 'bustSpan', + 'neck', + 'hpsToBust', + 'hpsToWaistFront', + 'hpsToWaistBack', + 'shoulderToShoulder', + 'shoulderSlope', + ], + octoplushy: [], + paco: [ + 'crossSeam', + 'crossSeamFront', + 'knee', + 'seat', + 'seatBack', + 'waist', + 'waistBack', + 'waistToFloor', + 'waistToKnee', + 'waistToHips', + 'waistToSeat', + 'waistToUpperLeg', + 'heel', + ], + penelope: ['waist', 'seat', 'waistToHips', 'waistToSeat', 'waistToKnee'], + plugintest: ['seat', 'seatBack', 'waist', 'waistBack', 'crossSeam', 'crossSeamFront'], + rendertest: [], + sandy: ['waist', 'waistToFloor', 'waistToHips', 'hips'], + shin: ['hips', 'upperLeg', 'waistToUpperLeg', 'waistToHips'], + simon: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'waist', + 'hips', + 'shoulderToWrist', + 'wrist', + ], + simone: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'waist', + 'hips', + 'highBust', + 'bustSpan', + 'shoulderToWrist', + 'wrist', + ], + sven: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'waist', + 'shoulderToWrist', + 'wrist', + ], + tamiko: ['shoulderToShoulder', 'chest', 'hpsToWaistBack', 'shoulderSlope', 'waistToHips'], + teagan: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'waist', + ], + tiberius: [ + 'head', + 'shoulderToElbow', + 'shoulderToShoulder', + 'biceps', + 'hpsToWaistBack', + 'waistToKnee', + 'waist', + 'chest', + 'seat', + 'hips', + 'waistToFloor', + 'waistToUpperLeg', + ], + titan: [ + 'crossSeam', + 'crossSeamFront', + 'knee', + 'seat', + 'seatBack', + 'waist', + 'waistBack', + 'waistToFloor', + 'waistToKnee', + 'waistToHips', + 'waistToSeat', + 'waistToUpperLeg', + ], + trayvon: ['hpsToWaistBack', 'waistToHips', 'neck'], + uma: ['waist', 'seat', 'waistToSeat', 'waistToUpperLeg'], + wahid: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'waist', + ], + walburga: [ + 'head', + 'shoulderToShoulder', + 'hpsToWaistBack', + 'waistToKnee', + 'waistToHips', + 'waistToFloor', + 'waistToUpperLeg', + 'neck', + ], + waralee: ['seat', 'inseam', 'crotchDepth', 'waistToHips'], + yuri: [ + 'biceps', + 'chest', + 'hpsToBust', + 'hpsToWaistBack', + 'neck', + 'shoulderToShoulder', + 'shoulderSlope', + 'waistToArmpit', + 'waistToHips', + 'hips', + 'shoulderToWrist', + 'wrist', + 'head', + ], +} diff --git a/sites/shared/prebuild/data/design-options.mjs b/sites/shared/prebuild/data/design-options.mjs new file mode 100644 index 00000000000..28a72af2693 --- /dev/null +++ b/sites/shared/prebuild/data/design-options.mjs @@ -0,0 +1,1601 @@ +// __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 +export const options = { + aaron: { + brianFitSleeve: false, + brianFitCollar: false, + collarFactor: 4.8, + bicepsEase: 0.05, + chestEase: { pct: 8, min: 0, max: 20, menu: 'style' }, + collarEase: 0, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false, menu: 'fit' }, + shoulderEase: 0, + lengthBonus: { pct: 10, min: -20, max: 60, menu: 'style' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: 0.97, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: 0.6, + backNeckCutout: 0.05, + frontArmholeDeeper: 0, + shoulderSlopeReduction: 0, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + hipsEase: { pct: 8, min: 0, max: 20, menu: 'fit' }, + stretchFactor: { pct: 5, min: 0, max: 15, menu: 'fit' }, + armholeDrop: { pct: 10, min: 0, max: 75, menu: 'style' }, + necklineBend: { pct: 100, min: 40, max: 100, menu: 'style' }, + necklineDrop: { pct: 20, min: 10, max: 35, menu: 'style' }, + shoulderStrapWidth: { pct: 15, min: 10, max: 40, menu: 'style' }, + shoulderStrapPlacement: { pct: 40, min: 20, max: 80, menu: 'style' }, + backlineBend: { pct: 50, min: 25, max: 100, menu: 'style' }, + knitBindingWidth: { pct: 600, min: 300, max: 800, menu: 'style' }, + }, + albert: { + backOpening: { pct: 10, min: 0, max: 25, menu: 'fit' }, + bibWidth: { pct: 100, min: 50, max: 125, menu: 'style' }, + bibLength: { pct: 75, min: 0, max: 90, menu: 'style' }, + lengthBonus: { pct: 0, min: -20, max: 25, menu: 'style' }, + chestDepth: { pct: 22, min: 15, max: 90, menu: 'fit' }, + strapWidth: { pct: 60, min: 20, max: 100, menu: 'style' }, + }, + bee: { + acrossBackFactor: 0.925, + shoulderSlopeBack: 1.23, + neckWidthBack: 0.197, + neckWidthFront: 0.17, + backDartLocation: 0.145, + backCenterWaistReduction: 0.35, + collarFactor: 0.19, + bustSpanEase: { pct: 10, min: 0, max: 20, menu: 'fit' }, + chestEase: { pct: 11, min: 5, max: 20, menu: 'fit' }, + fullChestEaseReduction: { pct: 4, min: 0, max: 8, menu: 'fit' }, + shoulderToShoulderEase: { pct: -0.5, min: -1, max: 5, menu: 'fit' }, + waistEase: { pct: 5, min: 1, max: 20, menu: 'fit' }, + backDartHeight: { pct: 46, min: 38, max: 54, menu: 'advanced' }, + bustDartCurve: 1, + bustDartLength: 1, + waistDartLength: 1, + armholeDepth: { pct: 44, min: 38, max: 46, menu: 'advanced' }, + backArmholeCurvature: 0.63, + backArmholePitchDepth: 0.35, + backArmholeSlant: 5, + frontArmholeCurvature: 0.63, + frontArmholePitchDepth: { pct: 29, max: 31, min: 27, menu: 'advanced' }, + backHemSlope: 2.5, + backNeckCutout: 0.06, + frontShoulderWidth: { pct: 95, max: 98, min: 92, menu: 'advanced' }, + highBustWidth: { pct: 86, max: 92, min: 80, menu: 'advanced' }, + ties: { bool: true, menu: 'style' }, + crossBackTies: { bool: false, menu: 'style' }, + bandLength: { pct: 85, min: 75, max: 90, menu: 'style' }, + neckTieLength: { pct: 80, min: 70, max: 100, menu: 'style' }, + neckTieWidth: { + pct: 6, + min: 2, + max: 18, + snap: { metric: [6, 13, 19, 25, 32, 38], imperial: [6.35, 12.7, 19.05, 25.4, 31.75, 38.1] }, + menu: 'style', + }, + reversible: { bool: false, menu: 'style' }, + topDepth: { pct: 54, min: 50, max: 80, menu: 'fit' }, + bottomCupDepth: { pct: 8, min: 0, max: 20, menu: 'fit' }, + sideDepth: { pct: 20.6, min: 0, max: 30, menu: 'fit' }, + sideCurve: { pct: 0, min: -50, max: 50, menu: 'fit' }, + frontCurve: { pct: 0, min: -50, max: 50, menu: 'fit' }, + bellaGuide: { bool: false, menu: 'fit' }, + pointedTieEnds: { bool: false, menu: 'style' }, + duoColorTies: { bool: false, menu: 'style' }, + bandTieWidth: { + pct: 3, + min: 1, + max: 9, + snap: { metric: [6, 13, 19, 25, 32, 38], imperial: [6.35, 12.7, 19.05, 25.4, 31.75, 38.1] }, + menu: 'style', + }, + bandTieLength: { pct: 35, min: 30, max: 50, menu: 'style' }, + }, + bella: { + acrossBackFactor: 0.925, + shoulderSlopeBack: 1.23, + neckWidthBack: 0.197, + neckWidthFront: 0.17, + backDartLocation: 0.145, + backCenterWaistReduction: 0.35, + collarFactor: 0.19, + bustSpanEase: { pct: 10, min: 0, max: 20, menu: 'fit' }, + chestEase: { pct: 11, min: 5, max: 20, menu: 'fit' }, + fullChestEaseReduction: { pct: 4, min: 0, max: 8, menu: 'fit' }, + shoulderToShoulderEase: { pct: -0.5, min: -1, max: 5, menu: 'fit' }, + waistEase: { pct: 5, min: 1, max: 20, menu: 'fit' }, + backDartHeight: { pct: 46, min: 38, max: 54, menu: 'darts' }, + bustDartCurve: { pct: 100, min: 0, max: 100, menu: 'darts' }, + bustDartLength: { pct: 90, min: 75, max: 100, menu: 'darts' }, + waistDartLength: { pct: 90, min: 75, max: 95, menu: 'darts' }, + armholeDepth: { pct: 44, min: 38, max: 46, menu: 'armhole' }, + backArmholeCurvature: { pct: 63, min: 50, max: 85, menu: 'armhole' }, + backArmholePitchDepth: { pct: 35, max: 40, min: 30, menu: 'armhole' }, + backArmholeSlant: { deg: 5, min: 1, max: 9, menu: 'armhole' }, + frontArmholeCurvature: { pct: 63, min: 50, max: 85, menu: 'armhole' }, + frontArmholePitchDepth: { pct: 29, max: 31, min: 27, menu: 'armhole' }, + backHemSlope: { deg: 2.5, min: 0, max: 5, menu: 'advanced' }, + backNeckCutout: { pct: 6, min: 3, max: 9, menu: 'advanced' }, + frontShoulderWidth: { pct: 95, max: 98, min: 92, menu: 'advanced' }, + highBustWidth: { pct: 86, max: 92, min: 80, menu: 'advanced' }, + }, + benjamin: { + transitionLength: 2, + bandLength: 0.17, + adjustmentRibbonWidth: 20, + collarEase: { pct: 3, min: 0, max: 6, menu: 'fit' }, + adjustmentRibbon: { bool: false, menu: 'fit' }, + tipWidth: { pct: 15, min: 0, max: 20, menu: 'style' }, + knotWidth: { pct: 7, min: 5, max: 10, menu: 'style' }, + bowLength: { pct: 28, min: 23, max: 33, menu: 'style' }, + bowStyle: { + dflt: 'butterfly', + list: ['diamond', 'butterfly', 'square', 'widesquare'], + menu: 'style', + }, + endStyle: { dflt: 'straight', list: ['straight', 'pointed', 'rounded'], menu: 'style' }, + collarBandHeight: { pct: 6, min: 5, max: 8, menu: 'style' }, + }, + bent: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 20, min: 10, max: 40, menu: 'fit' }, + chestEase: { pct: 8, min: -4, max: 20, menu: 'fit' }, + collarEase: { pct: 3.5, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 40, min: 2, max: 100, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 0, min: -4, max: 60, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 97, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 5, min: -10, max: 50 }, + armholeDepthFactor: { pct: 60, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.5, min: 0, max: 1.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + sleeveLengthBonus: { pct: 0, min: -20, max: 15, menu: 'fit' }, + sleeveBend: { deg: 10, min: 0, max: 20, menu: 'fit' }, + sleevecapHeight: { pct: 45, min: 40, max: 60, menu: 'advanced' }, + sleevecapEase: { pct: 1, min: 0, max: 10, menu: 'advanced' }, + }, + bob: { + neckRatio: { pct: 80, min: 70, max: 90, menu: 'fit' }, + widthRatio: { pct: 45, min: 35, max: 55, menu: 'fit' }, + lengthRatio: { pct: 75, min: 55, max: 85, menu: 'fit' }, + headSize: { pct: 100, min: 10, max: 200, snap: 5, menu: 'size' }, + }, + breanna: { + collarFactor: 4.8, + armholeDepthBase: 0.6, + shoulderSeamLength: 0.95, + sleeveWidthGuarantee: 0.9, + breannaFitSleeve: true, + breannaFitCollar: true, + shoulderDart: { bool: false, menu: 'fit' }, + waistDart: { bool: true, menu: 'fit' }, + primaryBustDart: { + list: [ + '06:00', + '07:00', + '08:00', + '09:00', + '10:00', + '11:00', + '11:30', + '12:00', + '12:30', + '13:00', + '13:30', + '14:00', + '15:00', + '16:00', + '17:00', + ], + dflt: '06:00', + doNotTranslate: true, + menu: 'style', + }, + secondaryBustDart: { + list: [ + 'none', + '06:00', + '07:00', + '08:00', + '09:00', + '10:00', + '11:00', + '11:30', + '12:00', + '12:30', + '13:00', + '13:30', + '14:00', + '15:00', + '16:00', + '17:00', + ], + dflt: '13:30', + doNotTranslate: true, + menu: 'style', + }, + acrossBackFactor: { pct: 96, min: 93, max: 100, menu: 'advanced' }, + armholeDepthFactor: { pct: 100, min: 80, max: 120, menu: 'advanced' }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + shoulderDartSize: { pct: 7, min: 4, max: 10 }, + shoulderDartLength: { pct: 85, min: 60, max: 100 }, + waistDartSize: { pct: 10, min: 4, max: 15 }, + waistDartLength: { pct: 85, min: 60, max: 100 }, + verticalEase: { pct: 2, min: 0, max: 8, menu: 'fit' }, + frontArmholeDeeper: { pct: 1, min: 0, max: 5, menu: 'advanced' }, + shoulderEase: { pct: 0, min: 0, max: 4, menu: 'fit' }, + collarEase: { pct: 3.5, min: 0, max: 10, menu: 'fit' }, + chestEase: { pct: 10, min: 5, max: 20, menu: 'fit' }, + waistEase: { pct: 10, min: 5, max: 20, menu: 'fit' }, + primaryBustDartShaping: { pct: 50, min: 25, max: 75, menu: 'style' }, + primaryBustDartLength: { pct: 85, min: 65, max: 95, menu: 'style' }, + secondaryBustDartLength: { pct: 85, min: 65, max: 95, menu: 'style' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 100, menu: 'advanced' }, + frontScyeDart: { pct: 25, min: 0, max: 45, menu: 'fit' }, + sleevecapEase: { pct: 0.5, min: 0, max: 2.5, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 110, min: 35, max: 165, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 45, min: 35, max: 55, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 3, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 5.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 4.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 12.5, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 12.5, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 12.5, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 12.5, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + cuffEase: { pct: 20, min: 0, max: 50, menu: 'fit' }, + sleeveLengthBonus: { pct: 0, min: -40, max: 10, menu: 'style' }, + }, + brian: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 5, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 0, min: -4, max: 60, menu: 'style' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + sleeveLengthBonus: { pct: 0, min: -40, max: 10, menu: 'style' }, + }, + bruce: { + hipRatioFront: 0.245, + hipRatioBack: 0.315, + legRatioInset: 0.3, + legRatioBack: 0.32, + gussetRatio: 0.0666, + gussetInsetRatio: 0.6, + heightRatioInset: 0.65, + bulge: { deg: 20, min: 0, max: 40, menu: 'fit' }, + legBonus: { pct: 0, min: -10, max: 20, menu: 'style' }, + rise: { pct: 10, min: 0, max: 25, menu: 'style' }, + stretch: { pct: 15, min: 5, max: 25, menu: 'fit' }, + legStretch: { pct: 40, min: 25, max: 45, menu: 'fit' }, + backRise: { pct: 5, min: 0, max: 10, menu: 'fit' }, + }, + carlita: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 20, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 10, min: 5, max: 20, menu: 'fit' }, + collarEase: 0.145, + cuffEase: { pct: 60, min: 30, max: 100, menu: 'fit' }, + draftForHighBust: true, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: 0, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 97, min: 93, max: 100, menu: 'fit' }, + armholeDepth: { pct: 5, min: -10, max: 50 }, + armholeDepthFactor: { pct: 65, min: 50, max: 70, menu: 'fit' }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.5, min: 0, max: 1.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 12, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + buttonSpacingHorizontal: { pct: 43.5, min: 15, max: 60, menu: 'style' }, + length: { pct: 69, min: 35, max: 100, menu: 'style' }, + lapelReduction: { pct: 5, min: 0, max: 10, menu: 'advanced' }, + frontOverlap: { pct: 1.5, min: 1, max: 2, menu: 'advanced' }, + pocketPlacementHorizontal: { pct: 11, min: 5, max: 20, menu: 'pockets' }, + pocketPlacementVertical: { pct: 6, min: 5, max: 60, menu: 'pockets' }, + pocketWidth: { pct: 95, min: 70, max: 120, menu: 'pockets' }, + pocketHeight: { pct: 15, min: 0, max: 40, menu: 'pockets' }, + pocketRadius: { pct: 20, min: 0, max: 50, menu: 'pockets' }, + pocketFlapRadius: { pct: 15, min: 0, max: 50, menu: 'pockets' }, + chestPocketPlacement: { pct: 55, min: 30, max: 65, menu: 'pockets' }, + chestPocketAngle: 0, + chestPocketHeight: { pct: 60, min: 40, max: 80, menu: 'pockets' }, + chestPocketWidth: { pct: 25, min: 15, max: 50, menu: 'pockets' }, + innerPocketPlacement: { pct: 53, min: 42, max: 62, menu: 'pockets' }, + innerPocketWidth: { pct: 50, min: 45, max: 65, menu: 'pockets' }, + waistEase: { pct: 14, min: 8, max: 25, menu: 'fit' }, + seatEase: { pct: 14, min: 8, max: 25, menu: 'fit' }, + innerPocketWeltHeight: { pct: 3.5, min: 2.5, max: 5, menu: 'pockets' }, + contour: { pct: 50, min: 25, max: 75, menu: 'advanced' }, + backPleat: 0.048, + beltWidth: { pct: 15, min: 10, max: 20, menu: 'style' }, + sleeveLengthBonus: { pct: 7, min: 0, max: 20, menu: 'fit' }, + sleeveBend: { deg: 10, min: 0, max: 20, menu: 'fit' }, + sleevecapHeight: { pct: 45, min: 40, max: 60, menu: 'advanced' }, + sleevecapEase: { pct: 1, min: 0, max: 10, menu: 'advanced' }, + cuffLength: { pct: 15, min: 10, max: 20, menu: 'style' }, + chestShapingMax: 5, + collarHeight: { pct: 9.6, min: 8, max: 11, menu: 'collar' }, + collarFlare: { pct: 20, min: 0, max: 40, menu: 'collar' }, + collarSpread: { deg: 4, min: 2, max: 6, menu: 'collar' }, + innerPocketDepth: { pct: 110, min: 75, max: 140, menu: 'pockets' }, + }, + carlton: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 20, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 10, min: 5, max: 20, menu: 'fit' }, + collarEase: 0.145, + cuffEase: { pct: 60, min: 30, max: 100, menu: 'fit' }, + draftForHighBust: { bool: false, menu: 'fit' }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: 0, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 97, min: 93, max: 100, menu: 'fit' }, + armholeDepth: { pct: 5, min: -10, max: 50 }, + armholeDepthFactor: { pct: 65, min: 50, max: 70, menu: 'fit' }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.5, min: 0, max: 1.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 12, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + buttonSpacingHorizontal: { pct: 43.5, min: 15, max: 60, menu: 'style' }, + length: { pct: 69, min: 35, max: 100, menu: 'style' }, + lapelReduction: { pct: 5, min: 0, max: 10, menu: 'advanced' }, + frontOverlap: { pct: 1.5, min: 1, max: 2, menu: 'advanced' }, + pocketPlacementHorizontal: { pct: 11, min: 5, max: 20, menu: 'pockets' }, + pocketPlacementVertical: { pct: 6, min: 5, max: 60, menu: 'pockets' }, + pocketWidth: { pct: 95, min: 70, max: 120, menu: 'pockets' }, + pocketHeight: { pct: 15, min: 0, max: 40, menu: 'pockets' }, + pocketRadius: { pct: 20, min: 0, max: 50, menu: 'pockets' }, + pocketFlapRadius: { pct: 15, min: 0, max: 50, menu: 'pockets' }, + chestPocketPlacement: { pct: 55, min: 30, max: 65, menu: 'pockets' }, + chestPocketAngle: { deg: 4, min: 0, max: 6, menu: 'pockets' }, + chestPocketHeight: { pct: 60, min: 40, max: 80, menu: 'pockets' }, + chestPocketWidth: { pct: 25, min: 15, max: 50, menu: 'pockets' }, + innerPocketPlacement: { pct: 53, min: 42, max: 62, menu: 'pockets' }, + innerPocketWidth: { pct: 50, min: 45, max: 65, menu: 'pockets' }, + waistEase: { pct: 14, min: 8, max: 25, menu: 'fit' }, + seatEase: { pct: 14, min: 8, max: 25, menu: 'fit' }, + innerPocketWeltHeight: { pct: 3.5, min: 2.5, max: 5, menu: 'pockets' }, + backPleat: 0.048, + beltWidth: { pct: 15, min: 10, max: 20, menu: 'style' }, + sleeveLengthBonus: { pct: 7, min: 0, max: 20, menu: 'fit' }, + sleeveBend: { deg: 10, min: 0, max: 20, menu: 'fit' }, + sleevecapHeight: { pct: 45, min: 40, max: 60, menu: 'advanced' }, + sleevecapEase: { pct: 1, min: 0, max: 10, menu: 'advanced' }, + cuffLength: { pct: 15, min: 10, max: 20, menu: 'style' }, + chestShapingMax: 5, + collarHeight: { pct: 9.6, min: 8, max: 11, menu: 'collar' }, + collarFlare: { pct: 20, min: 0, max: 40, menu: 'collar' }, + collarSpread: { deg: 4, min: 2, max: 6, menu: 'collar' }, + innerPocketDepth: { pct: 110, min: 75, max: 140, menu: 'pockets' }, + }, + cathrin: { + waistReduction: { pct: 10, min: 2, max: 20, menu: 'fit' }, + panels: { list: ['11', '13'], dflt: '13', menu: 'fit' }, + backOpening: { pct: 4, min: 3, max: 10, menu: 'style' }, + backRise: { pct: 15, min: 1, max: 25, menu: 'style' }, + backDrop: { pct: 2, min: 0, max: 5, menu: 'style' }, + frontRise: { pct: 4, min: 0.1, max: 8, menu: 'style' }, + frontDrop: { pct: 5, min: 0, max: 10, menu: 'style' }, + hipRise: { pct: 5, min: 0, max: 15, menu: 'style' }, + }, + charlie: { + fitCrossSeam: true, + fitCrossSeamFront: true, + fitCrossSeamBack: true, + fitGuides: false, + waistEase: { pct: 1, min: 0, max: 5, menu: 'fit' }, + seatEase: { pct: 5, min: 0, max: 10, menu: 'fit' }, + kneeEase: { pct: 15, min: 10, max: 30, menu: 'fit' }, + waistHeight: { pct: -4, min: -15, max: 40, menu: 'style' }, + lengthBonus: { pct: 2, min: -20, max: 10, menu: 'style' }, + crotchDrop: { pct: 2, min: 0, max: 15, menu: 'style' }, + fitKnee: true, + legBalance: { pct: 57.5, min: 52.5, max: 62.5, menu: 'advanced' }, + crossSeamCurveStart: { pct: 85, min: 60, max: 100, menu: 'advanced' }, + crossSeamCurveBend: { pct: 65, min: 45, max: 85, menu: 'advanced' }, + crossSeamCurveAngle: { deg: 12, min: 0, max: 20, menu: 'advanced' }, + crotchSeamCurveStart: { pct: 80, min: 60, max: 95, menu: 'advanced' }, + crotchSeamCurveBend: { pct: 80, min: 45, max: 100, menu: 'advanced' }, + crotchSeamCurveAngle: { deg: 25, min: 0, max: 35, menu: 'advanced' }, + waistBalance: { pct: 55, min: 30, max: 90, menu: 'advanced' }, + grainlinePosition: { pct: 50, min: 30, max: 60, menu: 'advanced' }, + waistbandWidth: { + pct: 3, + min: 1, + max: 6, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'style', + }, + waistbandReduction: 0.25, + waistbandFactor: 0.1, + frontPocketSlantDepth: { pct: 85, min: 70, max: 100, menu: 'pockets.frontpockets' }, + frontPocketSlantWidth: { pct: 25, min: 15, max: 35, menu: 'pockets.frontpockets' }, + frontPocketSlantRound: { pct: 30, min: 5, max: 50, menu: 'pockets.frontpockets' }, + frontPocketSlantBend: { pct: 25, min: 5, max: 50, menu: 'pockets.frontpockets' }, + frontPocketWidth: { pct: 55, min: 45, max: 65, menu: 'pockets.frontpockets' }, + frontPocketDepth: { pct: 100, min: 85, max: 110, menu: 'pockets.frontpockets' }, + frontPocketFacing: { pct: 45, min: 25, max: 65, menu: 'pockets.frontpockets' }, + flyCurve: { pct: 72, min: 50, max: 100, menu: 'advanced.fly' }, + flyLength: { pct: 45, min: 30, max: 60, menu: 'advanced.fly' }, + flyWidth: { pct: 15, min: 10, max: 20, menu: 'advanced.fly' }, + backPocketVerticalPlacement: { pct: 24, min: 18, max: 30, menu: 'pockets.backpockets' }, + backPocketHorizontalPlacement: { pct: 55, min: 48, max: 62, menu: 'pockets.backpockets' }, + backPocketWidth: { pct: 55, min: 50, max: 60, menu: 'pockets.backpockets' }, + backPocketDepth: { pct: 60, min: 40, max: 80, menu: 'pockets.backpockets' }, + backPocketFacing: { bool: true, menu: 'pockets.backpockets' }, + waistbandCurve: { pct: 0, min: 0, max: 35, menu: 'fit' }, + beltLoops: { count: 8, min: 6, max: 12, menu: 'advanced' }, + }, + cornelius: { + pctAtoO: 0.5, + pctAtoC: 0.25, + pctUtoA: 0.25, + pctJtoA: 0.25, + pctSeatAdjustment: 0.5, + ventLength: { pct: 70, min: 50, max: 110, menu: 'style' }, + fullness: { pct: 0, min: 0, max: 55, menu: 'fit' }, + waistbandBelowWaist: { pct: 5, min: 0, max: 15, menu: 'style' }, + waistReduction: { pct: 1, min: -2, max: 10, menu: 'fit' }, + bandBelowKnee: { pct: 25, min: 15, max: 50, menu: 'advanced' }, + pctZtoR: 0.35, + pctRtoZin: 0.75, + pctRtoZup: 0.25, + pctRtoKin: 0.75, + pctRtoKdown: 0.25, + pctKtoRout: 0.15, + pctKtoRup: 0.25, + pctKtoH: 0.7, + kneeToBelow: { pct: 94, min: 85, max: 110, menu: 'advanced' }, + cuffWidth: { pct: 0, min: -50, max: 150, menu: 'style' }, + cuffStyle: { dflt: 'elegant', list: ['traditional', 'elegant', 'keystone'], menu: 'style' }, + }, + diana: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 5, + bicepsEase: { pct: 0, min: -5, max: 50, menu: 'fit' }, + chestEase: { pct: 0, min: -10, max: 20, menu: 'fit' }, + collarEase: 0, + cuffEase: { pct: 20, min: 0, max: 30, menu: 'fit' }, + draftForHighBust: { bool: false, menu: 'fit' }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 0, min: 0, max: 50, menu: 'fit' }, + s3Collar: 0, + s3Armhole: 0, + acrossBackFactor: { pct: 97, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 0, min: 0, max: 20, menu: 'advanced' }, + armholeDepthFactor: { pct: 55, min: 50, max: 70, menu: 'advanced' }, + backNeckCutout: 0.05, + frontArmholeDeeper: { pct: 0, min: 0, max: 1.5, menu: 'advanced' }, + shoulderSlopeReduction: 0, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + drapeAngle: { deg: 20, min: 10, max: 30, menu: 'style' }, + sleeveLengthBonus: { pct: 0, min: -40, max: 10, menu: 'fit' }, + shoulderSeamLength: { pct: 35, min: 0.1, max: 60, menu: 'style' }, + waistEase: { pct: 0, min: -10, max: 20, menu: 'fit' }, + hipsEase: { pct: 0, min: -10, max: 20, menu: 'fit' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 100, min: 35, max: 165, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 3, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 5.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 4.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 6, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + }, + examples: { + size: { pct: 50, min: 5, max: 100, menu: 'stack' }, + x: { pct: 0, min: -100, max: 100, menu: 'stack' }, + y: { pct: 0, min: -100, max: 100, menu: 'stack' }, + stackIt: { dflt: 'Do stack', list: ['Do stack', 'Do not stack'], menu: 'stack' }, + }, + florence: { + length: { pct: 40, min: 35, max: 45, menu: 'fit' }, + height: { pct: 26, min: 23, max: 29, menu: 'fit' }, + curve: { pct: 12.5, min: 10, max: 15, menu: 'fit' }, + }, + florent: { topSide: 0.8, brim: 0, headEase: { pct: 2, min: 0, max: 5, menu: 'fit' } }, + hi: { + length: 1000, + size: { pct: 100, min: 5, max: 500, menu: 'style' }, + nosePointiness: { pct: 0, min: -5, max: 10, menu: 'style' }, + aggressive: { bool: false, menu: 'style' }, + hungry: { pct: 50, min: 0, max: 100, menu: 'style' }, + }, + holmes: { + headEase: { + pct: 3, + min: 0, + max: 9, + snap: { + metric: [6, 13, 19, 25, 32, 38, 44, 50], + imperial: [6.35, 12.7, 19.05, 25.4, 31.75, 38.1, 44.45, 50.8], + }, + menu: 'fit', + }, + lengthRatio: { pct: 55, min: 40, max: 60, menu: 'style' }, + gores: { count: 6, min: 4, max: 20, menu: 'style' }, + visorAngle: { deg: 45, min: 10, max: 90, menu: 'style' }, + visorWidth: { pct: 5, min: 1, max: 17, snap: 5, menu: 'style' }, + visorLength: { pct: 100, min: 80, max: 150, menu: 'advanced' }, + earLength: { pct: 100, min: 80, max: 150, menu: 'style' }, + earWidth: { pct: 100, min: 80, max: 150, menu: 'style' }, + buttonhole: { bool: false, menu: 'style' }, + }, + hortensia: { + width: 230, + height: 330, + size: { pct: 50, min: 20, max: 200, menu: 'style' }, + zipperSize: { + dflt: '#5', + list: ['#3', '#4', '#4.5', '#5', '#6', '#8', '#10', 'invisible'], + menu: 'style', + }, + minHandleSpaceWidth: 80, + maxHandleSpaceWidth: 250, + pctHandleSpace: 50, + pctHandleVert: 42, + handleWidth: { pct: 8.6, min: 4, max: 25, menu: 'style' }, + strapLength: { pct: 160, min: 75, max: 250, menu: 'style' }, + }, + huey: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 5, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 0, min: -4, max: 60, menu: 'style' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + ribbing: { bool: true, menu: 'style' }, + ribbingHeight: { pct: 10, min: 5, max: 15, menu: 'style' }, + hipsEase: { pct: 8, min: 4, max: 12, menu: 'fit' }, + pocket: { bool: true, menu: 'style' }, + pocketHeight: { pct: 30, min: 25, max: 35, menu: 'style' }, + pocketWidth: { pct: 60, min: 50, max: 70, menu: 'style' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + sleeveLengthBonus: { pct: 0, min: -40, max: 10, menu: 'style' }, + hoodHeight: { pct: 59, min: 55, max: 65, menu: 'style' }, + hoodCutback: { pct: 10, min: 5, max: 15, menu: 'style' }, + hoodClosure: { pct: 13.5, min: 10, max: 15, menu: 'style' }, + hoodDepth: { pct: 8.5, min: 5, max: 12, menu: 'style' }, + hoodAngle: { deg: 5, min: 2, max: 8, menu: 'style' }, + ribbingStretch: { pct: 15, min: 0, max: 30, menu: 'fit' }, + }, + hugo: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 8, min: 4, max: 20, menu: 'fit' }, + collarEase: 0.05, + cuffEase: { pct: 20, min: 10, max: 50, menu: 'fit' }, + draftForHighBust: { bool: false, menu: 'fit' }, + shoulderEase: 0, + lengthBonus: { pct: 10, min: 0, max: 20, menu: 'style' }, + s3Collar: 0, + s3Armhole: 0, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: 0.5, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: 0, + shoulderSlopeReduction: 0, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + hipsEase: { pct: 12, min: 4, max: 20, menu: 'fit' }, + ribbingHeight: { pct: 10, min: 4, max: 20, menu: 'style' }, + pocketWidth: { pct: 50, min: 35, max: 65, menu: 'style' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + sleeveLengthBonus: { pct: 2, min: 0, max: 10, menu: 'style' }, + ribbingStretch: { pct: 5, min: 0, max: 10, menu: 'fit' }, + }, + jaeger: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 5, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 19, min: 10, max: 25, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + centerBackDart: { pct: 0.5, min: 0, max: 1.5, menu: 'fit' }, + hipsEase: { pct: 12, min: 8, max: 20, menu: 'fit' }, + waistEase: { pct: 14, min: 8, max: 25, menu: 'fit' }, + rollLineCollarHeight: { pct: 6, min: 5, max: 9, menu: 'collar' }, + reduceWaistStandardFraction: 0.08, + reduceWaistDartFraction: 0.05, + reduceHipsStandardFraction: 0.1, + centerFrontHemDrop: { pct: 2, min: 0, max: 4, menu: 'style' }, + frontPocketPlacement: { pct: 75, min: 65, max: 85, menu: 'pockets' }, + frontPocketWidth: { pct: 68, min: 55, max: 75, menu: 'pockets' }, + frontPocketDepth: { pct: 110, min: 80, max: 130, menu: 'pockets' }, + frontPocketRadius: { pct: 10, min: 0, max: 50, menu: 'pockets' }, + frontDartPlacement: { pct: 55, min: 45, max: 60, menu: 'advanced' }, + sideFrontPlacement: { pct: 85, min: 80, max: 90, menu: 'advanced' }, + frontOverlap: { pct: 1.5, min: 1, max: 2, menu: 'advanced' }, + innerPocketPlacement: { pct: 52, min: 42, max: 62, menu: 'pockets' }, + innerPocketWidth: { pct: 50, min: 45, max: 65, menu: 'pockets' }, + innerPocketDepth: { pct: 110, min: 75, max: 140, menu: 'pockets' }, + innerPocketWeltHeight: { pct: 3.5, min: 2.5, max: 5, menu: 'pockets' }, + frontCutawayAngle: { deg: 2.5, min: 1, max: 4, menu: 'style' }, + frontCutawayStart: { pct: 30, min: 10, max: 70, menu: 'style' }, + frontCutawayEnd: { pct: 40, min: 10, max: 40, menu: 'style' }, + hemRadius: { pct: 100, min: 35, max: 100, menu: 'style' }, + chestPocketDepth: { pct: 110, min: 70, max: 150, menu: 'pockets' }, + chestPocketWidth: { pct: 37, min: 30, max: 45, menu: 'pockets' }, + chestPocketPlacement: { pct: 52, min: 40, max: 60, menu: 'pockets' }, + chestPocketAngle: { deg: 2.5, min: 0, max: 7, menu: 'pockets' }, + chestPocketWeltSize: { pct: 17.5, min: 10, max: 25, menu: 'pockets' }, + lapelStart: { pct: 10, min: 0, max: 35, menu: 'style' }, + collarHeight: { pct: 9, min: 7, max: 10, menu: 'collar' }, + collarNotchDepth: { pct: 15, min: 15, max: 50, menu: 'collar' }, + collarNotchAngle: { deg: 45, min: 30, max: 60, menu: 'collar' }, + collarNotchReturn: { pct: 100, min: 50, max: 100, menu: 'collar' }, + chestShaping: { pct: 30, min: 0, max: 100, menu: 'advanced' }, + buttons: { list: ['1', '2', '3'], dflt: '2', menu: 'style' }, + buttonLength: { pct: 30, min: 30, max: 60, menu: 'style' }, + chestShapingMax: 5, + lapelReduction: { pct: 5, min: 0, max: 10, menu: 'style' }, + backVent: { count: 1, min: 0, max: 2, menu: 'style' }, + backVentLength: { pct: 35, min: 15, max: 100, menu: 'style' }, + collarSpread: { deg: 13, min: 5, max: 35, menu: 'collar' }, + collarRoll: { pct: 5, min: 0, max: 10, menu: 'collar' }, + pocketFoldover: { pct: 25, min: 15, max: 35, menu: 'pockets' }, + sleeveLengthBonus: { pct: 0, min: -20, max: 15, menu: 'fit' }, + sleeveBend: { deg: 10, min: 0, max: 20, menu: 'fit' }, + sleevecapHeight: { pct: 45, min: 40, max: 60, menu: 'advanced' }, + sleevecapEase: { pct: 1, min: 0, max: 10, menu: 'advanced' }, + sleeveVentLength: { pct: 35, min: 25, max: 55, menu: 'sleeves' }, + sleeveVentWidth: { pct: 18, min: 10, max: 26, menu: 'sleeves' }, + }, + legend: {}, + lucy: { + width: { pct: 50, min: 30, max: 100, menu: 'style' }, + length: { pct: 50, min: 30, max: 100, menu: 'style' }, + edge: { pct: 25, min: 20, max: 50, menu: 'style' }, + }, + lunetius: { + lengthRatio: { pct: 105, min: 60, max: 130, menu: 'style' }, + widthRatio: { pct: 100, min: 50, max: 130, menu: 'style' }, + length: { + list: ['toKnee', 'toBelowKnee', 'toHips', 'toUpperLeg', 'toFloor'], + dflt: 'toBelowKnee', + menu: 'style', + }, + }, + magde: { + size: { pct: 100, min: 15, max: 200, menu: 'style' }, + taperRatio: { pct: 60, min: 50, max: 100, menu: 'style' }, + flapHeightRatio: { pct: 83, min: 60, max: 100, menu: 'style' }, + openingRatio: { pct: 66, min: 30, max: 90, menu: 'style' }, + onePieceLid: { bool: false, menu: 'style' }, + useCommonWebbingSizes: { bool: true, menu: 'style' }, + }, + noble: { + acrossBackFactor: 0.925, + shoulderSlopeBack: 1.23, + neckWidthBack: 0.197, + neckWidthFront: 0.17, + backDartLocation: 0.145, + backCenterWaistReduction: 0.35, + collarFactor: 0.19, + bustSpanEase: { pct: 0, min: -5, max: 20, menu: 'fit' }, + chestEase: { pct: 11, min: 5, max: 20, menu: 'fit' }, + fullChestEaseReduction: { pct: 4, min: 0, max: 8, menu: 'fit' }, + shoulderToShoulderEase: { pct: -0.5, min: -1, max: 5, menu: 'fit' }, + waistEase: { pct: 5, min: 1, max: 20, menu: 'fit' }, + backDartHeight: { pct: 46, min: 38, max: 54, menu: 'darts' }, + bustDartCurve: 1, + bustDartLength: 0.9, + waistDartLength: { pct: 90, min: 75, max: 95, menu: 'darts' }, + armholeDepth: { pct: 44, min: 38, max: 46, menu: 'armhole' }, + backArmholeCurvature: { pct: 63, min: 50, max: 85, menu: 'armhole' }, + backArmholePitchDepth: { pct: 35, max: 40, min: 30, menu: 'armhole' }, + backArmholeSlant: { deg: 5, min: 1, max: 9, menu: 'armhole' }, + frontArmholeCurvature: { pct: 63, min: 50, max: 85, menu: 'armhole' }, + frontArmholePitchDepth: { pct: 29, max: 31, min: 27, menu: 'armhole' }, + backHemSlope: { deg: 2.5, min: 0, max: 5, menu: 'advanced' }, + backNeckCutout: { pct: 6, min: 3, max: 9, menu: 'advanced' }, + frontShoulderWidth: { pct: 95, max: 98, min: 92, menu: 'advanced' }, + highBustWidth: { pct: 86, max: 92, min: 80, menu: 'advanced' }, + armholeDartPosition: { pct: 50, min: 10, max: 90 }, + dartPosition: { dflt: 'shoulder', list: ['shoulder', 'armhole'], menu: 'darts' }, + shoulderDartPosition: { pct: 50, min: 10, max: 90 }, + shoulderToShoulderCorrection: 0.995, + upperDartLength: { pct: 90, min: 80, max: 95, menu: 'darts' }, + }, + octoplushy: { + sizeConstant: 200, + size: { pct: 100, min: 5, max: 500, menu: 'style' }, + type: { dflt: 'octoplushy', list: ['octoplushy', 'octopus', 'squid'], menu: 'style' }, + armWidth: { pct: 15, min: 10, max: 30, menu: 'style' }, + armLength: { pct: 200, min: 100, max: 500, menu: 'style' }, + neckWidth: { pct: 25, min: 25, max: 45, menu: 'style' }, + armTaper: { pct: 25, min: 0, max: 50, menu: 'style' }, + bottomTopArmRatio: { pct: 57, min: 25, max: 75, menu: 'style' }, + bottomArmReduction: { pct: 90, min: 75, max: 125 }, + bottomArmReductionPlushy: { pct: 80, min: 75, max: 125 }, + }, + paco: { + fitCrossSeam: true, + fitCrossSeamFront: true, + fitCrossSeamBack: true, + fitGuides: false, + waistEase: { pct: 2, min: 0, max: 10, menu: 'fit' }, + seatEase: { pct: 5, min: 0, max: 15, menu: 'fit' }, + kneeEase: 0.06, + waistHeight: { pct: 5, min: 0, max: 100, menu: 'style' }, + lengthBonus: { pct: 0, min: -15, max: 10, menu: 'style' }, + crotchDrop: { pct: 2, min: 0, max: 10, menu: 'style' }, + fitKnee: false, + legBalance: { pct: 57.5, min: 52.5, max: 62.5, menu: 'advanced' }, + crossSeamCurveStart: { pct: 85, min: 60, max: 100, menu: 'advanced' }, + crossSeamCurveBend: { pct: 65, min: 45, max: 85, menu: 'advanced' }, + crossSeamCurveAngle: { deg: 12, min: 0, max: 20, menu: 'advanced' }, + crotchSeamCurveStart: { pct: 80, min: 60, max: 95, menu: 'advanced' }, + crotchSeamCurveBend: { pct: 80, min: 45, max: 100, menu: 'advanced' }, + crotchSeamCurveAngle: { deg: 25, min: 0, max: 35, menu: 'advanced' }, + waistBalance: { pct: 60, min: 30, max: 90, menu: 'advanced' }, + grainlinePosition: { pct: 45, min: 30, max: 60, menu: 'advanced' }, + waistbandWidth: { + pct: 3, + min: 1, + max: 6, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'elastic', + }, + titanPaperless: false, + frontPocketHeelRatio: 0.4, + backPocketWaistRatio: 0.4, + backPocketHeightRatio: 0.4, + backPocketWidthRatio: 0.37, + waistbandHeight: 0, + elasticatedCuff: { bool: true, menu: 'style' }, + ankleElastic: { + pct: 5, + min: 1, + max: 13, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'elastic', + }, + heelEase: { pct: 5, min: 0, max: 50, menu: 'elastic' }, + frontPockets: { bool: true, menu: 'pockets' }, + backPockets: { bool: false, menu: 'pockets' }, + frontPocketFlapSize: { + pct: 3, + min: 3, + max: 3, + snap: { metric: 1, imperial: 0.79375 }, + menu: false, + }, + weltFactor: 0.15, + }, + penelope: { + dartMaximumDifference: 0.344, + dartMinimumDifference: 0.2, + dartMinimumWidth: 0.006888, + dartSideMinimum: 10, + dartBackControl1: 0.114, + dartBackControl2: 5, + dartBackControl3: 4, + curvePlacement: 2.4, + dart2offset: 32, + dart2factor: 0.8, + hipCurveDividerDown: 40, + hipCurveDividerUp: 3, + sideSeamShiftPercentage: 0.006, + backVentWidth: 0.1, + paperlessOffset: 15, + curvedDartControlAngle: 2, + curvedDartTopControlOffset: 0.2, + curvedDartBottomControlOffset: 0.4, + curvedDarts: { bool: true, menu: 'style' }, + lengthBonus: { pct: 0, min: -50, max: 50, menu: 'style' }, + hemBonus: { pct: 0, min: -35, max: 0, menu: 'style' }, + hem: { pct: 2, min: 0, max: 5, menu: 'style' }, + backVent: { bool: true, menu: 'style' }, + backVentLength: { pct: 40, min: 5, max: 70 }, + zipperLocation: { dflt: 'backSeam', list: ['backSeam', 'sideSeam'], menu: 'style' }, + nrOfDarts: { count: 2, min: 1, max: 2, menu: 'style' }, + seatEase: { pct: 1, min: 0, max: 8, menu: 'fit' }, + waistEase: { pct: 1, min: 0, max: 8, menu: 'fit' }, + backDartDepthFactor: { pct: 50, min: 35, max: 70, menu: 'advanced' }, + frontDartDepthFactor: { pct: 45, min: 30, max: 65, menu: 'advanced' }, + dartToSideSeamFactor: { pct: 50, min: 30, max: 70, menu: 'advanced' }, + waistband: { bool: true, menu: 'style' }, + waistbandWidth: { pct: 10, min: 5, max: 20 }, + waistbandOverlap: { pct: 3.5, min: 0, max: 10 }, + }, + plugintest: { + plugin: { + dflt: 'all', + list: [ + 'all', + 'banner', + 'bartack', + 'buttons', + 'cutonfold', + 'dimension', + 'flip', + 'gore', + 'grainline', + 'i18n', + 'logo', + 'measurements', + 'mirror', + 'notches', + 'round', + 'scalebox', + 'sprinkle', + 'title', + 'versionfreeSvg', + ], + menu: 'tests', + }, + bannerDy: { count: -1, min: -15, max: 15, menu: 'annotations.banner' }, + bannerSpaces: { count: 10, min: 0, max: 20, menu: 'annotations.banner' }, + bannerRepeat: { count: 10, min: 1, max: 20, menu: 'annotations.banner' }, + bartackLength: { count: 15, min: 2, max: 100, menu: 'annotations.bartack' }, + bartackAngle: { count: 0, min: -360, max: 360, menu: 'annotations.bartack' }, + bartackDensity: { count: 3, min: 1, max: 5, menu: 'annotations.bartack' }, + bartackWidth: { count: 3, min: 1, max: 5, menu: 'annotations.bartack' }, + bartackStart: { pct: 25, min: 0, max: 100, menu: 'annotations.bartack' }, + bartackEnd: { pct: 75, min: 0, max: 100, menu: 'annotations.bartack' }, + crossboxText: { bool: true, menu: 'annotations.crossboxText' }, + cutonfoldMargin: { pct: 5, min: 0, max: 25, menu: 'annotations.cutonfold' }, + cutonfoldOffset: { count: 15, min: 0, max: 100, menu: 'annotations.cutonfold' }, + cutonfoldGrainline: { bool: false, menu: 'annotations.cutonfold' }, + dimensionsCustomText: { bool: false, menu: 'annotations.dimensions' }, + dimensionsEndMarker: { bool: true, menu: 'annotations.dimensions' }, + dimensionsStartMarker: { bool: true, menu: 'annotations.dimensions' }, + logoScale: { pct: 100, min: 10, max: 200, menu: 'annotations.logo' }, + logoRotate: { deg: 0, min: -360, max: 360, menu: 'annotations.logo' }, + pleatMargin: { count: 35, min: 0, max: 50, menu: 'annotations.pleat' }, + pleatReverse: { bool: false, menu: 'annotations.pleat' }, + scaleboxRotation: { deg: 0, min: 0, max: 360, menu: 'annotations.scalebox' }, + scaleboxText: { + dflt: 'default', + list: ['default', 'custom', 'suppress'], + menu: 'annotations.scalebox', + }, + sewtogetherHinge: { bool: true, menu: 'annotations.sewtogether' }, + sewtogetherMiddle: { bool: false, menu: 'annotations.sewtogether' }, + titleNr: { count: 1, min: 0, max: 100, menu: 'annotations.title' }, + titleTitle: { bool: true, menu: 'annotations.title' }, + titleMeta: { bool: true, menu: 'annotations.title' }, + titleScale: { pct: 100, min: 10, max: 200, menu: 'annotations.title' }, + titleRotate: { deg: 0, min: -360, max: 360, menu: 'annotations.title' }, + snippetScale: { pct: 100, min: 10, max: 200, menu: 'annotations.snippets' }, + snippetRotation: { deg: 0, min: -360, max: 360, menu: 'annotations.snippets' }, + flipAxis: { dflt: 'x', list: ['x', 'y'], menu: 'flip' }, + goreRadius: { count: 20, min: 10, max: 30, menu: 'gore' }, + goreGoreNumber: { count: 6, min: 4, max: 8, menu: 'gore' }, + goreExtraLength: { count: 10, min: 0, max: 20, menu: 'gore' }, + mirrorLine: { dflt: 'a', list: ['a', 'b', 'none'], menu: 'mirror' }, + mirrorClone: { bool: true, menu: 'mirror' }, + roundRadius: { count: 10, min: 0, max: 50, menu: 'round' }, + roundHide: { bool: false, menu: 'round' }, + sprinkleScale: { pct: 100, min: 10, max: 200, menu: 'sprinkle' }, + sprinkleRotate: { deg: 0, min: -360, max: 360, menu: 'sprinkle' }, + sprinkleSnippet: { + dflt: 'bnotch', + list: [ + 'notch', + 'bnotch', + 'button', + 'buttonhole', + 'buttonhole-start', + 'buttonhole-end', + 'snap-stud', + 'snap-socket', + 'logo', + ], + menu: 'sprinkle', + }, + }, + rendertest: { + width: { mm: 200, min: 50, max: 500, testIgnore: false }, + only: { + menu: 'show', + dflt: 'false', + list: [ + 'false', + 'circles', + 'colors', + 'widths', + 'styles', + 'combos', + 'text', + 'snippets', + 'macros', + ], + }, + }, + sandy: { + minimumOverlap: 15, + seamlessFullCircle: { bool: false, menu: 'construction' }, + waistbandWidth: { + pct: 4, + min: 1, + max: 8, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'style', + }, + waistbandPosition: { pct: 50, min: 0, max: 100, menu: 'fit' }, + lengthBonus: { pct: 50, min: 10, max: 100, menu: 'style' }, + circleRatio: { pct: 50, min: 20, max: 100, menu: 'style' }, + waistbandOverlap: { pct: 3, min: 0, max: 15, menu: 'style' }, + gathering: { pct: 0, min: 0, max: 200, menu: 'style' }, + hemWidth: { pct: 2, min: 1, max: 10, menu: 'construction' }, + waistbandShape: { list: ['straight', 'curved'], dflt: 'straight', menu: 'fit' }, + }, + shin: { + frontFactor: 0.58, + legFrontFactor: 0.48, + gussetFactor: 0.0714, + angle: 10, + elasticWidth: { + pct: 10, + min: 4, + max: 20, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'style', + }, + stretch: { pct: 20, min: 10, max: 30, menu: 'fit' }, + bulge: { pct: 2.5, min: 0, max: 5, menu: 'fit' }, + legReduction: { pct: 5, min: 0, max: 10, menu: 'fit' }, + rise: { pct: 0, min: 0, max: 25, menu: 'style' }, + backRise: { pct: 5, min: 0, max: 10, menu: 'fit' }, + }, + simon: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 5, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 2, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 20, min: 10, max: 40, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 2, min: 0, max: 15, menu: 'fit' }, + lengthBonus: { pct: 25, min: -4, max: 60, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + backDarts: { list: ['auto', 'never', 'always'], dflt: 'auto', menu: 'style' }, + backDartShaping: { pct: 25, min: 5, max: 75, menu: 'advanced' }, + boxPleat: { bool: false, menu: 'style' }, + boxPleatFold: { pct: 15, min: 10, max: 20, menu: 'advanced' }, + boxPleatWidth: { pct: 7, min: 4, max: 10, menu: 'advanced' }, + roundBack: { pct: 0, min: 0, max: 10, menu: 'fit' }, + buttonholePlacketWidth: { pct: 8, min: 4, max: 12, menu: 'style.closure' }, + buttonholePlacketFoldWidth: { pct: 16, min: 8, max: 24, menu: 'style.closure' }, + buttonPlacketWidth: { pct: 5, min: 2, max: 8, menu: 'style.closure' }, + hemCurve: { pct: 50, min: 25, max: 100, menu: 'style' }, + hemStyle: { list: ['straight', 'baseball', 'slashed'], dflt: 'straight', menu: 'style' }, + hipsEase: { pct: 15, min: 10, max: 35, menu: 'fit' }, + yokeHeight: { pct: 70, min: 40, max: 90, menu: 'style' }, + sleevePlacketWidth: { pct: 13, min: 8, max: 18, menu: 'style.cuffs' }, + waistEase: { pct: 15, min: 10, max: 35, menu: 'fit' }, + buttonFreeLength: { pct: 2, min: 0, max: 15, menu: 'style.closure' }, + extraTopButton: { bool: true, menu: 'style.closure' }, + seperateButtonPlacket: { bool: false, menu: 'style.closure' }, + seperateButtonholePlacket: { bool: false, menu: 'style.closure' }, + buttons: { count: 7, min: 4, max: 12, menu: 'style.closure' }, + ffsa: { pct: 150, min: 100, max: 200, menu: 'advanced' }, + collarAngle: { deg: 85, min: 60, max: 130, menu: 'style.collar' }, + collarBend: { pct: 3.5, min: 0, max: 10, menu: 'style.collar' }, + collarFlare: { deg: 3.5, min: 0, max: 10, menu: 'style.collar' }, + collarGap: { pct: 2.5, min: 0, max: 6, menu: 'style.collar' }, + collarRoll: { pct: 3, min: 0, max: 6, menu: 'style.collar' }, + collarStandBend: { deg: 3, min: 0, max: 5, menu: 'style.collar' }, + collarStandCurve: { deg: 2, min: 0, max: 5, menu: 'style.collar' }, + collarStandWidth: { pct: 8, min: 3, max: 13, menu: 'style.collar' }, + cuffOverlap: 0.15, + barrelCuffNarrowButton: { bool: true, menu: 'style.cuffs' }, + cuffButtonRows: { count: 1, min: 1, max: 2, menu: 'style.cuffs' }, + cuffDrape: { pct: 5, min: 0, max: 10, menu: 'style.cuffs' }, + cuffLength: { pct: 10, min: 3, max: 15, menu: 'style.cuffs' }, + cuffStyle: { + list: [ + 'roundedBarrelCuff', + 'angledBarrelCuff', + 'straightBarrelCuff', + 'roundedFrenchCuff', + 'angledFrenchCuff', + 'straightFrenchCuff', + ], + dflt: 'angledBarrelCuff', + menu: 'style.cuffs', + }, + buttonPlacketStyle: { list: ['classic', 'seamless'], dflt: 'classic' }, + buttonholePlacketStyle: { list: ['classic', 'seamless'], dflt: 'seamless' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + sleeveLengthBonus: { pct: 3.5, min: -40, max: 10, menu: 'fit' }, + sleevePlacketLength: { pct: 25, min: 15, max: 35, menu: 'style.cuffs' }, + splitYoke: { bool: false, menu: 'style' }, + }, + simone: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 5, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 2, min: 0, max: 10, menu: 'fit' }, + cuffEase: { pct: 20, min: 10, max: 40, menu: 'fit' }, + draftForHighBust: true, + shoulderEase: { pct: 2, min: 0, max: 15, menu: 'fit' }, + lengthBonus: { pct: 25, min: -4, max: 60, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + backDarts: { list: ['auto', 'never', 'always'], dflt: 'auto', menu: 'style' }, + backDartShaping: { pct: 25, min: 5, max: 75, menu: 'advanced' }, + boxPleat: { bool: false, menu: 'style' }, + boxPleatFold: { pct: 15, min: 10, max: 20, menu: 'advanced' }, + boxPleatWidth: { pct: 7, min: 4, max: 10, menu: 'advanced' }, + roundBack: { pct: 0, min: 0, max: 10, menu: 'fit' }, + buttonholePlacketWidth: { pct: 8, min: 4, max: 12, menu: 'style.closure' }, + buttonholePlacketFoldWidth: { pct: 16, min: 8, max: 24, menu: 'style.closure' }, + buttonPlacketWidth: { pct: 5, min: 2, max: 8, menu: 'style.closure' }, + hemCurve: { pct: 50, min: 25, max: 100, menu: 'style' }, + hemStyle: { list: ['straight', 'baseball', 'slashed'], dflt: 'straight', menu: 'style' }, + hipsEase: { pct: 15, min: 10, max: 35, menu: 'fit' }, + yokeHeight: { pct: 70, min: 40, max: 90, menu: 'style' }, + sleevePlacketWidth: { pct: 13, min: 8, max: 18, menu: 'style.cuffs' }, + waistEase: { pct: 15, min: 10, max: 35, menu: 'fit' }, + buttonFreeLength: { pct: 2, min: 0, max: 15, menu: 'style.closure' }, + extraTopButton: { bool: true, menu: 'style.closure' }, + seperateButtonPlacket: { bool: false, menu: 'style.closure' }, + seperateButtonholePlacket: { bool: false, menu: 'style.closure' }, + buttons: { count: 7, min: 4, max: 12, menu: 'style.closure' }, + ffsa: { pct: 150, min: 100, max: 200, menu: 'advanced' }, + minimalDartShaping: 5, + bustDartAngle: { deg: 10, min: 0, max: 20, menu: 'advanced' }, + bustDartLength: { pct: 80, min: 50, max: 90, menu: 'advanced' }, + frontDarts: { bool: false, menu: 'advanced' }, + frontDartLength: { pct: 45, min: 30, max: 60, menu: 'advanced' }, + contour: { pct: 50, min: 30, max: 75, menu: 'style' }, + bustAlignedButtons: { + dflt: 'disabled', + list: ['even', 'split', 'disabled'], + menu: 'style.closure', + }, + collarAngle: { deg: 85, min: 60, max: 130, menu: 'style.collar' }, + collarBend: { pct: 3.5, min: 0, max: 10, menu: 'style.collar' }, + collarFlare: { deg: 3.5, min: 0, max: 10, menu: 'style.collar' }, + collarGap: { pct: 2.5, min: 0, max: 6, menu: 'style.collar' }, + collarRoll: { pct: 3, min: 0, max: 6, menu: 'style.collar' }, + collarStandBend: { deg: 3, min: 0, max: 5, menu: 'style.collar' }, + collarStandCurve: { deg: 2, min: 0, max: 5, menu: 'style.collar' }, + collarStandWidth: { pct: 8, min: 3, max: 13, menu: 'style.collar' }, + cuffOverlap: 0.15, + barrelCuffNarrowButton: { bool: true, menu: 'style.cuffs' }, + cuffButtonRows: { count: 1, min: 1, max: 2, menu: 'style.cuffs' }, + cuffDrape: { pct: 5, min: 0, max: 10, menu: 'style.cuffs' }, + cuffLength: { pct: 10, min: 3, max: 15, menu: 'style.cuffs' }, + cuffStyle: { + list: [ + 'roundedBarrelCuff', + 'angledBarrelCuff', + 'straightBarrelCuff', + 'roundedFrenchCuff', + 'angledFrenchCuff', + 'straightFrenchCuff', + ], + dflt: 'angledBarrelCuff', + menu: 'style.cuffs', + }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + sleeveLengthBonus: { pct: 3.5, min: -40, max: 10, menu: 'fit' }, + sleevePlacketLength: { pct: 25, min: 15, max: 35, menu: 'style.cuffs' }, + splitYoke: { bool: false, menu: 'style' }, + buttonPlacketStyle: { list: ['classic', 'seamless'], dflt: 'classic' }, + buttonholePlacketStyle: { list: ['classic', 'seamless'], dflt: 'seamless' }, + }, + sven: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 10, min: 5, max: 30, menu: 'fit' }, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 15, min: 0, max: 30, menu: 'style' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + waistEase: 0.08, + sleeveLengthBonus: { pct: 3, min: 0, max: 10, menu: 'style' }, + ribbingHeight: { pct: 8, min: 3, max: 15, menu: 'style' }, + hipsEase: { pct: 8, min: -4, max: 20, menu: 'fit' }, + ribbing: { bool: true, menu: 'style' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + ribbingStretch: { pct: 15, min: 0, max: 30, menu: 'fit' }, + }, + tamiko: { + armholeDepthFactor: { pct: 50, min: 40, max: 60, menu: 'fit' }, + chestEase: { pct: 2, min: 1, max: 20, menu: 'fit' }, + flare: { deg: 15, min: -10, max: 30, menu: 'style' }, + lengthBonus: { pct: 13, min: 0, max: 60, menu: 'style' }, + shoulderseamLength: { pct: 10, min: 5, max: 25, menu: 'style' }, + draftForHighBust: { bool: false, menu: 'fit' }, + }, + teagan: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: 0.05, + chestEase: { pct: 12, min: 5, max: 25, menu: 'fit' }, + collarEase: 0, + cuffEase: { pct: 20, min: 0, max: 200, menu: 'fit' }, + draftForHighBust: { bool: false, menu: 'fit' }, + shoulderEase: 0, + lengthBonus: { pct: 5, min: -20, max: 60, menu: 'style' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 8, min: 4, max: 12, menu: 'fit' }, + frontArmholeDeeper: 0.005, + shoulderSlopeReduction: 0, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + sleeveWidthGuarantee: 0.85, + sleeveLength: { pct: 30, min: 20, max: 100, menu: 'fit' }, + curveToWaist: { bool: false, menu: 'fit' }, + curvedWaistEase: { pct: 25, min: 8, max: 40, menu: 'fit' }, + hipsEase: { pct: 18, min: 8, max: 30, menu: 'fit' }, + necklineDepth: { pct: 25, min: 20, max: 40, menu: 'style' }, + necklineWidth: { pct: 30, min: 10, max: 50, menu: 'style' }, + necklineBend: { pct: 30, min: 0, max: 70, menu: 'style' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveEase: { pct: 15, min: 5, max: 35, menu: 'style' }, + }, + tiberius: { + headRatio: { pct: 100, min: 80, max: 120, menu: 'fit' }, + armholeDrop: { pct: 110, min: 100, max: 150, menu: 'fit' }, + lengthBonus: { pct: 90, min: 60, max: 130, menu: 'style' }, + widthBonus: { pct: 100, min: 50, max: 130, menu: 'style' }, + clavi: { bool: false, menu: 'style.clavi' }, + clavusLocation: { pct: 65, min: 50, max: 80, menu: 'style.clavi' }, + clavusWidth: { pct: 100, min: 50, max: 150, menu: 'style.clavi' }, + length: { list: ['toKnee', 'toMidLeg', 'toFloor'], dflt: 'toKnee', menu: 'style' }, + width: { list: ['toElbow', 'toShoulder', 'toMidArm'], dflt: 'toMidArm', menu: 'style' }, + forceWidth: { bool: false, menu: 'advanced' }, + }, + titan: { + fitCrossSeam: true, + fitCrossSeamFront: true, + fitCrossSeamBack: true, + fitGuides: true, + waistEase: { pct: 2, min: 0, max: 10, menu: 'fit' }, + seatEase: { pct: 2, min: 0, max: 10, menu: 'fit' }, + kneeEase: { pct: 6, min: 1, max: 25, menu: 'fit' }, + waistHeight: { pct: 100, min: 0, max: 100, menu: 'style' }, + lengthBonus: { pct: 2, min: -20, max: 10, menu: 'style' }, + crotchDrop: { pct: 2, min: 0, max: 15, menu: 'style' }, + fitKnee: { bool: false, menu: 'style' }, + legBalance: { pct: 57.5, min: 52.5, max: 62.5, menu: 'advanced' }, + crossSeamCurveStart: { pct: 85, min: 60, max: 100, menu: 'advanced' }, + crossSeamCurveBend: { pct: 65, min: 45, max: 85, menu: 'advanced' }, + crossSeamCurveAngle: { deg: 12, min: 0, max: 20, menu: 'advanced' }, + crotchSeamCurveStart: { pct: 80, min: 60, max: 95, menu: 'advanced' }, + crotchSeamCurveBend: { pct: 80, min: 45, max: 100, menu: 'advanced' }, + crotchSeamCurveAngle: { deg: 25, min: 0, max: 35, menu: 'advanced' }, + waistBalance: { pct: 60, min: 30, max: 90, menu: 'advanced' }, + grainlinePosition: { pct: 45, min: 30, max: 60, menu: 'advanced' }, + waistbandWidth: { + pct: 3, + min: 1, + max: 6, + snap: { + metric: [3.5, 5, 10, 12, 20, 25, 30, 40, 50, 60, 80, 100, 120], + imperial: [ + 3.175, 6.35, 9.524999999999999, 12.7, 15.875, 19.049999999999997, 25.4, 31.75, + 38.099999999999994, 44.449999999999996, 50.8, 76.19999999999999, 101.6, 127, + ], + }, + menu: 'advanced', + }, + }, + trayvon: { + tipWidth: { pct: 15, min: 5, max: 35, snap: { metric: 1, imperial: 0.79375 }, menu: 'style' }, + knotWidth: { pct: 8, min: 4, max: 12, snap: { metric: 1, imperial: 0.79375 }, menu: 'style' }, + lengthBonus: { pct: 0, min: -50, max: 50, menu: 'style' }, + }, + uma: { + xStretch: { pct: 15, min: 0, max: 50, menu: 'fit' }, + yStretch: { pct: 15, min: 0, max: 50, menu: 'fit' }, + gussetWidth: { pct: 15, min: 5, max: 24, menu: 'fit' }, + gussetLength: { pct: 12.7, min: 10, max: 16, menu: 'fit' }, + gussetPosition: { pct: 70, min: 5, max: 95, menu: 'fit' }, + bulge: { deg: 0, min: 0, max: 30, menu: 'fit' }, + rise: { pct: 46, min: 30, max: 100, menu: 'style' }, + legRise: { pct: 54, min: 5, max: 95, menu: 'style' }, + frontDip: { pct: 5, min: -5, max: 15, menu: 'style' }, + frontExposure: { pct: 70, min: 5, max: 100, menu: 'style' }, + backDip: { pct: 2.5, min: -5, max: 15, menu: 'style' }, + backExposure: { pct: 30, min: 25, max: 125, menu: 'style' }, + }, + wahid: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: false }, + chestEase: { pct: 2, min: 1, max: 10, menu: 'fit' }, + collarEase: { pct: 5, min: 0, max: 10, menu: false }, + cuffEase: { pct: 20, min: 0, max: 200, menu: false }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: false }, + lengthBonus: { pct: 1, min: 0, max: 8, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: false }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: false }, + acrossBackFactor: 0.97, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 70, min: 60, max: 80, menu: 'fit' }, + backNeckCutout: { pct: 5, min: -2, max: 8, menu: false }, + frontArmholeDeeper: 0.005, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: false }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + frontOverlap: 0.01, + necklineDrop: { pct: 50, min: 35, max: 85, menu: 'style' }, + frontStyle: { dflt: 'classic', list: ['classic', 'rounded'], menu: 'style' }, + frontInset: { pct: 15, min: 10, max: 20, menu: 'advanced' }, + shoulderInset: { pct: 10, min: 0, max: 20, menu: 'advanced' }, + neckInset: { pct: 5, min: 0, max: 10, menu: 'advanced' }, + hemStyle: { dflt: 'classic', list: ['classic', 'rounded', 'square'], menu: 'style' }, + hemRadius: { pct: 6, min: 2, max: 12, menu: 'style' }, + pocketWidth: { pct: 10, max: 15, min: 8, menu: 'style' }, + pocketAngle: { deg: 5, min: 0, max: 5, menu: 'advanced' }, + pocketLocation: { pct: 35, min: 25, max: 55, menu: 'style' }, + frontScyeDart: { deg: 6, min: 0, max: 12, menu: 'fit' }, + buttons: { count: 6, min: 4, max: 12, menu: 'style' }, + waistEase: { pct: 8, min: 2, max: 15, menu: 'fit' }, + hipsEase: { pct: 8, min: 2, max: 15, menu: 'fit' }, + backInset: { pct: 15, min: 10, max: 20, menu: 'advanced' }, + centerBackDart: { pct: 2, min: 0, max: 5, menu: 'fit' }, + backScyeDart: { deg: 2, min: 0, max: 6, menu: 'fit' }, + weltHeight: { pct: 12.5, max: 20, min: 10, menu: 'style' }, + }, + walburga: { + headRatio: { pct: 100, min: 80, max: 120, menu: 'fit' }, + lengthBonus: { pct: 85, min: 60, max: 130, menu: 'style' }, + widthBonus: { pct: 95, min: 50, max: 130, menu: 'style' }, + length: { list: ['toKnee', 'toMidLeg', 'toFloor'], dflt: 'toKnee', menu: 'style' }, + neckline: { bool: true, menu: 'style' }, + neckoRatio: { pct: 100, min: 10, max: 190, menu: 'style' }, + }, + waralee: { + backPocket: { bool: true, menu: 'style' }, + backPocketDepth: 140, + backPocketHorizontalOffset: 0.045, + backPocketSize: 0.45, + backPocketVerticalOffset: 0.2, + backRaise: { pct: 10, min: 0, max: 25, menu: 'fit' }, + backWaistAdjustment: 0.3, + crotchBack: { pct: 45, min: 10, max: 70, menu: 'advanced' }, + crotchEase: 1.08, + crotchFactorBackHor: { pct: 90, min: 10, max: 100, menu: 'advanced' }, + crotchFactorBackVer: { pct: 60, min: 20, max: 90, menu: 'advanced' }, + crotchFactorFrontHor: { pct: 90, min: 10, max: 100, menu: 'advanced' }, + crotchFactorFrontVer: { pct: 30, min: 10, max: 70, menu: 'advanced' }, + crotchFront: { pct: 30, min: 10, max: 70, menu: 'advanced' }, + fitWaist: { bool: true, menu: 'fit' }, + frontPocket: { bool: true, menu: 'style' }, + frontPocketDepthFactor: 1.6, + frontPocketHorizontalOffset: 0.18, + frontPocketSize: 0.45, + frontPocketStyle: { dflt: 'welt', list: ['welt', 'waistband'], menu: 'style' }, + frontPocketVerticalOffset: 0.07, + frontWaistAdjustment: 0.163, + hemWidth: { pct: 1.75, min: 1, max: 2.5, menu: 'style' }, + knotInFront: { bool: true, menu: 'style' }, + legShortening: { pct: 25, min: -10, max: 50, menu: 'style' }, + minimizer: 4, + separateWaistband: { bool: false, menu: 'style' }, + showMini: { bool: true, menu: 'options' }, + waistOverlap: { pct: 50, min: 10, max: 100, menu: 'style' }, + waistRaise: { pct: 0, min: -20, max: 40, menu: 'fit' }, + waistbandWidth: { pct: 3.5, min: 2, max: 5, menu: 'style' }, + }, + yuri: { + brianFitSleeve: true, + brianFitCollar: true, + collarFactor: 4.8, + bicepsEase: { pct: 15, min: 0, max: 50, menu: 'fit' }, + chestEase: { pct: 15, min: -4, max: 35, menu: 'fit' }, + collarEase: { pct: 20, min: 10, max: 30, menu: 'fit' }, + cuffEase: { pct: 30, min: 20, max: 60, menu: 'fit' }, + draftForHighBust: { bool: false }, + shoulderEase: { pct: 0, min: -2, max: 6, menu: 'fit' }, + lengthBonus: { pct: 10, min: 5, max: 15, menu: 'fit' }, + s3Collar: { pct: 0, min: -100, max: 100, menu: 'style' }, + s3Armhole: { pct: 0, min: -100, max: 100, menu: 'style' }, + acrossBackFactor: { pct: 98, min: 93, max: 100, menu: 'advanced' }, + armholeDepth: { pct: 2, min: -10, max: 50 }, + armholeDepthFactor: { pct: 55, min: 50, max: 70 }, + backNeckCutout: { pct: 5, min: 2, max: 8, menu: 'advanced' }, + frontArmholeDeeper: { pct: 0.2, min: 0, max: 0.5, menu: 'advanced' }, + shoulderSlopeReduction: { pct: 0, min: 0, max: 80, menu: 'advanced' }, + legacyArmholeDepth: { bool: false, menu: 'advanced' }, + sleeveLengthBonus: { pct: 1, min: 0, max: 10, menu: 'fit' }, + hipsEase: { pct: 0, min: 0, max: 10, menu: 'fit' }, + sleevecapEase: { pct: 0, min: 0, max: 10, menu: 'advanced.sleevecap' }, + sleevecapTopFactorX: { pct: 50, min: 25, max: 75, menu: 'advanced.sleevecap' }, + sleevecapTopFactorY: { pct: 45, min: 35, max: 125, menu: 'advanced.sleevecap' }, + sleevecapBackFactorX: { pct: 60, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapBackFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorX: { pct: 55, min: 35, max: 65, menu: 'advanced.sleevecap' }, + sleevecapFrontFactorY: { pct: 33, min: 30, max: 65, menu: 'advanced.sleevecap' }, + sleevecapQ1Offset: { pct: 1.7, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ2Offset: { pct: 3.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ3Offset: { pct: 2.5, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ4Offset: { pct: 1, min: 0, max: 7, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ1Spread2: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread1: { pct: 15, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ2Spread2: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread1: { pct: 10, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ3Spread2: { pct: 8, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread1: { pct: 7, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleevecapQ4Spread2: { pct: 6.3, min: 4, max: 20, menu: 'advanced.sleevecap' }, + sleeveWidthGuarantee: { pct: 90, min: 25, max: 100, menu: 'advanced' }, + }, +} diff --git a/sites/shared/prebuild/data/designs.mjs b/sites/shared/prebuild/data/designs.mjs new file mode 100644 index 00000000000..149d4947fd2 --- /dev/null +++ b/sites/shared/prebuild/data/designs.mjs @@ -0,0 +1,54 @@ +// __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 +export const designs = [ + 'aaron', + 'albert', + 'bee', + 'bella', + 'benjamin', + 'bent', + 'bob', + 'breanna', + 'brian', + 'bruce', + 'carlita', + 'carlton', + 'cathrin', + 'charlie', + 'cornelius', + 'diana', + 'examples', + 'florence', + 'florent', + 'hi', + 'holmes', + 'hortensia', + 'huey', + 'hugo', + 'jaeger', + 'legend', + 'lucy', + 'lunetius', + 'magde', + 'noble', + 'octoplushy', + 'paco', + 'penelope', + 'plugintest', + 'rendertest', + 'sandy', + 'shin', + 'simon', + 'simone', + 'sven', + 'tamiko', + 'teagan', + 'tiberius', + 'titan', + 'trayvon', + 'uma', + 'wahid', + 'walburga', + 'waralee', + 'yuri', +] diff --git a/sites/shared/prebuild/designs.mjs b/sites/shared/prebuild/designs.mjs index 9e6d3eec8ea..de338f159ca 100644 --- a/sites/shared/prebuild/designs.mjs +++ b/sites/shared/prebuild/designs.mjs @@ -38,8 +38,9 @@ export const prebuildDesigns = async (store) => { } // Write out prebuild files - const header = - '// This file is auto-generated by the prebuild script | Any changes will be overwritten\n' + const header = `// __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 +` const nl = '\n' const dir = ['..', 'shared', 'prebuild', 'data'] promises.push(fs.mkdir(path.resolve(...dir), { recursive: true }))
+ You can use the data in your account, but this development environment does not come with + account management features. +
Give it a moment
{JSON.stringify(pattern, null, 2)}