@omega.js/web 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +98 -0
- package/README.md +640 -0
- package/bin/omega +2 -0
- package/bin/omega-web +2 -0
- package/bin/omg +2 -0
- package/core/_includes/admin/sections/sidebar.json +100 -0
- package/core/_includes/admin/sections/topbar.json +11 -0
- package/core/_includes/backend/sections/sidebar.json +39 -0
- package/core/_includes/backend/sections/topbar.json +16 -0
- package/core/_includes/core/body.html +102 -0
- package/core/_includes/core/foot.html +536 -0
- package/core/_includes/core/head.html +423 -0
- package/core/_includes/core/pricing/price-per-unit.html +33 -0
- package/core/_includes/core/showcase/entry-body.html +94 -0
- package/core/_includes/core/showcase/index-body.html +43 -0
- package/core/_includes/core/showcase/nav.html +60 -0
- package/core/_includes/frontend/sections/footer.json +74 -0
- package/core/_includes/frontend/sections/nav.json +70 -0
- package/core/_includes/global/sections/account.json +31 -0
- package/core/_includes/modules/engagement/giscus.html +26 -0
- package/core/_layouts/blueprint/404.html +10 -0
- package/core/_layouts/blueprint/about.html +10 -0
- package/core/_layouts/blueprint/account/index.html +11 -0
- package/core/_layouts/blueprint/admin/calendar/index.html +590 -0
- package/core/_layouts/blueprint/admin/dashboard/index.html +301 -0
- package/core/_layouts/blueprint/admin/firebase/index.html +214 -0
- package/core/_layouts/blueprint/admin/posts/editor.html +157 -0
- package/core/_layouts/blueprint/admin/posts/index.html +126 -0
- package/core/_layouts/blueprint/admin/stackblitz/index.html +30 -0
- package/core/_layouts/blueprint/admin/studio/index.html +85 -0
- package/core/_layouts/blueprint/admin/users/index.html +272 -0
- package/core/_layouts/blueprint/admin/users/new.html +82 -0
- package/core/_layouts/blueprint/admin/verts/index.html +204 -0
- package/core/_layouts/blueprint/alternatives/alternative.html +15 -0
- package/core/_layouts/blueprint/alternatives/index.html +10 -0
- package/core/_layouts/blueprint/app.html +10 -0
- package/core/_layouts/blueprint/auth/reset.html +19 -0
- package/core/_layouts/blueprint/auth/signin.html +19 -0
- package/core/_layouts/blueprint/auth/signup.html +19 -0
- package/core/_layouts/blueprint/auth/token.html +19 -0
- package/core/_layouts/blueprint/blog/categories/category.html +8 -0
- package/core/_layouts/blueprint/blog/categories/index.html +11 -0
- package/core/_layouts/blueprint/blog/index.html +10 -0
- package/core/_layouts/blueprint/blog/post.html +5 -0
- package/core/_layouts/blueprint/blog/tags/index.html +11 -0
- package/core/_layouts/blueprint/blog/tags/tag.html +8 -0
- package/core/_layouts/blueprint/careers.md +13 -0
- package/core/_layouts/blueprint/collection/category.html +9 -0
- package/core/_layouts/blueprint/collection/document.html +9 -0
- package/core/_layouts/blueprint/collection/index.html +9 -0
- package/core/_layouts/blueprint/connections/callback.html +11 -0
- package/core/_layouts/blueprint/contact.html +14 -0
- package/core/_layouts/blueprint/dashboard/index.html +10 -0
- package/core/_layouts/blueprint/download.html +20 -0
- package/core/_layouts/blueprint/extension/index.html +14 -0
- package/core/_layouts/blueprint/extension/installed.html +11 -0
- package/core/_layouts/blueprint/feedback.html +10 -0
- package/core/_layouts/blueprint/index.html +16 -0
- package/core/_layouts/blueprint/legal/cookies.md +57 -0
- package/core/_layouts/blueprint/legal/privacy.md +109 -0
- package/core/_layouts/blueprint/legal/terms.md +155 -0
- package/core/_layouts/blueprint/payment/checkout.html +15 -0
- package/core/_layouts/blueprint/payment/confirmation.html +14 -0
- package/core/_layouts/blueprint/portal/email-preferences.html +15 -0
- package/core/_layouts/blueprint/pricing.html +20 -0
- package/core/_layouts/blueprint/status.html +10 -0
- package/core/_layouts/blueprint/team/index.html +10 -0
- package/core/_layouts/blueprint/team/member.html +5 -0
- package/core/_layouts/blueprint/updates/index.html +10 -0
- package/core/_layouts/blueprint/updates/update.html +10 -0
- package/core/_layouts/core/root.html +45 -0
- package/core/_layouts/modules/utilities/redirect.html +129 -0
- package/core/css/_studio.scss +237 -0
- package/core/css/components/_index.scss +146 -0
- package/core/css/core/_.scss +0 -0
- package/core/css/core/_alert.scss +87 -0
- package/core/css/core/_animations.scss +343 -0
- package/core/css/core/_bindings.scss +116 -0
- package/core/css/core/_blog-search.scss +57 -0
- package/core/css/core/_chatsy.scss +61 -0
- package/core/css/core/_consent.scss +424 -0
- package/core/css/core/_custom-font-awesome.scss +146 -0
- package/core/css/core/_exit-popup.scss +42 -0
- package/core/css/core/_generated-badge.scss +33 -0
- package/core/css/core/_initialize.scss +29 -0
- package/core/css/core/_lazy-loading.scss +104 -0
- package/core/css/core/_social-sharing.scss +41 -0
- package/core/css/core/_tones.scss +32 -0
- package/core/css/core/_utilities.scss +157 -0
- package/core/css/main.scss +54 -0
- package/core/css/motion/_index.scss +368 -0
- package/core/css/pages/404/index.scss +0 -0
- package/core/css/pages/admin/calendar/index.scss +692 -0
- package/core/css/pages/admin/firebase/index.scss +33 -0
- package/core/css/pages/admin/index.scss +9 -0
- package/core/css/pages/admin/users/index.scss +9 -0
- package/core/css/pages/admin/verts/index.scss +9 -0
- package/core/css/pages/alternatives/[alternative]/index.scss +0 -0
- package/core/css/pages/blog/[slug].scss +55 -0
- package/core/css/pages/dashboard/account/index.scss +242 -0
- package/core/css/pages/download/index.scss +480 -0
- package/core/css/pages/extension/installed/index.scss +317 -0
- package/core/css/pages/feedback/index.scss +31 -0
- package/core/css/pages/payment/confirmation/index.scss +14 -0
- package/core/css/pages/pricing/index.scss +0 -0
- package/core/css/pages/status/index.scss +162 -0
- package/core/css/pages/test/libraries/layers/index.scss +28 -0
- package/core/css/pages/updates/[update].scss +46 -0
- package/core/css/pages/updates/index.scss +13 -0
- package/core/css/shell/_index.scss +207 -0
- package/core/css/tokens/_index.scss +166 -0
- package/core/icons/flags/ar.svg +1 -0
- package/core/icons/flags/bd.svg +1 -0
- package/core/icons/flags/ca.svg +1 -0
- package/core/icons/flags/ch.svg +1 -0
- package/core/icons/flags/cn.svg +1 -0
- package/core/icons/flags/co.svg +1 -0
- package/core/icons/flags/cw.svg +1 -0
- package/core/icons/flags/cz.svg +1 -0
- package/core/icons/flags/de.svg +1 -0
- package/core/icons/flags/dk.svg +1 -0
- package/core/icons/flags/eg.svg +1 -0
- package/core/icons/flags/es.svg +1 -0
- package/core/icons/flags/fi.svg +1 -0
- package/core/icons/flags/fr.svg +1 -0
- package/core/icons/flags/gb.svg +1 -0
- package/core/icons/flags/gq.svg +1 -0
- package/core/icons/flags/gr.svg +1 -0
- package/core/icons/flags/gt.svg +1 -0
- package/core/icons/flags/hn.svg +1 -0
- package/core/icons/flags/id.svg +1 -0
- package/core/icons/flags/ie.svg +1 -0
- package/core/icons/flags/in.svg +1 -0
- package/core/icons/flags/ir.svg +1 -0
- package/core/icons/flags/it.svg +1 -0
- package/core/icons/flags/jp.svg +1 -0
- package/core/icons/flags/kp.svg +1 -0
- package/core/icons/flags/kr.svg +1 -0
- package/core/icons/flags/ly.svg +1 -0
- package/core/icons/flags/ma.svg +1 -0
- package/core/icons/flags/mu.svg +1 -0
- package/core/icons/flags/mx.svg +1 -0
- package/core/icons/flags/ng.svg +1 -0
- package/core/icons/flags/pa.svg +1 -0
- package/core/icons/flags/ph.svg +1 -0
- package/core/icons/flags/pk.svg +1 -0
- package/core/icons/flags/pt.svg +1 -0
- package/core/icons/flags/ru.svg +1 -0
- package/core/icons/flags/sa.svg +1 -0
- package/core/icons/flags/sd.svg +1 -0
- package/core/icons/flags/se.svg +1 -0
- package/core/icons/flags/th.svg +1 -0
- package/core/icons/flags/tm.svg +1 -0
- package/core/icons/flags/tr.svg +1 -0
- package/core/icons/flags/us.svg +1 -0
- package/core/icons/flags/uy.svg +1 -0
- package/core/icons/flags/vn.svg +1 -0
- package/core/icons/flags/za.svg +1 -0
- package/core/images/exit-popup/subscriber-1.jpg +0 -0
- package/core/images/exit-popup/subscriber-2.jpg +0 -0
- package/core/images/exit-popup/subscriber-3.jpg +0 -0
- package/core/images/exit-popup/subscriber-4.jpg +0 -0
- package/core/images/placeholder/photo-1.jpg +0 -0
- package/core/images/placeholder/photo-2.jpg +0 -0
- package/core/images/placeholder/photo-3.jpg +0 -0
- package/core/js/core/analytics-loader.js +253 -0
- package/core/js/core/app-shell.js +136 -0
- package/core/js/core/appearance.js +195 -0
- package/core/js/core/auth.js +457 -0
- package/core/js/core/complete.js +72 -0
- package/core/js/core/consent.js +384 -0
- package/core/js/core/dev-icon-audit.js +63 -0
- package/core/js/core/dev-palette.js +670 -0
- package/core/js/core/dev-sections.js +53 -0
- package/core/js/core/exit-popup.js +276 -0
- package/core/js/core/initialize.js +8 -0
- package/core/js/core/language-switcher.js +167 -0
- package/core/js/core/lazy-loading.js +479 -0
- package/core/js/core/motion.js +28 -0
- package/core/js/core/query-strings.js +146 -0
- package/core/js/core/service-worker.js +28 -0
- package/core/js/core/social-sharing.js +293 -0
- package/core/js/first-paint.js +35 -0
- package/core/js/layouts/modules/utilities/redirect.js +122 -0
- package/core/js/libs/admin-helpers.js +62 -0
- package/core/js/libs/alert-dismiss.js +35 -0
- package/core/js/libs/analytics.js +368 -0
- package/core/js/libs/auth/email.js +144 -0
- package/core/js/libs/auth/errors.js +119 -0
- package/core/js/libs/auth/forms.js +206 -0
- package/core/js/libs/auth/index.js +181 -0
- package/core/js/libs/auth/oauth.js +394 -0
- package/core/js/libs/auth/orphan.js +110 -0
- package/core/js/libs/auth/password-toggle.js +44 -0
- package/core/js/libs/auth/session-params.js +266 -0
- package/core/js/libs/auth/tracking.js +41 -0
- package/core/js/libs/charts.js +516 -0
- package/core/js/libs/consent-region.js +127 -0
- package/core/js/libs/dev.js +150 -0
- package/core/js/libs/graph.js +201 -0
- package/core/js/libs/initialize-tooltips.js +31 -0
- package/core/js/libs/logger.js +38 -0
- package/core/js/libs/omega-copy.js +89 -0
- package/core/js/libs/path-prefix.js +44 -0
- package/core/js/libs/payment-config.js +76 -0
- package/core/js/libs/recaptcha.js +94 -0
- package/core/js/libs/sale-name.js +295 -0
- package/core/js/libs/showcase-frames.js +37 -0
- package/core/js/libs/srcset.js +69 -0
- package/core/js/libs/tracking-consent.js +161 -0
- package/core/js/main.js +144 -0
- package/core/js/pages/404/index.js +57 -0
- package/core/js/pages/admin/calendar/calendar-core.js +701 -0
- package/core/js/pages/admin/calendar/calendar-events.js +853 -0
- package/core/js/pages/admin/calendar/calendar-renderer.js +807 -0
- package/core/js/pages/admin/calendar/campaign-preview.js +105 -0
- package/core/js/pages/admin/calendar/index.js +40 -0
- package/core/js/pages/admin/firebase/index.js +727 -0
- package/core/js/pages/admin/index.js +531 -0
- package/core/js/pages/admin/posts/editor/index.js +230 -0
- package/core/js/pages/admin/posts/index.js +237 -0
- package/core/js/pages/admin/studio/index.js +538 -0
- package/core/js/pages/admin/users/index.js +669 -0
- package/core/js/pages/admin/users/new/index.js +65 -0
- package/core/js/pages/admin/verts/index.js +407 -0
- package/core/js/pages/alternatives/[alternative]/index.js +17 -0
- package/core/js/pages/app/index.js +135 -0
- package/core/js/pages/blog/[slug].js +132 -0
- package/core/js/pages/blog/_search.mjs +108 -0
- package/core/js/pages/blog/index.js +193 -0
- package/core/js/pages/blog/page/[num]/index.js +7 -0
- package/core/js/pages/connections/callback/index.js +148 -0
- package/core/js/pages/contact/index.js +170 -0
- package/core/js/pages/cookies.js +2 -0
- package/core/js/pages/dashboard/account/index.js +366 -0
- package/core/js/pages/dashboard/account/modules/orders.js +82 -0
- package/core/js/pages/dashboard/account/sections/api-keys.js +149 -0
- package/core/js/pages/dashboard/account/sections/billing.js +1667 -0
- package/core/js/pages/dashboard/account/sections/connections.js +333 -0
- package/core/js/pages/dashboard/account/sections/data-request.js +225 -0
- package/core/js/pages/dashboard/account/sections/delete.js +80 -0
- package/core/js/pages/dashboard/account/sections/notifications.js +167 -0
- package/core/js/pages/dashboard/account/sections/orders.js +151 -0
- package/core/js/pages/dashboard/account/sections/profile.js +200 -0
- package/core/js/pages/dashboard/account/sections/referrals.js +217 -0
- package/core/js/pages/dashboard/account/sections/refund.js +253 -0
- package/core/js/pages/dashboard/account/sections/security.js +726 -0
- package/core/js/pages/dashboard/account/sections/team.js +247 -0
- package/core/js/pages/download/index.js +418 -0
- package/core/js/pages/extension/index.js +164 -0
- package/core/js/pages/extension/installed/index.js +135 -0
- package/core/js/pages/feedback/index.js +193 -0
- package/core/js/pages/legal/_document.js +91 -0
- package/core/js/pages/payment/checkout/index.js +420 -0
- package/core/js/pages/payment/checkout/modules/api.js +139 -0
- package/core/js/pages/payment/checkout/modules/dev-section.js +175 -0
- package/core/js/pages/payment/checkout/modules/discount.js +69 -0
- package/core/js/pages/payment/checkout/modules/pricing.js +73 -0
- package/core/js/pages/payment/checkout/modules/state.js +339 -0
- package/core/js/pages/payment/checkout/modules/tracking.js +54 -0
- package/core/js/pages/payment/confirmation/index.js +91 -0
- package/core/js/pages/payment/confirmation/modules/celebration.js +45 -0
- package/core/js/pages/payment/confirmation/modules/state.js +112 -0
- package/core/js/pages/payment/confirmation/modules/tracking.js +133 -0
- package/core/js/pages/payment/confirmation/modules/verify.js +142 -0
- package/core/js/pages/portal/email-preferences/index.js +183 -0
- package/core/js/pages/pricing/index.js +425 -0
- package/core/js/pages/privacy.js +2 -0
- package/core/js/pages/reset/index.js +12 -0
- package/core/js/pages/signin/index.js +22 -0
- package/core/js/pages/signup/index.js +23 -0
- package/core/js/pages/status/index.js +687 -0
- package/core/js/pages/terms.js +2 -0
- package/core/js/pages/test/components/[category]/[name]/index.js +26 -0
- package/core/js/pages/test/libraries/appearance/index.js +220 -0
- package/core/js/pages/test/libraries/form-manager/index.js +328 -0
- package/core/js/pages/test/libraries/layers/index.js +16 -0
- package/core/js/pages/test/libraries/verts/index.js +68 -0
- package/core/js/pages/test/sections/[category]/[name]/index.js +28 -0
- package/core/js/pages/test/styleguide/index.js +35 -0
- package/core/js/pages/token/index.js +203 -0
- package/core/logos/brandmarks/original/apple-app-store.svg +1 -0
- package/core/logos/brandmarks/original/apple.svg +6 -0
- package/core/logos/brandmarks/original/bitbucket.svg +14 -0
- package/core/logos/brandmarks/original/bitcoin.svg +1 -0
- package/core/logos/brandmarks/original/bluesky.svg +7 -0
- package/core/logos/brandmarks/original/bootstrap.svg +43 -0
- package/core/logos/brandmarks/original/brave.svg +1 -0
- package/core/logos/brandmarks/original/chrome.svg +1 -0
- package/core/logos/brandmarks/original/discord.svg +1 -0
- package/core/logos/brandmarks/original/dropbox.svg +10 -0
- package/core/logos/brandmarks/original/edge.svg +1 -0
- package/core/logos/brandmarks/original/facebook-f.svg +1 -0
- package/core/logos/brandmarks/original/facebook.svg +8 -0
- package/core/logos/brandmarks/original/figma.svg +10 -0
- package/core/logos/brandmarks/original/firefox.svg +1 -0
- package/core/logos/brandmarks/original/github.svg +6 -0
- package/core/logos/brandmarks/original/gitlab.svg +17 -0
- package/core/logos/brandmarks/original/google-a-s.svg +1 -0
- package/core/logos/brandmarks/original/google-chrome-webstore.svg +49 -0
- package/core/logos/brandmarks/original/google-play-store.svg +1 -0
- package/core/logos/brandmarks/original/google-web-search.svg +1 -0
- package/core/logos/brandmarks/original/google.svg +1 -0
- package/core/logos/brandmarks/original/gulp.svg +4 -0
- package/core/logos/brandmarks/original/html-5.svg +1 -0
- package/core/logos/brandmarks/original/instagram.svg +1 -0
- package/core/logos/brandmarks/original/javascript.svg +1 -0
- package/core/logos/brandmarks/original/jira.svg +18 -0
- package/core/logos/brandmarks/original/kick.svg +7 -0
- package/core/logos/brandmarks/original/linkedin.svg +1 -0
- package/core/logos/brandmarks/original/linux.svg +28 -0
- package/core/logos/brandmarks/original/messenger.svg +16 -0
- package/core/logos/brandmarks/original/microsoft.svg +1 -0
- package/core/logos/brandmarks/original/npm.svg +8 -0
- package/core/logos/brandmarks/original/opera.svg +1 -0
- package/core/logos/brandmarks/original/patreon.svg +6 -0
- package/core/logos/brandmarks/original/pinterest.svg +6 -0
- package/core/logos/brandmarks/original/reddit.svg +1 -0
- package/core/logos/brandmarks/original/safari.svg +31 -0
- package/core/logos/brandmarks/original/sass.svg +3 -0
- package/core/logos/brandmarks/original/signal.svg +6 -0
- package/core/logos/brandmarks/original/skype.svg +47 -0
- package/core/logos/brandmarks/original/slack.svg +33 -0
- package/core/logos/brandmarks/original/soundcloud.svg +1 -0
- package/core/logos/brandmarks/original/spotify.svg +5 -0
- package/core/logos/brandmarks/original/steam.svg +6 -0
- package/core/logos/brandmarks/original/telegram.svg +14 -0
- package/core/logos/brandmarks/original/tiktok.svg +1 -0
- package/core/logos/brandmarks/original/trello.svg +16 -0
- package/core/logos/brandmarks/original/tumblr.svg +1 -0
- package/core/logos/brandmarks/original/twitch.svg +6 -0
- package/core/logos/brandmarks/original/twitter.svg +6 -0
- package/core/logos/brandmarks/original/unity.svg +6 -0
- package/core/logos/brandmarks/original/x.svg +7 -0
- package/core/logos/brandmarks/original/yahoo-y.svg +1 -0
- package/core/logos/brandmarks/original/youtube-square.svg +1 -0
- package/core/logos/brandmarks/original/youtube.svg +1 -0
- package/core/logos/combomarks/dark/airbnb.svg +30 -0
- package/core/logos/combomarks/dark/slack.svg +38 -0
- package/core/logos/combomarks/dark/spotify.svg +35 -0
- package/core/logos/combomarks/dark/twilio.svg +26 -0
- package/core/logos/combomarks/dark/weebly.svg +35 -0
- package/core/logos/combomarks/gray/airbnb.svg +33 -0
- package/core/logos/combomarks/gray/alphabet.svg +23 -0
- package/core/logos/combomarks/gray/amazon.svg +38 -0
- package/core/logos/combomarks/gray/boring-company.svg +91 -0
- package/core/logos/combomarks/gray/burberry.svg +239 -0
- package/core/logos/combomarks/gray/embark.svg +21 -0
- package/core/logos/combomarks/gray/fitbit.svg +61 -0
- package/core/logos/combomarks/gray/fred-perry.svg +94 -0
- package/core/logos/combomarks/gray/google.svg +27 -0
- package/core/logos/combomarks/gray/hollister.svg +34 -0
- package/core/logos/combomarks/gray/hubspot.svg +27 -0
- package/core/logos/combomarks/gray/kaplan.svg +33 -0
- package/core/logos/combomarks/gray/lenovo.svg +27 -0
- package/core/logos/combomarks/gray/levis.svg +25 -0
- package/core/logos/combomarks/gray/mapbox.svg +37 -0
- package/core/logos/combomarks/gray/netflix.svg +15 -0
- package/core/logos/combomarks/gray/new-balance.svg +32 -0
- package/core/logos/combomarks/gray/nike.svg +17 -0
- package/core/logos/combomarks/gray/paypal.svg +41 -0
- package/core/logos/combomarks/gray/puma.svg +82 -0
- package/core/logos/combomarks/gray/samsung.svg +26 -0
- package/core/logos/combomarks/gray/shopify.svg +36 -0
- package/core/logos/combomarks/gray/slack.svg +42 -0
- package/core/logos/combomarks/gray/spotify.svg +38 -0
- package/core/logos/combomarks/gray/stripe.svg +24 -0
- package/core/logos/combomarks/gray/tnf.svg +30 -0
- package/core/logos/combomarks/gray/twilio.svg +29 -0
- package/core/logos/combomarks/gray/uber.svg +24 -0
- package/core/logos/combomarks/gray/weebly.svg +38 -0
- package/core/logos/combomarks/original/airbnb.svg +33 -0
- package/core/logos/combomarks/original/alphabet.svg +23 -0
- package/core/logos/combomarks/original/amazon.svg +38 -0
- package/core/logos/combomarks/original/asana.svg +8 -0
- package/core/logos/combomarks/original/boring-company.svg +91 -0
- package/core/logos/combomarks/original/discord.svg +6 -0
- package/core/logos/combomarks/original/embark.svg +24 -0
- package/core/logos/combomarks/original/fitbit.svg +60 -0
- package/core/logos/combomarks/original/github.svg +6 -0
- package/core/logos/combomarks/original/gitlab.svg +20 -0
- package/core/logos/combomarks/original/google.svg +28 -0
- package/core/logos/combomarks/original/hubspot.svg +29 -0
- package/core/logos/combomarks/original/instagram.svg +7 -0
- package/core/logos/combomarks/original/kickstarter.svg +6 -0
- package/core/logos/combomarks/original/lenovo.svg +24 -0
- package/core/logos/combomarks/original/linkedin.svg +6 -0
- package/core/logos/combomarks/original/mapbox.svg +39 -0
- package/core/logos/combomarks/original/mastodon.svg +7 -0
- package/core/logos/combomarks/original/medium.svg +6 -0
- package/core/logos/combomarks/original/meta.svg +22 -0
- package/core/logos/combomarks/original/microsoft.svg +13 -0
- package/core/logos/combomarks/original/monday.svg +12 -0
- package/core/logos/combomarks/original/netflix.svg +15 -0
- package/core/logos/combomarks/original/notion.svg +9 -0
- package/core/logos/combomarks/original/paypal.svg +41 -0
- package/core/logos/combomarks/original/reddit.svg +13 -0
- package/core/logos/combomarks/original/samsung.svg +25 -0
- package/core/logos/combomarks/original/shopify.svg +35 -0
- package/core/logos/combomarks/original/slack.svg +47 -0
- package/core/logos/combomarks/original/spotify.svg +37 -0
- package/core/logos/combomarks/original/stackoverflow.svg +28 -0
- package/core/logos/combomarks/original/stripe.svg +24 -0
- package/core/logos/combomarks/original/tiktok.svg +12 -0
- package/core/logos/combomarks/original/tumblr.svg +6 -0
- package/core/logos/combomarks/original/uber.svg +24 -0
- package/core/logos/combomarks/original/weebly.svg +34 -0
- package/core/logos/combomarks/original/whatsapp.svg +20 -0
- package/core/logos/combomarks/original/youtube.svg +10 -0
- package/core/logos/combomarks/original/zoom.svg +7 -0
- package/core/logos/combomarks/white/airbnb.svg +33 -0
- package/core/logos/combomarks/white/alphabet.svg +23 -0
- package/core/logos/combomarks/white/amazon.svg +38 -0
- package/core/logos/combomarks/white/boring-company.svg +91 -0
- package/core/logos/combomarks/white/embark.svg +21 -0
- package/core/logos/combomarks/white/fitbit.svg +61 -0
- package/core/logos/combomarks/white/google.svg +27 -0
- package/core/logos/combomarks/white/hubspot.svg +27 -0
- package/core/logos/combomarks/white/kaplan.svg +33 -0
- package/core/logos/combomarks/white/lenovo.svg +27 -0
- package/core/logos/combomarks/white/mapbox.svg +37 -0
- package/core/logos/combomarks/white/netflix.svg +15 -0
- package/core/logos/combomarks/white/paypal.svg +40 -0
- package/core/logos/combomarks/white/samsung.svg +26 -0
- package/core/logos/combomarks/white/shopify.svg +36 -0
- package/core/logos/combomarks/white/slack.svg +42 -0
- package/core/logos/combomarks/white/spotify.svg +38 -0
- package/core/logos/combomarks/white/stripe.svg +24 -0
- package/core/logos/combomarks/white/twilio.svg +29 -0
- package/core/logos/combomarks/white/uber.svg +24 -0
- package/core/logos/combomarks/white/weebly.svg +38 -0
- package/defaults/pages/404.md +4 -0
- package/defaults/pages/about.md +4 -0
- package/defaults/pages/admin/calendar/index.html +4 -0
- package/defaults/pages/admin/firebase/index.html +4 -0
- package/defaults/pages/admin/index.md +4 -0
- package/defaults/pages/admin/posts/editor.html +4 -0
- package/defaults/pages/admin/posts/index.html +4 -0
- package/defaults/pages/admin/stackblitz/index.html +4 -0
- package/defaults/pages/admin/studio/index.html +4 -0
- package/defaults/pages/admin/users/index.html +4 -0
- package/defaults/pages/admin/users/new.html +4 -0
- package/defaults/pages/admin/verts/index.html +4 -0
- package/defaults/pages/ads-txt.html +11 -0
- package/defaults/pages/alternatives/index.md +4 -0
- package/defaults/pages/app.md +4 -0
- package/defaults/pages/auth/reset.md +4 -0
- package/defaults/pages/auth/signin.md +4 -0
- package/defaults/pages/auth/signup.md +4 -0
- package/defaults/pages/auth/token.md +4 -0
- package/defaults/pages/blog/categories/category.html +21 -0
- package/defaults/pages/blog/categories.md +4 -0
- package/defaults/pages/blog/index-json.html +27 -0
- package/defaults/pages/blog/tags/tag.html +21 -0
- package/defaults/pages/blog/tags.md +4 -0
- package/defaults/pages/blog.md +22 -0
- package/defaults/pages/careers.md +4 -0
- package/defaults/pages/connections/callback.md +4 -0
- package/defaults/pages/contact.md +4 -0
- package/defaults/pages/dashboard/account.md +4 -0
- package/defaults/pages/dashboard/index.md +12 -0
- package/defaults/pages/download.md +4 -0
- package/defaults/pages/extension/index.html +4 -0
- package/defaults/pages/extension/installed.html +4 -0
- package/defaults/pages/feedback.md +4 -0
- package/defaults/pages/feeds/posts-json.html +40 -0
- package/defaults/pages/feeds/posts-xml.html +38 -0
- package/defaults/pages/humans.html +25 -0
- package/defaults/pages/index.md +4 -0
- package/defaults/pages/legal/cookies.md +4 -0
- package/defaults/pages/legal/privacy.md +4 -0
- package/defaults/pages/legal/terms.md +4 -0
- package/defaults/pages/llms-txt.html +46 -0
- package/defaults/pages/opensearch.html +16 -0
- package/defaults/pages/pages-json.html +42 -0
- package/defaults/pages/payment/checkout.md +4 -0
- package/defaults/pages/payment/confirmation.md +4 -0
- package/defaults/pages/portal/email-preferences.md +4 -0
- package/defaults/pages/pricing.md +4 -0
- package/defaults/pages/redirects/account.md +12 -0
- package/defaults/pages/redirects/admin/dashboard.md +11 -0
- package/defaults/pages/redirects/auth/change-password.md +9 -0
- package/defaults/pages/redirects/auth/forgot.md +9 -0
- package/defaults/pages/redirects/auth/join.md +9 -0
- package/defaults/pages/redirects/auth/login.md +9 -0
- package/defaults/pages/redirects/auth/recover.md +9 -0
- package/defaults/pages/redirects/auth/register.md +9 -0
- package/defaults/pages/redirects/auth/reset-password.md +9 -0
- package/defaults/pages/redirects/billing/cancel.md +9 -0
- package/defaults/pages/redirects/billing/refund.md +9 -0
- package/defaults/pages/robots.html +36 -0
- package/defaults/pages/security-txt.html +11 -0
- package/defaults/pages/sitemap.html +37 -0
- package/defaults/pages/status.md +4 -0
- package/defaults/pages/team/index.md +4 -0
- package/defaults/pages/test/account/dashboard.html +16 -0
- package/defaults/pages/test/index.md +12 -0
- package/defaults/pages/test/libraries/appearance.html +268 -0
- package/defaults/pages/test/libraries/cover.html +50 -0
- package/defaults/pages/test/libraries/error.html +30 -0
- package/defaults/pages/test/libraries/firestore.html +202 -0
- package/defaults/pages/test/libraries/form-manager.html +374 -0
- package/defaults/pages/test/libraries/layers.html +52 -0
- package/defaults/pages/test/libraries/lazy-loading.html +450 -0
- package/defaults/pages/test/libraries/verts.html +149 -0
- package/defaults/pages/test/redirect/external.md +13 -0
- package/defaults/pages/test/redirect/internal.md +13 -0
- package/defaults/pages/test/styleguide/index.html +588 -0
- package/defaults/pages/test/translation/index.md +50 -0
- package/defaults/pages/updates/index.md +4 -0
- package/defaults/sample-posts/2026-01-12-welcome-to-the-blog.md +26 -0
- package/defaults/sample-posts/2026-02-03-a-field-guide-to-good-defaults.md +50 -0
- package/defaults/sample-posts/2026-02-24-shipping-week-notes.md +37 -0
- package/defaults/sample-posts/2026-03-17-the-case-for-one-config.md +36 -0
- package/defaults/sample-posts/2026-04-09-write-release-notes-people-read.md +34 -0
- package/defaults/sample-posts/2026-05-21-dark-mode-done-properly.md +38 -0
- package/defaults/sample-posts/2026-06-02-the-boring-deploy-is-the-good-deploy.md +30 -0
- package/defaults/sample-posts/2026-06-11-naming-things-a-survival-guide.md +30 -0
- package/defaults/sample-posts/2026-06-19-your-pricing-page-is-a-product.md +28 -0
- package/defaults/sample-posts/2026-06-30-email-is-an-api-with-feelings.md +28 -0
- package/defaults/sample-posts/2026-07-08-ship-the-docs-with-the-diff.md +30 -0
- package/defaults/sample-team/avery-quinn.md +22 -0
- package/defaults/sample-team/jordan-reyes.md +25 -0
- package/defaults/sample-team/riley-nakamura.md +22 -0
- package/defaults/sample-team/sam-okafor.md +22 -0
- package/defaults/sample-updates/v1.0.0.md +28 -0
- package/defaults/sample-updates/v1.1.0.md +27 -0
- package/defaults/sample-updates/v1.2.0.md +27 -0
- package/defaults/sample-updates/v1.3.0.md +28 -0
- package/defaults/showcase/components.html +62 -0
- package/defaults/showcase/entry.html +76 -0
- package/defaults/showcase/frame.html +62 -0
- package/defaults/showcase/index.html +59 -0
- package/dist/assets.js +1349 -0
- package/dist/brand-tokens.js +195 -0
- package/dist/build.js +192 -0
- package/dist/cachebreak-html.js +71 -0
- package/dist/cli-run.js +25 -0
- package/dist/cli.js +47 -0
- package/dist/collections.js +183 -0
- package/dist/commands/audit.js +470 -0
- package/dist/commands/build.js +197 -0
- package/dist/commands/clean.js +18 -0
- package/dist/commands/customize.js +125 -0
- package/dist/commands/deploy.js +441 -0
- package/dist/commands/dev.js +1067 -0
- package/dist/commands/install.js +31 -0
- package/dist/commands/lib/deploy-precheck.js +43 -0
- package/dist/commands/lib/ensure-target.js +115 -0
- package/dist/commands/migrate.js +86 -0
- package/dist/commands/purge.js +31 -0
- package/dist/commands/test.js +237 -0
- package/dist/commands/translate.js +57 -0
- package/dist/commands/update.js +22 -0
- package/dist/commands/version.js +11 -0
- package/dist/config-sections.js +245 -0
- package/dist/consumer-scan.js +118 -0
- package/dist/consumer.js +49 -0
- package/dist/customize.js +328 -0
- package/dist/decisions.js +153 -0
- package/dist/dist-audit.js +417 -0
- package/dist/dynamic-pages.js +357 -0
- package/dist/engine.js +1402 -0
- package/dist/firebase-auth-helpers.js +198 -0
- package/dist/font-metrics.js +420 -0
- package/dist/frontmatter-liquid.js +253 -0
- package/dist/github-secrets.js +80 -0
- package/dist/hero-animations.js +170 -0
- package/dist/imagemin.js +261 -0
- package/dist/index.js +41 -0
- package/dist/inline-icons.js +65 -0
- package/dist/language-flags.js +55 -0
- package/dist/layers.js +80 -0
- package/dist/layouts.js +44 -0
- package/dist/limit-collections.js +199 -0
- package/dist/link-resolver.js +303 -0
- package/dist/markdown-images.js +85 -0
- package/dist/merge.js +20 -0
- package/dist/migrate/codemod.js +172 -0
- package/dist/migrate/config-convert.js +448 -0
- package/dist/migrate/consumer-assets.js +130 -0
- package/dist/migrate/index.js +223 -0
- package/dist/migrate/lint.js +108 -0
- package/dist/migrate/rules.js +1929 -0
- package/dist/minify-html.js +148 -0
- package/dist/mode-helpers.js +96 -0
- package/dist/omega-bin.js +7 -0
- package/dist/overrides.js +190 -0
- package/dist/path-prefix.js +167 -0
- package/dist/paths.js +37 -0
- package/dist/pricing.js +301 -0
- package/dist/purge.js +95 -0
- package/dist/redirect-page.js +45 -0
- package/dist/sample-content.js +210 -0
- package/dist/scaffold.js +123 -0
- package/dist/sections.js +810 -0
- package/dist/service-worker.js +200 -0
- package/dist/social-pages.js +142 -0
- package/dist/srcset.js +67 -0
- package/dist/static-assets.js +154 -0
- package/dist/target-shortlinks.js +123 -0
- package/dist/theme-vocabulary.js +76 -0
- package/dist/translate/collect-text-nodes.js +93 -0
- package/dist/translate/default-routes.js +152 -0
- package/dist/translate/generate-defaults.js +297 -0
- package/dist/translate/index.js +568 -0
- package/dist/translate/packaged-defaults.js +127 -0
- package/dist/translate/sitemap.js +108 -0
- package/dist/vendor/account/engine.js +182 -0
- package/dist/vendor/account/features.js +220 -0
- package/dist/vendor/account/index.js +53 -0
- package/dist/vendor/account/schema.js +272 -0
- package/dist/vendor/account/subscription.js +38 -0
- package/dist/vendor/config/company.js +31 -0
- package/dist/vendor/config/defaults.js +173 -0
- package/dist/vendor/config/demo.js +18 -0
- package/dist/vendor/config/desktop-artifacts.js +110 -0
- package/dist/vendor/config/edit.js +769 -0
- package/dist/vendor/config/env-delivery.js +145 -0
- package/dist/vendor/config/env-rules.js +93 -0
- package/dist/vendor/config/env-schema.js +1078 -0
- package/dist/vendor/config/env.js +445 -0
- package/dist/vendor/config/hooks.js +97 -0
- package/dist/vendor/config/index.js +237 -0
- package/dist/vendor/config/instances.js +208 -0
- package/dist/vendor/config/load.js +490 -0
- package/dist/vendor/config/merge.js +68 -0
- package/dist/vendor/config/order.js +139 -0
- package/dist/vendor/config/ports.js +374 -0
- package/dist/vendor/config/providers.js +32 -0
- package/dist/vendor/config/repo.js +142 -0
- package/dist/vendor/config/retired-keys.js +430 -0
- package/dist/vendor/config/schema.js +1610 -0
- package/dist/vendor/config/secrets.js +50 -0
- package/dist/vendor/config/seed.js +34 -0
- package/dist/vendor/config/site-global.js +205 -0
- package/dist/vendor/config/validate.js +554 -0
- package/dist/vendor/config/winback.js +61 -0
- package/dist/vendor/devkit/actions-secrets.js +145 -0
- package/dist/vendor/devkit/attach-log-file.js +262 -0
- package/dist/vendor/devkit/bare-requires.js +153 -0
- package/dist/vendor/devkit/bundle.js +292 -0
- package/dist/vendor/devkit/ci-workflows.js +520 -0
- package/dist/vendor/devkit/cli-router.js +156 -0
- package/dist/vendor/devkit/command-path.js +46 -0
- package/dist/vendor/devkit/defaults-engine.js +372 -0
- package/dist/vendor/devkit/deploy-precheck.js +54 -0
- package/dist/vendor/devkit/deploy-record.js +180 -0
- package/dist/vendor/devkit/deploy.js +286 -0
- package/dist/vendor/devkit/env-watch.js +132 -0
- package/dist/vendor/devkit/framework-deps.js +46 -0
- package/dist/vendor/devkit/icons.js +178 -0
- package/dist/vendor/devkit/license.js +155 -0
- package/dist/vendor/devkit/local-https.js +360 -0
- package/dist/vendor/devkit/local.js +1905 -0
- package/dist/vendor/devkit/logger.js +128 -0
- package/dist/vendor/devkit/merge-line-files.js +296 -0
- package/dist/vendor/devkit/omega-bin.js +345 -0
- package/dist/vendor/devkit/reads.js +274 -0
- package/dist/vendor/devkit/safe-install.js +18 -0
- package/dist/vendor/devkit/scaffold-guard.js +96 -0
- package/dist/vendor/devkit/stop-signals.js +28 -0
- package/dist/vendor/devkit/strip-dev-blocks-plugin.js +29 -0
- package/dist/vendor/devkit/strip-dev-blocks.js +32 -0
- package/dist/vendor/devkit/target-secrets.js +165 -0
- package/dist/vendor/devkit/test/scope.js +162 -0
- package/dist/vendor/devkit/translate/cache.js +84 -0
- package/dist/vendor/devkit/translate/engine.js +243 -0
- package/dist/vendor/devkit/translate/index.js +49 -0
- package/dist/vendor/devkit/translate/languages.js +134 -0
- package/dist/vendor/devkit/translate/providers.js +188 -0
- package/dist/vendor/devkit/update.js +569 -0
- package/dist/vendor/template-kit/data/language-flags.js +54 -0
- package/dist/vendor/template-kit/data/languages.js +195 -0
- package/dist/vendor/template-kit/data/social-urls.js +26 -0
- package/dist/vendor/template-kit/filters.js +227 -0
- package/dist/vendor/template-kit/index.js +28 -0
- package/dist/vendor/template-kit/jekyll-compat.js +268 -0
- package/dist/vendor/template-kit/register-liquid.js +0 -0
- package/dist/vendor/template-kit/tags/collections.js +191 -0
- package/dist/vendor/template-kit/tags/conditionals.js +101 -0
- package/dist/vendor/template-kit/tags/content.js +175 -0
- package/dist/vendor/template-kit/tags/index.js +33 -0
- package/dist/vendor/template-kit/tags/media.js +376 -0
- package/dist/vendor/template-kit/variable-resolver.js +163 -0
- package/docs/ads-system.md +109 -0
- package/docs/classy-v2/DIRECTION.md +92 -0
- package/docs/classy-v2/draft-1.html +1932 -0
- package/docs/classy-v2/draft-2.html +1956 -0
- package/docs/frontmatter.md +153 -0
- package/docs/index.md +254 -0
- package/docs/libs.md +298 -0
- package/docs/omega-sections-spec.md +159 -0
- package/docs/page-contract.md +112 -0
- package/docs/sections.md +845 -0
- package/docs/shared/agent-docs.md +89 -0
- package/docs/shared/analytics.md +612 -0
- package/docs/shared/brands.md +51 -0
- package/docs/shared/breaking-changes.md +497 -0
- package/docs/shared/config.md +1387 -0
- package/docs/shared/deploys.md +215 -0
- package/docs/shared/icons.md +201 -0
- package/docs/shared/local-dev.md +147 -0
- package/docs/shared/logging.md +202 -0
- package/docs/shared/monitoring.md +153 -0
- package/docs/shared/publishing.md +183 -0
- package/docs/shared/rulings.md +34 -0
- package/docs/shared/testing.md +147 -0
- package/docs/shared/theming.md +604 -0
- package/docs/shared/translation.md +291 -0
- package/docs/shared/updates.md +61 -0
- package/docs/template-kit.md +128 -0
- package/docs/test-framework.md +163 -0
- package/package.json +122 -0
- package/runtime/boot.js +149 -0
- package/runtime/icons.js +77 -0
- package/runtime/manager.js +36 -0
- package/scaffold/.github/workflows/build.yml +139 -0
- package/scaffold/.nvmrc +1 -0
- package/scaffold/AGENTS.md +55 -0
- package/scaffold/CLAUDE.md +1 -0
- package/scaffold/_.gitattributes +4 -0
- package/scaffold/_.gitignore +27 -0
- package/scaffold/config/omega.json5 +20 -0
- package/scaffold/src/assets/css/pages/.gitkeep +0 -0
- package/scaffold/src/assets/images/.gitkeep +0 -0
- package/scaffold/src/assets/js/pages/.gitkeep +0 -0
- package/scaffold/src/pages/.gitkeep +0 -0
- package/scaffold/src/pages/example.md.txt +94 -0
- package/scaffold/src/service-worker.js +16 -0
- package/sw/entry.js +19 -0
- package/sw/manager.js +281 -0
- package/themes/_template/README.md +115 -0
- package/themes/_template/_config.scss +60 -0
- package/themes/_template/_theme.js +14 -0
- package/themes/_template/_theme.scss +28 -0
- package/themes/_template/css/base/_root.scss +19 -0
- package/themes/_template/css/components/_components.scss +23 -0
- package/themes/base/README.md +5 -0
- package/themes/base/_components/data/org-chart/component.html +33 -0
- package/themes/base/_components/data/org-chart/component.json5 +33 -0
- package/themes/base/_components/data/org-chart/component.scss +183 -0
- package/themes/base/_components/heading/masthead/component.html +22 -0
- package/themes/base/_components/heading/masthead/component.json5 +30 -0
- package/themes/base/_components/heading/section-head/component.html +18 -0
- package/themes/base/_components/heading/section-head/component.json5 +27 -0
- package/themes/base/_components/pricing/features/component.html +29 -0
- package/themes/base/_components/pricing/features/component.json5 +30 -0
- package/themes/base/_hero/orbit/index.html +30 -0
- package/themes/base/_hero/orbit/script.js +33 -0
- package/themes/base/_hero/orbit/style.scss +133 -0
- package/themes/base/_includes/admin/sections/sidebar.html +3 -0
- package/themes/base/_includes/admin/sections/topbar.html +3 -0
- package/themes/base/_includes/backend/sections/sidebar.html +3 -0
- package/themes/base/_includes/backend/sections/topbar.html +3 -0
- package/themes/base/_includes/frontend/components/connection-card.html +49 -0
- package/themes/base/_includes/frontend/components/post-card.html +54 -0
- package/themes/base/_includes/frontend/sections/account-connections.html +42 -0
- package/themes/base/_includes/frontend/sections/account-section-header.html +11 -0
- package/themes/base/_includes/frontend/sections/footer.html +154 -0
- package/themes/base/_includes/frontend/sections/nav.html +276 -0
- package/themes/base/_includes/global/sections/account.html +72 -0
- package/themes/base/_includes/global/sections/app-sidebar.html +248 -0
- package/themes/base/_includes/global/sections/app-topbar.html +228 -0
- package/themes/base/_includes/global/sections/page-header.html +99 -0
- package/themes/base/_layouts/admin/core/minimal-viewport-locked.html +22 -0
- package/themes/base/_layouts/admin/core/minimal.html +23 -0
- package/themes/base/_layouts/backend/core/base.html +57 -0
- package/themes/base/_layouts/backend/core/minimal-viewport-locked.html +32 -0
- package/themes/base/_layouts/backend/core/minimal.html +32 -0
- package/themes/base/_layouts/backend/pages/dashboard/index.html +230 -0
- package/themes/base/_layouts/frontend/core/base.html +31 -0
- package/themes/base/_layouts/frontend/core/cover.html +40 -0
- package/themes/base/_layouts/frontend/core/minimal.html +47 -0
- package/themes/base/_layouts/frontend/pages/404.html +54 -0
- package/themes/base/_layouts/frontend/pages/about.html +144 -0
- package/themes/base/_layouts/frontend/pages/account/index.html +2104 -0
- package/themes/base/_layouts/frontend/pages/alternatives/alternative.html +319 -0
- package/themes/base/_layouts/frontend/pages/alternatives/index.html +186 -0
- package/themes/base/_layouts/frontend/pages/app.html +142 -0
- package/themes/base/_layouts/frontend/pages/auth/reset.html +53 -0
- package/themes/base/_layouts/frontend/pages/auth/signin.html +90 -0
- package/themes/base/_layouts/frontend/pages/auth/signup.html +141 -0
- package/themes/base/_layouts/frontend/pages/auth/token.html +44 -0
- package/themes/base/_layouts/frontend/pages/blog/categories/category.html +88 -0
- package/themes/base/_layouts/frontend/pages/blog/categories/index.html +88 -0
- package/themes/base/_layouts/frontend/pages/blog/index.html +255 -0
- package/themes/base/_layouts/frontend/pages/blog/post.html +261 -0
- package/themes/base/_layouts/frontend/pages/blog/tags/index.html +84 -0
- package/themes/base/_layouts/frontend/pages/blog/tags/tag.html +88 -0
- package/themes/base/_layouts/frontend/pages/collection/category.html +72 -0
- package/themes/base/_layouts/frontend/pages/collection/document.html +54 -0
- package/themes/base/_layouts/frontend/pages/collection/index.html +84 -0
- package/themes/base/_layouts/frontend/pages/connections/callback.html +55 -0
- package/themes/base/_layouts/frontend/pages/contact.html +214 -0
- package/themes/base/_layouts/frontend/pages/download.html +793 -0
- package/themes/base/_layouts/frontend/pages/extension/index.html +253 -0
- package/themes/base/_layouts/frontend/pages/extension/installed.html +198 -0
- package/themes/base/_layouts/frontend/pages/feedback.html +171 -0
- package/themes/base/_layouts/frontend/pages/index.html +66 -0
- package/themes/base/_layouts/frontend/pages/legal/document.html +78 -0
- package/themes/base/_layouts/frontend/pages/payment/checkout.html +459 -0
- package/themes/base/_layouts/frontend/pages/payment/confirmation.html +131 -0
- package/themes/base/_layouts/frontend/pages/portal/email-preferences.html +104 -0
- package/themes/base/_layouts/frontend/pages/pricing.html +596 -0
- package/themes/base/_layouts/frontend/pages/status.html +361 -0
- package/themes/base/_layouts/frontend/pages/team/index.html +210 -0
- package/themes/base/_layouts/frontend/pages/team/member.html +125 -0
- package/themes/base/_layouts/frontend/pages/updates/index.html +119 -0
- package/themes/base/_layouts/frontend/pages/updates/update.html +118 -0
- package/themes/base/_sections/about/hero/section.html +68 -0
- package/themes/base/_sections/about/hero/section.json5 +58 -0
- package/themes/base/_sections/about/letter/section.html +60 -0
- package/themes/base/_sections/about/letter/section.json5 +56 -0
- package/themes/base/_sections/about/photo-band/section.html +24 -0
- package/themes/base/_sections/about/photo-band/section.json5 +23 -0
- package/themes/base/_sections/about/principles/section.html +17 -0
- package/themes/base/_sections/about/principles/section.json5 +34 -0
- package/themes/base/_sections/about/timeline/section.html +20 -0
- package/themes/base/_sections/about/timeline/section.json5 +34 -0
- package/themes/base/_sections/marketing/bento/section.html +91 -0
- package/themes/base/_sections/marketing/bento/section.json5 +152 -0
- package/themes/base/_sections/marketing/cta/section.html +44 -0
- package/themes/base/_sections/marketing/cta/section.json5 +47 -0
- package/themes/base/_sections/marketing/faq/section.html +52 -0
- package/themes/base/_sections/marketing/faq/section.json5 +68 -0
- package/themes/base/_sections/marketing/hero/section.html +349 -0
- package/themes/base/_sections/marketing/hero/section.json5 +335 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.html +38 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.js +86 -0
- package/themes/base/_sections/marketing/newsletter-cta/section.json5 +29 -0
- package/themes/base/_sections/marketing/pricing-cards/section.html +115 -0
- package/themes/base/_sections/marketing/pricing-cards/section.json5 +72 -0
- package/themes/base/_sections/marketing/product-demo/section.html +62 -0
- package/themes/base/_sections/marketing/product-demo/section.js +44 -0
- package/themes/base/_sections/marketing/product-demo/section.json5 +52 -0
- package/themes/base/_sections/marketing/prose/section.html +22 -0
- package/themes/base/_sections/marketing/prose/section.json5 +41 -0
- package/themes/base/_sections/marketing/showcase/section.html +35 -0
- package/themes/base/_sections/marketing/showcase/section.json5 +52 -0
- package/themes/base/_sections/marketing/stats/section.html +32 -0
- package/themes/base/_sections/marketing/stats/section.json5 +44 -0
- package/themes/base/_sections/marketing/testimonials/section.html +54 -0
- package/themes/base/_sections/marketing/testimonials/section.json5 +70 -0
- package/themes/base/_sections/marketing/trusted-by/section.html +30 -0
- package/themes/base/_sections/marketing/trusted-by/section.json5 +38 -0
- package/themes/base/_sections/verts/unit/section.html +7 -0
- package/themes/base/_sections/verts/unit/section.js +22 -0
- package/themes/base/_sections/verts/unit/section.json5 +24 -0
- package/themes/base/_sections/verts/unit/section.scss +24 -0
- package/themes/base/_theme.js +13 -0
- package/themes/base/_theme.scss +4 -0
- package/themes/bootstrap/_theme.js +16 -0
- package/themes/bootstrap/_theme.scss +11 -0
- package/themes/bootstrap/js/index.esm.js +19 -0
- package/themes/bootstrap/js/index.umd.js +34 -0
- package/themes/bootstrap/js/src/alert.js +87 -0
- package/themes/bootstrap/js/src/base-component.js +86 -0
- package/themes/bootstrap/js/src/button.js +72 -0
- package/themes/bootstrap/js/src/carousel.js +474 -0
- package/themes/bootstrap/js/src/collapse.js +297 -0
- package/themes/bootstrap/js/src/dom/data.js +55 -0
- package/themes/bootstrap/js/src/dom/event-handler.js +317 -0
- package/themes/bootstrap/js/src/dom/manipulator.js +71 -0
- package/themes/bootstrap/js/src/dom/selector-engine.js +126 -0
- package/themes/bootstrap/js/src/dropdown.js +458 -0
- package/themes/bootstrap/js/src/modal.js +378 -0
- package/themes/bootstrap/js/src/offcanvas.js +282 -0
- package/themes/bootstrap/js/src/popover.js +97 -0
- package/themes/bootstrap/js/src/scrollspy.js +296 -0
- package/themes/bootstrap/js/src/tab.js +315 -0
- package/themes/bootstrap/js/src/toast.js +224 -0
- package/themes/bootstrap/js/src/tooltip.js +632 -0
- package/themes/bootstrap/js/src/util/backdrop.js +151 -0
- package/themes/bootstrap/js/src/util/component-functions.js +35 -0
- package/themes/bootstrap/js/src/util/config.js +65 -0
- package/themes/bootstrap/js/src/util/focustrap.js +115 -0
- package/themes/bootstrap/js/src/util/index.js +306 -0
- package/themes/bootstrap/js/src/util/sanitizer.js +117 -0
- package/themes/bootstrap/js/src/util/scrollbar.js +114 -0
- package/themes/bootstrap/js/src/util/swipe.js +146 -0
- package/themes/bootstrap/js/src/util/template-factory.js +160 -0
- package/themes/bootstrap/overrides/_accordion.scss +21 -0
- package/themes/bootstrap/overrides/_avatars.scss +51 -0
- package/themes/bootstrap/overrides/_blog-images.scss +45 -0
- package/themes/bootstrap/overrides/_buttons-adaptive.scss +141 -0
- package/themes/bootstrap/overrides/_color-shades.scss +25 -0
- package/themes/bootstrap/overrides/_cursor-utilities.scss +13 -0
- package/themes/bootstrap/overrides/_index.scss +30 -0
- package/themes/bootstrap/overrides/_links.scss +26 -0
- package/themes/bootstrap/overrides/_soft-colors.scss +99 -0
- package/themes/bootstrap/overrides/_spacing-extended.scss +74 -0
- package/themes/bootstrap/overrides/_spinners.scss +22 -0
- package/themes/bootstrap/overrides/_typography-utilities.scss +40 -0
- package/themes/bootstrap/scss/_accordion.scss +153 -0
- package/themes/bootstrap/scss/_alert.scss +68 -0
- package/themes/bootstrap/scss/_badge.scss +38 -0
- package/themes/bootstrap/scss/_breadcrumb.scss +40 -0
- package/themes/bootstrap/scss/_button-group.scss +147 -0
- package/themes/bootstrap/scss/_buttons.scss +216 -0
- package/themes/bootstrap/scss/_card.scss +238 -0
- package/themes/bootstrap/scss/_carousel.scss +226 -0
- package/themes/bootstrap/scss/_close.scss +66 -0
- package/themes/bootstrap/scss/_containers.scss +41 -0
- package/themes/bootstrap/scss/_dropdown.scss +250 -0
- package/themes/bootstrap/scss/_forms.scss +9 -0
- package/themes/bootstrap/scss/_functions.scss +302 -0
- package/themes/bootstrap/scss/_grid.scss +39 -0
- package/themes/bootstrap/scss/_helpers.scss +12 -0
- package/themes/bootstrap/scss/_images.scss +42 -0
- package/themes/bootstrap/scss/_list-group.scss +199 -0
- package/themes/bootstrap/scss/_maps.scss +174 -0
- package/themes/bootstrap/scss/_mixins.scss +42 -0
- package/themes/bootstrap/scss/_modal.scss +240 -0
- package/themes/bootstrap/scss/_nav.scss +197 -0
- package/themes/bootstrap/scss/_navbar.scss +289 -0
- package/themes/bootstrap/scss/_offcanvas.scss +147 -0
- package/themes/bootstrap/scss/_pagination.scss +109 -0
- package/themes/bootstrap/scss/_placeholders.scss +51 -0
- package/themes/bootstrap/scss/_popover.scss +196 -0
- package/themes/bootstrap/scss/_progress.scss +68 -0
- package/themes/bootstrap/scss/_reboot.scss +611 -0
- package/themes/bootstrap/scss/_root.scss +187 -0
- package/themes/bootstrap/scss/_spinners.scss +85 -0
- package/themes/bootstrap/scss/_tables.scss +171 -0
- package/themes/bootstrap/scss/_toasts.scss +73 -0
- package/themes/bootstrap/scss/_tooltip.scss +119 -0
- package/themes/bootstrap/scss/_transitions.scss +27 -0
- package/themes/bootstrap/scss/_type.scss +106 -0
- package/themes/bootstrap/scss/_utilities.scss +806 -0
- package/themes/bootstrap/scss/_variables-dark.scss +102 -0
- package/themes/bootstrap/scss/_variables.scss +1753 -0
- package/themes/bootstrap/scss/bootstrap-grid.scss +62 -0
- package/themes/bootstrap/scss/bootstrap-reboot.scss +10 -0
- package/themes/bootstrap/scss/bootstrap-utilities.scss +19 -0
- package/themes/bootstrap/scss/bootstrap.scss +52 -0
- package/themes/bootstrap/scss/forms/_floating-labels.scss +97 -0
- package/themes/bootstrap/scss/forms/_form-check.scss +189 -0
- package/themes/bootstrap/scss/forms/_form-control.scss +214 -0
- package/themes/bootstrap/scss/forms/_form-range.scss +91 -0
- package/themes/bootstrap/scss/forms/_form-select.scss +80 -0
- package/themes/bootstrap/scss/forms/_form-text.scss +11 -0
- package/themes/bootstrap/scss/forms/_input-group.scss +132 -0
- package/themes/bootstrap/scss/forms/_labels.scss +36 -0
- package/themes/bootstrap/scss/forms/_validation.scss +12 -0
- package/themes/bootstrap/scss/helpers/_clearfix.scss +3 -0
- package/themes/bootstrap/scss/helpers/_color-bg.scss +7 -0
- package/themes/bootstrap/scss/helpers/_colored-links.scss +30 -0
- package/themes/bootstrap/scss/helpers/_focus-ring.scss +5 -0
- package/themes/bootstrap/scss/helpers/_icon-link.scss +25 -0
- package/themes/bootstrap/scss/helpers/_position.scss +36 -0
- package/themes/bootstrap/scss/helpers/_ratio.scss +26 -0
- package/themes/bootstrap/scss/helpers/_stacks.scss +15 -0
- package/themes/bootstrap/scss/helpers/_stretched-link.scss +15 -0
- package/themes/bootstrap/scss/helpers/_text-truncation.scss +7 -0
- package/themes/bootstrap/scss/helpers/_visually-hidden.scss +8 -0
- package/themes/bootstrap/scss/helpers/_vr.scss +8 -0
- package/themes/bootstrap/scss/mixins/_alert.scss +18 -0
- package/themes/bootstrap/scss/mixins/_backdrop.scss +14 -0
- package/themes/bootstrap/scss/mixins/_banner.scss +7 -0
- package/themes/bootstrap/scss/mixins/_border-radius.scss +78 -0
- package/themes/bootstrap/scss/mixins/_box-shadow.scss +18 -0
- package/themes/bootstrap/scss/mixins/_breakpoints.scss +127 -0
- package/themes/bootstrap/scss/mixins/_buttons.scss +70 -0
- package/themes/bootstrap/scss/mixins/_caret.scss +69 -0
- package/themes/bootstrap/scss/mixins/_clearfix.scss +9 -0
- package/themes/bootstrap/scss/mixins/_color-mode.scss +21 -0
- package/themes/bootstrap/scss/mixins/_color-scheme.scss +7 -0
- package/themes/bootstrap/scss/mixins/_container.scss +11 -0
- package/themes/bootstrap/scss/mixins/_deprecate.scss +10 -0
- package/themes/bootstrap/scss/mixins/_forms.scss +163 -0
- package/themes/bootstrap/scss/mixins/_gradients.scss +47 -0
- package/themes/bootstrap/scss/mixins/_grid.scss +151 -0
- package/themes/bootstrap/scss/mixins/_image.scss +16 -0
- package/themes/bootstrap/scss/mixins/_list-group.scss +26 -0
- package/themes/bootstrap/scss/mixins/_lists.scss +7 -0
- package/themes/bootstrap/scss/mixins/_pagination.scss +10 -0
- package/themes/bootstrap/scss/mixins/_reset-text.scss +17 -0
- package/themes/bootstrap/scss/mixins/_resize.scss +6 -0
- package/themes/bootstrap/scss/mixins/_table-variants.scss +24 -0
- package/themes/bootstrap/scss/mixins/_text-truncate.scss +8 -0
- package/themes/bootstrap/scss/mixins/_transition.scss +26 -0
- package/themes/bootstrap/scss/mixins/_utilities.scss +97 -0
- package/themes/bootstrap/scss/mixins/_visually-hidden.scss +38 -0
- package/themes/bootstrap/scss/tests/jasmine.js +16 -0
- package/themes/bootstrap/scss/tests/mixins/_auto-import-of-variables-dark.test.scss +7 -0
- package/themes/bootstrap/scss/tests/mixins/_color-modes.test.scss +69 -0
- package/themes/bootstrap/scss/tests/mixins/_media-query-color-mode-full.test.scss +8 -0
- package/themes/bootstrap/scss/tests/mixins/_utilities.test.scss +393 -0
- package/themes/bootstrap/scss/tests/sass-true/register.js +14 -0
- package/themes/bootstrap/scss/tests/sass-true/runner.js +17 -0
- package/themes/bootstrap/scss/tests/utilities/_api.test.scss +75 -0
- package/themes/bootstrap/scss/utilities/_api.scss +47 -0
- package/themes/bootstrap/scss/vendor/_rfs.scss +348 -0
- package/themes/classy/README.md +89 -0
- package/themes/classy/_config.scss +245 -0
- package/themes/classy/_theme.js +31 -0
- package/themes/classy/_theme.scss +57 -0
- package/themes/classy/css/app/_panels.scss +183 -0
- package/themes/classy/css/base/_fonts.scss +79 -0
- package/themes/classy/css/base/_no-raise.scss +49 -0
- package/themes/classy/css/base/_root.scss +113 -0
- package/themes/classy/css/base/_typography.scss +154 -0
- package/themes/classy/css/base/_utilities.scss +284 -0
- package/themes/classy/css/components/_alerts.scss +51 -0
- package/themes/classy/css/components/_badges.scss +46 -0
- package/themes/classy/css/components/_buttons.scss +175 -0
- package/themes/classy/css/components/_cards.scss +41 -0
- package/themes/classy/css/components/_dropdowns.scss +48 -0
- package/themes/classy/css/components/_forms.scss +171 -0
- package/themes/classy/css/components/_receipt.scss +45 -0
- package/themes/classy/css/layout/_footer.scss +298 -0
- package/themes/classy/css/layout/_general.scss +209 -0
- package/themes/classy/css/layout/_nav.scss +154 -0
- package/themes/classy/css/layout/_shell.scss +458 -0
- package/themes/classy/css/marketing/_bento.scss +238 -0
- package/themes/classy/css/marketing/_content.scss +1328 -0
- package/themes/classy/css/marketing/_downloads.scss +246 -0
- package/themes/classy/css/marketing/_hero.scss +311 -0
- package/themes/classy/css/marketing/_sections.scss +649 -0
- package/themes/classy/css/pages/404/index.scss +67 -0
- package/themes/classy/css/pages/_auth.scss +235 -0
- package/themes/classy/css/pages/admin/firebase/index.scss +22 -0
- package/themes/classy/css/pages/blog/[slug].scss +56 -0
- package/themes/classy/css/pages/cookies.scss +2 -0
- package/themes/classy/css/pages/dashboard/account/index.scss +31 -0
- package/themes/classy/css/pages/feedback/index.scss +39 -0
- package/themes/classy/css/pages/legal/_document.scss +192 -0
- package/themes/classy/css/pages/payment/checkout/index.scss +585 -0
- package/themes/classy/css/pages/payment/confirmation/index.scss +9 -0
- package/themes/classy/css/pages/privacy.scss +2 -0
- package/themes/classy/css/pages/status/index.scss +164 -0
- package/themes/classy/css/pages/terms.scss +2 -0
- package/themes/classy/css/pages/updates/index.scss +128 -0
- package/themes/classy/fonts/inter-italic-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/inter-italic-latin.woff2 +0 -0
- package/themes/classy/fonts/inter-normal-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/inter-normal-latin.woff2 +0 -0
- package/themes/classy/fonts/newsreader-italic-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/newsreader-italic-latin.woff2 +0 -0
- package/themes/classy/fonts/newsreader-normal-latin-ext.woff2 +0 -0
- package/themes/classy/fonts/newsreader-normal-latin.woff2 +0 -0
- package/themes/classy/js/hero-demo-form.js +56 -0
- package/themes/neobrutalism/README.md +118 -0
- package/themes/neobrutalism/_config.scss +139 -0
- package/themes/neobrutalism/_layouts/frontend/core/base.html +30 -0
- package/themes/neobrutalism/_layouts/frontend/pages/index.html +275 -0
- package/themes/neobrutalism/_theme.js +24 -0
- package/themes/neobrutalism/_theme.scss +61 -0
- package/themes/neobrutalism/css/base/_mixins.scss +46 -0
- package/themes/neobrutalism/css/base/_root.scss +169 -0
- package/themes/neobrutalism/css/base/_typography.scss +61 -0
- package/themes/neobrutalism/css/base/_utilities.scss +89 -0
- package/themes/neobrutalism/css/components/_billing-toggle.scss +74 -0
- package/themes/neobrutalism/css/components/_buttons.scss +148 -0
- package/themes/neobrutalism/css/components/_cards.scss +47 -0
- package/themes/neobrutalism/css/components/_forms.scss +88 -0
- package/themes/neobrutalism/css/components/_marketing.scss +244 -0
- package/themes/neobrutalism/css/layout/_general.scss +213 -0
- package/themes/neobrutalism/css/layout/_navigation.scss +171 -0
- package/themes/neobrutalism/css/pages/index.scss +203 -0
- package/themes/neobrutalism/css/pages/pricing/index.scss +58 -0
- package/themes/neobrutalism/css/pages/test/libraries/layers/index.scss +7 -0
- package/themes/neobrutalism/js/pages/test/libraries/layers/index.js +9 -0
- package/themes/newsflash/README.md +117 -0
- package/themes/newsflash/_components/heading/lede/component.html +14 -0
- package/themes/newsflash/_components/heading/lede/component.json5 +23 -0
- package/themes/newsflash/_components/heading/rule-head/component.html +17 -0
- package/themes/newsflash/_components/heading/rule-head/component.json5 +23 -0
- package/themes/newsflash/_components/news/byline/component.html +12 -0
- package/themes/newsflash/_components/news/byline/component.json5 +18 -0
- package/themes/newsflash/_components/news/story-card/component.html +25 -0
- package/themes/newsflash/_components/news/story-card/component.json5 +21 -0
- package/themes/newsflash/_config.scss +147 -0
- package/themes/newsflash/_layouts/frontend/core/base.html +51 -0
- package/themes/newsflash/_layouts/frontend/pages/blog/index.html +299 -0
- package/themes/newsflash/_layouts/frontend/pages/blog/post.html +235 -0
- package/themes/newsflash/_layouts/frontend/pages/index.html +328 -0
- package/themes/newsflash/_sections/marketing/desks/section.html +39 -0
- package/themes/newsflash/_sections/marketing/desks/section.json5 +49 -0
- package/themes/newsflash/_sections/marketing/newsletter-cta/section.html +103 -0
- package/themes/newsflash/_sections/marketing/newsletter-cta/section.json5 +50 -0
- package/themes/newsflash/_sections/marketing/rundown/section.html +28 -0
- package/themes/newsflash/_sections/marketing/rundown/section.json5 +40 -0
- package/themes/newsflash/_theme.js +24 -0
- package/themes/newsflash/_theme.scss +70 -0
- package/themes/newsflash/css/base/_fonts.scss +80 -0
- package/themes/newsflash/css/base/_mixins.scss +51 -0
- package/themes/newsflash/css/base/_root.scss +257 -0
- package/themes/newsflash/css/base/_typography.scss +49 -0
- package/themes/newsflash/css/base/_utilities.scss +122 -0
- package/themes/newsflash/css/components/_badges.scss +65 -0
- package/themes/newsflash/css/components/_billing-toggle.scss +61 -0
- package/themes/newsflash/css/components/_buttons.scss +139 -0
- package/themes/newsflash/css/components/_cards.scss +47 -0
- package/themes/newsflash/css/components/_editorial.scss +173 -0
- package/themes/newsflash/css/components/_forms.scss +75 -0
- package/themes/newsflash/css/components/_infinite-scroll.scss +102 -0
- package/themes/newsflash/css/components/_panels.scss +156 -0
- package/themes/newsflash/css/components/_ticker.scss +67 -0
- package/themes/newsflash/css/layout/_general.scss +330 -0
- package/themes/newsflash/css/layout/_navigation.scss +168 -0
- package/themes/newsflash/css/pages/404/index.scss +79 -0
- package/themes/newsflash/css/pages/blog/[slug].scss +186 -0
- package/themes/newsflash/css/pages/blog/index.scss +17 -0
- package/themes/newsflash/css/pages/index.scss +157 -0
- package/themes/newsflash/css/pages/pricing/index.scss +55 -0
- package/themes/newsflash/css/pages/test/libraries/layers/index.scss +7 -0
- package/themes/newsflash/fonts/fraunces-italic-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-italic-latin.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-normal-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/fraunces-normal-latin.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-italic-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-italic-latin.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-normal-latin-ext.woff2 +0 -0
- package/themes/newsflash/fonts/schibsted-grotesk-normal-latin.woff2 +0 -0
- package/themes/newsflash/js/pages/blog/[slug].js +29 -0
- package/themes/newsflash/js/pages/test/libraries/layers/index.js +9 -0
- package/translations/es/pages/404.json +86 -0
- package/translations/es/pages/account.json +36 -0
- package/translations/es/pages/app.json +44 -0
- package/translations/es/pages/cancel.json +36 -0
- package/translations/es/pages/change-password.json +36 -0
- package/translations/es/pages/connections/callback.json +41 -0
- package/translations/es/pages/dashboard/account.json +475 -0
- package/translations/es/pages/dashboard.json +36 -0
- package/translations/es/pages/forgot.json +36 -0
- package/translations/es/pages/join.json +36 -0
- package/translations/es/pages/login.json +36 -0
- package/translations/es/pages/payment/checkout.json +83 -0
- package/translations/es/pages/payment/confirmation.json +62 -0
- package/translations/es/pages/portal/email-preferences.json +46 -0
- package/translations/es/pages/recover.json +36 -0
- package/translations/es/pages/refund.json +36 -0
- package/translations/es/pages/register.json +36 -0
- package/translations/es/pages/reset-password.json +36 -0
- package/translations/es/pages/reset.json +42 -0
- package/translations/es/pages/signin.json +45 -0
- package/translations/es/pages/signup.json +60 -0
- package/translations/es/pages/token.json +39 -0
- package/translations/fa/pages/404.json +86 -0
- package/translations/fa/pages/account.json +36 -0
- package/translations/fa/pages/app.json +44 -0
- package/translations/fa/pages/cancel.json +36 -0
- package/translations/fa/pages/change-password.json +36 -0
- package/translations/fa/pages/connections/callback.json +41 -0
- package/translations/fa/pages/dashboard/account.json +475 -0
- package/translations/fa/pages/dashboard.json +36 -0
- package/translations/fa/pages/forgot.json +36 -0
- package/translations/fa/pages/join.json +36 -0
- package/translations/fa/pages/login.json +36 -0
- package/translations/fa/pages/payment/checkout.json +83 -0
- package/translations/fa/pages/payment/confirmation.json +62 -0
- package/translations/fa/pages/portal/email-preferences.json +46 -0
- package/translations/fa/pages/recover.json +36 -0
- package/translations/fa/pages/refund.json +36 -0
- package/translations/fa/pages/register.json +36 -0
- package/translations/fa/pages/reset-password.json +36 -0
- package/translations/fa/pages/reset.json +42 -0
- package/translations/fa/pages/signin.json +45 -0
- package/translations/fa/pages/signup.json +60 -0
- package/translations/fa/pages/token.json +39 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
// The checkout's dev palette section (#234) — everything the page's own gear
|
|
2
|
+
// dropdown used to offer, now registered into the palette so the checkout page
|
|
3
|
+
// carries no dev chrome of its own.
|
|
4
|
+
//
|
|
5
|
+
// DEVELOPMENT ONLY. Nothing but the `@dev-only` block in ../index.js imports
|
|
6
|
+
// this file, so a production build strips the import and this module never
|
|
7
|
+
// enters the bundle.
|
|
8
|
+
//
|
|
9
|
+
// Every control is a URL param, because that is the only way the page reads
|
|
10
|
+
// them — each is consumed ONCE at page init, before any of these controls
|
|
11
|
+
// exist:
|
|
12
|
+
// product, frequency → ../index.js (initializeCheckout)
|
|
13
|
+
// _dev_preDelay → ../index.js (artificial pre-delay)
|
|
14
|
+
// _dev_trialEligible → ../index.js (trial override)
|
|
15
|
+
// _dev_cardProvider → ./state.js (resolveProvider)
|
|
16
|
+
// _dev_recaptcha → ../../../../libs/recaptcha.js
|
|
17
|
+
// _dev_decline → ./api.js (the intent POST's simulate)
|
|
18
|
+
// So "apply" navigates with the params set rather than pretending it can
|
|
19
|
+
// change a decision the page already made. Session storage would not help:
|
|
20
|
+
// resolveProvider reads the URL, and only the URL.
|
|
21
|
+
|
|
22
|
+
import { getProducts } from '__main_assets__/js/libs/payment-config.js';
|
|
23
|
+
|
|
24
|
+
const CHECKOUT_PATH = '/payment/checkout';
|
|
25
|
+
|
|
26
|
+
// The param the checkout's intent call turns into `simulate: 'decline'`
|
|
27
|
+
// (./api.js). Presence is the arm, so it is applied as `=true` or not at all.
|
|
28
|
+
const DECLINE_PARAM = '_dev_decline';
|
|
29
|
+
|
|
30
|
+
// The fixed-option controls, in the order the gear dropdown showed them. An
|
|
31
|
+
// empty first value means "leave it to the page" and applies no param at all.
|
|
32
|
+
const CONTROLS = [
|
|
33
|
+
{
|
|
34
|
+
param: 'frequency',
|
|
35
|
+
label: 'Frequency',
|
|
36
|
+
options: [['annually', 'Annually'], ['monthly', 'Monthly'], ['weekly', 'Weekly'], ['daily', 'Daily']],
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
// The slow-boot rehearsal (#342): the page sleeps this long before the
|
|
40
|
+
// trial answer lands (#637), so the trial spot and the money line hold
|
|
41
|
+
// their skeletons long enough to look at rather than flashing past.
|
|
42
|
+
param: '_dev_preDelay',
|
|
43
|
+
label: 'Pre-delay',
|
|
44
|
+
options: [['', '(none)'], ['3000', '3s'], ['5000', '5s'], ['10000', '10s']],
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
param: '_dev_trialEligible',
|
|
48
|
+
label: 'Trial eligible',
|
|
49
|
+
options: [['', '(use API)'], ['true', 'Force true'], ['false', 'Force false']],
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
param: '_dev_cardProvider',
|
|
53
|
+
label: 'Card provider',
|
|
54
|
+
options: [['', '(auto)'], ['test', 'Test'], ['stripe', 'Stripe'], ['chargebee', 'Chargebee']],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
param: '_dev_recaptcha',
|
|
58
|
+
label: 'reCAPTCHA',
|
|
59
|
+
options: [['', '(normal)'], ['invalid', 'Send invalid token'], ['empty', 'Send empty token']],
|
|
60
|
+
},
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* The product control's options come from the brand's own payment config, so
|
|
65
|
+
* the list is whatever this brand actually sells.
|
|
66
|
+
* @returns {Array<[string, string]>}
|
|
67
|
+
*/
|
|
68
|
+
function productOptions() {
|
|
69
|
+
return getProducts().map((product) => [product.id, `${product.name} (${product.type})`]);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* One labelled select. The label WRAPS the select, so the control is named
|
|
74
|
+
* without needing an id to point at.
|
|
75
|
+
*/
|
|
76
|
+
function field(doc, { param, label, options }, value) {
|
|
77
|
+
const wrap = doc.createElement('label');
|
|
78
|
+
wrap.className = 'omega-devbar__field';
|
|
79
|
+
|
|
80
|
+
const text = doc.createElement('span');
|
|
81
|
+
text.className = 'omega-devbar__field-label';
|
|
82
|
+
text.textContent = label;
|
|
83
|
+
|
|
84
|
+
const select = doc.createElement('select');
|
|
85
|
+
select.className = 'omega-devbar__select';
|
|
86
|
+
select.setAttribute('data-dev-param', param);
|
|
87
|
+
options.forEach(([optionValue, optionLabel]) => {
|
|
88
|
+
const option = doc.createElement('option');
|
|
89
|
+
option.value = optionValue;
|
|
90
|
+
option.textContent = optionLabel;
|
|
91
|
+
select.appendChild(option);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
// Seeded explicitly rather than left to the browser's "first option" default,
|
|
95
|
+
// so the panel always shows the value the page was actually built with.
|
|
96
|
+
select.value = value;
|
|
97
|
+
|
|
98
|
+
wrap.append(text, select);
|
|
99
|
+
|
|
100
|
+
return { wrap, select };
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Arm the checkout to be declined by the provider, so the failure path is one
|
|
105
|
+
* click away instead of a card number to remember. A checkbox rather than a
|
|
106
|
+
* select because it is the one two-state control, but it applies with the rest:
|
|
107
|
+
* checked writes the param, unchecked drops it, and the arm lasts until it is
|
|
108
|
+
* applied away. It lived in the palette's built-ins until it followed the rest
|
|
109
|
+
* of the checkout's controls onto the page it belongs to.
|
|
110
|
+
*/
|
|
111
|
+
function declineToggle(doc, armed) {
|
|
112
|
+
const wrap = doc.createElement('label');
|
|
113
|
+
wrap.className = 'omega-devbar__toggle';
|
|
114
|
+
wrap.setAttribute('for', 'omega-devbar-decline');
|
|
115
|
+
|
|
116
|
+
const input = doc.createElement('input');
|
|
117
|
+
input.type = 'checkbox';
|
|
118
|
+
input.id = 'omega-devbar-decline';
|
|
119
|
+
input.checked = armed;
|
|
120
|
+
|
|
121
|
+
const text = doc.createElement('span');
|
|
122
|
+
text.textContent = 'Decline next checkout';
|
|
123
|
+
|
|
124
|
+
wrap.append(input, text);
|
|
125
|
+
|
|
126
|
+
return { wrap, input };
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
export const checkoutDevSection = {
|
|
130
|
+
title: 'Checkout',
|
|
131
|
+
|
|
132
|
+
appliesTo: () => window.location.pathname.startsWith(CHECKOUT_PATH),
|
|
133
|
+
|
|
134
|
+
buildNode: (doc) => {
|
|
135
|
+
const params = new URLSearchParams(window.location.search);
|
|
136
|
+
const controls = [{ param: 'product', label: 'Product', options: productOptions() }, ...CONTROLS];
|
|
137
|
+
|
|
138
|
+
const wrap = doc.createElement('div');
|
|
139
|
+
wrap.className = 'omega-devbar__fields';
|
|
140
|
+
|
|
141
|
+
const fields = controls.map((control) => {
|
|
142
|
+
const seeded = params.get(control.param) ?? (control.options[0]?.[0] || '');
|
|
143
|
+
const built = field(doc, control, seeded);
|
|
144
|
+
wrap.appendChild(built.wrap);
|
|
145
|
+
return { param: control.param, select: built.select };
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
const decline = declineToggle(doc, params.has(DECLINE_PARAM));
|
|
149
|
+
wrap.appendChild(decline.wrap);
|
|
150
|
+
|
|
151
|
+
const apply = doc.createElement('button');
|
|
152
|
+
apply.type = 'button';
|
|
153
|
+
apply.className = 'omega-devbar__btn';
|
|
154
|
+
apply.textContent = 'Apply & reload';
|
|
155
|
+
apply.addEventListener('click', () => {
|
|
156
|
+
// A fresh query string of exactly the dev controls — the gear's behaviour
|
|
157
|
+
// verbatim: an unset control applies no param.
|
|
158
|
+
const next = new URLSearchParams();
|
|
159
|
+
fields.forEach(({ param, select }) => {
|
|
160
|
+
const value = (select.value || '').trim();
|
|
161
|
+
if (value) {
|
|
162
|
+
next.set(param, value);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
if (decline.input.checked) {
|
|
166
|
+
next.set(DECLINE_PARAM, 'true');
|
|
167
|
+
}
|
|
168
|
+
window.location.search = next.toString();
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
wrap.appendChild(apply);
|
|
172
|
+
|
|
173
|
+
return wrap;
|
|
174
|
+
},
|
|
175
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
// Discount code logic for checkout
|
|
2
|
+
import { state, formatCurrency } from './state.js';
|
|
3
|
+
import { validateDiscountCode } from './api.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* What a validated code takes off, in its own shape: the server answers with a
|
|
7
|
+
* `percent` OR an `amount`, never both. Reading only the percent is what made
|
|
8
|
+
* a flat code announce itself as "undefined% off".
|
|
9
|
+
* @param {object} result - the validate() body
|
|
10
|
+
* @returns {string} e.g. "20% off" or "$10.00 off"
|
|
11
|
+
*/
|
|
12
|
+
function describeDiscount(result) {
|
|
13
|
+
return result.percent > 0
|
|
14
|
+
? `${result.percent}% off`
|
|
15
|
+
: `${formatCurrency(result.amount)} off`;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/** Put the receipt back on full price, in both discount shapes. */
|
|
19
|
+
function clearDiscount() {
|
|
20
|
+
state.discountCode = null;
|
|
21
|
+
state.discountPercent = 0;
|
|
22
|
+
state.discountAmount = 0;
|
|
23
|
+
state.discountDuration = null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Apply a discount code via server-side validation
|
|
28
|
+
* @param {string} code - Discount code to validate
|
|
29
|
+
* @param {Function} updateUI - Callback to refresh bindings
|
|
30
|
+
*/
|
|
31
|
+
export async function applyDiscountCode(code, updateUI) {
|
|
32
|
+
code = (code || '').trim().toUpperCase();
|
|
33
|
+
|
|
34
|
+
if (!code) {
|
|
35
|
+
clearDiscount();
|
|
36
|
+
state.discountUI = { loading: false, success: false, error: true, message: 'Please enter a discount code' };
|
|
37
|
+
updateUI();
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Show loading
|
|
42
|
+
state.discountUI = { loading: true, success: false, error: false, message: '' };
|
|
43
|
+
updateUI();
|
|
44
|
+
|
|
45
|
+
try {
|
|
46
|
+
const result = await validateDiscountCode(code);
|
|
47
|
+
|
|
48
|
+
if (result.valid) {
|
|
49
|
+
// One shape or the other reaches the receipt; the other stays zero, so
|
|
50
|
+
// the summary prices against whichever the server actually issued
|
|
51
|
+
state.discountCode = result.code;
|
|
52
|
+
state.discountPercent = result.percent || 0;
|
|
53
|
+
state.discountAmount = result.amount || 0;
|
|
54
|
+
// The server's own term for the code — the receipt prices the renewal
|
|
55
|
+
// off it rather than assuming the discount rides forever (#254)
|
|
56
|
+
state.discountDuration = result.duration || null;
|
|
57
|
+
state.discountUI = { loading: false, success: true, error: false, message: `Discount applied: ${describeDiscount(result)}` };
|
|
58
|
+
} else {
|
|
59
|
+
clearDiscount();
|
|
60
|
+
state.discountUI = { loading: false, success: false, error: true, message: 'Invalid discount code' };
|
|
61
|
+
}
|
|
62
|
+
} catch (e) {
|
|
63
|
+
console.warn('Discount validation failed:', e);
|
|
64
|
+
clearDiscount();
|
|
65
|
+
state.discountUI = { loading: false, success: false, error: true, message: 'Unable to validate discount code. Please try again.' };
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
updateUI();
|
|
69
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
// Pure pricing calculation -- no side effects, no state mutation
|
|
2
|
+
|
|
3
|
+
// Resolve price for a frequency. A catalog price is a bare number and nothing
|
|
4
|
+
// else — the config validator refuses `{ amount: N }` outright, because this
|
|
5
|
+
// page unwrapped it and every backend reader did not: the same entry priced the
|
|
6
|
+
// summary correctly and reached the confirmation URL as `[object Object]`
|
|
7
|
+
// ([#674](https://github.com/Omega-JS-Stack/omega/issues/674)).
|
|
8
|
+
function resolvePrice(prices, key) {
|
|
9
|
+
return Number(prices?.[key]) || 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// A discount code comes in one of TWO shapes, and the server returns exactly
|
|
13
|
+
// one of them: `discountPercent` (a share of the price) or `discountAmount` (a
|
|
14
|
+
// flat sum, `flatDiscount` here — the RETURNED `discountAmount` is the money
|
|
15
|
+
// that actually came off, which is what the receipt row prices against).
|
|
16
|
+
export function calculatePrices({ product, frequency, discountPercent, discountAmount: flatDiscount, discountDuration, trialEligible }) {
|
|
17
|
+
if (!product) {
|
|
18
|
+
return { subtotal: 0, discountAmount: 0, trialDiscountAmount: 0, total: 0, recurring: 0 };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const isSubscription = product.type === 'subscription';
|
|
22
|
+
const hasFreeTrial = isSubscription && trialEligible && (product.trial?.days > 0);
|
|
23
|
+
|
|
24
|
+
// Base price directly from API product
|
|
25
|
+
let basePrice;
|
|
26
|
+
if (isSubscription) {
|
|
27
|
+
basePrice = resolvePrice(product.prices, frequency);
|
|
28
|
+
} else {
|
|
29
|
+
// One-time: `once` is the catalog key; `amount`/`monthly` are legacy shapes
|
|
30
|
+
basePrice = resolvePrice(product.prices, 'once')
|
|
31
|
+
|| resolvePrice(product.prices, 'amount')
|
|
32
|
+
|| resolvePrice(product.prices, 'monthly')
|
|
33
|
+
|| 0;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const subtotal = basePrice;
|
|
37
|
+
|
|
38
|
+
// Both shapes are ONE subtraction from the same subtotal: a percent of it,
|
|
39
|
+
// or a flat sum off it. Clamped to [0, subtotal] so $10 off a $4.99 product
|
|
40
|
+
// is free rather than four cents owed back the other way.
|
|
41
|
+
const raw = discountPercent > 0
|
|
42
|
+
? (subtotal * discountPercent) / 100
|
|
43
|
+
: (flatDiscount || 0);
|
|
44
|
+
const discountAmount = Math.min(Math.max(raw, 0), subtotal);
|
|
45
|
+
const afterDiscount = subtotal - discountAmount;
|
|
46
|
+
|
|
47
|
+
let trialDiscountAmount = 0;
|
|
48
|
+
let total;
|
|
49
|
+
|
|
50
|
+
if (hasFreeTrial) {
|
|
51
|
+
// Free trial = $0 due today, but recurring stays
|
|
52
|
+
trialDiscountAmount = afterDiscount;
|
|
53
|
+
total = 0;
|
|
54
|
+
} else {
|
|
55
|
+
total = afterDiscount;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// The code's `duration` decides how far the discount reaches (#254). Every
|
|
59
|
+
// configured code is `duration: 'once'` and the backend prices the renewal at
|
|
60
|
+
// full list (discount-codes.js `applyToAmount()` — the FIRST charge only, via a
|
|
61
|
+
// Stripe `once` coupon), so reducing the recurring line promised a renewal
|
|
62
|
+
// price we never honor. An absent duration reads as 'once': the conservative
|
|
63
|
+
// side of a promise. Anything else is a code that really does ride every cycle.
|
|
64
|
+
const discountRecurs = !!discountDuration && discountDuration !== 'once';
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
subtotal,
|
|
68
|
+
discountAmount,
|
|
69
|
+
trialDiscountAmount,
|
|
70
|
+
total,
|
|
71
|
+
recurring: discountRecurs ? afterDiscount : subtotal,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
// State management for checkout
|
|
2
|
+
// Minimal mutable state -- everything else is derived by buildBindingsState()
|
|
3
|
+
|
|
4
|
+
import { calculatePrices } from './pricing.js';
|
|
5
|
+
import omega from '@omega.js/client';
|
|
6
|
+
|
|
7
|
+
// All supported billing frequencies
|
|
8
|
+
export const FREQUENCIES = ['daily', 'weekly', 'monthly', 'annually'];
|
|
9
|
+
|
|
10
|
+
// What a one-time buy bills on, which is nothing: `once` is not a cadence and
|
|
11
|
+
// is deliberately not in FREQUENCIES. It is still the word every reader
|
|
12
|
+
// downstream keys on — the intent payload, the intent doc, the confirmation
|
|
13
|
+
// URL, the receipt copy, the purchase pixel's `item_category` — so it is
|
|
14
|
+
// spelled here once ([#668](https://github.com/Omega-JS-Stack/omega/issues/668)).
|
|
15
|
+
export const ONE_TIME_FREQUENCY = 'once';
|
|
16
|
+
|
|
17
|
+
// The third answer a trial-eligibility check can produce, and it is NOT the
|
|
18
|
+
// same as "not eligible": the check timed out or failed, so nobody knows. The
|
|
19
|
+
// DISPLAY reads it conservatively (no trial quoted, the full amount due today
|
|
20
|
+
// — rule 3 never quotes a price the server has not confirmed), while the
|
|
21
|
+
// intent payload still ASKS for the trial, because the route re-checks and
|
|
22
|
+
// silently downgrades a buyer who does not qualify. Losing a trial to a slow
|
|
23
|
+
// network would cost a qualifying buyer their offer for nothing
|
|
24
|
+
// (Ian 2026-08-27, [#637](https://github.com/Omega-JS-Stack/omega/issues/637)).
|
|
25
|
+
export const TRIAL_ELIGIBILITY_UNKNOWN = 'unknown';
|
|
26
|
+
|
|
27
|
+
// Minimal mutable state
|
|
28
|
+
export const state = {
|
|
29
|
+
// From config (stored once, never transformed)
|
|
30
|
+
product: null,
|
|
31
|
+
providers: null,
|
|
32
|
+
|
|
33
|
+
// User selections
|
|
34
|
+
frequency: 'annually',
|
|
35
|
+
discountCode: null,
|
|
36
|
+
// A code takes off a PERCENT of the price or a flat AMOUNT of money — the
|
|
37
|
+
// server returns one shape or the other, so exactly one of these is ever
|
|
38
|
+
// non-zero
|
|
39
|
+
discountPercent: 0,
|
|
40
|
+
discountAmount: 0,
|
|
41
|
+
// How far the code reaches: 'once' (the first payment only, what every
|
|
42
|
+
// configured code is) vs a duration that rides every renewal (#254)
|
|
43
|
+
discountDuration: null,
|
|
44
|
+
// The server's answer: true, false, or TRIAL_ELIGIBILITY_UNKNOWN
|
|
45
|
+
trialEligibility: TRIAL_ELIGIBILITY_UNKNOWN,
|
|
46
|
+
// What the page DISPLAYS, which is only ever a confirmed yes
|
|
47
|
+
trialEligible: false,
|
|
48
|
+
|
|
49
|
+
// UI state
|
|
50
|
+
discountUI: { loading: false, success: false, error: false, message: '' },
|
|
51
|
+
error: { show: false, message: '' },
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
// Resolve which provider handles a payment method
|
|
55
|
+
export function resolveProvider(paymentMethod) {
|
|
56
|
+
if (paymentMethod === 'card') {
|
|
57
|
+
/* @dev-only:start */
|
|
58
|
+
{
|
|
59
|
+
// The dev palette's card-provider override, a URL param like every
|
|
60
|
+
// other checkout dev control. The read lives INSIDE the block, so
|
|
61
|
+
// production never looks and the literal never reaches a real bundle
|
|
62
|
+
// (#235) — a visitor can't point a real checkout at another provider.
|
|
63
|
+
if (omega.isDevelopment()) {
|
|
64
|
+
const forced = new URLSearchParams(window.location.search).get('_dev_cardProvider');
|
|
65
|
+
if (forced) return forced;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/* @dev-only:end */
|
|
69
|
+
|
|
70
|
+
// Prefer Stripe, fall back to Chargebee
|
|
71
|
+
if (state.providers?.stripe?.publishableKey) return 'stripe';
|
|
72
|
+
if (state.providers?.chargebee?.site) return 'chargebee';
|
|
73
|
+
return 'stripe';
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const map = { paypal: 'paypal', crypto: 'coinbase' };
|
|
77
|
+
return map[paymentMethod] || paymentMethod;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Resolve price for a frequency. A catalog price is a bare number and nothing
|
|
81
|
+
// else — the config validator refuses the object shape, so this page and the
|
|
82
|
+
// backend can never read one entry differently
|
|
83
|
+
// ([#674](https://github.com/Omega-JS-Stack/omega/issues/674)).
|
|
84
|
+
function resolvePrice(product, frequency) {
|
|
85
|
+
return Number(product?.prices?.[frequency]) || 0;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Determine which frequencies a product supports based on its prices object
|
|
89
|
+
export function getAvailableFrequencies(product) {
|
|
90
|
+
if (!product?.prices) return [];
|
|
91
|
+
return FREQUENCIES.filter(f => resolvePrice(product, f) > 0);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* What this checkout bills on — the ONE place the answer is decided, for the
|
|
96
|
+
* product being bought and for every product it is ever switched to.
|
|
97
|
+
*
|
|
98
|
+
* A one-time buy has no cadence to choose, so it is `once` OUTRIGHT: the URL
|
|
99
|
+
* param and the price list only ever decide a SUBSCRIPTION's term. Falling
|
|
100
|
+
* through to the cadence lane sent `frequency=annually` on a one-time checkout
|
|
101
|
+
* — a product with no annual price, so the fallback picked the default — and
|
|
102
|
+
* that word rode the intent payload all the way to the confirmation URL, where
|
|
103
|
+
* the page polled the account for a plan a one-time purchase never writes and
|
|
104
|
+
* sat on "still processing" until it timed out
|
|
105
|
+
* ([#668](https://github.com/Omega-JS-Stack/omega/issues/668)).
|
|
106
|
+
*
|
|
107
|
+
* @param {object|null} product - the catalog product being bought
|
|
108
|
+
* @param {string|null} frequencyParam - the URL's `frequency`, if any
|
|
109
|
+
* @returns {string} the frequency this checkout runs on
|
|
110
|
+
*/
|
|
111
|
+
export function resolveFrequency(product, frequencyParam) {
|
|
112
|
+
if (product?.type !== 'subscription') {
|
|
113
|
+
return ONE_TIME_FREQUENCY;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
const available = getAvailableFrequencies(product);
|
|
117
|
+
|
|
118
|
+
if (frequencyParam && FREQUENCIES.includes(frequencyParam) && available.includes(frequencyParam)) {
|
|
119
|
+
return frequencyParam;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Longest term (last in FREQUENCIES order: daily < weekly < monthly < annually)
|
|
123
|
+
return available[available.length - 1] || 'annually';
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Build the complete bindings state from minimal state
|
|
127
|
+
// Returns a fresh object every time -- no mutation of shared references
|
|
128
|
+
export function buildBindingsState() {
|
|
129
|
+
const product = state.product;
|
|
130
|
+
const user = omega.auth().getUser();
|
|
131
|
+
const prices = calculatePrices(state);
|
|
132
|
+
|
|
133
|
+
const isSubscription = product?.type === 'subscription';
|
|
134
|
+
const hasFreeTrial = isSubscription && state.trialEligible && (product?.trial?.days > 0);
|
|
135
|
+
const cycle = state.frequency;
|
|
136
|
+
|
|
137
|
+
// Determine which frequencies are available for this product
|
|
138
|
+
const availableFrequencies = getAvailableFrequencies(product);
|
|
139
|
+
|
|
140
|
+
// A price is a bare number on the product, and a frequency it has no price for
|
|
141
|
+
// reads 0 — which is exactly what getAvailableFrequencies() filters on
|
|
142
|
+
const monthlyPrice = resolvePrice(product, 'monthly');
|
|
143
|
+
const annualPrice = resolvePrice(product, 'annually');
|
|
144
|
+
const weeklyPrice = resolvePrice(product, 'weekly');
|
|
145
|
+
const dailyPrice = resolvePrice(product, 'daily');
|
|
146
|
+
const cyclePrice = resolvePrice(product, cycle);
|
|
147
|
+
|
|
148
|
+
// Savings calculation (compare monthly annualized vs annual price)
|
|
149
|
+
const monthlyTotal = monthlyPrice * 12;
|
|
150
|
+
const savingsPercent = monthlyTotal > 0
|
|
151
|
+
? Math.round(((monthlyTotal - annualPrice) / monthlyTotal) * 100)
|
|
152
|
+
: 0;
|
|
153
|
+
|
|
154
|
+
// Frequency display text map
|
|
155
|
+
const frequencyLabels = { daily: 'daily', weekly: 'weekly', monthly: 'monthly', annually: 'annually' };
|
|
156
|
+
|
|
157
|
+
// A discount is in force in EITHER shape. Reading only the percent reported
|
|
158
|
+
// no discount for a flat code, so the receipt showed full price while the
|
|
159
|
+
// backend went on to charge the discounted one.
|
|
160
|
+
const hasDiscount = state.discountPercent > 0 || state.discountAmount > 0;
|
|
161
|
+
|
|
162
|
+
// A code that covers the WHOLE price leaves nothing to charge, and the two
|
|
163
|
+
// providers this framework computes the amount for cannot take a $0.00
|
|
164
|
+
// payment — the backend refuses that checkout before it reaches them
|
|
165
|
+
// ([#786](https://github.com/Omega-JS-Stack/omega/issues/786)), so the buttons
|
|
166
|
+
// that could only end there are not offered.
|
|
167
|
+
//
|
|
168
|
+
// A free TRIAL is never this case, and the backend agrees: nothing is charged
|
|
169
|
+
// today (the provider's own trial cycle does that, and PayPal's setup-fee
|
|
170
|
+
// discount is skipped outright on a trial), and the code comes off the first
|
|
171
|
+
// PAID period later — so both buttons stay. It is read off the trial and the
|
|
172
|
+
// DISCOUNT, never off `prices.total`, which a trial zeroes on its own.
|
|
173
|
+
const fullyDiscounted = hasDiscount && !hasFreeTrial && prices.subtotal > 0 && prices.subtotal - prices.discountAmount <= 0;
|
|
174
|
+
|
|
175
|
+
// What this checkout can still be paid with — built before the bindings
|
|
176
|
+
// because the page has to know when the set is EMPTY.
|
|
177
|
+
const paymentMethods = {
|
|
178
|
+
card: !!(state.providers?.stripe?.publishableKey || state.providers?.chargebee?.site),
|
|
179
|
+
paypal: !!state.providers?.paypal?.clientId && !fullyDiscounted,
|
|
180
|
+
applePay: false,
|
|
181
|
+
googlePay: false,
|
|
182
|
+
// Crypto is the one method with a PRODUCT condition as well as a
|
|
183
|
+
// provider one: Coinbase Commerce sells a single hosted charge and has
|
|
184
|
+
// no recurring anything, so the backend's intent provider refuses a
|
|
185
|
+
// subscription outright. A button offered there could only ever end in
|
|
186
|
+
// the checkout's generic failure sentence
|
|
187
|
+
// ([#642](https://github.com/Omega-JS-Stack/omega/issues/642)).
|
|
188
|
+
// One-time ONLY, spelled positively: a product with no `type` is a
|
|
189
|
+
// subscription to the backend intent route, so the button must not show.
|
|
190
|
+
crypto: product?.type === 'one-time' && state.providers?.coinbase?.enabled === true && !fullyDiscounted,
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// A brand selling through PayPal (and crypto) alone has NO method left once a
|
|
194
|
+
// code covers the price, and the page's only "no payment methods" sentence is
|
|
195
|
+
// an init-time read of the provider CONFIG — so the grid just emptied and the
|
|
196
|
+
// page said nothing (#786). The sentence goes where the remedy is: the
|
|
197
|
+
// discount field's own error line, which keeps the code removable. The
|
|
198
|
+
// page-level error surface is not reusable here — it HIDES the whole checkout
|
|
199
|
+
// (`@hide checkout.error.show`), taking the discount field with it.
|
|
200
|
+
const noMethodsLeft = fullyDiscounted && !Object.values(paymentMethods).some(Boolean);
|
|
201
|
+
const blockedMessage = noMethodsLeft
|
|
202
|
+
? `Discount code ${state.discountCode} covers the full price, and no payment method here can take a $0.00 charge. Remove the code to continue.`
|
|
203
|
+
: '';
|
|
204
|
+
|
|
205
|
+
return {
|
|
206
|
+
checkout: {
|
|
207
|
+
product: {
|
|
208
|
+
name: product?.name || 'Loading...',
|
|
209
|
+
description: product?.description || '',
|
|
210
|
+
isSubscription,
|
|
211
|
+
},
|
|
212
|
+
// Which frequency options to show (driven by product.prices)
|
|
213
|
+
frequencies: {
|
|
214
|
+
daily: availableFrequencies.includes('daily'),
|
|
215
|
+
weekly: availableFrequencies.includes('weekly'),
|
|
216
|
+
monthly: availableFrequencies.includes('monthly'),
|
|
217
|
+
annually: availableFrequencies.includes('annually'),
|
|
218
|
+
},
|
|
219
|
+
pricing: {
|
|
220
|
+
dailyPrice: formatCurrency(dailyPrice || null),
|
|
221
|
+
weeklyPrice: formatCurrency(weeklyPrice || null),
|
|
222
|
+
monthlyPrice: formatCurrency(monthlyPrice || null),
|
|
223
|
+
annualMonthlyRate: formatCurrency(annualPrice ? annualPrice / 12 : null),
|
|
224
|
+
savingsBadge: savingsPercent > 0 ? `Save ${savingsPercent}%` : '',
|
|
225
|
+
showSavingsBadge: savingsPercent > 0,
|
|
226
|
+
// `once` is not a cadence (#558, the checkout-side sibling of #282):
|
|
227
|
+
// `cycle` is the URL default for EVERY product, so pricing a one-time
|
|
228
|
+
// buy by cycle quoted "$0.00 annually" under a $49.99 product while
|
|
229
|
+
// the rows beneath it said $49.99. calculatePrices() is the one place
|
|
230
|
+
// that knows the `once` key, and its subtotal is the list price the
|
|
231
|
+
// summary line names.
|
|
232
|
+
frequencyPaymentText: isSubscription
|
|
233
|
+
? `${formatCurrency(cyclePrice)} ${frequencyLabels[cycle] || cycle}`
|
|
234
|
+
: `${formatCurrency(prices.subtotal)} one-time`,
|
|
235
|
+
subtotal: formatCurrency(prices.subtotal),
|
|
236
|
+
},
|
|
237
|
+
discount: {
|
|
238
|
+
hasDiscount: hasDiscount,
|
|
239
|
+
// What the receipt row's parenthetical says. A percent names itself;
|
|
240
|
+
// a flat code names ITSELF, because "Discount ($10.00) −$10.00" says
|
|
241
|
+
// the same number twice.
|
|
242
|
+
label: state.discountPercent > 0 ? `${state.discountPercent}%` : (state.discountCode || ''),
|
|
243
|
+
amount: prices.discountAmount.toFixed(2),
|
|
244
|
+
loading: state.discountUI.loading,
|
|
245
|
+
// A code the server accepted, that this brand can then charge nobody
|
|
246
|
+
// with, is not a success the buyer can act on — it reads as the
|
|
247
|
+
// refusal it is, on the one line beside the field it was typed in
|
|
248
|
+
success: state.discountUI.success && !noMethodsLeft,
|
|
249
|
+
error: state.discountUI.error || noMethodsLeft,
|
|
250
|
+
successMessage: state.discountUI.message || 'Discount applied',
|
|
251
|
+
errorMessage: noMethodsLeft ? blockedMessage : (state.discountUI.message || 'Invalid discount code'),
|
|
252
|
+
},
|
|
253
|
+
paymentMethods: paymentMethods,
|
|
254
|
+
error: {
|
|
255
|
+
show: state.error.show,
|
|
256
|
+
message: state.error.message,
|
|
257
|
+
},
|
|
258
|
+
},
|
|
259
|
+
// The half the SERVER decides (#637). Its own bindings root because a root
|
|
260
|
+
// key is this system's unit of deferral: the page's build-config paint
|
|
261
|
+
// publishes `checkout` alone, which leaves every spot below still wearing
|
|
262
|
+
// its skeleton until trial eligibility has answered. Everything here reads
|
|
263
|
+
// differently depending on that one answer, so it is written exactly once.
|
|
264
|
+
order: {
|
|
265
|
+
total: formatCurrency(prices.total),
|
|
266
|
+
totalDueText: `${formatCurrency(prices.total)} due today`,
|
|
267
|
+
showTerms: isSubscription,
|
|
268
|
+
termsText: buildTermsText(product, cycle, hasFreeTrial, prices, hasDiscount),
|
|
269
|
+
trial: {
|
|
270
|
+
show: hasFreeTrial,
|
|
271
|
+
hasFreeTrial: hasFreeTrial && prices.total === 0,
|
|
272
|
+
// The length is the CATALOG's, never a framework constant (#273): a
|
|
273
|
+
// trial the product doesn't sell fails `hasFreeTrial` and the sentence
|
|
274
|
+
// never renders, so there is no number left to invent.
|
|
275
|
+
message: hasFreeTrial ? `Start your ${product.trial.days}-day free trial today!` : '',
|
|
276
|
+
discountAmount: prices.trialDiscountAmount.toFixed(2),
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
auth: {
|
|
280
|
+
user: {
|
|
281
|
+
email: user?.email || '',
|
|
282
|
+
},
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// Format a number as currency, or return placeholder. Exported because it is
|
|
288
|
+
// the page's ONE money format: the discount module's success message speaks it
|
|
289
|
+
// too ("$10.00 off"), rather than growing a second one.
|
|
290
|
+
export function formatCurrency(amount) {
|
|
291
|
+
if (amount == null || isNaN(amount)) return '$--';
|
|
292
|
+
return `$${Number(amount).toFixed(2)}`;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
// Map frequency to renewal period in days
|
|
296
|
+
const FREQUENCY_DAYS = { daily: 1, weekly: 7, monthly: 30, annually: 365 };
|
|
297
|
+
|
|
298
|
+
// Build subscription terms text
|
|
299
|
+
function buildTermsText(product, cycle, hasFreeTrial, prices, hasDiscount) {
|
|
300
|
+
if (!product || product.type !== 'subscription') return '';
|
|
301
|
+
|
|
302
|
+
const periodAdjectiveMap = { daily: 'daily', weekly: 'weekly', monthly: 'monthly', annually: 'annual' };
|
|
303
|
+
const periodText = periodAdjectiveMap[cycle] || cycle;
|
|
304
|
+
const renewalDate = new Date();
|
|
305
|
+
// Same catalog number the trial message states (#273) — the date the first
|
|
306
|
+
// charge lands on is the trial's own length, not a default one.
|
|
307
|
+
const daysToAdd = hasFreeTrial
|
|
308
|
+
? product.trial.days
|
|
309
|
+
: (FREQUENCY_DAYS[cycle] || 30);
|
|
310
|
+
renewalDate.setDate(renewalDate.getDate() + daysToAdd);
|
|
311
|
+
|
|
312
|
+
const formatted = renewalDate.toLocaleDateString('en-US', {
|
|
313
|
+
month: 'short',
|
|
314
|
+
day: 'numeric',
|
|
315
|
+
year: 'numeric',
|
|
316
|
+
});
|
|
317
|
+
|
|
318
|
+
// PayPal takes a code too since [#759](https://github.com/Omega-JS-Stack/omega/issues/759)
|
|
319
|
+
// (a discounted first period, charged as the plan's setup fee), so the note
|
|
320
|
+
// says the one thing that is still true of every code: it comes off once.
|
|
321
|
+
const discountNote = hasDiscount ? ' Discount code applies to first payment only.' : '';
|
|
322
|
+
|
|
323
|
+
if (hasFreeTrial) {
|
|
324
|
+
// The charge that lands when the trial ends is the FIRST invoice, and a
|
|
325
|
+
// first-payment code is attached to exactly that one (the intent route
|
|
326
|
+
// sends the `once` coupon alongside the trial — intent/providers/
|
|
327
|
+
// stripe.js). So the trial line prices the first charge DISCOUNTED and
|
|
328
|
+
// names the renewal price separately; quoting list price here promised a
|
|
329
|
+
// bigger first charge than the card will see (#254).
|
|
330
|
+
const firstCharge = prices.subtotal - prices.discountAmount;
|
|
331
|
+
const renewalNote = firstCharge !== prices.recurring
|
|
332
|
+
? ` It renews at ${formatCurrency(prices.recurring)} after that.`
|
|
333
|
+
: '';
|
|
334
|
+
|
|
335
|
+
return `You won't be charged for your free trial. On ${formatted}, your ${periodText} subscription will start and you'll be charged ${formatCurrency(firstCharge)} plus applicable tax.${renewalNote} Cancel anytime before then.${discountNote}`;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return `Your ${periodText} subscription will start today and renew on ${formatted} for ${formatCurrency(prices.recurring)} plus applicable tax. Cancel anytime.${discountNote}`;
|
|
339
|
+
}
|